mirror of
https://github.com/JakeHillion/drgn.git
synced 2024-12-26 02:25:36 +00:00
6abb2f2402
While we're here, clean up some rough edges of the API and document a lot more.
338 lines
16 KiB
Python
338 lines
16 KiB
Python
import unittest
|
|
from drgn.typename import (
|
|
parse_type_name,
|
|
ArrayTypeName,
|
|
BasicTypeName,
|
|
EnumTypeName,
|
|
FunctionTypeName,
|
|
PointerTypeName,
|
|
StructTypeName,
|
|
TypedefTypeName,
|
|
TypeName,
|
|
UnionTypeName,
|
|
VoidTypeName,
|
|
)
|
|
|
|
|
|
# TODO: complex types
|
|
|
|
|
|
def type_name_eq(self, other):
|
|
return (isinstance(other, self.__class__) and
|
|
self.__dict__ == other.__dict__)
|
|
|
|
|
|
class TestParseTypeName(unittest.TestCase):
|
|
def setUp(self):
|
|
TypeName.__eq__ = type_name_eq
|
|
|
|
def tearDown(self):
|
|
del TypeName.__eq__
|
|
|
|
def test_empty(self):
|
|
self.assertRaises(ValueError, parse_type_name, '')
|
|
self.assertRaises(ValueError, parse_type_name, ' ')
|
|
|
|
def test_invalid_character(self):
|
|
self.assertRaises(ValueError, parse_type_name, '`')
|
|
|
|
def test_void(self):
|
|
self.assertEqual(parse_type_name('void'), VoidTypeName())
|
|
|
|
def test_basic_types(self):
|
|
self.assertEqual(parse_type_name('char'), BasicTypeName('char'))
|
|
self.assertEqual(parse_type_name('int'), BasicTypeName('int'))
|
|
self.assertEqual(parse_type_name('float'), BasicTypeName('float'))
|
|
self.assertEqual(parse_type_name('double'), BasicTypeName('double'))
|
|
self.assertEqual(parse_type_name('_Bool'), BasicTypeName('_Bool'))
|
|
|
|
def test_size(self):
|
|
self.assertEqual(parse_type_name('long int'), BasicTypeName('long'))
|
|
self.assertEqual(parse_type_name('long'), BasicTypeName('long'))
|
|
self.assertEqual(parse_type_name('int long'), BasicTypeName('long'))
|
|
|
|
self.assertEqual(parse_type_name('long long int'),
|
|
BasicTypeName('long long'))
|
|
self.assertEqual(parse_type_name('long long'),
|
|
BasicTypeName('long long'))
|
|
self.assertEqual(parse_type_name('int long long'),
|
|
BasicTypeName('long long'))
|
|
self.assertEqual(parse_type_name('long int long'),
|
|
BasicTypeName('long long'))
|
|
|
|
self.assertEqual(parse_type_name('short int'), BasicTypeName('short'))
|
|
self.assertEqual(parse_type_name('short'), BasicTypeName('short'))
|
|
self.assertEqual(parse_type_name('int short'), BasicTypeName('short'))
|
|
|
|
self.assertEqual(parse_type_name('long double'),
|
|
BasicTypeName('long double'))
|
|
self.assertEqual(parse_type_name('double long'),
|
|
BasicTypeName('long double'))
|
|
|
|
self.assertRaises(ValueError, parse_type_name, 'short long int')
|
|
self.assertRaises(ValueError, parse_type_name, 'long long long int')
|
|
self.assertRaises(ValueError, parse_type_name, 'short double')
|
|
self.assertRaises(ValueError, parse_type_name, 'double short')
|
|
self.assertRaises(ValueError, parse_type_name, 'long long double')
|
|
self.assertRaises(ValueError, parse_type_name, 'long double long')
|
|
self.assertRaises(ValueError, parse_type_name, 'double long long')
|
|
self.assertRaises(ValueError, parse_type_name, 'long char')
|
|
self.assertRaises(ValueError, parse_type_name, 'char long')
|
|
|
|
def test_sign(self):
|
|
self.assertEqual(parse_type_name('signed int'), BasicTypeName('int'))
|
|
self.assertEqual(parse_type_name('signed'), BasicTypeName('int'))
|
|
self.assertEqual(parse_type_name('int signed'), BasicTypeName('int'))
|
|
|
|
self.assertEqual(parse_type_name('unsigned'),
|
|
BasicTypeName('unsigned int'))
|
|
self.assertEqual(parse_type_name('unsigned int'),
|
|
BasicTypeName('unsigned int'))
|
|
self.assertEqual(parse_type_name('unsigned'),
|
|
BasicTypeName('unsigned int'))
|
|
self.assertEqual(parse_type_name('int unsigned'),
|
|
BasicTypeName('unsigned int'))
|
|
|
|
self.assertEqual(parse_type_name('signed char'),
|
|
BasicTypeName('signed char'))
|
|
self.assertEqual(parse_type_name('char signed'),
|
|
BasicTypeName('signed char'))
|
|
|
|
self.assertEqual(parse_type_name('unsigned char'),
|
|
BasicTypeName('unsigned char'))
|
|
self.assertEqual(parse_type_name('char unsigned'),
|
|
BasicTypeName('unsigned char'))
|
|
|
|
self.assertRaises(ValueError, parse_type_name, 'signed unsigned int')
|
|
self.assertRaises(ValueError, parse_type_name, 'signed _Bool')
|
|
self.assertRaises(ValueError, parse_type_name, '_Bool signed')
|
|
|
|
def test_qualifiers(self):
|
|
self.assertEqual(parse_type_name('const int'),
|
|
BasicTypeName('int', qualifiers={'const'}))
|
|
self.assertEqual(parse_type_name('restrict int'),
|
|
BasicTypeName('int', qualifiers={'restrict'}))
|
|
self.assertEqual(parse_type_name('volatile int'),
|
|
BasicTypeName('int', qualifiers={'volatile'}))
|
|
self.assertEqual(parse_type_name('_Atomic int'),
|
|
BasicTypeName('int', qualifiers={'_Atomic'}))
|
|
self.assertEqual(parse_type_name('const volatile int'),
|
|
BasicTypeName('int', qualifiers={'const', 'volatile'}))
|
|
self.assertEqual(parse_type_name('const const int'),
|
|
BasicTypeName('int', qualifiers={'const'}))
|
|
|
|
def test_specifiers_qualifiers(self):
|
|
self.assertEqual(parse_type_name('long const int unsigned'),
|
|
BasicTypeName('unsigned long',
|
|
qualifiers={'const'}))
|
|
|
|
def test_typedef(self):
|
|
self.assertEqual(parse_type_name('u32'), TypedefTypeName('u32'))
|
|
|
|
def test_tagged_type(self):
|
|
self.assertEqual(parse_type_name('struct point'),
|
|
StructTypeName('point'))
|
|
self.assertEqual(parse_type_name('union value'),
|
|
UnionTypeName('value'))
|
|
self.assertEqual(parse_type_name('enum color'), EnumTypeName('color'))
|
|
|
|
def test_pointer(self):
|
|
self.assertEqual(parse_type_name('int *'),
|
|
PointerTypeName(BasicTypeName('int')))
|
|
self.assertEqual(parse_type_name('int * const'),
|
|
PointerTypeName(BasicTypeName('int'),
|
|
qualifiers={'const'}))
|
|
|
|
self.assertEqual(parse_type_name('struct point *'),
|
|
PointerTypeName(StructTypeName('point')))
|
|
|
|
self.assertEqual(parse_type_name('int **'),
|
|
PointerTypeName(PointerTypeName(BasicTypeName('int'))))
|
|
|
|
self.assertEqual(parse_type_name('int *((*))'),
|
|
PointerTypeName(PointerTypeName(BasicTypeName('int'))))
|
|
|
|
self.assertEqual(parse_type_name('int * const *'),
|
|
PointerTypeName(PointerTypeName(BasicTypeName('int'),
|
|
qualifiers={'const'})))
|
|
|
|
def test_array(self):
|
|
self.assertEqual(parse_type_name('int []'),
|
|
ArrayTypeName(BasicTypeName('int'), None))
|
|
self.assertEqual(parse_type_name('int [2]'),
|
|
ArrayTypeName(BasicTypeName('int'), 2))
|
|
self.assertEqual(parse_type_name('int [0x10]'),
|
|
ArrayTypeName(BasicTypeName('int'), 16))
|
|
self.assertEqual(parse_type_name('int [010]'),
|
|
ArrayTypeName(BasicTypeName('int'), 8))
|
|
self.assertEqual(parse_type_name('int [2][3]'),
|
|
ArrayTypeName(ArrayTypeName(BasicTypeName('int'), 3), 2))
|
|
self.assertEqual(parse_type_name('int [2][3][4]'),
|
|
ArrayTypeName(ArrayTypeName(ArrayTypeName(BasicTypeName('int'), 4), 3), 2))
|
|
|
|
def test_array_of_pointers(self):
|
|
self.assertEqual(parse_type_name('int *[2][3]'),
|
|
ArrayTypeName(ArrayTypeName(PointerTypeName(BasicTypeName('int')), 3), 2))
|
|
|
|
def test_pointer_to_array(self):
|
|
self.assertEqual(parse_type_name('int (*)[2]'),
|
|
PointerTypeName(ArrayTypeName(BasicTypeName('int'), 2)))
|
|
self.assertEqual(parse_type_name('int (*)[2][3]'),
|
|
PointerTypeName(ArrayTypeName(ArrayTypeName(BasicTypeName('int'), 3), 2)))
|
|
|
|
def test_pointer_to_pointer_to_array(self):
|
|
self.assertEqual(parse_type_name('int (**)[2]'),
|
|
PointerTypeName(PointerTypeName(ArrayTypeName(BasicTypeName('int'), 2))))
|
|
|
|
def test_pointer_to_array_of_pointers(self):
|
|
self.assertEqual(parse_type_name('int *(*)[2]'),
|
|
PointerTypeName(ArrayTypeName(PointerTypeName(BasicTypeName('int')), 2)))
|
|
self.assertEqual(parse_type_name('int *((*)[2])'),
|
|
PointerTypeName(ArrayTypeName(PointerTypeName(BasicTypeName('int')), 2)))
|
|
|
|
def test_array_of_pointers_to_array(self):
|
|
self.assertEqual(parse_type_name('int (*[2])[3]'),
|
|
ArrayTypeName(PointerTypeName(ArrayTypeName(BasicTypeName('int'), 3)), 2))
|
|
|
|
|
|
class TestTypeStr(unittest.TestCase):
|
|
def test_void(self):
|
|
self.assertEqual(str(BasicTypeName('void')), 'void')
|
|
|
|
def test_basic_types(self):
|
|
self.assertEqual(str(BasicTypeName('char')), 'char')
|
|
self.assertEqual(str(BasicTypeName('int')), 'int')
|
|
self.assertEqual(str(BasicTypeName('float')), 'float')
|
|
self.assertEqual(str(BasicTypeName('double')), 'double')
|
|
self.assertEqual(str(BasicTypeName('_Bool')), '_Bool')
|
|
|
|
def test_size(self):
|
|
self.assertEqual(str(BasicTypeName('long')), 'long')
|
|
self.assertEqual(str(BasicTypeName('long long')), 'long long')
|
|
self.assertEqual(str(BasicTypeName('short')), 'short')
|
|
self.assertEqual(str(BasicTypeName('long double')), 'long double')
|
|
|
|
def test_sign(self):
|
|
self.assertEqual(str(BasicTypeName('unsigned int')), 'unsigned int')
|
|
self.assertEqual(str(BasicTypeName('signed char')), 'signed char')
|
|
self.assertEqual(str(BasicTypeName('unsigned char')), 'unsigned char')
|
|
|
|
def test_qualifiers(self):
|
|
self.assertEqual(str(BasicTypeName('int', qualifiers={'const'})),
|
|
'const int')
|
|
self.assertEqual(str(BasicTypeName('int', qualifiers={'restrict'})),
|
|
'restrict int')
|
|
self.assertEqual(str(BasicTypeName('int', qualifiers={'volatile'})),
|
|
'volatile int')
|
|
self.assertEqual(str(BasicTypeName('int', qualifiers={'_Atomic'})),
|
|
'_Atomic int')
|
|
self.assertEqual(str(BasicTypeName('int', qualifiers={'const', 'volatile'})),
|
|
'const volatile int')
|
|
|
|
def test_specifiers_qualifiers(self):
|
|
self.assertEqual(str(BasicTypeName('unsigned long', qualifiers={'const'})),
|
|
'const unsigned long')
|
|
|
|
def test_typedef(self):
|
|
self.assertEqual(str(TypedefTypeName('u32')), 'u32')
|
|
|
|
def test_tagged_type(self):
|
|
self.assertEqual(str(StructTypeName('point')), 'struct point')
|
|
self.assertEqual(str(UnionTypeName('value')), 'union value')
|
|
self.assertEqual(str(EnumTypeName('color')), 'enum color')
|
|
|
|
self.assertEqual(str(StructTypeName(None)), 'struct')
|
|
self.assertEqual(str(UnionTypeName(None)), 'union')
|
|
self.assertEqual(str(EnumTypeName(None)), 'enum')
|
|
|
|
def test_pointer(self):
|
|
self.assertEqual(str(PointerTypeName(BasicTypeName('int'))), 'int *')
|
|
self.assertEqual(str(PointerTypeName(BasicTypeName('int'), qualifiers={'const'})),
|
|
'int * const')
|
|
|
|
self.assertEqual(str(PointerTypeName(BasicTypeName('struct point'))),
|
|
'struct point *')
|
|
|
|
self.assertEqual(str(PointerTypeName(PointerTypeName(BasicTypeName('int')))),
|
|
'int **')
|
|
|
|
self.assertEqual(str(PointerTypeName(PointerTypeName(BasicTypeName('int'),
|
|
qualifiers={'const'}))),
|
|
'int * const *')
|
|
|
|
def test_array(self):
|
|
self.assertEqual(str(ArrayTypeName(BasicTypeName('int'), None)),
|
|
'int []')
|
|
self.assertEqual(str(ArrayTypeName(BasicTypeName('int'), 2)),
|
|
'int [2]')
|
|
self.assertEqual(str(ArrayTypeName(ArrayTypeName(BasicTypeName('int'), 3), 2)),
|
|
'int [2][3]')
|
|
self.assertEqual(str(ArrayTypeName(ArrayTypeName(ArrayTypeName(BasicTypeName('int'), 4), 3), 2)),
|
|
'int [2][3][4]')
|
|
|
|
def test_array_of_pointers(self):
|
|
self.assertEqual(str(ArrayTypeName(ArrayTypeName(PointerTypeName(BasicTypeName('int')), 3), 2)),
|
|
'int *[2][3]')
|
|
|
|
def test_pointer_to_array(self):
|
|
self.assertEqual(str(PointerTypeName(ArrayTypeName(BasicTypeName('int'), 2))),
|
|
'int (*)[2]')
|
|
|
|
def test_pointer_to_pointer_to_array(self):
|
|
self.assertEqual(str(PointerTypeName(PointerTypeName(ArrayTypeName(BasicTypeName('int'), 2)))),
|
|
'int (**)[2]')
|
|
|
|
def test_pointer_to_array_of_pointers(self):
|
|
self.assertEqual(str(PointerTypeName(ArrayTypeName(PointerTypeName(BasicTypeName('int')), 2))),
|
|
'int *(*)[2]')
|
|
|
|
def test_array_of_pointers_to_array(self):
|
|
self.assertEqual(str(ArrayTypeName(PointerTypeName(ArrayTypeName(BasicTypeName('int'), 3)), 2)),
|
|
'int (*[2])[3]')
|
|
|
|
def test_pointer_to_function(self):
|
|
self.assertEqual(str(PointerTypeName(FunctionTypeName(BasicTypeName('int'), [(BasicTypeName('int'), None)]))),
|
|
'int (*)(int)')
|
|
self.assertEqual(str(PointerTypeName(FunctionTypeName(BasicTypeName('int'), [(BasicTypeName('int'), 'x')]))),
|
|
'int (*)(int x)')
|
|
self.assertEqual(str(PointerTypeName(FunctionTypeName(BasicTypeName('int'), [(BasicTypeName('int'), None), (BasicTypeName('float'), None)]))),
|
|
'int (*)(int, float)')
|
|
|
|
def test_pointer_to_function_returning_pointer(self):
|
|
self.assertEqual(str(PointerTypeName(FunctionTypeName(PointerTypeName(BasicTypeName('int')), [(BasicTypeName('int'), None)]))),
|
|
'int *(*)(int)')
|
|
self.assertEqual(str(PointerTypeName(FunctionTypeName(PointerTypeName(BasicTypeName('int')), [(PointerTypeName(BasicTypeName('int')), None)]))),
|
|
'int *(*)(int *)')
|
|
|
|
def test_pointer_to_function_returning_pointer_to_const(self):
|
|
self.assertEqual(str(PointerTypeName(FunctionTypeName(PointerTypeName(BasicTypeName('int', qualifiers={'const'})), [(BasicTypeName('int'), None)]))),
|
|
'const int *(*)(int)')
|
|
|
|
def test_pointer_to_function_returning_const_pointer(self):
|
|
self.assertEqual(str(PointerTypeName(FunctionTypeName(PointerTypeName(BasicTypeName('int'), qualifiers={'const'}), [(BasicTypeName('int'), None)]))),
|
|
'int * const (*)(int)')
|
|
|
|
def test_const_pointer_to_function_returning_pointer(self):
|
|
self.assertEqual(str(PointerTypeName(FunctionTypeName(PointerTypeName(BasicTypeName('int')), [(BasicTypeName('int'), None)]), qualifiers={'const'})),
|
|
'int *(* const)(int)')
|
|
|
|
def test_array_of_pointers_to_functions(self):
|
|
self.assertEqual(str(ArrayTypeName(PointerTypeName(FunctionTypeName(BasicTypeName('int'), [(BasicTypeName('int'), None)])), 4)),
|
|
'int (*[4])(int)')
|
|
|
|
def test_array_of_const_pointers_to_functions(self):
|
|
self.assertEqual(str(ArrayTypeName(PointerTypeName(FunctionTypeName(BasicTypeName('int'), [(BasicTypeName('int'), None)]), qualifiers={'const'}), None)),
|
|
'int (* const [])(int)')
|
|
|
|
def test_pointer_to_variadic_function(self):
|
|
self.assertEqual(str(PointerTypeName(FunctionTypeName(BasicTypeName('int'), [(BasicTypeName('int'), None)], variadic=True))),
|
|
'int (*)(int, ...)')
|
|
|
|
def test_pointer_to_function_with_no_parameter_specification(self):
|
|
self.assertEqual(str(PointerTypeName(FunctionTypeName(BasicTypeName('int'), None))),
|
|
'int (*)()')
|
|
|
|
def test_pointer_to_function_with_no_parameters(self):
|
|
self.assertEqual(str(PointerTypeName(FunctionTypeName(BasicTypeName('int'), []))),
|
|
'int (*)(void)')
|