123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174 |
- #!/usr/bin/python
- """
- Filters out some of the #defines used throughout the GCC sources:
- - GTY(()) marks declarations for gengtype.c
- - PARAMS(()) is used for K&R compatibility. See ansidecl.h.
- When passed one or more filenames, acts on those files and prints the
- results to stdout.
- When run without a filename, runs a unit-testing suite.
- """
- import re
- import sys
- import unittest
- # Optional whitespace
- OPT_WS = '\s*'
- def filter_src(text):
- """
- str -> str. We operate on the whole of the source file at once
- (rather than individual lines) so that we can have multiline
- regexes.
- """
- # Convert C comments from GNU coding convention of:
- # /* FIRST_LINE
- # NEXT_LINE
- # FINAL_LINE. */
- # to:
- # /** @verbatim FIRST_LINE
- # NEXT_LINE
- # FINAL_LINE. @endverbatim */
- # so that doxygen will parse them.
- #
- # Only comments that begin on the left-most column are converted.
- #
- text = re.sub(r'^/\*\* ',
- r'/** @verbatim ',
- text,
- flags=re.MULTILINE)
- text = re.sub(r'^/\* ',
- r'/** @verbatim ',
- text,
- flags=re.MULTILINE)
- text = re.sub(r'\*/',
- r' @endverbatim */',
- text)
- # Remove GTY markings (potentially multiline ones):
- text = re.sub('GTY' + OPT_WS + r'\(\(.*?\)\)\s+',
- '',
- text,
- flags=(re.MULTILINE|re.DOTALL))
- # Strip out 'ATTRIBUTE_UNUSED'
- text = re.sub('\sATTRIBUTE_UNUSED',
- '',
- text)
- # PARAMS(()) is used for K&R compatibility. See ansidecl.h.
- text = re.sub('PARAMS' + OPT_WS + r'\(\((.*?)\)\)',
- r'(\1)',
- text)
- # Replace 'ENUM_BITFIELD(enum_name)' with 'enum enum_name'.
- text = re.sub('ENUM_BITFIELD\s*\(([^\)]*)\)',
- r'enum \1',
- text)
- return text
- class FilteringTests(unittest.TestCase):
- '''
- Unit tests for filter_src.
- '''
- def assert_filters_to(self, src_input, expected_result):
- # assertMultiLineEqual was added to unittest in 2.7/3.1
- if hasattr(self, 'assertMultiLineEqual'):
- assertion = self.assertMultiLineEqual
- else:
- assertion = self.assertEqual
- assertion(expected_result, filter_src(src_input))
- def test_comment_example(self):
- self.assert_filters_to(
- ('/* FIRST_LINE\n'
- ' NEXT_LINE\n'
- ' FINAL_LINE. */\n'),
- ('/** @verbatim FIRST_LINE\n'
- ' NEXT_LINE\n'
- ' FINAL_LINE. @endverbatim */\n'))
- def test_comment_example_gengtype(self):
- self.assert_filters_to(
- ('/** Allocate and initialize an input buffer state.\n'
- ' * @param file A readable stream.\n'
- ' * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.\n'
- ' * \n'
- ' * @return the allocated buffer state.\n'
- ' */'),
- ('/** @verbatim Allocate and initialize an input buffer state.\n'
- ' * @param file A readable stream.\n'
- ' * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.\n'
- ' * \n'
- ' * @return the allocated buffer state.\n'
- ' @endverbatim */'))
- def test_oneliner_comment(self):
- self.assert_filters_to(
- '/* Returns the string representing CLASS. */\n',
- ('/** @verbatim Returns the string representing CLASS. @endverbatim */\n'))
- def test_multiline_comment(self):
- self.assert_filters_to(
- ('/* The thread-local storage model associated with a given VAR_DECL\n'
- " or SYMBOL_REF. This isn't used much, but both trees and RTL refer\n"
- " to it, so it's here. */\n"),
- ('/** @verbatim The thread-local storage model associated with a given VAR_DECL\n'
- " or SYMBOL_REF. This isn't used much, but both trees and RTL refer\n"
- " to it, so it's here. @endverbatim */\n"))
- def test_GTY(self):
- self.assert_filters_to(
- ('typedef struct GTY(()) alias_pair {\n'
- ' tree decl;\n'
- ' tree target;\n'
- '} alias_pair;\n'),
- ('typedef struct alias_pair {\n'
- ' tree decl;\n'
- ' tree target;\n'
- '} alias_pair;\n'))
- def test_multiline_GTY(self):
- # Ensure that a multiline GTY is filtered out.
- self.assert_filters_to(
- ('class GTY((desc ("%h.type"), tag ("SYMTAB_SYMBOL"),\n'
- '\t chain_next ("%h.next"), chain_prev ("%h.previous")))\n'
- ' symtab_node_base\n'
- '{\n'),
- ('class symtab_node_base\n'
- '{\n'))
- def test_ATTRIBUTE_UNUSED(self):
- # Ensure that ATTRIBUTE_UNUSED is filtered out.
- self.assert_filters_to(
- ('static void\n'
- 'record_set (rtx dest, const_rtx set, void *data ATTRIBUTE_UNUSED)\n'
- '{\n'),
- ('static void\n'
- 'record_set (rtx dest, const_rtx set, void *data)\n'
- '{\n'))
- def test_PARAMS(self):
- self.assert_filters_to(
- 'char *strcpy PARAMS ((char *dest, char *source));\n',
- 'char *strcpy (char *dest, char *source);\n')
- def test_ENUM_BITFIELD(self):
- self.assert_filters_to(
- ' ENUM_BITFIELD (sym_intent) intent:2;\n',
- ' enum sym_intent intent:2;\n')
- def act_on_files(argv):
- for filename in argv[1:]:
- with open(filename) as f:
- text = f.read()
- print(filter_src(text))
- if __name__ == '__main__':
- if len(sys.argv) > 1:
- act_on_files(sys.argv)
- else:
- unittest.main()
|