def parseIncludeFile(f, define = [], includes = [], ps = 4): global ptr_size ptr_size = ps gccxmlexe = os.getenv("GCCXML", "gccxml") config = parser.config_t(gccxml_path = gccxmlexe, define_symbols = define, include_paths = includes) functions = {} if isinstance(f, list): global_ns = parser.parse(f, config) else: global_ns = parser.parse([f], config) all_decls = declarations.make_flatten(global_ns) all_functions = filter(lambda decl: isinstance(decl, declarations.free_function_t), \ all_decls) for f in all_functions: if not f.name.startswith("__"): # if f.name == "ReadFileEx": functions[f.name] = parseFunction(f) return functions
def test_directory_cache_twice(self): """ Setup two caches in a row. The second run will reload the same cache directory. """ cache = parser.directory_cache_t(directory=self.cache_dir) parser.parse([self.header], self.config, cache=cache) cache = parser.directory_cache_t(directory=self.cache_dir) parser.parse([self.header], self.config, cache=cache)
def test_directory_cache_without_compression(self): """ Test the directory cache without compression """ # Test with compression OFF cache = parser.directory_cache_t(directory=self.cache_dir) # Generate a cache on first read parser.parse([self.header], self.config, cache=cache) # Read from the cache the second time parser.parse([self.header], self.config, cache=cache)
def test_attributes(self): decls = parser.parse([self.header], self.config) Test.global_ns = declarations.get_global_namespace(decls) Test.global_ns.init_optimizer() numeric = self.global_ns.class_('numeric_t') do_nothing = numeric.member_function('do_nothing') arg = do_nothing.arguments[0] generator = self.config.xml_generator_from_xml_file if generator.is_castxml1 or \ (generator.is_castxml and float(generator.xml_output_version) >= 1.137): # This works since: # https://github.com/CastXML/CastXML/issues/25 # https://github.com/CastXML/CastXML/pull/26 # https://github.com/CastXML/CastXML/pull/27 # The version bump to 1.137 came way later but this is the # only way to make sure the test is running correctly self.assertTrue("annotate(sealed)" == numeric.attributes) self.assertTrue("annotate(no throw)" == do_nothing.attributes) self.assertTrue("annotate(out)" == arg.attributes) self.assertTrue( numeric.member_operators(name="=")[0].attributes is None) else: self.assertTrue("gccxml(no throw)" == do_nothing.attributes) self.assertTrue("gccxml(out)" == arg.attributes)
def global_namespace(): #configure GCC-XML parser config = parser.config_t( gccxml_path= "c:/Progra~1/GCC_XML/bin/gccxml.exe",\ include_paths= ["e:/starteam/docplatform/nextrelease/code/common"] ) #parsing source file decls = parser.parse( ['interf.h'], config ) return declarations.get_global_namespace( decls )
def setUp(self): if not tester_t.global_ns: decls = parser.parse([self.header], self.config) tester_t.global_ns = declarations.get_global_namespace(decls) tester_t.global_ns.init_optimizer() process = subprocess.Popen( args='scons msvc_compiler=%s' % autoconfig.cxx_parsers_cfg.gccxml.compiler, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, cwd=self.binary_parsers_dir) process.stdin.close() while process.poll() is None: line = process.stdout.readline() print(line.rstrip()) for line in process.stdout.readlines(): print(line.rstrip()) if process.returncode: raise RuntimeError( ("unable to compile binary parser module. " + "See output for the errors."))
def setUp(self): if not Test.declarations: Test.declarations = parser.parse([self.header], self.config) Test.xml_generator_from_xml_file = \ self.config.xml_generator_from_xml_file self.declarations = Test.declarations self.xml_generator_from_xml_file = Test.xml_generator_from_xml_file
def test_update(self): # Save the content of the header file for later with open(self.header, "r") as old_header: content = old_header.read() declarations = parser.parse([self.header], self.config) cache = parser.file_cache_t(self.cache_file) cache.update( source_file=self.header, configuration=self.config, declarations=declarations, included_files=[]) self.assertTrue( declarations == cache.cached_value( self.header, self.config), "cached declarations and source declarations are different") self.touch() self.assertTrue( cache.cached_value(self.header, self.config) is None, "cache didn't recognize that some files on disk has been changed") # We wrote a //touch in the header file. Just replace the file with the # original content. The touched file would be sometimes commited by # error as it was modified. with open(self.header, "w") as new_header: new_header.write(content)
def test_dir_compatibility(self): """ For retro-compatibility, test if the dir argument is still working This test can be removed in v2.0.0. """ # Do not clutter the tests with warnings warnings.simplefilter("ignore", DeprecationWarning) cache = parser.directory_cache_t(dir=self.cache_dir, compression=True) parser.parse([self.header], self.config, cache=cache) # Reset this warning to always warnings.simplefilter("error", DeprecationWarning)
def setUp(self): if not self.declarations: self.declarations = parser.parse( ['typedefs1.hpp', 'typedefs2.hpp'], self.config, self.COMPILATION_MODE)
def test_attributes_thiscall(self): """ Test attributes with the "f2" flag """ if self.config.compiler != "msvc": return self.config.flags = ["f2"] decls = parser.parse([self.header], self.config) Test.global_ns = declarations.get_global_namespace(decls) Test.global_ns.init_optimizer() numeric = self.global_ns.class_('numeric_t') do_nothing = numeric.member_function('do_nothing') arg = do_nothing.arguments[0] generator = self.config.xml_generator_from_xml_file if generator.is_castxml1 or ( generator.is_castxml and float(generator.xml_output_version) >= 1.137): self.assertTrue("annotate(sealed)" == numeric.attributes) self.assertTrue("annotate(out)" == arg.attributes) self.assertTrue( "__thiscall__ annotate(no throw)" == do_nothing.attributes) self.assertTrue( numeric.member_operators(name="=")[0].attributes == "__thiscall__")
def test_map_gcc5(self): """ The code in test_map_gcc5.hpp was breaking pygccxml. Test that case (gcc5 + castxml + c++11). See issue #45 and #55 """ if self.config.xml_generator == "gccxml": return decls = parser.parse([self.header], self.config) global_ns = declarations.get_global_namespace(decls) # This calldef is defined with gcc > 4.9 (maybe earlier, not tested) # and -std=c++11. Calling create_decl_string is failing with gcc. # With clang the calldef does not exist so the matcher # will just return an empty list, letting the test pass. # See the test_argument_without_name.py for an equivalent test, # which is not depending on the presence of the _M_clone_node # method in the stl_tree.h file. criteria = declarations.calldef_matcher(name="_M_clone_node") free_funcs = declarations.matcher.find(criteria, global_ns) for free_funcs in free_funcs: free_funcs.create_decl_string(with_defaults=False)
def setUp(self): if not self.declarations: self.declarations = parser.parse( [self.header], self.config ) self.global_ns = declarations.find_declaration( self.declarations , type=declarations.namespace_t , name='::' ) self.global_ns.init_optimizer()
def test_function_pointer(self): """ Test working with pointers and function pointers. """ decls = parser.parse([self.header], self.config) global_ns = declarations.get_global_namespace(decls) # Test on a function pointer criteria = declarations.variable_matcher(name="func1") variables = declarations.matcher.find(criteria, global_ns) self.assertTrue(variables[0].name == "func1") self.assertTrue( isinstance(variables[0].decl_type, declarations.pointer_t)) self.assertTrue( str(variables[0].decl_type) == "void (*)( int,double )") self.assertTrue( declarations.is_calldef_pointer(variables[0].decl_type)) self.assertTrue( isinstance(declarations.remove_pointer(variables[0].decl_type), declarations.free_function_type_t)) # Get the function (free_function_type_t) and test the return and # argument types function = variables[0].decl_type.base self.assertTrue(isinstance(function.return_type, declarations.void_t)) self.assertTrue( isinstance(function.arguments_types[0], declarations.int_t)) self.assertTrue( isinstance(function.arguments_types[1], declarations.double_t)) # Test on a normal pointer criteria = declarations.variable_matcher(name="myPointer") variables = declarations.matcher.find(criteria, global_ns) self.assertTrue(variables[0].name == "myPointer") self.assertTrue( isinstance(variables[0].decl_type, declarations.pointer_t)) self.assertFalse( declarations.is_calldef_pointer(variables[0].decl_type)) self.assertTrue( isinstance(declarations.remove_pointer(variables[0].decl_type), declarations.volatile_t)) # Test on function pointer in struct (x8) for d in global_ns.declarations: if d.name == "x8": self.assertTrue( isinstance(d.decl_type, declarations.pointer_t)) self.assertTrue(declarations.is_calldef_pointer(d.decl_type)) self.assertTrue( isinstance( declarations.remove_pointer(d.decl_type), declarations.member_function_type_t)) self.assertTrue( str(declarations.remove_pointer(d.decl_type)) == "void ( ::some_struct_t::* )( )")
def setUp(self): if not self.global_ns: decls = parser.parse([self.header], self.config) self.global_ns = declarations.get_global_namespace(decls) self.global_ns.init_optimizer() Test.xml_generator_from_xml_file = \ self.config.xml_generator_from_xml_file self.xml_generator_from_xml_file = Test.xml_generator_from_xml_file
def setUp(self): if not gccxml_declarations_t.global_ns: decls = parser.parse( self.test_files, self.config, self.COMPILATION_MODE) gccxml_declarations_t.global_ns = \ declarations.get_global_namespace(decls) if not self.global_ns: self.global_ns = gccxml_declarations_t.global_ns
def global_namespace(options): config = setup_pygccxml(options) gcccache = options["gccxml-cache"] if not gcccache: gcccache = "gcccache" cache = parser.directory_cache.directory_cache_t(dir=gcccache, md5_sigs=False) # normalize input files so that cache can match them # mixed slashes does not play well with the cache in_files = [os.path.abspath(p) for p in options["infiles"]] decls = parser.parse(in_files, config, cache=cache) return declarations.get_global_namespace(decls)
def setUp(self): if not core_t.global_ns: decls = parser.parse( self.test_files, self.config, self.COMPILATION_MODE) core_t.global_ns = pygccxml.declarations.get_global_namespace( decls) if self.INIT_OPTIMIZER: core_t.global_ns.init_optimizer() self.global_ns = core_t.global_ns
def test_map_gcc5(self): """ The code in test_map_gcc5.hpp was breaking pygccxml. Test that case (gcc5 + castxml + c++11). See issue #45 """ if self.config.xml_generator == "gccxml": return decls = parser.parse([self.header], self.config) self.global_ns = declarations.get_global_namespace(decls)
def test_comparison_from_reverse(self): parsed = parser.parse([self.header], self.config) copied = copy.deepcopy(parsed) parsed.sort() copied.reverse() copied.sort() x = parsed[4:6] x.sort() y = copied[4:6] y.sort() self.failUnless( parsed == copied, "__lt__ and/or __qe__ does not working properly")
def test_from_file(self): declarations = parser.parse([self.header], self.config) cache = parser.file_cache_t(self.cache_file) cache.update(source_file=self.header, configuration=self.config, declarations=declarations, included_files=[]) self.assertTrue( declarations == cache.cached_value(self.header, self.config), "cached declarations and source declarations are different", ) cache.flush() cache = parser.file_cache_t(self.cache_file) self.assertTrue( declarations == cache.cached_value(self.header, self.config), ("cached declarations and source declarations are different, " + "after pickling"), )
def test_template_split_std_vector(self): """ Demonstrate error in pattern parser, see #60 """ if self.config.xml_generator == "gccxml": return decls = parser.parse([self.header], self.config) for decl in declarations.make_flatten(decls): if "myClass" in decl.name: _ = decl.partial_name
def test_matcher(self): """ Run the matcher on all the templated classes. This exercises the whole pipeline even more. """ if self.config.xml_generator == "gccxml": return decls = parser.parse([self.header], self.config) global_ns = declarations.get_global_namespace(decls) criteria = declarations.declaration_matcher(name="myClass") _ = declarations.matcher.find(criteria, global_ns)
def test_is_elaborated_type(self): """ Test for the is_elaborated function """ if self.config.castxml_epic_version != 1: return decls = parser.parse([self.header], self.config) global_ns = declarations.get_global_namespace(decls) if self.config.xml_generator_from_xml_file.is_castxml1: for specifier in ["class", "struct", "enum", "union"]: self._test_impl_yes(global_ns, specifier) self._test_impl_no(global_ns, specifier) self._test_arg_impl(global_ns, specifier)
def main(): config = parser.config_t(include_paths=["../../include"], compiler="gcc") headers = ["brw_types.h", "brw_structs.h"] decls = parser.parse(headers, config, parser.COMPILATION_MODE.ALL_AT_ONCE) global_ns = declarations.get_global_namespace(decls) names = [] for class_ in global_ns.classes(decl_filter): names.append(class_.name) names.sort() dump_interfaces(decls, global_ns, names) dump_implementations(decls, global_ns, names)
def test(self): """ Test different compilation standards by setting cflags. """ # Skip this test for gccxml, this is a CastXML feature. if "gccxml" in self.config.xml_generator: return True parser.parse(["cpp_standards.hpp"], self.config) if platform.system() != 'Windows': self.config.cflags = "-std=c++98" parser.parse(["cpp_standards.hpp"], self.config) self.config.cflags = "-std=c++03" parser.parse(["cpp_standards.hpp"], self.config) self.config.cflags = "-std=c++11" parser.parse(["cpp_standards.hpp"], self.config) # This is broken with llvm 3.6.2 (the one from homebrew) # It should work with never llvms but I keep the test disabled # See https://llvm.org/bugs/show_bug.cgi?id=24872 # self.config.cflags = "-std=c++14" # parser.parse(["cpp_standards.hpp"], self.config) # Same as above # self.config.cflags = "-std=c++1z" # parser.parse(["cpp_standards.hpp"], self.config) # Pass down a flag that does not exist. # This should raise an exception. self.config.cflags = "-std=c++00" self.assertRaises( RuntimeError, lambda: parser.parse(["cpp_standards.hpp"], self.config))
def test_comparison_declaration_by_declaration(self): parsed = parser.parse([self.header], self.config) copied = copy.deepcopy(parsed) parsed = declarations.make_flatten(parsed) copied = declarations.make_flatten(copied) parsed.sort() copied.sort() failuers = [] for parsed_decl, copied_decl, index in \ zip(parsed, copied, list(range(len(copied)))): if parsed_decl != copied_decl: failuers.append( ("__lt__ and/or __qe__ does not working " + "properly in case of %s, %s, index %d") % (parsed_decl.__class__.__name__, copied_decl.__class__.__name__, index)) self.failUnless(not failuers, 'Failures: ' + '\n\t'.join(failuers))
def main(): print copyright.strip() print print '/**' print ' * @file' print ' * Dump SVGA commands.' print ' *' print ' * Generated automatically from svga3d_reg.h by svga_dump.py.' print ' */' print print '#include "svga_types.h"' print '#include "svga_shader_dump.h"' print '#include "svga3d_reg.h"' print print '#include "util/u_debug.h"' print '#include "svga_dump.h"' print config = parser.config_t( include_paths = ['../../../include', '../include'], compiler = 'gcc', ) headers = [ 'svga_types.h', 'svga3d_reg.h', ] decls = parser.parse(headers, config, parser.COMPILATION_MODE.ALL_AT_ONCE) global_ns = declarations.get_global_namespace(decls) names = set() for id, header, body, footer in cmds: names.add(header) for struct, count in body: names.add(struct) if footer is not None: names.add(footer) for class_ in global_ns.classes(lambda decl: decl.name in names): dump_struct(decls, class_) dump_cmds()
def test_infinite_recursion_sstream(self): """ Test find_noncopyable_vars See #71 find_noncopyable_vars was throwing: RuntimeError: maximum recursion depth exceeded while calling a Python object """ decls = parser.parse([self.header], self.config) global_ns = declarations.get_global_namespace(decls) # Real life example of the bug. This leads to a similar error, # but the situation is more complex as there are multiple # classes that are related the one to the others # (basic_istream, basic_ios, ios_base, ...) test_ns = global_ns.namespace('Test2') cls = test_ns.class_('FileStreamDataStream') declarations.type_traits_classes.find_noncopyable_vars(cls) self.assertFalse(declarations.type_traits_classes.is_noncopyable(cls))
def _setEnvironment(self): #gccxml_09_path = os.path.join('/', 'usr', 'bin', 'castxml') ---> CASTXML will be used for C++11 syntax. generator_path = os.path.join('/', 'usr', 'bin', 'castxml') generator_name = 'castxml' # Configure GCC-XML parser # config = parser.gccxml_configuration_t( # gccxml_path=gccxml_09_path, compiler='g++') xml_generator_config = parser.xml_generator_configuration_t( xml_generator_path = generator_path, xml_generator = generator_name, ) #Location where sources files are stored and will be written. # headerFilesDirectory = os.path.join(currentModuleDirectoryPath, '..', 'headerFiles') # generatedFilesDirectory = os.path.join(currentModuleDirectoryPath, '..', 'generatedFiles') #The directory where header files reside. # self._file_directory = self._headerFilesDirectory + "\\" #Parsing source file self._decls = parser.parse([os.path.join(self._file_directory, self._file_name)], xml_generator_config)
def setUp(self): if not Test.declarations: Test.declarations = parser.parse([self.header], self.config) self.declarations = Test.declarations
from pygccxml import declarations from pygccxml import parser import os import sys import warnings warnings.simplefilter("error", Warning) # Find out the file location within the sources tree this_module_dir_path = os.path.abspath( os.path.dirname(sys.modules[__name__].__file__)) # Find the location of the xml generator (castxml or gccxml) generator_path, generator_name = utils.find_xml_generator() # Configure the xml generator xml_generator_config = parser.xml_generator_configuration_t( xml_generator_path=generator_path, xml_generator=generator_name) # The c++ file we want to parse filename = "example.hpp" filename = this_module_dir_path + "/" + filename # Parse the c++ file decls = parser.parse([filename], xml_generator_config) # Get access to the global namespace global_namespace = declarations.get_global_namespace(decls) # Get access to the 'ns' namespace ns = global_namespace.namespace("ns")
def test_simple(self): decls = parser.parse([self.header], self.config) self.__check_result(decls)
def test_order(self): """ Test order of const, volatile, etc... in decl_string. The convention in pygccxml is that const and volatile qualifiers are placed on the right of their `base` type. """ decls = parser.parse([self.header], self.config) global_ns = declarations.get_global_namespace(decls) c1 = global_ns.variable("c1") c2 = global_ns.variable("c2") self.assertEqual(c1.decl_type.decl_string, "int const") self.assertEqual(c2.decl_type.decl_string, "int const") cptr1 = global_ns.variable("cptr1") cptr2 = global_ns.variable("cptr2") self.assertEqual(cptr1.decl_type.decl_string, "int const * const") self.assertEqual(cptr2.decl_type.decl_string, "int const * const") v1 = global_ns.variable("v1") v2 = global_ns.variable("v2") self.assertEqual(v1.decl_type.decl_string, "int volatile") self.assertEqual(v2.decl_type.decl_string, "int volatile") vptr1 = global_ns.variable("vptr1") vptr2 = global_ns.variable("vptr2") decl_string = "int volatile * volatile" self.assertEqual(vptr1.decl_type.decl_string, decl_string) self.assertEqual(vptr2.decl_type.decl_string, decl_string) cv1 = global_ns.variable("cv1") cv2 = global_ns.variable("cv2") cv3 = global_ns.variable("cv3") cv4 = global_ns.variable("cv4") self.assertEqual(cv1.decl_type.decl_string, "int const volatile") self.assertEqual(cv2.decl_type.decl_string, "int const volatile") self.assertEqual(cv3.decl_type.decl_string, "int const volatile") self.assertEqual(cv4.decl_type.decl_string, "int const volatile") cvptr1 = global_ns.variable("cvptr1") cvptr2 = global_ns.variable("cvptr2") cvptr3 = global_ns.variable("cvptr3") cvptr4 = global_ns.variable("cvptr4") decl_string = "int const volatile * const volatile" self.assertEqual(cvptr1.decl_type.decl_string, decl_string) self.assertEqual(cvptr2.decl_type.decl_string, decl_string) self.assertEqual(cvptr3.decl_type.decl_string, decl_string) self.assertEqual(cvptr4.decl_type.decl_string, decl_string) ac1 = global_ns.variable("ac1") ac2 = global_ns.variable("ac2") if self.config.xml_generator_from_xml_file.is_gccxml: self.assertEqual(ac1.decl_type.decl_string, "int [2] const") self.assertEqual(ac2.decl_type.decl_string, "int [2] const") else: self.assertEqual(ac1.decl_type.decl_string, "int const [2]") self.assertEqual(ac2.decl_type.decl_string, "int const [2]") acptr1 = global_ns.variable("acptr1") acptr2 = global_ns.variable("acptr2") if self.config.xml_generator_from_xml_file.is_gccxml: decl_string = "int const * [2] const" self.assertEqual(acptr1.decl_type.decl_string, decl_string) self.assertEqual(acptr2.decl_type.decl_string, decl_string) else: t_string = "int const * const [2]" self.assertEqual(acptr1.decl_type.decl_string, t_string) self.assertEqual(acptr2.decl_type.decl_string, t_string) class_a = global_ns.variable("classA") if self.config.xml_generator_from_xml_file.is_castxml1: # The elaborated type specifier (class) is on the left self.assertEqual(class_a.decl_type.decl_string, "class ::A const") else: self.assertEqual(class_a.decl_type.decl_string, "::A const")
def setUp(self): if self.config.xml_generator == "gccxml": return decls = parser.parse([self.header], self.config) self.global_ns = declarations.get_global_namespace(decls)
def get_header_info(self): """ PyGCCXML header code parser magic happens here! : returns the parsed header data in python dict : return dict keys: namespace, class, io_signature, make, properties, methods : Can be used as an CLI command or an extenal API """ gr = self.modname.split('-')[0] module = self.modname.split('-')[-1] generator_path, generator_name = utils.find_xml_generator() xml_generator_config = parser.xml_generator_configuration_t( xml_generator_path=generator_path, xml_generator=generator_name, compiler='gcc') decls = parser.parse( [self.target_file], xml_generator_config) global_namespace = declarations.get_global_namespace(decls) # namespace try: self.parsed_data['namespace'] = [] ns = global_namespace.namespace(gr) if ns is None: raise BlockToolException main_namespace = ns.namespace(module) if main_namespace is None: raise BlockToolException('namespace cannot be none') self.parsed_data['namespace'] = [gr, module] if main_namespace.declarations: for _namespace in main_namespace.declarations: if isinstance(_namespace, declarations.namespace_t): if Constants.KERNEL not in str(_namespace): main_namespace = _namespace self.parsed_data['namespace'].append( str(_namespace).split('::')[-1].split(' ')[0]) except RuntimeError: raise BlockToolException( 'Invalid namespace format in the block header file') # class try: self.parsed_data['class'] = '' for _class in main_namespace.declarations: if isinstance(_class, declarations.class_t): main_class = _class self.parsed_data['class'] = str(_class).split('::')[ 2].split(' ')[0] except RuntimeError: raise BlockToolException( 'Block header namespace {} must consist of a valid class instance'.format(module)) # io_signature, message_ports self.parsed_data['io_signature'] = {} self.parsed_data['message_port'] = {} if os.path.isfile(self.impl_file) and exist_comments(self): self.parsed_data['io_signature'] = io_signature( self.impl_file) self.parsed_data['message_port'] = message_port( self.impl_file) read_comments(self) elif os.path.isfile(self.impl_file) and not exist_comments(self): self.parsed_data['io_signature'] = io_signature( self.impl_file) self.parsed_data['message_port'] = message_port( self.impl_file) if self.addcomments: add_comments(self) elif not os.path.isfile(self.impl_file) and exist_comments(self): read_comments(self) else: self.parsed_data['io_signature'] = { "input": [], "output": [] } self.parsed_data['message_port'] = self.parsed_data['io_signature'] # make try: self.parsed_data['make'] = {} self.parsed_data['make']['arguments'] = [] query_m = declarations.custom_matcher_t( lambda mem_fun: mem_fun.name.startswith('make')) query_make = query_m & declarations.access_type_matcher_t('public') make_func = main_class.member_functions(function=query_make, allow_empty=True, header_file=self.target_file) criteria = declarations.calldef_matcher(name='make') _make_fun = declarations.matcher.get_single(criteria, main_class) _make_fun = str(_make_fun).split( 'make')[-1].split(')')[0].split('(')[1].lstrip().rstrip().split(',') if make_func: for arg in make_func[0].arguments: for _arg in _make_fun: if str(arg.name) in _arg: make_arguments = { "name": str(arg.name), "dtype": str(arg.decl_type), "default": "" } if re.findall(r'[-+]?\d*\.\d+|\d+', _arg): make_arguments['default'] = re.findall( r'[-+]?\d*\.\d+|\d+', _arg)[0] elif re.findall(r'\"(.+?)\"', _arg): make_arguments['default'] = re.findall( r'\"(.+?)\"', _arg)[0] elif "true" in _arg: make_arguments['default'] = "True" elif "false" in _arg: make_arguments['default'] = "False" self.parsed_data['make']['arguments'].append( make_arguments.copy()) except RuntimeError: self.parsed_data['make'] = {} self.parsed_data['make']['arguments'] = [] # setters try: self.parsed_data['methods'] = [] query_methods = declarations.access_type_matcher_t('public') setters = main_class.member_functions(function=query_methods, allow_empty=True, header_file=self.target_file) getter_arguments = [] if setters: for setter in setters: if str(setter.name).startswith('set_') and setter.arguments: setter_args = { "name": str(setter.name), "arguments_type": [] } for argument in setter.arguments: args = { "name": str(argument.name), "dtype": str(argument.decl_type) } getter_arguments.append(args['name']) setter_args['arguments_type'].append(args.copy()) self.parsed_data['methods'].append(setter_args.copy()) except RuntimeError: self.parsed_data['methods'] = [] # getters try: self.parsed_data['properties'] = [] query_properties = declarations.access_type_matcher_t('public') getters = main_class.member_functions(function=query_properties, allow_empty=True, header_file=self.target_file) if getters: for getter in getters: if not getter.arguments or getter.has_const: getter_args = { "name": str(getter.name), "dtype": str(getter.return_type), "read_only": True } if getter_args['name'] in getter_arguments: getter_args["read_only"] = False self.parsed_data['properties'].append( getter_args.copy()) except RuntimeError: self.parsed_data['properties'] = [] # documentation try: _index = None header_file = codecs.open(self.target_file, 'r', 'cp932') self.parsed_data['docstring'] = re.compile( r'//.*?$|/\*.*?\*/', re.DOTALL | re.MULTILINE).findall( header_file.read())[2:] header_file.close() for doc in self.parsed_data['docstring']: if Constants.BLOCKTOOL in doc: _index = self.parsed_data['docstring'].index(doc) if _index is not None: self.parsed_data['docstring'] = self.parsed_data['docstring'][: _index] except: self.parsed_data['docstring'] = [] return self.parsed_data
def main(): defines = [] includes = [] cxxflags = [ '-Wno-unknown-attributes', '-Wno-unused-value', '-Wno-macro-redefined', ] compiler = 'g++' args = sys.argv[1:] while args and args[0].startswith('-'): arg = args.pop(0) if arg.startswith('-I'): include = arg[2:] includes.append(include) elif arg.startswith('-D'): define = arg[2:] defines.append(define) else: sys.stderr.write('error: unknown option %r\n' % arg) sys.exit(1) winsdk = True if winsdk: # Set up Clang compiler flags to use MinGW runtime # http://stackoverflow.com/a/19839946 p = subprocess.Popen([ "x86_64-w64-mingw32-g++", "-x", "c++", "-E", "-Wp,-v", '-', '-fsyntax-only' ], stdin=open(os.devnull, 'rt'), stdout=open(os.devnull, 'wt'), stderr=subprocess.PIPE) includes.append('/usr/share/castxml/clang/include') for line in p.stderr: if line.startswith(' '): include = line.strip() if os.path.isdir(include): if os.path.exists(os.path.join(include, 'ia32intrin.h')): # XXX: We must use Clang's intrinsic headers continue includes.append(os.path.normpath(include)) winver = 0x0602 defines += [ # emulate MinGW '__MINGW32__', '_WIN32', '_WIN64', '__declspec(x)=', # Avoid namespace pollution when including windows.h # http://support.microsoft.com/kb/166474 'WIN32_LEAN_AND_MEAN', # Set Windows version to 8.1 '_WIN32_WINNT=0x%04X' % winver, 'WINVER=0x%04X' % winver, 'NTDDI_VERSION=0x%04X0000' % winver, # Prevent headers from requiring a rpcndr.h version beyond MinGW's '__REQUIRED_RPCNDR_H_VERSION__=475', # Avoid C++ helper classes 'D3D10_NO_HELPERS', 'D3D11_NO_HELPERS', 'D3D11_VIDEO_NO_HELPERS', ] # XXX: Change compiler? #compiler = 'cl' # XXX: This doesn't seem to work well cxxflags += [ #'-m32', #'-target', 'x86_64-pc-mingw32', ] sys.stderr.write('Include path:\n') for include in includes: sys.stderr.write(' %s\n' % include) sys.stderr.write('Definitions:\n') for define in defines: sys.stderr.write(' %s\n' % define) import logging utils.loggers.set_level(logging.DEBUG) # Find the location of the xml generator (castxml or gccxml) generator_path, generator_name = utils.find_xml_generator("castxml") # Configure the xml generator config = parser.xml_generator_configuration_t( xml_generator_path=generator_path, xml_generator=generator_name, define_symbols=defines, include_paths=includes, cflags=' '.join(cxxflags), compiler=compiler, #keep_xml = True, ) script_dir = os.path.dirname(__file__) headers = [ os.path.join(script_dir, '..', '..', 'compat', 'winsdk_compat.h'), os.path.join(script_dir, 'cxx2api.h'), ] main_header = args[0] headers.append(main_header) decls = parser.parse(headers, config, parser.COMPILATION_MODE.ALL_AT_ONCE) global_ns = declarations.get_global_namespace(decls) def decl_filter(decl): location = decl.location if location is None: return False return os.path.basename(location.file_name) in map( os.path.basename, args) module, _ = os.path.splitext(main_header) visitor = decl2_dumper_t(module) visitor.start() for decl in global_ns.declarations: if not decl_filter(decl): continue if sys.stdout.isatty(): print('# ' + str(decl)) visitor.decl = decl algorithm.apply_visitor(visitor, decl) visitor.finish()
from pygccxml import parser # nopep8 from pygccxml import declarations # nopep8 from pygccxml import utils # nopep8 # Find out the xml generator (gccxml or castxml) generator_path, generator_name = utils.find_xml_generator() # Configure the xml generator config = parser.xml_generator_configuration_t( xml_generator_path=generator_path, xml_generator=generator_name, compiler="gcc") # Parsing source file decls = parser.parse([this_module_dir_path + '/example.hpp'], config) global_ns = declarations.get_global_namespace(decls) # Get object that describes unittests namespace unittests = global_ns.namespace('unittests') print('"unittests" declarations: \n') declarations.print_declarations(unittests) # Print all base and derived class names for class_ in unittests.classes(): print('class "%s" hierarchy information:' % class_.name) print('\tbase classes : ', repr([ base.related_class.name for base in class_.bases])) print('\tderived classes: ', repr([ derive.related_class.name for derive in class_.derived]))
def parseHeaders(hFiles, config=None): global parHFiles par = [] par = parser.parse(hFiles, config) parHFiles.extend(par) return par
def setUp(self): if not tester_t.global_ns: decls = parser.parse([self.header], self.config) tester_t.global_ns = declarations.get_global_namespace(decls) tester_t.global_ns.init_optimizer() self.global_ns = tester_t.global_ns
def parse_file(filename, project_source_directory, include_directories, declaration_names, stream): """ Entry point for parsing a file """ # Find out the xml generator (gccxml or castxml) generator_path, generator_name = utils.find_xml_generator() # Configure the xml generator config = parser.xml_generator_configuration_t( start_with_declarations=declaration_names.split(" "), include_paths=include_directories.split(" "), xml_generator_path=generator_path, xml_generator=generator_name, cflags='-std=c++11 -Wc++11-extensions') # Parse source file decls = parser.parse([os.path.abspath(filename)], config, compilation_mode=parser.COMPILATION_MODE.ALL_AT_ONCE) # grab global namespace try: global_ns = declarations.get_global_namespace(decls) except RuntimeError: return [] # output file preamble fileguard = "pybind_" + \ filename.replace('.', '_').replace('/', '_').replace('-', '_') stream( """//========================================================================= // Copyright (c) Kitware, Inc. // All rights reserved. // See LICENSE.txt for details. // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notice for more information. //========================================================================= """) stream("#ifndef %s" % fileguard) stream("#define %s" % fileguard) stream("") stream("#include <pybind11/pybind11.h>") stream("") stream("#include \"%s\"" % os.path.relpath( os.path.abspath(filename), os.path.commonprefix([ os.path.abspath(project_source_directory), os.path.abspath(filename) ]))) stream("") includes = get_includes(global_ns, filename, project_source_directory) for include in includes: stream("#include \"%s\"" % include) if includes: stream("") stream("namespace py = pybind11;") stream("") wrapped_objects = {} for enum_ in global_ns.enumerations(allow_empty=True): if enum_.location.file_name != os.path.abspath(filename): continue if enum_.parent and type(enum_.parent).__name__.find('class_t') != -1: continue wrapped_objects[enum_] = parse_free_enumeration(enum_, stream) stream("") for class_ in global_ns.classes(allow_empty=True): if class_.location.file_name != os.path.abspath(filename) or\ class_ in parsed_classes: continue if class_.parent and type( class_.parent).__name__.find('class_t') != -1: continue wrapped_objects[class_] = parse_class(class_, stream) stream("") all_functions = set() overloaded_functions = set() for fn_ in global_ns.free_functions(allow_empty=True): if fn_.location.file_name != os.path.abspath(filename): continue if fn_.name in all_functions: overloaded_functions.add(fn_.name) else: all_functions.add(fn_.name) for fn_ in global_ns.free_functions(allow_empty=True): if fn_.location.file_name != os.path.abspath(filename): continue wrapped_objects[fn_] = parse_free_function( fn_, fn_.name in overloaded_functions, stream) stream("") stream("#endif") parsed_classes.clear() return wrapped_objects
return prio elif len(files) > 1: print(files) print('Error while finding {:}, found no match'.format( header_file)) else: return prio print('Error proccessing header {:}'.format(header)) # main loop config = parser.config_t(include_paths=include_paths, ignore_gccxml_output=True) decls = parser.parse(all_headers, config, compilation_mode=COMPILATION_MODE.ALL_AT_ONCE) global_ns = declarations.get_global_namespace(decls) # classes in siconos_namespace class_names = dict() # class name of classes with a least a base (for the boost archive # registration) with_base = [] # a typedef table to replace templated class by their typedefs in # macros call typedef = dict() for t in global_ns.typedefs(): typedef[str(t._type)] = name(t)
def setUp(self): if not self.declarations: self.declarations = parser.parse([self.header], self.config) self.global_ns = declarations.find_declaration( self.declarations, type=declarations.namespace_t, name='::') self.global_ns.init_optimizer()
from pygccxml import utils from pygccxml import declarations from pygccxml import parser import pygccxml import sys # Find the location of the xml generator (castxml or gccxml) generator_path, generator_name = utils.find_xml_generator() # Configure the xml generator xml_generator_config = parser.xml_generator_configuration_t( xml_generator_path=generator_path, xml_generator=generator_name) # Parse the c++ file decls = parser.parse([sys.argv[1]], xml_generator_config) declarations.print_declarations(decls)
# Configure the xml generator config = parser.xml_generator_configuration_t( xml_generator_path=generator_path, xml_generator=generator_name, cflags=" ".join(flags), # start_with_declarations="test", #compiler="gcc", ) # Parsing source file filenames = list(filter(lambda x: not x.startswith("-"), sys.argv[1:])) full_filenames = [os.path.abspath(filename) for filename in filenames] decls = parser.parse(full_filenames, config, compilation_mode=parser.COMPILATION_MODE.ALL_AT_ONCE) global_ns = declarations.get_global_namespace(decls) write_hdrs = True if write_hdrs: for filename in filenames: print('#include "%s"' % filename) def get_prefix(member, duplicates): p = [] try: if member.name in duplicates: p.append("overload")
from pygccxml import utils from pygccxml import declarations from pygccxml import parser import os import sys # Find the location of the xml generator (castxml or gccxml) generator_path= "C:\\castxml\\bin\\castxml.exe" generator_name = "castxml" names = [] path = "" a,b,c,d,e,f,g,h,i,j = split_list(heads,10) lists = [a,b,c,d,e,f,g,h,i,j] for list in lists: parser.parse(list,xml_generator_config) # Configure the xml generator xml_generator_config = parser.xml_generator_configuration_t( xml_generator_path=generator_path, xml_generator=generator_name, compiler='cl.exe', compiler_path='C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\bin\\cl.exe', include_paths=godot_headers,keep_xml=True,cflags= ''.join(env['CCFLAGS'])) print(sys.platform) if sys.platform == "win32": path = 'C:\\godot-haxe\\godot-cpp\\include\\' arr = os.listdir(path) parser.parse() for p in arr: temp = os.listdir(path+p+"\\") for name in temp: names.append(path+p+"\\"+name) print(names)
def setUp(self): if not tester_t.declarations: tester_t.declarations = parser.parse([self.header], self.config) self.declarations = tester_t.declarations
def setUp(self): if not Test.global_ns: decls = parser.parse([self.header], self.config) Test.global_ns = declarations.get_global_namespace(decls) self.global_ns = Test.global_ns
def get_header_info(self): """ PyGCCXML header code parser magic happens here! : returns the parsed header data in python dict : return dict keys: namespace, class, io_signature, make, properties, methods : Can be used as an CLI command or an external API """ gr = self.modname.split('-')[0] module = self.modname.split('-')[-1] self.parsed_data['module_name'] = module generator_path, generator_name = utils.find_xml_generator() xml_generator_config = parser.xml_generator_configuration_t( xml_generator_path=generator_path, xml_generator=generator_name, include_paths=self.include_paths, compiler='gcc', define_symbols=['BOOST_ATOMIC_DETAIL_EXTRA_BACKEND_GENERIC'], cflags='-std=c++11') decls = parser.parse([self.target_file], xml_generator_config) global_namespace = declarations.get_global_namespace(decls) # namespace try: self.parsed_data['namespace'] = [] ns = global_namespace.namespace(gr) if ns is None: raise BlockToolException main_namespace = ns.namespace(module) if main_namespace is None: raise BlockToolException('namespace cannot be none') self.parsed_data['namespace'] = [gr, module] if main_namespace.declarations: for _namespace in main_namespace.declarations: if isinstance(_namespace, declarations.namespace_t): if Constants.KERNEL not in str(_namespace): main_namespace = _namespace self.parsed_data['namespace'].append( str(_namespace).split('::')[-1].split(' ')[0]) except RuntimeError: raise BlockToolException( 'Invalid namespace format in the block header file') # class try: self.parsed_data['class'] = '' for _class in main_namespace.declarations: if isinstance(_class, declarations.class_t): expected_class_name = self.filename.split('.')[0] if expected_class_name in str(_class): main_class = _class self.parsed_data['class'] = str(_class).split( '::')[2].split(' ')[0] # in more complicated blocks, there are many classes included in this declaration # Break after the first class - safe to assume this is the "main class"? if len(main_class.bases) > 0: self.parsed_data['block_type'] = main_class.bases[ 0].declaration_path[-1] break except RuntimeError: raise BlockToolException( 'Block header namespace {} must consist of a valid class instance' .format(module)) # io_signature, message_ports self.parsed_data['io_signature'] = {} self.parsed_data['message_port'] = {} if os.path.isfile(self.impl_file) and exist_comments(self): self.parsed_data['io_signature'] = io_signature(self.impl_file) self.parsed_data['message_port'] = message_port(self.impl_file) read_comments(self) elif os.path.isfile(self.impl_file) and not exist_comments(self): self.parsed_data['io_signature'] = io_signature(self.impl_file) self.parsed_data['message_port'] = message_port(self.impl_file) if self.addcomments: add_comments(self) elif not os.path.isfile(self.impl_file) and exist_comments(self): read_comments(self) else: self.parsed_data['io_signature'] = {"input": [], "output": []} self.parsed_data['message_port'] = self.parsed_data['io_signature'] # make try: self.parsed_data['make'] = {} self.parsed_data['make']['arguments'] = [] query_m = declarations.custom_matcher_t( lambda mem_fun: mem_fun.name.startswith('make')) query_make = query_m & declarations.access_type_matcher_t('public') make_func = main_class.member_functions( function=query_make, allow_empty=True, header_file=self.target_file) criteria = declarations.calldef_matcher(name='make') _make_fun = declarations.matcher.get_single(criteria, main_class) _make_fun = str(_make_fun).split('make')[-1].split(')')[0].split( '(')[1].lstrip().rstrip().split(',') if make_func: for arg in make_func[0].arguments: make_arguments = None ''' for _arg in _make_fun: if str(arg.name) in _arg: make_arguments = { "name": str(arg.name), "dtype": str(arg.decl_type), "default": "" } if re.findall(r'[-+]?\d*\.\d+|\d+', _arg): make_arguments['default'] = re.findall( r'[-+]?\d*\.\d+|\d+', _arg)[0] elif re.findall(r'\"(.+?)\"', _arg): make_arguments['default'] = re.findall( r'\"(.+?)\"', _arg)[0] elif "true" in _arg: make_arguments['default'] = "True" elif "false" in _arg: make_arguments['default'] = "False" ''' # In case the search did not find an argument in the inner loop # This happens while parsing digital/symbol_sync_cc.h if make_arguments: self.parsed_data['make']['arguments'].append( make_arguments.copy()) else: self.parsed_data['make']['arguments'].append({ "name": str(arg.name), "dtype": str(arg.decl_type), "default": arg. default_value # can we get default argument directly from arg }) except RuntimeError: self.parsed_data['make'] = {} self.parsed_data['make']['arguments'] = [] # setters try: self.parsed_data['methods'] = [] query_methods = declarations.access_type_matcher_t('public') setters = main_class.member_functions(function=query_methods, allow_empty=True, header_file=self.target_file) getter_arguments = [] if setters: for setter in setters: if str(setter.name).startswith( 'set_') and setter.arguments: setter_args = { "name": str(setter.name), "arguments_type": [] } for argument in setter.arguments: args = { "name": str(argument.name), "dtype": str(argument.decl_type) } getter_arguments.append(args['name']) setter_args['arguments_type'].append(args.copy()) self.parsed_data['methods'].append(setter_args.copy()) except RuntimeError: self.parsed_data['methods'] = [] # getters try: self.parsed_data['properties'] = [] query_properties = declarations.access_type_matcher_t('public') getters = main_class.member_functions(function=query_properties, allow_empty=True, header_file=self.target_file) if getters: for getter in getters: if not getter.arguments or getter.has_const: getter_args = { "name": str(getter.name), "dtype": str(getter.return_type), "read_only": True } if getter_args['name'] in getter_arguments: getter_args["read_only"] = False self.parsed_data['properties'].append( getter_args.copy()) except RuntimeError: self.parsed_data['properties'] = [] # all member functions # setters and getters do not return all member functions for a block try: self.parsed_data['member_functions'] = [] query_methods = declarations.access_type_matcher_t('public') functions = main_class.member_functions( function=query_methods, allow_empty=True, header_file=self.target_file) if functions: for fcn in functions: if str(fcn.name) not in [ main_class.name, '~' + main_class.name, 'make' ]: fcn_args = {"name": str(fcn.name), "arguments": []} for argument in fcn.arguments: args = { "name": str(argument.name), "dtype": str(argument.decl_type), "default": argument.default_value } fcn_args['arguments'].append(args.copy()) self.parsed_data['member_functions'].append( fcn_args.copy()) except RuntimeError: self.parsed_data['member_functions'] = [] # documentation try: _index = None header_file = codecs.open(self.target_file, 'r', 'cp932') self.parsed_data['docstring'] = re.compile( r'//.*?$|/\*.*?\*/', re.DOTALL | re.MULTILINE).findall(header_file.read())[2:] header_file.close() for doc in self.parsed_data['docstring']: if Constants.BLOCKTOOL in doc: _index = self.parsed_data['docstring'].index(doc) if _index is not None: self.parsed_data['docstring'] = self.parsed_data[ 'docstring'][:_index] except: self.parsed_data['docstring'] = [] return self.parsed_data
def setUp(self): if not self.declarations: self.declarations = parser.parse( [self.header], self.config )
def setUp(self): if not self.global_ns: self.global_ns = declarations.get_global_namespace( parser.parse( [self.header], self.config ) )
def test_same_declarations_different_intances(self): parsed = parser.parse([self.header], self.config) copied = copy.deepcopy(parsed) self.assertTrue(parsed == copied, "__lt__ and/or __qe__ does not working properly")
def get_header_info(self, namespace_to_parse): """ PyGCCXML header code parser magic happens here! : returns the parsed header data in python dict : return dict keys: namespace, class, io_signature, make, properties, methods : Can be used as an CLI command or an external API """ module = self.modname.split('-')[-1] self.parsed_data['module_name'] = module self.parsed_data['filename'] = self.filename import hashlib hasher = hashlib.md5() with open(self.target_file, 'rb') as file_in: buf = file_in.read() hasher.update(buf) self.parsed_data['md5hash'] = hasher.hexdigest() # Right now if pygccxml is not installed, it will only handle the make function # TODO: extend this to other publicly declared functions in the h file if not PYGCCXML_AVAILABLE: self.parsed_data['parser'] = 'simple' (params, iosig, blockname) = self._parse_cc_h(self.target_file) self.parsed_data['target_namespace'] = namespace_to_parse namespace_dict = {} namespace_dict['name'] = "::".join(namespace_to_parse) class_dict = {} class_dict['name'] = blockname mf_dict = { "name": "make", "return_type": "::".join(namespace_to_parse + [blockname, "sptr"]), "has_static": "1" } args = [] for p in params: arg_dict = { "name": p['key'], "dtype": p['type'], "default": p['default'] } args.append(arg_dict) mf_dict["arguments"] = args class_dict["member_functions"] = [mf_dict] namespace_dict["classes"] = [class_dict] self.parsed_data["namespace"] = namespace_dict return self.parsed_data else: self.parsed_data['parser'] = 'pygccxml' generator_path, generator_name = utils.find_xml_generator() xml_generator_config = parser.xml_generator_configuration_t( xml_generator_path=generator_path, xml_generator=generator_name, include_paths=self.include_paths, compiler='gcc', undefine_symbols=['__PIE__'], define_symbols=self.define_symbols, cflags='-std=c++17 -fPIC') decls = parser.parse([self.target_file], xml_generator_config) global_namespace = declarations.get_global_namespace(decls) # namespace # try: main_namespace = global_namespace for ns in namespace_to_parse: main_namespace = main_namespace.namespace(ns) if main_namespace is None: raise BlockToolException('namespace cannot be none') self.parsed_data['target_namespace'] = namespace_to_parse self.parsed_data['namespace'] = self.parse_namespace( main_namespace) # except RuntimeError: # raise BlockToolException( # 'Invalid namespace format in the block header file') # namespace return self.parsed_data
pathLen = len(this_module_dir_path) #find out gccxml location #gccxml_09_path = os.path.join( this_module_dir_path, '..', '..', '..', 'gccxml_bin', 'v09', sys.platform, 'bin' ) gccxml_09_path = os.path.join('gccxml') #add pygccxml package to Python path #sys.path.append( os.path.join( this_module_dir_path, '..', '..' ) ) print this_module_dir_path from pygccxml import parser from pygccxml import declarations #configure GCC-XML parser config = parser.config_t(gccxml_path=gccxml_09_path, compiler='gcc') #parsing source file decls = parser.parse(['HaskellBulletAPI.h'], config) global_ns = declarations.get_global_namespace(decls) #from bulletCfg import * #{#fun [pure] [unsafe] cid [as (hsid | ^)] [ctxt =>] { parm1 , ... , parmn } -> parm #{#class [hsid1 =>] hsid2 hsid3#} # class example #{#pointer *GtkWidget newtype#} #{#class GtkObjectClass => GtkWidgetClass GtkWidget#} # Overview: # from c++ headers collect methods and synthetize following things # - c binding code # - hsc binding code
def setUp(self): if not self.global_ns: decls = parser.parse(self.headers, self.config) self.global_ns = declarations.get_global_namespace(decls) self.global_ns.init_optimizer()
def generate_xml(env): heads = [] flags = '' add_sources(heads, 'include/core', 'hpp') add_sources(heads, 'include/gen', 'hpp') gen_path = '/usr/bin/castxml' if sys.platform == 'win32': gen_path = "C:\\castxml\\bin\\castxml.exe" generator_path = gen_path generator_name = "castxml" for st in env['CCFLAGS']: flags += ' ' + st # Configure the xml generator xml_generator_config = parser.xml_generator_configuration_t( xml_generator_path=generator_path, xml_generator=generator_name, compiler=env['CXX'], compiler_path=env['CC'], include_paths=env['CPPPATH'], keep_xml=True, flags=flags, castxml_epic_version=1) # To test just do [heads[index]] # Parse the cpp files and output docs for t in heads: decls = parser.parse([t], xml_generator_config) global_ns = declarations.get_global_namespace(decls) ns = global_ns.namespace('godot') classes = to_dict(ns.classes(allow_empty=True), t) print(classes.values()) for clAss in classes.values(): print(clAss.name) # Parse classes if clAss.name != "" and clAss.class_type == 'class' or ( not clAss.name.startswith('_') and clAss.class_type == 'struct') or clAss.class_type == 'union': print(clAss.class_type) root = ET.Element('class', name=clAss.name, path=t) methods = ET.SubElement(root, 'methods') members = ET.SubElement(root, 'members') constants = ET.SubElement(root, 'constants') if len(clAss.bases) != 0: root.set('inherits', clAss.bases[0].related_class.name) # Parse functions for member in clAss.member_functions(allow_empty=True): if member.access_type == 'public' and member.name != "": method = ET.SubElement(methods, 'method', name=member.name) typ = str(member.return_type).replace( '::', '').replace('godot', '').replace('const', '') returnType = ET.SubElement(method, 'return', type=typ) indx = 0 for args in member.arguments: if str(args.decl_type) in member.decl_string: typeText = str(args.decl_type).replace( '::', '').replace('godot', '').replace('const', '') argument = ET.SubElement(method, 'argument', index=str(indx), name=args.name, type=typeText) # indx += 1 if member.has_const: method.set('qualifiers', "const") # Parse constructors for member in clAss.constructors(allow_empty=True): if member.access_type == 'public' and member.name != "": method = ET.SubElement(methods, 'method', name=member.name) typ = str(member.return_type).replace( '::', '').replace('godot', '').replace('const', '') if typ != 'None': returnType = ET.SubElement(method, 'return', type=typ) indx = 0 for args in member.arguments: if str(args.decl_type) in member.decl_string: typeText = str(args.decl_type).replace( '::', '').replace('godot', '').replace('const', '') argument = ET.SubElement(method, 'argument', index=str(indx), name=args.name, type=typeText) # indx += 1 if member.has_const: method.set('qualifiers', "const") # Parse variables for var in clAss.variables(allow_empty=True): if var.name == "": continue if var.access_type == 'public': typeText = str(var.decl_type).replace('::', '').replace( 'godot', '') if '[' in typeText: typeText = 'Array<' + typeText.partition('[')[0] + '>' variable = ET.SubElement(members, 'member', name=var.name, type=typeText) # Parse enumerations for enum in clAss.enumerations(allow_empty=True): for val in enum.values: constant = ET.SubElement(constants, 'constant', name=val[0], value=str(val[1]), enum=enum.name) indent(root) ET.ElementTree(root).write('../libraries/' + 'Godot/' + clAss.name + '.xml')
def __init__(self, *args): parser_test_case.parser_test_case_t.__init__(self, *args) self.header = "find_noncopyable_vars.hpp" decls = parser.parse([self.header], self.config) self.global_ns = declarations.get_global_namespace(decls)
#find out the file location within the sources tree this_module_dir_path = os.path.abspath ( os.path.dirname( sys.modules[__name__].__file__) ) #find out gccxml location gccxml_09_path = os.path.join( this_module_dir_path, '..', '..', '..', 'gccxml_bin', 'v09', sys.platform, 'bin' ) #add pygccxml package to Python path sys.path.append( os.path.join( this_module_dir_path, '..', '..' ) ) from pygccxml import parser from pygccxml import declarations #configure GCC-XML parser config = parser.config_t( gccxml_path=gccxml_09_path ) #parsing source file decls = parser.parse( ['example.hpp'], config ) global_ns = declarations.get_global_namespace( decls ) #get object that describes unittests namespace unittests = global_ns.namespace( 'unittests' ) print '"unittests" declarations: ' declarations.print_declarations( unittests ) #print all base and derived class names for class_ in unittests.classes(): print 'class "%s" hierarchy information:' % class_.name print '\tbase classes : ', `[base.related_class.name for base in class_.bases]` print '\tderived classes: ', `[derive.related_class.name for derive in class_.derived]` print '\n'
def parse_file(filename): # Find the location of the xml generator (castxml or gccxml) generator_path, generator_name = utils.find_xml_generator(name='castxml') # Configure the xml generator xml_generator_config = parser.xml_generator_configuration_t( # cflags="-std=gnu++11", cflags="-Wno-c++11-extensions", include_paths=["/Users/markoates/Repos/allegro_flare/include"], xml_generator_path=generator_path, compiler="g++", xml_generator=generator_name) # Parse the c++ file decls = parser.parse([filename], xml_generator_config) # output some GOLD! global_namespace = declarations.get_global_namespace(decls) # Search for functions which return a double. Two functions will be found criteria = declarations.calldef_matcher( #return_type="float", #header_file="/Users/markoates/Repos/allegro_flare/include/allegro_flare/" + filename) header_file=os.path.abspath(filename)) # criteria = declarations.calldef_matcher(return_type=double_type) found_items = declarations.matcher.find(criteria, global_namespace) # populate the table with unique names count = 0 for item in found_items: count = count + 1 #print item.location.file_name + " : " + str(item.location.line) cleaned_filename = re.match( r'/Users/markoates/Repos/allegro_flare/(.*)', item.location.file_name).group(1) # create `declaration_type` declaration_type = item.__class__.__name__ if declaration_type[-2:] == "_t": declaration_type = declaration_type[:-2] declaration_type = declaration_type.replace('_', ' ') declaration_type = "%s" % declaration_type # create `declaration` declaration = str(item) declaration = re.match(r'(.*) \[.*\]$', declaration).group(1) parse_cache_make_table_connection.execute( "INSERT INTO parsed_declarations VALUES (NULL,?,?,?,?,?,?,?,?,?,?,?,?);", (str(item), item.decl_string, declaration, item.name, declaration_type, str(item.parent.name), str( item.top_parent.name), item.attributes, cleaned_filename, str(item.location.line), "", "")) parse_cache_connection.commit() # create a list of unique items unique_item_names = set() for item in found_items: unique_item_names.update({item.name}) # cross-correlate declarations in the database docs_connection = sqlite3.connect('doc_entries.db') docs_connection.row_factory = sqlite3.Row docs_c = docs_connection.cursor() found_items = 0 unfound_items = 0 for item in unique_item_names: docs_c.execute('SELECT * FROM entries WHERE decl=?', (item, )) entries = docs_c.fetchall() if len(entries) == 0: print item unfound_items += 1 else: print_green(item + " - FOUND") found_items += 1 if unfound_items == 0: print_func = print_green elif found_items == 0: print_func = print_red else: print_func = print_yellow print_func("==============================") print_func(str(found_items) + " items found.") print_func(str(unfound_items) + " matches missing.") print_func("==============================") return