Fix use of restrict in wchar.h
[glibc.git] / conform / conformtest.pl
blobd324d81c53f3aa220c73dbab7306e93181db7672
1 #! /usr/bin/perl
3 use Getopt::Long;
4 use POSIX;
6 $CC = "gcc";
8 $dialect="XOPEN2K";
9 GetOptions ('headers=s' => \@headers, 'dialect=s' => \$dialect);
10 @headers = split(/,/,join(',',@headers));
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");
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\"";
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";
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');
56 # These are symbols which are known to pollute the namespace.
57 @knownproblems = ('unix', 'linux', 'i386');
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";
71 # Make a hash table from this information.
72 while ($#keywords >= 0) {
73 $iskeyword{pop (@keywords)} = 1;
76 # Make a hash table from the known problems.
77 while ($#knownproblems >= 0) {
78 $isknown{pop (@knownproblems)} = 1;
81 $uid = getuid();
82 ($pwname,$pwpasswd,$pwuid,$pwgid,
83 $pwquota,$pwcomment,$pwgcos,$pwdir,$pwshell,$pwexpire) = getpwuid($uid);
84 $tmpdir = "$pwdir";
86 $verbose = 1;
88 $total = 0;
89 $skipped = 0;
90 $errors = 0;
93 sub poorfnmatch {
94 my($pattern, $string) = @_;
95 my($strlen) = length ($string);
96 my($res);
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;
109 return $res;
113 sub compiletest
115 my($fnamebase, $msg, $errmsg, $skip, $optional) = @_;
116 my($result) = $skip;
117 my($printlog) = 0;
119 ++$total;
120 printf (" $msg...");
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;
137 ++$errors;
138 $result = 1;
140 } else {
141 printf (" OK\n");
142 if ($verbose > 1 && -s "$fnamebase.out") {
143 # We print all warnings issued.
144 $printlog = 1;
147 if ($printlog != 0) {
148 printf (" " . "-" x 71 . "\n");
149 open (MESSAGE, "< $fnamebase.out");
150 while (<MESSAGE>) {
151 printf (" %s", $_);
153 close (MESSAGE);
154 printf (" " . "-" x 71 . "\n");
157 unlink "$fnamebase.c";
158 unlink "$fnamebase.o";
159 unlink "$fnamebase.out";
161 $result;
165 sub runtest
167 my($fnamebase, $msg, $errmsg, $skip) = @_;
168 my($result) = $skip;
169 my($printlog) = 0;
171 ++$total;
172 printf (" $msg...");
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;
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";
197 } else {
198 printf (" FAIL\n");
199 ++$errors;
200 $printlog = 1;
201 unlink "$fnamebase.out";
202 rename "$fnamebase.out2", "$fnamebase.out";
205 if ($printlog != 0) {
206 printf (" " . "-" x 71 . "\n");
207 open (MESSAGE, "< $fnamebase.out");
208 while (<MESSAGE>) {
209 printf (" %s", $_);
211 close (MESSAGE);
212 printf (" " . "-" x 71 . "\n");
215 unlink "$fnamebase";
216 unlink "$fnamebase.c";
217 unlink "$fnamebase.o";
218 unlink "$fnamebase.out";
219 unlink "$fnamebase.out2";
221 $result;
225 sub newtoken {
226 my($token, @allow) = @_;
227 my($idx);
229 return if ($token =~ /^[0-9_]/ || $iskeyword{$token});
231 for ($idx = 0; $idx <= $#allow; ++$idx) {
232 return if (poorfnmatch ($allow[$idx], $token));
235 if ($isknown{$token}) {
236 ++$nknown;
237 } else {
238 $errors{$token} = 1;
243 sub removetoken {
244 my($token) = @_;
245 my($idx);
247 return if ($token =~ /^[0-9_]/ || $iskeyword{$token});
249 if (exists $errors{$token}) {
250 undef $errors{$token};
255 sub checknamespace {
256 my($h, $fnamebase, @allow) = @_;
258 ++$total;
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);
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);
280 foreach $token (split(/[^a-zA-Z0-9_]/, $str)) {
281 if ($token ne "") {
282 newtoken ($token, @allow);
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;
299 printf (" Namespace violation: \"%s\"\n", $f);
302 printf (" " . "-" x 72 . "\n") if ($realerror != 0);
305 if ($realerror == 0) {
306 if ($nknown > 0) {
307 printf ("EXPECTED FAILURES\n");
308 ++$known;
309 } else {
310 printf ("OK\n");
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};
327 printf ("Testing <$h>\n");
328 printf ("----------" . "-" x length ($h) . "\n");
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);
336 $missing = compiletest ($fnamebase, "Checking whether <$h> is available",
337 "Header <$h> not available", 0, 0);
339 printf ("\n");
341 open (CONTROL, "$CC -E -D$dialect - < data/$h-data |");
342 control: while (<CONTROL>) {
343 chop;
344 next control if (/^#/);
345 next control if (/^[ ]*$/);
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;
354 # Remember that this name is allowed.
355 push @allow, $member;
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);
369 $res = compiletest ($fnamebase, "Testing for member $member",
370 "Member \"$member\" not available.", $res, 0);
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);
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;
392 # Remember that this name is allowed.
393 push @allow, $member;
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);
407 $res = compiletest ($fnamebase, "Testing for member $member",
408 "NOT AVAILABLE.", $res, 1);
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);
420 compiletest ($fnamebase, "Testing for type of member $member",
421 "Member \"$member\" does not have the correct type.",
422 $res, 0);
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;
430 # Remember that this name is allowed.
431 push @allow, $const;
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);
440 $res = compiletest ($fnamebase, "Testing for constant $const",
441 "NOT PRESENT", $res, 1);
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);
452 $res = runtest ($fnamebase, "Testing for value of constant $const",
453 "Constant \"$const\" has not the right value.", $res);
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;
461 # Remember that this name is allowed.
462 push @allow, $const;
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);
471 $res = compiletest ($fnamebase, "Testing for constant $const",
472 "Constant \"$const\" not available.", $res, 0);
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);
483 $res = runtest ($fnamebase, "Testing for value of constant $const",
484 "Constant \"$const\" has not the right value.", $res);
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;
492 # Remember that this name is allowed.
493 push @allow, $const;
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);
502 $res = compiletest ($fnamebase, "Testing for constant $const",
503 "Constant \"$const\" not available.", $res, 0);
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);
513 compiletest ($fnamebase, "Testing for type of constant $const",
514 "Constant \"$const\" does not have the correct type.",
515 $res, 0);
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);
525 $res = runtest ($fnamebase, "Testing for value of constant $const",
526 "Constant \"$const\" has not the right value.", $res);
528 } elsif (/^optional-constant *([a-zA-Z0-9_]*) *([A-Za-z0-9_]*)?/) {
529 my($const) = $1;
530 my($value) = $2;
531 my($res) = $missing;
533 # Remember that this name is allowed.
534 push @allow, $const;
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);
543 $res = compiletest ($fnamebase, "Testing for constant $const",
544 "NOT PRESENT", $res, 1);
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);
554 $res = runtest ($fnamebase, "Testing for value of constant $const",
555 "Constant \"$const\" has not the right value.", $res);
557 } elsif (/^constant *([a-zA-Z0-9_]*) *([A-Za-z0-9_]*)?/) {
558 my($const) = $1;
559 my($value) = $2;
560 my($res) = $missing;
562 # Remember that this name is allowed.
563 push @allow, $const;
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);
572 $res = compiletest ($fnamebase, "Testing for constant $const",
573 "Constant \"$const\" not available.", $res, 0);
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);
583 $res = runtest ($fnamebase, "Testing for value of constant $const",
584 "Constant \"$const\" has not the right value.", $res);
586 } elsif (/^symbol *([a-zA-Z0-9_]*) *([A-Za-z0-9_]*)?/) {
587 my($symbol) = $1;
588 my($value) = $2;
589 my($res) = $missing;
591 # Remember that this name is allowed.
592 push @allow, $symbol;
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);
603 $res = compiletest ($fnamebase, "Testing for symbol $symbol",
604 "Symbol \"$symbol\" not available.", $res, 0);
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);
614 $res = runtest ($fnamebase, "Testing for value of symbol $symbol",
615 "Symbol \"$symbol\" has not the right value.", $res);
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;
623 # Remember that this name is allowed.
624 push @allow, $const;
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);
633 $res = compiletest ($fnamebase, "Testing for constant $const",
634 "Constant \"$const\" not available.", $res, 0);
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);
644 compiletest ($fnamebase, "Testing for type of constant $const",
645 "Constant \"$const\" does not have the correct type.",
646 $res, 0);
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);
656 $res = runtest ($fnamebase, "Testing for value of constant $const",
657 "Constant \"$const\" has not the right value.", $res);
659 } elsif (/^optional-type *({([^}]*)|([a-zA-Z0-9_]*))/) {
660 my($type) = "$2$3";
661 my($maybe_opaque) = 0;
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;
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";
682 close (TESTFILE);
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;
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;
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";
709 close (TESTFILE);
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";
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;
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);
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;
740 # Remember that this name is allowed.
741 push @allow, $fname;
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);
751 $res = compiletest ($fnamebase, "Test availability of function $fname",
752 "NOT AVAILABLE", $res, 1);
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);
764 compiletest ($fnamebase, "Test for type of function $fname",
765 "Function \"$fname\" has incorrect type.", $res, 0);
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;
773 # Remember that this name is allowed.
774 push @allow, $fname;
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);
784 $res = compiletest ($fnamebase, "Test availability of function $fname",
785 "Function \"$fname\" is not available.", $res, 0);
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);
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;
804 # Remember that this name is allowed.
805 push @allow, $fname;
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);
815 $res = compiletest ($fnamebase, "Test availability of function $fname",
816 "NOT AVAILABLE", $res, 1);
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);
828 compiletest ($fnamebase, "Test for type of function $fname",
829 "Function \"$fname\" has incorrect type.", $res, 0);
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;
837 # Remember that this name is allowed.
838 push @allow, $fname;
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);
848 $res = compiletest ($fnamebase, "Test availability of function $fname",
849 "Function \"$fname\" is not available.", $res, 0);
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);
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;
868 # Remember that this name is allowed.
869 push @allow, $vname;
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);
880 $res = compiletest ($fnamebase, "Test availability of variable $vname",
881 "Variable \"$vname\" is not available.", $res, 0);
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);
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;
899 # Remember that this name is allowed.
900 push @allow, $fname;
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);
911 $res = compiletest ($fnamebase, "Test availability of function $fname",
912 "Function \"$fname\" is not available.", $res, 0);
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);
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;
932 # Remember that this name is allowed.
933 push @allow, $macro;
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);
944 compiletest ($fnamebase, "Test availability of macro $macro",
945 "Macro \"$macro\" is not available.", $missing, 0);
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);
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";
961 # Remember that this name is allowed.
962 push @allow, $macro;
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);
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;
981 # Remember that this name is allowed.
982 push @allow, $macro;
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);
993 $res = compiletest ($fnamebase, "Test availability of macro $macro",
994 "Macro \"$macro\" is not available.", $res, 0);
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);
1005 $res = runtest ($fnamebase, "Testing for value of constant $macro",
1006 "Macro \"$macro\" has not the right value.", $res);
1008 } elsif (/^macro *([^ ]*)/) {
1009 my($macro) = "$1";
1011 # Remember that this name is allowed.
1012 push @allow, $macro;
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);
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;
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;
1041 printf ("\n");
1043 close (CONTROL);
1045 # Read the data files for the header files which are allowed to be included.
1046 while ($#allowheader >= 0) {
1047 my($ah) = pop @allowheader;
1049 open (ALLOW, "$CC -E -D$dialect - < data/$ah-data |");
1050 acontrol: while (<ALLOW>) {
1051 chop;
1052 next acontrol if (/^#/);
1053 next acontrol if (/^[ ]*$/);
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";
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;
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;
1087 } elsif (/^allow *(.*)/) {
1088 push @allow, $1;
1091 close (ALLOW);
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);
1103 printf ("\n\n");
1106 printf "-" x 76 . "\n";
1107 printf (" Total number of tests : %4d\n", $total);
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);
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);
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);
1133 exit $errors != 0;