Provide missing "AlmanacInterfaceTransactionQuery"
[phabricator.git] / externals / figlet / chkfont.c
blob63bf381b31aee293c34cff69e1c051c9efa7160c
1 #include <stdio.h>
2 #include <string.h>
3 #include <ctype.h>
4 #ifdef __STDC__
5 #include <stdlib.h>
6 #endif
8 #define DATE "20 Feb 1996"
9 #define VERSION "2.2"
12 chkfont
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
22 full o' bugs ....
25 /* #define CHECKBLANKS */
26 #define FONTFILESUFFIX ".flf"
27 #define FONTFILEMAGICNUMBER "flf2"
28 char posshardblanks[9] = { '!', '@', '#', '$', '%', '&', '*', 0x7f, 0 };
30 char *myname,*fontfilename;
31 FILE *fontfile;
32 char hardblank;
33 int charheight,upheight,maxlen=0,old_layout;
34 int spectagcnt;
35 char *fileline;
36 int maxlinelength=0,currline;
37 int ec,wc;
39 int incon_endmarkwarn,endmark_countwarn,nonincrwarn;
40 int bigcodetagwarn,deutschcodetagwarn,asciicodetagwarn;
41 int codetagcnt;
42 int gone;
44 void weregone(really)
45 int really;
47 if (!really && 2*ec+wc<=40) {
48 return;
50 if (ec+wc>0) printf("*******************************************************************************\n");
51 if (!really) {
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");
63 gone=1;
66 char *my_alloc(size)
67 int size;
69 char *ptr;
71 ptr=(char *)malloc(size);
72 if (ptr==NULL) {
73 fprintf(stderr,"%s: Out of memory\n",myname);
74 exit(1);
76 return(ptr);
79 int badsuffix(path,suffix)
80 char *path;
81 char *suffix;
83 char ucsuffix[10];
84 char *s;
86 strcpy(ucsuffix,suffix);
87 for (s = ucsuffix; *s; s++) {
88 *s = toupper(*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;
95 return 1;
98 void usageerr()
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);
105 exit(1);
108 void readchar()
110 int i,expected_width,k,len,newlen,diff,l;
111 char endmark,expected_endmark;
112 int leadblanks,minleadblanks,trailblanks,mintrailblanks;
113 char *ret;
115 expected_width = expected_endmark = 0; /* prevent compiler warning */
116 for (i=0;i<charheight;i++) {
117 ret = fgets(fileline,maxlen+1000,fontfile);
118 if (ret == NULL) {
119 printf("%s: ERROR (fatal)- Unexpected read error after line %d.\n",
120 fontfilename,currline);
121 ec++;
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);
127 ec++;
128 weregone(1); if (gone) return;
130 currline++;
131 len=strlen(fileline)-1;
132 if (len>maxlinelength) {
133 maxlinelength=len;
135 if (len>maxlen) {
136 printf("%s: ERROR- Line length > maxlen in line %d.\n",
137 fontfilename,currline);
138 ec++;
139 weregone(0); if (gone) return;
141 k=len;
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--) {
144 fileline[k]='\0';
146 newlen=strlen(fileline);
147 for (l=0;l<newlen ? fileline[l]==' ' : 0;l++) ;
148 leadblanks = l;
149 for (l=newlen-1;l>=0 ? fileline[l]==' ' : 0;l--) ;
150 trailblanks = newlen-1-l;
151 if (i==0) {
152 expected_endmark = endmark;
153 expected_width = newlen;
154 minleadblanks = leadblanks;
155 mintrailblanks = trailblanks;
156 if (endmark==' ') {
157 printf("%s: Warning- Blank endmark in line %d.\n",
158 fontfilename,currline);
159 wc++;
160 weregone(0); if (gone) return;
163 else {
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",
170 fontfilename);
171 incon_endmarkwarn = 1;
172 wc++;
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);
178 ec++;
179 weregone(0); if (gone) return;
182 diff=len-newlen;
183 if (diff>2) {
184 printf("%s: ERROR- Too many endmarks in line %d.\n",
185 fontfilename,currline);
186 ec++;
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",
194 fontfilename);
195 endmark_countwarn = 1;
196 wc++;
197 weregone(0); if (gone) return;
201 #ifdef CHECKBLANKS
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",
206 fontfilename);
207 wc++;
208 weregone(0); if (gone) return;
210 #endif /* #ifdef CHECKBLANKS */
214 void checkit()
216 int i,k,cmtcount,numsread,ffrighttoleft,have_layout,layout;
217 char magicnum[5],cha;
218 long oldord,theord;
219 int tmpcnt,len;
221 ec=0;wc=0;
222 incon_endmarkwarn=0; endmark_countwarn=0; nonincrwarn=0;
223 bigcodetagwarn=0; deutschcodetagwarn=0;
224 asciicodetagwarn=0;
225 codetagcnt=0;
226 gone=0;
227 if (!strcmp(fontfilename,"-")) {
228 fontfilename="(stdin)";
229 fontfile=stdin;
231 else {
232 fontfile=fopen(fontfilename,"r");
233 if (fontfile == NULL) {
234 fprintf(stderr,"%s: Could not open file '%s'\n",myname,fontfilename);
235 exit(1);
239 if (fontfile!=stdin) {
240 if (badsuffix(fontfilename,FONTFILESUFFIX)) {
241 printf("%s: ERROR- Filename does not end with '%s'.\n",
242 fontfilename,FONTFILESUFFIX);
243 ec++;
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);
250 ec++;
251 weregone(0); if (gone) return;
253 if (strcmp(magicnum,FONTFILEMAGICNUMBER)) {
254 printf("%s: ERROR- Incorrect magic number.\n",fontfilename);
255 ec++;
256 weregone(0); if (gone) return;
258 cha=getc(fontfile);
259 if (cha!='a') {
260 printf("%s: Warning- Sub-version character is not 'a'.\n",fontfilename);
261 wc++;
262 weregone(0); if (gone) return;
264 fileline=(char*)my_alloc(sizeof(char)*(1001));
265 if (fgets(fileline,1001,fontfile)==NULL) {
266 fileline[0] = '\0';
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);
274 free(fileline);
275 fileline = NULL;
276 if (numsread<7) {
277 ffrighttoleft=0;
279 if (numsread<9) {
280 spectagcnt=-1;
282 have_layout = (numsread>=8);
283 if (6>numsread) {
284 printf("%s: ERROR (fatal)- First line improperly formatted.\n",fontfilename);
285 ec++;
286 weregone(1); if (gone) return;
288 if (!strchr(posshardblanks,hardblank)) {
289 printf("%s: Warning- Unusual hardblank.\n",fontfilename);
290 wc++;
291 weregone(0); if (gone) return;
293 if (charheight<1) {
294 printf("%s: ERROR (fatal)- charheight not positive.\n",fontfilename);
295 ec++;
296 weregone(1); if (gone) return;
298 if (upheight>charheight || upheight<1) {
299 printf("%s: ERROR- up_height out of bounds.\n",fontfilename);
300 ec++;
301 weregone(0); if (gone) return;
303 if (maxlen<1) {
304 printf("%s: ERROR (fatal)- maxlen not positive.\n",fontfilename);
305 ec++;
306 weregone(1); if (gone) return;
308 if (old_layout<-1) {
309 printf("%s: ERROR- old_layout < -1.\n",fontfilename);
310 ec++;
311 weregone(0); if (gone) return;
313 if (old_layout>63) {
314 printf("%s: ERROR- old_layout > 63.\n",fontfilename);
315 ec++;
316 weregone(0); if (gone) return;
318 if (have_layout && layout<0) {
319 printf("%s: ERROR- layout < 0.\n", fontfilename);
320 ec++;
321 weregone(0); if (gone) return;
323 if (have_layout &&layout>32767) {
324 printf("%s: ERROR- layout > 32767.\n", fontfilename);
325 ec++;
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);
331 ec++;
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);
338 ec++;
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);
345 ec++;
346 weregone(0); if (gone) return;
348 if (cmtcount<0) {
349 printf("%s: ERROR- cmt_count is negative.\n",fontfilename);
350 ec++;
351 weregone(0); if (gone) return;
353 if (ffrighttoleft<0 || ffrighttoleft>1) {
354 printf("%s: ERROR- rtol out of bounds.\n",fontfilename);
355 ec++;
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 */
363 maxlinelength = 0;
364 currline=cmtcount+1;
365 fileline=(char*)my_alloc(sizeof(char)*(maxlen+1001));
366 for (i=0;i<102;i++) {
367 readchar();
368 if (gone) return;
371 oldord=0;
372 while(fgets(fileline,maxlen+1000,fontfile)!=NULL) {
373 currline++;
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);
381 ec++;
382 weregone(0); if (gone) return;
384 tmpcnt=sscanf(fileline,"%li",&theord);
385 if (tmpcnt<1) {
386 printf("%s: Warning- Extra chars after font in line %d.\n",
387 fontfilename,currline);
388 wc++;
389 weregone(0); if (gone) return;
390 break;
392 codetagcnt++;
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",
397 fontfilename);
398 bigcodetagwarn = 1;
399 wc++;
400 weregone(0); if (gone) return;
402 if (theord==-1) {
403 printf("%s: ERROR- Code tag -1 (unusable) in line %d.\n",
404 fontfilename,currline);
405 ec++;
406 weregone(0); if (gone) return;
407 break;
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",
413 fontfilename);
414 deutschcodetagwarn = 1;
415 wc++;
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",
422 fontfilename);
423 asciicodetagwarn = 1;
424 wc++;
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",
431 fontfilename);
432 nonincrwarn = 1;
433 wc++;
434 weregone(0); if (gone) return;
436 oldord=theord;
437 readchar();
438 if (gone) return;
441 if (spectagcnt!=-1 && spectagcnt!=codetagcnt) {
442 printf("%s: ERROR- Inconsistent Codetag_Cnt value %d\n",
443 fontfilename, spectagcnt);
444 ec++;
445 weregone(0); if (gone) return;
448 if (fontfile!=stdin) fclose(fontfile);
450 weregone(1); if (gone) return;
454 int main(argc,argv)
455 int argc;
456 char *argv[];
458 int arg;
460 if ((myname=strrchr(argv[0],'/'))!=NULL) {
461 myname++;
463 else {
464 myname = argv[0];
466 if (argc<2) {
467 usageerr();
469 for (arg=1;arg<argc;arg++) {
470 fontfilename=argv[arg];
471 fileline=NULL;
472 checkit();
473 if (fileline!=NULL) free(fileline);
475 return 0;