Use strcasecmp_l instead of strcasecmp
[platform/upstream/glibc.git] / conform / conformtest.pl
1 #! /usr/bin/perl
2
3 use Getopt::Long;
4 use POSIX;
5
6 $CC = "gcc";
7
8 $dialect="XOPEN2K";
9 GetOptions ('headers=s' => \@headers, 'dialect=s' => \$dialect);
10 @headers = split(/,/,join(',',@headers));
11
12 # List of the headers we are testing.
13 if (@headers == ()) {
14   @headers = ("wordexp.h", "wctype.h", "wchar.h", "varargs.h", "utmpx.h",
15               "utime.h", "unistd.h", "ulimit.h", "ucontext.h", "time.h",
16               "tgmath.h", "termios.h", "tar.h", "sys/wait.h", "sys/utsname.h",
17               "sys/un.h", "sys/uio.h", "sys/types.h", "sys/times.h",
18               "sys/timeb.h", "sys/time.h", "sys/statvfs.h", "sys/stat.h",
19               "sys/socket.h", "sys/shm.h", "sys/sem.h", "sys/select.h",
20               "sys/resource.h", "sys/msg.h", "sys/mman.h", "sys/ipc.h",
21               "syslog.h", "stropts.h", "strings.h", "string.h", "stdlib.h",
22               "stdio.h", "stdint.h", "stddef.h", "stdarg.h", "spawn.h",
23               "signal.h", "setjmp.h", "semaphore.h", "search.h", "sched.h",
24               "regex.h", "pwd.h", "pthread.h", "poll.h", "nl_types.h",
25               "netinet/tcp.h", "netinet/in.h", "net/if.h", "netdb.h", "ndbm.h",
26               "mqueue.h", "monetary.h", "math.h", "locale.h", "libgen.h",
27               "limits.h", "langinfo.h", "iso646.h", "inttypes.h", "iconv.h",
28               "grp.h", "glob.h", "ftw.h", "fnmatch.h", "fmtmsg.h", "float.h",
29               "fcntl.h", "errno.h", "dlfcn.h", "dirent.h", "ctype.h", "cpio.h",
30               "complex.h", "assert.h", "arpa/inet.h", "aio.h");
31 }
32
33 if ($dialect ne "ISO" && $dialect ne "POSIX" && $dialect ne "XPG3"
34     && $dialect ne "XPG4" && $dialect ne "UNIX98" && $dialect ne "XOPEN2K"
35     && $dialect ne "XOPEN2K8" && $dialect ne "POSIX2008") {
36   die "unknown dialect \"$dialect\"";
37 }
38
39 $CFLAGS{"ISO"} = "-I. -fno-builtin '-D__attribute__(x)=' -ansi";
40 $CFLAGS{"POSIX"} = "-I. -fno-builtin '-D__attribute__(x)=' -D_POSIX_C_SOURCE=199912";
41 $CFLAGS{"XPG3"} = "-I. -fno-builtin '-D__attribute__(x)=' -D_XOPEN_SOURCE";
42 $CFLAGS{"XPG4"} = "-I. -fno-builtin '-D__attribute__(x)=' -D_XOPEN_SOURCE_EXTENDED";
43 $CFLAGS{"UNIX98"} = "-I. -fno-builtin '-D__attribute__(x)=' -D_XOPEN_SOURCE=500";
44 $CFLAGS{"XOPEN2K"} = "-I. -fno-builtin '-D__attribute__(x)=' -D_XOPEN_SOURCE=600";
45 $CFLAGS{"XOPEN2K8"} = "-I. -fno-builtin '-D__attribute__(x)=' -D_XOPEN_SOURCE=700";
46 $CFLAGS{"POSIX2008"} = "-I. -fno-builtin '-D__attribute__(x)=' -D_POSIX_C_SOURCE=200809L";
47
48
49 # These are the ISO C99 keywords.
50 @keywords = ('auto', 'break', 'case', 'char', 'const', 'continue', 'default',
51              'do', 'double', 'else', 'enum', 'extern', 'float', 'for', 'goto',
52              'if', 'inline', 'int', 'long', 'register', 'restrict', 'return',
53              'short', 'signed', 'sizeof', 'static', 'struct', 'switch',
54              'typedef', 'union', 'unsigned', 'void', 'volatile', 'while');
55
56 # These are symbols which are known to pollute the namespace.
57 @knownproblems = ('unix', 'linux', 'i386');
58
59 if ($dialect ne "XOPEN2K8" && $dialect ne "POSIX2008") {
60   # Some headers need a bit more attention.  At least with XPG7
61   # all headers should be self-contained.
62   $mustprepend{'inttypes.h'} = "#include <stddef.h>\n";
63   $mustprepend{'regex.h'} = "#include <sys/types.h>\n";
64   $mustprepend{'sched.h'} = "#include <sys/types.h>\n";
65   $mustprepend{'signal.h'} = "#include <pthread.h>\n";
66   $mustprepend{'stdio.h'} = "#include <sys/types.h>\n";
67   $mustprepend{'wchar.h'} = "#include <stdarg.h>\n";
68   $mustprepend{'wordexp.h'} = "#include <stddef.h>\n";
69 }
70
71 # Make a hash table from this information.
72 while ($#keywords >= 0) {
73   $iskeyword{pop (@keywords)} = 1;
74 }
75
76 # Make a hash table from the known problems.
77 while ($#knownproblems >= 0) {
78   $isknown{pop (@knownproblems)} = 1;
79 }
80
81 $uid = getuid();
82 ($pwname,$pwpasswd,$pwuid,$pwgid,
83  $pwquota,$pwcomment,$pwgcos,$pwdir,$pwshell,$pwexpire) = getpwuid($uid);
84 $tmpdir = "$pwdir";
85
86 $verbose = 1;
87
88 $total = 0;
89 $skipped = 0;
90 $errors = 0;
91
92
93 sub poorfnmatch {
94   my($pattern, $string) = @_;
95   my($strlen) = length ($string);
96   my($res);
97
98   if (substr ($pattern, 0, 1) eq '*') {
99     my($patlen) = length ($pattern) - 1;
100     $res = ($strlen >= $patlen
101             && substr ($pattern, -$patlen, $patlen) eq substr ($string, -$patlen, $patlen));
102   } elsif (substr ($pattern, -1, 1) eq '*') {
103     my($patlen) = length ($pattern) - 1;
104     $res = ($strlen >= $patlen
105             && substr ($pattern, 0, $patlen) eq substr ($string, 0, $patlen));
106   } else {
107     $res = $pattern eq $string;
108   }
109   return $res;
110 }
111
112
113 sub compiletest
114 {
115   my($fnamebase, $msg, $errmsg, $skip, $optional) = @_;
116   my($result) = $skip;
117   my($printlog) = 0;
118
119   ++$total;
120   printf ("  $msg...");
121
122   if ($skip != 0) {
123     ++$skipped;
124     printf (" SKIP\n");
125   } else {
126     $ret = system "$CC $CFLAGS{$dialect} -c $fnamebase.c -o $fnamebase.o > $fnamebase.out 2>&1";
127     if ($ret != 0) {
128       if ($optional != 0) {
129         printf (" $errmsg\n");
130         $result = 1;
131       } else {
132         printf (" FAIL\n");
133         if ($verbose != 0) {
134           printf ("    $errmsg  Compiler message:\n");
135           $printlog = 1;
136         }
137         ++$errors;
138         $result = 1;
139       }
140     } else {
141       printf (" OK\n");
142       if ($verbose > 1 && -s "$fnamebase.out") {
143         # We print all warnings issued.
144         $printlog = 1;
145       }
146     }
147     if ($printlog != 0) {
148       printf ("    " . "-" x 71 . "\n");
149       open (MESSAGE, "< $fnamebase.out");
150       while (<MESSAGE>) {
151         printf ("    %s", $_);
152       }
153       close (MESSAGE);
154       printf ("    " . "-" x 71 . "\n");
155     }
156   }
157   unlink "$fnamebase.c";
158   unlink "$fnamebase.o";
159   unlink "$fnamebase.out";
160
161   $result;
162 }
163
164
165 sub runtest
166 {
167   my($fnamebase, $msg, $errmsg, $skip) = @_;
168   my($result) = $skip;
169   my($printlog) = 0;
170
171   ++$total;
172   printf ("  $msg...");
173
174   if ($skip != 0) {
175     ++$skipped;
176     printf (" SKIP\n");
177   } else {
178     $ret = system "$CC $CFLAGS{$dialect} -o $fnamebase $fnamebase.c > $fnamebase.out 2>&1";
179     if ($ret != 0) {
180       printf (" FAIL\n");
181       if ($verbose != 0) {
182         printf ("    $errmsg  Compiler message:\n");
183         $printlog = 1;
184       }
185       ++$errors;
186       $result = 1;
187     } else {
188       # Now run the program.  If the exit code is not zero something is wrong.
189       $result = system "$fnamebase > $fnamebase.out2 2>&1";
190       if ($result == 0) {
191         printf (" OK\n");
192         if ($verbose > 1 && -s "$fnamebase.out") {
193           # We print all warnings issued.
194           $printlog = 1;
195           system "cat $fnamebase.out2 >> $fnamebase.out";
196         }
197       } else {
198         printf (" FAIL\n");
199         ++$errors;
200         $printlog = 1;
201         unlink "$fnamebase.out";
202         rename "$fnamebase.out2", "$fnamebase.out";
203       }
204     }
205     if ($printlog != 0) {
206       printf ("    " . "-" x 71 . "\n");
207       open (MESSAGE, "< $fnamebase.out");
208       while (<MESSAGE>) {
209         printf ("    %s", $_);
210       }
211       close (MESSAGE);
212       printf ("    " . "-" x 71 . "\n");
213     }
214   }
215   unlink "$fnamebase";
216   unlink "$fnamebase.c";
217   unlink "$fnamebase.o";
218   unlink "$fnamebase.out";
219   unlink "$fnamebase.out2";
220
221   $result;
222 }
223
224
225 sub newtoken {
226   my($token, @allow) = @_;
227   my($idx);
228
229   return if ($token =~ /^[0-9_]/ || $iskeyword{$token});
230
231   for ($idx = 0; $idx <= $#allow; ++$idx) {
232     return if (poorfnmatch ($allow[$idx], $token));
233   }
234
235   if ($isknown{$token}) {
236     ++$nknown;
237   } else {
238     $errors{$token} = 1;
239   }
240 }
241
242
243 sub removetoken {
244   my($token) = @_;
245   my($idx);
246
247   return if ($token =~ /^[0-9_]/ || $iskeyword{$token});
248
249   if (exists $errors{$token}) {
250     undef $errors{$token};
251   }
252 }
253
254
255 sub checknamespace {
256   my($h, $fnamebase, @allow) = @_;
257
258   ++$total;
259
260   # Generate a program to get the contents of this header.
261   open (TESTFILE, ">$fnamebase.c");
262   print TESTFILE "#include <$h>\n";
263   close (TESTFILE);
264
265   undef %errors;
266   $nknown = 0;
267   open (CONTENT, "$CC $CFLAGS{$dialect} -E $fnamebase.c -P -Wp,-dN | sed -e '/^# [1-9]/d' -e '/^[[:space:]]*\$/d' |");
268   loop: while (<CONTENT>) {
269     chop;
270     if (/^#define (.*)/) {
271       newtoken ($1, @allow);
272     } elsif (/^#undef (.*)/) {
273       removetoken ($1);
274     } else {
275       # We have to tokenize the line.
276       my($str) = $_;
277       my($index) = 0;
278       my($len) = length ($str);
279
280       foreach $token (split(/[^a-zA-Z0-9_]/, $str)) {
281         if ($token ne "") {
282           newtoken ($token, @allow);
283         }
284       }
285     }
286   }
287   close (CONTENT);
288   unlink "$fnamebase.c";
289   $realerror = 0;
290   if ($#errors != 0) {
291     # Sort the output list so it's easier to compare results with diff.
292     foreach $f (sort keys(%errors)) {
293       if ($errors{$f} == 1) {
294         if ($realerror == 0) {
295           printf ("FAIL\n    " . "-" x 72 . "\n");
296           $realerror = 1;
297           ++$errors;
298         }
299         printf ("    Namespace violation: \"%s\"\n", $f);
300       }
301     }
302     printf ("    " . "-" x 72 . "\n") if ($realerror != 0);
303   }
304
305   if ($realerror == 0) {
306     if ($nknown > 0) {
307       printf ("EXPECTED FAILURES\n");
308       ++$known;
309     } else {
310       printf ("OK\n");
311     }
312   }
313 }
314
315
316 while ($#headers >= 0) {
317   my($h) = pop (@headers);
318   my($hf) = $h;
319   $hf =~ s|/|-|;
320   my($fnamebase) = "$tmpdir/$hf-test";
321   my($missing);
322   my(@allow) = ();
323   my(@allowheader) = ();
324   my(%seenheader) = ();
325   my($prepend) = $mustprepend{$h};
326
327   printf ("Testing <$h>\n");
328   printf ("----------" . "-" x length ($h) . "\n");
329
330   # Generate a program to test for the availability of this header.
331   open (TESTFILE, ">$fnamebase.c");
332   print TESTFILE "$prepend";
333   print TESTFILE "#include <$h>\n";
334   close (TESTFILE);
335
336   $missing = compiletest ($fnamebase, "Checking whether <$h> is available",
337                           "Header <$h> not available", 0, 0);
338
339   printf ("\n");
340
341   open (CONTROL, "$CC -E -D$dialect - < data/$h-data |");
342   control: while (<CONTROL>) {
343     chop;
344     next control if (/^#/);
345     next control if (/^[        ]*$/);
346
347     if (/^element *({([^}]*)}|([^{ ]*)) *({([^}]*)}|([^{ ]*)) *([A-Za-z0-9_]*) *(.*)/) {
348       my($struct) = "$2$3";
349       my($type) = "$5$6";
350       my($member) = "$7";
351       my($rest) = "$8";
352       my($res) = $missing;
353
354       # Remember that this name is allowed.
355       push @allow, $member;
356
357       # Generate a program to test for the availability of this member.
358       open (TESTFILE, ">$fnamebase.c");
359       print TESTFILE "$prepend";
360       print TESTFILE "#include <$h>\n";
361       print TESTFILE "$struct a;\n";
362       print TESTFILE "$struct b;\n";
363       print TESTFILE "extern void xyzzy (__typeof__ (&b.$member), __typeof__ (&a.$member), unsigned);\n";
364       print TESTFILE "void foobarbaz (void) {\n";
365       print TESTFILE "  xyzzy (&a.$member, &b.$member, sizeof (a.$member));\n";
366       print TESTFILE "}\n";
367       close (TESTFILE);
368
369       $res = compiletest ($fnamebase, "Testing for member $member",
370                           "Member \"$member\" not available.", $res, 0);
371
372
373       # Test the types of the members.
374       open (TESTFILE, ">$fnamebase.c");
375       print TESTFILE "$prepend";
376       print TESTFILE "#include <$h>\n";
377       print TESTFILE "$struct a;\n";
378       print TESTFILE "extern $type b$rest;\n";
379       print TESTFILE "extern __typeof__ (a.$member) b;\n";
380       close (TESTFILE);
381
382       compiletest ($fnamebase, "Testing for type of member $member",
383                    "Member \"$member\" does not have the correct type.",
384                    $res, 0);
385     } elsif (/^optional-element *({([^}]*)}|([^{ ]*)) *({([^}]*)}|([^{ ]*)) *([A-Za-z0-9_]*) *(.*)/) {
386       my($struct) = "$2$3";
387       my($type) = "$5$6";
388       my($member) = "$7";
389       my($rest) = "$8";
390       my($res) = $missing;
391
392       # Remember that this name is allowed.
393       push @allow, $member;
394
395       # Generate a program to test for the availability of this member.
396       open (TESTFILE, ">$fnamebase.c");
397       print TESTFILE "$prepend";
398       print TESTFILE "#include <$h>\n";
399       print TESTFILE "$struct a;\n";
400       print TESTFILE "$struct b;\n";
401       print TESTFILE "extern void xyzzy (__typeof__ (&b.$member), __typeof__ (&a.$member), unsigned);\n";
402       print TESTFILE "void foobarbaz (void) {\n";
403       print TESTFILE "  xyzzy (&a.$member, &b.$member, sizeof (a.$member));\n";
404       print TESTFILE "}\n";
405       close (TESTFILE);
406
407       $res = compiletest ($fnamebase, "Testing for member $member",
408                           "NOT AVAILABLE.", $res, 1);
409
410       if ($res == 0 || $missing != 0) {
411         # Test the types of the members.
412         open (TESTFILE, ">$fnamebase.c");
413         print TESTFILE "$prepend";
414         print TESTFILE "#include <$h>\n";
415         print TESTFILE "$struct a;\n";
416         print TESTFILE "extern $type b$rest;\n";
417         print TESTFILE "extern __typeof__ (a.$member) b;\n";
418         close (TESTFILE);
419
420         compiletest ($fnamebase, "Testing for type of member $member",
421                      "Member \"$member\" does not have the correct type.",
422                      $res, 0);
423       }
424     } elsif (/^optional-constant *([a-zA-Z0-9_]*) ([>=<]+) ([A-Za-z0-9_]*)/) {
425       my($const) = $1;
426       my($op) = $2;
427       my($value) = $3;
428       my($res) = $missing;
429
430       # Remember that this name is allowed.
431       push @allow, $const;
432
433       # Generate a program to test for the availability of this constant.
434       open (TESTFILE, ">$fnamebase.c");
435       print TESTFILE "$prepend";
436       print TESTFILE "#include <$h>\n";
437       print TESTFILE "__typeof__ ($const) a = $const;\n";
438       close (TESTFILE);
439
440       $res = compiletest ($fnamebase, "Testing for constant $const",
441                           "NOT PRESENT", $res, 1);
442
443       if ($value ne "" && $res == 0) {
444         # Generate a program to test for the value of this constant.
445         open (TESTFILE, ">$fnamebase.c");
446         print TESTFILE "$prepend";
447         print TESTFILE "#include <$h>\n";
448         # Negate the value since 0 means ok
449         print TESTFILE "int main (void) { return !($const $op $value); }\n";
450         close (TESTFILE);
451
452         $res = runtest ($fnamebase, "Testing for value of constant $const",
453                         "Constant \"$const\" has not the right value.", $res);
454       }
455     } elsif (/^constant *([a-zA-Z0-9_]*) *([>=<]+) ([A-Za-z0-9_]*)/) {
456       my($const) = $1;
457       my($op) = $2;
458       my($value) = $3;
459       my($res) = $missing;
460
461       # Remember that this name is allowed.
462       push @allow, $const;
463
464       # Generate a program to test for the availability of this constant.
465       open (TESTFILE, ">$fnamebase.c");
466       print TESTFILE "$prepend";
467       print TESTFILE "#include <$h>\n";
468       print TESTFILE "__typeof__ ($const) a = $const;\n";
469       close (TESTFILE);
470
471       $res = compiletest ($fnamebase, "Testing for constant $const",
472                           "Constant \"$const\" not available.", $res, 0);
473
474       if ($value ne "") {
475         # Generate a program to test for the value of this constant.
476         open (TESTFILE, ">$fnamebase.c");
477         print TESTFILE "$prepend";
478         print TESTFILE "#include <$h>\n";
479         # Negate the value since 0 means ok
480         print TESTFILE "int main (void) { return !($const $op $value); }\n";
481         close (TESTFILE);
482
483         $res = runtest ($fnamebase, "Testing for value of constant $const",
484                         "Constant \"$const\" has not the right value.", $res);
485       }
486     } elsif (/^typed-constant *([a-zA-Z0-9_]*) *({([^}]*)}|([^ ]*)) *([A-Za-z0-9_]*)?/) {
487       my($const) = $1;
488       my($type) = "$3$4";
489       my($value) = $5;
490       my($res) = $missing;
491
492       # Remember that this name is allowed.
493       push @allow, $const;
494
495       # Generate a program to test for the availability of this constant.
496       open (TESTFILE, ">$fnamebase.c");
497       print TESTFILE "$prepend";
498       print TESTFILE "#include <$h>\n";
499       print TESTFILE "__typeof__ ($const) a = $const;\n";
500       close (TESTFILE);
501
502       $res = compiletest ($fnamebase, "Testing for constant $const",
503                           "Constant \"$const\" not available.", $res, 0);
504
505       # Test the types of the members.
506       open (TESTFILE, ">$fnamebase.c");
507       print TESTFILE "$prepend";
508       print TESTFILE "#include <$h>\n";
509       print TESTFILE "__typeof__ (($type) 0) a;\n";
510       print TESTFILE "extern __typeof__ ($const) a;\n";
511       close (TESTFILE);
512
513       compiletest ($fnamebase, "Testing for type of constant $const",
514                    "Constant \"$const\" does not have the correct type.",
515                    $res, 0);
516
517       if ($value ne "") {
518         # Generate a program to test for the value of this constant.
519         open (TESTFILE, ">$fnamebase.c");
520         print TESTFILE "$prepend";
521         print TESTFILE "#include <$h>\n";
522         print TESTFILE "int main (void) { return $const != $value; }\n";
523         close (TESTFILE);
524
525         $res = runtest ($fnamebase, "Testing for value of constant $const",
526                         "Constant \"$const\" has not the right value.", $res);
527       }
528     } elsif (/^optional-constant *([a-zA-Z0-9_]*) *([A-Za-z0-9_]*)?/) {
529       my($const) = $1;
530       my($value) = $2;
531       my($res) = $missing;
532
533       # Remember that this name is allowed.
534       push @allow, $const;
535
536       # Generate a program to test for the availability of this constant.
537       open (TESTFILE, ">$fnamebase.c");
538       print TESTFILE "$prepend";
539       print TESTFILE "#include <$h>\n";
540       print TESTFILE "__typeof__ ($const) a = $const;\n";
541       close (TESTFILE);
542
543       $res = compiletest ($fnamebase, "Testing for constant $const",
544                           "NOT PRESENT", $res, 1);
545
546       if ($value ne "" && $res == 0) {
547         # Generate a program to test for the value of this constant.
548         open (TESTFILE, ">$fnamebase.c");
549         print TESTFILE "$prepend";
550         print TESTFILE "#include <$h>\n";
551         print TESTFILE "int main (void) { return $const != $value; }\n";
552         close (TESTFILE);
553
554         $res = runtest ($fnamebase, "Testing for value of constant $const",
555                         "Constant \"$const\" has not the right value.", $res);
556       }
557     } elsif (/^constant *([a-zA-Z0-9_]*) *([A-Za-z0-9_]*)?/) {
558       my($const) = $1;
559       my($value) = $2;
560       my($res) = $missing;
561
562       # Remember that this name is allowed.
563       push @allow, $const;
564
565       # Generate a program to test for the availability of this constant.
566       open (TESTFILE, ">$fnamebase.c");
567       print TESTFILE "$prepend";
568       print TESTFILE "#include <$h>\n";
569       print TESTFILE "__typeof__ ($const) a = $const;\n";
570       close (TESTFILE);
571
572       $res = compiletest ($fnamebase, "Testing for constant $const",
573                           "Constant \"$const\" not available.", $res, 0);
574
575       if ($value ne "") {
576         # Generate a program to test for the value of this constant.
577         open (TESTFILE, ">$fnamebase.c");
578         print TESTFILE "$prepend";
579         print TESTFILE "#include <$h>\n";
580         print TESTFILE "int main (void) { return $const != $value; }\n";
581         close (TESTFILE);
582
583         $res = runtest ($fnamebase, "Testing for value of constant $const",
584                         "Constant \"$const\" has not the right value.", $res);
585       }
586     } elsif (/^symbol *([a-zA-Z0-9_]*) *([A-Za-z0-9_]*)?/) {
587       my($symbol) = $1;
588       my($value) = $2;
589       my($res) = $missing;
590
591       # Remember that this name is allowed.
592       push @allow, $symbol;
593
594       # Generate a program to test for the availability of this constant.
595       open (TESTFILE, ">$fnamebase.c");
596       print TESTFILE "$prepend";
597       print TESTFILE "#include <$h>\n";
598       print TESTFILE "void foobarbaz (void) {\n";
599       print TESTFILE "__typeof__ ($symbol) a = $symbol;\n";
600       print TESTFILE "}\n";
601       close (TESTFILE);
602
603       $res = compiletest ($fnamebase, "Testing for symbol $symbol",
604                           "Symbol \"$symbol\" not available.", $res, 0);
605
606       if ($value ne "") {
607         # Generate a program to test for the value of this constant.
608         open (TESTFILE, ">$fnamebase.c");
609         print TESTFILE "$prepend";
610         print TESTFILE "#include <$h>\n";
611         print TESTFILE "int main (void) { return $symbol != $value; }\n";
612         close (TESTFILE);
613
614         $res = runtest ($fnamebase, "Testing for value of symbol $symbol",
615                         "Symbol \"$symbol\" has not the right value.", $res);
616       }
617     } elsif (/^typed-constant *([a-zA-Z0-9_]*) *({([^}]*)}|([^ ]*)) *([A-Za-z0-9_]*)?/) {
618       my($const) = $1;
619       my($type) = "$3$4";
620       my($value) = $5;
621       my($res) = $missing;
622
623       # Remember that this name is allowed.
624       push @allow, $const;
625
626       # Generate a program to test for the availability of this constant.
627       open (TESTFILE, ">$fnamebase.c");
628       print TESTFILE "$prepend";
629       print TESTFILE "#include <$h>\n";
630       print TESTFILE "__typeof__ ($const) a = $const;\n";
631       close (TESTFILE);
632
633       $res = compiletest ($fnamebase, "Testing for constant $const",
634                           "Constant \"$const\" not available.", $res, 0);
635
636       # Test the types of the members.
637       open (TESTFILE, ">$fnamebase.c");
638       print TESTFILE "$prepend";
639       print TESTFILE "#include <$h>\n";
640       print TESTFILE "__typeof__ (($type) 0) a;\n";
641       print TESTFILE "extern __typeof__ ($const) a;\n";
642       close (TESTFILE);
643
644       compiletest ($fnamebase, "Testing for type of constant $const",
645                    "Constant \"$const\" does not have the correct type.",
646                    $res, 0);
647
648       if ($value ne "") {
649         # Generate a program to test for the value of this constant.
650         open (TESTFILE, ">$fnamebase.c");
651         print TESTFILE "$prepend";
652         print TESTFILE "#include <$h>\n";
653         print TESTFILE "int main (void) { return $const != $value; }\n";
654         close (TESTFILE);
655
656         $res = runtest ($fnamebase, "Testing for value of constant $const",
657                         "Constant \"$const\" has not the right value.", $res);
658       }
659     } elsif (/^optional-type *({([^}]*)|([a-zA-Z0-9_]*))/) {
660       my($type) = "$2$3";
661       my($maybe_opaque) = 0;
662
663       # Remember that this name is allowed.
664       if ($type =~ /^struct *(.*)/) {
665         push @allow, $1;
666       } elsif ($type =~ /^union *(.*)/) {
667         push @allow, $1;
668       } else {
669         push @allow, $type;
670         $maybe_opaque = 1;
671       }
672
673       # Generate a program to test for the availability of this constant.
674       open (TESTFILE, ">$fnamebase.c");
675       print TESTFILE "$prepend";
676       print TESTFILE "#include <$h>\n";
677       if ($maybe_opaque == 1) {
678         print TESTFILE "$type *a;\n";
679       } else {
680         print TESTFILE "$type a;\n";
681       }
682       close (TESTFILE);
683
684       compiletest ($fnamebase, "Testing for type $type",
685                    "NOT AVAILABLE", $missing, 1);
686     } elsif (/^type *({([^}]*)|([a-zA-Z0-9_]*))/) {
687       my($type) = "$2$3";
688       my($maybe_opaque) = 0;
689
690       # Remember that this name is allowed.
691       if ($type =~ /^struct *(.*)/) {
692         push @allow, $1;
693       } elsif ($type =~ /^union *(.*)/) {
694         push @allow, $1;
695       } else {
696         push @allow, $type;
697         $maybe_opaque = 1;
698       }
699
700       # Generate a program to test for the availability of this type.
701       open (TESTFILE, ">$fnamebase.c");
702       print TESTFILE "$prepend";
703       print TESTFILE "#include <$h>\n";
704       if ($maybe_opaque == 1) {
705         print TESTFILE "$type *a;\n";
706       } else {
707         print TESTFILE "$type a;\n";
708       }
709       close (TESTFILE);
710
711       compiletest ($fnamebase, "Testing for type $type",
712                    "Type \"$type\" not available.", $missing, 0);
713     } elsif (/^tag *({([^}]*)|([a-zA-Z0-9_]*))/) {
714       my($type) = "$2$3";
715
716       # Remember that this name is allowed.
717       if ($type =~ /^struct *(.*)/) {
718         push @allow, $1;
719       } elsif ($type =~ /^union *(.*)/) {
720         push @allow, $1;
721       } else {
722         push @allow, $type;
723       }
724
725       # Generate a program to test for the availability of this type.
726       open (TESTFILE, ">$fnamebase.c");
727       print TESTFILE "$prepend";
728       print TESTFILE "#include <$h>\n";
729       print TESTFILE "$type;\n";
730       close (TESTFILE);
731
732       compiletest ($fnamebase, "Testing for type $type",
733                    "Type \"$type\" not available.", $missing, 0);
734     } elsif (/^optional-function *({([^}]*)}|([a-zA-Z0-9_]*)) [(][*]([a-zA-Z0-9_]*) ([(].*[)])/) {
735       my($rettype) = "$2$3";
736       my($fname) = "$4";
737       my($args) = "$5";
738       my($res) = $missing;
739
740       # Remember that this name is allowed.
741       push @allow, $fname;
742
743       # Generate a program to test for availability of this function.
744       open (TESTFILE, ">$fnamebase.c");
745       print TESTFILE "$prepend";
746       print TESTFILE "#include <$h>\n";
747       # print TESTFILE "#undef $fname\n";
748       print TESTFILE "$rettype (*(*foobarbaz) $args = $fname;\n";
749       close (TESTFILE);
750
751       $res = compiletest ($fnamebase, "Test availability of function $fname",
752                           "NOT AVAILABLE", $res, 1);
753
754       if ($res == 0 || $missing == 1) {
755         # Generate a program to test for the type of this function.
756         open (TESTFILE, ">$fnamebase.c");
757         print TESTFILE "$prepend";
758         print TESTFILE "#include <$h>\n";
759         # print TESTFILE "#undef $fname\n";
760         print TESTFILE "extern $rettype (*(*foobarbaz) $args;\n";
761         print TESTFILE "extern __typeof__ (&$fname) foobarbaz;\n";
762         close (TESTFILE);
763
764         compiletest ($fnamebase, "Test for type of function $fname",
765                      "Function \"$fname\" has incorrect type.", $res, 0);
766       }
767     } elsif (/^function *({([^}]*)}|([a-zA-Z0-9_]*)) [(][*]([a-zA-Z0-9_]*) ([(].*[)])/) {
768       my($rettype) = "$2$3";
769       my($fname) = "$4";
770       my($args) = "$5";
771       my($res) = $missing;
772
773       # Remember that this name is allowed.
774       push @allow, $fname;
775
776       # Generate a program to test for availability of this function.
777       open (TESTFILE, ">$fnamebase.c");
778       print TESTFILE "$prepend";
779       print TESTFILE "#include <$h>\n";
780       # print TESTFILE "#undef $fname\n";
781       print TESTFILE "$rettype (*(*foobarbaz) $args = $fname;\n";
782       close (TESTFILE);
783
784       $res = compiletest ($fnamebase, "Test availability of function $fname",
785                           "Function \"$fname\" is not available.", $res, 0);
786
787       # Generate a program to test for the type of this function.
788       open (TESTFILE, ">$fnamebase.c");
789       print TESTFILE "$prepend";
790       print TESTFILE "#include <$h>\n";
791       # print TESTFILE "#undef $fname\n";
792       print TESTFILE "extern $rettype (*(*foobarbaz) $args;\n";
793       print TESTFILE "extern __typeof__ (&$fname) foobarbaz;\n";
794       close (TESTFILE);
795
796       compiletest ($fnamebase, "Test for type of function $fname",
797                    "Function \"$fname\" has incorrect type.", $res, 0);
798     } elsif (/^optional-function *({([^}]*)}|([a-zA-Z0-9_]*)) ([a-zA-Z0-9_]*) ([(].*[)])/) {
799       my($rettype) = "$2$3";
800       my($fname) = "$4";
801       my($args) = "$5";
802       my($res) = $missing;
803
804       # Remember that this name is allowed.
805       push @allow, $fname;
806
807       # Generate a program to test for availability of this function.
808       open (TESTFILE, ">$fnamebase.c");
809       print TESTFILE "$prepend";
810       print TESTFILE "#include <$h>\n";
811       # print TESTFILE "#undef $fname\n";
812       print TESTFILE "$rettype (*foobarbaz) $args = $fname;\n";
813       close (TESTFILE);
814
815       $res = compiletest ($fnamebase, "Test availability of function $fname",
816                           "NOT AVAILABLE", $res, 1);
817
818       if ($res == 0 || $missing != 0) {
819         # Generate a program to test for the type of this function.
820         open (TESTFILE, ">$fnamebase.c");
821         print TESTFILE "$prepend";
822         print TESTFILE "#include <$h>\n";
823         # print TESTFILE "#undef $fname\n";
824         print TESTFILE "extern $rettype (*foobarbaz) $args;\n";
825         print TESTFILE "extern __typeof__ (&$fname) foobarbaz;\n";
826         close (TESTFILE);
827
828         compiletest ($fnamebase, "Test for type of function $fname",
829                      "Function \"$fname\" has incorrect type.", $res, 0);
830       }
831     } elsif (/^function *({([^}]*)}|([a-zA-Z0-9_]*)) ([a-zA-Z0-9_]*) ([(].*[)])/) {
832       my($rettype) = "$2$3";
833       my($fname) = "$4";
834       my($args) = "$5";
835       my($res) = $missing;
836
837       # Remember that this name is allowed.
838       push @allow, $fname;
839
840       # Generate a program to test for availability of this function.
841       open (TESTFILE, ">$fnamebase.c");
842       print TESTFILE "$prepend";
843       print TESTFILE "#include <$h>\n";
844       # print TESTFILE "#undef $fname\n";
845       print TESTFILE "$rettype (*foobarbaz) $args = $fname;\n";
846       close (TESTFILE);
847
848       $res = compiletest ($fnamebase, "Test availability of function $fname",
849                           "Function \"$fname\" is not available.", $res, 0);
850
851       # Generate a program to test for the type of this function.
852       open (TESTFILE, ">$fnamebase.c");
853       print TESTFILE "$prepend";
854       print TESTFILE "#include <$h>\n";
855       # print TESTFILE "#undef $fname\n";
856       print TESTFILE "extern $rettype (*foobarbaz) $args;\n";
857       print TESTFILE "extern __typeof__ (&$fname) foobarbaz;\n";
858       close (TESTFILE);
859
860       compiletest ($fnamebase, "Test for type of function $fname",
861                    "Function \"$fname\" has incorrect type.", $res, 0);
862     } elsif (/^variable *({([^}]*)}|([a-zA-Z0-9_]*)) ([a-zA-Z0-9_]*) *(.*)/) {
863       my($type) = "$2$3";
864       my($vname) = "$4";
865       my($rest) = "$5";
866       my($res) = $missing;
867
868       # Remember that this name is allowed.
869       push @allow, $vname;
870
871       # Generate a program to test for availability of this function.
872       open (TESTFILE, ">$fnamebase.c");
873       print TESTFILE "$prepend";
874       print TESTFILE "#include <$h>\n";
875       # print TESTFILE "#undef $fname\n";
876       print TESTFILE "typedef $type xyzzy$rest;\n";
877       print TESTFILE "$xyzzy *foobarbaz = &$vname;\n";
878       close (TESTFILE);
879
880       $res = compiletest ($fnamebase, "Test availability of variable $vname",
881                           "Variable \"$vname\" is not available.", $res, 0);
882
883       # Generate a program to test for the type of this function.
884       open (TESTFILE, ">$fnamebase.c");
885       print TESTFILE "$prepend";
886       print TESTFILE "#include <$h>\n";
887       # print TESTFILE "#undef $fname\n";
888       print TESTFILE "extern $type $vname$rest;\n";
889       close (TESTFILE);
890
891       compiletest ($fnamebase, "Test for type of variable $fname",
892                    "Variable \"$vname\" has incorrect type.", $res, 0);
893     } elsif (/^macro-function *({([^}]*)}|([a-zA-Z0-9_]*)) ([a-zA-Z0-9_]*) ([(].*[)])/) {
894       my($rettype) = "$2$3";
895       my($fname) = "$4";
896       my($args) = "$5";
897       my($res) = $missing;
898
899       # Remember that this name is allowed.
900       push @allow, $fname;
901
902       # Generate a program to test for availability of this function.
903       open (TESTFILE, ">$fnamebase.c");
904       print TESTFILE "$prepend";
905       print TESTFILE "#include <$h>\n";
906       print TESTFILE "#ifndef $fname\n";
907       print TESTFILE "$rettype (*foobarbaz) $args = $fname;\n";
908       print TESTFILE "#endif\n";
909       close (TESTFILE);
910
911       $res = compiletest ($fnamebase, "Test availability of function $fname",
912                           "Function \"$fname\" is not available.", $res, 0);
913
914       # Generate a program to test for the type of this function.
915       open (TESTFILE, ">$fnamebase.c");
916       print TESTFILE "$prepend";
917       print TESTFILE "#include <$h>\n";
918       print TESTFILE "#ifndef $fname\n";
919       print TESTFILE "extern $rettype (*foobarbaz) $args;\n";
920       print TESTFILE "extern __typeof__ (&$fname) foobarbaz;\n";
921       print TESTFILE "#endif\n";
922       close (TESTFILE);
923
924       compiletest ($fnamebase, "Test for type of function $fname",
925                    "Function \"$fname\" has incorrect type.", $res, 0);
926     } elsif (/^macro-str *([^    ]*) *(\".*\")/) {
927       # The above regex doesn't handle a \" in a string.
928       my($macro) = "$1";
929       my($string) = "$2";
930       my($res) = $missing;
931
932       # Remember that this name is allowed.
933       push @allow, $macro;
934
935       # Generate a program to test for availability of this macro.
936       open (TESTFILE, ">$fnamebase.c");
937       print TESTFILE "$prepend";
938       print TESTFILE "#include <$h>\n";
939       print TESTFILE "#ifndef $macro\n";
940       print TESTFILE "# error \"Macro $macro not defined\"\n";
941       print TESTFILE "#endif\n";
942       close (TESTFILE);
943
944       compiletest ($fnamebase, "Test availability of macro $macro",
945                    "Macro \"$macro\" is not available.", $missing, 0);
946
947       # Generate a program to test for the value of this macro.
948       open (TESTFILE, ">$fnamebase.c");
949       print TESTFILE "$prepend";
950       print TESTFILE "#include <$h>\n";
951       # We can't include <string.h> here.
952       print TESTFILE "extern int (strcmp)(const char *, const char *);\n";
953       print TESTFILE "int main (void) { return (strcmp) ($macro, $string) != 0;}\n";
954       close (TESTFILE);
955
956       $res = runtest ($fnamebase, "Testing for value of macro $macro",
957                       "Macro \"$macro\" has not the right value.", $res);
958     } elsif (/^optional-macro *([^      ]*)/) {
959       my($macro) = "$1";
960
961       # Remember that this name is allowed.
962       push @allow, $macro;
963
964       # Generate a program to test for availability of this macro.
965       open (TESTFILE, ">$fnamebase.c");
966       print TESTFILE "$prepend";
967       print TESTFILE "#include <$h>\n";
968       print TESTFILE "#ifndef $macro\n";
969       print TESTFILE "# error \"Macro $macro not defined\"\n";
970       print TESTFILE "#endif\n";
971       close (TESTFILE);
972
973       compiletest ($fnamebase, "Test availability of macro $macro",
974                    "NOT PRESENT", $missing, 1);
975     } elsif (/^macro *([a-zA-Z0-9_]*) *([>=<]+) ([A-Za-z0-9_]*)/) {
976       my($macro) = "$1";
977       my($op) = $2;
978       my($value) = $3;
979       my($res) = $missing;
980
981       # Remember that this name is allowed.
982       push @allow, $macro;
983
984       # Generate a program to test for availability of this macro.
985       open (TESTFILE, ">$fnamebase.c");
986       print TESTFILE "$prepend";
987       print TESTFILE "#include <$h>\n";
988       print TESTFILE "#ifndef $macro\n";
989       print TESTFILE "# error \"Macro $macro not defined\"\n";
990       print TESTFILE "#endif\n";
991       close (TESTFILE);
992
993       $res = compiletest ($fnamebase, "Test availability of macro $macro",
994                           "Macro \"$macro\" is not available.", $res, 0);
995
996       if ($value ne "") {
997         # Generate a program to test for the value of this constant.
998         open (TESTFILE, ">$fnamebase.c");
999         print TESTFILE "$prepend";
1000         print TESTFILE "#include <$h>\n";
1001         # Negate the value since 0 means ok
1002         print TESTFILE "int main (void) { return !($macro $op $value); }\n";
1003         close (TESTFILE);
1004
1005         $res = runtest ($fnamebase, "Testing for value of constant $macro",
1006                         "Macro \"$macro\" has not the right value.", $res);
1007       }
1008     } elsif (/^macro *([^       ]*)/) {
1009       my($macro) = "$1";
1010
1011       # Remember that this name is allowed.
1012       push @allow, $macro;
1013
1014       # Generate a program to test for availability of this macro.
1015       open (TESTFILE, ">$fnamebase.c");
1016       print TESTFILE "$prepend";
1017       print TESTFILE "#include <$h>\n";
1018       print TESTFILE "#ifndef $macro\n";
1019       print TESTFILE "# error \"Macro $macro not defined\"\n";
1020       print TESTFILE "#endif\n";
1021       close (TESTFILE);
1022
1023       compiletest ($fnamebase, "Test availability of macro $macro",
1024                    "Macro \"$macro\" is not available.", $missing, 0);
1025     } elsif (/^allow-header *(.*)/) {
1026       my($pattern) = $1;
1027       if ($seenheader{$pattern} != 1) {
1028         push @allowheader, $pattern;
1029         $seenheader{$pattern} = 1;
1030       }
1031       next control;
1032     } elsif (/^allow *(.*)/) {
1033       my($pattern) = $1;
1034       push @allow, $pattern;
1035       next control;
1036     } else {
1037       # printf ("line is `%s'\n", $_);
1038       next control;
1039     }
1040
1041     printf ("\n");
1042   }
1043   close (CONTROL);
1044
1045   # Read the data files for the header files which are allowed to be included.
1046   while ($#allowheader >= 0) {
1047     my($ah) = pop @allowheader;
1048
1049     open (ALLOW, "$CC -E -D$dialect - < data/$ah-data |");
1050     acontrol: while (<ALLOW>) {
1051       chop;
1052       next acontrol if (/^#/);
1053       next acontrol if (/^[     ]*$/);
1054
1055       if (/^element *({([^}]*)}|([^ ]*)) *({([^}]*)}|([^ ]*)) *([A-Za-z0-9_]*) *(.*)/) {
1056         push @allow, $7;
1057       } elsif (/^constant *([a-zA-Z0-9_]*) *([A-Za-z0-9_]*)?/) {
1058         push @allow, $1;
1059       } elsif (/^typed-constant *([a-zA-Z0-9_]*) *({([^}]*)}|([^ ]*)) *([A-Za-z0-9_]*)?/) {
1060         push @allow, 1;
1061       } elsif (/^(type|tag) *({([^}]*)|([a-zA-Z0-9_]*))/) {
1062         my($type) = "$3$4";
1063
1064         # Remember that this name is allowed.
1065         if ($type =~ /^struct *(.*)/) {
1066           push @allow, $1;
1067         } elsif ($type =~ /^union *(.*)/) {
1068           push @allow, $1;
1069         } else {
1070           push @allow, $type;
1071         }
1072       } elsif (/^function *({([^}]*)}|([a-zA-Z0-9_]*)) [(][*]([a-zA-Z0-9_]*) ([(].*[)])/) {
1073         push @allow, $4;
1074       } elsif (/^function *({([^}]*)}|([a-zA-Z0-9_]*)) ([a-zA-Z0-9_]*) ([(].*[)])/) {
1075         push @allow, $4;
1076       } elsif (/^variable *({([^}]*)}|([a-zA-Z0-9_]*)) ([a-zA-Z0-9_]*)/) {
1077         push @allow, $4;
1078       } elsif (/^macro-function *({([^}]*)}|([a-zA-Z0-9_]*)) ([a-zA-Z0-9_]*) ([(].*[)])/) {
1079         push @allow, $4;
1080       } elsif (/^macro *([^     ]*)/) {
1081         push @allow, $1;
1082       } elsif (/^allow-header *(.*)/) {
1083         if ($seenheader{$1} != 1) {
1084           push @allowheader, $1;
1085           $seenheader{$1} = 1;
1086         }
1087       } elsif (/^allow *(.*)/) {
1088         push @allow, $1;
1089       }
1090     }
1091     close (ALLOW);
1092   }
1093
1094   # Now check the namespace.
1095   printf ("  Checking the namespace of \"%s\"... ", $h);
1096   if ($missing) {
1097     ++$skipped;
1098     printf ("SKIP\n");
1099   } else {
1100     checknamespace ($h, $fnamebase, @allow);
1101   }
1102
1103   printf ("\n\n");
1104 }
1105
1106 printf "-" x 76 . "\n";
1107 printf ("  Total number of tests   : %4d\n", $total);
1108
1109 printf ("  Number of known failures: %4d (", $known);
1110 $percent = ($known * 100) / $total;
1111 if ($known > 0 && $percent < 1.0) {
1112   printf (" <1%%)\n");
1113 } else {
1114   printf ("%3d%%)\n", $percent);
1115 }
1116
1117 printf ("  Number of failed tests  : %4d (", $errors);
1118 $percent = ($errors * 100) / $total;
1119 if ($errors > 0 && $percent < 1.0) {
1120   printf (" <1%%)\n");
1121 } else {
1122   printf ("%3d%%)\n", $percent);
1123 }
1124
1125 printf ("  Number of skipped tests : %4d (", $skipped);
1126 $percent = ($skipped * 100) / $total;
1127 if ($skipped > 0 && $percent < 1.0) {
1128   printf (" <1%%)\n");
1129 } else {
1130   printf ("%3d%%)\n", $percent);
1131 }
1132
1133 exit $errors != 0;