
1: #! /usr/bin/perl 2: 3: use Getopt::Long; 4: 5: $CC = "gcc"; 6: 7: $dialect="XOPEN2K"; 8: GetOptions ('headers=s' => \@headers, 'dialect=s' => \$dialect); 9: @headers = split(/,/,join(',',@headers)); 10: 11: # List of the headers we are testing. 12: if (@headers == ()) { 13: @headers = ("wordexp.h", "wctype.h", "wchar.h", "varargs.h", "utmpx.h", 14: "utime.h", "unistd.h", "ulimit.h", "ucontext.h", "time.h", 15: "tgmath.h", "termios.h", "tar.h", "sys/wait.h", "sys/utsname.h", 16: "sys/un.h", "sys/uio.h", "sys/types.h", "sys/times.h", 17: "sys/timeb.h", "sys/time.h", "sys/statvfs.h", "sys/stat.h", 18: "sys/socket.h", "sys/shm.h", "sys/sem.h", "sys/select.h", 19: "sys/resource.h", "sys/msg.h", "sys/mman.h", "sys/ipc.h", 20: "syslog.h", "stropts.h", "strings.h", "string.h", "stdlib.h", 21: "stdio.h", "stdint.h", "stddef.h", "stdarg.h", "spawn.h", 22: "signal.h", "setjmp.h", "semaphore.h", "search.h", "sched.h", 23: "regex.h", "pwd.h", "pthread.h", "poll.h", "nl_types.h", 24: "netinet/tcp.h", "netinet/in.h", "net/if.h", "netdb.h", "ndbm.h", 25: "mqueue.h", "monetary.h", "math.h", "locale.h", "libgen.h", 26: "limits.h", "langinfo.h", "iso646.h", "inttypes.h", "iconv.h", 27: "grp.h", "glob.h", "ftw.h", "fnmatch.h", "fmtmsg.h", "float.h", 28: "fcntl.h", "errno.h", "dlfcn.h", "dirent.h", "ctype.h", "cpio.h", 29: "complex.h", "assert.h", "arpa/inet.h", "aio.h"); 30: } 31: 32: if ($dialect ne "ISO" && $dialect ne "POSIX" && $dialect ne "XPG3" 33: && $dialect ne "XPG4" && $dialect ne "UNIX98" && $dialect ne "XOPEN2K") { 34: die "unknown dialect \"$dialect\""; 35: } 36: 37: $CFLAGS{"ISO"} = "-I. -fno-builtin '-D__attribute__(x)=' -ansi"; 38: $CFLAGS{"POSIX"} = "-I. -fno-builtin '-D__attribute__(x)=' -D_POSIX_C_SOURCE=199912"; 39: $CFLAGS{"XPG3"} = "-I. -fno-builtin '-D__attribute__(x)=' -D_XOPEN_SOURCE"; 40: $CFLAGS{"XPG4"} = "-I. -fno-builtin '-D__attribute__(x)=' -D_XOPEN_SOURCE_EXTENDED"; 41: $CFLAGS{"UNIX98"} = "-I. -fno-builtin '-D__attribute__(x)=' -D_XOPEN_SOURCE=500"; 42: $CFLAGS{"XOPEN2K"} = "-I. -fno-builtin '-D__attribute__(x)=' -D_XOPEN_SOURCE=600"; 43: 44: 45: # These are the ISO C99 keywords. 46: @keywords = ('auto', 'break', 'case', 'char', 'const', 'continue', 'default', 47: 'do', 'double', 'else', 'enum', 'extern', 'float', 'for', 'goto', 48: 'if', 'inline', 'int', 'long', 'register', 'restrict', 'return', 49: 'short', 'signed', 'sizeof', 'static', 'struct', 'switch', 50: 'typedef', 'union', 'unsigned', 'void', 'volatile', 'while'); 51: 52: # These are symbols which are known to pollute the namespace. 53: @knownproblems = ('unix', 'linux', 'i386'); 54: 55: # Some headers need a bit more attention. 56: $mustprepend{'inttypes.h'} = "#include <stddef.h>\n"; 57: $mustprepend{'regex.h'} = "#include <sys/types.h>\n"; 58: $mustprepend{'sched.h'} = "#include <sys/types.h>\n"; 59: $mustprepend{'signal.h'} = "#include <pthread.h>\n"; 60: $mustprepend{'stdio.h'} = "#include <sys/types.h>\n"; 61: $mustprepend{'wchar.h'} = "#include <stdarg.h>\n"; 62: $mustprepend{'wordexp.h'} = "#include <stddef.h>\n"; 63: 64: # Make a hash table from this information. 65: while ($#keywords >= 0) { 66: $iskeyword{pop (@keywords)} = 1; 67: } 68: 69: # Make a hash table from the known problems. 70: while ($#knownproblems >= 0) { 71: $isknown{pop (@knownproblems)} = 1; 72: } 73: 74: $tmpdir = "/tmp"; 75: 76: $verbose = 1; 77: 78: $total = 0; 79: $skipped = 0; 80: $errors = 0; 81: 82: 83: sub poorfnmatch { 84: my($pattern, $string) = @_; 85: my($strlen) = length ($string); 86: my($res); 87: 88: if (substr ($pattern, 0, 1) eq '*') { 89: my($patlen) = length ($pattern) - 1; 90: $res = ($strlen >= $patlen 91: && substr ($pattern, -$patlen, $patlen) eq substr ($string, -$patlen, $patlen)); 92: } elsif (substr ($pattern, -1, 1) eq '*') { 93: my($patlen) = length ($pattern) - 1; 94: $res = ($strlen >= $patlen 95: && substr ($pattern, 0, $patlen) eq substr ($string, 0, $patlen)); 96: } else { 97: $res = $pattern eq $string; 98: } 99: return $res; 100: } 101: 102: 103: sub compiletest 104: { 105: my($fnamebase, $msg, $errmsg, $skip, $optional) = @_; 106: my($result) = $skip; 107: my($printlog) = 0; 108: 109: ++$total; 110: printf (" $msg..."); 111: 112: if ($skip != 0) { 113: ++$skipped; 114: printf (" SKIP\n"); 115: } else { 116: $ret = system "$CC $CFLAGS{$dialect} -c $fnamebase.c -o $fnamebase.o > $fnamebase.out 2>&1"; 117: if ($ret != 0) { 118: if ($optional != 0) { 119: printf (" $errmsg\n"); 120: $result = 1; 121: } else { 122: printf (" FAIL\n"); 123: if ($verbose != 0) { 124: printf (" $errmsg Compiler message:\n"); 125: $printlog = 1; 126: } 127: ++$errors; 128: $result = 1; 129: } 130: } else { 131: printf (" OK\n"); 132: if ($verbose > 1 && -s "$fnamebase.out") { 133: # We print all warnings issued. 134: $printlog = 1; 135: } 136: } 137: if ($printlog != 0) { 138: printf (" " . "-" x 71 . "\n"); 139: open (MESSAGE, "< $fnamebase.out"); 140: while (<MESSAGE>) { 141: printf (" %s", $_); 142: } 143: close (MESSAGE); 144: printf (" " . "-" x 71 . "\n"); 145: } 146: } 147: unlink "$fnamebase.c"; 148: unlink "$fnamebase.o"; 149: unlink "$fnamebase.out"; 150: 151: $result; 152: } 153: 154: 155: sub runtest 156: { 157: my($fnamebase, $msg, $errmsg, $skip) = @_; 158: my($result) = $skip; 159: my($printlog) = 0; 160: 161: ++$total; 162: printf (" $msg..."); 163: 164: if ($skip != 0) { 165: ++$skipped; 166: printf (" SKIP\n"); 167: } else { 168: $ret = system "$CC $CFLAGS{$dialect} -o $fnamebase $fnamebase.c > $fnamebase.out 2>&1"; 169: if ($ret != 0) { 170: printf (" FAIL\n"); 171: if ($verbose != 0) { 172: printf (" $errmsg Compiler message:\n"); 173: $printlog = 1; 174: } 175: ++$errors; 176: $result = 1; 177: } else { 178: # Now run the program. If the exit code is not zero something is wrong. 179: $result = system "$fnamebase > $fnamebase.out2 2>&1"; 180: if ($result == 0) { 181: printf (" OK\n"); 182: if ($verbose > 1 && -s "$fnamebase.out") { 183: # We print all warnings issued. 184: $printlog = 1; 185: system "cat $fnamebase.out2 >> $fnamebase.out"; 186: } 187: } else { 188: printf (" FAIL\n"); 189: ++$errors; 190: $printlog = 1; 191: unlink "$fnamebase.out"; 192: rename "$fnamebase.out2", "$fnamebase.out"; 193: } 194: } 195: if ($printlog != 0) { 196: printf (" " . "-" x 71 . "\n"); 197: open (MESSAGE, "< $fnamebase.out"); 198: while (<MESSAGE>) { 199: printf (" %s", $_); 200: } 201: close (MESSAGE); 202: printf (" " . "-" x 71 . "\n"); 203: } 204: } 205: unlink "$fnamebase"; 206: unlink "$fnamebase.c"; 207: unlink "$fnamebase.o"; 208: unlink "$fnamebase.out"; 209: unlink "$fnamebase.out2"; 210: 211: $result; 212: } 213: 214: 215: sub newtoken { 216: my($token, @allow) = @_; 217: my($idx); 218: 219: return if ($token =~ /^[0-9_]/ || $iskeyword{$token}); 220: 221: for ($idx = 0; $idx <= $#allow; ++$idx) { 222: return if (poorfnmatch ($allow[$idx], $token)); 223: } 224: 225: if ($isknown{$token}) { 226: ++$nknown; 227: } else { 228: $errors{$token} = 1; 229: } 230: } 231: 232: 233: sub removetoken { 234: my($token) = @_; 235: my($idx); 236: 237: return if ($token =~ /^[0-9_]/ || $iskeyword{$token}); 238: 239: if (exists $errors{$token}) { 240: undef $errors{$token}; 241: } 242: } 243: 244: 245: sub checknamespace { 246: my($h, $fnamebase, @allow) = @_; 247: 248: ++$total; 249: 250: # Generate a program to get the contents of this header. 251: open (TESTFILE, ">$fnamebase.c"); 252: print TESTFILE "#include <$h>\n"; 253: close (TESTFILE); 254: 255: undef %errors; 256: $nknown = 0; 257: open (CONTENT, "$CC $CFLAGS{$dialect} -E $fnamebase.c -P -Wp,-dN | sed -e '/^# [1-9]/d' -e '/^[[:space:]]*\$/d' |"); 258: loop: while (<CONTENT>) { 259: chop; 260: if (/^#define (.*)/) { 261: newtoken ($1, @allow); 262: } elsif (/^#undef (.*)/) { 263: removetoken ($1); 264: } else { 265: # We have to tokenize the line. 266: my($str) = $_; 267: my($index) = 0; 268: my($len) = length ($str); 269: 270: foreach $token (split(/[^a-zA-Z0-9_]/, $str)) { 271: if ($token ne "") { 272: newtoken ($token, @allow); 273: } 274: } 275: } 276: } 277: close (CONTENT); 278: unlink "$fnamebase.c"; 279: $realerror = 0; 280: if ($#errors != 0) { 281: # Sort the output list so it's easier to compare results with diff. 282: foreach $f (sort keys(%errors)) { 283: if ($errors{$f} == 1) { 284: if ($realerror == 0) { 285: printf ("FAIL\n " . "-" x 72 . "\n"); 286: $realerror = 1; 287: ++$errors; 288: } 289: printf (" Namespace violation: \"%s\"\n", $f); 290: } 291: } 292: printf (" " . "-" x 72 . "\n") if ($realerror != 0); 293: } 294: 295: if ($realerror == 0) { 296: if ($nknown > 0) { 297: printf ("EXPECTED FAILURES\n"); 298: ++$known; 299: } else { 300: printf ("OK\n"); 301: } 302: } 303: } 304: 305: 306: while ($#headers >= 0) { 307: my($h) = pop (@headers); 308: my($hf) = $h; 309: $hf =~ s|/|-|; 310: my($fnamebase) = "$tmpdir/$hf-test"; 311: my($missing); 312: my(@allow) = (); 313: my(@allowheader) = (); 314: my(%seenheader) = (); 315: my($prepend) = $mustprepend{$h}; 316: 317: printf ("Testing <$h>\n"); 318: printf ("----------" . "-" x length ($h) . "\n"); 319: 320: # Generate a program to test for the availability of this header. 321: open (TESTFILE, ">$fnamebase.c"); 322: print TESTFILE "$prepend"; 323: print TESTFILE "#include <$h>\n"; 324: close (TESTFILE); 325: 326: $missing = compiletest ($fnamebase, "Checking whether <$h> is available", 327: "Header <$h> not available", 0, 0); 328: 329: printf ("\n"); 330: 331: open (CONTROL, "$CC -E -D$dialect - < data/$h-data |"); 332: control: while (<CONTROL>) { 333: chop; 334: next control if (/^#/); 335: next control if (/^[ ]*$/); 336: 337: if (/^element *({([^}]*)}|([^{ ]*)) *({([^}]*)}|([^{ ]*)) *([A-Za-z0-9_]*) *(.*)/) { 338: my($struct) = "$2$3"; 339: my($type) = "$5$6"; 340: my($member) = "$7"; 341: my($rest) = "$8"; 342: my($res) = $missing; 343: 344: # Remember that this name is allowed. 345: push @allow, $member; 346: 347: # Generate a program to test for the availability of this member. 348: open (TESTFILE, ">$fnamebase.c"); 349: print TESTFILE "$prepend"; 350: print TESTFILE "#include <$h>\n"; 351: print TESTFILE "$struct a;\n"; 352: print TESTFILE "$struct b;\n"; 353: print TESTFILE "extern void xyzzy (__typeof__ (&b.$member), __typeof__ (&a.$member), unsigned);\n"; 354: print TESTFILE "void foobarbaz (void) {\n"; 355: print TESTFILE " xyzzy (&a.$member, &b.$member, sizeof (a.$member));\n"; 356: print TESTFILE "}\n"; 357: close (TESTFILE); 358: 359: $res = compiletest ($fnamebase, "Testing for member $member", 360: "Member \"$member\" not available.", $res, 0); 361: 362: 363: # Test the types of the members. 364: open (TESTFILE, ">$fnamebase.c"); 365: print TESTFILE "$prepend"; 366: print TESTFILE "#include <$h>\n"; 367: print TESTFILE "$struct a;\n"; 368: print TESTFILE "extern $type b$rest;\n"; 369: print TESTFILE "extern __typeof__ (a.$member) b;\n"; 370: close (TESTFILE); 371: 372: compiletest ($fnamebase, "Testing for type of member $member", 373: "Member \"$member\" does not have the correct type.", 374: $res, 0); 375: } elsif (/^optional-element *({([^}]*)}|([^{ ]*)) *({([^}]*)}|([^{ ]*)) *([A-Za-z0-9_]*) *(.*)/) { 376: my($struct) = "$2$3"; 377: my($type) = "$5$6"; 378: my($member) = "$7"; 379: my($rest) = "$8"; 380: my($res) = $missing; 381: 382: # Remember that this name is allowed. 383: push @allow, $member; 384: 385: # Generate a program to test for the availability of this member. 386: open (TESTFILE, ">$fnamebase.c"); 387: print TESTFILE "$prepend"; 388: print TESTFILE "#include <$h>\n"; 389: print TESTFILE "$struct a;\n"; 390: print TESTFILE "$struct b;\n"; 391: print TESTFILE "extern void xyzzy (__typeof__ (&b.$member), __typeof__ (&a.$member), unsigned);\n"; 392: print TESTFILE "void foobarbaz (void) {\n"; 393: print TESTFILE " xyzzy (&a.$member, &b.$member, sizeof (a.$member));\n"; 394: print TESTFILE "}\n"; 395: close (TESTFILE); 396: 397: $res = compiletest ($fnamebase, "Testing for member $member", 398: "NOT AVAILABLE.", $res, 1); 399: 400: if ($res == 0 || $missing != 0) { 401: # Test the types of the members. 402: open (TESTFILE, ">$fnamebase.c"); 403: print TESTFILE "$prepend"; 404: print TESTFILE "#include <$h>\n"; 405: print TESTFILE "$struct a;\n"; 406: print TESTFILE "extern $type b$rest;\n"; 407: print TESTFILE "extern __typeof__ (a.$member) b;\n"; 408: close (TESTFILE); 409: 410: compiletest ($fnamebase, "Testing for type of member $member", 411: "Member \"$member\" does not have the correct type.", 412: $res, 0); 413: } 414: } elsif (/^optional-constant *([a-zA-Z0-9_]*) ([>=<]+) ([A-Za-z0-9_]*)/) { 415: my($const) = $1; 416: my($op) = $2; 417: my($value) = $3; 418: my($res) = $missing; 419: 420: # Remember that this name is allowed. 421: push @allow, $const; 422: 423: # Generate a program to test for the availability of this constant. 424: open (TESTFILE, ">$fnamebase.c"); 425: print TESTFILE "$prepend"; 426: print TESTFILE "#include <$h>\n"; 427: print TESTFILE "__typeof__ ($const) a = $const;\n"; 428: close (TESTFILE); 429: 430: $res = compiletest ($fnamebase, "Testing for constant $const", 431: "NOT PRESENT", $res, 1); 432: 433: if ($value ne "" && $res == 0) { 434: # Generate a program to test for the value of this constant. 435: open (TESTFILE, ">$fnamebase.c"); 436: print TESTFILE "$prepend"; 437: print TESTFILE "#include <$h>\n"; 438: # Negate the value since 0 means ok 439: print TESTFILE "int main (void) { return !($const $op $value); }\n"; 440: close (TESTFILE); 441: 442: $res = runtest ($fnamebase, "Testing for value of constant $const", 443: "Constant \"$const\" has not the right value.", $res); 444: } 445: } elsif (/^constant *([a-zA-Z0-9_]*) *([>=<]+) ([A-Za-z0-9_]*)/) { 446: my($const) = $1; 447: my($op) = $2; 448: my($value) = $3; 449: my($res) = $missing; 450: 451: # Remember that this name is allowed. 452: push @allow, $const; 453: 454: # Generate a program to test for the availability of this constant. 455: open (TESTFILE, ">$fnamebase.c"); 456: print TESTFILE "$prepend"; 457: print TESTFILE "#include <$h>\n"; 458: print TESTFILE "__typeof__ ($const) a = $const;\n"; 459: close (TESTFILE); 460: 461: $res = compiletest ($fnamebase, "Testing for constant $const", 462: "Constant \"$const\" not available.", $res, 0); 463: 464: if ($value ne "") { 465: # Generate a program to test for the value of this constant. 466: open (TESTFILE, ">$fnamebase.c"); 467: print TESTFILE "$prepend"; 468: print TESTFILE "#include <$h>\n"; 469: # Negate the value since 0 means ok 470: print TESTFILE "int main (void) { return !($const $op $value); }\n"; 471: close (TESTFILE); 472: 473: $res = runtest ($fnamebase, "Testing for value of constant $const", 474: "Constant \"$const\" has not the right value.", $res); 475: } 476: } elsif (/^typed-constant *([a-zA-Z0-9_]*) *({([^}]*)}|([^ ]*)) *([A-Za-z0-9_]*)?/) { 477: my($const) = $1; 478: my($type) = "$3$4"; 479: my($value) = $5; 480: my($res) = $missing; 481: 482: # Remember that this name is allowed. 483: push @allow, $const; 484: 485: # Generate a program to test for the availability of this constant. 486: open (TESTFILE, ">$fnamebase.c"); 487: print TESTFILE "$prepend"; 488: print TESTFILE "#include <$h>\n"; 489: print TESTFILE "__typeof__ ($const) a = $const;\n"; 490: close (TESTFILE); 491: 492: $res = compiletest ($fnamebase, "Testing for constant $const", 493: "Constant \"$const\" not available.", $res, 0); 494: 495: # Test the types of the members. 496: open (TESTFILE, ">$fnamebase.c"); 497: print TESTFILE "$prepend"; 498: print TESTFILE "#include <$h>\n"; 499: print TESTFILE "__typeof__ (($type) 0) a;\n"; 500: print TESTFILE "extern __typeof__ ($const) a;\n"; 501: close (TESTFILE); 502: 503: compiletest ($fnamebase, "Testing for type of constant $const", 504: "Constant \"$const\" does not have the correct type.", 505: $res, 0); 506: 507: if ($value ne "") { 508: # Generate a program to test for the value of this constant. 509: open (TESTFILE, ">$fnamebase.c"); 510: print TESTFILE "$prepend"; 511: print TESTFILE "#include <$h>\n"; 512: print TESTFILE "int main (void) { return $const != $value; }\n"; 513: close (TESTFILE); 514: 515: $res = runtest ($fnamebase, "Testing for value of constant $const", 516: "Constant \"$const\" has not the right value.", $res); 517: } 518: } elsif (/^optional-constant *([a-zA-Z0-9_]*) *([A-Za-z0-9_]*)?/) { 519: my($const) = $1; 520: my($value) = $2; 521: my($res) = $missing; 522: 523: # Remember that this name is allowed. 524: push @allow, $const; 525: 526: # Generate a program to test for the availability of this constant. 527: open (TESTFILE, ">$fnamebase.c"); 528: print TESTFILE "$prepend"; 529: print TESTFILE "#include <$h>\n"; 530: print TESTFILE "__typeof__ ($const) a = $const;\n"; 531: close (TESTFILE); 532: 533: $res = compiletest ($fnamebase, "Testing for constant $const", 534: "NOT PRESENT", $res, 1); 535: 536: if ($value ne "" && $res == 0) { 537: # Generate a program to test for the value of this constant. 538: open (TESTFILE, ">$fnamebase.c"); 539: print TESTFILE "$prepend"; 540: print TESTFILE "#include <$h>\n"; 541: print TESTFILE "int main (void) { return $const != $value; }\n"; 542: close (TESTFILE); 543: 544: $res = runtest ($fnamebase, "Testing for value of constant $const", 545: "Constant \"$const\" has not the right value.", $res); 546: } 547: } elsif (/^constant *([a-zA-Z0-9_]*) *([A-Za-z0-9_]*)?/) { 548: my($const) = $1; 549: my($value) = $2; 550: my($res) = $missing; 551: 552: # Remember that this name is allowed. 553: push @allow, $const; 554: 555: # Generate a program to test for the availability of this constant. 556: open (TESTFILE, ">$fnamebase.c"); 557: print TESTFILE "$prepend"; 558: print TESTFILE "#include <$h>\n"; 559: print TESTFILE "__typeof__ ($const) a = $const;\n"; 560: close (TESTFILE); 561: 562: $res = compiletest ($fnamebase, "Testing for constant $const", 563: "Constant \"$const\" not available.", $res, 0); 564: 565: if ($value ne "") { 566: # Generate a program to test for the value of this constant. 567: open (TESTFILE, ">$fnamebase.c"); 568: print TESTFILE "$prepend"; 569: print TESTFILE "#include <$h>\n"; 570: print TESTFILE "int main (void) { return $const != $value; }\n"; 571: close (TESTFILE); 572: 573: $res = runtest ($fnamebase, "Testing for value of constant $const", 574: "Constant \"$const\" has not the right value.", $res); 575: } 576: } elsif (/^symbol *([a-zA-Z0-9_]*) *([A-Za-z0-9_]*)?/) { 577: my($symbol) = $1; 578: my($value) = $2; 579: my($res) = $missing; 580: 581: # Remember that this name is allowed. 582: push @allow, $symbol; 583: 584: # Generate a program to test for the availability of this constant. 585: open (TESTFILE, ">$fnamebase.c"); 586: print TESTFILE "$prepend"; 587: print TESTFILE "#include <$h>\n"; 588: print TESTFILE "void foobarbaz (void) {\n"; 589: print TESTFILE "__typeof__ ($symbol) a = $symbol;\n"; 590: print TESTFILE "}\n"; 591: close (TESTFILE); 592: 593: $res = compiletest ($fnamebase, "Testing for symbol $symbol", 594: "Symbol \"$symbol\" not available.", $res, 0); 595: 596: if ($value ne "") { 597: # Generate a program to test for the value of this constant. 598: open (TESTFILE, ">$fnamebase.c"); 599: print TESTFILE "$prepend"; 600: print TESTFILE "#include <$h>\n"; 601: print TESTFILE "int main (void) { return $symbol != $value; }\n"; 602: close (TESTFILE); 603: 604: $res = runtest ($fnamebase, "Testing for value of symbol $symbol", 605: "Symbol \"$symbol\" has not the right value.", $res); 606: } 607: } elsif (/^typed-constant *([a-zA-Z0-9_]*) *({([^}]*)}|([^ ]*)) *([A-Za-z0-9_]*)?/) { 608: my($const) = $1; 609: my($type) = "$3$4"; 610: my($value) = $5; 611: my($res) = $missing; 612: 613: # Remember that this name is allowed. 614: push @allow, $const; 615: 616: # Generate a program to test for the availability of this constant. 617: open (TESTFILE, ">$fnamebase.c"); 618: print TESTFILE "$prepend"; 619: print TESTFILE "#include <$h>\n"; 620: print TESTFILE "__typeof__ ($const) a = $const;\n"; 621: close (TESTFILE); 622: 623: $res = compiletest ($fnamebase, "Testing for constant $const", 624: "Constant \"$const\" not available.", $res, 0); 625: 626: # Test the types of the members. 627: open (TESTFILE, ">$fnamebase.c"); 628: print TESTFILE "$prepend"; 629: print TESTFILE "#include <$h>\n"; 630: print TESTFILE "__typeof__ (($type) 0) a;\n"; 631: print TESTFILE "extern __typeof__ ($const) a;\n"; 632: close (TESTFILE); 633: 634: compiletest ($fnamebase, "Testing for type of constant $const", 635: "Constant \"$const\" does not have the correct type.", 636: $res, 0); 637: 638: if ($value ne "") { 639: # Generate a program to test for the value of this constant. 640: open (TESTFILE, ">$fnamebase.c"); 641: print TESTFILE "$prepend"; 642: print TESTFILE "#include <$h>\n"; 643: print TESTFILE "int main (void) { return $const != $value; }\n"; 644: close (TESTFILE); 645: 646: $res = runtest ($fnamebase, "Testing for value of constant $const", 647: "Constant \"$const\" has not the right value.", $res); 648: } 649: } elsif (/^optional-type *({([^}]*)|([a-zA-Z0-9_]*))/) { 650: my($type) = "$2$3"; 651: my($maybe_opaque) = 0; 652: 653: # Remember that this name is allowed. 654: if ($type =~ /^struct *(.*)/) { 655: push @allow, $1; 656: } elsif ($type =~ /^union *(.*)/) { 657: push @allow, $1; 658: } else { 659: push @allow, $type; 660: $maybe_opaque = 1; 661: } 662: 663: # Remember that this name is allowed. 664: push @allow, $type; 665: 666: # Generate a program to test for the availability of this constant. 667: open (TESTFILE, ">$fnamebase.c"); 668: print TESTFILE "$prepend"; 669: print TESTFILE "#include <$h>\n"; 670: if ($maybe_opaque == 1) { 671: print TESTFILE "$type *a;\n"; 672: } else { 673: print TESTFILE "$type a;\n"; 674: } 675: close (TESTFILE); 676: 677: compiletest ($fnamebase, "Testing for type $type", 678: "NOT AVAILABLE", $missing, 1); 679: } elsif (/^type *({([^}]*)|([a-zA-Z0-9_]*))/) { 680: my($type) = "$2$3"; 681: my($maybe_opaque) = 0; 682: 683: # Remember that this name is allowed. 684: if ($type =~ /^struct *(.*)/) { 685: push @allow, $1; 686: } elsif ($type =~ /^union *(.*)/) { 687: push @allow, $1; 688: } else { 689: push @allow, $type; 690: $maybe_opaque = 1; 691: } 692: 693: # Remember that this name is allowed. 694: push @allow, $type; 695: 696: # Generate a program to test for the availability of this type. 697: open (TESTFILE, ">$fnamebase.c"); 698: print TESTFILE "$prepend"; 699: print TESTFILE "#include <$h>\n"; 700: if ($maybe_opaque == 1) { 701: print TESTFILE "$type *a;\n"; 702: } else { 703: print TESTFILE "$type a;\n"; 704: } 705: close (TESTFILE); 706: 707: compiletest ($fnamebase, "Testing for type $type", 708: "Type \"$type\" not available.", $missing, 0); 709: } elsif (/^optional-function *({([^}]*)}|([a-zA-Z0-9_]*)) [(][*]([a-zA-Z0-9_]*) ([(].*[)])/) { 710: my($rettype) = "$2$3"; 711: my($fname) = "$4"; 712: my($args) = "$5"; 713: my($res) = $missing; 714: 715: # Remember that this name is allowed. 716: push @allow, $fname; 717: 718: # Generate a program to test for availability of this function. 719: open (TESTFILE, ">$fnamebase.c"); 720: print TESTFILE "$prepend"; 721: print TESTFILE "#include <$h>\n"; 722: # print TESTFILE "#undef $fname\n"; 723: print TESTFILE "$rettype (*(*foobarbaz) $args = $fname;\n"; 724: close (TESTFILE); 725: 726: $res = compiletest ($fnamebase, "Test availability of function $fname", 727: "NOT AVAILABLE", $res, 1); 728: 729: if ($res == 0 || $missing == 1) { 730: # Generate a program to test for the type of this function. 731: open (TESTFILE, ">$fnamebase.c"); 732: print TESTFILE "$prepend"; 733: print TESTFILE "#include <$h>\n"; 734: # print TESTFILE "#undef $fname\n"; 735: print TESTFILE "extern $rettype (*(*foobarbaz) $args;\n"; 736: print TESTFILE "extern __typeof__ (&$fname) foobarbaz;\n"; 737: close (TESTFILE); 738: 739: compiletest ($fnamebase, "Test for type of function $fname", 740: "Function \"$fname\" has incorrect type.", $res, 0); 741: } 742: } elsif (/^function *({([^}]*)}|([a-zA-Z0-9_]*)) [(][*]([a-zA-Z0-9_]*) ([(].*[)])/) { 743: my($rettype) = "$2$3"; 744: my($fname) = "$4"; 745: my($args) = "$5"; 746: my($res) = $missing; 747: 748: # Remember that this name is allowed. 749: push @allow, $fname; 750: 751: # Generate a program to test for availability of this function. 752: open (TESTFILE, ">$fnamebase.c"); 753: print TESTFILE "$prepend"; 754: print TESTFILE "#include <$h>\n"; 755: # print TESTFILE "#undef $fname\n"; 756: print TESTFILE "$rettype (*(*foobarbaz) $args = $fname;\n"; 757: close (TESTFILE); 758: 759: $res = compiletest ($fnamebase, "Test availability of function $fname", 760: "Function \"$fname\" is not available.", $res, 0);