Exemplo n.º 1
0
    def test_ifdef(self):
        parsed_pre_ast = self.parser.parse("""
    #define BAZ    1024
    int Some(text);
    # if BAZ > 1000
      #define BOO 2
      int more_Text();
    # else
      #define BOO 4
    #endif
    """)

        # Learn about the macros defined above.
        actual = self.visitor.preprocess(parsed_pre_ast)
        expected = pre_ast.CompositeBlock([
            pre_ast.TextBlock(content='int Some(text);'),
            pre_ast.CompositeBlock(
                [pre_ast.TextBlock(content='int more_Text();')])
        ])
        self.assertASTEqual(actual, expected)

        # Make sure that the right macro was defined.
        self.assertASTEqual(
            self.macros.object_likes["BOO"],
            pre_ast.DefineObjectLike(name="BOO", replacement="2"))
Exemplo n.º 2
0
 def test_parse_with_empty_if_elif_and_else_blocks(self):
     source = """
     #if CONFIG_SOMETHING
     #elif defined(CONFIG_SOMETHING_ELSE)
     #else
     #endif
     """
     actual = self.parser.parse(source)
     expected = pre_ast.CompositeBlock([
         pre_ast.If(conditional_blocks=[
             pre_ast.ConditionalBlock(
                 conditional_expression='CONFIG_SOMETHING',
                 content=[],
             ),
             pre_ast.ConditionalBlock(
                 conditional_expression='defined(CONFIG_SOMETHING_ELSE)',
                 content=[],
             ),
             pre_ast.ConditionalBlock(
                 conditional_expression='1',
                 content=[],
             ),
         ]),
     ])
     self.assertASTEqual(actual, expected)
Exemplo n.º 3
0
 def test_parse_pragma_with_string_argument(self):
     source = '#pragma "-foo"'
     actual = self.parser.parse(source)
     expected = pre_ast.CompositeBlock([
         pre_ast.Pragma('"-foo"'),
     ])
     self.assertASTEqual(actual, expected)
Exemplo n.º 4
0
 def test_parse_with_nested_if_blocks(self):
     source = """
     #if CONFIG_SOMETHING
       #if CONFIG_SOMETHING_ELSE
         #define FOO
       #endif
     #else
         #define BAR
     #endif
     """
     actual = self.parser.parse(source)
     expected = pre_ast.CompositeBlock([
         pre_ast.If(conditional_blocks=[
             pre_ast.ConditionalBlock(
                 conditional_expression='CONFIG_SOMETHING',
                 content=[
                     pre_ast.If(conditional_blocks=[
                         pre_ast.ConditionalBlock(
                             conditional_expression="CONFIG_SOMETHING_ELSE",
                             content=[
                                 pre_ast.DefineObjectLike(name="FOO",
                                                          replacement="")
                             ],
                         )
                     ])
                 ]),
             pre_ast.ConditionalBlock(
                 conditional_expression='1',
                 content=[
                     pre_ast.DefineObjectLike(name="BAR", replacement="")
                 ],
             ),
         ]),
     ])
     self.assertASTEqual(actual, expected)
Exemplo n.º 5
0
    def test_parse_with_top_level_ifdef_and_else_blocks(self):
        source = """
int a;
#ifdef CONFIG_SOMETHING
struct s {
  int x;
} y;
struct s t, u;
#else
int z;
#endif
int b;
"""
        actual = self.parser.parse(source)
        expected = pre_ast.CompositeBlock([
            pre_ast.TextBlock('int a;'),
            pre_ast.If(conditional_blocks=[
                pre_ast.ConditionalBlock(
                    conditional_expression='defined(CONFIG_SOMETHING)',
                    content=[
                        pre_ast.TextBlock(
                            '\n'.join((
                                'struct s {',
                                '  int x;',
                                '} y;',
                                'struct s t, u;',
                            )), ),
                    ]),
                pre_ast.ConditionalBlock(conditional_expression="1",
                                         content=[pre_ast.TextBlock('int z;')])
            ]),
            pre_ast.TextBlock('int b;')
        ])
        self.assertASTEqual(actual, expected)
Exemplo n.º 6
0
 def visit_composite_block(self, composite_block):
     preprocessed_content = []
     for element in composite_block.content:
         maybe_preprocessed_element = element.accept(self)
         if maybe_preprocessed_element:
             preprocessed_content.append(maybe_preprocessed_element)
     return pre_ast.CompositeBlock(preprocessed_content)
Exemplo n.º 7
0
 def test_parse_error(self):
     source = '#error foo bar 42 baz'
     actual = self.parser.parse(source)
     expected = pre_ast.CompositeBlock([
         pre_ast.Error('foo bar 42 baz'),
     ])
     self.assertASTEqual(actual, expected)
Exemplo n.º 8
0
 def test_parse_text_block(self):
     source = 'int x;'
     actual = self.parser.parse(source)
     expected = pre_ast.CompositeBlock([
         pre_ast.TextBlock('int x;'),
     ])
     self.assertASTEqual(actual, expected)
