Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F92191238
chkfont.c
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Mon, Nov 18, 04:19
Size
12 KB
Mime Type
text/x-c
Expires
Wed, Nov 20, 04:19 (2 d)
Engine
blob
Format
Raw Data
Handle
22388306
Attached To
rPH Phabricator
chkfont.c
View Options
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#ifdef __STDC__
#include <stdlib.h>
#endif
#define DATE "20 Feb 1996"
#define VERSION "2.2"
/*
chkfont
By Glenn Chappell <ggc@uiuc.edu>
This program checks figlet 2.0/2.1 font files for format errors.
It also looks for signs of common problems and gives warnings.
chkfont does not modify font files.
Usage: chkfont fontfile ...
Note: This is very much a spare-time project. It's probably
full o' bugs ....
*/
/* #define CHECKBLANKS */
#define FONTFILESUFFIX ".flf"
#define FONTFILEMAGICNUMBER "flf2"
char posshardblanks[9] = { '!', '@', '#', '$', '%', '&', '*', 0x7f, 0 };
char *myname,*fontfilename;
FILE *fontfile;
char hardblank;
int charheight,upheight,maxlen=0,old_layout;
int spectagcnt;
char *fileline;
int maxlinelength=0,currline;
int ec,wc;
int incon_endmarkwarn,endmark_countwarn,nonincrwarn;
int bigcodetagwarn,deutschcodetagwarn,asciicodetagwarn;
int codetagcnt;
int gone;
void weregone(really)
int really;
{
if (!really && 2*ec+wc<=40) {
return;
}
if (ec+wc>0) printf("*******************************************************************************\n");
if (!really) {
printf("%s: Too many errors/warnings.\n",fontfilename);
}
printf("%s: Errors: %d, Warnings: %d\n",fontfilename,ec,wc);
if (currline>1 && maxlen!=maxlinelength) {
printf("%s: maxlen: %d, actual max line length: %d\n",
fontfilename,maxlen,maxlinelength);
if (codetagcnt>0 && spectagcnt==-1) {
printf("%s: Code-tagged characters: %d\n",fontfilename,codetagcnt);
}
}
printf("-------------------------------------------------------------------------------\n");
gone=1;
}
char *my_alloc(size)
int size;
{
char *ptr;
ptr=(char *)malloc(size);
if (ptr==NULL) {
fprintf(stderr,"%s: Out of memory\n",myname);
exit(1);
}
return(ptr);
}
int badsuffix(path,suffix)
char *path;
char *suffix;
{
char ucsuffix[10];
char *s;
strcpy(ucsuffix,suffix);
for (s = ucsuffix; *s; s++) {
*s = toupper(*s);
}
if (strlen(path)<strlen(suffix)) return 1;
s = path + strlen(path) - strlen(suffix);
if (strcmp(s,suffix) == 0) return 0;
if (strcmp(s,ucsuffix) == 0) return 0;
return 1;
}
void usageerr()
{
fprintf(stderr,"chkfont by Glenn Chappell <ggc@uiuc.edu>\n");
fprintf(stderr,"Version: %s, date: %s\n",VERSION,DATE);
fprintf(stderr,"Checks figlet 2.0/2.1 font files for format errors.\n");
fprintf(stderr,"(Does not modify font files.)\n");
fprintf(stderr,"Usage: %s fontfile ...\n",myname);
exit(1);
}
void readchar()
{
int i,expected_width,k,len,newlen,diff,l;
char endmark,expected_endmark;
int leadblanks,minleadblanks,trailblanks,mintrailblanks;
char *ret;
expected_width = expected_endmark = 0; /* prevent compiler warning */
for (i=0;i<charheight;i++) {
ret = fgets(fileline,maxlen+1000,fontfile);
if (ret == NULL) {
printf("%s: ERROR (fatal)- Unexpected read error after line %d.\n",
fontfilename,currline);
ec++;
weregone(1); if (gone) return;
}
if (feof(fontfile)) {
printf("%s: ERROR (fatal)- Unexpected end of file after line %d.\n",
fontfilename,currline);
ec++;
weregone(1); if (gone) return;
}
currline++;
len=strlen(fileline)-1;
if (len>maxlinelength) {
maxlinelength=len;
}
if (len>maxlen) {
printf("%s: ERROR- Line length > maxlen in line %d.\n",
fontfilename,currline);
ec++;
weregone(0); if (gone) return;
}
k=len;
endmark=k<0?'\0':(k==0||fileline[k]!='\n')?fileline[k]:fileline[k-1];
for(;k>=0?(fileline[k]=='\n' || fileline[k]==endmark):0;k--) {
fileline[k]='\0';
}
newlen=strlen(fileline);
for (l=0;l<newlen ? fileline[l]==' ' : 0;l++) ;
leadblanks = l;
for (l=newlen-1;l>=0 ? fileline[l]==' ' : 0;l--) ;
trailblanks = newlen-1-l;
if (i==0) {
expected_endmark = endmark;
expected_width = newlen;
minleadblanks = leadblanks;
mintrailblanks = trailblanks;
if (endmark==' ') {
printf("%s: Warning- Blank endmark in line %d.\n",
fontfilename,currline);
wc++;
weregone(0); if (gone) return;
}
}
else {
if (leadblanks<minleadblanks) minleadblanks = leadblanks;
if (trailblanks<mintrailblanks) mintrailblanks = trailblanks;
if (endmark!=expected_endmark && !incon_endmarkwarn) {
printf("%s: Warning- Inconsistent endmark in line %d.\n",
fontfilename,currline);
printf("%s: (Above warning will only be printed once.)\n",
fontfilename);
incon_endmarkwarn = 1;
wc++;
weregone(0); if (gone) return;
}
if (newlen!=expected_width) {
printf("%s: ERROR- Inconsistent character width in line %d.\n",
fontfilename,currline);
ec++;
weregone(0); if (gone) return;
}
}
diff=len-newlen;
if (diff>2) {
printf("%s: ERROR- Too many endmarks in line %d.\n",
fontfilename,currline);
ec++;
weregone(0); if (gone) return;
}
else if (charheight>1 && (diff!=(i==charheight-1)+1)) {
if (!endmark_countwarn) {
printf("%s: Warning- Endchar count convention violated in line %d.\n",
fontfilename,currline);
printf("%s: (Above warning will only be printed once.)\n",
fontfilename);
endmark_countwarn = 1;
wc++;
weregone(0); if (gone) return;
}
}
}
#ifdef CHECKBLANKS
if (minleadblanks+mintrailblanks>0 && old_layout>=0) {
printf("%s: Warning- Leading/trailing blanks in char. ending at line %d.\n",
fontfilename,currline);
printf("%s: (Above warning only given when old_layout > -1.)\n",
fontfilename);
wc++;
weregone(0); if (gone) return;
}
#endif /* #ifdef CHECKBLANKS */
}
void checkit()
{
int i,k,cmtcount,numsread,ffrighttoleft,have_layout,layout;
char magicnum[5],cha;
long oldord,theord;
int tmpcnt,len;
ec=0;wc=0;
incon_endmarkwarn=0; endmark_countwarn=0; nonincrwarn=0;
bigcodetagwarn=0; deutschcodetagwarn=0;
asciicodetagwarn=0;
codetagcnt=0;
gone=0;
if (!strcmp(fontfilename,"-")) {
fontfilename="(stdin)";
fontfile=stdin;
}
else {
fontfile=fopen(fontfilename,"r");
if (fontfile == NULL) {
fprintf(stderr,"%s: Could not open file '%s'\n",myname,fontfilename);
exit(1);
}
}
if (fontfile!=stdin) {
if (badsuffix(fontfilename,FONTFILESUFFIX)) {
printf("%s: ERROR- Filename does not end with '%s'.\n",
fontfilename,FONTFILESUFFIX);
ec++;
weregone(0); if (gone) return;
}
}
numsread=fscanf(fontfile,"%4s",magicnum);
if (numsread == EOF) {
printf("%s: ERROR- can't read magic number.\n",fontfilename);
ec++;
weregone(0); if (gone) return;
}
if (strcmp(magicnum,FONTFILEMAGICNUMBER)) {
printf("%s: ERROR- Incorrect magic number.\n",fontfilename);
ec++;
weregone(0); if (gone) return;
}
cha=getc(fontfile);
if (cha!='a') {
printf("%s: Warning- Sub-version character is not 'a'.\n",fontfilename);
wc++;
weregone(0); if (gone) return;
}
fileline=(char*)my_alloc(sizeof(char)*(1001));
if (fgets(fileline,1001,fontfile)==NULL) {
fileline[0] = '\0';
}
if (strlen(fileline)>0 ? fileline[strlen(fileline)-1]!='\n' : 0) {
while(k=getc(fontfile),k!='\n'&&k!=EOF) ; /* Advance to end of line */
}
numsread=sscanf(fileline,"%c %d %d %d %d %d %d %d %d",
&hardblank,&charheight,&upheight,&maxlen,&old_layout,&cmtcount,
&ffrighttoleft,&layout,&spectagcnt);
free(fileline);
fileline = NULL;
if (numsread<7) {
ffrighttoleft=0;
}
if (numsread<9) {
spectagcnt=-1;
}
have_layout = (numsread>=8);
if (6>numsread) {
printf("%s: ERROR (fatal)- First line improperly formatted.\n",fontfilename);
ec++;
weregone(1); if (gone) return;
}
if (!strchr(posshardblanks,hardblank)) {
printf("%s: Warning- Unusual hardblank.\n",fontfilename);
wc++;
weregone(0); if (gone) return;
}
if (charheight<1) {
printf("%s: ERROR (fatal)- charheight not positive.\n",fontfilename);
ec++;
weregone(1); if (gone) return;
}
if (upheight>charheight || upheight<1) {
printf("%s: ERROR- up_height out of bounds.\n",fontfilename);
ec++;
weregone(0); if (gone) return;
}
if (maxlen<1) {
printf("%s: ERROR (fatal)- maxlen not positive.\n",fontfilename);
ec++;
weregone(1); if (gone) return;
}
if (old_layout<-1) {
printf("%s: ERROR- old_layout < -1.\n",fontfilename);
ec++;
weregone(0); if (gone) return;
}
if (old_layout>63) {
printf("%s: ERROR- old_layout > 63.\n",fontfilename);
ec++;
weregone(0); if (gone) return;
}
if (have_layout && layout<0) {
printf("%s: ERROR- layout < 0.\n", fontfilename);
ec++;
weregone(0); if (gone) return;
}
if (have_layout &&layout>32767) {
printf("%s: ERROR- layout > 32767.\n", fontfilename);
ec++;
weregone(0); if (gone) return;
}
if (have_layout && old_layout == -1 && (layout & 192)) {
printf("%s: ERROR- layout %d is inconsistent with old_layout -1.\n",
fontfilename,layout);
ec++;
weregone(0); if (gone) return;
}
if (have_layout && old_layout == 0 && (layout & 192) != 64 &&
(layout & 255) != 128) {
printf("%s: ERROR- layout %d is inconsistent with old_layout 0.\n",
fontfilename,layout);
ec++;
weregone(0); if (gone) return;
}
if (have_layout && old_layout > 0 &&
(!(layout & 128) || old_layout != (layout & 63))) {
printf("%s: ERROR- layout %d is inconsistent with old_layout %d.\n",
fontfilename,layout,old_layout);
ec++;
weregone(0); if (gone) return;
}
if (cmtcount<0) {
printf("%s: ERROR- cmt_count is negative.\n",fontfilename);
ec++;
weregone(0); if (gone) return;
}
if (ffrighttoleft<0 || ffrighttoleft>1) {
printf("%s: ERROR- rtol out of bounds.\n",fontfilename);
ec++;
weregone(0); if (gone) return;
}
for (i=1;i<=cmtcount;i++) {
while(k=getc(fontfile),k!='\n'&&k!=EOF) ; /* Advance to end of line */
}
maxlinelength = 0;
currline=cmtcount+1;
fileline=(char*)my_alloc(sizeof(char)*(maxlen+1001));
for (i=0;i<102;i++) {
readchar();
if (gone) return;
}
oldord=0;
while(fgets(fileline,maxlen+1000,fontfile)!=NULL) {
currline++;
len=strlen(fileline)-1;
if (len-100>maxlinelength) {
maxlinelength=len-100;
}
if (len>maxlen+100) {
printf("%s: ERROR- Code tag line way too long in line %d.\n",
fontfilename,currline);
ec++;
weregone(0); if (gone) return;
}
tmpcnt=sscanf(fileline,"%li",&theord);
if (tmpcnt<1) {
printf("%s: Warning- Extra chars after font in line %d.\n",
fontfilename,currline);
wc++;
weregone(0); if (gone) return;
break;
}
codetagcnt++;
if (theord>65535 && !bigcodetagwarn) {
printf("%s: Warning- Code tag > 65535 in line %d.\n",
fontfilename,currline);
printf("%s: (Above warning will only be printed once.)\n",
fontfilename);
bigcodetagwarn = 1;
wc++;
weregone(0); if (gone) return;
}
if (theord==-1) {
printf("%s: ERROR- Code tag -1 (unusable) in line %d.\n",
fontfilename,currline);
ec++;
weregone(0); if (gone) return;
break;
}
if (theord>=-255 && theord<=-249 &&!deutschcodetagwarn) {
printf("%s: Warning- Code tag in old Deutsch area in line %d.\n",
fontfilename,currline);
printf("%s: (Above warning will only be printed once.)\n",
fontfilename);
deutschcodetagwarn = 1;
wc++;
weregone(0); if (gone) return;
}
if (theord<127 && theord>31 && !asciicodetagwarn) {
printf("%s: Warning- Code tag in ASCII range in line %d.\n",
fontfilename,currline);
printf("%s: (Above warning will only be printed once.)\n",
fontfilename);
asciicodetagwarn = 1;
wc++;
weregone(0); if (gone) return;
}
else if (theord<=oldord && theord>=0 && oldord>=0 && !nonincrwarn) {
printf("%s: Warning- Non-increasing code tag in line %d.\n",
fontfilename,currline);
printf("%s: (Above warning will only be printed once.)\n",
fontfilename);
nonincrwarn = 1;
wc++;
weregone(0); if (gone) return;
}
oldord=theord;
readchar();
if (gone) return;
}
if (spectagcnt!=-1 && spectagcnt!=codetagcnt) {
printf("%s: ERROR- Inconsistent Codetag_Cnt value %d\n",
fontfilename, spectagcnt);
ec++;
weregone(0); if (gone) return;
}
if (fontfile!=stdin) fclose(fontfile);
weregone(1); if (gone) return;
}
int main(argc,argv)
int argc;
char *argv[];
{
int arg;
if ((myname=strrchr(argv[0],'/'))!=NULL) {
myname++;
}
else {
myname = argv[0];
}
if (argc<2) {
usageerr();
}
for (arg=1;arg<argc;arg++) {
fontfilename=argv[arg];
fileline=NULL;
checkit();
if (fileline!=NULL) free(fileline);
}
return 0;
}
Event Timeline
Log In to Comment