]>
Commit | Line | Data |
---|---|---|
da1067a9 UD |
1 | #! /usr/bin/perl |
2 | ||
3 | $CC = "gcc"; | |
52cf7d34 | 4 | $CFLAGS = "-I. '-D__attribute__(x)=' -D_XOPEN_SOURCE=500"; |
da1067a9 UD |
5 | |
6 | # List of the headers we are testing. | |
0ed99ce4 UD |
7 | @headers = ("wordexp.h", "wctype.h", "wchar.h", "varargs.h", "utmpx.h", |
8 | "utime.h", "unistd.h", "ulimit.h", "ucontext.h", "time.h", | |
9 | "termios.h", "tar.h", "sys/wait.h", "sys/uio.h", "sys/types.h", | |
10 | "sys/times.h", "sys/timeb.h", "sys/time.h", "sys/statvfs.h", | |
11 | "sys/stat.h", "sys/shm.h", "sys/sem.h", "sys/resource.h", | |
12 | "sys/msg.h", "sys/mman.h", "sys/ipc.h", "syslog.h", | |
bba09d23 | 13 | "stropts.h", "strings.h", "string.h", "stdlib.h", "stdio.h", |
8ce9ea0c UD |
14 | "stddef.h", "stdarg.h", "signal.h", "setjmp.h", "semaphore.h", |
15 | "search.h", "sched.h", "regex.h", "pwd.h", "pthread.h", | |
7f42d3dd | 16 | "poll.h", "nl_types.h", "ndbm.h", "mqueue.h", "monetary.h", |
7b5fd91d | 17 | "math.h", "locale.h", "libgen.h", "langinfo.h", "iso646.h", |
52cf7d34 UD |
18 | "inttypes.h", "iconv.h", "grp.h", "glob.h", "ftw.h", "fnmatch.h", |
19 | "fmtmsg.h", "float.h", "fcntl.h", "errno.h", "dlfcn.h", "dirent.h", | |
da1067a9 UD |
20 | "ctype.h", "cpio.h", "assert.h", "aio.h"); |
21 | ||
bba09d23 | 22 | # These are the ISO C99 keywords. |
da1067a9 UD |
23 | @keywords = ('auto', 'break', 'case', 'char', 'const', 'continue', 'default', |
24 | 'do', 'double', 'else', 'enum', 'extern', 'float', 'for', 'goto', | |
25 | 'if', 'inline', 'int', 'long', 'register', 'restrict', 'return', | |
26 | 'short', 'signed', 'sizeof', 'static', 'struct', 'switch', | |
27 | 'typedef', 'union', 'unsigned', 'void', 'volatile', 'while'); | |
28 | ||
77faa354 UD |
29 | # Some headers need a bit more attention. |
30 | $mustprepend{'regex.h'} = "#include <sys/types.h>\n"; | |
31 | ||
da1067a9 UD |
32 | # Make an hash table from this information. |
33 | while ($#keywords) { | |
34 | $iskeyword{pop (@keywords)} = 1; | |
35 | } | |
36 | ||
37 | $tmpdir = "/tmp"; | |
38 | ||
39 | $verbose = 1; | |
40 | ||
41 | $total = 0; | |
42 | $skipped = 0; | |
43 | $errors = 0; | |
44 | ||
45 | #$dialect = "ISO"; | |
46 | #$dialect = "POSIX"; | |
47 | #$dialect = "XPG3"; | |
48 | #$dialect = "XPG4"; | |
49 | $dialect = "UNIX98"; | |
50 | ||
51 | ||
52 | sub poorfnmatch { | |
53 | my($pattern, $string) = @_; | |
54 | my($strlen) = length ($string); | |
55 | my($res); | |
56 | ||
57 | if (substr ($pattern, 0, 1) eq '*') { | |
58 | my($patlen) = length ($pattern) - 1; | |
59 | $res = ($strlen >= $patlen | |
60 | && substr ($pattern, -$patlen, $patlen) eq substr ($string, -$patlen, $patlen)); | |
61 | } elsif (substr ($pattern, -1, 1) eq '*') { | |
62 | my($patlen) = length ($pattern) - 1; | |
63 | $res = ($strlen >= $patlen | |
64 | && substr ($pattern, 0, $patlen) eq substr ($string, 0, $patlen)); | |
65 | } else { | |
66 | $res = $pattern eq $string; | |
67 | } | |
68 | return $res; | |
69 | } | |
70 | ||
71 | ||
72 | sub compiletest | |
73 | { | |
74 | my($fnamebase, $msg, $errmsg, $skip) = @_; | |
75 | my($result) = $skip; | |
76 | my($printlog) = 0; | |
77 | ||
78 | ++$total; | |
79 | printf (" $msg..."); | |
80 | ||
81 | if ($skip != 0) { | |
82 | ++$skipped; | |
83 | printf (" SKIP\n"); | |
84 | } else { | |
85 | $ret = system "$CC $CFLAGS -c $fnamebase.c -o $fnamebase.o > $fnamebase.out 2>&1"; | |
86 | if ($ret != 0) { | |
87 | printf (" FAIL\n"); | |
88 | if ($verbose != 0) { | |
89 | printf (" $errmsg Compiler message:\n"); | |
90 | $printlog = 1; | |
91 | } | |
92 | ++$errors; | |
93 | $result = 1; | |
94 | } else { | |
95 | printf (" OK\n"); | |
96 | if ($verbose > 1 && -s "$fnamebase.out") { | |
97 | # We print all warnings issued. | |
98 | $printlog = 1; | |
99 | } | |
100 | } | |
101 | if ($printlog != 0) { | |
102 | printf (" " . "-" x 71 . "\n"); | |
103 | open (MESSAGE, "< $fnamebase.out"); | |
104 | while (<MESSAGE>) { | |
105 | printf (" %s", $_); | |
106 | } | |
107 | close (MESSAGE); | |
108 | printf (" " . "-" x 71 . "\n"); | |
109 | } | |
110 | } | |
111 | unlink "$fnamebase.c"; | |
112 | unlink "$fnamebase.o"; | |
113 | unlink "$fnamebase.out"; | |
114 | ||
115 | $result; | |
116 | } | |
117 | ||
118 | ||
119 | sub runtest | |
120 | { | |
121 | my($fnamebase, $msg, $errmsg, $skip) = @_; | |
122 | my($result) = $skip; | |
123 | my($printlog) = 0; | |
124 | ||
125 | ++$total; | |
126 | printf (" $msg..."); | |
127 | ||
128 | if ($skip != 0) { | |
129 | ++$skipped; | |
130 | printf (" SKIP\n"); | |
131 | } else { | |
132 | $ret = system "$CC $CFLAGS -o $fnamebase $fnamebase.c > $fnamebase.out 2>&1"; | |
133 | if ($ret != 0) { | |
134 | printf (" FAIL\n"); | |
135 | if ($verbose != 0) { | |
136 | printf (" $errmsg Compiler message:\n"); | |
137 | $printlog = 1; | |
138 | } | |
139 | ++$errors; | |
140 | $result = 1; | |
141 | } else { | |
142 | # Now run the program. If the exit code is not zero something is wrong. | |
143 | $result = system "$fnamebase > $fnamebase.out2 2>&1"; | |
144 | if ($result == 0) { | |
145 | printf (" OK\n"); | |
146 | if ($verbose > 1 && -s "$fnamebase.out") { | |
147 | # We print all warnings issued. | |
148 | $printlog = 1; | |
149 | system "cat $fnamebase.out2 >> $fnamebase.out"; | |
150 | } | |
151 | } else { | |
152 | printf (" FAIL\n"); | |
153 | $printlog = 1; | |
154 | unlink "$fnamebase.out"; | |
155 | rename "$fnamebase.out2", "$fnamebase.out"; | |
156 | } | |
157 | } | |
158 | if ($printlog != 0) { | |
159 | printf (" " . "-" x 71 . "\n"); | |
160 | open (MESSAGE, "< $fnamebase.out"); | |
161 | while (<MESSAGE>) { | |
162 | printf (" %s", $_); | |
163 | } | |
164 | close (MESSAGE); | |
165 | printf (" " . "-" x 71 . "\n"); | |
166 | } | |
167 | } | |
168 | unlink "$fnamebase"; | |
169 | unlink "$fnamebase.c"; | |
170 | unlink "$fnamebase.o"; | |
171 | unlink "$fnamebase.out"; | |
172 | unlink "$fnamebase.out2"; | |
173 | ||
174 | $result; | |
175 | } | |
176 | ||
177 | ||
178 | sub newtoken { | |
179 | my($token, $nerrors, @allow) = @_; | |
180 | my($idx); | |
181 | ||
8ce9ea0c UD |
182 | if ($token =~ /^[0-9_]/ || $iskeyword{$token}) { |
183 | return $nerrors; | |
184 | } | |
185 | ||
da1067a9 | 186 | for ($idx = 0; $idx <= $#allow; ++$idx) { |
8ce9ea0c | 187 | if (poorfnmatch ($allow[$idx], $token)) { |
da1067a9 UD |
188 | return $nerrors; |
189 | } | |
190 | } | |
191 | ||
192 | ++$nerrors; | |
193 | if ($nerrors == 1) { | |
194 | printf ("FAIL\n " . "-" x 72 . "\n"); | |
195 | } | |
196 | printf (" Namespace violation: \"%s\"\n", $token); | |
197 | return $nerrors; | |
198 | } | |
199 | ||
200 | ||
201 | sub checknamespace { | |
202 | my($h, $fnamebase, @allow) = @_; | |
203 | my($nerrors) = 0; | |
204 | ||
205 | ++$total; | |
206 | ||
207 | # Generate a program to get the contents of this header. | |
208 | open (TESTFILE, ">$fnamebase.c"); | |
209 | print TESTFILE "#include <$h>\n"; | |
210 | close (TESTFILE); | |
211 | ||
212 | open (CONTENT, "$CC $CFLAGS -E $fnamebase.c -Wp,-dN | sed -e '/^# [1-9]/d' -e '/^[[:space:]]*\$/d' |"); | |
213 | while (<CONTENT>) { | |
214 | chop; | |
215 | if (/^#define (.*)/) { | |
216 | $nerrors = newtoken ($1, $nerrors, @allow); | |
217 | } else { | |
218 | # We have to tokenize the line. | |
219 | my($str) = $_; | |
220 | my($index) = 0; | |
221 | my($len) = length ($str); | |
222 | ||
223 | foreach $token (split(/[^a-zA-Z0-9_]/, $str)) { | |
224 | if ($token ne "") { | |
225 | $nerrors = newtoken ($token, $nerrors, @allow); | |
226 | } | |
227 | } | |
228 | } | |
229 | } | |
230 | close (CONTENT); | |
231 | unlink "$fnamebase.c"; | |
232 | if ($nerrors != 0) { | |
233 | printf (" " . "-" x 72 . "\n"); | |
234 | ++$errors; | |
235 | } else { | |
236 | printf ("OK\n"); | |
237 | } | |
238 | } | |
239 | ||
240 | ||
241 | while ($#headers >= 0) { | |
242 | my($h) = pop (@headers); | |
bba09d23 UD |
243 | my($hf) = $h; |
244 | $hf =~ s|/|-|; | |
245 | my($fnamebase) = "$tmpdir/$hf-test"; | |
da1067a9 UD |
246 | my($missing); |
247 | my(@allow) = (); | |
0ed99ce4 | 248 | my(@allowheader) = (); |
77faa354 | 249 | my($prepend) = $mustprepend{$h}; |
da1067a9 UD |
250 | |
251 | printf ("Testing <$h>\n"); | |
252 | printf ("----------" . "-" x length ($h) . "\n"); | |
253 | ||
254 | # Generate a program to test for the availability of this header. | |
255 | open (TESTFILE, ">$fnamebase.c"); | |
77faa354 | 256 | print TESTFILE "$prepend"; |
da1067a9 UD |
257 | print TESTFILE "#include <$h>\n"; |
258 | close (TESTFILE); | |
259 | ||
260 | $missing = compiletest ($fnamebase, "Checking whether <$h> is available", | |
261 | "Header <$h> not available", 0); | |
262 | ||
263 | printf ("\n"); | |
264 | ||
265 | open (CONTROL, "$CC -E -D$dialect - < data/$h-data |"); | |
266 | control: while (<CONTROL>) { | |
267 | chop; | |
268 | next control if (/^#/); | |
269 | next control if (/^[ ]*$/); | |
270 | ||
271 | if (/^element *({([^}]*)}|([^ ]*)) *({([^}]*)}|([^ ]*)) *([A-Za-z0-9_]*) *(.*)/) { | |
272 | my($struct) = "$2$3"; | |
273 | my($type) = "$5$6"; | |
274 | my($member) = "$7"; | |
275 | my($rest) = "$8"; | |
276 | my($res) = $missing; | |
277 | ||
278 | # Remember that this name is allowed. | |
279 | push @allow, $member; | |
280 | ||
281 | # Generate a program to test for the availability of this member. | |
282 | open (TESTFILE, ">$fnamebase.c"); | |
77faa354 | 283 | print TESTFILE "$prepend"; |
da1067a9 UD |
284 | print TESTFILE "#include <$h>\n"; |
285 | print TESTFILE "$struct a;\n"; | |
286 | print TESTFILE "$struct b;\n"; | |
287 | print TESTFILE "extern void xyzzy (__typeof__ (&b.$member), __typeof__ (&a.$member), unsigned);\n"; | |
288 | print TESTFILE "void foobarbaz (void) {\n"; | |
289 | print TESTFILE " xyzzy (&a.$member, &b.$member, sizeof (a.$member));\n"; | |
290 | print TESTFILE "}\n"; | |
291 | close (TESTFILE); | |
292 | ||
293 | $res = compiletest ($fnamebase, "Testing for member $member", | |
294 | "Member \"$member\" not available.", $res); | |
295 | ||
296 | ||
297 | # Test the types of the members. | |
298 | open (TESTFILE, ">$fnamebase.c"); | |
77faa354 | 299 | print TESTFILE "$prepend"; |
da1067a9 UD |
300 | print TESTFILE "#include <$h>\n"; |
301 | print TESTFILE "$struct a;\n"; | |
302 | print TESTFILE "extern $type b$rest;\n"; | |
303 | print TESTFILE "extern __typeof__ (a.$member) b;\n"; | |
304 | close (TESTFILE); | |
305 | ||
306 | compiletest ($fnamebase, "Testing for type of member $member", | |
307 | "Member \"$member\" does not have the correct type.", $res); | |
308 | } elsif (/^constant *([a-zA-Z0-9_]*) *([A-Za-z0-9_]*)?/) { | |
309 | my($const) = $1; | |
310 | my($value) = $2; | |
311 | my($res) = $missing; | |
312 | ||
313 | # Remember that this name is allowed. | |
314 | push @allow, $const; | |
315 | ||
316 | # Generate a program to test for the availability of this constant. | |
317 | open (TESTFILE, ">$fnamebase.c"); | |
77faa354 | 318 | print TESTFILE "$prepend"; |
da1067a9 UD |
319 | print TESTFILE "#include <$h>\n"; |
320 | print TESTFILE "__typeof__ ($const) a = $const;\n"; | |
321 | close (TESTFILE); | |
322 | ||
323 | $res = compiletest ($fnamebase, "Testing for constant $const", | |
324 | "Constant \"$const\" not available.", $res); | |
325 | ||
8ce9ea0c UD |
326 | if ($value ne "") { |
327 | # Generate a program to test for the value of this constant. | |
328 | open (TESTFILE, ">$fnamebase.c"); | |
329 | print TESTFILE "$prepend"; | |
330 | print TESTFILE "#include <$h>\n"; | |
331 | print TESTFILE "int main (void) { return $const != $value; }\n"; | |
332 | close (TESTFILE); | |
333 | ||
334 | $res = runtest ($fnamebase, "Testing for value of constant $const", | |
335 | "Constant \"$const\" has not the right value.", $res); | |
336 | } | |
337 | } elsif (/^typed-constant *([a-zA-Z0-9_]*) *({([^}]*)}|([^ ]*)) *([A-Za-z0-9_]*)?/) { | |
338 | my($const) = $1; | |
339 | my($type) = "$3$4"; | |
340 | my($value) = $5; | |
341 | my($res) = $missing; | |
342 | ||
343 | # Remember that this name is allowed. | |
344 | push @allow, $const; | |
345 | ||
346 | # Generate a program to test for the availability of this constant. | |
347 | open (TESTFILE, ">$fnamebase.c"); | |
348 | print TESTFILE "$prepend"; | |
349 | print TESTFILE "#include <$h>\n"; | |
350 | print TESTFILE "__typeof__ ($const) a = $const;\n"; | |
351 | close (TESTFILE); | |
352 | ||
353 | $res = compiletest ($fnamebase, "Testing for constant $const", | |
354 | "Constant \"$const\" not available.", $res); | |
355 | ||
356 | # Test the types of the members. | |
357 | open (TESTFILE, ">$fnamebase.c"); | |
358 | print TESTFILE "$prepend"; | |
359 | print TESTFILE "#include <$h>\n"; | |
360 | print TESTFILE "__typeof__ (($type) 0) a;\n"; | |
361 | print TESTFILE "extern __typeof__ ($const) a;\n"; | |
362 | close (TESTFILE); | |
363 | ||
364 | compiletest ($fnamebase, "Testing for type of constant $const", | |
365 | "Constant \"$const\" does not have the correct type.", | |
366 | $res); | |
367 | ||
da1067a9 UD |
368 | if ($value ne "") { |
369 | # Generate a program to test for the value of this constant. | |
370 | open (TESTFILE, ">$fnamebase.c"); | |
77faa354 | 371 | print TESTFILE "$prepend"; |
da1067a9 UD |
372 | print TESTFILE "#include <$h>\n"; |
373 | print TESTFILE "int main (void) { return $const != $value; }\n"; | |
374 | close (TESTFILE); | |
375 | ||
376 | $res = runtest ($fnamebase, "Testing for value of constant $const", | |
377 | "Constant \"$const\" has not the right value.", $res); | |
378 | } | |
379 | } elsif (/^type *({([^}]*)|([a-zA-Z0-9_]*))/) { | |
380 | my($type) = "$2$3"; | |
381 | ||
382 | # Remember that this name is allowed. | |
383 | if ($type =~ /^struct *(.*)/) { | |
384 | push @allow, $1; | |
385 | } elsif ($type =~ /^union *(.*)/) { | |
386 | push @allow, $1; | |
387 | } else { | |
388 | push @allow, $type; | |
389 | } | |
390 | ||
391 | # Remember that this name is allowed. | |
392 | push @allow, $type; | |
393 | ||
394 | # Generate a program to test for the availability of this constant. | |
395 | open (TESTFILE, ">$fnamebase.c"); | |
77faa354 | 396 | print TESTFILE "$prepend"; |
da1067a9 UD |
397 | print TESTFILE "#include <$h>\n"; |
398 | print TESTFILE "$type *a;\n"; | |
399 | close (TESTFILE); | |
400 | ||
401 | compiletest ($fnamebase, "Testing for type $type", | |
402 | "Type \"$type\" not available.", $missing); | |
8ce9ea0c UD |
403 | } elsif (/^function *({([^}]*)}|([a-zA-Z0-9_]*)) [(][*]([a-zA-Z0-9_]*) ([(].*[)])/) { |
404 | my($rettype) = "$2$3"; | |
405 | my($fname) = "$4"; | |
406 | my($args) = "$5"; | |
407 | my($res) = $missing; | |
408 | ||
409 | # Remember that this name is allowed. | |
410 | push @allow, $fname; | |
411 | ||
412 | # Generate a program to test for availability of this function. | |
413 | open (TESTFILE, ">$fnamebase.c"); | |
414 | print TESTFILE "$prepend"; | |
415 | print TESTFILE "#include <$h>\n"; | |
416 | # print TESTFILE "#undef $fname\n"; | |
417 | print TESTFILE "$rettype (*(*foobarbaz) $args = $fname;\n"; | |
418 | close (TESTFILE); | |
419 | ||
420 | $res = compiletest ($fnamebase, "Test availability of function $fname", | |
421 | "Function \"$fname\" is not available.", $res); | |
422 | ||
423 | # Generate a program to test for the type of this function. | |
424 | open (TESTFILE, ">$fnamebase.c"); | |
425 | print TESTFILE "$prepend"; | |
426 | print TESTFILE "#include <$h>\n"; | |
427 | # print TESTFILE "#undef $fname\n"; | |
428 | print TESTFILE "extern $rettype (*(*foobarbaz) $args;\n"; | |
429 | print TESTFILE "extern __typeof__ (&$fname) foobarbaz;\n"; | |
430 | close (TESTFILE); | |
431 | ||
432 | compiletest ($fnamebase, "Test for type of function $fname", | |
433 | "Function \"$fname\" has incorrect type.", $res); | |
434 | } elsif (/^function *({([^}]*)}|([a-zA-Z0-9_]*)) ([a-zA-Z0-9_]*) ([(].*[)])/) { | |
da1067a9 UD |
435 | my($rettype) = "$2$3"; |
436 | my($fname) = "$4"; | |
437 | my($args) = "$5"; | |
438 | my($res) = $missing; | |
439 | ||
440 | # Remember that this name is allowed. | |
441 | push @allow, $fname; | |
442 | ||
443 | # Generate a program to test for availability of this function. | |
444 | open (TESTFILE, ">$fnamebase.c"); | |
77faa354 | 445 | print TESTFILE "$prepend"; |
da1067a9 | 446 | print TESTFILE "#include <$h>\n"; |
52cf7d34 | 447 | # print TESTFILE "#undef $fname\n"; |
da1067a9 UD |
448 | print TESTFILE "$rettype (*foobarbaz) $args = $fname;\n"; |
449 | close (TESTFILE); | |
450 | ||
451 | $res = compiletest ($fnamebase, "Test availability of function $fname", | |
452 | "Function \"$fname\" is not available.", $res); | |
453 | ||
454 | # Generate a program to test for the type of this function. | |
455 | open (TESTFILE, ">$fnamebase.c"); | |
77faa354 | 456 | print TESTFILE "$prepend"; |
da1067a9 | 457 | print TESTFILE "#include <$h>\n"; |
52cf7d34 | 458 | # print TESTFILE "#undef $fname\n"; |
da1067a9 UD |
459 | print TESTFILE "extern $rettype (*foobarbaz) $args;\n"; |
460 | print TESTFILE "extern __typeof__ (&$fname) foobarbaz;\n"; | |
461 | close (TESTFILE); | |
462 | ||
8ce9ea0c UD |
463 | compiletest ($fnamebase, "Test for type of function $fname", |
464 | "Function \"$fname\" has incorrect type.", $res); | |
465 | } elsif (/^variable *({([^}]*)}|([a-zA-Z0-9_]*)) ([a-zA-Z0-9_]*)/) { | |
466 | my($type) = "$2$3"; | |
467 | my($vname) = "$4"; | |
468 | my($res) = $missing; | |
469 | ||
470 | # Remember that this name is allowed. | |
471 | push @allow, $vname; | |
472 | ||
473 | # Generate a program to test for availability of this function. | |
474 | open (TESTFILE, ">$fnamebase.c"); | |
475 | print TESTFILE "$prepend"; | |
476 | print TESTFILE "#include <$h>\n"; | |
477 | # print TESTFILE "#undef $fname\n"; | |
478 | print TESTFILE "$type *foobarbaz = &$vname;\n"; | |
479 | close (TESTFILE); | |
480 | ||
481 | $res = compiletest ($fnamebase, "Test availability of variable $vname", | |
482 | "Variable \"$vname\" is not available.", $res); | |
483 | ||
484 | # Generate a program to test for the type of this function. | |
485 | open (TESTFILE, ">$fnamebase.c"); | |
486 | print TESTFILE "$prepend"; | |
487 | print TESTFILE "#include <$h>\n"; | |
488 | # print TESTFILE "#undef $fname\n"; | |
489 | print TESTFILE "extern $type $vname;\n"; | |
490 | close (TESTFILE); | |
491 | ||
492 | compiletest ($fnamebase, "Test for type of variable $fname", | |
493 | "Variable \"$vname\" has incorrect type.", $res); | |
494 | } elsif (/^macro-function *({([^}]*)}|([a-zA-Z0-9_]*)) ([a-zA-Z0-9_]*) ([(].*[)])/) { | |
495 | my($rettype) = "$2$3"; | |
496 | my($fname) = "$4"; | |
497 | my($args) = "$5"; | |
498 | my($res) = $missing; | |
499 | ||
500 | # Remember that this name is allowed. | |
501 | push @allow, $fname; | |
502 | ||
503 | # Generate a program to test for availability of this function. | |
504 | open (TESTFILE, ">$fnamebase.c"); | |
505 | print TESTFILE "$prepend"; | |
506 | print TESTFILE "#include <$h>\n"; | |
507 | print TESTFILE "#ifndef $fname\n"; | |
508 | print TESTFILE "$rettype (*foobarbaz) $args = $fname;\n"; | |
509 | print TESTFILE "#endif\n"; | |
510 | close (TESTFILE); | |
511 | ||
512 | $res = compiletest ($fnamebase, "Test availability of function $fname", | |
513 | "Function \"$fname\" is not available.", $res); | |
514 | ||
515 | # Generate a program to test for the type of this function. | |
516 | open (TESTFILE, ">$fnamebase.c"); | |
517 | print TESTFILE "$prepend"; | |
518 | print TESTFILE "#include <$h>\n"; | |
519 | print TESTFILE "#ifndef $fname\n"; | |
520 | print TESTFILE "extern $rettype (*foobarbaz) $args;\n"; | |
521 | print TESTFILE "extern __typeof__ (&$fname) foobarbaz;\n"; | |
522 | print TESTFILE "#endif\n"; | |
523 | close (TESTFILE); | |
524 | ||
da1067a9 UD |
525 | compiletest ($fnamebase, "Test for type of function $fname", |
526 | "Function \"$fname\" has incorrect type.", $res); | |
527 | } elsif (/^macro *([^ ]*)/) { | |
528 | my($macro) = "$1"; | |
529 | ||
530 | # Remember that this name is allowed. | |
531 | push @allow, $macro; | |
532 | ||
533 | # Generate a program to test for availability of this macro. | |
534 | open (TESTFILE, ">$fnamebase.c"); | |
77faa354 | 535 | print TESTFILE "$prepend"; |
da1067a9 UD |
536 | print TESTFILE "#include <$h>\n"; |
537 | print TESTFILE "#ifndef $macro\n"; | |
538 | print TESTFILE "# error \"Macro $macro not defined\"\n"; | |
539 | print TESTFILE "#endif\n"; | |
540 | close (TESTFILE); | |
541 | ||
542 | compiletest ($fnamebase, "Test availability of macro $macro", | |
543 | "Macro \"$macro\" is not available.", $missing); | |
544 | } elsif (/^allow *(.*)/) { | |
545 | my($pattern) = $1; | |
546 | push @allow, $pattern; | |
547 | next control; | |
0ed99ce4 UD |
548 | } elsif (/^allow-header *(.*)/) { |
549 | my($pattern) = $1; | |
550 | push @allowheader, $pattern; | |
551 | next control; | |
da1067a9 UD |
552 | } else { |
553 | # printf ("line is `%s'\n", $_); | |
554 | next control; | |
555 | } | |
556 | ||
557 | printf ("\n"); | |
558 | } | |
559 | close (CONTROL); | |
560 | ||
0ed99ce4 UD |
561 | # Read the data files for the header files which are allowed to be included. |
562 | while ($#allowheader >= 0) { | |
563 | my($ah) = pop @allowheader; | |
564 | ||
565 | open (ALLOW, "$CC -E -D$dialect - < data/$ah-data |"); | |
566 | acontrol: while (<ALLOW>) { | |
567 | next acontrol if (/^#/); | |
568 | next acontrol if (/^[ ]*$/); | |
569 | ||
570 | if (/^element *({([^}]*)}|([^ ]*)) *({([^}]*)}|([^ ]*)) *([A-Za-z0-9_]*) *(.*)/) { | |
571 | push @allow, $7; | |
572 | } elsif (/^constant *([a-zA-Z0-9_]*) *([A-Za-z0-9_]*)?/) { | |
573 | push @allow, $1; | |
574 | } elsif (/^typed-constant *([a-zA-Z0-9_]*) *({([^}]*)}|([^ ]*)) *([A-Za-z0-9_]*)?/) { | |
575 | push @allow, 1; | |
576 | } elsif (/^type *({([^}]*)|([a-zA-Z0-9_]*))/) { | |
577 | my($type) = "$2$3"; | |
578 | ||
579 | # Remember that this name is allowed. | |
580 | if ($type =~ /^struct *(.*)/) { | |
581 | push @allow, $1; | |
582 | } elsif ($type =~ /^union *(.*)/) { | |
583 | push @allow, $1; | |
584 | } else { | |
585 | push @allow, $type; | |
586 | } | |
587 | } elsif (/^function *({([^}]*)}|([a-zA-Z0-9_]*)) [(][*]([a-zA-Z0-9_]*) ([(].*[)])/) { | |
588 | push @allow, $4; | |
589 | } elsif (/^function *({([^}]*)}|([a-zA-Z0-9_]*)) ([a-zA-Z0-9_]*) ([(].*[)])/) { | |
590 | push @allow, $4; | |
591 | } elsif (/^variable *({([^}]*)}|([a-zA-Z0-9_]*)) ([a-zA-Z0-9_]*)/) { | |
592 | push @allow, $4; | |
593 | } elsif (/^macro-function *({([^}]*)}|([a-zA-Z0-9_]*)) ([a-zA-Z0-9_]*) ([(].*[)])/) { | |
594 | push @allow, $4; | |
595 | } elsif (/^macro *([^ ]*)/) { | |
596 | push @allow, $1; | |
597 | } elsif (/^allow *(.*)/) { | |
598 | push @allow, $1; | |
599 | } elsif (/^allow-header *(.*)/) { | |
600 | push @allowheader, $1; | |
601 | } | |
602 | } | |
603 | close (ALLOW); | |
604 | } | |
605 | ||
da1067a9 UD |
606 | # Now check the namespace. |
607 | printf (" Checking the namespace of \"%s\"... ", $h); | |
608 | if ($missing) { | |
609 | ++$skipped; | |
610 | printf ("SKIP\n"); | |
611 | } else { | |
612 | checknamespace ($h, $fnamebase, @allow); | |
613 | } | |
614 | ||
615 | printf ("\n\n"); | |
616 | } | |
617 | ||
618 | printf "-" x 76 . "\n"; | |
619 | printf (" Total number of tests : %4d\n", $total); | |
620 | printf (" Number of failed tests : %4d (%3d%%)\n", $errors, ($errors * 100) / $total); | |
621 | printf (" Number of skipped tests: %4d (%3d%%)\n", $skipped, ($skipped * 100) / $total); | |
622 | ||
623 | exit $errors != 0; |