def profile_project():
    include_std_header = os.path.join(autoconfig.data_directory,
                                      'include_std.hpp')
    reader = parser.project_reader_t(
        parser.xml_generator_configuration_t(
            xml_generator_path=autoconfig.generator_path))
    reader.read_files([include_std_header])
Exemplo n.º 2
0
    def parse(self):

        xml_generator_config = parser.xml_generator_configuration_t(xml_generator_path=self.castxml_binary, 
                                                                    xml_generator="castxml",
                                                                    cflags="-std=c++11",
                                                                    include_paths=self.source_includes)

        print ("INFO: Parsing Code")
        decls = parser.parse([self.wrapper_header_collection], xml_generator_config,
                             compilation_mode=parser.COMPILATION_MODE.ALL_AT_ONCE)

        # Get access to the global namespace
        self.global_ns = declarations.get_global_namespace(decls)

        # Clean decls to only include those for which file locations exist
        print ("INFO: Cleaning Decls")
        query = declarations.custom_matcher_t(lambda decl: decl.location is not None)
        decls_loc_not_none = self.global_ns.decls(function=query)

        # Identify decls in our source tree
        def check_loc(loc):
            return (self.source_root in loc) or ("wrapper_header_collection" in loc)
        
        source_decls = [decl for decl in decls_loc_not_none if check_loc(decl.location.file_name)]
        self.source_ns = declarations.namespace_t("source", source_decls)

        print ("INFO: Optimizing Decls")
        self.source_ns.init_optimizer()
Exemplo n.º 3
0
    def _setEnvironment(self):


        # gccxml_09_path = os.path.join('/', 'usr', 'bin', 'castxml') ---> CASTXML will be used for C++11 syntax.
        # gccxml_09_path = os.path.join('/', 'usr', 'bin', 'gccxml')
        generator_path = os.path.join('/', 'usr', 'bin', 'castxml')
        generator_name = 'castxml'
        # generator_path, generator_name = pygccxml.utils.find_xml_generator()


        # 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 = pygccxml.parser.parse([os.path.join(self._file_directory, self._file_name)], xml_generator_config)
def profile_project2():
    he = r"2003\Vc7\PlatformSDK\Include\windows.h"
    include_std_header = r"D:\Program Files\Microsoft Visual Studio .NET " + he
    reader = parser.project_reader_t(
        parser.xml_generator_configuration_t(
            xml_generator_path=autoconfig.generator_path))
    reader.read_files([include_std_header])
Exemplo n.º 5
0
    def __parse_declarations(self, files, xml_generator_config,
                             compilation_mode, cache, indexing_suite_version):
        if None is xml_generator_config:
            xml_generator_config = parser.xml_generator_configuration_t()
        if None is compilation_mode:
            compilation_mode = parser.COMPILATION_MODE.FILE_BY_FILE
        start_time = timer()
        self.logger.debug('parsing files - started')
        reader = parser.project_reader_t(xml_generator_config, cache,
                                         decl_wrappers.dwfactory_t())
        decls = reader.read_files(files, compilation_mode)

        self.logger.debug('parsing files - done( %f seconds )' %
                          (timer() - start_time))
        self.logger.debug('settings declarations defaults - started')

        global_ns = decls_package.matcher.get_single(
            decls_package.namespace_matcher_t(name='::'), decls)
        if indexing_suite_version != 1:
            for cls in global_ns.classes(allow_empty=True):
                cls.indexing_suite_version = indexing_suite_version
            for cls in global_ns.decls(
                    decl_type=decls_package.class_declaration_t,
                    allow_empty=True):
                cls.indexing_suite_version = indexing_suite_version

        start_time = timer()
        self.__apply_decls_defaults(decls)
        self.logger.debug(
            'settings declarations defaults - done( %f seconds )' %
            (timer() - start_time))
        return global_ns
Exemplo n.º 6
0
def parse_files(path, files):
    # Find the location of the xml generator (castxml or gccxml)
    #generator_path, generator_name = utils.find_xml_generator()
    #print("GENER " + generator_path)
    # Configure the xml generator

    args = {
        'include_paths':[path],
        'keep_xml': True
        }
    if(xml_generator != None):
        args['xml_generator'] =xml_generator
    if(xml_generator_path != None):
        args['xml_generator_path'] =xml_generator_path

    xml_generator_config = parser.xml_generator_configuration_t(**args)
    
    # not sure this actually does anything when compilation_mode is set to "ALL_AT_ONCE"
    def cache_file(filename):
        return parser.file_configuration_t(
            data=filename,
            content_type=parser.CONTENT_TYPE.CACHED_SOURCE_FILE,
            cached_source_file=filename.replace(path, "tmp/xml")+".xml")
    cached_files = [cache_file(f) for f in files]

    project_reader = parser.project_reader_t(xml_generator_config)
    decls = project_reader.read_files(
        cached_files,
        compilation_mode=parser.COMPILATION_MODE.ALL_AT_ONCE)

    return declarations.get_global_namespace(decls)
Exemplo n.º 7
0
def main(namespace, *headers, outfile=None):
    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,
        cflags='-std=c++14')

    decls = parser.parse(headers, xml_generator_config)
    global_namespace = declarations.get_global_namespace(decls[0])

    ns = global_namespace.namespace(namespace)

    if outfile is None:
        outfile = sys.stdout
    else:
        outfile = open(outfile, 'w')

    def out(s):
        if not s: return
        outfile.write(s)
        outfile.write('\n')

    out("#include <pybind11/pybind11.h>")
    out("#include <pybind11/stl.h>")
    for header in headers:
        out(f'#include "{header}"')
    out("namespace py = pybind11;")
    out(f'PYBIND11_MODULE({namespace}, m){{')
    out("using namespace pybind11::literals;")
    for decl in ns.declarations:
        out(dump_decl(decl))
    out('}')
    def __parse_declarations( self, files, xml_generator_config, compilation_mode, cache, indexing_suite_version ):
        if None is xml_generator_config:
            xml_generator_config = parser.xml_generator_configuration_t()
        if None is compilation_mode:
            compilation_mode = parser.COMPILATION_MODE.FILE_BY_FILE
        start_time = time.clock()
        self.logger.debug( 'parsing files - started' )
        reader = parser.project_reader_t( xml_generator_config, cache, decl_wrappers.dwfactory_t() )
        decls = reader.read_files( files, compilation_mode )

        self.logger.debug( 'parsing files - done( %f seconds )' % ( time.clock() - start_time ) )
        self.logger.debug( 'settings declarations defaults - started' )

        global_ns = decls_package.matcher.get_single(
                decls_package.namespace_matcher_t( name='::' )
                , decls )
        if indexing_suite_version != 1:
            for cls in global_ns.classes():
                cls.indexing_suite_version = indexing_suite_version
            for cls in global_ns.decls(decl_type=decls_package.class_declaration_t):
                cls.indexing_suite_version = indexing_suite_version

        start_time = time.clock()
        self.__apply_decls_defaults(decls)
        self.logger.debug( 'settings declarations defaults - done( %f seconds )'
                           % ( time.clock() - start_time ) )
        return global_ns
Exemplo n.º 9
0
def profile_project2():
    he = r"2003\Vc7\PlatformSDK\Include\windows.h"
    include_std_header = r"D:\Program Files\Microsoft Visual Studio .NET " + he
    reader = parser.project_reader_t(
        parser.xml_generator_configuration_t(
            xml_generator_path=autoconfig.generator_path))
    reader.read_files([include_std_header])
Exemplo n.º 10
0
def parse_big_file():
    path = os.path.join(autoconfig.data_directory, 'big.xml')
    reader = parser.project_reader_t(
        parser.xml_generator_configuration_t(
            xml_generator_path=autoconfig.xml_generator_path))
    reader.read_files([parser.create_gccxml_fc(path)])
    reader.read_files([parser.create_gccxml_fc(path)])
    reader.read_files([parser.create_gccxml_fc(path)])
Exemplo n.º 11
0
def profile_project():
    include_std_header = os.path.join(
        autoconfig.data_directory,
        'include_std.hpp')
    reader = parser.project_reader_t(
        parser.xml_generator_configuration_t(
            xml_generator_path=autoconfig.generator_path))
    reader.read_files([include_std_header])
Exemplo n.º 12
0
def test_on_big_file(file_name, count):
    file_name = os.path.join(autoconfig.data_directory, file_name)
    for i in range(count):
        reader = parser.project_reader_t(
            parser.xml_generator_configuration_t(
                xml_generator_path=autoconfig.generator_path))
        decls = reader.read_files([parser.create_gccxml_fc(file_name)])
        global_ns = declarations.get_global_namespace(decls)
        global_ns.init_optimizer()
Exemplo n.º 13
0
def test_on_big_file(file_name, count):
    file_name = os.path.join(autoconfig.data_directory, file_name)
    for i in range(count):
        reader = parser.project_reader_t(
            parser.xml_generator_configuration_t(
                xml_generator_path=autoconfig.generator_path))
        decls = reader.read_files([parser.create_gccxml_fc(file_name)])
        global_ns = declarations.get_global_namespace(decls)
        global_ns.init_optimizer()
Exemplo n.º 14
0
def test_project_on_include_std_dot_hpp():
    include_std_header = os.path.join(autoconfig.data_directory,
                                      'include_std.hpp')
    clock_prev = time.perf_counter()
    dcache = parser.file_cache_t(dcache_file_name)
    reader = parser.project_reader_t(
        parser.xml_generator_configuration_t(
            xml_generator_path=autoconfig.generator_path), dcache)
    reader.read_files([include_std_header])
    dcache.flush()
    clock_now = time.perf_counter()
    print(('without cache: %f seconds' % (clock_now - clock_prev)))

    clock_prev = time.perf_counter()
    dcache = parser.file_cache_t(dcache_file_name)
    reader = parser.project_reader_t(
        parser.xml_generator_configuration_t(
            xml_generator_path=autoconfig.generator_path), dcache)
    reader.read_files([include_std_header])
    clock_now = time.perf_counter()
    print(('with cache   : %f seconds' % (clock_now - clock_prev)))