Exemplo n.º 9
0
 def test_parse_pragma(self):
     source = '#pragma foo'
     actual = self.parser.parse(source)
     expected = pre_ast.CompositeBlock([
         pre_ast.Pragma('foo'),
     ])
     self.assertASTEqual(actual, expected)
Exemplo n.º 10
0
 def test_parse_undef(self):
     source = '#undef foo'
     actual = self.parser.parse(source)
     expected = pre_ast.CompositeBlock([
         pre_ast.Undef('foo'),
     ])
     self.assertASTEqual(actual, expected)
Exemplo n.º 11
0
 def test_parse_include_with_double_quotes(self):
     source = '#include "some/path/to/file_2.h"'
     actual = self.parser.parse(source)
     expected = pre_ast.CompositeBlock(
         [pre_ast.Include(
             path='some/path/to/file_2.h',
             quotes_type='"',
         )])
     self.assertASTEqual(actual, expected)
Exemplo n.º 12
0
 def test_parse_include_with_angle_brackets(self):
     source = '# include <some/path/to/file_1.h>'
     actual = self.parser.parse(source)
     expected = pre_ast.CompositeBlock(content=[
         pre_ast.Include(
             path='some/path/to/file_1.h',
             quotes_type="<",
         )
     ])
     self.assertASTEqual(actual, expected)
Exemplo n.º 13
0
 def test_parse_define_object_like_as_numeric_constant(self):
     source = '#define foo 42'
     actual = self.parser.parse(source)
     expected = pre_ast.CompositeBlock([
         pre_ast.DefineObjectLike(
             name='foo',
             replacement='42',
         ),
     ])
     self.assertASTEqual(actual, expected)
Exemplo n.º 14
0
 def test_parse_define_empty_object_like(self):
     source = '#define foo'
     actual = self.parser.parse(source)
     expected = pre_ast.CompositeBlock([
         pre_ast.DefineObjectLike(
             name='foo',
             replacement="",
         ),
     ])
     self.assertASTEqual(actual, expected)
Exemplo n.º 15
0
 def test_parse_pragma_and_text_block(self):
     source = '\n'.join((
         '#pragma foo bar',
         'int x;',
     ))
     actual = self.parser.parse(source)
     expected = pre_ast.CompositeBlock([
         pre_ast.Pragma("foo bar"),
         pre_ast.TextBlock('int x;'),
     ])
     self.assertASTEqual(actual, expected)
Exemplo n.º 16
0
 def test_parse_define_empty_funcion_like(self):
     source = '#define foo()'
     actual = self.parser.parse(source)
     expected = pre_ast.CompositeBlock([
         pre_ast.DefineFunctionLike(
             name='foo',
             arguments=[],
             replacement="",
         ),
     ])
     self.assertASTEqual(actual, expected)
Exemplo n.º 17
0
 def test_parse_define_empty_object_like_looks_like_func(self):
     # https://gcc.gnu.org/onlinedocs/cpp/Function-like-Macros.html
     # This is not a function like macro.
     source = '#define foo (bar)'
     actual = self.parser.parse(source)
     expected = pre_ast.CompositeBlock([
         pre_ast.DefineObjectLike(
             name='foo',
             replacement="(bar)",
         ),
     ])
     self.assertASTEqual(actual, expected)
Exemplo n.º 18
0
 def test_parse_define_with_function_like_expression_and_concatenation(
         self):
     source = '#define __DECL_REG(name) uint64_t r ## name;'
     actual = self.parser.parse(source)
     expected = pre_ast.CompositeBlock([
         pre_ast.DefineFunctionLike(
             name='__DECL_REG',
             arguments=["name"],
             replacement='uint64_t r ## name;',
         ),
     ])
     self.assertASTEqual(actual, expected)
Exemplo n.º 19
0
 def test_parse_function_call_with_multiword_argument(self):
     source = 'f(union u)'
     expected = c_ast.CFunctionCall(
         function_name='f',
         arguments=[
             pre_ast.CompositeBlock([
                 c_ast.CVariable('union'),
                 c_ast.CVariable('u'),
             ]),
         ],
     )
     actual = self.parser.parse(source)
     self.assertASTEqual(actual, expected)
Exemplo n.º 20
0
 def test_parse_with_empty_ifndef_block(self):
     source = """
     #ifndef CONFIG_SOMETHING
     #endif
     """
     actual = self.parser.parse(source)
     expected = pre_ast.CompositeBlock([
         pre_ast.If([
             pre_ast.ConditionalBlock(
                 conditional_expression="!defined(CONFIG_SOMETHING)",
                 content=[]),
         ])
     ])
     self.assertASTEqual(actual, expected)
Exemplo n.º 21
0
 def test_parse_multiline_define(self):
     source = '\n'.join([
         '#define foo bar\\',
         '    baz',
         '    42',
     ])
     actual = self.parser.parse(source)
     expected = pre_ast.CompositeBlock([
         pre_ast.DefineObjectLike(
             name='foo',
             replacement='bar    baz',
         ),
         pre_ast.TextBlock('42'),
     ])
     self.assertASTEqual(actual, expected)
 def test_collect_includes_with_composite_block(self):
     mock_conditiona_block_1 = mock.MagicMock()
     mock_conditiona_block_2 = mock.MagicMock()
     mock_conditiona_block_3 = mock.MagicMock()
     node = pre_ast.CompositeBlock([
         mock_conditiona_block_1,
         mock_conditiona_block_2,
         mock_conditiona_block_3,
     ])
     mock_conditiona_block_1.accept.return_value = [33]
     mock_conditiona_block_2.accept.return_value = []
     mock_conditiona_block_3.accept.return_value = ['foo', 42]
     actual = self.include_collector.collect_includes(node)
     expected = [33, 'foo', 42]
     self.assertEqual(actual, expected)
