4 $CFLAGS = "-I. '-D__attribute__(x)=' -D_XOPEN_SOURCE=500";
6 # List of the headers we are testing.
7 @headers = ("math.h", "locale.h", "libgen.h", "langinfo.h", "iso646.h",
8 "inttypes.h", "iconv.h", "grp.h", "glob.h", "ftw.h", "fnmatch.h",
9 "fmtmsg.h", "float.h", "fcntl.h", "errno.h", "dlfcn.h", "dirent.h",
10 "ctype.h", "cpio.h", "assert.h", "aio.h");
12 # These are the ISO C9x keywords.
13 @keywords = ('auto', 'break', 'case', 'char', 'const', 'continue', 'default',
14 'do', 'double', 'else', 'enum', 'extern', 'float', 'for', 'goto',
15 'if', 'inline', 'int', 'long', 'register', 'restrict', 'return',
16 'short', 'signed', 'sizeof', 'static', 'struct', 'switch',
17 'typedef', 'union', 'unsigned', 'void', 'volatile', 'while');
19 # Make an hash table from this information.
21 $iskeyword{pop (@keywords)} = 1;
40 my($pattern, $string) = @_;
41 my($strlen) = length ($string);
44 if (substr ($pattern, 0, 1) eq '*') {
45 my($patlen) = length ($pattern) - 1;
46 $res = ($strlen >= $patlen
47 && substr ($pattern, -$patlen, $patlen) eq substr ($string, -$patlen, $patlen));
48 } elsif (substr ($pattern, -1, 1) eq '*') {
49 my($patlen) = length ($pattern) - 1;
50 $res = ($strlen >= $patlen
51 && substr ($pattern, 0, $patlen) eq substr ($string, 0, $patlen));
53 $res = $pattern eq $string;
61 my($fnamebase, $msg, $errmsg, $skip) = @_;
72 $ret = system "$CC $CFLAGS -c $fnamebase.c -o $fnamebase.o > $fnamebase.out 2>&1";
76 printf (" $errmsg Compiler message:\n");
83 if ($verbose > 1 && -s "$fnamebase.out") {
84 # We print all warnings issued.
89 printf (" " . "-" x 71 . "\n");
90 open (MESSAGE, "< $fnamebase.out");
95 printf (" " . "-" x 71 . "\n");
98 unlink "$fnamebase.c";
99 unlink "$fnamebase.o";
100 unlink "$fnamebase.out";
108 my($fnamebase, $msg, $errmsg, $skip) = @_;
119 $ret = system "$CC $CFLAGS -o $fnamebase $fnamebase.c > $fnamebase.out 2>&1";
123 printf (" $errmsg Compiler message:\n");
129 # Now run the program. If the exit code is not zero something is wrong.
130 $result = system "$fnamebase > $fnamebase.out2 2>&1";
133 if ($verbose > 1 && -s "$fnamebase.out") {
134 # We print all warnings issued.
136 system "cat $fnamebase.out2 >> $fnamebase.out";
141 unlink "$fnamebase.out";
142 rename "$fnamebase.out2", "$fnamebase.out";
145 if ($printlog != 0) {
146 printf (" " . "-" x 71 . "\n");
147 open (MESSAGE, "< $fnamebase.out");
152 printf (" " . "-" x 71 . "\n");
156 unlink "$fnamebase.c";
157 unlink "$fnamebase.o";
158 unlink "$fnamebase.out";
159 unlink "$fnamebase.out2";
166 my($token, $nerrors, @allow) = @_;
169 for ($idx = 0; $idx <= $#allow; ++$idx) {
170 if ($token =~ /^[0-9_]/ || $iskeyword{$token} || poorfnmatch ($allow[$idx], $token)) {
177 printf ("FAIL\n " . "-" x 72 . "\n");
179 printf (" Namespace violation: \"%s\"\n", $token);
185 my($h, $fnamebase, @allow) = @_;
190 # Generate a program to get the contents of this header.
191 open (TESTFILE, ">$fnamebase.c");
192 print TESTFILE "#include <$h>\n";
195 open (CONTENT, "$CC $CFLAGS -E $fnamebase.c -Wp,-dN | sed -e '/^# [1-9]/d' -e '/^[[:space:]]*\$/d' |");
198 if (/^#define (.*)/) {
199 $nerrors = newtoken ($1, $nerrors, @allow);
201 # We have to tokenize the line.
204 my($len) = length ($str);
206 foreach $token (split(/[^a-zA-Z0-9_]/, $str)) {
208 $nerrors = newtoken ($token, $nerrors, @allow);
214 unlink "$fnamebase.c";
216 printf (" " . "-" x 72 . "\n");
224 while ($#headers >= 0) {
225 my($h) = pop (@headers);
226 my($fnamebase) = "$tmpdir/$h-test";
230 printf ("Testing <$h>\n");
231 printf ("----------" . "-" x length ($h) . "\n");
233 # Generate a program to test for the availability of this header.
234 open (TESTFILE, ">$fnamebase.c");
235 print TESTFILE "#include <$h>\n";
238 $missing = compiletest ($fnamebase, "Checking whether <$h> is available",
239 "Header <$h> not available", 0);
243 open (CONTROL, "$CC -E -D$dialect - < data/$h-data |");
244 control: while (<CONTROL>) {
246 next control if (/^#/);
247 next control if (/^[ ]*$/);
249 if (/^element *({([^}]*)}|([^ ]*)) *({([^}]*)}|([^ ]*)) *([A-Za-z0-9_]*) *(.*)/) {
250 my($struct) = "$2$3";
256 # Remember that this name is allowed.
257 push @allow, $member;
259 # Generate a program to test for the availability of this member.
260 open (TESTFILE, ">$fnamebase.c");
261 print TESTFILE "#include <$h>\n";
262 print TESTFILE "$struct a;\n";
263 print TESTFILE "$struct b;\n";
264 print TESTFILE "extern void xyzzy (__typeof__ (&b.$member), __typeof__ (&a.$member), unsigned);\n";
265 print TESTFILE "void foobarbaz (void) {\n";
266 print TESTFILE " xyzzy (&a.$member, &b.$member, sizeof (a.$member));\n";
267 print TESTFILE "}\n";
270 $res = compiletest ($fnamebase, "Testing for member $member",
271 "Member \"$member\" not available.", $res);
274 # Test the types of the members.
275 open (TESTFILE, ">$fnamebase.c");
276 print TESTFILE "#include <$h>\n";
277 print TESTFILE "$struct a;\n";
278 print TESTFILE "extern $type b$rest;\n";
279 print TESTFILE "extern __typeof__ (a.$member) b;\n";
282 compiletest ($fnamebase, "Testing for type of member $member",
283 "Member \"$member\" does not have the correct type.", $res);
284 } elsif (/^constant *([a-zA-Z0-9_]*) *([A-Za-z0-9_]*)?/) {
289 # Remember that this name is allowed.
292 # Generate a program to test for the availability of this constant.
293 open (TESTFILE, ">$fnamebase.c");
294 print TESTFILE "#include <$h>\n";
295 print TESTFILE "__typeof__ ($const) a = $const;\n";
298 $res = compiletest ($fnamebase, "Testing for constant $const",
299 "Constant \"$const\" not available.", $res);
302 # Generate a program to test for the value of this constant.
303 open (TESTFILE, ">$fnamebase.c");
304 print TESTFILE "#include <$h>\n";
305 print TESTFILE "int main (void) { return $const != $value; }\n";
308 $res = runtest ($fnamebase, "Testing for value of constant $const",
309 "Constant \"$const\" has not the right value.", $res);
311 } elsif (/^type *({([^}]*)|([a-zA-Z0-9_]*))/) {
314 # Remember that this name is allowed.
315 if ($type =~ /^struct *(.*)/) {
317 } elsif ($type =~ /^union *(.*)/) {
323 # Remember that this name is allowed.
326 # Generate a program to test for the availability of this constant.
327 open (TESTFILE, ">$fnamebase.c");
328 print TESTFILE "#include <$h>\n";
329 print TESTFILE "$type *a;\n";
332 compiletest ($fnamebase, "Testing for type $type",
333 "Type \"$type\" not available.", $missing);
334 } elsif (/^function *({([^}]*)}|([a-zA-Z0-9_]*)) ([a-zA-Z0-9_]*) ([(][^)]*[)])/) {
335 my($rettype) = "$2$3";
340 # Remember that this name is allowed.
343 # Generate a program to test for availability of this function.
344 open (TESTFILE, ">$fnamebase.c");
345 print TESTFILE "#include <$h>\n";
346 # print TESTFILE "#undef $fname\n";
347 print TESTFILE "$rettype (*foobarbaz) $args = $fname;\n";
350 $res = compiletest ($fnamebase, "Test availability of function $fname",
351 "Function \"$fname\" is not available.", $res);
353 # Generate a program to test for the type of this function.
354 open (TESTFILE, ">$fnamebase.c");
355 print TESTFILE "#include <$h>\n";
356 # print TESTFILE "#undef $fname\n";
357 print TESTFILE "extern $rettype (*foobarbaz) $args;\n";
358 print TESTFILE "extern __typeof__ (&$fname) foobarbaz;\n";
361 compiletest ($fnamebase, "Test for type of function $fname",
362 "Function \"$fname\" has incorrect type.", $res);
363 } elsif (/^macro *([^ ]*)/) {
366 # Remember that this name is allowed.
369 # Generate a program to test for availability of this macro.
370 open (TESTFILE, ">$fnamebase.c");
371 print TESTFILE "#include <$h>\n";
372 print TESTFILE "#ifndef $macro\n";
373 print TESTFILE "# error \"Macro $macro not defined\"\n";
374 print TESTFILE "#endif\n";
377 compiletest ($fnamebase, "Test availability of macro $macro",
378 "Macro \"$macro\" is not available.", $missing);
379 } elsif (/^allow *(.*)/) {
381 push @allow, $pattern;
384 # printf ("line is `%s'\n", $_);
392 # Now check the namespace.
393 printf (" Checking the namespace of \"%s\"... ", $h);
398 checknamespace ($h, $fnamebase, @allow);
404 printf "-" x 76 . "\n";
405 printf (" Total number of tests : %4d\n", $total);
406 printf (" Number of failed tests : %4d (%3d%%)\n", $errors, ($errors * 100) / $total);
407 printf (" Number of skipped tests: %4d (%3d%%)\n", $skipped, ($skipped * 100) / $total);