Beispiel #1
0
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)
Beispiel #4
0
    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)
Beispiel #5
0
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."))
Beispiel #7
0
 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
Beispiel #8
0
    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)
Beispiel #10
0
 def setUp(self):
     if not self.declarations:
         self.declarations = parser.parse(
             ['typedefs1.hpp',
              'typedefs2.hpp'],
             self.config,
             self.COMPILATION_MODE)
Beispiel #11
0
    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__")
Beispiel #12
0
    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)
Beispiel #13
0
 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
Beispiel #16
0
 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
Beispiel #17
0
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)
Beispiel #18
0
 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
Beispiel #19
0
    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")
Beispiel #21
0
 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"),
     )
Beispiel #22
0
    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
Beispiel #23
0
    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)
Beispiel #25
0
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)
Beispiel #26
0
    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))
Beispiel #28
0
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))
Beispiel #30
0
    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)
Beispiel #31
0
 def setUp(self):
     if not Test.declarations:
         Test.declarations = parser.parse([self.header], self.config)
     self.declarations = Test.declarations
Beispiel #32
0
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)
Beispiel #34
0
    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
Beispiel #37
0
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()
Beispiel #38
0
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
Beispiel #41
0
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
Beispiel #42
0
                                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)
Beispiel #43
0
 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()
Beispiel #44
0
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)
Beispiel #45
0
# 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")
Beispiel #46
0
 def setUp(self):
     if not self.declarations:
         self.declarations = parser.parse(
             ['typedefs1.hpp', 'typedefs2.hpp'], self.config,
             self.COMPILATION_MODE)
Beispiel #47
0
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
Beispiel #49
0
 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
Beispiel #50
0
    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")
Beispiel #54
0
    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
Beispiel #55
0
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
Beispiel #56
0
 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()
Beispiel #57
0
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)
Beispiel #59
0
#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'
Beispiel #60
0
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