Exemplo n.º 23
0
 def test_to_string_with_composite_block(self):
     mock_node_1 = mock.MagicMock()
     mock_node_2 = mock.MagicMock()
     mock_node_3 = mock.MagicMock()
     node = pre_ast.CompositeBlock([
         mock_node_1,
         mock_node_2,
         mock_node_3,
     ])
     mock_node_1.accept.side_effect = (lambda visitor, parts: parts.extend(
         ('foo', 'bar', '42')))
     mock_node_2.accept.side_effect = (lambda visitor, parts: parts.extend(
         ()))
     mock_node_3.accept.side_effect = (lambda visitor, parts: parts.extend(
         ('33 24', )))
     actual = self.to_string_visitor.to_string(node)
     expected = 'foo bar 42 33 24'
     self.assertEqual(actual, expected)
Exemplo n.º 24
0
 def test_resolve_with_composite_block(self):
     mock_conditional_block_1 = mock.MagicMock()
     mock_conditional_block_2 = mock.MagicMock()
     mock_conditional_block_3 = mock.MagicMock()
     node = pre_ast.CompositeBlock([
         mock_conditional_block_1,
         mock_conditional_block_2,
         mock_conditional_block_3,
     ])
     self.include_linking_visitor.resolve(node, self.files)
     for mock_node in (
             mock_conditional_block_1,
             mock_conditional_block_2,
             mock_conditional_block_3,
     ):
         mock_node.accept.assert_called_once_with(
             self.include_linking_visitor,
             self.files,
         )
Exemplo n.º 25
0
 def test_parse_with_empty_ifndef_header_guard(self):
     source = """
     #ifndef _SOMETHING_H
     #define _SOMETHING_H
     #endif
     """
     actual = self.parser.parse(source)
     expected = pre_ast.CompositeBlock([
         pre_ast.If([
             pre_ast.ConditionalBlock(
                 conditional_expression="!defined(_SOMETHING_H)",
                 content=[
                     pre_ast.DefineObjectLike(
                         name='_SOMETHING_H',
                         replacement="",
                     ),
                 ],
             ),
         ]),
     ])
     self.assertASTEqual(actual, expected)
Exemplo n.º 26
0
    def parse(self, source):
        line_continuation = pyparsing.Literal('\\\n')
        ignorable = (
            line_continuation
            | pyparsing.cppStyleComment.addParseAction(
                pyparsing.ParserElement.resetCache)
            # Removed for now because it is too expensive at this point. We can
            # eliminate those later in the trimming phase.
            # | parser.extern_field()
            | self.static_function()).suppress()
        source = ignorable.transformString(source)
        source = Sanitizer().transform(source)

        # Start parsing: Top level node will be a pre_ast.File
        self.push_node(pre_ast.CompositeBlock(content=[]))
        last_block_end = 0

        scanner = self._preprocessor_directive().parseWithTabs()
        for tokens, start, end in scanner.scanString(source):
            text = source[last_block_end:start].strip()
            if text:
                # We skipped over a text block - push it on the current node.
                self.current_node.content.append(pre_ast.TextBlock(text))

            last_block_end = end

            # Now process the different directives.
            directive, rest_of_line = tokens
            if directive == "include":
                self._process_include(rest_of_line)

            # Im not really sure what #pragma is supposed to do here.
            elif directive == "pragma":
                self.current_node.content.append(pre_ast.Pragma(rest_of_line))

            elif directive == "error":
                self.current_node.content.append(pre_ast.Error(rest_of_line))

            elif directive == "define":
                self._define_parser.parseString(rest_of_line)

            elif directive == "undef":
                self.current_node.content.append(pre_ast.Undef(rest_of_line))

            elif directive == "if":
                self._add_conditional_block(rest_of_line)

            elif directive == "ifdef":
                self._add_conditional_block("defined(%s)" % rest_of_line)

            elif directive == "ifndef":
                self._add_conditional_block("!defined(%s)" % rest_of_line)

            elif directive == "else":
                self._add_elif_block("1")

            elif directive == "elif":
                self._add_elif_block(rest_of_line)

            elif directive == "endif":
                # Pop the stack.
                self.pop_node()  # ConditionalBlock
                self.pop_node()  # If block.

        # Last text node.
        text = source[last_block_end:].strip()
        if text:
            self.current_node.content.append(pre_ast.TextBlock(text))

        return self.pop_node()
Exemplo n.º 27
0
 def test_parse_empty_program(self):
     source = ''
     actual = self.parser.parse(source)
     expected = pre_ast.CompositeBlock([])
     self.assertASTEqual(actual, expected)