def _create_ofsetof(type_name_words, field_name): type_name = ' '.join(type_name_words) return c_ast.CFunctionCall( function_name='offsetof', arguments=[ c_ast.CLiteral(type_name), c_ast.CLiteral(field_name), ], )
def test_parse_offsetof_expression(self): source = '((size_t)&((struct raw_spinlock *)0)->dep_map)' actual = self.parser.parseString(source, parseAll=True) expected = c_ast.CFunctionCall( function_name='offsetof', arguments=[ c_ast.CLiteral('struct raw_spinlock'), c_ast.CLiteral('dep_map'), ], ) self.assertEqual(actual.asList(), [expected])
def test_parse_offsetof_expression_with_additional_parentheses(self): source = '(((size_t)&((struct raw_spinlock *)0)->dep_map))' actual = self.parser.parseString(source, parseAll=True) expected = c_ast.CNestedExpression( opener='(', content=c_ast.CFunctionCall( function_name='offsetof', arguments=[ c_ast.CLiteral('struct raw_spinlock'), c_ast.CLiteral('dep_map'), ], ), closer=')', ) self.assertEqual(actual.asList(), [expected])
def _parse_value(self, value): if value == 'y': return c_ast.CNumber(1) elif len(value) >= 2 and value[0] == '"' and value[-1] == '"': return c_ast.CLiteral(value[1:-1]) else: return c_ast.CNumber(int(value, base=0)) # Throws ValueError.
def _create_cast_expression(target, expression): return c_ast.CFunctionCall( function_name='()', arguments=[ c_ast.CLiteral(target), expression, ], )
def test_parse_sizeof(self): source = 'sizeof(struct s*)' actual = self.parser.parseString(source, parseAll=True) expected = c_ast.CFunctionCall( function_name='sizeof', arguments=[c_ast.CLiteral('struct s*')], ) self.assertEquals(actual.asList(), [expected])
def test_parse_alignof_with_double_underscores_of_array(self): source = '__alignof__(unsigned int[42])' actual = self.parser.parseString(source, parseAll=True) expected = c_ast.CFunctionCall( function_name='__alignof__', arguments=[c_ast.CLiteral('unsigned int[42]')], ) self.assertEquals(actual.asList(), [expected])
def test_parse_function_call_with_argument_with_dots(self): source = 'f(.init.text)' expected = c_ast.CFunctionCall( function_name='f', arguments=[ c_ast.CLiteral('.init.text'), ], ) actual = self.parser.parseString(source, parseAll=True) self.assertEqual(actual.asList(), [expected])
def test_parse_cast_to_typeof_expression(self): source = '(typeof(32)) x' actual = self.parser.parseString(source, parseAll=True) expected = c_ast.CFunctionCall( function_name='()', arguments=[ c_ast.CLiteral('typeof(32)'), c_ast.CVariable('x'), ], ) self.assertEqual(actual.asList(), [expected])
def test_parse_cast_to_pointer_without_space(self): source = '(void*) x' actual = self.parser.parseString(source, parseAll=True) expected = c_ast.CFunctionCall( function_name='()', arguments=[ c_ast.CLiteral('void*'), c_ast.CVariable('x'), ], ) self.assertEqual(actual.asList(), [expected])
def test_parse_define_string(self): source = '#define foo "bar"' actual = self.parser.parse(source) expected = pre_ast.File(content=pre_ast.CompositeBlock([ pre_ast.DefineObjectLike( name='foo', replacement=c_ast.CLiteral('"bar"'), string_replacement=' "bar"', ), ]), ) self.assertEqual(actual, expected)
def test_parse_sizeof_and_binary_plus_operators_and_additional_parentheses( self, ): source = """ ( sizeof(struct ymmh_struct) + sizeof(struct lwp_struct) + sizeof(struct mpx_struct) ) """ actual = self.parser.parseString(source, parseAll=True) expected = c_ast.CNestedExpression( opener='(', content=c_ast.CFunctionCall( function_name='+', arguments=[ c_ast.CFunctionCall( function_name='+', arguments=[ c_ast.CFunctionCall( function_name='sizeof', arguments=[ c_ast.CLiteral('struct ymmh_struct') ], ), c_ast.CFunctionCall( function_name='sizeof', arguments=[ c_ast.CLiteral('struct lwp_struct') ], ), ], ), c_ast.CFunctionCall( function_name='sizeof', arguments=[c_ast.CLiteral('struct mpx_struct')], ), ], ), closer=')', ) self.assertEqual(actual.asList(), [expected])
def test_visit_function_call(self): function_call = c_ast.CFunctionCall( function_name='f1', arguments=[ c_ast.CNumber(24), c_ast.CLiteral('literal'), ], ) actual = self.expression_evaluator.evaluate(function_call) self.assertEqual(actual, 33) self.assertEqual(self.x, [24]) self.assertEqual(self.y, ['literal'])
def test_evaluate_identifier_defined_to_empty_string(self): self.object_likes.update({ 'foo': pre_ast.DefineObjectLike( name='foo', replacement=None, string_replacement='', ), }) expression = c_ast.CVariable('foo') actual = self.evaluator.evaluate(expression) expected = c_ast.CLiteral('') self.assertEqual(actual, expected)
def _wrap_result(self, result): """This method converts the result to the type of the proper AST Node.""" if isinstance(result, bool): result = c_ast.CNumber(1 if result else 0) if isinstance(result, int): result = c_ast.CNumber(result) if isinstance(result, basestring): result = c_ast.CLiteral(result) if isinstance(result, c_ast.CLiteral): if self._C_IDENTIFIER_OR_LITERAL_PATTERN.match(result.value): result = c_ast.CVariable(result.value) if isinstance(result, c_ast.CVariable): match = self._C_INT_PATTERN.match(result.name) if match: result = c_ast.CNumber(int(match.group('number'), base=0)) return result
def test_evaluate_defined_with_defined_object_like( self, ): self.object_likes.update({ 'x': pre_ast.DefineObjectLike( name='x', replacement=c_ast.CLiteral(''), string_replacement='', ), }) expression = c_ast.CFunctionCall( function_name='defined', arguments=[c_ast.CVariable('x')], ) actual = self.evaluator.evaluate(expression) expected = c_ast.CNumber(1) self.assertEqual(actual, expected)
def test_parse_define_statement_as_functional_like(self): source = '#define module_init(x) __initcall(x);' actual = self.parser.parse(source) expected = pre_ast.File(content=pre_ast.CompositeBlock([ pre_ast.DefineFunctionLike( name='module_init', arguments=['x'], replacement=pre_ast.CompositeBlock([ c_ast.CFunctionCall( function_name='__initcall', arguments=[c_ast.CVariable('x')], ), c_ast.CLiteral(';'), ]), string_replacement=' __initcall(x);', ) ])) self.assertEqual(actual, expected)
def get_x86_64_kernel_compile_object_likes(): return { '__STDC__': pre_ast.DefineObjectLike( name='__STDC__', replacement=c_ast.CNumber(1), string_replacement='1', ), '__STDC_VERSION__': pre_ast.DefineObjectLike( name='__STDC_VERSION__', replacement=c_ast.CNumber(201112L), string_replacement='201112L', ), '_XOPEN_SOURCE': pre_ast.DefineObjectLike( name='_XOPEN_SOURCE', replacement=c_ast.CNumber(500), string_replacement='500', ), '__GNUC__': pre_ast.DefineObjectLike( name='__GNUC__', replacement=c_ast.CNumber(4), string_replacement='4', ), '__GNUC_MINOR__': pre_ast.DefineObjectLike( name='__GNUC_MINOR__', replacement=c_ast.CNumber(8), string_replacement='8', ), '__GNUC_PATCHLEVEL__': pre_ast.DefineObjectLike( name='__GNUC_PATCHLEVEL__', replacement=c_ast.CNumber(4), string_replacement='4', ), '__x86_64__': pre_ast.DefineObjectLike( name='__x86_64__', replacement=c_ast.CNumber(1), string_replacement='1', ), '__KERNEL__': pre_ast.DefineObjectLike( name='__KERNEL__', replacement=c_ast.CLiteral(''), string_replacement='', ), }
def test_evaluate_identifier_defined_to_identifier_defined_to_undefined_id( self, ): self.object_likes.update({ 'foo': pre_ast.DefineObjectLike( name='foo', replacement=c_ast.CVariable('bar'), string_replacement='bar', ), 'bar': pre_ast.DefineObjectLike( name='bar', replacement=c_ast.CLiteral('baz'), string_replacement='baz', ), }) expression = c_ast.CVariable('foo') actual = self.evaluator.evaluate(expression) expected = c_ast.CVariable('baz') self.assertEqual(actual, expected)
def test_parse_define_object_with_statement_concatenation(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.CFunctionCall( function_name='##', arguments=[ c_ast.CVariable('bar'), c_ast.CVariable('baz'), ], ), c_ast.CLiteral(';'), ]), string_replacement=' bar ## baz;', ), ]), ) self.assertEqual(actual, expected)
def test_parse_with_string_flag(self): config = 'FLAG="33"' actual = self.parser.parse(config) expected = {'FLAG': c_ast.CLiteral('33')} self.assertEqual(actual, expected)
def test_visit_literal(self): literal = c_ast.CLiteral('value') actual = self.expression_evaluator.evaluate(literal) self.assertEqual(actual, 'value')
def _create_sizeof_type(sizeof, type_name): return c_ast.CFunctionCall( function_name=sizeof, arguments=[c_ast.CLiteral(type_name)], )
def test_kernel(self): kernel = self.object_likes['__KERNEL__'] self.assertEqual(kernel.name, '__KERNEL__') self.assertEqual(kernel.replacement, c_ast.CLiteral('')) self.assertEqual(kernel.string_replacement, '')
def test_parse_sizeof_and_binary_operators(self): source = """ ((((1 << 0)) + (8 * sizeof(long)) - 1) / (8 * sizeof(long))) """ actual = self.parser.parseString(source, parseAll=True) expected = c_ast.CNestedExpression( opener='(', content=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.CNestedExpression( opener='(', content=c_ast.CNestedExpression( opener='(', content=c_ast.CFunctionCall( function_name='<<', arguments=[ c_ast.CNumber(1), c_ast.CNumber(0), ], ), closer=')', ), closer=')', ), c_ast.CNestedExpression( opener='(', content=c_ast.CFunctionCall( function_name='*', arguments=[ c_ast.CNumber(8), c_ast.CFunctionCall( function_name='sizeof', arguments=[ c_ast.CLiteral( 'long'), ], ), ], ), closer=')', ), ], ), c_ast.CNumber(1), ], ), closer=')', ), c_ast.CNestedExpression( opener='(', content=c_ast.CFunctionCall( function_name='*', arguments=[ c_ast.CNumber(8), c_ast.CFunctionCall( function_name='sizeof', arguments=[c_ast.CLiteral('long')], ), ], ), closer=')', ), ], ), closer=')', ) self.assertEqual(actual.asList(), [expected])