diff options
Diffstat (limited to '')
-rw-r--r-- | chkfont.c | 461 |
1 files changed, 461 insertions, 0 deletions
diff --git a/chkfont.c b/chkfont.c new file mode 100644 index 0000000..8272207 --- /dev/null +++ b/chkfont.c @@ -0,0 +1,461 @@ +#include <stdio.h> +#include <string.h> +#include <ctype.h> + +#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); + } +else { + 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; + +for (i=0;i<charheight;i++) { + fgets(fileline,maxlen+1000,fontfile); + 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; + } + } +fscanf(fontfile,"%4s",magicnum); +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); +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); + } +exit(0); +} |