8 #define DATE "20 Feb 1996"
13 By Glenn Chappell <ggc@uiuc.edu>
15 This program checks figlet 2.0/2.1 font files for format errors.
16 It also looks for signs of common problems and gives warnings.
17 chkfont does not modify font files.
19 Usage: chkfont fontfile ...
21 Note: This is very much a spare-time project. It's probably
25 /* #define CHECKBLANKS */
26 #define FONTFILESUFFIX ".flf"
27 #define FONTFILEMAGICNUMBER "flf2"
28 char posshardblanks
[9] = { '!', '@', '#', '$', '%', '&', '*', 0x7f, 0 };
30 char *myname
,*fontfilename
;
33 int charheight
,upheight
,maxlen
=0,old_layout
;
36 int maxlinelength
=0,currline
;
39 int incon_endmarkwarn
,endmark_countwarn
,nonincrwarn
;
40 int bigcodetagwarn
,deutschcodetagwarn
,asciicodetagwarn
;
47 if (!really
&& 2*ec
+wc
<=40) {
50 if (ec
+wc
>0) printf("*******************************************************************************\n");
52 printf("%s: Too many errors/warnings.\n",fontfilename
);
54 printf("%s: Errors: %d, Warnings: %d\n",fontfilename
,ec
,wc
);
55 if (currline
>1 && maxlen
!=maxlinelength
) {
56 printf("%s: maxlen: %d, actual max line length: %d\n",
57 fontfilename
,maxlen
,maxlinelength
);
58 if (codetagcnt
>0 && spectagcnt
==-1) {
59 printf("%s: Code-tagged characters: %d\n",fontfilename
,codetagcnt
);
62 printf("-------------------------------------------------------------------------------\n");
71 ptr
=(char *)malloc(size
);
73 fprintf(stderr
,"%s: Out of memory\n",myname
);
79 int badsuffix(path
,suffix
)
86 strcpy(ucsuffix
,suffix
);
87 for (s
= ucsuffix
; *s
; s
++) {
91 if (strlen(path
)<strlen(suffix
)) return 1;
92 s
= path
+ strlen(path
) - strlen(suffix
);
93 if (strcmp(s
,suffix
) == 0) return 0;
94 if (strcmp(s
,ucsuffix
) == 0) return 0;
100 fprintf(stderr
,"chkfont by Glenn Chappell <ggc@uiuc.edu>\n");
101 fprintf(stderr
,"Version: %s, date: %s\n",VERSION
,DATE
);
102 fprintf(stderr
,"Checks figlet 2.0/2.1 font files for format errors.\n");
103 fprintf(stderr
,"(Does not modify font files.)\n");
104 fprintf(stderr
,"Usage: %s fontfile ...\n",myname
);
110 int i
,expected_width
,k
,len
,newlen
,diff
,l
;
111 char endmark
,expected_endmark
;
112 int leadblanks
,minleadblanks
,trailblanks
,mintrailblanks
;
115 expected_width
= expected_endmark
= 0; /* prevent compiler warning */
116 for (i
=0;i
<charheight
;i
++) {
117 ret
= fgets(fileline
,maxlen
+1000,fontfile
);
119 printf("%s: ERROR (fatal)- Unexpected read error after line %d.\n",
120 fontfilename
,currline
);
122 weregone(1); if (gone
) return;
124 if (feof(fontfile
)) {
125 printf("%s: ERROR (fatal)- Unexpected end of file after line %d.\n",
126 fontfilename
,currline
);
128 weregone(1); if (gone
) return;
131 len
=strlen(fileline
)-1;
132 if (len
>maxlinelength
) {
136 printf("%s: ERROR- Line length > maxlen in line %d.\n",
137 fontfilename
,currline
);
139 weregone(0); if (gone
) return;
142 endmark
=k
<0?'\0':(k
==0||fileline
[k
]!='\n')?fileline
[k
]:fileline
[k
-1];
143 for(;k
>=0?(fileline
[k
]=='\n' || fileline
[k
]==endmark
):0;k
--) {
146 newlen
=strlen(fileline
);
147 for (l
=0;l
<newlen
? fileline
[l
]==' ' : 0;l
++) ;
149 for (l
=newlen
-1;l
>=0 ? fileline
[l
]==' ' : 0;l
--) ;
150 trailblanks
= newlen
-1-l
;
152 expected_endmark
= endmark
;
153 expected_width
= newlen
;
154 minleadblanks
= leadblanks
;
155 mintrailblanks
= trailblanks
;
157 printf("%s: Warning- Blank endmark in line %d.\n",
158 fontfilename
,currline
);
160 weregone(0); if (gone
) return;
164 if (leadblanks
<minleadblanks
) minleadblanks
= leadblanks
;
165 if (trailblanks
<mintrailblanks
) mintrailblanks
= trailblanks
;
166 if (endmark
!=expected_endmark
&& !incon_endmarkwarn
) {
167 printf("%s: Warning- Inconsistent endmark in line %d.\n",
168 fontfilename
,currline
);
169 printf("%s: (Above warning will only be printed once.)\n",
171 incon_endmarkwarn
= 1;
173 weregone(0); if (gone
) return;
175 if (newlen
!=expected_width
) {
176 printf("%s: ERROR- Inconsistent character width in line %d.\n",
177 fontfilename
,currline
);
179 weregone(0); if (gone
) return;
184 printf("%s: ERROR- Too many endmarks in line %d.\n",
185 fontfilename
,currline
);
187 weregone(0); if (gone
) return;
189 else if (charheight
>1 && (diff
!=(i
==charheight
-1)+1)) {
190 if (!endmark_countwarn
) {
191 printf("%s: Warning- Endchar count convention violated in line %d.\n",
192 fontfilename
,currline
);
193 printf("%s: (Above warning will only be printed once.)\n",
195 endmark_countwarn
= 1;
197 weregone(0); if (gone
) return;
202 if (minleadblanks
+mintrailblanks
>0 && old_layout
>=0) {
203 printf("%s: Warning- Leading/trailing blanks in char. ending at line %d.\n",
204 fontfilename
,currline
);
205 printf("%s: (Above warning only given when old_layout > -1.)\n",
208 weregone(0); if (gone
) return;
210 #endif /* #ifdef CHECKBLANKS */
216 int i
,k
,cmtcount
,numsread
,ffrighttoleft
,have_layout
,layout
;
217 char magicnum
[5],cha
;
222 incon_endmarkwarn
=0; endmark_countwarn
=0; nonincrwarn
=0;
223 bigcodetagwarn
=0; deutschcodetagwarn
=0;
227 if (!strcmp(fontfilename
,"-")) {
228 fontfilename
="(stdin)";
232 fontfile
=fopen(fontfilename
,"r");
233 if (fontfile
== NULL
) {
234 fprintf(stderr
,"%s: Could not open file '%s'\n",myname
,fontfilename
);
239 if (fontfile
!=stdin
) {
240 if (badsuffix(fontfilename
,FONTFILESUFFIX
)) {
241 printf("%s: ERROR- Filename does not end with '%s'.\n",
242 fontfilename
,FONTFILESUFFIX
);
244 weregone(0); if (gone
) return;
247 numsread
=fscanf(fontfile
,"%4s",magicnum
);
248 if (numsread
== EOF
) {
249 printf("%s: ERROR- can't read magic number.\n",fontfilename
);
251 weregone(0); if (gone
) return;
253 if (strcmp(magicnum
,FONTFILEMAGICNUMBER
)) {
254 printf("%s: ERROR- Incorrect magic number.\n",fontfilename
);
256 weregone(0); if (gone
) return;
260 printf("%s: Warning- Sub-version character is not 'a'.\n",fontfilename
);
262 weregone(0); if (gone
) return;
264 fileline
=(char*)my_alloc(sizeof(char)*(1001));
265 if (fgets(fileline
,1001,fontfile
)==NULL
) {
268 if (strlen(fileline
)>0 ? fileline
[strlen(fileline
)-1]!='\n' : 0) {
269 while(k
=getc(fontfile
),k
!='\n'&&k
!=EOF
) ; /* Advance to end of line */
271 numsread
=sscanf(fileline
,"%c %d %d %d %d %d %d %d %d",
272 &hardblank
,&charheight
,&upheight
,&maxlen
,&old_layout
,&cmtcount
,
273 &ffrighttoleft
,&layout
,&spectagcnt
);
282 have_layout
= (numsread
>=8);
284 printf("%s: ERROR (fatal)- First line improperly formatted.\n",fontfilename
);
286 weregone(1); if (gone
) return;
288 if (!strchr(posshardblanks
,hardblank
)) {
289 printf("%s: Warning- Unusual hardblank.\n",fontfilename
);
291 weregone(0); if (gone
) return;
294 printf("%s: ERROR (fatal)- charheight not positive.\n",fontfilename
);
296 weregone(1); if (gone
) return;
298 if (upheight
>charheight
|| upheight
<1) {
299 printf("%s: ERROR- up_height out of bounds.\n",fontfilename
);
301 weregone(0); if (gone
) return;
304 printf("%s: ERROR (fatal)- maxlen not positive.\n",fontfilename
);
306 weregone(1); if (gone
) return;
309 printf("%s: ERROR- old_layout < -1.\n",fontfilename
);
311 weregone(0); if (gone
) return;
314 printf("%s: ERROR- old_layout > 63.\n",fontfilename
);
316 weregone(0); if (gone
) return;
318 if (have_layout
&& layout
<0) {
319 printf("%s: ERROR- layout < 0.\n", fontfilename
);
321 weregone(0); if (gone
) return;
323 if (have_layout
&&layout
>32767) {
324 printf("%s: ERROR- layout > 32767.\n", fontfilename
);
326 weregone(0); if (gone
) return;
328 if (have_layout
&& old_layout
== -1 && (layout
& 192)) {
329 printf("%s: ERROR- layout %d is inconsistent with old_layout -1.\n",
330 fontfilename
,layout
);
332 weregone(0); if (gone
) return;
334 if (have_layout
&& old_layout
== 0 && (layout
& 192) != 64 &&
335 (layout
& 255) != 128) {
336 printf("%s: ERROR- layout %d is inconsistent with old_layout 0.\n",
337 fontfilename
,layout
);
339 weregone(0); if (gone
) return;
341 if (have_layout
&& old_layout
> 0 &&
342 (!(layout
& 128) || old_layout
!= (layout
& 63))) {
343 printf("%s: ERROR- layout %d is inconsistent with old_layout %d.\n",
344 fontfilename
,layout
,old_layout
);
346 weregone(0); if (gone
) return;
349 printf("%s: ERROR- cmt_count is negative.\n",fontfilename
);
351 weregone(0); if (gone
) return;
353 if (ffrighttoleft
<0 || ffrighttoleft
>1) {
354 printf("%s: ERROR- rtol out of bounds.\n",fontfilename
);
356 weregone(0); if (gone
) return;
359 for (i
=1;i
<=cmtcount
;i
++) {
360 while(k
=getc(fontfile
),k
!='\n'&&k
!=EOF
) ; /* Advance to end of line */
365 fileline
=(char*)my_alloc(sizeof(char)*(maxlen
+1001));
366 for (i
=0;i
<102;i
++) {
372 while(fgets(fileline
,maxlen
+1000,fontfile
)!=NULL
) {
374 len
=strlen(fileline
)-1;
375 if (len
-100>maxlinelength
) {
376 maxlinelength
=len
-100;
378 if (len
>maxlen
+100) {
379 printf("%s: ERROR- Code tag line way too long in line %d.\n",
380 fontfilename
,currline
);
382 weregone(0); if (gone
) return;
384 tmpcnt
=sscanf(fileline
,"%li",&theord
);
386 printf("%s: Warning- Extra chars after font in line %d.\n",
387 fontfilename
,currline
);
389 weregone(0); if (gone
) return;
393 if (theord
>65535 && !bigcodetagwarn
) {
394 printf("%s: Warning- Code tag > 65535 in line %d.\n",
395 fontfilename
,currline
);
396 printf("%s: (Above warning will only be printed once.)\n",
400 weregone(0); if (gone
) return;
403 printf("%s: ERROR- Code tag -1 (unusable) in line %d.\n",
404 fontfilename
,currline
);
406 weregone(0); if (gone
) return;
409 if (theord
>=-255 && theord
<=-249 &&!deutschcodetagwarn
) {
410 printf("%s: Warning- Code tag in old Deutsch area in line %d.\n",
411 fontfilename
,currline
);
412 printf("%s: (Above warning will only be printed once.)\n",
414 deutschcodetagwarn
= 1;
416 weregone(0); if (gone
) return;
418 if (theord
<127 && theord
>31 && !asciicodetagwarn
) {
419 printf("%s: Warning- Code tag in ASCII range in line %d.\n",
420 fontfilename
,currline
);
421 printf("%s: (Above warning will only be printed once.)\n",
423 asciicodetagwarn
= 1;
425 weregone(0); if (gone
) return;
427 else if (theord
<=oldord
&& theord
>=0 && oldord
>=0 && !nonincrwarn
) {
428 printf("%s: Warning- Non-increasing code tag in line %d.\n",
429 fontfilename
,currline
);
430 printf("%s: (Above warning will only be printed once.)\n",
434 weregone(0); if (gone
) return;
441 if (spectagcnt
!=-1 && spectagcnt
!=codetagcnt
) {
442 printf("%s: ERROR- Inconsistent Codetag_Cnt value %d\n",
443 fontfilename
, spectagcnt
);
445 weregone(0); if (gone
) return;
448 if (fontfile
!=stdin
) fclose(fontfile
);
450 weregone(1); if (gone
) return;
460 if ((myname
=strrchr(argv
[0],'/'))!=NULL
) {
469 for (arg
=1;arg
<argc
;arg
++) {
470 fontfilename
=argv
[arg
];
473 if (fileline
!=NULL
) free(fileline
);