class TestParsing(object): """Test parsing. """ h_dir = H_DIRECTORY def setup(self): self.parser = CParser(process_all=False) def test_variables(self): path = os.path.join(self.h_dir, 'variables.h') self.parser.load_file(path) self.parser.process_all() variables = self.parser.defs['variables'] # Integers assert ('short1' in variables and variables['short1'] == (1, Type('signed short'))) assert ('short_int' in variables and variables['short_int'] == (1, Type('short int'))) assert ('short_un' in variables and variables['short_un'] == (1, Type('unsigned short'))) assert ('short_int_un' in variables and variables['short_int_un'] == (1, Type('unsigned short int'))) assert ('int1' in variables and variables['int1'] == (1, Type('int'))) assert ('un' in variables and variables['un'] == (1, Type('unsigned'))) assert ('int_un' in variables and variables['int_un'] == (1, Type('unsigned int'))) assert ('long1' in variables and variables['long1'] == (1, Type('long'))) assert ('long_int' in variables and variables['long_int'] == (1, Type('long int'))) assert ('long_un' in variables and variables['long_un'] == (1, Type('unsigned long'))) assert ('long_int_un' in variables and variables['long_int_un'] == (1, Type('unsigned long int'))) if sys.platform == 'win32': assert ('int64' in variables and variables['int64'] == (1, Type('__int64'))) assert ('int64_un' in variables and variables['int64_un'] == (1, Type('unsigned __int64'))) assert ('long_long' in variables and variables['long_long'] == (1, Type('long long'))) assert ('long_long_int' in variables and variables['long_long_int'] == (1, Type('long long int'))) assert ('long_long_un' in variables and variables['long_long_un'] == (1, Type('unsigned long long'))) assert ('long_long_int_un' in variables and variables['long_long_int_un'] == (1, Type('unsigned long ' 'long int'))) # C99 integers for i in (8, 16, 32, 64): assert ('i%d' % i in variables and variables['i%d' % i] == (1, Type('int%d_t' % i))) assert ('u%d' % i in variables and variables['u%d' % i] == (1, Type('uint%d_t' % i))) # Floating point number assert ('fl' in variables and variables['fl'] == (1., Type('float'))) assert ('db' in variables and variables['db'] == (0.1, Type('double'))) assert ('dbl' in variables and variables['dbl'] == (-10., Type('long double'))) # Const and static modif assert ('int_const' in variables and variables['int_const'] == (4, Type('int', type_quals=(('const', ), )))) assert ('int_stat' in variables and variables['int_stat'] == (4, Type('int'))) assert ('int_con_stat' in variables and variables['int_con_stat'] == (4, Type('int', type_quals=(('const', ), )))) assert ('int_extern' in variables and variables['int_extern'] == (4, Type('int'))) # String assert ('str1' in variables and variables['str1'] == ("normal string", Type('char', '*'))) assert ('str2' in variables and variables['str2'] == ("string with macro: INT", Type('char', '*', '*'))) assert ('str3' in variables and variables['str3'] == ("string with comment: /*comment inside string*/", Type('char', '*', type_quals=(('const', ), ('const', ))))) assert ('str4' in variables and variables['str4'] == ("string with define #define MACRO5 macro5_in_string ", Type('char', '*'))) assert ('str5' in variables and variables['str5'] == ("string with \"escaped quotes\" ", Type('char', '*'))) # Test complex evaluation assert ('x1' in variables and variables['x1'] == (1., Type('float'))) # Test type casting handling. assert ('x2' in variables and variables['x2'] == (88342528, Type('int'))) # Test array handling assert ('array' in variables and variables['array'] == ([1, 3141500.0], Type('float', [2]))) assert ('intJunk' in variables and variables['intJunk'] == (None, Type('int', '*', '*', '*', [4], type_quals=(('const', ), ('const', ), (), (), ())))) # test type qualifiers assert variables.get('typeQualedIntPtrPtr') == \ (None, Type('int', '*', '*', type_quals=(('const',), ('volatile',), ())) ) assert variables.get('typeQualedIntPtr') == \ (None, Type('int', '*', type_quals=(('const', 'volatile',), ()))) # test type definition precedence assert variables.get('prec_ptr_of_arr') == \ (None, Type('int', [1], '*')) assert variables.get('prec_arr_of_ptr') == \ (None, Type('int', '*', [1])) assert variables.get('prec_arr_of_ptr2') == \ (None, Type('int', '*', [1])) # No structure, no unions, no enum def test_typedef(self): path = os.path.join(self.h_dir, 'typedefs.h') self.parser.load_file(path) self.parser.process_all() types = self.parser.defs['types'] variables = self.parser.defs['variables'] # Test defining types from base types. assert ('typeChar' in types and types['typeChar'] == Type('char', '*', '*')) assert ('typeInt' in types and types['typeInt'] == Type('int')) assert ('typeIntPtr' in types and types['typeIntPtr'] == Type('int', '*')) assert ('typeIntArr' in types and types['typeIntArr'] == Type('int', [10])) assert ('typeIntDArr' in types and types['typeIntDArr'] == Type('int', [5], [6])) assert ('typeTypeInt' in types and types['typeTypeInt'] == Type('typeInt')) assert not self.parser.is_fund_type('typeTypeInt') assert self.parser.eval_type(['typeTypeInt']) == Type('int') assert ('ULONG' in types and types['ULONG'] == Type('unsigned long')) # Test annotated types assert ('voidpc' in types and types['voidpc'] == Type( 'void', '*', type_quals=(('const', ), ()))) assert ('charf' in types and types['charf'] == Type('char', type_quals=(('far', ), ))) # Test using custom type. assert ('ttip5' in variables and variables['ttip5'] == (None, Type('typeTypeInt', '*', [5]))) # Handling undefined types assert ('SomeOtherType' in types and types['SomeOtherType'] == Type('someType')) assert ('x' in variables and variables['x'] == (None, Type('undefined'))) assert not self.parser.is_fund_type('SomeOtherType') with raises(Exception): self.parser.eval_type(Type('undefined')) # Testing recursive defs assert 'recType1' in types assert 'recType2' in types assert 'recType3' in types with raises(Exception): self.parser.eval_type(Type('recType3')) def test_enums(self): path = os.path.join(self.h_dir, 'enums.h') self.parser.load_file(path) self.parser.process_all() enums = self.parser.defs['enums'] types = self.parser.defs['types'] variables = self.parser.defs['variables'] print(self.parser.defs['values']) assert ('enum_name' in enums and 'enum enum_name' in types) assert enums['enum_name'] == { 'enum1': 129, 'enum2': 6, 'enum3': 7, 'enum4': 8 } assert types['enum enum_name'] == Type( 'enum', 'enum_name', ) assert ('enum_inst' in variables and variables['enum_inst'] == (None, Type('enum enum_name', ))) assert 'anon_enum0' in enums assert 'anon_enum1' in enums assert 'no_name_enum_typeddef' in types def test_struct(self): path = os.path.join(self.h_dir, 'structs.h') self.parser.load_file(path) self.parser.process_all() structs = self.parser.defs['structs'] types = self.parser.defs['types'] variables = self.parser.defs['variables'] # Test creating a structure using only base types. assert ('struct_name' in structs and 'struct struct_name' in types) assert structs['struct_name'] == \ Struct(('x', Type('int'), 1), ('y', Type('type_type_int'), None, 2), ('str', Type('char', [10]), None)) assert ('struct_inst' in variables and variables['struct_inst'] == (None, Type('struct struct_name'))) # Test creating a pointer type from a structure. assert ('struct_name_ptr' in types and types['struct_name_ptr'] == Type('struct struct_name', '*')) assert ('struct_name2_ptr' in types and types['struct_name2_ptr'] == Type('struct anon_struct0', '*')) # Test declaring a recursive structure. assert ('recursive_struct' in structs and 'struct recursive_struct' in types) assert structs['recursive_struct'] == \ Struct(('next', Type('struct recursive_struct', '*'), None)) # Test declaring near and far pointers. assert 'tagWNDCLASSEXA' in structs assert ('NPWNDCLASSEXA' in types and (types['NPWNDCLASSEXA'] == Type( 'struct tagWNDCLASSEXA', '*', type_quals=(('near', ), ())))) # Test altering the packing of a structure. assert ('struct_name_p' in structs and 'struct struct_name_p' in types) assert structs['struct_name_p'] == \ Struct(('x', Type('int'), None), ('y', Type('type_type_int'), None), ('str', Type('char', [10]), "brace } \0"), pack=16) def test_unions(self): path = os.path.join(self.h_dir, 'unions.h') self.parser.load_file(path) self.parser.process_all() unions = self.parser.defs['unions'] structs = self.parser.defs['structs'] types = self.parser.defs['types'] variables = self.parser.defs['variables'] # Test declaring an union. assert 'union_name' in unions and 'union union_name' in types assert unions['union_name'] == \ Union(('x', Type('int'), 1), ('y', Type('int'), None), pack=None) assert ('union_name_ptr' in types and types['union_name_ptr'] == Type('union union_name', '*')) # Test defining an unnamed union assert ('no_name_union_inst' in variables and variables['no_name_union_inst'] == (None, Type('union anon_union0'))) # Test defining a structure using an unnamed union internally. assert ('tagRID_DEVICE_INFO' in structs and structs['tagRID_DEVICE_INFO'] == \ Struct(('cbSize', Type('DWORD'), None), ('dwType', Type('DWORD'), None), (None, Type('union anon_union1'), None))) assert ('RID_DEVICE_INFO' in types and types['RID_DEVICE_INFO'] == Type('struct tagRID_DEVICE_INFO')) assert ('PRID_DEVICE_INFO' in types and types['PRID_DEVICE_INFO'] == Type( 'struct tagRID_DEVICE_INFO', '*')) assert ('LPRID_DEVICE_INFO' in types and (types['LPRID_DEVICE_INFO'] == Type( 'struct tagRID_DEVICE_INFO', '*'))) def test_functions(self): path = os.path.join(self.h_dir, 'functions.h') self.parser.load_file(path) self.parser.process_all() functions = self.parser.defs['functions'] variables = self.parser.defs['variables'] assert functions.get('f') == \ Type(Type('void'), ( (None, Type('int'), None), (None, Type('int'), None) )) assert functions['g'] == \ Type(Type('int'), ( ('ch', Type('char', '*'), None), ('str', Type('char', '*', '*'), None) )) assert variables.get('fnPtr') == \ (None, Type('int', ( (None, Type('char'), None), (None, Type('float'), None) ), '*')) assert functions.get('function1') == \ Type(Type('int', '__stdcall', type_quals=((), None)), ()) assert functions.get('function2') == Type(Type('int'), ()) assert 'externFunc' in functions ptyp = Type('int', '*', '*', type_quals=(('volatile', ), ('const', ), ())) assert functions.get('typeQualedFunc') == \ Type(Type('int'), ((None, ptyp, None),))
class TestParsing(object): """Test parsing. """ h_dir = H_DIRECTORY def setup(self): self.parser = CParser(process_all=False) def test_variables(self): path = os.path.join(self.h_dir, "variables.h") self.parser.load_file(path) self.parser.process_all() variables = self.parser.defs["variables"] # Integers assert "short1" in variables and variables["short1"] == (1, Type("signed short")) assert "short_int" in variables and variables["short_int"] == (1, Type("short int")) assert "short_un" in variables and variables["short_un"] == (1, Type("unsigned short")) assert "short_int_un" in variables and variables["short_int_un"] == (1, Type("unsigned short int")) assert "int1" in variables and variables["int1"] == (1, Type("int")) assert "un" in variables and variables["un"] == (1, Type("unsigned")) assert "int_un" in variables and variables["int_un"] == (1, Type("unsigned int")) assert "long1" in variables and variables["long1"] == (1, Type("long")) assert "long_int" in variables and variables["long_int"] == (1, Type("long int")) assert "long_un" in variables and variables["long_un"] == (1, Type("unsigned long")) assert "long_int_un" in variables and variables["long_int_un"] == (1, Type("unsigned long int")) if sys.platform == "win32": assert "int64" in variables and variables["int64"] == (1, Type("__int64")) assert "int64_un" in variables and variables["int64_un"] == (1, Type("unsigned __int64")) assert "long_long" in variables and variables["long_long"] == (1, Type("long long")) assert "long_long_int" in variables and variables["long_long_int"] == (1, Type("long long int")) assert "long_long_un" in variables and variables["long_long_un"] == (1, Type("unsigned long long")) assert "long_long_int_un" in variables and variables["long_long_int_un"] == ( 1, Type("unsigned long " "long int"), ) # Floating point number assert "fl" in variables and variables["fl"] == (1.0, Type("float")) assert "db" in variables and variables["db"] == (0.1, Type("double")) assert "dbl" in variables and variables["dbl"] == (-10.0, Type("long double")) # Const and static modif assert "int_const" in variables and variables["int_const"] == (4, Type("int", type_quals=(("const",),))) assert "int_stat" in variables and variables["int_stat"] == (4, Type("int")) assert "int_con_stat" in variables and variables["int_con_stat"] == (4, Type("int", type_quals=(("const",),))) assert "int_extern" in variables and variables["int_extern"] == (4, Type("int")) # String assert "str1" in variables and variables["str1"] == ("normal string", Type("char", "*")) assert "str2" in variables and variables["str2"] == ("string with macro: INT", Type("char", "*", "*")) assert "str3" in variables and variables["str3"] == ( "string with comment: /*comment inside string*/", Type("char", "*", type_quals=(("const",), ("const",))), ) assert "str4" in variables and variables["str4"] == ( "string with define #define MACRO5 macro5_in_string ", Type("char", "*"), ) assert "str5" in variables and variables["str5"] == ('string with "escaped quotes" ', Type("char", "*")) # Test complex evaluation assert "x1" in variables and variables["x1"] == (1.0, Type("float")) # Test type casting handling. assert "x2" in variables and variables["x2"] == (88342528, Type("int")) # Test array handling assert "array" in variables and variables["array"] == ([1, 3141500.0], Type("float", [2])) assert "intJunk" in variables and variables["intJunk"] == ( None, Type("int", "*", "*", "*", [4], type_quals=(("const",), ("const",), (), (), ())), ) # test type qualifiers assert variables.get("typeQualedIntPtrPtr") == ( None, Type("int", "*", "*", type_quals=(("const",), ("volatile",), ())), ) assert variables.get("typeQualedIntPtr") == (None, Type("int", "*", type_quals=(("const", "volatile"), ()))) # test type definition precedence assert variables.get("prec_ptr_of_arr") == (None, Type("int", [1], "*")) assert variables.get("prec_arr_of_ptr") == (None, Type("int", "*", [1])) assert variables.get("prec_arr_of_ptr2") == (None, Type("int", "*", [1])) # No structure, no unions, no enum def test_typedef(self): path = os.path.join(self.h_dir, "typedefs.h") self.parser.load_file(path) self.parser.process_all() types = self.parser.defs["types"] variables = self.parser.defs["variables"] # Test defining types from base types. assert "typeChar" in types and types["typeChar"] == Type("char", "*", "*") assert "typeInt" in types and types["typeInt"] == Type("int") assert "typeIntPtr" in types and types["typeIntPtr"] == Type("int", "*") assert "typeIntArr" in types and types["typeIntArr"] == Type("int", [10]) assert "typeIntDArr" in types and types["typeIntDArr"] == Type("int", [5], [6]) assert "typeTypeInt" in types and types["typeTypeInt"] == Type("typeInt") assert not self.parser.is_fund_type("typeTypeInt") assert self.parser.eval_type(["typeTypeInt"]) == Type("int") assert "ULONG" in types and types["ULONG"] == Type("unsigned long") # Test annotated types assert "voidpc" in types and types["voidpc"] == Type("void", "*", type_quals=(("const",), ())) assert "charf" in types and types["charf"] == Type("char", type_quals=(("far",),)) # Test using custom type. assert "ttip5" in variables and variables["ttip5"] == (None, Type("typeTypeInt", "*", [5])) # Handling undefined types assert "SomeOtherType" in types and types["SomeOtherType"] == Type("someType") assert "x" in variables and variables["x"] == (None, Type("undefined")) assert not self.parser.is_fund_type("SomeOtherType") with raises(Exception): self.parser.eval_type(Type("undefined")) # Testing recursive defs assert "recType1" in types assert "recType2" in types assert "recType3" in types with raises(Exception): self.parser.eval_type(Type("recType3")) def test_enums(self): path = os.path.join(self.h_dir, "enums.h") self.parser.load_file(path) self.parser.process_all() enums = self.parser.defs["enums"] types = self.parser.defs["types"] variables = self.parser.defs["variables"] print(self.parser.defs["values"]) assert "enum_name" in enums and "enum enum_name" in types assert enums["enum_name"] == {"enum1": 129, "enum2": 6, "enum3": 7, "enum4": 8} assert types["enum enum_name"] == Type("enum", "enum_name") assert "enum_inst" in variables and variables["enum_inst"] == (None, Type("enum enum_name")) assert "anon_enum0" in enums assert "anon_enum1" in enums assert "no_name_enum_typeddef" in types def test_struct(self): path = os.path.join(self.h_dir, "structs.h") self.parser.load_file(path) self.parser.process_all() structs = self.parser.defs["structs"] types = self.parser.defs["types"] variables = self.parser.defs["variables"] # Test creating a structure using only base types. assert "struct_name" in structs and "struct struct_name" in types assert structs["struct_name"] == Struct( ("x", Type("int"), 1), ("y", Type("type_type_int"), None, 2), ("str", Type("char", [10]), None) ) assert "struct_inst" in variables and variables["struct_inst"] == (None, Type("struct struct_name")) # Test creating a pointer type from a structure. assert "struct_name_ptr" in types and types["struct_name_ptr"] == Type("struct struct_name", "*") assert "struct_name2_ptr" in types and types["struct_name2_ptr"] == Type("struct anon_struct0", "*") # Test declaring a recursive structure. assert "recursive_struct" in structs and "struct recursive_struct" in types assert structs["recursive_struct"] == Struct(("next", Type("struct recursive_struct", "*"), None)) # Test declaring near and far pointers. assert "tagWNDCLASSEXA" in structs assert "NPWNDCLASSEXA" in types and ( types["NPWNDCLASSEXA"] == Type("struct tagWNDCLASSEXA", "*", type_quals=(("near",), ())) ) # Test altering the packing of a structure. assert "struct_name_p" in structs and "struct struct_name_p" in types assert structs["struct_name_p"] == Struct( ("x", Type("int"), None), ("y", Type("type_type_int"), None), ("str", Type("char", [10]), "brace } \0"), pack=16, ) def test_unions(self): path = os.path.join(self.h_dir, "unions.h") self.parser.load_file(path) self.parser.process_all() unions = self.parser.defs["unions"] structs = self.parser.defs["structs"] types = self.parser.defs["types"] variables = self.parser.defs["variables"] # Test declaring an union. assert "union_name" in unions and "union union_name" in types assert unions["union_name"] == Union(("x", Type("int"), 1), ("y", Type("int"), None), pack=None) assert "union_name_ptr" in types and types["union_name_ptr"] == Type("union union_name", "*") # Test defining an unnamed union assert "no_name_union_inst" in variables and variables["no_name_union_inst"] == ( None, Type("union anon_union0"), ) # Test defining a structure using an unnamed union internally. assert "tagRID_DEVICE_INFO" in structs and structs["tagRID_DEVICE_INFO"] == Struct( ("cbSize", Type("DWORD"), None), ("dwType", Type("DWORD"), None), (None, Type("union anon_union1"), None) ) assert "RID_DEVICE_INFO" in types and types["RID_DEVICE_INFO"] == Type("struct tagRID_DEVICE_INFO") assert "PRID_DEVICE_INFO" in types and types["PRID_DEVICE_INFO"] == Type("struct tagRID_DEVICE_INFO", "*") assert "LPRID_DEVICE_INFO" in types and (types["LPRID_DEVICE_INFO"] == Type("struct tagRID_DEVICE_INFO", "*")) def test_functions(self): path = os.path.join(self.h_dir, "functions.h") self.parser.load_file(path) self.parser.process_all() functions = self.parser.defs["functions"] variables = self.parser.defs["variables"] assert functions.get("f") == Type(Type("void"), ((None, Type("int"), None), (None, Type("int"), None))) assert functions["g"] == Type( Type("int"), (("ch", Type("char", "*"), None), ("str", Type("char", "*", "*"), None)) ) assert variables.get("fnPtr") == ( None, Type("int", ((None, Type("char"), None), (None, Type("float"), None)), "*"), ) assert functions.get("function1") == Type(Type("int", "__stdcall", type_quals=((), None)), ()) assert functions.get("function2") == Type(Type("int"), ()) assert "externFunc" in functions ptyp = Type("int", "*", "*", type_quals=(("volatile",), ("const",), ())) assert functions.get("typeQualedFunc") == Type(Type("int"), ((None, ptyp, None),))
class TestParsing(object): """Test parsing. """ h_dir = H_DIRECTORY def setup(self): self.parser = CParser(process_all=False) def test_variables(self): path = os.path.join(self.h_dir, 'variables.h') self.parser.load_file(path) self.parser.process_all() variables = self.parser.defs['variables'] # Integers assert ('short1' in variables and variables['short1'] == (1, Type('signed short'))) assert ('short_int' in variables and variables['short_int'] == (1, Type('short int'))) assert ('short_un' in variables and variables['short_un'] == (1, Type('unsigned short'))) assert ('short_int_un' in variables and variables['short_int_un'] == (1, Type('unsigned short int'))) assert ('int1' in variables and variables['int1'] == (1, Type('int'))) assert ('un' in variables and variables['un'] == (1, Type('unsigned'))) assert ('int_un' in variables and variables['int_un'] == (1, Type('unsigned int'))) assert ('long1' in variables and variables['long1'] == (1, Type('long'))) assert ('long_int' in variables and variables['long_int'] == (1, Type('long int'))) assert ('long_un' in variables and variables['long_un'] == (1, Type('unsigned long'))) assert ('long_int_un' in variables and variables['long_int_un'] == (1, Type('unsigned long int'))) if sys.platform == 'win32': assert ('int64' in variables and variables['int64'] == (1, Type('__int64'))) assert ('int64_un' in variables and variables['int64_un'] == (1, Type('unsigned __int64'))) assert ('long_long' in variables and variables['long_long'] == (1, Type('long long'))) assert ('long_long_int' in variables and variables['long_long_int'] == (1, Type('long long int'))) assert ('long_long_un' in variables and variables['long_long_un'] == (1, Type('unsigned long long'))) assert ('long_long_int_un' in variables and variables['long_long_int_un'] == (1, Type('unsigned long ' 'long int'))) # Floating point number assert ('fl' in variables and variables['fl'] == (1., Type('float'))) assert ('db' in variables and variables['db'] == (0.1, Type('double'))) assert ('dbl' in variables and variables['dbl'] == (-10., Type('long double'))) # Const and static modif assert ('int_const' in variables and variables['int_const'] == (4, Type('int', type_quals=(('const',),)))) assert ('int_stat' in variables and variables['int_stat'] == (4, Type('int'))) assert ('int_con_stat' in variables and variables['int_con_stat'] == (4, Type('int', type_quals=(('const',),)))) assert ('int_extern' in variables and variables['int_extern'] == (4, Type('int'))) # String assert ('str1' in variables and variables['str1'] == ("normal string", Type('char', '*'))) assert ('str2' in variables and variables['str2'] == ("string with macro: INT", Type('char', '*', '*'))) assert ('str3' in variables and variables['str3'] == ("string with comment: /*comment inside string*/", Type('char', '*', type_quals=(('const',), ('const',))))) assert ('str4' in variables and variables['str4'] == ("string with define #define MACRO5 macro5_in_string ", Type('char', '*'))) assert ('str5' in variables and variables['str5'] == ("string with \"escaped quotes\" ", Type('char', '*'))) # Test complex evaluation assert ('x1' in variables and variables['x1'] == (1., Type('float'))) # Test type casting handling. assert ('x2' in variables and variables['x2'] == (88342528, Type('int'))) # Test array handling assert ('array' in variables and variables['array'] == ([1, 3141500.0], Type('float', [2]))) assert ('intJunk' in variables and variables['intJunk'] == ( None, Type('int', '*', '*', '*', [4], type_quals=(('const',), ('const',), (), (), ())) ) ) # test type qualifiers assert variables.get('typeQualedIntPtrPtr') == \ (None, Type('int', '*', '*', type_quals=(('const',), ('volatile',), ())) ) assert variables.get('typeQualedIntPtr') == \ (None, Type('int', '*', type_quals=(('const', 'volatile',), ()))) # test type definition precedence assert variables.get('prec_ptr_of_arr') == \ (None, Type('int', [1], '*')) assert variables.get('prec_arr_of_ptr') == \ (None, Type('int', '*', [1])) assert variables.get('prec_arr_of_ptr2') == \ (None, Type('int', '*', [1])) # No structure, no unions, no enum def test_typedef(self): path = os.path.join(self.h_dir, 'typedefs.h') self.parser.load_file(path) self.parser.process_all() types = self.parser.defs['types'] variables = self.parser.defs['variables'] # Test defining types from base types. assert ('typeChar' in types and types['typeChar'] == Type('char', '*', '*')) assert ('typeInt' in types and types['typeInt'] == Type('int')) assert ('typeIntPtr' in types and types['typeIntPtr'] == Type('int', '*')) assert ('typeIntArr' in types and types['typeIntArr'] == Type('int', [10])) assert ('typeIntDArr' in types and types['typeIntDArr'] == Type('int', [5], [6])) assert ('typeTypeInt' in types and types['typeTypeInt'] == Type('typeInt')) assert not self.parser.is_fund_type('typeTypeInt') assert self.parser.eval_type(['typeTypeInt']) == Type('int') assert ('ULONG' in types and types['ULONG'] == Type('unsigned long')) # Test annotated types assert ('voidpc' in types and types['voidpc'] == Type('void', '*', type_quals=(('const',), ()))) assert ('charf' in types and types['charf'] == Type('char', type_quals=(('far',),))) # Test using custom type. assert ('ttip5' in variables and variables['ttip5'] == (None, Type('typeTypeInt', '*', [5]))) # Handling undefined types assert ('SomeOtherType' in types and types['SomeOtherType'] == Type('someType')) assert ('x' in variables and variables['x'] == (None, Type('undefined'))) assert not self.parser.is_fund_type('SomeOtherType') with raises(Exception): self.parser.eval_type(Type('undefined')) # Testing recursive defs assert 'recType1' in types assert 'recType2' in types assert 'recType3' in types with raises(Exception): self.parser.eval_type(Type('recType3')) def test_enums(self): path = os.path.join(self.h_dir, 'enums.h') self.parser.load_file(path) self.parser.process_all() enums = self.parser.defs['enums'] types = self.parser.defs['types'] variables = self.parser.defs['variables'] print(self.parser.defs['values']) assert ('enum_name' in enums and 'enum enum_name' in types) assert enums['enum_name'] == {'enum1': 129, 'enum2': 6, 'enum3': 7, 'enum4': 8} assert types['enum enum_name'] == Type('enum', 'enum_name',) assert ('enum_inst' in variables and variables['enum_inst'] == (None, Type('enum enum_name',))) assert 'anon_enum0' in enums assert 'anon_enum1' in enums assert 'no_name_enum_typeddef' in types def test_struct(self): path = os.path.join(self.h_dir, 'structs.h') self.parser.load_file(path) self.parser.process_all() structs = self.parser.defs['structs'] types = self.parser.defs['types'] variables = self.parser.defs['variables'] # Test creating a structure using only base types. assert ('struct_name' in structs and 'struct struct_name' in types) assert structs['struct_name'] == \ Struct(('x', Type('int'), 1), ('y', Type('type_type_int'), None, 2), ('str', Type('char', [10]), None)) assert ('struct_inst' in variables and variables['struct_inst'] == (None, Type('struct struct_name'))) # Test creating a pointer type from a structure. assert ('struct_name_ptr' in types and types['struct_name_ptr'] == Type('struct struct_name', '*')) assert ('struct_name2_ptr' in types and types['struct_name2_ptr'] == Type('struct anon_struct0', '*')) # Test declaring a recursive structure. assert ('recursive_struct' in structs and 'struct recursive_struct' in types) assert structs['recursive_struct'] == \ Struct(('next', Type('struct recursive_struct', '*'), None)) # Test declaring near and far pointers. assert 'tagWNDCLASSEXA' in structs assert ('NPWNDCLASSEXA' in types and ( types['NPWNDCLASSEXA'] == Type('struct tagWNDCLASSEXA', '*', type_quals=(('near',), ())))) # Test altering the packing of a structure. assert ('struct_name_p' in structs and 'struct struct_name_p' in types) assert structs['struct_name_p'] == \ Struct(('x', Type('int'), None), ('y', Type('type_type_int'), None), ('str', Type('char', [10]), "brace } \0"), pack=16) def test_unions(self): path = os.path.join(self.h_dir, 'unions.h') self.parser.load_file(path) self.parser.process_all() unions = self.parser.defs['unions'] structs = self.parser.defs['structs'] types = self.parser.defs['types'] variables = self.parser.defs['variables'] # Test declaring an union. assert 'union_name' in unions and 'union union_name' in types assert unions['union_name'] == \ Union(('x', Type('int'), 1), ('y', Type('int'), None), pack=None) assert ('union_name_ptr' in types and types['union_name_ptr'] == Type('union union_name', '*')) # Test defining an unnamed union assert ('no_name_union_inst' in variables and variables['no_name_union_inst'] == (None, Type('union anon_union0'))) # Test defining a structure using an unnamed union internally. assert ('tagRID_DEVICE_INFO' in structs and structs['tagRID_DEVICE_INFO'] == \ Struct(('cbSize', Type('DWORD'), None), ('dwType', Type('DWORD'), None), (None, Type('union anon_union1'), None))) assert ('RID_DEVICE_INFO' in types and types['RID_DEVICE_INFO'] == Type('struct tagRID_DEVICE_INFO')) assert ('PRID_DEVICE_INFO' in types and types['PRID_DEVICE_INFO'] == Type('struct tagRID_DEVICE_INFO', '*') ) assert ('LPRID_DEVICE_INFO' in types and ( types['LPRID_DEVICE_INFO'] == Type('struct tagRID_DEVICE_INFO', '*') ) ) def test_functions(self): path = os.path.join(self.h_dir, 'functions.h') self.parser.load_file(path) self.parser.process_all() functions = self.parser.defs['functions'] variables = self.parser.defs['variables'] assert functions.get('f') == \ Type(Type('void'), ( (None, Type('int'), None), (None, Type('int'), None) )) assert functions['g'] == \ Type(Type('int'), ( ('ch', Type('char', '*'), None), ('str', Type('char', '*', '*'), None) )) assert variables.get('fnPtr') == \ (None, Type('int', ( (None, Type('char'), None), (None, Type('float'), None) ), '*')) assert functions.get('function1') == \ Type(Type('int', '__stdcall', type_quals=((), None)), ()) assert functions.get('function2') == Type(Type('int'), ()) assert 'externFunc' in functions ptyp = Type('int', '*', '*', type_quals=(('volatile',), ('const',), ())) assert functions.get('typeQualedFunc') == \ Type(Type('int'), ((None, ptyp, None),))