Exemplo n.º 15
0
def test_on_windows_dot_h():
    he = r"2003\Vc7\PlatformSDK\Include\windows.h"
    windows_header = r"D:\Program Files\Microsoft Visual Studio .NET " + he
    clock_prev = time.perf_counter()
    dcache = parser.file_cache_t(dcache_file_name)
    reader = parser.source_reader_t(
        parser.xml_generator_configuration_t(
            xml_generator_path=autoconfig.generator_path), dcache)
    reader.read_file(windows_header)
    dcache.flush()
    clock_now = time.perf_counter()
    print(('without cache: %f seconds' % (clock_now - clock_prev)))

    clock_prev = time.perf_counter()
    dcache = parser.file_cache_t(dcache_file_name)
    reader = parser.source_reader_t(
        parser.xml_generator_configuration_t(
            xml_generator_path=autoconfig.generator_path), dcache)
    reader.read_file(windows_header)
    clock_now = time.perf_counter()
    print(('with cache   : %f seconds' % (clock_now - clock_prev)))
Exemplo n.º 16
0
def test_source_on_include_std_dot_hpp():
    include_std_header = os.path.join(autoconfig.data_directory,
                                      'include_std.hpp')
    clock_prev = timeit.default_timer()
    dcache = parser.file_cache_t(dcache_file_name)
    reader = parser.source_reader_t(
        parser.xml_generator_configuration_t(
            xml_generator_path=autoconfig.generator_path), dcache)
    reader.read_file(include_std_header)
    dcache.flush()
    clock_now = timeit.default_timer()
    print('without cache: %f seconds' % (clock_now - clock_prev))

    clock_prev = timeit.default_timer()
    dcache = parser.file_cache_t(dcache_file_name)
    reader = parser.source_reader_t(
        parser.xml_generator_configuration_t(
            xml_generator_path=autoconfig.generator_path), dcache)
    reader.read_file(include_std_header)
    clock_now = timeit.default_timer()
    print('with cache   : %f seconds' % (clock_now - clock_prev))
Exemplo n.º 17
0
    def __parse_declarations( self, files, xml_generator_config, compilation_mode=None, cache=None ):
        if None is xml_generator_config:
            xml_generator_config = parser.xml_generator_configuration_t()
        if None is compilation_mode:
            compilation_mode = parser.COMPILATION_MODE.FILE_BY_FILE
        start_time = time.clock()
        self.logger.debug( 'parsing files - started' )
        reader = parser.project_reader_t( xml_generator_config, cache, decl_wrappers.dwfactory_t() )
        decls = reader.read_files( files, compilation_mode )

        self.logger.debug( 'parsing files - done( %f seconds )' % ( time.clock() - start_time ) )

        return decls_package.matcher.get_single( decls_package.namespace_matcher_t( name='::' )
                                                 , decls )
Exemplo n.º 18
0
def test_on_windows_dot_h():
    he = r"2003\Vc7\PlatformSDK\Include\windows.h"
    windows_header = r"D:\Program Files\Microsoft Visual Studio .NET " + he
    clock_prev = time.clock()
    dcache = parser.file_cache_t(dcache_file_name)
    reader = parser.source_reader_t(
        parser.xml_generator_configuration_t(
            xml_generator_path=autoconfig.generator_path),
        dcache)
    reader.read_file(windows_header)
    dcache.flush()
    clock_now = time.clock()
    print('without cache: %f seconds' % (clock_now - clock_prev))

    clock_prev = time.clock()
    dcache = parser.file_cache_t(dcache_file_name)
    reader = parser.source_reader_t(
        parser.xml_generator_configuration_t(
            xml_generator_path=autoconfig.generator_path),
        dcache)
    reader.read_file(windows_header)
    clock_now = time.clock()
    print('with cache   : %f seconds' % (clock_now - clock_prev))
Exemplo n.º 19
0
def pygccxml_parser(filename):
    """
    Implementation of pygccxml parser
    """
    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)
    filename = filename
    decls = parser.parse([filename], xml_generator_config)

    global_namespace = declarations.get_global_namespace(decls)
    ns = global_namespace.namespace("sample_namespace")
    return declarations.print_declarations(ns)
Exemplo n.º 20
0
def test_project_on_include_std_dot_hpp():
    include_std_header = os.path.join(
        autoconfig.data_directory,
        'include_std.hpp')
    clock_prev = time.clock()
    dcache = parser.file_cache_t(dcache_file_name)
    reader = parser.project_reader_t(
        parser.xml_generator_configuration_t(
            xml_generator_path=autoconfig.generator_path),
        dcache)
    reader.read_files([include_std_header])
    dcache.flush()
    clock_now = time.clock()
    print('without cache: %f seconds' % (clock_now - clock_prev))

    clock_prev = time.clock()
    dcache = parser.file_cache_t(dcache_file_name)
    reader = parser.project_reader_t(
        parser.xml_generator_configuration_t(
            xml_generator_path=autoconfig.generator_path),
        dcache)
    reader.read_files([include_std_header])
    clock_now = time.clock()
    print('with cache   : %f seconds' % (clock_now - clock_prev))
Exemplo n.º 21
0
    def test_config(self):
        """
            Test that a missing include directory is printing a warning,
            not raising an error
        """

        # Some code to parse for the example
        code = "int a;"

        # Find the location of the xml generator (castxml or gccxml)
        generator_path, name = utils.find_xml_generator()

        # Path given as include director doesn't exist
        config = parser.xml_generator_configuration_t(
            xml_generator_path=generator_path,
            xml_generator=name,
            include_paths=["doesnt/exist", os.getcwd()])
        self.assertWarns(RuntimeWarning, parser.parse_string, code, config)
Exemplo n.º 22
0
    def __parse_declarations(self,
                             files,
                             xml_generator_config,
                             compilation_mode=None,
                             cache=None):
        if None is xml_generator_config:
            xml_generator_config = parser.xml_generator_configuration_t()
        if None is compilation_mode:
            compilation_mode = parser.COMPILATION_MODE.FILE_BY_FILE
        start_time = timer()
        self.logger.debug('parsing files - started')
        reader = parser.project_reader_t(xml_generator_config, cache,
                                         decl_wrappers.dwfactory_t())
        decls = reader.read_files(files, compilation_mode)

        self.logger.debug('parsing files - done( %f seconds )' %
                          (timer() - start_time))

        return decls_package.matcher.get_single(
            decls_package.namespace_matcher_t(name='::'), decls)
Exemplo n.º 23
0
def main():
    """
    Main function to generate Python-C++ binding code
    """

    # Find out the xml generator (gccxml or castxml)
    generator_path, generator_name = utils.find_xml_generator()
    compiler = "g++"
    compiler_path = "/usr/bin/g++"

    # Create configuration for CastXML
    xml_generator_config = parser.xml_generator_configuration_t(
        xml_generator_path=generator_path,
        xml_generator=generator_name,
        compiler=compiler,
        compiler_path=compiler_path)

    # Set include dirs and cflags to avoid warnings and errors
    xml_generator_config.append_cflags("-std=c++11")
    xml_generator_config.include_paths.append("../include/generated/")

    # Find all relevant headers
    header_list = get_list_of_files("../include/generated/")
    header_list = header_list + get_list_of_files("../include/ad_rss/core/")
    header_list = header_list + get_list_of_files("../include/ad_rss/physics/")

    # Parses the source files and creates a module_builder object
    builder = module_builder.module_builder_t(
        header_list,
        xml_generator_path=generator_path,
        xml_generator_config=xml_generator_config)

    # Automatically detect properties and associated getters/setters
    builder.classes().add_properties(exclude_accessors=True)

    # Define a name for the module
    builder.build_code_creator(module_name="libad_rss_python")

    # Writes the C++ interface file
    builder.write_module('PythonWrapper.cpp')
Exemplo n.º 24
0
    def test_config(self):
        """Test config setup with wrong xml generator setups."""

        # Some code to parse for the example
        code = "int a;"

        # Find the location of the xml generator (castxml or gccxml)
        generator_path, name = utils.find_xml_generator()

        # No xml generator path
        config = parser.xml_generator_configuration_t(xml_generator=name)
        self.assertRaises(
            RuntimeError, lambda: parser.parse_string(code, config))

        # Invalid path
        config = parser.xml_generator_configuration_t(
            xml_generator_path="wrong/path",
            xml_generator=name)
        self.assertRaises(
            RuntimeError, lambda: parser.parse_string(code, config))

        # None path
        config = parser.xml_generator_configuration_t(
            xml_generator_path=None,
            xml_generator=name)
        self.assertRaises(
            RuntimeError, lambda: parser.parse_string(code, config))

        # No name
        config = parser.xml_generator_configuration_t(
            xml_generator_path=generator_path)
        self.assertRaises(
            RuntimeError, lambda: parser.parse_string(code, config))

        # Random name
        config = parser.xml_generator_configuration_t(
            xml_generator_path=generator_path,
            xml_generator="not_a_generator")
        self.assertRaises(
            RuntimeError, lambda: parser.parse_string(code, config))

        # None name
        config = parser.xml_generator_configuration_t(
            xml_generator_path=generator_path,
            xml_generator=None)
        self.assertRaises(
            RuntimeError, lambda: parser.parse_string(code, config))
