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