예제 #1
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)
예제 #2
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"))
예제 #3
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)
예제 #4
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)
예제 #5
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)
예제 #6
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()
예제 #7
0
 def visit_text_block(self, text_block):
     expanded_content = self._macro_expander.expand(text_block.content,
                                                    eval_mode=False)
     return pre_ast.TextBlock(expanded_content)
 def test_collect_includes_with_text_block(self):
     node = pre_ast.TextBlock('some_content')
     actual = self.include_collector.collect_includes(node)
     expected = []
     self.assertEqual(actual, expected)
예제 #9
0
 def test_to_string_with_text_block(self):
     node = pre_ast.TextBlock('some text content')
     actual = self.to_string_visitor.to_string(node)
     expected = 'some text content'
     self.assertEqual(actual, expected)