My Project
Toggle main menu visibility
Loading...
Searching...
No Matches
Singular
checklibs.c
Go to the documentation of this file.
1
#include <stdio.h>
2
#include <string.h>
3
#include <ctype.h>
4
5
6
#define NUM_PROC 200
7
#define LINE_LEN 200
8
#define RECOMMENDED_LEN 100
9
FILE *
f
;
10
int
trailing_spaces
=0;
11
int
tabs
=0;
12
int
verylong_lines
=0;
13
int
lines
=0;
14
unsigned
char
buf
[
LINE_LEN
];
15
int
proc_cnt
=0;
16
unsigned
char
*
proc
[
NUM_PROC
];
17
unsigned
char
have_doc
[
NUM_PROC
];
18
unsigned
char
have_example
[
NUM_PROC
];
19
unsigned
char
proc_found
[
NUM_PROC
];
20
int
non_ascii
=0;
21
int
non_ascii_line
=0;
22
int
star_nl
=0;
23
int
footer
=0;
24
int
header
=0;
25
int
crlf
=0;
26
int
proc_help_lines
=0;
27
int
proc_help_texinfo
=0;
28
29
void
get_next
()
30
{
31
int
i
;
32
memset(
buf
,0,
LINE_LEN
);
33
fgets(
buf
,
LINE_LEN
,
f
);
34
lines
++;
35
if
(
buf
[0]!=
'\0'
)
36
{
37
int
non_ascii_found=0;
38
if
(strchr(
buf
,
'\r'
)!=
NULL
)
crlf
++;
39
if
((
buf
[
LINE_LEN
-1]!=
'\0'
)||(strlen(
buf
)>
RECOMMENDED_LEN
))
40
{
41
if
(
verylong_lines
==0) printf(
"warning: very long line (%d):\n%s\n"
,
lines
,
buf
);
42
verylong_lines
++;
43
}
44
if
((strstr(
buf
,
" \n"
)!=
NULL
)||(strstr(
buf
,
" \r\n"
)!=
NULL
))
trailing_spaces
++;
45
if
(strchr(
buf
,
'\t'
)!=
NULL
)
tabs
++;
46
47
for
(
i
=0;(
i
<
LINE_LEN
) && (
buf
[
i
]!=
'\0'
);
i
++)
48
{
49
if
(
buf
[
i
]>=127) { non_ascii_found=1;
non_ascii
++;
non_ascii_line
=
lines
;
break
; }
50
}
51
if
(non_ascii_found) printf(
"non-ascii:>>%s<<\n"
,
buf
);
52
if
(
footer
==0)
/* we are still in the header */
53
{
54
if
(strstr(
buf
,
"@*"
)!=
NULL
)
star_nl
++;
55
}
56
}
57
}
58
59
void
scan_proc
(
int
*
l
)
60
{
61
unsigned
char
*
p
;
62
while
(1)
63
{
64
get_next
(); (*l)++;
65
if
(((
p
=strchr(
buf
,
'('
))!=
NULL
)&&(isalnum(*(--
p
))||(*
p
==
'_'
)))
66
{
67
unsigned
char
*
s
=
buf
;
68
while
(*
s
==
' '
)
s
++;
69
p
++; (*p)=
'\0'
;
70
if
((((
int
)(
long
)(
s
-
buf
))>10)||(strchr(
s
,
' '
)!=
NULL
))
71
{
72
printf(
"warning: probably not a proc ? (%s)\n"
,
s
);
73
}
74
else
75
{
76
if
(strlen(
s
)<4)
77
printf(
"error: minimal length of a procedure name is 4: %s\n"
,
s
);
78
proc
[
proc_cnt
]=
strdup
(
s
);
proc_cnt
++;
79
}
80
}
81
else
if
(strstr(
buf
,
"LIB "
)!=
NULL
)
break
;
82
else
if
(strstr(
buf
,
"LIB\""
)!=
NULL
)
break
;
83
else
if
(strstr(
buf
,
"proc "
)!=
NULL
)
break
;
84
else
if
(strncmp(
buf
,
"\";"
,2)==0)
break
;
/* poor mans end-of-info*/
85
else
if
((
p
=strstr(
buf
,
":"
))!=
NULL
)
86
{
/* handles all capital letters + : */
87
/* SEE ALSO, KEYWORDS, NOTE, ... */
88
int
ch;
89
unsigned
char
*
pp
=
buf
;
90
while
((*
pp
==
' '
)||(*
pp
==
'\t'
))
pp
++;
91
ch=strspn(
pp
,
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
);
92
if
((ch>1)||(
pp
+ch==
p
))
93
{
94
break
;
95
}
96
}
97
}
98
if
(
proc_cnt
==0)
99
printf(
"warning: no proc found in the section PROCEDURES ?\n"
);
100
printf(
"\n# proc mentioned in the header: %d\n"
,
proc_cnt
);
101
}
102
103
void
scan_keywords
(
int
*
l
)
104
{
105
/* the main problem with KEYWORDS: seperator between is ;,
106
* but it MUST NOT appear at the end */
107
unsigned
char
*
p
;
108
while
(!feof(
f
))
109
{
110
p
=strrchr(
buf
,
';'
);
/* the last ; in the line*/
111
if
(
p
==
NULL
) {
get_next
(); (*l)++;
return
; }
112
while
(*
p
==
' '
)
p
++;
113
if
(isalpha(*
p
)) {
get_next
(); (*l)++;
return
; }
114
if
(*
p
==
'\0'
) {
get_next
(); (*l)++; }
115
else
if
(strstr(
buf
,
"LIB "
)!=
NULL
)
break
;
116
else
if
(strstr(
buf
,
"LIB\""
)!=
NULL
)
break
;
117
else
if
(strstr(
buf
,
"proc "
)!=
NULL
)
break
;
118
else
if
(strncmp(
buf
,
"\";"
,2)==0)
break
;
/* poor mans end-of-info*/
119
else
if
((
p
=strstr(
buf
,
":"
))!=
NULL
)
120
{
/* handles all capital letters + : */
121
/* SEE ALSO, KEYWORDS, NOTE, ... */
122
int
ch;
123
unsigned
char
*
pp
=
buf
;
124
while
((*
pp
==
' '
)||(*
pp
==
'\t'
))
pp
++;
125
ch=strspn(
pp
,
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
);
126
if
((ch>1)||(
pp
+ch==
p
))
127
{
128
break
;
129
}
130
}
131
}
132
printf(
"error: seperate keywords by ; but do not have ; after the last keyword\n"
);
133
}
134
void
scan_proc_help
(
const
char
*
s
)
135
{
136
while
(!feof(
f
))
137
{
138
proc_help_lines
++;
139
if
(strstr(
buf
,
"\";"
)!=
NULL
)
break
;
140
if
(
buf
[0]==
'{'
)
break
;
141
if
(strstr(
buf
,
"@"
)!=
NULL
)
142
{
143
proc_help_texinfo
++;
144
buf
[strlen(
buf
)-1]=
'\0'
;
145
strcat(
buf
,
"<<\n"
);
146
printf(
"texinfo in proc help(%s): >>%s"
,
s
,
buf
);
147
}
148
get_next
();
149
}
150
}
151
void
scan_info
(
int
*
l
)
152
{
153
int
have_LIBRARY=0;
154
int
have_AUTHORS=0;
155
int
have_PROCEDURES=0;
156
int
have_SEEALSO=0;
157
int
have_KEYWORDS=0;
158
int
have_OVERVIEW=0;
159
int
have_NOTE=0;
160
int
have_other=0;
161
int
texinfo=0;
162
unsigned
char
*
p
;
163
164
while
(!feof(
f
))
165
{
166
if
(strstr(
buf
,
"LIBRARY: "
)!=
NULL
)
167
{
168
have_LIBRARY++;
169
/* musrt be first*/
170
if
(have_other+have_AUTHORS+have_PROCEDURES+have_KEYWORDS+have_SEEALSO!=0)
171
printf(
"error: LIBRARY: must be the first section in info\n"
);
172
}
173
else
if
(strstr(
buf
,
"NOTE:"
)!=
NULL
)
174
{
175
if
(have_PROCEDURES!=0)
176
printf(
"error: only KEYWORDS/SEE ALSO may follow PROCEDURES\n"
);
177
have_NOTE++;
178
}
179
else
if
(strstr(
buf
,
"OVERVIEW:"
)!=
NULL
)
180
{
181
have_OVERVIEW++;
182
if
(have_PROCEDURES!=0)
183
printf(
"error: only KEYWORDS/SEE ALSO may follow PROCEDURES\n"
);
184
}
185
else
if
(strstr(
buf
,
"KEYWORDS: "
)!=
NULL
)
186
{
187
have_KEYWORDS++;
188
}
189
else
if
(strstr(
buf
,
"SEE ALSO: "
)!=
NULL
)
190
{
191
have_SEEALSO++;
192
}
193
else
if
((strstr(
buf
,
"AUTHORS: "
)!=
NULL
)
194
||(strstr(
buf
,
"AUTHOR: "
)!=
NULL
))
195
{
196
have_AUTHORS++;
197
if
(have_PROCEDURES!=0)
198
printf(
"error: only KEYWORDS/SEE ALSO may follow PROCEDURES\n"
);
199
}
200
else
if
((
p
=strstr(
buf
,
"PROCEDURES"
))!=
NULL
)
201
{
202
unsigned
char
*
pp
=
buf
;
203
while
(
pp
!=
p
)
204
{
205
if
((*
pp
!=
' '
)&&(*
pp
!=
'\t'
))
break
;
206
pp
++;
207
}
208
if
(
p
==
pp
)
209
{
210
have_PROCEDURES++;
211
scan_proc
(
l
);
212
continue
;
213
}
214
else
215
{
216
printf(
"error: unknown section in library header: %s"
,
buf
);
217
have_other++;
218
}
219
}
220
else
if
((
p
=strstr(
buf
,
":"
))!=
NULL
)
221
{
222
int
ch;
223
unsigned
char
*
pp
=
buf
;
224
while
((*
pp
==
' '
)||(*
pp
==
'\t'
))
pp
++;
225
ch=strspn(
pp
,
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
);
226
if
((ch>1)||(
pp
+ch==
p
))
227
{
228
/* check for other allowed sections: REFERENCES*/
229
if
((ch!=10)||(strncmp(
pp
,
"REFERENCES"
,10)!=0))
230
{
231
printf(
"error: unknown section in library header: %s"
,
buf
);
232
have_other++;
233
}
234
if
(have_PROCEDURES!=0)
235
printf(
"error: only KEYWORDS/SEE ALSO may follow PROCEDURES\n"
);
236
}
237
}
238
else
if
(strncmp(
buf
,
"\";"
,2)==0)
goto
e_o_info;
/* poor mans end-of-info*/
239
else
240
{
241
p
=
buf
;
242
if
(strchr(
buf
,
'@'
)!=
NULL
)
243
{ texinfo++; printf(
"%s"
,
buf
); }
244
}
245
get_next
(); (*l)++;
246
}
247
e_o_info:
248
printf(
"\nSUMMARY OF THE HEADER:\n"
);
249
if
(have_LIBRARY!=1)
250
printf(
"error: missing/duplicate LIBRARY (%d lines found, should be 1)\n"
,have_LIBRARY);
251
if
(have_AUTHORS!=1)
252
printf(
"error: missing/duplicate AUTHOR/AUTHORS (%d lines found, should be 1)\n"
,have_AUTHORS);
253
if
(have_PROCEDURES!=1)
254
printf(
"error: missing/duplicate PROCEDURES (%d lines found, should be 1)\n"
,have_PROCEDURES);
255
if
(have_SEEALSO>1)
256
printf(
"error: duplicate SEE ALSO (%d lines found)\n"
,have_SEEALSO);
257
if
(have_KEYWORDS>1)
258
printf(
"error: duplicate KEYWORDS (%d lines found)\n"
,have_KEYWORDS);
259
if
(have_NOTE==1)
260
printf(
"hint: avoid NOTE: if not used for a library requirement\n"
);
261
else
if
(have_NOTE>1)
262
printf(
"error: duplicate NOTE (%d lines found)\n"
,have_NOTE);
263
if
((have_OVERVIEW==1)&&(
proc_cnt
<3))
264
printf(
"hint: avoid OVERVIEW: for small libraries\n"
);
265
else
if
(have_OVERVIEW>1)
266
printf(
"error: duplicate OVERVIEW (%d lines found)\n"
,have_OVERVIEW);
267
268
if
(have_other!=0)
269
printf(
"error: other header entries found (illegal ?) :%d lines found, should be 0\n"
,have_other);
270
if
((
star_nl
>0)&&(
star_nl
*10>=
header
))
271
{
272
printf(
"warning: %d forced line breaks in %d header lines: @* should be used very rarely!\n"
,
star_nl
,
header
);
273
}
274
if
(texinfo>0)
275
{
276
printf(
"warning: %d texinfo commands in %d header lines: should be used very rarely!\n"
,texinfo,
header
);
277
}
278
}
279
280
int
main
(
int
argc,
char
** argv)
281
{
282
int
have_version=0;
283
int
have_category=0;
284
int
have_info=0;
285
unsigned
char
*
p
;
286
287
memset(
proc
,0,
NUM_PROC
*
sizeof
(
char
*));
288
memset(
have_doc
,0,
NUM_PROC
);
289
memset(
have_example
,0,
NUM_PROC
);
290
memset(
proc_found
,0,
NUM_PROC
);
291
if
(argc==1)
292
{
293
f
=stdin;
294
}
295
else
296
{
297
if
(argc!=2) { printf(
"usage: %s lib-file\n"
,argv[0]);
return
1;}
298
printf(
"\n CHECKING LIBRARY %s\n\n"
,argv[1]);
299
f
=fopen(argv[1],
"r"
);
300
if
(
f
==
NULL
) { printf(
"cannot read %s\n"
,argv[1]);
return
2; }
301
}
302
303
buf
[0]=
'\0'
;
304
get_next
();
header
++;
305
if
(strncmp(
buf
,
"//"
,2)!=0) { printf(
"error: lib must start with //\n"
); }
306
else
{
get_next
();
header
++; }
307
/* pass 1: check header */
308
while
(1)
309
{
310
if
((
p
=strstr(
buf
,
"version="
))!=
NULL
)
311
{
312
unsigned
char
*
pp
=
buf
;
313
while
(
pp
!=
p
)
314
{
315
if
((*
pp
!=
' '
)&&(*
pp
!=
'\t'
))
break
;
316
pp
++;
317
}
318
if
(
p
=
pp
)
319
{
320
have_version++;
321
pp
=
p
+8;
322
while
((*
pp
)==
' '
)
pp
++;
323
/* syntax of version string: "version <filename> <version> <date> "
324
if (*pp)!='"')
325
printf("error: version string should ....");
326
*/
327
}
328
}
329
if
((
p
=strstr(
buf
,
"category="
))!=
NULL
)
330
{
331
unsigned
char
*
pp
=
buf
;
332
while
(
pp
!=
p
)
333
{
334
if
((*
pp
!=
' '
)&&(*
pp
!=
'\t'
))
break
;
335
pp
++;
336
}
337
if
(
p
=
pp
) have_category++;
338
}
339
if
((
p
=strstr(
buf
,
"info="
))!=
NULL
)
340
{
341
unsigned
char
*
pp
=
buf
;
342
while
(
pp
!=
p
)
343
{
344
if
((*
pp
!=
' '
)&&(*
pp
!=
'\t'
))
break
;
345
pp
++;
346
}
347
if
(
p
=
pp
) { have_info++;
scan_info
(&
header
); }
348
}
349
if
((
p
=strstr(
buf
,
"LIB\""
))!=
NULL
)
350
{
351
printf(
"error: use a space between LIB and \"\n"
);
352
if
(
p
!=
buf
)
353
{ printf(
"end of header ? LIB should be in col. 1:>>%s<<\n"
,
buf
); }
354
break
;
/* end of header */
355
}
356
if
((
p
=strstr(
buf
,
"LIB \""
))!=
NULL
)
357
{
358
if
(
p
!=
buf
)
359
{ printf(
"end of header ? LIB should be in col. 1:>>%s<<\n"
,
buf
); }
360
break
;
/* end of header */
361
}
362
if
((
p
=strstr(
buf
,
"proc "
))!=
NULL
)
363
{
364
if
((
p
!=
buf
)&&(strncmp(
buf
,
"static proc "
,12)!=0))
365
{ printf(
"end of header ? proc should be in col. 1:>>%s<<\n"
,
buf
); }
366
break
;
/* end of header */
367
}
368
get_next
();
header
++;
369
if
(feof(
f
))
break
;
370
}
371
printf(
"header parsed: %d lines of %s\n\n"
,
header
,argv[1]);
372
/* part 2: procs */
373
while
(!feof(
f
))
374
{
375
if
((strstr(
buf
,
"static"
)==(
char
*)
buf
) && (strstr(
buf
,
"proc"
)==
NULL
))
376
{
377
printf(
"error: 'static' without 'proc' found\n"
);
378
get_next
();
379
}
380
if
(((
p
=strstr(
buf
,
"proc "
))!=
NULL
)
381
&&(strncmp(
buf
,
"static proc "
,12)!=0))
382
{
383
unsigned
char
*
pp
=
buf
;
384
int
i
;
385
while
(*
pp
==
' '
)
pp
++;
386
if
((
pp
!=
buf
)&&(
pp
==
p
))
387
{
388
printf(
"warning: proc should be in col. 1: line %d:%s"
,
lines
,
buf
);
389
}
390
else
if
(
pp
!=
p
)
391
{
392
footer
++;
get_next
();
continue
;
/* this is not a proc start*/
393
}
394
p
+=5;
/* skip proc+blank*/
395
while
(*
p
==
' '
)
p
++;
396
pp
=
p
;
397
while
(isalnum(*
p
)||(*
p
==
'_'
))
p
++;
398
*
p
=
'\0'
;
399
for
(
i
=
proc_cnt
-1;
i
>=0;
i
--)
400
{
401
if
(strcmp(
proc
[
i
],
pp
)==0)
break
;
402
}
403
if
(
i
<0)
404
{
405
printf(
"hint: global proc %s not found in header\n"
,
pp
);
406
footer
++;
get_next
();
407
}
408
else
409
{
410
proc_found
[
i
]=1;
411
footer
++;
get_next
();
/* doc should start at next line */
412
p
=
buf
;
413
while
(*
p
==
' '
)
p
++;
414
if
(*
p
==
'"'
)
have_doc
[
i
]=1;
415
/* scan proc help*/
416
scan_proc_help
(
proc
[
i
]);
417
/* serach for example */
418
while
(!feof(
f
))
419
{
420
if
(strncmp(
buf
,
"proc "
,5)==0)
break
;
421
if
(strncmp(
buf
,
"static proc "
,12)==0)
break
;
422
if
(strncmp(
buf
,
"example"
,7)==0)
423
{
424
have_example
[
i
]=1;
425
break
;
426
}
427
footer
++;
get_next
();
428
}
429
}
430
}
431
else
{
get_next
();
footer
++;}
432
}
433
{
434
int
i
;
435
for
(
i
=
proc_cnt
-1;
i
>=0;
i
--)
436
{
437
if
(
proc_found
[
i
]==0) printf(
"proc %s not found\n"
,
proc
[
i
]);
438
else
439
{
440
if
(
have_doc
[
i
]==0) printf(
"proc %s has no documentation\n"
,
proc
[
i
]);
441
if
(
have_example
[
i
]==0) printf(
"proc %s has no example (or it does not start in col. 1)\n"
,
proc
[
i
]);
442
}
443
}
444
}
445
/* part 3: summary*/
446
printf(
"\nproc part parsed: %d lines of %s\n"
,
footer
,argv[1]);
447
if
(have_version!=1) printf(
"version missing/duplicate (%d)\n"
,have_version);
448
if
(have_category!=1) printf(
"category missing/duplicate (%d)\n"
,have_category);
449
if
(have_info!=1) printf(
"info missing/duplicate (%d)\n"
,have_info);
450
451
printf(
"\nGENERAL SUMMARY:\n"
);
452
if
(
tabs
!=0) printf(
"warning: lib should not contain tabs, >=%d found\n"
,
tabs
);
453
if
(
trailing_spaces
!=0) printf(
"hint: lib should not contain trailing_spaces, >=%d found\n"
,
trailing_spaces
);
454
if
(
verylong_lines
!=0) printf(
"hint: lib should not contain very long lines, >=%d found\n"
,
verylong_lines
);
455
if
(
non_ascii
>0)
456
printf(
"error: lib should not contain non-ascii characters, %d found, last in line %d\n"
,
non_ascii
,
non_ascii_line
);
457
if
(
crlf
>=
lines
-1)
458
{
459
printf(
"warning: DOS format (%d)\n"
,
crlf
);
460
}
461
else
if
(
crlf
>0)
462
{
463
printf(
"error: some lines are in DOS format, some not (%d/%d)\n"
,
crlf
,
lines
);
464
}
465
printf(
"%d lines parsed\n"
,
lines
);
466
printf(
"%d proc found in header\n"
,
proc_cnt
);
467
printf(
"%d lines found in proc help\n"
,
proc_help_lines
);
468
printf(
"%d lines found in proc help with texinfo commands (should be very small)\n"
,
proc_help_texinfo
);
469
fclose(
f
);
470
return
0;
471
}
pp
CanonicalForm FACTORY_PUBLIC pp(const CanonicalForm &)
CanonicalForm pp ( const CanonicalForm & f ).
Definition
cf_gcd.cc:676
l
int l
Definition
cfEzgcd.cc:100
i
int i
Definition
cfEzgcd.cc:132
p
int p
Definition
cfModGcd.cc:4086
scan_proc_help
void scan_proc_help(const char *s)
Definition
checklibs.c:134
scan_info
void scan_info(int *l)
Definition
checklibs.c:151
proc_found
unsigned char proc_found[NUM_PROC]
Definition
checklibs.c:19
trailing_spaces
int trailing_spaces
Definition
checklibs.c:10
f
FILE * f
Definition
checklibs.c:9
proc_help_texinfo
int proc_help_texinfo
Definition
checklibs.c:27
LINE_LEN
#define LINE_LEN
Definition
checklibs.c:7
scan_keywords
void scan_keywords(int *l)
Definition
checklibs.c:103
RECOMMENDED_LEN
#define RECOMMENDED_LEN
Definition
checklibs.c:8
non_ascii_line
int non_ascii_line
Definition
checklibs.c:21
have_doc
unsigned char have_doc[NUM_PROC]
Definition
checklibs.c:17
verylong_lines
int verylong_lines
Definition
checklibs.c:12
have_example
unsigned char have_example[NUM_PROC]
Definition
checklibs.c:18
get_next
void get_next()
Definition
checklibs.c:29
non_ascii
int non_ascii
Definition
checklibs.c:20
lines
int lines
Definition
checklibs.c:13
crlf
int crlf
Definition
checklibs.c:25
proc_cnt
int proc_cnt
Definition
checklibs.c:15
proc_help_lines
int proc_help_lines
Definition
checklibs.c:26
scan_proc
void scan_proc(int *l)
Definition
checklibs.c:59
NUM_PROC
#define NUM_PROC
Definition
checklibs.c:6
footer
int footer
Definition
checklibs.c:23
star_nl
int star_nl
Definition
checklibs.c:22
tabs
int tabs
Definition
checklibs.c:11
proc
unsigned char * proc[NUM_PROC]
Definition
checklibs.c:16
s
const CanonicalForm int s
Definition
facAbsFact.cc:51
header
#define header
Definition
libparse.cc:1228
strdup
#define strdup
Definition
omAllocFunc.c:18
NULL
#define NULL
Definition
omList.c:12
main
int main()
Definition
p_Procs_Generate.cc:219
buf
int status int void * buf
Definition
si_signals.h:69
Generated on
for My Project by
doxygen 1.17.0
for
Singular