Example #1
0
 def test_evaluate_function_call_with_identifier_defined_to_other_identifier(
     self,
 ):
   self.object_likes.update({
       'foo': pre_ast.DefineObjectLike(
           name='foo',
           replacement=c_ast.CVariable('bar'),
           string_replacement='bar',
       ),
   })
   self.function_likes.update({
       'bar': pre_ast.DefineFunctionLike(
           name='bar',
           arguments=['x'],
           replacement=c_ast.CNumber(42),
           string_replacement='42',
       ),
   })
   expression = c_ast.CFunctionCall(
       function_name='foo',
       arguments=[c_ast.CVariable('x')],
   )
   actual = self.evaluator.evaluate(expression)
   expected = c_ast.CNumber(42)
   self.assertEqual(actual, expected)
Example #2
0
 def test_evaluate_with_argument_passing_to_function_call(
     self,
 ):
   self.function_likes.update({
       'f': pre_ast.DefineFunctionLike(
           name='f',
           arguments=['x'],
           replacement=c_ast.CFunctionCall(
               function_name='g',
               arguments=[c_ast.CVariable('x')],
           ),
           string_replacement='g(x)',
       ),
       'g': pre_ast.DefineFunctionLike(
           name='g',
           arguments=['y'],
           replacement=c_ast.CVariable('y'),
           string_replacement='y',
       ),
   })
   expression = c_ast.CFunctionCall(
       function_name='f',
       arguments=[c_ast.CNumber(42)],
   )
   actual = self.evaluator.evaluate(expression)
   expected = c_ast.CNumber(42)
   self.assertEqual(actual, expected)
Example #3
0
 def test_evaluate_against_mistnesting(
     self,
 ):
   self.function_likes.update({
       'twice': pre_ast.DefineFunctionLike(
           name='twice',
           arguments=['x'],
           replacement=c_ast.CFunctionCall(
               function_name='*',
               arguments=[
                   c_ast.CNumber(2),
                   c_ast.CVariable('x'),
               ],
           ),
           string_replacement='(2*(x))',
       ),
       'call_with_1': pre_ast.DefineFunctionLike(
           name='call_with_1',
           arguments=['x'],
           replacement=c_ast.CFunctionCall(
               function_name='x',
               arguments=[c_ast.CNumber(1)],
           ),
           string_replacement='(2*(x))',
       ),
   })
   expression = c_ast.CFunctionCall(
       function_name='call_with_1',
       arguments=[c_ast.CVariable('twice')],
   )
   actual = self.evaluator.evaluate(expression)
   expected = c_ast.CNumber(2)
   self.assertEqual(actual, expected)
Example #4
0
 def test_evaluate_function_variable_cycle(
     self,
 ):
   self.object_likes.update({
       'y': pre_ast.DefineObjectLike(
           name='y',
           replacement=c_ast.CFunctionCall(
               function_name='f',
               arguments=[c_ast.CVariable('x')],
           ),
           string_replacement='f(x)',
       ),
   })
   self.function_likes.update({
       'f': pre_ast.DefineFunctionLike(
           name='f',
           arguments=['x'],
           replacement=c_ast.CVariable('y'),
           string_replacement='y',
       ),
   })
   expression = c_ast.CFunctionCall(
       function_name='f',
       arguments=[c_ast.CNumber(42)],
   )
   actual = self.evaluator.evaluate(expression)
   expected = c_ast.CFunctionCall(
       function_name='f',
       arguments=[c_ast.CVariable('x')],
   )
   self.assertEqual(actual, expected)
Example #5
0
 def test_evaluate_with_argument_to_resolve_named_as_unresolvable_object(
     self,
 ):
   self.object_likes.update({
       'x': pre_ast.DefineObjectLike(
           name='x',
           replacement=c_ast.CFunctionCall(
               function_name='f',
               arguments=[c_ast.CNumber(42)],
           ),
           string_replacement='f(42)',
       ),
   })
   self.function_likes.update({
       'f': pre_ast.DefineFunctionLike(
           name='f',
           arguments=['x'],
           replacement=c_ast.CVariable('x'),
           string_replacement='x',
       ),
   })
   expression = c_ast.CVariable('x')
   actual = self.evaluator.evaluate(expression)
   expected = c_ast.CNumber(42)
   self.assertEqual(actual, expected)
