4 $CFLAGS = "-I. '-D__attribute__(x)=' -D_XOPEN_SOURCE=500";
6 # List of the headers we are testing.
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/utsname.h", "sys/un.h",
10 "sys/uio.h", "sys/types.h", "sys/times.h", "sys/timeb.h",
11 "sys/time.h", "sys/statvfs.h", "sys/stat.h", "sys/socket.h",
12 "sys/shm.h", "sys/sem.h", "sys/resource.h", "sys/msg.h",
13 "sys/mman.h", "sys/ipc.h", "syslog.h", "stropts.h", "strings.h",
14 "string.h", "stdlib.h", "stdio.h", "stddef.h", "stdarg.h",
15 "spawn.h", "signal.h", "setjmp.h", "semaphore.h",
16 "search.h", "sched.h", "regex.h", "pwd.h", "pthread.h",
17 "poll.h", "nl_types.h", "netinet/tcp.h", "netinet/in.h",
18 "net/if.h", "netdb.h", "ndbm.h", "mqueue.h", "monetary.h",
19 "math.h", "locale.h", "libgen.h", "limits.h", "langinfo.h",
20 "iso646.h", "inttypes.h", "iconv.h", "grp.h", "glob.h", "ftw.h",
21 "fnmatch.h", "fmtmsg.h", "float.h", "fcntl.h", "errno.h",
22 "dlfcn.h", "dirent.h", "ctype.h", "cpio.h", "assert.h",
23 "arpa/inet.h", "aio.h");
25 # These are the ISO C99 keywords.
26 @keywords = ('auto', 'break', 'case', 'char', 'const', 'continue', 'default',
27 'do', 'double', 'else', 'enum', 'extern', 'float', 'for', 'goto',
28 'if', 'inline', 'int', 'long', 'register', 'restrict', 'return',
29 'short', 'signed', 'sizeof', 'static', 'struct', 'switch',
30 'typedef', 'union', 'unsigned', 'void', 'volatile', 'while');
32 # Some headers need a bit more attention.
33 $mustprepend{'regex.h'} = "#include <sys/types.h>\n";
35 # Make an hash table from this information.
37 $iskeyword{pop (@keywords)} = 1;
56 my($pattern, $string) = @_;
57 my($strlen) = length ($string);
60 if (substr ($pattern, 0, 1) eq '*') {
61 my($patlen) = length ($pattern) - 1;
62 $res = ($strlen >= $patlen
63 && substr ($pattern, -$patlen, $patlen) eq substr ($string, -$patlen, $patlen));
64 } elsif (substr ($pattern, -1, 1) eq '*') {
65 my($patlen) = length ($pattern) - 1;
66 $res = ($strlen >= $patlen
67 && substr ($pattern, 0, $patlen) eq substr ($string, 0, $patlen));
69 $res = $pattern eq $string;
77 my($fnamebase, $msg, $errmsg, $skip) = @_;
88 $ret = system "$CC $CFLAGS -c $fnamebase.c -o $fnamebase.o > $fnamebase.out 2>&1";
92 printf (" $errmsg Compiler message:\n");
99 if ($verbose > 1 && -s "$fnamebase.out") {
100 # We print all warnings issued.
104 if ($printlog != 0) {
105 printf (" " . "-" x 71 . "\n");
106 open (MESSAGE, "< $fnamebase.out");
111 printf (" " . "-" x 71 . "\n");
114 unlink "$fnamebase.c";
115 unlink "$fnamebase.o";
116 unlink "$fnamebase.out";
124 my($fnamebase, $msg, $errmsg, $skip) = @_;
135 $ret = system "$CC $CFLAGS -o $fnamebase $fnamebase.c > $fnamebase.out 2>&1";
139 printf (" $errmsg Compiler message:\n");
145 # Now run the program. If the exit code is not zero something is wrong.
146 $result = system "$fnamebase > $fnamebase.out2 2>&1";
149 if ($verbose > 1 && -s "$fnamebase.out") {
150 # We print all warnings issued.
152 system "cat $fnamebase.out2 >> $fnamebase.out";
157 unlink "$fnamebase.out";
158 rename "$fnamebase.out2", "$fnamebase.out";
161 if ($printlog != 0) {
162 printf (" " . "-" x 71 . "\n");
163 open (MESSAGE, "< $fnamebase.out");
168 printf (" " . "-" x 71 . "\n");
172 unlink "$fnamebase.c";
173 unlink "$fnamebase.o";
174 unlink "$fnamebase.out";
175 unlink "$fnamebase.out2";
182 my($token, $nerrors, @allow) = @_;
185 if ($token =~ /^[0-9_]/ || $iskeyword{$token}) {
189 for ($idx = 0; $idx <= $#allow; ++$idx) {
190 if (poorfnmatch ($allow[$idx], $token)) {
197 printf ("FAIL\n " . "-" x 72 . "\n");
199 printf (" Namespace violation: \"%s\"\n", $token);
205 my($h, $fnamebase, @allow) = @_;
210 # Generate a program to get the contents of this header.
211 open (TESTFILE, ">$fnamebase.c");
212 print TESTFILE "#include <$h>\n";
215 open (CONTENT, "$CC $CFLAGS -E $fnamebase.c -P -Wp,-dN | sed -e '/^# [1-9]/d' -e '/^[[:space:]]*\$/d' |");
216 loop: while (<CONTENT>) {
217 next loop if (/^#undef /);
219 if (/^#define (.*)/) {
220 $nerrors = newtoken ($1, $nerrors, @allow);
222 # We have to tokenize the line.
225 my($len) = length ($str);
227 foreach $token (split(/[^a-zA-Z0-9_]/, $str)) {
229 $nerrors = newtoken ($token, $nerrors, @allow);
235 unlink "$fnamebase.c";
237 printf (" " . "-" x 72 . "\n");
245 while ($#headers >= 0) {
246 my($h) = pop (@headers);
249 my($fnamebase) = "$tmpdir/$hf-test";
252 my(@allowheader) = ();
253 my($prepend) = $mustprepend{$h};
255 printf ("Testing <$h>\n");
256 printf ("----------" . "-" x length ($h) . "\n");
258 # Generate a program to test for the availability of this header.
259 open (TESTFILE, ">$fnamebase.c");
260 print TESTFILE "$prepend";
261 print TESTFILE "#include <$h>\n";
264 $missing = compiletest ($fnamebase, "Checking whether <$h> is available",
265 "Header <$h> not available", 0);
269 open (CONTROL, "$CC -E -D$dialect - < data/$h-data |");
270 control: while (<CONTROL>) {
272 next control if (/^#/);
273 next control if (/^[ ]*$/);
275 if (/^element *({([^}]*)}|([^ ]*)) *({([^}]*)}|([^ ]*)) *([A-Za-z0-9_]*) *(.*)/) {
276 my($struct) = "$2$3";
282 # Remember that this name is allowed.
283 push @allow, $member;
285 # Generate a program to test for the availability of this member.
286 open (TESTFILE, ">$fnamebase.c");
287 print TESTFILE "$prepend";
288 print TESTFILE "#include <$h>\n";
289 print TESTFILE "$struct a;\n";
290 print TESTFILE "$struct b;\n";
291 print TESTFILE "extern void xyzzy (__typeof__ (&b.$member), __typeof__ (&a.$member), unsigned);\n";
292 print TESTFILE "void foobarbaz (void) {\n";
293 print TESTFILE " xyzzy (&a.$member, &b.$member, sizeof (a.$member));\n";
294 print TESTFILE "}\n";
297 $res = compiletest ($fnamebase, "Testing for member $member",
298 "Member \"$member\" not available.", $res);
301 # Test the types of the members.
302 open (TESTFILE, ">$fnamebase.c");
303 print TESTFILE "$prepend";
304 print TESTFILE "#include <$h>\n";
305 print TESTFILE "$struct a;\n";
306 print TESTFILE "extern $type b$rest;\n";
307 print TESTFILE "extern __typeof__ (a.$member) b;\n";
310 compiletest ($fnamebase, "Testing for type of member $member",
311 "Member \"$member\" does not have the correct type.", $res);
312 } elsif (/^constant *([a-zA-Z0-9_]*) ([>=<]+) ([A-Za-z0-9_]*)/) {
318 # Remember that this name is allowed.
321 # Generate a program to test for the availability of this constant.
322 open (TESTFILE, ">$fnamebase.c");
323 print TESTFILE "$prepend";
324 print TESTFILE "#include <$h>\n";
325 print TESTFILE "__typeof__ ($const) a = $const;\n";
328 $res = compiletest ($fnamebase, "Testing for constant $const",
329 "Constant \"$const\" not available.", $res);
332 # Generate a program to test for the value of this constant.
333 open (TESTFILE, ">$fnamebase.c");
334 print TESTFILE "$prepend";
335 print TESTFILE "#include <$h>\n";
336 # Negate the value since 0 means ok
337 print TESTFILE "int main (void) { return !($const $op $value); }\n";
340 $res = runtest ($fnamebase, "Testing for value of constant $const",
341 "Constant \"$const\" has not the right value.", $res);
343 } elsif (/^typed-constant *([a-zA-Z0-9_]*) *({([^}]*)}|([^ ]*)) *([A-Za-z0-9_]*)?/) {
349 # Remember that this name is allowed.
352 # Generate a program to test for the availability of this constant.
353 open (TESTFILE, ">$fnamebase.c");
354 print TESTFILE "$prepend";
355 print TESTFILE "#include <$h>\n";
356 print TESTFILE "__typeof__ ($const) a = $const;\n";
359 $res = compiletest ($fnamebase, "Testing for constant $const",
360 "Constant \"$const\" not available.", $res);
362 # Test the types of the members.
363 open (TESTFILE, ">$fnamebase.c");
364 print TESTFILE "$prepend";
365 print TESTFILE "#include <$h>\n";
366 print TESTFILE "__typeof__ (($type) 0) a;\n";
367 print TESTFILE "extern __typeof__ ($const) a;\n";
370 compiletest ($fnamebase, "Testing for type of constant $const",
371 "Constant \"$const\" does not have the correct type.",
375 # Generate a program to test for the value of this constant.
376 open (TESTFILE, ">$fnamebase.c");
377 print TESTFILE "$prepend";
378 print TESTFILE "#include <$h>\n";
379 print TESTFILE "int main (void) { return $const != $value; }\n";
382 $res = runtest ($fnamebase, "Testing for value of constant $const",
383 "Constant \"$const\" has not the right value.", $res);
385 } elsif (/^constant *([a-zA-Z0-9_]*) *([A-Za-z0-9_]*)?/) {
390 # Remember that this name is allowed.
393 # Generate a program to test for the availability of this constant.
394 open (TESTFILE, ">$fnamebase.c");
395 print TESTFILE "$prepend";
396 print TESTFILE "#include <$h>\n";
397 print TESTFILE "__typeof__ ($const) a = $const;\n";
400 $res = compiletest ($fnamebase, "Testing for constant $const",
401 "Constant \"$const\" not available.", $res);
404 # Generate a program to test for the value of this constant.
405 open (TESTFILE, ">$fnamebase.c");
406 print TESTFILE "$prepend";
407 print TESTFILE "#include <$h>\n";
408 print TESTFILE "int main (void) { return $const != $value; }\n";
411 $res = runtest ($fnamebase, "Testing for value of constant $const",
412 "Constant \"$const\" has not the right value.", $res);
414 } elsif (/^typed-constant *([a-zA-Z0-9_]*) *({([^}]*)}|([^ ]*)) *([A-Za-z0-9_]*)?/) {
420 # Remember that this name is allowed.
423 # Generate a program to test for the availability of this constant.
424 open (TESTFILE, ">$fnamebase.c");
425 print TESTFILE "$prepend";
426 print TESTFILE "#include <$h>\n";
427 print TESTFILE "__typeof__ ($const) a = $const;\n";
430 $res = compiletest ($fnamebase, "Testing for constant $const",
431 "Constant \"$const\" not available.", $res);
433 # Test the types of the members.
434 open (TESTFILE, ">$fnamebase.c");
435 print TESTFILE "$prepend";
436 print TESTFILE "#include <$h>\n";
437 print TESTFILE "__typeof__ (($type) 0) a;\n";
438 print TESTFILE "extern __typeof__ ($const) a;\n";
441 compiletest ($fnamebase, "Testing for type of constant $const",
442 "Constant \"$const\" does not have the correct type.",
446 # Generate a program to test for the value of this constant.
447 open (TESTFILE, ">$fnamebase.c");
448 print TESTFILE "$prepend";
449 print TESTFILE "#include <$h>\n";
450 print TESTFILE "int main (void) { return $const != $value; }\n";
453 $res = runtest ($fnamebase, "Testing for value of constant $const",
454 "Constant \"$const\" has not the right value.", $res);
456 } elsif (/^type *({([^}]*)|([a-zA-Z0-9_]*))/) {
459 # Remember that this name is allowed.
460 if ($type =~ /^struct *(.*)/) {
462 } elsif ($type =~ /^union *(.*)/) {
468 # Remember that this name is allowed.
471 # Generate a program to test for the availability of this constant.
472 open (TESTFILE, ">$fnamebase.c");
473 print TESTFILE "$prepend";
474 print TESTFILE "#include <$h>\n";
475 print TESTFILE "$type *a;\n";
478 compiletest ($fnamebase, "Testing for type $type",
479 "Type \"$type\" not available.", $missing);
480 } elsif (/^function *({([^}]*)}|([a-zA-Z0-9_]*)) [(][*]([a-zA-Z0-9_]*) ([(].*[)])/) {
481 my($rettype) = "$2$3";
486 # Remember that this name is allowed.
489 # Generate a program to test for availability of this function.
490 open (TESTFILE, ">$fnamebase.c");
491 print TESTFILE "$prepend";
492 print TESTFILE "#include <$h>\n";
493 # print TESTFILE "#undef $fname\n";
494 print TESTFILE "$rettype (*(*foobarbaz) $args = $fname;\n";
497 $res = compiletest ($fnamebase, "Test availability of function $fname",
498 "Function \"$fname\" is not available.", $res);
500 # Generate a program to test for the type of this function.
501 open (TESTFILE, ">$fnamebase.c");
502 print TESTFILE "$prepend";
503 print TESTFILE "#include <$h>\n";
504 # print TESTFILE "#undef $fname\n";
505 print TESTFILE "extern $rettype (*(*foobarbaz) $args;\n";
506 print TESTFILE "extern __typeof__ (&$fname) foobarbaz;\n";
509 compiletest ($fnamebase, "Test for type of function $fname",
510 "Function \"$fname\" has incorrect type.", $res);
511 } elsif (/^function *({([^}]*)}|([a-zA-Z0-9_]*)) ([a-zA-Z0-9_]*) ([(].*[)])/) {
512 my($rettype) = "$2$3";
517 # Remember that this name is allowed.
520 # Generate a program to test for availability of this function.
521 open (TESTFILE, ">$fnamebase.c");
522 print TESTFILE "$prepend";
523 print TESTFILE "#include <$h>\n";
524 # print TESTFILE "#undef $fname\n";
525 print TESTFILE "$rettype (*foobarbaz) $args = $fname;\n";
528 $res = compiletest ($fnamebase, "Test availability of function $fname",
529 "Function \"$fname\" is not available.", $res);
531 # Generate a program to test for the type of this function.
532 open (TESTFILE, ">$fnamebase.c");
533 print TESTFILE "$prepend";
534 print TESTFILE "#include <$h>\n";
535 # print TESTFILE "#undef $fname\n";
536 print TESTFILE "extern $rettype (*foobarbaz) $args;\n";
537 print TESTFILE "extern __typeof__ (&$fname) foobarbaz;\n";
540 compiletest ($fnamebase, "Test for type of function $fname",
541 "Function \"$fname\" has incorrect type.", $res);
542 } elsif (/^variable *({([^}]*)}|([a-zA-Z0-9_]*)) ([a-zA-Z0-9_]*)/) {
547 # Remember that this name is allowed.
550 # Generate a program to test for availability of this function.
551 open (TESTFILE, ">$fnamebase.c");
552 print TESTFILE "$prepend";
553 print TESTFILE "#include <$h>\n";
554 # print TESTFILE "#undef $fname\n";
555 print TESTFILE "$type *foobarbaz = &$vname;\n";
558 $res = compiletest ($fnamebase, "Test availability of variable $vname",
559 "Variable \"$vname\" is not available.", $res);
561 # Generate a program to test for the type of this function.
562 open (TESTFILE, ">$fnamebase.c");
563 print TESTFILE "$prepend";
564 print TESTFILE "#include <$h>\n";
565 # print TESTFILE "#undef $fname\n";
566 print TESTFILE "extern $type $vname;\n";
569 compiletest ($fnamebase, "Test for type of variable $fname",
570 "Variable \"$vname\" has incorrect type.", $res);
571 } elsif (/^macro-function *({([^}]*)}|([a-zA-Z0-9_]*)) ([a-zA-Z0-9_]*) ([(].*[)])/) {
572 my($rettype) = "$2$3";
577 # Remember that this name is allowed.
580 # Generate a program to test for availability of this function.
581 open (TESTFILE, ">$fnamebase.c");
582 print TESTFILE "$prepend";
583 print TESTFILE "#include <$h>\n";
584 print TESTFILE "#ifndef $fname\n";
585 print TESTFILE "$rettype (*foobarbaz) $args = $fname;\n";
586 print TESTFILE "#endif\n";
589 $res = compiletest ($fnamebase, "Test availability of function $fname",
590 "Function \"$fname\" is not available.", $res);
592 # Generate a program to test for the type of this function.
593 open (TESTFILE, ">$fnamebase.c");
594 print TESTFILE "$prepend";
595 print TESTFILE "#include <$h>\n";
596 print TESTFILE "#ifndef $fname\n";
597 print TESTFILE "extern $rettype (*foobarbaz) $args;\n";
598 print TESTFILE "extern __typeof__ (&$fname) foobarbaz;\n";
599 print TESTFILE "#endif\n";
602 compiletest ($fnamebase, "Test for type of function $fname",
603 "Function \"$fname\" has incorrect type.", $res);
604 } elsif (/^macro-str *([^ ]*)\s*(\".*\")/) {
605 # The above regex doesn't handle a \" in a string.
610 # Remember that this name is allowed.
613 # Generate a program to test for availability of this macro.
614 open (TESTFILE, ">$fnamebase.c");
615 print TESTFILE "$prepend";
616 print TESTFILE "#include <$h>\n";
617 print TESTFILE "#ifndef $macro\n";
618 print TESTFILE "# error \"Macro $macro not defined\"\n";
619 print TESTFILE "#endif\n";
622 compiletest ($fnamebase, "Test availability of macro $macro",
623 "Macro \"$macro\" is not available.", $missing);
625 # Generate a program to test for the value of this macro.
626 open (TESTFILE, ">$fnamebase.c");
627 print TESTFILE "$prepend";
628 print TESTFILE "#include <$h>\n";
629 # We can't include <string.h> here.
630 print TESTFILE "extern int (strcmp)(const char *, const char *);\n";
631 print TESTFILE "int main (void) { return strcmp ($macro, $string) != 0;}\n";
634 $res = runtest ($fnamebase, "Testing for value of macro $macro",
635 "Macro \"$macro\" has not the right value.", $res);
636 } elsif (/^macro *([^ ]*)/) {
639 # Remember that this name is allowed.
642 # Generate a program to test for availability of this macro.
643 open (TESTFILE, ">$fnamebase.c");
644 print TESTFILE "$prepend";
645 print TESTFILE "#include <$h>\n";
646 print TESTFILE "#ifndef $macro\n";
647 print TESTFILE "# error \"Macro $macro not defined\"\n";
648 print TESTFILE "#endif\n";
651 compiletest ($fnamebase, "Test availability of macro $macro",
652 "Macro \"$macro\" is not available.", $missing);
653 } elsif (/^allow-header *(.*)/) {
655 push @allowheader, $pattern;
657 } elsif (/^allow *(.*)/) {
659 push @allow, $pattern;
662 # printf ("line is `%s'\n", $_);
670 # Read the data files for the header files which are allowed to be included.
671 while ($#allowheader >= 0) {
672 my($ah) = pop @allowheader;
674 open (ALLOW, "$CC -E -D$dialect - < data/$ah-data |");
675 acontrol: while (<ALLOW>) {
676 next acontrol if (/^#/);
677 next acontrol if (/^[ ]*$/);
679 if (/^element *({([^}]*)}|([^ ]*)) *({([^}]*)}|([^ ]*)) *([A-Za-z0-9_]*) *(.*)/) {
681 } elsif (/^constant *([a-zA-Z0-9_]*) *([A-Za-z0-9_]*)?/) {
683 } elsif (/^typed-constant *([a-zA-Z0-9_]*) *({([^}]*)}|([^ ]*)) *([A-Za-z0-9_]*)?/) {
685 } elsif (/^type *({([^}]*)|([a-zA-Z0-9_]*))/) {
688 # Remember that this name is allowed.
689 if ($type =~ /^struct *(.*)/) {
691 } elsif ($type =~ /^union *(.*)/) {
696 } elsif (/^function *({([^}]*)}|([a-zA-Z0-9_]*)) [(][*]([a-zA-Z0-9_]*) ([(].*[)])/) {
698 } elsif (/^function *({([^}]*)}|([a-zA-Z0-9_]*)) ([a-zA-Z0-9_]*) ([(].*[)])/) {
700 } elsif (/^variable *({([^}]*)}|([a-zA-Z0-9_]*)) ([a-zA-Z0-9_]*)/) {
702 } elsif (/^macro-function *({([^}]*)}|([a-zA-Z0-9_]*)) ([a-zA-Z0-9_]*) ([(].*[)])/) {
704 } elsif (/^macro *([^ ]*)/) {
706 } elsif (/^allow *(.*)/) {
708 } elsif (/^allow-header *(.*)/) {
709 # XXX We should have a test for recursive dependencies here.
710 push @allowheader, $1;
716 # Now check the namespace.
717 printf (" Checking the namespace of \"%s\"... ", $h);
722 checknamespace ($h, $fnamebase, @allow);
728 printf "-" x 76 . "\n";
729 printf (" Total number of tests : %4d\n", $total);
730 printf (" Number of failed tests : %4d (%3d%%)\n", $errors, ($errors * 100) / $total);
731 printf (" Number of skipped tests: %4d (%3d%%)\n", $skipped, ($skipped * 100) / $total);