(root)/
gcc-13.2.0/
contrib/
filter_params.py
       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 ESC[4;38;5;81mFilteringTests(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
      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()