Example #6
0
 def test_parse_unary_operator_on_expression_in_parentheses(self):
     source = '!(x > 0 || y == 0)'
     expected = c_ast.CFunctionCall(
         function_name='!',
         arguments=[
             c_ast.CNestedExpression(
                 opener='(',
                 content=c_ast.CFunctionCall(
                     function_name='||',
                     arguments=[
                         c_ast.CFunctionCall(
                             function_name='>',
                             arguments=[
                                 c_ast.CVariable('x'),
                                 c_ast.CNumber(0),
                             ],
                         ),
                         c_ast.CFunctionCall(
                             function_name='==',
                             arguments=[
                                 c_ast.CVariable('y'),
                                 c_ast.CNumber(0),
                             ],
                         ),
                     ],
                 ),
                 closer=')',
             ),
         ],
     )
     actual = self.parser.parseString(source, parseAll=True)
     self.assertEqual(actual.asList(), [expected])
Example #7
0
 def test_multiplication_in_parentheses_and_binary_minus(self):
     # This is tricky because it's not a cast and an unary minus.
     # To fully distinguish those cases we would need to know what identifiers
     # are types and what identifiers are variables, e.g.
     #     (x) - y
     # depends on the meaning of x. If x is a type then it can be a cast and
     # an unary minus, if x is a variable then it is a binary minus.
     source = '(a * b) - c'
     actual = self.parser.parseString(source, parseAll=True)
     expected = c_ast.CFunctionCall(
         function_name='-',
         arguments=[
             c_ast.CNestedExpression(opener='(',
                                     content=c_ast.CFunctionCall(
                                         function_name='*',
                                         arguments=[
                                             c_ast.CVariable('a'),
                                             c_ast.CVariable('b'),
                                         ],
                                     ),
                                     closer=')'),
             c_ast.CVariable('c'),
         ],
     )
     self.assertEqual(actual.asList(), [expected])
 def test_parse_with_empty_if_and_elif_blocks_and_expressions(self):
     source = """
     #if CONFIG_SOMETHING == 32
     #elif CONFIG_SOMETHING == 64
     #endif
     """
     actual = self.parser.parse(source)
     expected = pre_ast.File(
         pre_ast.CompositeBlock([
             pre_ast.If(conditional_blocks=[
                 pre_ast.ConditionalBlock(
                     conditional_expression=c_ast.CFunctionCall(
                         function_name='==',
                         arguments=[
                             c_ast.CVariable('CONFIG_SOMETHING'),
                             c_ast.CNumber(32),
                         ],
                     ),
                     content=pre_ast.CompositeBlock([]),
                 ),
                 pre_ast.ConditionalBlock(
                     conditional_expression=c_ast.CFunctionCall(
                         function_name='==',
                         arguments=[
                             c_ast.CVariable('CONFIG_SOMETHING'),
                             c_ast.CNumber(64),
                         ],
                     ),
                     content=pre_ast.CompositeBlock([]),
                 ),
             ], ),
         ]), )
     self.assertEqual(actual, expected)
 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.File(
         pre_ast.CompositeBlock([
             pre_ast.If(
                 conditional_blocks=[
                     pre_ast.ConditionalBlock(
                         conditional_expression=c_ast.CVariable(
                             name='CONFIG_SOMETHING', ),
                         content=pre_ast.CompositeBlock([]),
                     ),
                     pre_ast.ConditionalBlock(
                         conditional_expression=c_ast.CFunctionCall(
                             function_name='defined',
                             arguments=[
                                 c_ast.CVariable('CONFIG_SOMETHING_ELSE'),
                             ],
                         ),
                         content=pre_ast.CompositeBlock([]),
                     )
                 ],
                 else_content=pre_ast.CompositeBlock([]),
             ),
         ]), )
     self.assertEqual(actual, expected)
