re PR fortran/87318 (gfortran.dg/dtio_1.f90 is invalid)
[official-gcc.git] / contrib / filter_params.py
bloba82a8d5728cdb3b282ec80e2c5fb991c1de19702
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.
7 When passed one or more filenames, acts on those files and prints the
8 results to stdout.
10 When run without a filename, runs a unit-testing suite.
11 """
12 import re
13 import sys
14 import unittest
16 # Optional whitespace
17 OPT_WS = '\s*'
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 """
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.
36 # Only comments that begin on the left-most column are converted.
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)
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))
56 # Strip out 'ATTRIBUTE_UNUSED'
57 text = re.sub('\sATTRIBUTE_UNUSED',
58 '',
59 text)
61 # PARAMS(()) is used for K&R compatibility. See ansidecl.h.
62 text = re.sub('PARAMS' + OPT_WS + r'\(\((.*?)\)\)',
63 r'(\1)',
64 text)
66 # Replace 'ENUM_BITFIELD(enum_name)' with 'enum enum_name'.
67 text = re.sub('ENUM_BITFIELD\s*\(([^\)]*)\)',
68 r'enum \1',
69 text)
71 return text
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))
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'))
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 */'))
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'))
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"))
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'))
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'))
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'))
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')
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')
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))
170 if __name__ == '__main__':
171 if len(sys.argv) > 1:
172 act_on_files(sys.argv)
173 else:
174 unittest.main()