]>
Commit | Line | Data |
---|---|---|
892c1fce DM |
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 | text = re.sub(r'^/\* ', | |
38 | r'/** @verbatim ', | |
39 | text, | |
40 | flags=re.MULTILINE) | |
41 | text = re.sub(r'\*/', | |
42 | r' @endverbatim */', | |
43 | text) | |
44 | ||
45 | # Remove GTY markings (potentially multiline ones): | |
46 | text = re.sub('GTY' + OPT_WS + r'\(\(.*?\)\)\s+', | |
47 | '', | |
48 | text, | |
49 | flags=(re.MULTILINE|re.DOTALL)) | |
50 | ||
51 | # Strip out 'ATTRIBUTE_UNUSED' | |
52 | text = re.sub('\sATTRIBUTE_UNUSED', | |
53 | '', | |
54 | text) | |
55 | ||
56 | # PARAMS(()) is used for K&R compatibility. See ansidecl.h. | |
57 | text = re.sub('PARAMS' + OPT_WS + r'\(\((.*?)\)\)', | |
58 | r'(\1)', | |
59 | text) | |
60 | ||
61 | return text | |
62 | ||
63 | class FilteringTests(unittest.TestCase): | |
64 | ''' | |
65 | Unit tests for filter_src. | |
66 | ''' | |
67 | def assert_filters_to(self, src_input, expected_result): | |
68 | # assertMultiLineEqual was added to unittest in 2.7/3.1 | |
69 | if hasattr(self, 'assertMultiLineEqual'): | |
70 | assertion = self.assertMultiLineEqual | |
71 | else: | |
72 | assertion = self.assertEqual | |
73 | assertion(expected_result, filter_src(src_input)) | |
74 | ||
75 | def test_comment_example(self): | |
76 | self.assert_filters_to( | |
77 | ('/* FIRST_LINE\n' | |
78 | ' NEXT_LINE\n' | |
79 | ' FINAL_LINE. */\n'), | |
80 | ('/** @verbatim FIRST_LINE\n' | |
81 | ' NEXT_LINE\n' | |
82 | ' FINAL_LINE. @endverbatim */\n')) | |
83 | ||
84 | def test_oneliner_comment(self): | |
85 | self.assert_filters_to( | |
86 | '/* Returns the string representing CLASS. */\n', | |
87 | ('/** @verbatim Returns the string representing CLASS. @endverbatim */\n')) | |
88 | ||
89 | def test_multiline_comment(self): | |
90 | self.assert_filters_to( | |
91 | ('/* The thread-local storage model associated with a given VAR_DECL\n' | |
92 | " or SYMBOL_REF. This isn't used much, but both trees and RTL refer\n" | |
93 | " to it, so it's here. */\n"), | |
94 | ('/** @verbatim The thread-local storage model associated with a given VAR_DECL\n' | |
95 | " or SYMBOL_REF. This isn't used much, but both trees and RTL refer\n" | |
96 | " to it, so it's here. @endverbatim */\n")) | |
97 | ||
98 | def test_GTY(self): | |
99 | self.assert_filters_to( | |
100 | ('typedef struct GTY(()) alias_pair {\n' | |
101 | ' tree decl;\n' | |
102 | ' tree target;\n' | |
103 | '} alias_pair;\n'), | |
104 | ('typedef struct alias_pair {\n' | |
105 | ' tree decl;\n' | |
106 | ' tree target;\n' | |
107 | '} alias_pair;\n')) | |
108 | ||
109 | def test_multiline_GTY(self): | |
110 | # Ensure that a multiline GTY is filtered out. | |
111 | self.assert_filters_to( | |
112 | ('class GTY((desc ("%h.type"), tag ("SYMTAB_SYMBOL"),\n' | |
113 | '\t chain_next ("%h.next"), chain_prev ("%h.previous")))\n' | |
114 | ' symtab_node_base\n' | |
115 | '{\n'), | |
116 | ('class symtab_node_base\n' | |
117 | '{\n')) | |
118 | ||
119 | def test_ATTRIBUTE_UNUSED(self): | |
120 | # Ensure that ATTRIBUTE_UNUSED is filtered out. | |
121 | self.assert_filters_to( | |
122 | ('static void\n' | |
123 | 'record_set (rtx dest, const_rtx set, void *data ATTRIBUTE_UNUSED)\n' | |
124 | '{\n'), | |
125 | ('static void\n' | |
126 | 'record_set (rtx dest, const_rtx set, void *data)\n' | |
127 | '{\n')) | |
128 | ||
129 | def test_PARAMS(self): | |
130 | self.assert_filters_to( | |
131 | 'char *strcpy PARAMS ((char *dest, char *source));\n', | |
132 | 'char *strcpy (char *dest, char *source);\n') | |
133 | ||
134 | def act_on_files(argv): | |
135 | for filename in argv[1:]: | |
136 | with open(filename) as f: | |
137 | text = f.read() | |
138 | print(filter_src(text)) | |
139 | ||
140 | if __name__ == '__main__': | |
141 | if len(sys.argv) > 1: | |
142 | act_on_files(sys.argv) | |
143 | else: | |
144 | unittest.main() |