Example #10
0
 def test_parse_logical_or_and_negation(self):
     source = 'someFunction(a) || !defined(b) || c < 2'
     expected = c_ast.CFunctionCall(
         function_name='||',
         arguments=[
             c_ast.CFunctionCall(
                 function_name='||',
                 arguments=[
                     c_ast.CFunctionCall(
                         function_name='someFunction',
                         arguments=[c_ast.CVariable('a')],
                     ),
                     c_ast.CFunctionCall(
                         function_name='!',
                         arguments=[
                             c_ast.CFunctionCall(
                                 function_name='defined',
                                 arguments=[c_ast.CVariable('b')],
                             )
                         ],
                     ),
                 ],
             ),
             c_ast.CFunctionCall(
                 function_name='<',
                 arguments=[
                     c_ast.CVariable('c'),
                     c_ast.CNumber(2),
                 ],
             ),
         ],
     )
     actual = self.parser.parseString(source, parseAll=True)
     self.assertEqual(actual.asList(), [expected])
Example #11
0
 def test_evaluate_nested_call_access_top_level_variable(
     self,
 ):
   self.object_likes.update({
       'x': pre_ast.DefineObjectLike(
           name='x',
           replacement=c_ast.CNumber(33),
           string_replacement='33',
       ),
   })
   self.function_likes.update({
       'f': pre_ast.DefineFunctionLike(
           name='f',
           arguments=['x'],
           replacement=c_ast.CFunctionCall(
               function_name='g',
               arguments=[],
           ),
           string_replacement='g()',
       ),
       'g': pre_ast.DefineFunctionLike(
           name='g',
           arguments=[],
           replacement=c_ast.CVariable('x'),
           string_replacement='x',
       ),
   })
   expression = c_ast.CVariable('x')
   actual = self.evaluator.evaluate(expression)
   expected = c_ast.CNumber(33)
   self.assertEqual(actual, expected)
Example #12
0
 def test_parse_array_expression(self):
     source = 't[x]'
     actual = self.parser.parseString(source, parseAll=True)
     expected = c_ast.CFunctionCall(
         function_name='[]',
         arguments=[
             c_ast.CVariable('t'),
             c_ast.CVariable('x'),
         ],
     )
     self.assertEqual(actual.asList(), [expected])
Example #13
0
 def test_parse_ternary_conditional(self):
     source = 'a ? b : c'
     actual = self.parser.parseString(source, parseAll=True)
     expected = c_ast.CFunctionCall(
         function_name='?:',
         arguments=[
             c_ast.CVariable('a'),
             c_ast.CVariable('b'),
             c_ast.CVariable('c'),
         ],
     )
     self.assertEqual(actual.asList(), [expected])
Example #14
0
 def test_evaluate_identifier_defined_to_undefined_identifier(self):
   self.object_likes.update({
       'foo': pre_ast.DefineObjectLike(
           name='foo',
           replacement=c_ast.CVariable('bar'),
           string_replacement='bar',
       ),
   })
   expression = c_ast.CVariable('foo')
   actual = self.evaluator.evaluate(expression)
   expected = c_ast.CVariable('bar')
   self.assertEqual(actual, expected)
Example #15
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.parseString(source, parseAll=True)
     self.assertEqual(actual.asList(), [expected])
Example #16
0
 def test_parse_addition_and_multiplication_precedence(self):
     source = 'a + b * c'
     expected = c_ast.CFunctionCall(function_name='+',
                                    arguments=[
                                        c_ast.CVariable('a'),
                                        c_ast.CFunctionCall(
                                            function_name='*',
                                            arguments=[
                                                c_ast.CVariable('b'),
                                                c_ast.CVariable('c'),
                                            ])
                                    ])
     actual = self.parser.parseString(source, parseAll=True)
     self.assertEqual(actual.asList(), [expected])
 def test_parse_define_object_with_two_expressions(self):
     source = '#define foo bar baz'
     actual = self.parser.parse(source)
     expected = pre_ast.File(content=pre_ast.CompositeBlock([
         pre_ast.DefineObjectLike(
             name='foo',
             replacement=pre_ast.CompositeBlock([
                 c_ast.CVariable('bar'),
                 c_ast.CVariable('baz'),
             ]),
             string_replacement=' bar baz',
         ),
     ]), )
     self.assertEqual(actual, expected)
