Update.
[platform/upstream/glibc.git] / conform / conformtest.pl
1 #! /usr/bin/perl
2
3 $CC = "gcc";
4 $CFLAGS = "-I. '-D__attribute__(x)=' -D_XOPEN_SOURCE=500";
5
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");
24
25 @headers = ("aio.h");
26
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');
33
34 # Some headers need a bit more attention.
35 $mustprepend{'regex.h'} = "#include <sys/types.h>\n";
36
37 # Make an hash table from this information.
38 while ($#keywords) {
39   $iskeyword{pop (@keywords)} = 1;
40 }
41
42 $tmpdir = "/tmp";
43
44 $verbose = 1;
45
46 $total = 0;
47 $skipped = 0;
48 $errors = 0;
49
50 #$dialect = "ISO";
51 #$dialect = "POSIX";
52 #$dialect = "XPG3";
53 #$dialect = "XPG4";
54 $dialect = "UNIX98";
55
56
57 sub poorfnmatch {
58   my($pattern, $string) = @_;
59   my($strlen) = length ($string);
60   my($res);
61
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));
70   } else {
71     $res = $pattern eq $string;
72   }
73   return $res;
74 }
75
76
77 sub compiletest
78 {
79   my($fnamebase, $msg, $errmsg, $skip) = @_;
80   my($result) = $skip;
81   my($printlog) = 0;
82
83   ++$total;
84   printf ("  $msg...");
85
86   if ($skip != 0) {
87     ++$skipped;
88     printf (" SKIP\n");
89   } else {
90     $ret = system "$CC $CFLAGS -c $fnamebase.c -o $fnamebase.o > $fnamebase.out 2>&1";
91     if ($ret != 0) {
92       printf (" FAIL\n");
93       if ($verbose != 0) {
94         printf ("    $errmsg  Compiler message:\n");
95         $printlog = 1;
96       }
97       ++$errors;
98       $result = 1;
99     } else {
100       printf (" OK\n");
101       if ($verbose > 1 && -s "$fnamebase.out") {
102         # We print all warnings issued.
103         $printlog = 1;
104       }
105     }
106     if ($printlog != 0) {
107       printf ("    " . "-" x 71 . "\n");
108       open (MESSAGE, "< $fnamebase.out");
109       while (<MESSAGE>) {
110         printf ("    %s", $_);
111       }
112       close (MESSAGE);
113       printf ("    " . "-" x 71 . "\n");
114     }
115   }
116   unlink "$fnamebase.c";
117   unlink "$fnamebase.o";
118   unlink "$fnamebase.out";
119
120   $result;
121 }
122
123
124 sub runtest
125 {
126   my($fnamebase, $msg, $errmsg, $skip) = @_;
127   my($result) = $skip;
128   my($printlog) = 0;
129
130   ++$total;
131   printf ("  $msg...");
132
133   if ($skip != 0) {
134     ++$skipped;
135     printf (" SKIP\n");
136   } else {
137     $ret = system "$CC $CFLAGS -o $fnamebase $fnamebase.c > $fnamebase.out 2>&1";
138     if ($ret != 0) {
139       printf (" FAIL\n");
140       if ($verbose != 0) {
141         printf ("    $errmsg  Compiler message:\n");
142         $printlog = 1;
143       }
144       ++$errors;
145       $result = 1;
146     } else {
147       # Now run the program.  If the exit code is not zero something is wrong.
148       $result = system "$fnamebase > $fnamebase.out2 2>&1";
149       if ($result == 0) {
150         printf (" OK\n");
151         if ($verbose > 1 && -s "$fnamebase.out") {
152           # We print all warnings issued.
153           $printlog = 1;
154           system "cat $fnamebase.out2 >> $fnamebase.out";
155         }
156       } else {
157         printf (" FAIL\n");
158         $printlog = 1;
159         unlink "$fnamebase.out";
160         rename "$fnamebase.out2", "$fnamebase.out";
161       }
162     }
163     if ($printlog != 0) {
164       printf ("    " . "-" x 71 . "\n");
165       open (MESSAGE, "< $fnamebase.out");
166       while (<MESSAGE>) {
167         printf ("    %s", $_);
168       }
169       close (MESSAGE);
170       printf ("    " . "-" x 71 . "\n");
171     }
172   }
173   unlink "$fnamebase";
174   unlink "$fnamebase.c";
175   unlink "$fnamebase.o";
176   unlink "$fnamebase.out";
177   unlink "$fnamebase.out2";
178
179   $result;
180 }
181
182
183 sub newtoken {
184   my($token, $nerrors, @allow) = @_;
185   my($idx);
186
187   if ($token =~ /^[0-9_]/ || $iskeyword{$token}) {
188     return $nerrors;
189   }
190
191   for ($idx = 0; $idx <= $#allow; ++$idx) {
192     if (poorfnmatch ($allow[$idx], $token)) {
193       return $nerrors;
194     }
195   }
196
197   ++$nerrors;
198   if ($nerrors == 1) {
199     printf ("FAIL\n    " . "-" x 72 . "\n");
200   }
201   printf ("    Namespace violation: \"%s\"\n", $token);
202   return $nerrors;
203 }
204
205
206 sub checknamespace {
207   my($h, $fnamebase, @allow) = @_;
208   my($nerrors) = 0;
209
210   ++$total;
211
212   # Generate a program to get the contents of this header.
213   open (TESTFILE, ">$fnamebase.c");
214   print TESTFILE "#include <$h>\n";
215   close (TESTFILE);
216
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 /);
220     chop;
221     if (/^#define (.*)/) {
222       $nerrors = newtoken ($1, $nerrors, @allow);
223     } else {
224       # We have to tokenize the line.
225       my($str) = $_;
226       my($index) = 0;
227       my($len) = length ($str);
228
229       foreach $token (split(/[^a-zA-Z0-9_]/, $str)) {
230         if ($token ne "") {
231           $nerrors = newtoken ($token, $nerrors, @allow);
232         }
233       }
234     }
235   }
236   close (CONTENT);
237   unlink "$fnamebase.c";
238   if ($nerrors != 0) {
239     printf ("    " . "-" x 72 . "\n");
240     ++$errors;
241   } else {
242     printf ("OK\n");
243   }
244 }
245
246
247 while ($#headers >= 0) {
248   my($h) = pop (@headers);
249   my($hf) = $h;
250   $hf =~ s|/|-|;
251   my($fnamebase) = "$tmpdir/$hf-test";
252   my($missing);
253   my(@allow) = ();
254   my(@allowheader) = ();
255   my($prepend) = $mustprepend{$h};
256
257   printf ("Testing <$h>\n");
258   printf ("----------" . "-" x length ($h) . "\n");
259
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";
264   close (TESTFILE);
265
266   $missing = compiletest ($fnamebase, "Checking whether <$h> is available",
267                           "Header <$h> not available", 0);
268
269   printf ("\n");
270
271   open (CONTROL, "$CC -E -D$dialect - < data/$h-data |");
272   control: while (<CONTROL>) {
273     chop;
274     next control if (/^#/);
275     next control if (/^[        ]*$/);
276
277     if (/^element *({([^}]*)}|([^ ]*)) *({([^}]*)}|([^ ]*)) *([A-Za-z0-9_]*) *(.*)/) {
278       my($struct) = "$2$3";
279       my($type) = "$5$6";
280       my($member) = "$7";
281       my($rest) = "$8";
282       my($res) = $missing;
283
284       # Remember that this name is allowed.
285       push @allow, $member;
286
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";
297       close (TESTFILE);
298
299       $res = compiletest ($fnamebase, "Testing for member $member",
300                           "Member \"$member\" not available.", $res);
301
302
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";
310       close (TESTFILE);
311
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_]*)/) {
315       my($const) = $1;
316       my($op) = $2;
317       my($value) = $3;
318       my($res) = $missing;
319
320       # Remember that this name is allowed.
321       push @allow, $const;
322
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";
328       close (TESTFILE);
329
330       $res = compiletest ($fnamebase, "Testing for constant $const",
331                           "Constant \"$const\" not available.", $res);
332
333       if ($value ne "") {
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";
340         close (TESTFILE);
341
342         $res = runtest ($fnamebase, "Testing for value of constant $const",
343                         "Constant \"$const\" has not the right value.", $res);
344       }
345     } elsif (/^typed-constant *([a-zA-Z0-9_]*) *({([^}]*)}|([^ ]*)) *([A-Za-z0-9_]*)?/) {
346       my($const) = $1;
347       my($type) = "$3$4";
348       my($value) = $5;
349       my($res) = $missing;
350
351       # Remember that this name is allowed.
352       push @allow, $const;
353
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";
359       close (TESTFILE);
360
361       $res = compiletest ($fnamebase, "Testing for constant $const",
362                           "Constant \"$const\" not available.", $res);
363
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";
370       close (TESTFILE);
371
372       compiletest ($fnamebase, "Testing for type of constant $const",
373                    "Constant \"$const\" does not have the correct type.",
374                    $res);
375
376       if ($value ne "") {
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";
382         close (TESTFILE);
383
384         $res = runtest ($fnamebase, "Testing for value of constant $const",
385                         "Constant \"$const\" has not the right value.", $res);
386       }
387     } elsif (/^constant *([a-zA-Z0-9_]*) *([A-Za-z0-9_]*)?/) {
388       my($const) = $1;
389       my($value) = $2;
390       my($res) = $missing;
391
392       # Remember that this name is allowed.
393       push @allow, $const;
394
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";
400       close (TESTFILE);
401
402       $res = compiletest ($fnamebase, "Testing for constant $const",
403                           "Constant \"$const\" not available.", $res);
404
405       if ($value ne "") {
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";
411         close (TESTFILE);
412
413         $res = runtest ($fnamebase, "Testing for value of constant $const",
414                         "Constant \"$const\" has not the right value.", $res);
415       }
416     } elsif (/^typed-constant *([a-zA-Z0-9_]*) *({([^}]*)}|([^ ]*)) *([A-Za-z0-9_]*)?/) {
417       my($const) = $1;
418       my($type) = "$3$4";
419       my($value) = $5;
420       my($res) = $missing;
421
422       # Remember that this name is allowed.
423       push @allow, $const;
424
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";
430       close (TESTFILE);
431
432       $res = compiletest ($fnamebase, "Testing for constant $const",
433                           "Constant \"$const\" not available.", $res);
434
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";
441       close (TESTFILE);
442
443       compiletest ($fnamebase, "Testing for type of constant $const",
444                    "Constant \"$const\" does not have the correct type.",
445                    $res);
446
447       if ($value ne "") {
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";
453         close (TESTFILE);
454
455         $res = runtest ($fnamebase, "Testing for value of constant $const",
456                         "Constant \"$const\" has not the right value.", $res);
457       }
458     } elsif (/^type *({([^}]*)|([a-zA-Z0-9_]*))/) {
459       my($type) = "$2$3";
460
461       # Remember that this name is allowed.
462       if ($type =~ /^struct *(.*)/) {
463         push @allow, $1;
464       } elsif ($type =~ /^union *(.*)/) {
465         push @allow, $1;
466       } else {
467         push @allow, $type;
468       }
469
470       # Remember that this name is allowed.
471       push @allow, $type;
472
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";
478       close (TESTFILE);
479
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";
484       my($fname) = "$4";
485       my($args) = "$5";
486       my($res) = $missing;
487
488       # Remember that this name is allowed.
489       push @allow, $fname;
490
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";
497       close (TESTFILE);
498
499       $res = compiletest ($fnamebase, "Test availability of function $fname",
500                           "Function \"$fname\" is not available.", $res);
501
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";
509       close (TESTFILE);
510
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";
515       my($fname) = "$4";
516       my($args) = "$5";
517       my($res) = $missing;
518
519       # Remember that this name is allowed.
520       push @allow, $fname;
521
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";
528       close (TESTFILE);
529
530       $res = compiletest ($fnamebase, "Test availability of function $fname",
531                           "Function \"$fname\" is not available.", $res);
532
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";
540       close (TESTFILE);
541
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_]*)/) {
545       my($type) = "$2$3";
546       my($vname) = "$4";
547       my($res) = $missing;
548
549       # Remember that this name is allowed.
550       push @allow, $vname;
551
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";
558       close (TESTFILE);
559
560       $res = compiletest ($fnamebase, "Test availability of variable $vname",
561                           "Variable \"$vname\" is not available.", $res);
562
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";
569       close (TESTFILE);
570
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";
575       my($fname) = "$4";
576       my($args) = "$5";
577       my($res) = $missing;
578
579       # Remember that this name is allowed.
580       push @allow, $fname;
581
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";
589       close (TESTFILE);
590
591       $res = compiletest ($fnamebase, "Test availability of function $fname",
592                           "Function \"$fname\" is not available.", $res);
593
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";
602       close (TESTFILE);
603
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.
608       my($macro) = "$1";
609       my($string) = "$2";
610       my($res) = $missing;
611
612       # Remember that this name is allowed.
613       push @allow, $macro;
614
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";
622       close (TESTFILE);
623
624       compiletest ($fnamebase, "Test availability of macro $macro",
625                    "Macro \"$macro\" is not available.", $missing);
626
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";
634       close (TESTFILE);
635
636       $res = runtest ($fnamebase, "Testing for value of macro $macro",
637                       "Macro \"$macro\" has not the right value.", $res);
638     } elsif (/^macro *([^       ]*)/) {
639       my($macro) = "$1";
640
641       # Remember that this name is allowed.
642       push @allow, $macro;
643
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";
651       close (TESTFILE);
652
653       compiletest ($fnamebase, "Test availability of macro $macro",
654                    "Macro \"$macro\" is not available.", $missing);
655     } elsif (/^allow *(.*)/) {
656       my($pattern) = $1;
657       push @allow, $pattern;
658       next control;
659     } elsif (/^allow-header *(.*)/) {
660       my($pattern) = $1;
661       push @allowheader, $pattern;
662       next control;
663     } else {
664       # printf ("line is `%s'\n", $_);
665       next control;
666     }
667
668     printf ("\n");
669   }
670   close (CONTROL);
671
672   # Read the data files for the header files which are allowed to be included.
673   while ($#allowheader >= 0) {
674     my($ah) = pop @allowheader;
675
676     open (ALLOW, "$CC -E -D$dialect - < data/$ah-data |");
677     acontrol: while (<ALLOW>) {
678       next acontrol if (/^#/);
679       next acontrol if (/^[     ]*$/);
680
681       if (/^element *({([^}]*)}|([^ ]*)) *({([^}]*)}|([^ ]*)) *([A-Za-z0-9_]*) *(.*)/) {
682         push @allow, $7;
683       } elsif (/^constant *([a-zA-Z0-9_]*) *([A-Za-z0-9_]*)?/) {
684         push @allow, $1;
685       } elsif (/^typed-constant *([a-zA-Z0-9_]*) *({([^}]*)}|([^ ]*)) *([A-Za-z0-9_]*)?/) {
686         push @allow, 1;
687       } elsif (/^type *({([^}]*)|([a-zA-Z0-9_]*))/) {
688         my($type) = "$2$3";
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         }
698       } elsif (/^function *({([^}]*)}|([a-zA-Z0-9_]*)) [(][*]([a-zA-Z0-9_]*) ([(].*[)])/) {
699         push @allow, $4;
700       } elsif (/^function *({([^}]*)}|([a-zA-Z0-9_]*)) ([a-zA-Z0-9_]*) ([(].*[)])/) {
701         push @allow, $4;
702       } elsif (/^variable *({([^}]*)}|([a-zA-Z0-9_]*)) ([a-zA-Z0-9_]*)/) {
703         push @allow, $4;
704       } elsif (/^macro-function *({([^}]*)}|([a-zA-Z0-9_]*)) ([a-zA-Z0-9_]*) ([(].*[)])/) {
705         push @allow, $4;
706       } elsif (/^macro *([^     ]*)/) {
707         push @allow, $1;
708       } elsif (/^allow *(.*)/) {
709         push @allow, $1;
710       } elsif (/^allow-header *(.*)/) {
711         push @allowheader, $1;
712       }
713     }
714     close (ALLOW);
715   }
716
717   # Now check the namespace.
718   printf ("  Checking the namespace of \"%s\"... ", $h);
719   if ($missing) {
720     ++$skipped;
721     printf ("SKIP\n");
722   } else {
723     checknamespace ($h, $fnamebase, @allow);
724   }
725
726   printf ("\n\n");
727 }
728
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);
733
734 exit $errors != 0;