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