Example #18
0
 def test_evaluate_object_like_with_simple_recursion(
     self,
 ):
   self.object_likes.update({
       'x': pre_ast.DefineObjectLike(
           name='x',
           replacement=c_ast.CVariable('x'),
           string_replacement='x',
       ),
   })
   expression = c_ast.CVariable('x')
   actual = self.evaluator.evaluate(expression)
   expected = c_ast.CVariable('x')
   self.assertEqual(actual, expected)
 def test_parse_define_function_like_with_multiple_expressions(self):
     source = '#define foo() bar baz'
     actual = self.parser.parse(source)
     expected = pre_ast.File(content=pre_ast.CompositeBlock([
         pre_ast.DefineFunctionLike(
             name='foo',
             arguments=[],
             replacement=pre_ast.CompositeBlock([
                 c_ast.CVariable('bar'),
                 c_ast.CVariable('baz'),
             ]),
             string_replacement=' bar baz',
         ),
     ]))
     self.assertEqual(actual, expected)
 def test_parse_pragma_with_argument_with_arguments(self):
     source = '#pragma foo(bar, baz)'
     actual = self.parser.parse(source)
     expected = pre_ast.File(content=pre_ast.CompositeBlock([
         pre_ast.Pragma([
             pre_ast.PragmaArgument(
                 name='foo',
                 arguments=[
                     c_ast.CVariable('bar'),
                     c_ast.CVariable('baz'),
                 ],
             ),
         ]),
     ]), )
     self.assertEqual(actual, expected)
Example #21
0
 def test_expand_with_function_call(self):
     source = 'foo(bar, 42)'
     self.expression_evaluator.evaluate.return_value = c_ast.CVariable(
         'baz')
     actual = self.macro_expander.expand(source)
     self.expression_evaluator.evaluate.assert_called_with(
         c_ast.CFunctionCall(
             function_name='foo',
             arguments=[
                 c_ast.CVariable('bar'),
                 c_ast.CNumber(42),
             ],
         ), )
     expected = 'baz'
     self.assertEqual(actual, expected)
Example #22
0
 def test_parse_parentheses_and_binary_plus(self):
     source = '(a) + b'
     actual = self.parser.parseString(source, parseAll=True)
     expected = c_ast.CFunctionCall(
         function_name='+',
         arguments=[
             c_ast.CNestedExpression(
                 opener='(',
                 content=c_ast.CVariable('a'),
                 closer=')',
             ),
             c_ast.CVariable('b'),
         ],
     )
     self.assertEqual(actual.asList(), [expected])
 def test_parse_with_top_level_if_elif_and_else_blocks(self):
     source = '\n'.join((
         'int a;',
         '#if CONFIG_SOMETHING',
         'struct s {',
         '  int x;',
         '} y;',
         '#elif defined(CONFIG_SOMETHING_ELSE)',
         'struct s t, u;',
         '#else',
         'int z;',
         '#endif',
         'int b;',
     ))
     actual = self.parser.parse(source)
     expected = pre_ast.File(content=pre_ast.CompositeBlock([
         pre_ast.TextBlock('int a;'),
         pre_ast.If(
             conditional_blocks=[
                 pre_ast.ConditionalBlock(
                     conditional_expression=c_ast.CVariable(
                         name='CONFIG_SOMETHING', ),
                     content=pre_ast.CompositeBlock([
                         pre_ast.TextBlock(
                             '\n'.join((
                                 'struct s {',
                                 '  int x;',
                                 '} y;',
                             )), ),
                     ]),
                 ),
                 pre_ast.ConditionalBlock(
                     conditional_expression=c_ast.CFunctionCall(
                         function_name='defined',
                         arguments=[
                             c_ast.CVariable('CONFIG_SOMETHING_ELSE'),
                         ],
                     ),
                     content=pre_ast.CompositeBlock(
                         [pre_ast.TextBlock('struct s t, u;')]),
                 ),
             ],
             else_content=pre_ast.CompositeBlock(
                 [pre_ast.TextBlock('int z;')]),
         ),
         pre_ast.TextBlock('int b;'),
     ]), )
     self.assertEqual(actual, expected)
