Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/phabricator
Path: blob/master/externals/figlet/chkfont.c
12240 views
1
#include <stdio.h>
2
#include <string.h>
3
#include <ctype.h>
4
#ifdef __STDC__
5
#include <stdlib.h>
6
#endif
7
8
#define DATE "20 Feb 1996"
9
#define VERSION "2.2"
10
11
/*
12
chkfont
13
By Glenn Chappell <[email protected]>
14
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.
18
19
Usage: chkfont fontfile ...
20
21
Note: This is very much a spare-time project. It's probably
22
full o' bugs ....
23
*/
24
25
/* #define CHECKBLANKS */
26
#define FONTFILESUFFIX ".flf"
27
#define FONTFILEMAGICNUMBER "flf2"
28
char posshardblanks[9] = { '!', '@', '#', '$', '%', '&', '*', 0x7f, 0 };
29
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;
38
39
int incon_endmarkwarn,endmark_countwarn,nonincrwarn;
40
int bigcodetagwarn,deutschcodetagwarn,asciicodetagwarn;
41
int codetagcnt;
42
int gone;
43
44
void weregone(really)
45
int really;
46
{
47
if (!really && 2*ec+wc<=40) {
48
return;
49
}
50
if (ec+wc>0) printf("*******************************************************************************\n");
51
if (!really) {
52
printf("%s: Too many errors/warnings.\n",fontfilename);
53
}
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);
60
}
61
}
62
printf("-------------------------------------------------------------------------------\n");
63
gone=1;
64
}
65
66
char *my_alloc(size)
67
int size;
68
{
69
char *ptr;
70
71
ptr=(char *)malloc(size);
72
if (ptr==NULL) {
73
fprintf(stderr,"%s: Out of memory\n",myname);
74
exit(1);
75
}
76
return(ptr);
77
}
78
79
int badsuffix(path,suffix)
80
char *path;
81
char *suffix;
82
{
83
char ucsuffix[10];
84
char *s;
85
86
strcpy(ucsuffix,suffix);
87
for (s = ucsuffix; *s; s++) {
88
*s = toupper(*s);
89
}
90
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;
96
}
97
98
void usageerr()
99
{
100
fprintf(stderr,"chkfont by Glenn Chappell <[email protected]>\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);
106
}
107
108
void readchar()
109
{
110
int i,expected_width,k,len,newlen,diff,l;
111
char endmark,expected_endmark;
112
int leadblanks,minleadblanks,trailblanks,mintrailblanks;
113
char *ret;
114
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;
123
}
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;
129
}
130
currline++;
131
len=strlen(fileline)-1;
132
if (len>maxlinelength) {
133
maxlinelength=len;
134
}
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;
140
}
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';
145
}
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;
161
}
162
}
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;
174
}
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;
180
}
181
}
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;
188
}
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;
198
}
199
}
200
}
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;
209
}
210
#endif /* #ifdef CHECKBLANKS */
211
}
212
213
214
void checkit()
215
{
216
int i,k,cmtcount,numsread,ffrighttoleft,have_layout,layout;
217
char magicnum[5],cha;
218
long oldord,theord;
219
int tmpcnt,len;
220
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;
230
}
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);
236
}
237
}
238
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;
245
}
246
}
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;
252
}
253
if (strcmp(magicnum,FONTFILEMAGICNUMBER)) {
254
printf("%s: ERROR- Incorrect magic number.\n",fontfilename);
255
ec++;
256
weregone(0); if (gone) return;
257
}
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;
263
}
264
fileline=(char*)my_alloc(sizeof(char)*(1001));
265
if (fgets(fileline,1001,fontfile)==NULL) {
266
fileline[0] = '\0';
267
}
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 */
270
}
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;
278
}
279
if (numsread<9) {
280
spectagcnt=-1;
281
}
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;
287
}
288
if (!strchr(posshardblanks,hardblank)) {
289
printf("%s: Warning- Unusual hardblank.\n",fontfilename);
290
wc++;
291
weregone(0); if (gone) return;
292
}
293
if (charheight<1) {
294
printf("%s: ERROR (fatal)- charheight not positive.\n",fontfilename);
295
ec++;
296
weregone(1); if (gone) return;
297
}
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;
302
}
303
if (maxlen<1) {
304
printf("%s: ERROR (fatal)- maxlen not positive.\n",fontfilename);
305
ec++;
306
weregone(1); if (gone) return;
307
}
308
if (old_layout<-1) {
309
printf("%s: ERROR- old_layout < -1.\n",fontfilename);
310
ec++;
311
weregone(0); if (gone) return;
312
}
313
if (old_layout>63) {
314
printf("%s: ERROR- old_layout > 63.\n",fontfilename);
315
ec++;
316
weregone(0); if (gone) return;
317
}
318
if (have_layout && layout<0) {
319
printf("%s: ERROR- layout < 0.\n", fontfilename);
320
ec++;
321
weregone(0); if (gone) return;
322
}
323
if (have_layout &&layout>32767) {
324
printf("%s: ERROR- layout > 32767.\n", fontfilename);
325
ec++;
326
weregone(0); if (gone) return;
327
}
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;
333
}
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;
340
}
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;
347
}
348
if (cmtcount<0) {
349
printf("%s: ERROR- cmt_count is negative.\n",fontfilename);
350
ec++;
351
weregone(0); if (gone) return;
352
}
353
if (ffrighttoleft<0 || ffrighttoleft>1) {
354
printf("%s: ERROR- rtol out of bounds.\n",fontfilename);
355
ec++;
356
weregone(0); if (gone) return;
357
}
358
359
for (i=1;i<=cmtcount;i++) {
360
while(k=getc(fontfile),k!='\n'&&k!=EOF) ; /* Advance to end of line */
361
}
362
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;
369
}
370
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;
377
}
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;
383
}
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;
391
}
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;
401
}
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;
408
}
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;
417
}
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;
426
}
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;
435
}
436
oldord=theord;
437
readchar();
438
if (gone) return;
439
}
440
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;
446
}
447
448
if (fontfile!=stdin) fclose(fontfile);
449
450
weregone(1); if (gone) return;
451
}
452
453
454
int main(argc,argv)
455
int argc;
456
char *argv[];
457
{
458
int arg;
459
460
if ((myname=strrchr(argv[0],'/'))!=NULL) {
461
myname++;
462
}
463
else {
464
myname = argv[0];
465
}
466
if (argc<2) {
467
usageerr();
468
}
469
for (arg=1;arg<argc;arg++) {
470
fontfilename=argv[arg];
471
fileline=NULL;
472
checkit();
473
if (fileline!=NULL) free(fileline);
474
}
475
return 0;
476
}
477
478