aboutsummaryrefslogtreecommitdiffstats
path: root/chkfont.c
diff options
context:
space:
mode:
Diffstat (limited to 'chkfont.c')
-rw-r--r--chkfont.c461
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);
+}