Example #24
0
def _construct_ifndef_expression(identifier):
  return c_ast.CFunctionCall(
      function_name='!',
      arguments=[
          c_ast.CFunctionCall('defined', [c_ast.CVariable(identifier)]),
      ],
  )
 def test_parse_with_empty_ifndef_block_and_endif_with_comment(self):
     source = """
     #ifndef _SOMETHING_H
     #endif /* _SOMETHING_H */
     """
     actual = self.parser.parse(source)
     expected = pre_ast.File(
         pre_ast.CompositeBlock([
             pre_ast.If([
                 pre_ast.ConditionalBlock(
                     conditional_expression=c_ast.CFunctionCall(
                         function_name='!',
                         arguments=[
                             c_ast.CFunctionCall(
                                 function_name='defined',
                                 arguments=[
                                     c_ast.CVariable('_SOMETHING_H')
                                 ]),
                         ],
                     ),
                     content=pre_ast.CompositeBlock([]),
                 ),
             ]),
         ]), )
     self.assertEqual(actual, expected)
 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.File(
         pre_ast.CompositeBlock([
             pre_ast.If([
                 pre_ast.ConditionalBlock(
                     conditional_expression=c_ast.CFunctionCall(
                         function_name='!',
                         arguments=[
                             c_ast.CFunctionCall(
                                 function_name='defined',
                                 arguments=[
                                     c_ast.CVariable('_SOMETHING_H')
                                 ]),
                         ],
                     ),
                     content=pre_ast.CompositeBlock([
                         pre_ast.DefineObjectLike(
                             name='_SOMETHING_H',
                             replacement=None,
                             string_replacement='',
                         ),
                     ]),
                 ),
             ]),
         ]), )
     self.assertEqual(actual, expected)
Example #27
0
 def test_keep_parentheses_in_nested_expression(self):
   evaluator = (
       macro_expression_evaluator_visitor.MacroExpressionEvaluatorVisitor(
           object_likes=self.object_likes,
           function_likes=self.function_likes,
           functions=self.functions,
           lazy_functions=self.lazy_functions,
           keep_parentheses=True,
       )
   )
   self.object_likes.update({
       'foo': pre_ast.DefineObjectLike(
           name='foo',
           replacement=c_ast.CNumber(42),
           string_replacement='42',
       ),
       'bar': pre_ast.DefineObjectLike(
           name='bar',
           replacement=c_ast.CNumber(33),
           string_replacement='33',
       ),
   })
   expression = c_ast.CNestedExpression(
       opener='(',
       content=c_ast.CVariable('foo'),
       closer=')',
   )
   actual = evaluator.evaluate(expression)
   expected = c_ast.CNestedExpression(
       opener='(',
       content=c_ast.CNumber(42),
       closer=')',
   )
   self.assertEqual(actual, expected)
Example #28
0
 def test_evaluate_function_argument_cycle_with_composition(
     self,
 ):
   self.function_likes.update({
       'f': pre_ast.DefineFunctionLike(
           name='f',
           arguments=['x'],
           replacement=c_ast.CFunctionCall(
               function_name='f',
               arguments=[
                   c_ast.CFunctionCall(
                       function_name='f',
                       arguments=[c_ast.CVariable('x')],
                   ),
               ],
           ),
           string_replacement='f(f(x))',
       ),
   })
   expression = c_ast.CFunctionCall(
       function_name='f',
       arguments=[c_ast.CNumber(42)],
   )
   actual = self.evaluator.evaluate(expression)
   expected = c_ast.CFunctionCall(
       function_name='f',
       arguments=[
           c_ast.CFunctionCall(
               function_name='f',
               arguments=[c_ast.CNumber(42)],
           )
       ]
   )
   self.assertEqual(actual, expected)
Example #29
0
 def test_transform_result_to_integer_as_hex(
     self,
 ):
   expression = c_ast.CVariable('0x33')
   actual = self.evaluator.evaluate(expression)
   expected = c_ast.CNumber(51)
   self.assertEqual(actual, expected)
Example #30
0
 def test_visit_nested_expression(self):
     expression = c_ast.CNestedExpression(
         opener='(',
         content=c_ast.CVariable('a'),
         closer=')',
     )
     actual = self.expression_evaluator.evaluate(expression)
     self.assertEqual(actual, 'b')