Exemplo n.º 25
0
def try_pygccxml():
    from pygccxml import declarations
    from pygccxml import utils
    from pygccxml import parser

    # Find out the c++ parser. This should resolve to the castxml
    # version installed in Docker.
    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,
        include_paths=["/usr/include/eigen3"],
        # TODO(eric.cousineau): Why is `compiler_path` necessary?
        compiler_path=generator_path,
        start_with_declarations=["ns"],
    )

    t_start = time.time()
    (global_ns, ) = parser.parse_string(code, config)
    dt = time.time() - t_start
    return dt
    def __init__(   self
                    , files
                    , includes
                    , symbols
                    , is_client = False
                ): 
        symbols = list(basesymbols + symbols)
        
        includepaths = incl_paths + includes

        includepaths = list(map(lambda p: p.replace('\\', '/'), includepaths))
        includepaths = list(filter(os.path.normpath, includepaths))

        self.definedsymbols = symbols
        self.includes = includepaths

        xml_generator_config = parser.xml_generator_configuration_t( xml_generator_path='/usr/bin/castxml'
                                         , working_directory='.'
                                         , include_paths=includepaths
                                         , define_symbols=symbols
                                         , undefine_symbols=usymbols
                                         , start_with_declarations=None
                                         #, ignore_gccxml_output=False
                                         , cflags=cflags
                                         , compiler_path='gcc-4.7'
                                         , xml_generator='castxml'
                                         )
        
        module_builder.module_builder_t.__init__(
                    self
                    , files
                    , xml_generator_config=xml_generator_config
                    , cache=None
                    , optimize_queries=True
                    , encoding='ascii'
                    , compilation_mode=parser.COMPILATION_MODE.ALL_AT_ONCE
                    )
Exemplo n.º 27
0
def generate_wrappers(args):
    module_name = args[1]
    work_dir = args[2]
    header_collection = args[3]
    castxml_binary = args[4]
    includes = args[5:]
    
    xml_generator_config = parser.xml_generator_configuration_t(xml_generator_path=castxml_binary, 
                                                                xml_generator="castxml",
                                                                compiler = "gnu",
                                                                compiler_path="/usr/bin/c++",
                                                                include_paths=includes)
     
    builder = module_builder.module_builder_t([header_collection],
                                                xml_generator_path = castxml_binary,
                                                xml_generator_config = xml_generator_config,
                                                start_with_declarations = ['chaste'],
                                                include_paths = includes,
                                                indexing_suite_version=2)
    messages.disable(messages.W1040) # unexposed declaration
    messages.disable(messages.W1031) # user to expose non public member function
    
    # Don't wrap std library
    builder.global_ns.namespace('std').exclude()
    
    # Set up the builder for each module
    builder = do_module(module_name, builder)
    
    # Make the wrapper code
    builder.build_code_creator(module_name="_chaste_project_PyChaste_" + module_name)
    builder.code_creator.user_defined_directories.append(work_dir + "/dynamic/wrapper_headers/")
    builder.write_module(work_dir + "/dynamic/" + module_name + ".cpp")
    
    # Fix a bug with boost units
    boost_units_namespace_fix(work_dir + "/dynamic/" + module_name + ".cpp")
    strip_undefined_call_policies(work_dir + "/dynamic/" + module_name + ".cpp")
Exemplo n.º 28
0
    def test_config(self):
        """Test config setup with wrong xml generator setups."""

        # Some code to parse for the example
        code = "int a;"

        # Find the location of the xml generator (castxml or gccxml)
        generator_path, name = utils.find_xml_generator()

        # No xml generator path
        config = parser.xml_generator_configuration_t(xml_generator=name)
        self.assertRaises(RuntimeError,
                          lambda: parser.parse_string(code, config))

        # Invalid path
        config = parser.xml_generator_configuration_t(
            xml_generator_path="wrong/path", xml_generator=name)
        self.assertRaises(RuntimeError,
                          lambda: parser.parse_string(code, config))

        # None path
        config = parser.xml_generator_configuration_t(xml_generator_path=None,
                                                      xml_generator=name)
        self.assertRaises(RuntimeError,
                          lambda: parser.parse_string(code, config))

        # No name
        config = parser.xml_generator_configuration_t(
            xml_generator_path=generator_path)
        self.assertRaises(RuntimeError,
                          lambda: parser.parse_string(code, config))

        # Random name
        config = parser.xml_generator_configuration_t(
            xml_generator_path=generator_path, xml_generator="not_a_generator")
        self.assertRaises(RuntimeError,
                          lambda: parser.parse_string(code, config))

        # None name
        config = parser.xml_generator_configuration_t(
            xml_generator_path=generator_path, xml_generator=None)
        self.assertRaises(RuntimeError,
                          lambda: parser.parse_string(code, config))
Exemplo n.º 29
0
#!/usr/bin/python
from pygccxml import parser
from pygccxml import declarations
from pyplusplus import module_builder
import sys

generator_path = '/usr/bin/castxml'
if len(sys.argv) > 1:
    generator_path = sys.argv[1]

# Create configuration for CastXML
xml_generator_config = parser.xml_generator_configuration_t(
    xml_generator_path=generator_path,
    xml_generator='castxml',
    compiler='gnu',
    compiler_path='/usr/bin/gcc',
    cflags='-std=c++11 -I../liblc3')

# List of all the C++ header of our library
header_collection = ["PyLC3.hpp", "../liblc3/lc3_all.hpp"]

# Parses the source files and creates a module_builder object
builder = module_builder.module_builder_t(
    header_collection,
    xml_generator_path='/usr/bin/castxml',
    xml_generator_config=xml_generator_config)

# Debugging
#builder.print_declarations()

# Whitelist exporting of stuff.
Exemplo n.º 30
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,
    include_paths=[str(x[2:]) for x in sys.argv[2:]],
    cflags=' '.join(str(x) for x in sys.argv[2:]))

# Parse the c++ file
decls = parser.parse([sys.argv[1]], xml_generator_config)
declarations.print_declarations(decls)
Exemplo n.º 31
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)

    # grab global namespace
    try:
        global_ns = declarations.get_global_namespace(decls)
    except RuntimeError:
        return []

    # output file preamble
    fileguard = "pybind_" + filename.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
Exemplo n.º 32
0
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")
Exemplo n.º 33
0
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")
Exemplo n.º 34
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()
Exemplo n.º 35
0
# Find out the file location within the sources tree
this_module_dir_path = os.path.abspath(
    os.path.dirname(sys.modules[__name__].__file__))
# Add pygccxml package to Python path
sys.path.append(os.path.join(this_module_dir_path, '..', '..'))

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)
Exemplo n.º 36
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
        if 0:
            # XXX: This doesn't work
            # 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):
                        includes.append(os.path.normpath(include))
        elif 0:
            # XXX: This matches what wclang does, but doensn't work neither
            cxxflags += [
                "-target",
                "x86_64-w64-mingw32",
                "-nostdinc",
                "-isystem",
                "/usr/lib/clang/3.6.0/include",
                "-isystem",
                "/usr/x86_64-w64-mingw32/include",
                "-isystem",
                "/usr/lib/gcc/x86_64-w64-mingw32/4.9-win32/include/c++",
                "-isystem",
                "/usr/lib/gcc/x86_64-w64-mingw32/4.9-win32/include/c++/x86_64-w64-mingw32",
            ]
        else:
            # This works somehow, but seems brittle
            includes += [
                '/usr/x86_64-w64-mingw32/include',
                '/usr/lib/gcc/x86_64-w64-mingw32/4.9-win32/include/c++',
                '/usr/lib/gcc/x86_64-w64-mingw32/4.9-win32/include/c++/x86_64-w64-mingw32',
            ]

        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,
            # 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 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
        visitor.decl = decl
        algorithm.apply_visitor(visitor, decl)
    visitor.finish()
