111
|
1 #!/usr/bin/python
|
|
2 """
|
|
3 Filters out some of the #defines used throughout the GCC sources:
|
|
4 - GTY(()) marks declarations for gengtype.c
|
|
5 - PARAMS(()) is used for K&R compatibility. See ansidecl.h.
|
|
6
|
|
7 When passed one or more filenames, acts on those files and prints the
|
|
8 results to stdout.
|
|
9
|
|
10 When run without a filename, runs a unit-testing suite.
|
|
11 """
|
|
12 import re
|
|
13 import sys
|
|
14 import unittest
|
|
15
|
|
16 # Optional whitespace
|
|
17 OPT_WS = '\s*'
|
|
18
|
|
19 def filter_src(text):
|
|
20 """
|
|
21 str -> str. We operate on the whole of the source file at once
|
|
22 (rather than individual lines) so that we can have multiline
|
|
23 regexes.
|
|
24 """
|
|
25
|
|
26 # Convert C comments from GNU coding convention of:
|
|
27 # /* FIRST_LINE
|
|
28 # NEXT_LINE
|
|
29 # FINAL_LINE. */
|
|
30 # to:
|
|
31 # /** @verbatim FIRST_LINE
|
|
32 # NEXT_LINE
|
|
33 # FINAL_LINE. @endverbatim */
|
|
34 # so that doxygen will parse them.
|
|
35 #
|
|
36 # Only comments that begin on the left-most column are converted.
|
|
37 #
|
|
38 text = re.sub(r'^/\*\* ',
|
|
39 r'/** @verbatim ',
|
|
40 text,
|
|
41 flags=re.MULTILINE)
|
|
42 text = re.sub(r'^/\* ',
|
|
43 r'/** @verbatim ',
|
|
44 text,
|
|
45 flags=re.MULTILINE)
|
|
46 text = re.sub(r'\*/',
|
|
47 r' @endverbatim */',
|
|
48 text)
|
|
49
|
|
50 # Remove GTY markings (potentially multiline ones):
|
|
51 text = re.sub('GTY' + OPT_WS + r'\(\(.*?\)\)\s+',
|
|
52 '',
|
|
53 text,
|
|
54 flags=(re.MULTILINE|re.DOTALL))
|
|
55
|
|
56 # Strip out 'ATTRIBUTE_UNUSED'
|
|
57 text = re.sub('\sATTRIBUTE_UNUSED',
|
|
58 '',
|
|
59 text)
|
|
60
|
|
61 # PARAMS(()) is used for K&R compatibility. See ansidecl.h.
|
|
62 text = re.sub('PARAMS' + OPT_WS + r'\(\((.*?)\)\)',
|
|
63 r'(\1)',
|
|
64 text)
|
|
65
|
|
66 # Replace 'ENUM_BITFIELD(enum_name)' with 'enum enum_name'.
|
|
67 text = re.sub('ENUM_BITFIELD\s*\(([^\)]*)\)',
|
|
68 r'enum \1',
|
|
69 text)
|
|
70
|
|
71 return text
|
|
72
|
|
73 class FilteringTests(unittest.TestCase):
|
|
74 '''
|
|
75 Unit tests for filter_src.
|
|
76 '''
|
|
77 def assert_filters_to(self, src_input, expected_result):
|
|
78 # assertMultiLineEqual was added to unittest in 2.7/3.1
|
|
79 if hasattr(self, 'assertMultiLineEqual'):
|
|
80 assertion = self.assertMultiLineEqual
|
|
81 else:
|
|
82 assertion = self.assertEqual
|
|
83 assertion(expected_result, filter_src(src_input))
|
|
84
|
|
85 def test_comment_example(self):
|
|
86 self.assert_filters_to(
|
|
87 ('/* FIRST_LINE\n'
|
|
88 ' NEXT_LINE\n'
|
|
89 ' FINAL_LINE. */\n'),
|
|
90 ('/** @verbatim FIRST_LINE\n'
|
|
91 ' NEXT_LINE\n'
|
|
92 ' FINAL_LINE. @endverbatim */\n'))
|
|
93
|
|
94 def test_comment_example_gengtype(self):
|
|
95 self.assert_filters_to(
|
|
96 ('/** Allocate and initialize an input buffer state.\n'
|
|
97 ' * @param file A readable stream.\n'
|
|
98 ' * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.\n'
|
|
99 ' * \n'
|
|
100 ' * @return the allocated buffer state.\n'
|
|
101 ' */'),
|
|
102 ('/** @verbatim Allocate and initialize an input buffer state.\n'
|
|
103 ' * @param file A readable stream.\n'
|
|
104 ' * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.\n'
|
|
105 ' * \n'
|
|
106 ' * @return the allocated buffer state.\n'
|
|
107 ' @endverbatim */'))
|
|
108
|
|
109 def test_oneliner_comment(self):
|
|
110 self.assert_filters_to(
|
|
111 '/* Returns the string representing CLASS. */\n',
|
|
112 ('/** @verbatim Returns the string representing CLASS. @endverbatim */\n'))
|
|
113
|
|
114 def test_multiline_comment(self):
|
|
115 self.assert_filters_to(
|
|
116 ('/* The thread-local storage model associated with a given VAR_DECL\n'
|
|
117 " or SYMBOL_REF. This isn't used much, but both trees and RTL refer\n"
|
|
118 " to it, so it's here. */\n"),
|
|
119 ('/** @verbatim The thread-local storage model associated with a given VAR_DECL\n'
|
|
120 " or SYMBOL_REF. This isn't used much, but both trees and RTL refer\n"
|
|
121 " to it, so it's here. @endverbatim */\n"))
|
|
122
|
|
123 def test_GTY(self):
|
|
124 self.assert_filters_to(
|
|
125 ('typedef struct GTY(()) alias_pair {\n'
|
|
126 ' tree decl;\n'
|
|
127 ' tree target;\n'
|
|
128 '} alias_pair;\n'),
|
|
129 ('typedef struct alias_pair {\n'
|
|
130 ' tree decl;\n'
|
|
131 ' tree target;\n'
|
|
132 '} alias_pair;\n'))
|
|
133
|
|
134 def test_multiline_GTY(self):
|
|
135 # Ensure that a multiline GTY is filtered out.
|
|
136 self.assert_filters_to(
|
|
137 ('class GTY((desc ("%h.type"), tag ("SYMTAB_SYMBOL"),\n'
|
|
138 '\t chain_next ("%h.next"), chain_prev ("%h.previous")))\n'
|
|
139 ' symtab_node_base\n'
|
|
140 '{\n'),
|
|
141 ('class symtab_node_base\n'
|
|
142 '{\n'))
|
|
143
|
|
144 def test_ATTRIBUTE_UNUSED(self):
|
|
145 # Ensure that ATTRIBUTE_UNUSED is filtered out.
|
|
146 self.assert_filters_to(
|
|
147 ('static void\n'
|
|
148 'record_set (rtx dest, const_rtx set, void *data ATTRIBUTE_UNUSED)\n'
|
|
149 '{\n'),
|
|
150 ('static void\n'
|
|
151 'record_set (rtx dest, const_rtx set, void *data)\n'
|
|
152 '{\n'))
|
|
153
|
|
154 def test_PARAMS(self):
|
|
155 self.assert_filters_to(
|
|
156 'char *strcpy PARAMS ((char *dest, char *source));\n',
|
|
157 'char *strcpy (char *dest, char *source);\n')
|
|
158
|
|
159 def test_ENUM_BITFIELD(self):
|
|
160 self.assert_filters_to(
|
|
161 ' ENUM_BITFIELD (sym_intent) intent:2;\n',
|
|
162 ' enum sym_intent intent:2;\n')
|
|
163
|
|
164 def act_on_files(argv):
|
|
165 for filename in argv[1:]:
|
|
166 with open(filename) as f:
|
|
167 text = f.read()
|
|
168 print(filter_src(text))
|
|
169
|
|
170 if __name__ == '__main__':
|
|
171 if len(sys.argv) > 1:
|
|
172 act_on_files(sys.argv)
|
|
173 else:
|
|
174 unittest.main()
|