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");
27 # These are the ISO C99 keywords.
28 @keywords = ('auto', 'break', 'case', 'char', 'const', 'continue', 'default',
29 'do', 'double', 'else', 'enum', 'extern', 'float', 'for', 'goto',
30 'if', 'inline', 'int', 'long', 'register', 'restrict', 'return',
31 'short', 'signed', 'sizeof', 'static', 'struct', 'switch',
32 'typedef', 'union', 'unsigned', 'void', 'volatile', 'while');
34 # Some headers need a bit more attention.
35 $mustprepend{'regex.h'} = "#include <sys/types.h>\n";
37 # Make an hash table from this information.
39 $iskeyword{pop (@keywords)} = 1;
58 my($pattern, $string) = @_;
59 my($strlen) = length ($string);
62 if (substr ($pattern, 0, 1) eq '*') {
63 my($patlen) = length ($pattern) - 1;
64 $res = ($strlen >= $patlen
65 && substr ($pattern, -$patlen, $patlen) eq substr ($string, -$patlen, $patlen));
66 } elsif (substr ($pattern, -1, 1) eq '*') {
67 my($patlen) = length ($pattern) - 1;
68 $res = ($strlen >= $patlen
69 && substr ($pattern, 0, $patlen) eq substr ($string, 0, $patlen));
71 $res = $pattern eq $string;
79 my($fnamebase, $msg, $errmsg, $skip) = @_;
90 $ret = system "$CC $CFLAGS -c $fnamebase.c -o $fnamebase.o > $fnamebase.out 2>&1";
94 printf (" $errmsg Compiler message:\n");
101 if ($verbose > 1 && -s "$fnamebase.out") {
102 # We print all warnings issued.
106 if ($printlog != 0) {
107 printf (" " . "-" x 71 . "\n");
108 open (MESSAGE, "< $fnamebase.out");
113 printf (" " . "-" x 71 . "\n");
116 unlink "$fnamebase.c";
117 unlink "$fnamebase.o";
118 unlink "$fnamebase.out";
126 my($fnamebase, $msg, $errmsg, $skip) = @_;
137 $ret = system "$CC $CFLAGS -o $fnamebase $fnamebase.c > $fnamebase.out 2>&1";
141 printf (" $errmsg Compiler message:\n");
147 # Now run the program. If the exit code is not zero something is wrong.
148 $result = system "$fnamebase > $fnamebase.out2 2>&1";
151 if ($verbose > 1 && -s "$fnamebase.out") {
152 # We print all warnings issued.
154 system "cat $fnamebase.out2 >> $fnamebase.out";
159 unlink "$fnamebase.out";
160 rename "$fnamebase.out2", "$fnamebase.out";
163 if ($printlog != 0) {
164 printf (" " . "-" x 71 . "\n");
165 open (MESSAGE, "< $fnamebase.out");
170 printf (" " . "-" x 71 . "\n");
174 unlink "$fnamebase.c";
175 unlink "$fnamebase.o";
176 unlink "$fnamebase.out";
177 unlink "$fnamebase.out2";
184 my($token, $nerrors, @allow) = @_;
187 if ($token =~ /^[0-9_]/ || $iskeyword{$token}) {
191 for ($idx = 0; $idx <= $#allow; ++$idx) {
192 if (poorfnmatch ($allow[$idx], $token)) {
199 printf ("FAIL\n " . "-" x 72 . "\n");
201 printf (" Namespace violation: \"%s\"\n", $token);
207 my($h, $fnamebase, @allow) = @_;
212 # Generate a program to get the contents of this header.
213 open (TESTFILE, ">$fnamebase.c");
214 print TESTFILE "#include <$h>\n";
217 open (CONTENT, "$CC $CFLAGS -E $fnamebase.c -Wp,-dN | sed -e '/^# [1-9]/d' -e '/^[[:space:]]*\$/d' |");
218 loop: while (<CONTENT>) {
219 next loop if (/^#undef /);
221 if (/^#define (.*)/) {
222 $nerrors = newtoken ($1, $nerrors, @allow);
224 # We have to tokenize the line.
227 my($len) = length ($str);
229 foreach $token (split(/[^a-zA-Z0-9_]/, $str)) {
231 $nerrors = newtoken ($token, $nerrors, @allow);
237 unlink "$fnamebase.c";
239 printf (" " . "-" x 72 . "\n");
247 while ($#headers >= 0) {
248 my($h) = pop (@headers);
251 my($fnamebase) = "$tmpdir/$hf-test";
254 my(@allowheader) = ();
255 my($prepend) = $mustprepend{$h};
257 printf ("Testing <$h>\n");
258 printf ("----------" . "-" x length ($h) . "\n");
260 # Generate a program to test for the availability of this header.
261 open (TESTFILE, ">$fnamebase.c");
262 print TESTFILE "$prepend";
263 print TESTFILE "#include <$h>\n";
266 $missing = compiletest ($fnamebase, "Checking whether <$h> is available",
267 "Header <$h> not available", 0);
271 open (CONTROL, "$CC -E -D$dialect - < data/$h-data |");
272 control: while (<CONTROL>) {
274 next control if (/^#/);
275 next control if (/^[ ]*$/);
277 if (/^element *({([^}]*)}|([^ ]*)) *({([^}]*)}|([^ ]*)) *([A-Za-z0-9_]*) *(.*)/) {
278 my($struct) = "$2$3";
284 # Remember that this name is allowed.
285 push @allow, $member;
287 # Generate a program to test for the availability of this member.
288 open (TESTFILE, ">$fnamebase.c");
289 print TESTFILE "$prepend";
290 print TESTFILE "#include <$h>\n";
291 print TESTFILE "$struct a;\n";
292 print TESTFILE "$struct b;\n";
293 print TESTFILE "extern void xyzzy (__typeof__ (&b.$member), __typeof__ (&a.$member), unsigned);\n";
294 print TESTFILE "void foobarbaz (void) {\n";
295 print TESTFILE " xyzzy (&a.$member, &b.$member, sizeof (a.$member));\n";
296 print TESTFILE "}\n";
299 $res = compiletest ($fnamebase, "Testing for member $member",
300 "Member \"$member\" not available.", $res);
303 # Test the types of the members.
304 open (TESTFILE, ">$fnamebase.c");
305 print TESTFILE "$prepend";
306 print TESTFILE "#include <$h>\n";
307 print TESTFILE "$struct a;\n";
308 print TESTFILE "extern $type b$rest;\n";
309 print TESTFILE "extern __typeof__ (a.$member) b;\n";
312 compiletest ($fnamebase, "Testing for type of member $member",
313 "Member \"$member\" does not have the correct type.", $res);
314 } elsif (/^constant *([a-zA-Z0-9_]*) ([>=<]+) ([A-Za-z0-9_]*)/) {
320 # Remember that this name is allowed.
323 # Generate a program to test for the availability of this constant.
324 open (TESTFILE, ">$fnamebase.c");
325 print TESTFILE "$prepend";
326 print TESTFILE "#include <$h>\n";
327 print TESTFILE "__typeof__ ($const) a = $const;\n";
330 $res = compiletest ($fnamebase, "Testing for constant $const",
331 "Constant \"$const\" not available.", $res);
334 # Generate a program to test for the value of this constant.
335 open (TESTFILE, ">$fnamebase.c");
336 print TESTFILE "$prepend";
337 print TESTFILE "#include <$h>\n";
338 # Negate the value since 0 means ok
339 print TESTFILE "int main (void) { return !($const $op $value); }\n";
342 $res = runtest ($fnamebase, "Testing for value of constant $const",
343 "Constant \"$const\" has not the right value.", $res);
345 } elsif (/^typed-constant *([a-zA-Z0-9_]*) *({([^}]*)}|([^ ]*)) *([A-Za-z0-9_]*)?/) {
351 # Remember that this name is allowed.
354 # Generate a program to test for the availability of this constant.
355 open (TESTFILE, ">$fnamebase.c");
356 print TESTFILE "$prepend";
357 print TESTFILE "#include <$h>\n";
358 print TESTFILE "__typeof__ ($const) a = $const;\n";
361 $res = compiletest ($fnamebase, "Testing for constant $const",
362 "Constant \"$const\" not available.", $res);
364 # Test the types of the members.
365 open (TESTFILE, ">$fnamebase.c");
366 print TESTFILE "$prepend";
367 print TESTFILE "#include <$h>\n";
368 print TESTFILE "__typeof__ (($type) 0) a;\n";
369 print TESTFILE "extern __typeof__ ($const) a;\n";
372 compiletest ($fnamebase, "Testing for type of constant $const",
373 "Constant \"$const\" does not have the correct type.",
377 # Generate a program to test for the value of this constant.
378 open (TESTFILE, ">$fnamebase.c");
379 print TESTFILE "$prepend";
380 print TESTFILE "#include <$h>\n";
381 print TESTFILE "int main (void) { return $const != $value; }\n";
384 $res = runtest ($fnamebase, "Testing for value of constant $const",
385 "Constant \"$const\" has not the right value.", $res);
387 } elsif (/^constant *([a-zA-Z0-9_]*) *([A-Za-z0-9_]*)?/) {
392 # Remember that this name is allowed.
395 # Generate a program to test for the availability of this constant.
396 open (TESTFILE, ">$fnamebase.c");
397 print TESTFILE "$prepend";
398 print TESTFILE "#include <$h>\n";
399 print TESTFILE "__typeof__ ($const) a = $const;\n";
402 $res = compiletest ($fnamebase, "Testing for constant $const",
403 "Constant \"$const\" not available.", $res);
406 # Generate a program to test for the value of this constant.
407 open (TESTFILE, ">$fnamebase.c");
408 print TESTFILE "$prepend";
409 print TESTFILE "#include <$h>\n";
410 print TESTFILE "int main (void) { return $const != $value; }\n";
413 $res = runtest ($fnamebase, "Testing for value of constant $const",
414 "Constant \"$const\" has not the right value.", $res);
416 } elsif (/^typed-constant *([a-zA-Z0-9_]*) *({([^}]*)}|([^ ]*)) *([A-Za-z0-9_]*)?/) {
422 # Remember that this name is allowed.
425 # Generate a program to test for the availability of this constant.
426 open (TESTFILE, ">$fnamebase.c");
427 print TESTFILE "$prepend";
428 print TESTFILE "#include <$h>\n";
429 print TESTFILE "__typeof__ ($const) a = $const;\n";
432 $res = compiletest ($fnamebase, "Testing for constant $const",
433 "Constant \"$const\" not available.", $res);
435 # Test the types of the members.
436 open (TESTFILE, ">$fnamebase.c");
437 print TESTFILE "$prepend";
438 print TESTFILE "#include <$h>\n";
439 print TESTFILE "__typeof__ (($type) 0) a;\n";
440 print TESTFILE "extern __typeof__ ($const) a;\n";
443 compiletest ($fnamebase, "Testing for type of constant $const",
444 "Constant \"$const\" does not have the correct type.",
448 # Generate a program to test for the value of this constant.
449 open (TESTFILE, ">$fnamebase.c");
450 print TESTFILE "$prepend";
451 print TESTFILE "#include <$h>\n";
452 print TESTFILE "int main (void) { return $const != $value; }\n";
455 $res = runtest ($fnamebase, "Testing for value of constant $const",
456 "Constant \"$const\" has not the right value.", $res);
458 } elsif (/^type *({([^}]*)|([a-zA-Z0-9_]*))/) {
461 # Remember that this name is allowed.
462 if ($type =~ /^struct *(.*)/) {
464 } elsif ($type =~ /^union *(.*)/) {
470 # Remember that this name is allowed.
473 # Generate a program to test for the availability of this constant.
474 open (TESTFILE, ">$fnamebase.c");
475 print TESTFILE "$prepend";
476 print TESTFILE "#include <$h>\n";
477 print TESTFILE "$type *a;\n";
480 compiletest ($fnamebase, "Testing for type $type",
481 "Type \"$type\" not available.", $missing);
482 } elsif (/^function *({([^}]*)}|([a-zA-Z0-9_]*)) [(][*]([a-zA-Z0-9_]*) ([(].*[)])/) {
483 my($rettype) = "$2$3";
488 # Remember that this name is allowed.
491 # Generate a program to test for availability of this function.
492 open (TESTFILE, ">$fnamebase.c");
493 print TESTFILE "$prepend";
494 print TESTFILE "#include <$h>\n";
495 # print TESTFILE "#undef $fname\n";
496 print TESTFILE "$rettype (*(*foobarbaz) $args = $fname;\n";
499 $res = compiletest ($fnamebase, "Test availability of function $fname",
500 "Function \"$fname\" is not available.", $res);
502 # Generate a program to test for the type of this function.
503 open (TESTFILE, ">$fnamebase.c");
504 print TESTFILE "$prepend";
505 print TESTFILE "#include <$h>\n";
506 # print TESTFILE "#undef $fname\n";
507 print TESTFILE "extern $rettype (*(*foobarbaz) $args;\n";
508 print TESTFILE "extern __typeof__ (&$fname) foobarbaz;\n";
511 compiletest ($fnamebase, "Test for type of function $fname",
512 "Function \"$fname\" has incorrect type.", $res);
513 } elsif (/^function *({([^}]*)}|([a-zA-Z0-9_]*)) ([a-zA-Z0-9_]*) ([(].*[)])/) {
514 my($rettype) = "$2$3";
519 # Remember that this name is allowed.
522 # Generate a program to test for availability of this function.
523 open (TESTFILE, ">$fnamebase.c");
524 print TESTFILE "$prepend";
525 print TESTFILE "#include <$h>\n";
526 # print TESTFILE "#undef $fname\n";
527 print TESTFILE "$rettype (*foobarbaz) $args = $fname;\n";
530 $res = compiletest ($fnamebase, "Test availability of function $fname",
531 "Function \"$fname\" is not available.", $res);
533 # Generate a program to test for the type of this function.
534 open (TESTFILE, ">$fnamebase.c");
535 print TESTFILE "$prepend";
536 print TESTFILE "#include <$h>\n";
537 # print TESTFILE "#undef $fname\n";
538 print TESTFILE "extern $rettype (*foobarbaz) $args;\n";
539 print TESTFILE "extern __typeof__ (&$fname) foobarbaz;\n";
542 compiletest ($fnamebase, "Test for type of function $fname",
543 "Function \"$fname\" has incorrect type.", $res);
544 } elsif (/^variable *({([^}]*)}|([a-zA-Z0-9_]*)) ([a-zA-Z0-9_]*)/) {
549 # Remember that this name is allowed.
552 # Generate a program to test for availability of this function.
553 open (TESTFILE, ">$fnamebase.c");
554 print TESTFILE "$prepend";
555 print TESTFILE "#include <$h>\n";
556 # print TESTFILE "#undef $fname\n";
557 print TESTFILE "$type *foobarbaz = &$vname;\n";
560 $res = compiletest ($fnamebase, "Test availability of variable $vname",
561 "Variable \"$vname\" is not available.", $res);
563 # Generate a program to test for the type of this function.
564 open (TESTFILE, ">$fnamebase.c");
565 print TESTFILE "$prepend";
566 print TESTFILE "#include <$h>\n";
567 # print TESTFILE "#undef $fname\n";
568 print TESTFILE "extern $type $vname;\n";
571 compiletest ($fnamebase, "Test for type of variable $fname",
572 "Variable \"$vname\" has incorrect type.", $res);
573 } elsif (/^macro-function *({([^}]*)}|([a-zA-Z0-9_]*)) ([a-zA-Z0-9_]*) ([(].*[)])/) {
574 my($rettype) = "$2$3";
579 # Remember that this name is allowed.
582 # Generate a program to test for availability of this function.
583 open (TESTFILE, ">$fnamebase.c");
584 print TESTFILE "$prepend";
585 print TESTFILE "#include <$h>\n";
586 print TESTFILE "#ifndef $fname\n";
587 print TESTFILE "$rettype (*foobarbaz) $args = $fname;\n";
588 print TESTFILE "#endif\n";
591 $res = compiletest ($fnamebase, "Test availability of function $fname",
592 "Function \"$fname\" is not available.", $res);
594 # Generate a program to test for the type of this function.
595 open (TESTFILE, ">$fnamebase.c");
596 print TESTFILE "$prepend";
597 print TESTFILE "#include <$h>\n";
598 print TESTFILE "#ifndef $fname\n";
599 print TESTFILE "extern $rettype (*foobarbaz) $args;\n";
600 print TESTFILE "extern __typeof__ (&$fname) foobarbaz;\n";
601 print TESTFILE "#endif\n";
604 compiletest ($fnamebase, "Test for type of function $fname",
605 "Function \"$fname\" has incorrect type.", $res);
606 } elsif (/^macro-str *([^ ]*)\s*(\".*\")/) {
607 # The above regex doesn't handle a \" in a string.
612 # Remember that this name is allowed.
615 # Generate a program to test for availability of this macro.
616 open (TESTFILE, ">$fnamebase.c");
617 print TESTFILE "$prepend";
618 print TESTFILE "#include <$h>\n";
619 print TESTFILE "#ifndef $macro\n";
620 print TESTFILE "# error \"Macro $macro not defined\"\n";
621 print TESTFILE "#endif\n";
624 compiletest ($fnamebase, "Test availability of macro $macro",
625 "Macro \"$macro\" is not available.", $missing);
627 # Generate a program to test for the value of this macro.
628 open (TESTFILE, ">$fnamebase.c");
629 print TESTFILE "$prepend";
630 print TESTFILE "#include <$h>\n";
631 # We can't include <string.h> here.
632 print TESTFILE "extern int (strcmp)(const char *, const char *);\n";
633 print TESTFILE "int main (void) { return strcmp ($macro, $string) != 0;}\n";
636 $res = runtest ($fnamebase, "Testing for value of macro $macro",
637 "Macro \"$macro\" has not the right value.", $res);
638 } elsif (/^macro *([^ ]*)/) {
641 # Remember that this name is allowed.
644 # Generate a program to test for availability of this macro.
645 open (TESTFILE, ">$fnamebase.c");
646 print TESTFILE "$prepend";
647 print TESTFILE "#include <$h>\n";
648 print TESTFILE "#ifndef $macro\n";
649 print TESTFILE "# error \"Macro $macro not defined\"\n";
650 print TESTFILE "#endif\n";
653 compiletest ($fnamebase, "Test availability of macro $macro",
654 "Macro \"$macro\" is not available.", $missing);
655 } elsif (/^allow *(.*)/) {
657 push @allow, $pattern;
659 } elsif (/^allow-header *(.*)/) {
661 push @allowheader, $pattern;
664 # printf ("line is `%s'\n", $_);
672 # Read the data files for the header files which are allowed to be included.
673 while ($#allowheader >= 0) {
674 my($ah) = pop @allowheader;
676 open (ALLOW, "$CC -E -D$dialect - < data/$ah-data |");
677 acontrol: while (<ALLOW>) {
678 next acontrol if (/^#/);
679 next acontrol if (/^[ ]*$/);
681 if (/^element *({([^}]*)}|([^ ]*)) *({([^}]*)}|([^ ]*)) *([A-Za-z0-9_]*) *(.*)/) {
683 } elsif (/^constant *([a-zA-Z0-9_]*) *([A-Za-z0-9_]*)?/) {
685 } elsif (/^typed-constant *([a-zA-Z0-9_]*) *({([^}]*)}|([^ ]*)) *([A-Za-z0-9_]*)?/) {
687 } elsif (/^type *({([^}]*)|([a-zA-Z0-9_]*))/) {
690 # Remember that this name is allowed.
691 if ($type =~ /^struct *(.*)/) {
693 } elsif ($type =~ /^union *(.*)/) {
698 } elsif (/^function *({([^}]*)}|([a-zA-Z0-9_]*)) [(][*]([a-zA-Z0-9_]*) ([(].*[)])/) {
700 } elsif (/^function *({([^}]*)}|([a-zA-Z0-9_]*)) ([a-zA-Z0-9_]*) ([(].*[)])/) {
702 } elsif (/^variable *({([^}]*)}|([a-zA-Z0-9_]*)) ([a-zA-Z0-9_]*)/) {
704 } elsif (/^macro-function *({([^}]*)}|([a-zA-Z0-9_]*)) ([a-zA-Z0-9_]*) ([(].*[)])/) {
706 } elsif (/^macro *([^ ]*)/) {
708 } elsif (/^allow *(.*)/) {
710 } elsif (/^allow-header *(.*)/) {
711 push @allowheader, $1;
717 # Now check the namespace.
718 printf (" Checking the namespace of \"%s\"... ", $h);
723 checknamespace ($h, $fnamebase, @allow);
729 printf "-" x 76 . "\n";
730 printf (" Total number of tests : %4d\n", $total);
731 printf (" Number of failed tests : %4d (%3d%%)\n", $errors, ($errors * 100) / $total);
732 printf (" Number of skipped tests: %4d (%3d%%)\n", $skipped, ($skipped * 100) / $total);