Exemplo n.º 37
0
def generate(defined_symbols, extraIncludes):
    messages.disable(
        messages.W1005 # using a non public variable type for arguments or returns
        , messages.W1006 # `Py++` need your
                         # help to expose function that takes > as argument/returns C++ arrays.
                         # Take a look on "Function Transformation" > functionality and define
                         # the transformation.
        , messages.W1007 # more than 10 args -> BOOST_PYTHON_MAX_ARITY is set
        , messages.W1009 # execution error W1009: The function takes as argument (name=pFunIdx, pos=1) >
                         # non-const reference to Python immutable type - function could not be called > from Python
        , messages.W1014 # "operator*" is not supported. See
        , messages.W1016 # `Py++` does not exports non-const casting operators
        # Warnings 1020 - 1031 are all about why Py++ generates wrapper for class X
        , messages.W1023 # Py++` will generate class wrapper - there are few functions that should be
                         # redefined in class wrapper
        , messages.W1025 # `Py++` will generate class wrapper - class contains "c_" - T* > member variable
        , messages.W1026 # `Py++` will generate class wrapper - class contains "arr_" - T& > member variable
        , messages.W1027 # `Py++` will generate class wrapper - class contains "mat_" - > array member variable
        , messages.W1035 # error. `Py++` can not expose static pointer member variables.
        , messages.W1036 # error. `Py++` can not expose pointer to Python immutable > member variables. This
                         # could be changed in future.
        , messages.W1040 # error. The declaration is unexposed, but there are other > declarations, which
                         # refer to it. This could cause "no to_python converter > found" run
                         # time error
        # This is serious and lead to RuntimeError: `Py++` is going to write different content to the same file
        , messages.W1047 # There are two or more classes that use same > alias("MatElement"). Duplicated aliases causes
                         # few problems, but the main one > is that some of the classes will not
                         # be exposed to Python.Other classes : >
        , messages.W1049 # This method could not be overriden in Python - method returns >
                         # reference to local variable!
        , messages.W1052 # `Py++` will not expose free operator      
        
    )

    logger.debug("Install SRC:  ", os.path.abspath(__file__))
    logger.debug("Execute from: ", os.getcwd())

    sourcedir = os.path.dirname(os.path.abspath(__file__))
    sourceHeader = os.path.abspath(sourcedir + "/" + r"pygimli.h")
    gimliInclude = os.path.dirname(
                         os.path.abspath(sourcedir + "/../src/" + r"gimli.h"))
    settings.includesPaths.append(gimliInclude)

    xml_cached_fc = parser.create_cached_source_fc(
        sourceHeader, settings.module_name + '.cache')
    #xml_cached_fc = parser.create_cached_source_fc(os.path.join(r"pygimli.h"), settings.module_name + '.cache')

    import platform

    defines = ['PYGIMLI_CAST', 'HAVE_BOOST_THREAD_HPP']
    caster = 'gccxml'
    compiler_path = None
    
    if platform.system() == 'Windows':
        if platform.architecture()[0] == '64bit': 
            compiler_path='C:/msys64/mingw64/bin/clang++'
            if sys.platform == 'darwin':
                pass
            else:
                defines.append('_WIN64')
                defines.append('MS_WIN64')
                
                logger.info('Marking win64 for gccxml')
        else:
            compiler_path='C:/msys32/mingw32/bin/clang++'
            
    for define in [settings.gimli_defines, defined_symbols]:
        if len(define) > 0:
            defines.append(define)

    try:
        if sys.platform == 'win32':
            # os.name == 'nt' (default on my mingw) results in wrong commandline
            # for gccxml
            os.name = 'mingw'
            casterpath = settings.caster_path.replace('\\', '\\\\')
            casterpath = settings.caster_path.replace('/', '\\')
            
            
            if not 'gccxml' in casterpath:
                caster = 'castxml'
            
            if not '.exe' in casterpath:
                casterpath += '\\' + caster + '.exe'

        else:
            casterpath = settings.caster_path
            if not 'gccxml' in casterpath:
                caster = 'castxml'
            
    except Exception as e:
        logger.info("caster_path=%s" % casterpath)
        logger.info(str(e))
        raise Exception("Problems determine castxml binary")

    settings.includesPaths.insert(0, os.path.abspath(extraIncludes))

    logger.info("caster_path=%s" % casterpath)
    logger.info("working_directory=%s" % settings.gimli_path)
    logger.info("include_paths=%s" % settings.includesPaths)
    logger.info("define_symbols=%s" % defines)
    logger.info("indexing_suite_version=2")

    xml_generator_config = parser.xml_generator_configuration_t( 
                                                xml_generator=caster,
                                                xml_generator_path=casterpath,
                                                working_directory=settings.gimli_path,
                                                include_paths=settings.includesPaths,
                                                define_symbols=defines,
                                                ignore_gccxml_output=False,
                                                cflags="",
                                                compiler_path=compiler_path)
    
    mb = module_builder.module_builder_t([xml_cached_fc], 
                                         indexing_suite_version=2,
                                         xml_generator_config=xml_generator_config
                                         )

    #mb = module_builder.module_builder_t([xml_cached_fc],
                                         #xml_generator_path=casterpath,
                                         #working_directory=settings.gimli_path,
                                         #include_paths=settings.includesPaths,
                                         #define_symbols=defines,
                                         #indexing_suite_version=2,
                                         #compiler_path=compiler_path,
                                         #caster=caster
                                         #)

    logger.info("Reading of c++ sources done.")
        
    mb.classes().always_expose_using_scope = True
    mb.calldefs().create_with_signature = True

    global_ns = mb.global_ns
    global_ns.exclude()
    main_ns = global_ns.namespace(MAIN_NAMESPACE)
    main_ns.include()
    

    #for c in main_ns.free_functions():
        ##print(c)
        #if 'pow' in c.name:
            #print(c)
            #print(c.name)
        ##if c.decl_string.startswith('::GIMLI::pow'):
            ##print(c)
            ##print(c.name)
            
    #sys.exit()
                
    logger.info("Apply handmade wrappers.")
    try:
        hand_made_wrappers.apply(mb)
    except Exception as e:
        print(e)

    logger.info("Apply custom rvalues.")
    # START manual r-value converters
    rvalue_converters = [
        'register_pytuple_to_rvector3_conversion',
        'register_pysequence_to_rvector_conversion',
        #'register_pysequence_to_bvector_conversion',
        'register_pysequence_to_indexvector_conversion',
        'register_pysequence_to_r3vector_conversion',
        'register_pysequence_to_StdVectorRVector3_conversion',
        #'register_rvector_to_ndarray_conversion',
    ]
    
    for converter in rvalue_converters:
        mb.add_declaration_code('void %s();' % converter)
        mb.add_registration_code('%s();' % converter)

    # END manual r-value converters

    custom_rvalue_path = os.path.join(
        os.path.abspath(os.path.dirname(__file__)), 'custom_rvalue.cpp')

    logger.info("Starting to exclude stuff that we don't need or that is known to be spurious.")
    
    exclude(main_ns.variables,
            name=[
                'Triangle6_S1',
                'Triangle6_S2',
                'Triangle6_S3',
                'HexahedronFacesID',
                'Hexahedron20FacesID',
                'TetrahedronFacesID',
                'HexahedronSplit5TetID',
                'HexahedronSplit6TetID',
                'TriPrismFacesID',
                'TriPrimSplit3TetID',
                'NodeCoordinates',
                'EdgeCoordinates',
                'TriCoordinates',
                'QuadCoordinates',
                'TetCoordinates',
                'HexCoordinates',
                'PrismCoordinates',
                'PyramidCoordinates',
                'PyramidFacesID',
                'Tet10NodeSplit',
                'Tet10NodeSplitZienk',
                'Hex20NodeSplit',
                'Prism15NodeSplit',
                'Pyramid13NodeSplit'
                ]
            )

    exclude(main_ns.free_functions,
            return_type=[
                'float *',
                'float &',
                "::GIMLI::__VectorExpr< double, GIMLI::__VectorUnaryExprOp< double, GIMLI::VectorIterator< double >, GIMLI::ABS_ > >"],
            name=[
                'strReplaceBlankWithUnderscore',
                'toStr',
                'toInt',
                'toFloat',
                'toDouble',
                'str',
                'getRowSubstrings',
                'getNonEmptyRow',
                'getSubstrings',
                'abs',
                'type']
            )

    exclude(main_ns.free_operators,
            name=[''],
            return_type=['::std::ostream &', '::std::istream &']
        )

    exclude(main_ns.classes,
            name=['ABS_', 'ACOT', 'ATAN', 'COS', 'COT', 'EXP',
                  'ABS_', 'LOG', 'LOG10', 'SIGN', 'SIN', 'SQRT', 'SQR', 'TAN', 'TANH',
                  'PLUS', 'MINUS', 'MULT', 'DIVID', 'BINASSIGN', 'cerrPtr',
                  'cerrPtrObject', 'coutPtr', 'coutPtrObject', 'deletePtr', 'edge_',
                  'distancePair_', 'IPCMessage', 'PythonGILSave',
                  ]
            )

    exclude(main_ns.member_functions,
            name=['begin',
                  'end',
                  'val'],
            return_type=['']
        )

    exclude(main_ns.member_operators, 
            symbol=[''])
    
    
    for f in main_ns.declarations:
        if isinstance(f, decl_wrappers.calldef_wrapper.free_function_t):
            if (str(f.return_type).find('GIMLI::VectorExpr') != -1):
                f.exclude()
    
    ex = ['::GIMLI::MatrixElement',
          '::GIMLI::__VectorUnaryExprOp',
          '::GIMLI::__VectorBinaryExprOp',
          '::GIMLI::__ValVectorExprOp',
          '::GIMLI::__VectorValExprOp',
          '::GIMLI::__VectorExpr',
          '::GIMLI::Expr',
          '::GIMLI::InversionBase',
          'GIMLI::MatrixElement',
          'GIMLI::__VectorUnaryExprOp',
          'GIMLI::__VectorBinaryExprOp',
          'GIMLI::__ValVectorExprOp',
          'GIMLI::__VectorValExprOp',
          'GIMLI::__VectorExpr',
          'GIMLI::Expr',
          'GIMLI::InversionBase',
          'std::vector<unsigned long',
          'std::vector<bool',
          ]
    
    for c in main_ns.free_functions():
        for e in ex:
            if c.decl_string.find(e) > -1:
                try:
                    c.exclude()
                    logger.debug("Exclude: " + str(c))
                except:
                    logger.debug("Fail to exclude: " + str(c))
                    
    for c in main_ns.classes():
        for e in ex:
            if c.decl_string.startswith(e):
                try:
                    c.exclude()
                    logger.debug("Exclude: " + c.name)
                except:
                    logger.debug("Fail to exclude: " + c.name)
          
        try:
            for mem in c.constructors():
                for e in ex:
                    if mem.decl_string.find(e) > -1:
                        try:
                            mem.exclude()
                            #logger.info("Exclude: " + str(mem))
                        except:
                            logger.debug("Fail to exclude: " + str(mem))
                            
            for mem in c.member_functions():
                for e in ex:
                    if mem.decl_string.find(e) > -1:
                        try:
                            mem.exclude()
                            #logger.info("Exclude: " + str(mem))
                        except:
                            logger.debug("Fail to exclude: " + str(mem))
        except:
            #print(c, "has no member functions")
            pass
        
        #print('#'*100)
        #print(c, c.name)
        if c.name.startswith('Vector<unsigned long>'):
            #print('         ', c.name)
            for mem in c.constructors():
                #print("mem", mem, mem.decl_string)
                if mem.decl_string.find('( ::GIMLI::Index )') > -1:
                    logger.debug("Exclude: " + str(mem))
                    mem.exclude()
                
                #print("mem", mem)
     
    try:
        mb.calldefs(access_type_matcher_t('protected')).exclude()
        mb.calldefs(access_type_matcher_t('private')).exclude()
    except:
        pass

    # setMemberFunctionCallPolicieByReturn(mb, [ '::GIMLI::Node &'
    #, '::GIMLI::Cell &'
    #, '::GIMLI::Boundary &'
    #, '::GIMLI::Shape &'
    #, '::GIMLI::Node *'
    #, '::GIMLI::Cell *'
    #, '::GIMLI::Boundary *'
    #, '::GIMLI::Shape *'
    #]
    #, call_policies.reference_existing_object)

    setMemberFunctionCallPolicieByReturn(
        mb,
        ['::std::string *', 'float *', 'double *',
         'int *',
         'long *',
         'long int *', 
         'long long int *',
         'unsigned int *',
         'long unsigned int *', 
         'unsigned long long int *',
         'long long unsigned int *',
         '::GIMLI::Index *', '::GIMLI::SIndex *', 'bool *'],
        call_policies.return_pointee_value)

    setMemberFunctionCallPolicieByReturn(mb, ['::std::string &',
                                              'float &',
                                              'double &',
                                              'int &',
                                              'long &',
                                              'long int &',
                                              'long long int &',
                                              'unsigned int &',
                                              'long unsigned int &',
                                              'long long unsigned int &',
                                              'unsigned long long int &',
                                              '::GIMLI::Index &',
                                              '::GIMLI::SIndex &',
                                              'bool &'
                                              ], call_policies.return_by_value)

    # setMemberFunctionCallPolicieByReturn(mb, ['::GIMLI::VectorIterator<double> &']
    #, call_policies.copy_const_reference)
    # setMemberFunctionCallPolicieByReturn(mb, [
    #,  'double &' ]
    #, call_policies.reference_existing_object)

    # call_policies.return_value_policy(call_policies.reference_existing_object)
    # call_policies.return_value_policy(call_policies.copy_non_const_reference)
    # call_policies.return_value_policy(call_policies.copy_const_reference)

    # addAutoConversions(mb)

   # excludeMemberByReturn(main_ns, ['::DCFEMLib::SparseMatrix<double> &'])
    #main_ns.classes(decl_starts_with(['STLMatrix']), allow_empty=True).exclude()
    #fun = mb.global_ns.member_functions('begin', allow_empty=True)
    # for f in fun:
    # f.exclude()

    # excludeFreeFunctionsByName(main_ns, ['strReplaceBlankWithUnderscore'
    #'toStr', 'toInt', 'toFloat', 'toDouble',
    #'getRowSubstrings', 'getNonEmptyRow', 'getSubstrings' ])

    #excludeFreeFunctionsByReturn(main_ns, [ 'float *', 'float &' ])
    #fun = ns.free_operators(return_type=funct, allow_empty=True)

    #excludeMemberOperators(main_ns, ['++', '--', '*'])

    # exclude all that does not match any predefined callpolicie

    excludeRest = True

    if excludeRest:
        mem_funs = mb.calldefs()

        for mem_fun in mem_funs:
            if mem_fun.call_policies:
                continue
            if not mem_fun.call_policies and \
                    (declarations.is_reference(mem_fun.return_type) or declarations.is_pointer(mem_fun.return_type)):
                # print mem_fun
                # mem_fun.exclude()
                mem_fun.call_policies = call_policies.return_value_policy(
                    call_policies.reference_existing_object)
                # mem_fun.call_policies = \
                #    call_policies.return_value_policy(call_policies.return_pointee_value)
                # mem_fun.call_policies = \
                #    call_policies.return_value_policy(call_policies.return_opaque_pointer)
                # mem_fun.call_policies = \
                #   call_policies.return_value_policy(call_policies.copy_non_const_reference)

    logger.info("Create api documentation from Doxgen comments.")
    # Now it is the time to give a name to our module
    from doxygen import doxygen_doc_extractor
    extractor = doxygen_doc_extractor()

    logger.info("Create code creator.")
    mb.build_code_creator(settings.module_name, doc_extractor=extractor)

    # It is common requirement in software world - each file should have license
    #mb.code_creator.license = '//Boost Software License(http://boost.org/more/license_info.html)'

    # I don't want absolute includes within code
    mb.code_creator.user_defined_directories.append(os.path.abspath('.'))

    # And finally we can write code to the disk
    def ignore(val):
        pass
    logger.info("Create bindings code.")
    mb.split_module('./generated', on_unused_file_found=ignore)

    additional_files = [
        os.path.join(
               os.path.abspath(os.path.dirname(__file__)), 'custom_rvalue.cpp'), 
        os.path.join(
                os.path.abspath(os.path.dirname(__file__)), 'generators.h'),
        os.path.join(
                os.path.abspath(os.path.dirname(__file__)), 'tuples.hpp')]

    logger.info("Add additional files.")
    
    for sourcefile in additional_files:
        p, filename = os.path.split(sourcefile)
        destfile = os.path.join('./generated', filename)

        if not samefile(sourcefile, destfile):
            shutil.copy(sourcefile, './generated')
            logger.info("Updated " +  filename + "as it was missing or out of date")
