]> git.ipfire.org Git - thirdparty/gcc.git/blame - contrib/filter_params.py
Port Doxygen support script from Perl to Python; add unittests
[thirdparty/gcc.git] / contrib / filter_params.py
CommitLineData
892c1fce
DM
1#!/usr/bin/python
2"""
3Filters 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
7When passed one or more filenames, acts on those files and prints the
8results to stdout.
9
10When run without a filename, runs a unit-testing suite.
11"""
12import re
13import sys
14import unittest
15
16# Optional whitespace
17OPT_WS = '\s*'
18
19def 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
63class 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
134def 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
140if __name__ == '__main__':
141 if len(sys.argv) > 1:
142 act_on_files(sys.argv)
143 else:
144 unittest.main()