]>
Commit | Line | Data |
---|---|---|
2bbd06bc JM |
1 | #!/usr/bin/python |
2 | # Shared code for glibc conformance tests. | |
04277e02 | 3 | # Copyright (C) 2018-2019 Free Software Foundation, Inc. |
2bbd06bc JM |
4 | # This file is part of the GNU C Library. |
5 | # | |
6 | # The GNU C Library is free software; you can redistribute it and/or | |
7 | # modify it under the terms of the GNU Lesser General Public | |
8 | # License as published by the Free Software Foundation; either | |
9 | # version 2.1 of the License, or (at your option) any later version. | |
10 | # | |
11 | # The GNU C Library is distributed in the hope that it will be useful, | |
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
14 | # Lesser General Public License for more details. | |
15 | # | |
16 | # You should have received a copy of the GNU Lesser General Public | |
17 | # License along with the GNU C Library; if not, see | |
5a82c748 | 18 | # <https://www.gnu.org/licenses/>. |
2bbd06bc JM |
19 | |
20 | import os.path | |
21 | import re | |
2bbd06bc JM |
22 | import subprocess |
23 | import tempfile | |
24 | ||
25 | ||
26 | # Compiler options for each standard. | |
27 | CFLAGS = {'ISO': '-ansi', | |
28 | 'ISO99': '-std=c99', | |
29 | 'ISO11': '-std=c11', | |
30 | 'POSIX': '-D_POSIX_C_SOURCE=199506L -ansi', | |
31 | 'XPG4': '-ansi -D_XOPEN_SOURCE', | |
32 | 'XPG42': '-ansi -D_XOPEN_SOURCE -D_XOPEN_SOURCE_EXTENDED', | |
33 | 'UNIX98': '-ansi -D_XOPEN_SOURCE=500', | |
34 | 'XOPEN2K': '-std=c99 -D_XOPEN_SOURCE=600', | |
35 | 'XOPEN2K8': '-std=c99 -D_XOPEN_SOURCE=700', | |
36 | 'POSIX2008': '-std=c99 -D_POSIX_C_SOURCE=200809L'} | |
37 | ||
c3ec0972 JM |
38 | # ISO C90 keywords. |
39 | KEYWORDS_C90 = {'auto', 'break', 'case', 'char', 'const', 'continue', | |
40 | 'default', 'do', 'double', 'else', 'enum', 'extern', 'float', | |
41 | 'for', 'goto', 'if', 'int', 'long', 'register', 'return', | |
42 | 'short', 'signed', 'sizeof', 'static', 'struct', 'switch', | |
43 | 'typedef', 'union', 'unsigned', 'void', 'volatile', 'while'} | |
44 | ||
45 | # ISO C99 keywords. | |
46 | KEYWORDS_C99 = KEYWORDS_C90 | {'inline', 'restrict'} | |
47 | ||
48 | # Keywords for each standard. | |
49 | KEYWORDS = {'ISO': KEYWORDS_C90, | |
50 | 'ISO99': KEYWORDS_C99, | |
51 | 'ISO11': KEYWORDS_C99, | |
52 | 'POSIX': KEYWORDS_C90, | |
53 | 'XPG4': KEYWORDS_C90, | |
54 | 'XPG42': KEYWORDS_C90, | |
55 | 'UNIX98': KEYWORDS_C90, | |
56 | 'XOPEN2K': KEYWORDS_C99, | |
57 | 'XOPEN2K8': KEYWORDS_C99, | |
58 | 'POSIX2008': KEYWORDS_C99} | |
59 | ||
2bbd06bc JM |
60 | |
61 | def list_exported_functions(cc, standard, header): | |
62 | """Return the set of functions exported by a header, empty if an | |
63 | include of the header does not compile. | |
64 | ||
65 | """ | |
66 | cc_all = '%s -D_ISOMAC %s' % (cc, CFLAGS[standard]) | |
954cf3c2 JM |
67 | with tempfile.TemporaryDirectory() as temp_dir: |
68 | c_file_name = os.path.join(temp_dir, 'test.c') | |
69 | aux_file_name = os.path.join(temp_dir, 'test.c.aux') | |
2bbd06bc JM |
70 | with open(c_file_name, 'w') as c_file: |
71 | c_file.write('#include <%s>\n' % header) | |
72 | fns = set() | |
73 | cmd = ('%s -c %s -o /dev/null -aux-info %s' | |
74 | % (cc_all, c_file_name, aux_file_name)) | |
75 | try: | |
76 | subprocess.check_call(cmd, shell=True) | |
77 | except subprocess.CalledProcessError: | |
78 | return fns | |
79 | with open(aux_file_name, 'r') as aux_file: | |
80 | for line in aux_file: | |
81 | line = re.sub(r'/\*.*?\*/', '', line) | |
82 | line = line.strip() | |
83 | if line: | |
84 | # The word before a '(' that isn't '(*' is the | |
85 | # function name before the argument list (not | |
86 | # fully general, but sufficient for -aux-info | |
87 | # output on standard headers). | |
88 | m = re.search(r'([A-Za-z0-9_]+) *\([^*]', line) | |
89 | if m: | |
90 | fns.add(m.group(1)) | |
91 | else: | |
92 | raise ValueError("couldn't parse -aux-info output: %s" | |
93 | % line) | |
2bbd06bc | 94 | return fns |