Exemplo n.º 38
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
        if 0:
            # XXX: This doesn't work
            # 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):
                        includes.append(os.path.normpath(include))
        elif 0:
            # XXX: This matches what wclang does, but doensn't work neither
            cxxflags += [
                "-target",
                "x86_64-w64-mingw32",
                "-nostdinc",
                "-isystem",
                "/usr/lib/clang/3.6.0/include",
                "-isystem",
                "/usr/x86_64-w64-mingw32/include",
                "-isystem",
                "/usr/lib/gcc/x86_64-w64-mingw32/4.9-win32/include/c++",
                "-isystem",
                "/usr/lib/gcc/x86_64-w64-mingw32/4.9-win32/include/c++/x86_64-w64-mingw32",
            ]
        else:
            # This works somehow, but seems brittle
            includes += [
                "/usr/x86_64-w64-mingw32/include",
                "/usr/lib/gcc/x86_64-w64-mingw32/4.9-win32/include/c++",
                "/usr/lib/gcc/x86_64-w64-mingw32/4.9-win32/include/c++/x86_64-w64-mingw32",
            ]

        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,
            # 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 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
        visitor.decl = decl
        algorithm.apply_visitor(visitor, decl)
    visitor.finish()
Exemplo n.º 39
0
def generate_python_wrapper(header_directories,
                            include_paths,
                            library_name,
                            cpp_filename,
                            declarations,
                            ignore_declarations={},
                            ignore_files={}):
    """
    Function to generate Python-C++ binding code by calling pygccxml and py++

    :param header_directories: directories with headers to create python binding for
    :type header_directories: list<string>
    :param include_paths: directories required as includes for the header files
    :type include_paths: list<string>
    :param library_name: the output name of the library to be created
    :type library_name: string
    :param cpp_filename: the output name of the C++ file to be created
    :type cpp_filename: string
    :param declarations: a list of declarations to be used for starting the AST syntax tree. See also
      pygccxml start_with_declarations or either -fxml-start(gccxml) or -castxml-start(castxml)
    :type declarations: list<string>
    :param ignore_declarations: a list of declarations to be ignored when generating C++ code
    :type ignore_declarations: list<string>
    :param ignore_files: a list of files to be ignored
    :type ignore_files: list<string>
    :return:
    """

    # Find out the xml generator (gccxml or castxml)
    generator_path, generator_name = utils.find_xml_generator()
    compiler = "g++"
    compiler_path = "/usr/bin/g++"

    # Create configuration for CastXML
    xml_generator_config = parser.xml_generator_configuration_t(
        xml_generator_path=generator_path,
        xml_generator=generator_name,
        compiler=compiler,
        compiler_path=compiler_path,
        start_with_declarations=declarations)

    # Set include dirs and cflags to avoid warnings and errors
    xml_generator_config.append_cflags("-std=c++11")

    for inc_dir in include_paths:
        xml_generator_config.include_paths.append(inc_dir)

    for header_dir in header_directories:
        xml_generator_config.include_paths.append(header_dir)

    # Find all relevant headers
    header_list = list()
    for header_dir in header_directories:
        header_list = header_list + get_list_of_files(
            header_dir, ignore_files=ignore_files)

    # Parses the source files and creates a module_builder object
    builder = module_builder.module_builder_t(
        header_list,
        xml_generator_path=generator_path,
        compilation_mode=parser.COMPILATION_MODE.ALL_AT_ONCE,
        xml_generator_config=xml_generator_config,
        indexing_suite_version=2)

    for ignore_declaration in ignore_declarations:
        builder.decls(lambda decl: ignore_declaration in decl.name).exclude()

    # for some reason there is a problem with variables named 'length'
    # the filename is empty and the line no is set to -1
    # therefore the declaration is not processed in the code later on
    # this is to fix length struct members
    for decl in builder.decls("length"):
        if isinstance(decl, decl_wrappers.variable_wrapper.variable_t):
            if isinstance(decl.parent, decl_wrappers.class_wrapper.class_t):
                decl.location.file_name = decl.parent.location.file_name
                decl.location.line = decl.parent.location.line + 1
                decl.ignore = False

    # Automatically detect properties and associated getters/setters
    builder.classes().add_properties(exclude_accessors=True)

    # Define a name for the module
    builder.build_code_creator(module_name=library_name)

    # Writes the C++ interface file
    builder.write_module(cpp_filename)
Exemplo n.º 40
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 
        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)

        # try to extract any preceeding '//' comments above the declaration
        in_source_documentation = extract_in_source_documentation(item.location.file_name, item.location.line)

        # get grandparent's name
        grandparent = item.parent.parent
        grandparent_name = grandparent.name if grandparent else ''

        # insert the content into the table
        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(grandparent_name), item.attributes, cleaned_filename, str(item.location.line), in_source_documentation, "")
            )
        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
Exemplo n.º 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
Exemplo n.º 42
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
Exemplo n.º 43
0
def generate_wrappers(args):

    work_dir = args[1]
    header_collection = args[2]
    castxml_binary = args[3]
    module_name = args[4]
    includes = args[5:]

    xml_generator_config = parser.xml_generator_configuration_t(
        xml_generator_path=castxml_binary,
        xml_generator="castxml",
        #compiler = "gnu",
        #compiler_path="/usr/bin/c++",
        cflags="-std=c++11",
        include_paths=includes)

    builder = module_builder.module_builder_t(
        [header_collection],
        xml_generator_path=castxml_binary,
        xml_generator_config=xml_generator_config,
        start_with_declarations=['chaste'],
        include_paths=includes,
        #cflags = "-std=c++11",
        indexing_suite_version=2,
        cache=file_cache_t(work_dir + "/dynamic/wrappers/castxml_cache.xml"))

    messages.disable(messages.W1040)  # unexposed declaration
    messages.disable(
        messages.W1031)  # user to expose non public member function
    messages.disable(messages.W1023)  # user to define some functions
    messages.disable(messages.W1014)  # operator not supported
    messages.disable(messages.W1036)  # can't expose immutable member variables

    # Don't wrap std or boost library
    builder.global_ns.namespace('std').exclude()
    builder.global_ns.namespace('boost').exclude()

    # Strip out Instantiation 'tricks' in the header file
    # todo - the first line is presumably no longer necessary
    builder.free_function("GetPetscMatForWrapper"
                          ).call_policies = call_policies.return_value_policy(
                              call_policies.return_opaque_pointer)
    builder.free_function("GetPetscMatForWrapper").exclude()
    builder.free_function("Instantiation").exclude()

    # Load the classes to be wrapped
    with open(work_dir + "/dynamic/wrappers/class_data.p", 'rb') as fp:
        classes = pickle.load(fp)

    possible_module_names = [module_name]
    possible_module_names = [
        "core", "ode", "pde", "mesh", "cell_based", "tutorial", "visualization"
    ]
    if module_name == "All":
        possible_module_names = [
            "core", "ode", "pde", "mesh", "cell_based", "tutorial",
            "visualization"
        ]

    for idx, eachModule in enumerate(possible_module_names):

        print 'Generating Wrapper Code for: ' + eachModule + ' Module.'

        if "core" not in eachModule and len(possible_module_names) > 1:
            builder.register_module_dependency(work_dir +
                                               "/dynamic/wrappers/" +
                                               possible_module_names[idx - 1])

        # Set up the builder for each module

        print 'Starting Module: ' + eachModule + ' Module.'
        builder = do_module(eachModule, builder,
                            work_dir + "/dynamic/wrappers/" + eachModule + "/",
                            classes)

        # Make the wrapper code
        #     builder.build_code_creator(module_name="_chaste_project_PyChaste_" + module_name,
        #                                doc_extractor=doxygen_extractor.doxygen_doc_extractor())
        builder.build_code_creator(module_name="_chaste_project_PyChaste_" +
                                   eachModule)
        builder.code_creator.user_defined_directories.append(work_dir)
        builder.code_creator.user_defined_directories.append(
            work_dir + "/dynamic/wrappers/")
        builder.code_creator.user_defined_directories.append(
            work_dir + "/dynamic/wrappers/" + eachModule + "/")
        builder.code_creator.license = chaste_license

        file_list = builder.split_module(work_dir + "/dynamic/wrappers/" +
                                         eachModule)
        value_traits_files = []
        for eachFile in file_list:
            if "__value_traits" in eachFile:
                value_traits_files.append(ntpath.basename(eachFile))

        # Manually strip any undefined call policies we have missed. Strictly there should not be any/many.
        for file in os.listdir(work_dir + "/dynamic/wrappers/" + eachModule +
                               "/"):
            if file.endswith(".cpp"):
                strip_undefined_call_policies(work_dir + "/dynamic/wrappers/" +
                                              eachModule + "/" + file)

        # Manually remove some value traits in std headers (https://mail.python.org/pipermail/cplusplus-sig/2008-April/013105.html)
        for file in os.listdir(work_dir + "/dynamic/wrappers/" + eachModule +
                               "/"):
            if file.endswith(".cpp"):
                strip_value_traits(
                    work_dir + "/dynamic/wrappers/" + eachModule + "/" + file,
                    value_traits_files)
Exemplo n.º 44
0
            length = dat.index(b'\x00')
            return dat[:length]
        else:
            return dat[:16]

    def get_formatted(self, data):
        return repr(data)[1:]


with open(os.path.join(os.path.dirname(__file__), "../stm/src/common/slots.h"),
          "r") as f:
    full_text = f.read()

# parse the file
gp, gn = utils.find_xml_generator()
xml_generator_config = parser.xml_generator_configuration_t(
    xml_generator_path=gp, xml_generator=gn)

declarations_in_file = parser.parse_string(full_text, xml_generator_config)


def _convert_opaque_to_token(x):
    """
    convert either a string from re or a value from pygccxml to a struct token
    """

    if type(x) is str:
        return {
            "BOOL": "?",
            "UINT8_T": "B",
            "INT8_T": "b",
            "UINT16_T": "H",
Exemplo n.º 45
0
                        for ee in sorted(kernel_prio, key=lambda k: k[1]):
                            if ee[0] in path:
                                prio += ee[1]
                                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
if 'xml_generator_configuration_t' in dir(parser):
    config = parser.xml_generator_configuration_t(include_paths=include_paths, ignore_gccxml_output=False,
                                                  keep_xml=True, xml_generator='castxml')
else:
    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
Exemplo n.º 46
0
#!/usr/bin/python
from pygccxml import parser
from pygccxml import declarations
from pyplusplus import module_builder
import sys

generator_path = '/usr/bin/castxml'
if len(sys.argv) > 1:
    generator_path = sys.argv[1]

# Create configuration for CastXML
xml_generator_config = parser.xml_generator_configuration_t(
                                    xml_generator_path=generator_path,
                                    xml_generator='castxml',
                                    compiler='gnu',
                                    compiler_path='/usr/bin/gcc',
                                    cflags='-std=c++11 -I../liblc3')

# List of all the C++ header of our library
header_collection = ["PyLC3.hpp", "../liblc3/lc3_all.hpp"]

# Parses the source files and creates a module_builder object
builder = module_builder.module_builder_t(
                        header_collection,
                        xml_generator_path='/usr/bin/castxml',
                        xml_generator_config=xml_generator_config)

# Debugging
#builder.print_declarations()

# Whitelist exporting of stuff.
    def __init__( self
                  , files
                  , gccxml_path=''
                  , xml_generator_path=''
                  , working_directory='.'
                  , include_paths=None
                  , define_symbols=None
                  , undefine_symbols=None
                  , start_with_declarations=None
                  , compilation_mode=None
                  , cache=None
                  , optimize_queries=True
                  , ignore_gccxml_output=False
                  , indexing_suite_version=1
                  , cflags=""
                  , encoding='ascii'
                  , compiler=None
                  , gccxml_config=None
                  , xml_generator_config=None):
        """
        :param files: list of files, declarations from them you want to export
        :type files: list of strings or :class:`parser.file_configuration_t` instances

        :param xml_generator_path: path to gccxml/castxml binary. If you don't pass this argument,
                            pygccxml parser will try to locate it using your environment PATH variable
        :type xml_generator_path: str

        :param include_paths: additional header files location. You don't have to
                              specify system and standard directories.
        :type include_paths: list of strings

        :param define_symbols: list of symbols to be defined for preprocessor.
        :param define_symbols: list of strings

        :param undefine_symbols: list of symbols to be undefined for preprocessor.
        :param undefine_symbols: list of strings

        :param cflags: Raw string to be added to xml generator command line.

        :param xml_generator_config: instance of pygccxml.parser.xml_generator_configuration_t class, holds
                              xml generator configuration. You can use this
                              argument instead of passing the compiler configuration separately.

        :param gccxml_path: DEPRECATED
        :param gccxml_config: DEPRECATED
        """
        module_builder.module_builder_t.__init__( self, global_ns=None, encoding=encoding )

        # handle deprecated parameters
        if not gccxml_path == '' and xml_generator_path == '':
            xml_generator_path = gccxml_path
        if gccxml_config and not xml_generator_config:
            xml_generator_config = gccxml_config

        if not xml_generator_config:
            xml_generator_config = parser.xml_generator_configuration_t( xml_generator_path=xml_generator_path
                                             , working_directory=working_directory
                                             , include_paths=include_paths
                                             , define_symbols=define_symbols
                                             , undefine_symbols=undefine_symbols
                                             , start_with_declarations=start_with_declarations
                                             , ignore_gccxml_output=ignore_gccxml_output
                                             , cflags=cflags
                                             , compiler=compiler)

        #may be in future I will add those directories to user_defined_directories to self.__code_creator.
        self.__parsed_files = list(map( pygccxml_utils.normalize_path
                                   , parser.project_reader_t.get_os_file_names( files ) ))
        tmp = [os.path.split( file_ )[0] for file_ in self.__parsed_files]
        self.__parsed_dirs = [_f for _f in tmp if _f]

        self.global_ns = self.__parse_declarations( files
                                                    , xml_generator_config
                                                    , compilation_mode
                                                    , cache
                                                    , indexing_suite_version)
        self.global_ns.decls(recursive=True, allow_empty=True)._code_generator = decl_wrappers.CODE_GENERATOR_TYPES.CTYPES

        self.__code_creator = None
        if optimize_queries:
            self.run_query_optimizer()

        self.__declarations_code_head = []
        self.__declarations_code_tail = []

        self.__registrations_code_head = []
        self.__registrations_code_tail = []
Exemplo n.º 48
0
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 out the c++ parser
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,
    castxml_epic_version=1)

# The c++ file we want to parse
filename = "example.hpp"
filename = this_module_dir_path + "/" + filename

decls = parser.parse([filename], xml_generator_config)
global_namespace = declarations.get_global_namespace(decls)

a1 = global_namespace.variable("a1")
print(str(a1.decl_type), type(a1.decl_type))
# > 'A', <class 'pygccxml.declarations.cpptypes.declarated_t'>

print(declarations.is_elaborated(a1.decl_type))
# > False
Exemplo n.º 49
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
Exemplo n.º 50
0
        return self.__aliasStrs

    def getEnumLines(self):
        return self.__enumStrs


generator_path, generator_name = utils.find_xml_generator()

if (generator_name != 'castxml'):
    print(generator_name +
          ' does not equal castxml.  Please make sure castxml is installed.')
    sys.exit(1)

# Configure the xml generator
config = parser.xml_generator_configuration_t(\
    xml_generator_path=generator_path,\
    xml_generator=generator_name,\
    cflags=flags)

# find struct in vulkan headers
for path in sys.argv[startIdx:]:
    #print (path)
    # Parsing source file
    decls = parser.parse([path], config)
    global_ns = declarations.get_global_namespace(decls)
    # generate vulkan type list code
    # iterate classes and get member information
    for clas in [
            global_ns.classes(),
            global_ns.enumerations(),
            global_ns.typedefs()
    ]:  #,global_ns.enumerations():
Exemplo n.º 51
0
def generate(defined_symbols, extraIncludes):
    messages.disable(
        messages.W1005  # using a non public variable type for arguments or returns
        , messages.W1006  # `Py++` need your
                          # help to expose function that takes > as argument/returns C++ arrays.
                          # Take a look on "Function Transformation" > functionality and define
                          # the transformation.
        , messages.W1007  # more than 10 args -> BOOST_PYTHON_MAX_ARITY is set
        , messages.W1009  # execution error W1009: The function takes as argument (name=pFunIdx, pos=1) >
                          # non-const reference to Python immutable type - function could not be called > from Python
        , messages.W1014  # "operator*" is not supported. See
        , messages.W1016  # `Py++` does not exports non-const casting operators
        # Warnings 1020 - 1031 are all about why Py++ generates wrapper for class X
        , messages.W1023  # Py++` will generate class wrapper - there are few functions that should be
                          # redefined in class wrapper
        , messages.W1025  # `Py++` will generate class wrapper - class contains "c_" - T* > member variable
        , messages.W1026  # `Py++` will generate class wrapper - class contains "arr_" - T& > member variable
        , messages.W1027  # `Py++` will generate class wrapper - class contains "mat_" - > array member variable
        , messages.W1035  # error. `Py++` can not expose static pointer member variables.
        , messages.W1036  # error. `Py++` can not expose pointer to Python immutable > member variables. This
                          # could be changed in future.
        , messages.W1040  # error. The declaration is unexposed, but there are other > declarations, which
                          # refer to it. This could cause "no to_python converter > found" run
                          # time error
        # This is serious and lead to RuntimeError: `Py++` is going to write different content to the same file
        , messages.W1047 # There are two or more classes that use same > alias("MatElement"). Duplicated aliases causes
                         # few problems, but the main one > is that some of the classes will not
                         # be exposed to Python.Other classes : >
        , messages.W1049  # This method could not be overriden in Python - method returns >
                          # reference to local variable!
        , messages.W1052  # `Py++` will not expose free operator
    )

    logger.debug("Install SRC:  ", os.path.abspath(__file__))
    logger.debug("Execute from: ", os.getcwd())

    sourcedir = os.path.dirname(os.path.abspath(__file__))
    sourceHeader = os.path.abspath(sourcedir + "/" + r"pygimli.h")
    gimliInclude = os.path.dirname(
                         os.path.abspath(sourcedir + "/../src/" + r"gimli.h"))
    settings.includesPaths.append(gimliInclude)

    xml_cached_fc = parser.create_cached_source_fc(
        sourceHeader, settings.module_name + '.cache')

    import platform

    defines = ['PYGIMLI_CAST', 'HAVE_BOOST_THREAD_HPP']
    caster = 'gccxml'
    compiler_path = options.clang

    if platform.system() == 'Windows':
        if platform.architecture()[0] == '64bit':
            #compiler_path = 'C:/msys64/mingw64/bin/clang++'
            if sys.platform == 'darwin':
                pass
            else:
                defines.append('_WIN64')
                defines.append('MS_WIN64')

                logger.info('Marking win64 for gccxml')
        else:
            pass
            #compiler_path = 'C:/msys32/mingw32/bin/clang++'

    if len(compiler_path) == 0:
        compiler_path = None

    for define in [settings.gimli_defines, defined_symbols]:
        if len(define) > 0:
            defines.append(define)

    try:
        if sys.platform == 'win32':
            # os.name == 'nt' (default on my mingw)results in wrong commandline
            # for gccxml
            os.name = 'mingw'
            casterpath = settings.caster_path.replace('\\', '\\\\')
            casterpath = settings.caster_path.replace('/', '\\')

            if 'gccxml' not in casterpath:
                caster = 'castxml'

            if '.exe' not in casterpath:
                casterpath += '\\' + caster + '.exe'

        else:
            casterpath = settings.caster_path
            if 'gccxml' not in casterpath:
                caster = 'castxml'

    except Exception as e:
        logger.info("caster_path=%s" % casterpath)
        logger.info(str(e))
        raise Exception("Problems determine castxml binary")

    settings.includesPaths.insert(0, os.path.abspath(extraIncludes))

    logger.info("caster_path=%s" % casterpath)
    logger.info("working_directory=%s" % settings.gimli_path)
    logger.info("include_paths=%s" % settings.includesPaths)
    logger.info("define_symbols=%s" % defines)
    logger.info("compiler_path=%s" % compiler_path)
    logger.info("indexing_suite_version=2")

    xml_generator_config = parser.xml_generator_configuration_t(
                                        xml_generator=caster,
                                        xml_generator_path=casterpath,
                                        working_directory=settings.gimli_path,
                                        include_paths=settings.includesPaths,
                                        define_symbols=defines,
                                        ignore_gccxml_output=False,
                                        cflags="",
                                        compiler_path=compiler_path)

    mb = module_builder.module_builder_t(
                                [xml_cached_fc],
                                indexing_suite_version=2,
                                xml_generator_config=xml_generator_config
                                )

    logger.info("Reading of c++ sources done.")

    mb.classes().always_expose_using_scope = True
    mb.calldefs().create_with_signature = True

    global_ns = mb.global_ns
    global_ns.exclude()
    main_ns = global_ns.namespace(MAIN_NAMESPACE)
    main_ns.include()

    # for c in main_ns.free_functions():
    #   print(c)
    #   if 'pow' in c.name:
    #       print(c)
    #       print(c.name)
    #   if c.decl_string.startswith('::GIMLI::pow'):
    #       print(c)
    #       print(c.name)
    # sys.exit()

    logger.info("Apply handmade wrappers.")
    try:
        hand_made_wrappers.apply(mb)
    except BaseException as e:
        print(e)

    logger.info("Apply custom rvalues.")
    # START manual r-value converters
    rvalue_converters = [
        'register_pytuple_to_rvector3_conversion',
        'register_pysequence_to_rvector_conversion',
        # 'register_pysequence_to_bvector_conversion',
        'register_pysequence_to_indexvector_conversion',
        'register_pysequence_to_r3vector_conversion',
        'register_pysequence_to_StdVectorRVector3_conversion',
        # 'register_rvector_to_ndarray_conversion',
    ]

    for converter in rvalue_converters:
        mb.add_declaration_code('void %s();' % converter)
        mb.add_registration_code('%s();' % converter)

    # END manual r-value converters

    custom_rvalue_path = os.path.join(
        os.path.abspath(os.path.dirname(__file__)), 'custom_rvalue.cpp')

    logger.info("Starting to exclude stuff that we don't need "
                "or that is known to be spurious.")

    exclude(main_ns.variables,
            name=[
                'Triangle6_S1',
                'Triangle6_S2',
                'Triangle6_S3',
                'HexahedronFacesID',
                'Hexahedron20FacesID',
                'TetrahedronFacesID',
                'HexahedronSplit5TetID',
                'HexahedronSplit6TetID',
                'TriPrismFacesID',
                'TriPrimSplit3TetID',
                'NodeCoordinates',
                'EdgeCoordinates',
                'TriCoordinates',
                'QuadCoordinates',
                'TetCoordinates',
                'HexCoordinates',
                'PrismCoordinates',
                'PyramidCoordinates',
                'PyramidFacesID',
                'Tet10NodeSplit',
                'Tet10NodeSplitZienk',
                'Hex20NodeSplit',
                'Prism15NodeSplit',
                'Pyramid13NodeSplit'
                ]
            )

    exclude(main_ns.free_functions,
            return_type=[
                'float *',
                'float &',
                "::GIMLI::__VectorExpr< double, " +
                "GIMLI::__VectorUnaryExprOp< double, " +
                "GIMLI::VectorIterator< double >, GIMLI::ABS_ > >"],
            name=[
                'strReplaceBlankWithUnderscore',
                'toStr',
                'toInt',
                'toFloat',
                'toDouble',
                'str',
                'getRowSubstrings',
                'getNonEmptyRow',
                'getSubstrings',
                'abs',
                'type']
            )

    exclude(main_ns.free_operators,
            name=[''],
            return_type=['::std::ostream &', '::std::istream &']
            )

    exclude(main_ns.classes,
            name=['ABS_', 'ACOT', 'ATAN', 'COS', 'COT', 'EXP',
                  'ABS_', 'LOG', 'LOG10', 'SIGN', 'SIN', 'SQRT', 'SQR',
                  'TAN', 'TANH',
                  'PLUS', 'MINUS', 'MULT', 'DIVID', 'BINASSIGN', 'cerrPtr',
                  'cerrPtrObject', 'coutPtr', 'coutPtrObject', 'deletePtr',
                  'edge_',
                  'distancePair_', 'IPCMessage', 'PythonGILSave',
                  ]
            )

    exclude(main_ns.member_functions,
            name=['begin',
                  'end',
                  'val'],
            return_type=['']
            )

    exclude(main_ns.member_operators,
            symbol=[''])

    for f in main_ns.declarations:
        if isinstance(f, decl_wrappers.calldef_wrapper.free_function_t):
            if (str(f.return_type).find('GIMLI::VectorExpr') != -1):
                f.exclude()

    ex = ['::GIMLI::MatrixElement',
          '::GIMLI::__VectorUnaryExprOp',
          '::GIMLI::__VectorBinaryExprOp',
          '::GIMLI::__ValVectorExprOp',
          '::GIMLI::__VectorValExprOp',
          '::GIMLI::__VectorExpr',
          '::GIMLI::Expr',
          '::GIMLI::InversionBase',
          'GIMLI::MatrixElement',
          'GIMLI::__VectorUnaryExprOp',
          'GIMLI::__VectorBinaryExprOp',
          'GIMLI::__ValVectorExprOp',
          'GIMLI::__VectorValExprOp',
          'GIMLI::__VectorExpr',
          'GIMLI::Expr',
          'GIMLI::InversionBase',
          'std::vector<unsigned long',
          'std::vector<bool',
          'std::vector<double',
          ]

    for c in main_ns.free_functions():
        for e in ex:
            if c.decl_string.find(e) > -1:
                try:
                    c.exclude()
                    logger.debug("Exclude: " + str(c))
                except BaseException as _:
                    logger.debug("Fail to exclude: " + str(c))

    for c in main_ns.classes():
        for e in ex:
            if c.decl_string.startswith(e):
                try:
                    c.exclude()
                    logger.debug("Exclude: " + c.name)
                except BaseException as _:
                    logger.debug("Fail to exclude: " + c.name)

        try:
            for mem in c.variables():
                try:
                    mem.exclude()
                    # logger.info("Exclude: " + str(mem))
                except BaseException as _:
                    logger.debug("Fail to exclude: " + str(mem))
        except BaseException as _:
            # print(c, "has no member functions")
            pass

        try:
            for mem in c.constructors():
                for e in ex:
                    if mem.decl_string.find(e) > -1:
                        try:
                            mem.exclude()
                            # logger.info("Exclude: " + str(mem))
                        except BaseException as _:
                            logger.debug("Fail to exclude: " + str(mem))

            for mem in c.member_functions():
                for e in ex:
                    if mem.decl_string.find(e) > -1:
                        try:
                            mem.exclude()
                            # logger.info("Exclude: " + str(mem))
                        except BaseException as _:
                            logger.debug("Fail to exclude: " + str(mem))



        except BaseException as _:
            # print(c, "has no member functions")
            pass

        # print('#'*100)
        # print(c, c.name)
        if c.name.startswith('Vector<unsigned long>'):
            # print('         ', c.name)
            for mem in c.constructors():
                # print("mem", mem, mem.decl_string)
                if mem.decl_string.find('( ::GIMLI::Index )') > -1:
                    logger.debug("Exclude: " + str(mem))
                    mem.exclude()

                # print("mem", mem)

    try:
        mb.calldefs(access_type_matcher_t('protected')).exclude()
        mb.calldefs(access_type_matcher_t('private')).exclude()
    except BaseException as _:
        pass

    # setMemberFunctionCallPolicieByReturn(mb, [ '::GIMLI::Node &'
    # , '::GIMLI::Cell &'
    # , '::GIMLI::Boundary &'
    # , '::GIMLI::Shape &'
    # , '::GIMLI::Node *'
    # , '::GIMLI::Cell *'
    # , '::GIMLI::Boundary *'
    # , '::GIMLI::Shape *'
    # ]
    # , call_policies.reference_existing_object)

    setMemberFunctionCallPolicieByReturn(
        mb,
        ['::std::string *', 'float *', 'double *',
         'int *',
         'long *',
         'long int *',
         'long long int *',
         'unsigned int *',
         'long unsigned int *',
         'unsigned long long int *',
         'long long unsigned int *',
         '::GIMLI::Index *', '::GIMLI::SIndex *', 'bool *'],
        call_policies.return_pointee_value)

    setMemberFunctionCallPolicieByReturn(mb, ['::std::string &',
                                              'float &',
                                              'double &',
                                              'int &',
                                              'long &',
                                              'long int &',
                                              'long long int &',
                                              'unsigned int &',
                                              'long unsigned int &',
                                              'long long unsigned int &',
                                              'unsigned long long int &',
                                              '::GIMLI::Index &',
                                              '::GIMLI::SIndex &',
                                              'bool &'
                                              ], call_policies.return_by_value)

    # setMemberFunctionCallPolicieByReturn(mb,
    #                                   ['::GIMLI::VectorIterator<double> &']
    # , call_policies.copy_const_reference)
    # setMemberFunctionCallPolicieByReturn(mb, [
    # ,  'double &' ]
    # , call_policies.reference_existing_object)

    # call_policies.return_value_policy(call_policies.reference_existing_object)
    # call_policies.return_value_policy(call_policies.copy_non_const_reference)
    # call_policies.return_value_policy(call_policies.copy_const_reference)

    # addAutoConversions(mb)

    # excludeMemberByReturn(main_ns, ['::DCFEMLib::SparseMatrix<double> &'])
    # fun = mb.global_ns.member_functions('begin', allow_empty=True)
    # for f in fun:
    # f.exclude()

    # excludeFreeFunctionsByName(main_ns, ['strReplaceBlankWithUnderscore'
    # 'toStr', 'toInt', 'toFloat', 'toDouble',
    # 'getRowSubstrings', 'getNonEmptyRow', 'getSubstrings' ])

    # excludeFreeFunctionsByReturn(main_ns, [ 'float *', 'float &' ])
    # fun = ns.free_operators(return_type=funct, allow_empty=True)

    # excludeMemberOperators(main_ns, ['++', '--', '*'])

    # exclude all that does not match any predefined callpolicie

    excludeRest = True

    if excludeRest:
        mem_funs = mb.calldefs()

        for mem_fun in mem_funs:
            if mem_fun.call_policies:
                continue
            if not mem_fun.call_policies and \
                    (declarations.is_reference(mem_fun.return_type) or
                        declarations.is_pointer(mem_fun.return_type)):
                # print mem_fun
                # mem_fun.exclude()
                mem_fun.call_policies = call_policies.return_value_policy(
                    call_policies.reference_existing_object)
                # mem_fun.call_policies = \
                #    call_policies.return_value_policy(call_policies.return_pointee_value)
                # mem_fun.call_policies = \
                #    call_policies.return_value_policy(call_policies.return_opaque_pointer)
                # mem_fun.call_policies = \
                #   call_policies.return_value_policy(call_policies.copy_non_const_reference)

    logger.info("Create api documentation from Doxgen comments.")
    # Now it is the time to give a name to our module
    from doxygen import doxygen_doc_extractor
    extractor = doxygen_doc_extractor()

    logger.info("Create code creator.")
    mb.build_code_creator(settings.module_name, doc_extractor=extractor)

    # It is common requirement in software world-each file should have license
    # mb.code_creator.license = '//Boost Software
    # License(http://boost.org/more/license_info.html)'

    # I don't want absolute includes within code
    mb.code_creator.user_defined_directories.append(os.path.abspath('.'))

    # And finally we can write code to the disk
    def ignore(val):
        pass
    logger.info("Create bindings code.")
    mb.split_module('./generated', on_unused_file_found=ignore)

    additional_files = [
        os.path.join(
            os.path.abspath(os.path.dirname(__file__)), 'custom_rvalue.cpp'),
        os.path.join(
            os.path.abspath(os.path.dirname(__file__)), 'generators.h'),
        os.path.join(
            os.path.abspath(os.path.dirname(__file__)), 'tuples.hpp')]

    logger.info("Add additional files.")

    for sourcefile in additional_files:
        p, filename = os.path.split(sourcefile)
        destfile = os.path.join('./generated', filename)

        if not samefile(sourcefile, destfile):
            shutil.copy(sourcefile, './generated')
            logger.info("Updated " + filename +
                        "as it was missing or out of date")
Exemplo n.º 52
0
this_module_dir_path = os.path.abspath(
    os.path.dirname(sys.modules[__name__].__file__))
# Add pygccxml package to Python path
sys.path.append(os.path.join(this_module_dir_path, '..', '..'))


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)