def test(self):
        module_builder.set_logger_level( logging.CRITICAL )
        messages.disable( *messages.all_warning_msgs )

        ogre_file = autoconfig.data_directory.replace( 'pyplusplus_dev', 'pygccxml_dev' )
        ogre_file = parser.create_gccxml_fc( os.path.join( ogre_file, 'ogre.1.7.xml' ) )

        mb = module_builder.module_builder_t(
                [ ogre_file ]
                , gccxml_path=autoconfig.gccxml.executable
                , indexing_suite_version=2
                , compiler=pygccxml.utils.native_compiler.get_gccxml_compiler())

        mb.global_ns.exclude()
        mb.namespace('Ogre').include()

        x = mb.global_ns.decls( lambda d: 'Animation*' in d.name and 'MapIterator' in d.name )
        for y in x:
            print y.name
            print y.partial_name
            print declarations.full_name( y, with_defaults=False )

        target_dir = os.path.join( autoconfig.build_directory, 'ogre' )
        #~ if os.path.exists( target_dir ):
            #~ shutil.rmtree( target_dir )
        #~ os.mkdir( target_dir )

        mb.build_code_creator( 'Ogre3d' )
        mb.split_module( target_dir )
    def test(self):
        module_builder.set_logger_level( logging.CRITICAL )
        messages.disable( *messages.all_warning_msgs )

        xml_file = parser.create_gccxml_fc( os.path.join( autoconfig.data_directory, 'particleuniverse.xml' ) )

        mb = module_builder.module_builder_t(
                [ xml_file ]
                , gccxml_path=autoconfig.gccxml.executable
                , indexing_suite_version=2
                , compiler=pygccxml.utils.native_compiler.get_gccxml_compiler())

        mb.global_ns.exclude()
        mb.namespace('ParticleUniverse').include()
        mb.namespace('Ogre').include()
        mb.namespace('Ogre').classes().already_exposed = True

        target_dir = os.path.join( autoconfig.build_directory, 'particle_universe' )
        #~ if os.path.exists( target_dir ):
            #~ shutil.rmtree( target_dir )
        #~ os.mkdir( target_dir )
        psp = mb.class_( '::ParticleUniverse::ParticleScriptParser' )
        declarations.print_declarations( psp )
        mb.build_code_creator( 'PU' )
        mb.split_module( target_dir )
    def test(self):
        module_builder.set_logger_level( logging.CRITICAL )
        messages.disable( *messages.all_warning_msgs )

        ogre_file = autoconfig.data_directory.replace( 'pyplusplus_dev', 'pygccxml_dev' )
        ogre_file = parser.create_gccxml_fc( os.path.join( ogre_file, 'ogre.1.7.xml' ) )

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

        mb.global_ns.exclude()
        mb.namespace('Ogre').include()

        x = mb.global_ns.decls( lambda d: 'Animation*' in d.name and 'MapIterator' in d.name )
        for y in x:
            print(y.name)
            print(y.partial_name)
            print(declarations.full_name( y, with_defaults=False ))

        target_dir = os.path.join( autoconfig.build_directory, 'ogre' )
        #~ if os.path.exists( target_dir ):
            #~ shutil.rmtree( target_dir )
        #~ os.mkdir( target_dir )

        mb.build_code_creator( 'Ogre3d' )
        mb.split_module( target_dir )
Exemple #4
0
def generate():
    ### disable unnecessary warnings
    # py++ will create a wrapper
    messages.disable(messages.W1023, messages.W1025, messages.W1026, messages.W1027, messages.W1031)
    # can't be overridden in python
    messages.disable(messages.W1049)

    # "CEGUIBASE_EXPORTS" seems to help with internal compiler error with VS2008SP1 and gccxml 0.9
    mb = common_utils.createModuleBuilder("python_CEGUIOpenGLRenderer.h", ["OPENGL_GUIRENDERER_EXPORTS", "CEGUIBASE_EXPORTS"])
    CEGUI_ns = mb.global_ns.namespace("CEGUI")

    mb.register_module_dependency(cegui_base.OUTPUT_DIR)

    common_utils.addSupportForString(mb)

    filterDeclarations(mb)

    common_utils.setDefaultCallPolicies(CEGUI_ns)

    ## add additional version information to the module to help identify it correctly 
    # todo: this should be done automatically
    common_utils.addVersionInfo(mb, PACKAGE_NAME, PACKAGE_VERSION)

    # Creating code creator. After this step you should not modify/customize declarations.
    mb.build_code_creator(module_name = MODULE_NAME, doc_extractor = common_utils.createDocumentationExtractor())

    common_utils.writeModule(mb, OUTPUT_DIR)
Exemple #5
0
def generate():
    ### disable unnecessary warnings
    # py++ will create a wrapper
    messages.disable(messages.W1023, messages.W1025, messages.W1026, messages.W1027, messages.W1031)
    # can't be overridden in python
    messages.disable(messages.W1049)

    # "CEGUIBASE_EXPORTS" seems to help with internal compiler error with VS2008SP1 and gccxml 0.9
    mb = common_utils.createModuleBuilder("python_CEGUINullRenderer.h", ["NULL_GUIRENDERER_EXPORTS", "CEGUIBASE_EXPORTS"])
    CEGUI_ns = mb.global_ns.namespace("CEGUI")

    mb.register_module_dependency(cegui_base.OUTPUT_DIR)

    common_utils.addSupportForString(mb)

    filterDeclarations(mb)

    common_utils.setDefaultCallPolicies(CEGUI_ns)

    ## add additional version information to the module to help identify it correctly 
    common_utils.addVersionInfo(mb, PACKAGE_NAME, PACKAGE_VERSION)

    # Creating code creator. After this step you should not modify/customize declarations.
    mb.build_code_creator(module_name = MODULE_NAME, doc_extractor = common_utils.createDocumentationExtractor())

    common_utils.writeModule(mb, OUTPUT_DIR)
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")
Exemple #7
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)
import pyplusplus.code_repository.indexing_suite.pair_header
from pyplusplus import decl_wrappers
import pyplusplus.file_writers.multiple_files
from pyplusplus.function_transformers import templates
from pyplusplus.function_transformers import transformer
from pyplusplus.module_builder import call_policies
import pair_header_patch

####################################################################################################

startTime = time.clock()

####################################################################################################

# Da abilitare solo se necessario
messages.disable(messages.W1023)		# Py++ will generate class wrapper - there are few functions that should be redefined in class wrapper.
# Necessario per funzioni virtuali protette
messages.disable(messages.W1031)		# Py++ will generate class wrapper - user asked to expose non - public member function <name>
# Dalla versione 1.40 del boost i duplicati sono supportati
messages.disable(messages.W1032)		# Boost.Python library does not support enums with duplicate values
# Da abilitare solo se necessario
messages.disable(messages.W1041)		# Property <x> could not be created. There is another exposed declaration with the same name( alias )." The property will make it inaccessible.
# Some "declaration is unexposed" is a false warning.
messages.disable(messages.W1040)	  	# execution error W1040: The declaration is unexposed, but there are other declarations, which refer to it. This could cause "no to_python converter found" run time error. 

####################################################################################################

logger = utils._create_logger_(settings.module_name)

####################################################################################################
def generate_code():  
    messages.disable( 
# #           Warnings 1020 - 1031 are all about why Py++ generates wrapper for class X
          messages.W1020
        , messages.W1021
        , messages.W1022
        , messages.W1023
        , messages.W1024
        , messages.W1025
        , messages.W1026
        , messages.W1027
        , messages.W1028
        , messages.W1029
        , messages.W1030
        , messages.W1031
#         , messages.W1035
#         , messages.W1040 
#         , messages.W1038        
        , messages.W1041
        , messages.W1036 # pointer to Python immutable member
#         , messages.W1033 # unnamed variables
#         , messages.W1018 # expose unnamed classes
        , messages.W1049 # returns reference to local variable
        , messages.W1014 # unsupported '=' operator
         )
    #
    # Use GCCXML to create the controlling XML file.
    # If the cache file (../cache/*.xml) doesn't exist it gets created, otherwise it just gets loaded
    # NOTE: If you update the source library code you need to manually delete the cache .XML file   
    #
    xml_cached_fc = parser.create_cached_source_fc(
                        os.path.join( environment.opcode.root_dir, "python_opcode.h" )
                        , environment.opcode.cache_file )

    defined_symbols = ['OPCODE_EXPORTS'] #, 'ICE_NO_DLL'] #, 'OPC_USE_CALLBACKS' ]
    defined_symbols.append( 'VERSION_' + environment.opcode.version )  
    
    #
    # build the core Py++ system from the GCCXML created source
    #    
    mb = module_builder.module_builder_t( [ xml_cached_fc ]
                                          , gccxml_path=environment.gccxml_bin
                                          , working_directory=environment.root_dir
                                          , include_paths=environment.opcode.include_dirs
                                          , define_symbols=defined_symbols
                                          , indexing_suite_version=2
                                          , cflags=environment.ogre.cflags
                                           )
    # NOTE THE CHANGE HERE                                           
    mb.constructors().allow_implicit_conversion = False                                           
    
    mb.BOOST_PYTHON_MAX_ARITY = 25
    mb.classes().always_expose_using_scope = True
    
        
    #
    # We filter (both include and exclude) specific classes and functions that we want to wrap
    # 
    global_ns = mb.global_ns
    global_ns.exclude()
    for ns in NAMESPACES:
        main_ns = global_ns.namespace( ns )
        main_ns.include()
    
   
    AutoExclude ( mb )
    ManualExclude ( mb )
    AutoInclude ( mb )
    ManualInclude ( mb )
    # here we fixup functions that expect to modifiy their 'passed' variables    
    ManualTransformations ( mb )
    
    AutoFixes ( mb )
    ManualFixes ( mb )
            
    #
    # We need to tell boost how to handle calling (and returning from) certain functions
    #
    for ns in NAMESPACES:
        Set_Call_Policies ( mb.global_ns.namespace (ns) )
    
#IceMaths::Quat IceMaths::Matrix3x3::operator ::IceMaths::Quat() const [casting operator]
    c = mb.global_ns.namespace ( 'IceMaths').class_('Matrix3x3')
    for o in c.operators():
#         print o
#         print dir(o)
#         print o.partial_decl_string
#         print o.name
        if 'Quat' in o.partial_decl_string:
            o.exclude()
            print "Excluded Op", o, "\n", o.partial_decl_string
##  OP float const * IceMaths::Point::operator float const *() const [casting operator]
    c = mb.global_ns.namespace ( 'IceMaths').class_('Point')
    for o in c.operators():
        if 'float const *' in o.partial_decl_string:
            o.exclude()
            print "Excluded Op", o, "\n", o.partial_decl_string
    ##Spere(udword nb_verts, const Point* verts);  Not Implemented
    c = mb.global_ns.namespace ( 'IceMaths').class_('Sphere')
    for o in c.constructors(arg_types=("::udword","::IceMaths::Point const *") ):
        o.exclude()
    c = mb.global_ns.namespace ( 'IceMaths').class_('Matrix4x4')
    for o in c.constructors():
        if len (o.arguments) > 10:
            o.exclude()
    for o in c.member_functions():
        if len (o.arguments) > 10:
            print "Too Many Arguments - excluded:", o, o.partial_decl_string
            o.exclude()
    c = mb.global_ns.namespace ( 'IceMaths').class_('Matrix4x4')
    for o in c.casting_operators():
        rett = o.return_type.decl_string
        if 'Quat' in rett or 'PR' in rett:
            o.exclude()
            print "Excluded Op", o
             
    #
    # the manual stuff all done here !!!
    #
    hand_made_wrappers.apply( mb )

    NoPropClasses = [""]
    for ns in NAMESPACES:
        main_ns = global_ns.namespace( ns )
        for cls in main_ns.classes():
            if cls.name not in NoPropClasses:
                cls.add_properties( recognizer=ogre_properties.ogre_property_recognizer_t() )
            
    ## add additional version information to the module to help identify it correctly 
    common_utils.addDetailVersion ( mb, environment, environment.opcode )

    ##########################################################################################
    #
    # Creating the code. After this step you should not modify/customize declarations.
    #
    ##########################################################################################
    extractor = exdoc.doc_extractor("") # I'm excluding the UTFstring docs as lots about nothing 
    mb.build_code_creator (module_name='_opcode_' , doc_extractor= extractor )
    
    for inc in environment.opcode.include_dirs:
        mb.code_creator.user_defined_directories.append(inc )
    mb.code_creator.user_defined_directories.append( environment.opcode.generated_dir )
    mb.code_creator.replace_included_headers( customization_data.header_files( environment.opcode.version ) )

    huge_classes = map( mb.class_, customization_data.huge_classes( environment.opcode.version ) )

    mb.split_module(environment.opcode.generated_dir, huge_classes)

    ## now we need to ensure a series of headers and additional source files are
    ## copied to the generaated directory..
    additional_dirs=[
                    [environment.Config.PATH_OPCODE ,''],
                    [os.path.join(environment.Config.PATH_OPCODE, 'Ice'),'Ice'],
                    [os.path.join(environment.Config.PATH_OPCODE, 'Ice'),''],  ## double copy to make the compile work..
                    ]
    for d,d1 in additional_dirs:
        for f in os.listdir(d):
            if f.endswith('cpp') or f.endswith('.h') or f.endswith('.c'):
                sourcefile = os.path.join(d, f)
                destfile = os.path.join(environment.opcode.generated_dir, d1,  f ) 
                if not os.path.exists ( os.path.join(environment.opcode.generated_dir, d1 ) ):
                    os.mkdir ( os.path.join(environment.opcode.generated_dir, d1 ) )
                if not common_utils.samefile( sourcefile ,destfile ):
                    shutil.copy( sourcefile, environment.opcode.generated_dir )
                    print "Updated ", f, "as it was missing or out of date"
def generate_code():  
    messages.disable( 
#           Warnings 1020 - 1031 are all about why Py++ generates wrapper for class X
          messages.W1020
        , messages.W1021
        , messages.W1022
        , messages.W1023
        , messages.W1024
        , messages.W1025
        , messages.W1026
        , messages.W1027
        , messages.W1028
        , messages.W1029
        , messages.W1030
        , messages.W1031
        , messages.W1035
        , messages.W1040 
        , messages.W1038 
        , messages.W1039       
        , messages.W1041
        , messages.W1036 # pointer to Python immutable member
        , messages.W1033 # unnamed variables
        , messages.W1018 # expose unnamed classes
        , messages.W1049 # returns reference to local variable
        , messages.W1014 # unsupported '=' operator
         )
    #
    # Use GCCXML to create the controlling XML file.
    # If the cache file (../cache/*.xml) doesn't exist it gets created, otherwise it just gets loaded
    # NOTE: If you update the source library code you need to manually delete the cache .XML file   
    #
    xml_cached_fc = parser.create_cached_source_fc(
                        os.path.join( environment.ogredshow.root_dir, "python_ogredshow.h" )
                        , environment.ogredshow.cache_file )

    defined_symbols = [ 'ogredshow_EXPORTS','OGRE_NONCLIENT_BUILD', 'OGRE_GCC_VISIBILITY']
    if environment._USE_THREADS:
        defined_symbols.append('BOOST_HAS_THREADS')
        defined_symbols.append('BOOST_HAS_WINTHREADS')
    defined_symbols.append( 'VERSION_' + environment.ogredshow.version )  
    
    undefined_symbols = []
    #
    # build the core Py++ system from the GCCXML created source
    #    
    mb = module_builder.module_builder_t( [ xml_cached_fc ]
                                          , gccxml_path=environment.gccxml_bin
                                          , working_directory=environment.root_dir
                                          , include_paths=environment.ogredshow.include_dirs
                                          , define_symbols=defined_symbols
# #                                           , undefine_symbols = undefined_symbols
                                          , indexing_suite_version=2
                                          , cflags=environment.ogredshow.cflags
                                           )
    # NOTE THE CHANGE HERE                                           
    mb.constructors().allow_implicit_conversion = False                                           
    mb.register_module_dependency ( environment.ogre.generated_dir )

    mb.BOOST_PYTHON_MAX_ARITY = 25
    mb.classes().always_expose_using_scope = True
    
        
    #
    # We filter (both include and exclude) specific classes and functions that we want to wrap
    # 
    global_ns = mb.global_ns
    global_ns.exclude()
    main_ns = global_ns.namespace( MAIN_NAMESPACE )
    main_ns.include()
    
   
    AutoExclude ( mb )
    ManualExclude ( mb )
    AutoInclude ( mb )
    ManualInclude ( mb )
    # here we fixup functions that expect to modifiy their 'passed' variables    
    ManualTransformations ( mb )
    
    AutoFixes ( mb )
    ManualFixes ( mb )
            
    #
    # We need to tell boost how to handle calling (and returning from) certain functions
    #
    Set_Call_Policies ( mb.global_ns.namespace (MAIN_NAMESPACE) )
    
    #
    # the manual stuff all done here !!!
    #
    hand_made_wrappers.apply( mb )

    NoPropClasses = [""]
    for cls in main_ns.classes():
        if cls.name not in NoPropClasses:
            cls.add_properties( recognizer=ogre_properties.ogre_property_recognizer_t() )
            
    ## add additional version information to the module to help identify it correctly 
    common_utils.addDetailVersion ( mb, environment, environment.ogredshow )

    ##########################################################################################
    #
    # Creating the code. After this step you should not modify/customize declarations.
    #
    ##########################################################################################
    extractor = exdoc.doc_extractor("") # I'm excluding the UTFstring docs as lots about nothing 
    mb.build_code_creator (module_name='_ogredshow_' , doc_extractor= extractor )
    
    for inc in environment.ogredshow.include_dirs:
        mb.code_creator.user_defined_directories.append(inc )
    mb.code_creator.user_defined_directories.append( environment.ogredshow.generated_dir )
    mb.code_creator.replace_included_headers( customization_data.header_files( environment.ogredshow.version ) )

    huge_classes = map( mb.class_, customization_data.huge_classes( environment.ogredshow.version ) )

    mb.split_module(environment.ogredshow.generated_dir, huge_classes,use_files_sum_repository=False)

    ## now we need to ensure a series of headers and additional source files are
    ## copied to the generaated directory..
    additional_files=[]
    paths = [environment.Config.PATH_INCLUDE_ogredshow]

    for p in paths:
        additional_files = os.listdir(p)
        for f in additional_files:
            if f.endswith('cpp') or f.endswith('.h'):
                sourcefile = os.path.join(p, f)
                destfile = os.path.join(environment.ogredshow.generated_dir, f ) 
        
                if not common_utils.samefile( sourcefile ,destfile ):
                    shutil.copy( sourcefile, environment.ogredshow.generated_dir )
                    print "Updated ", f, "as it was missing or out of date"
def generate_code():  
    messages.disable( 
#           Warnings 1020 - 1031 are all about why Py++ generates wrapper for class X
          messages.W1020
        , messages.W1021
        , messages.W1022
        , messages.W1023
        , messages.W1024
        , messages.W1025
        , messages.W1026
        , messages.W1027
        , messages.W1028
        , messages.W1029
        , messages.W1030
        , messages.W1031
#         , messages.W1035
#         , messages.W1040 
#         , messages.W1038 
#         , messages.W1039       
#         , messages.W1041
        , messages.W1036 # pointer to Python immutable member
        , messages.W1033 # unnamed variables
        , messages.W1018 # expose unnamed classes
        , messages.W1049 # returns reference to local variable
        , messages.W1014 # unsupported '=' operator
         )
    #
    # Use GCCXML to create the controlling XML file.
    # If the cache file (../cache/*.xml) doesn't exist it gets created, otherwise it just gets loaded
    # NOTE: If you update the source library code you need to manually delete the cache .XML file   
    #
    xml_cached_fc = parser.create_cached_source_fc(
                        os.path.join( environment.nxogre.root_dir, "python_nxogre.h" )
                        , environment.nxogre.cache_file )
    if os.name == 'nt':
        defined_symbols = [ '__PYTHONOGRE_BUILD_CODE','OGRE_NONCLIENT_BUILD', 'OGRE_GCC_VISIBILITY', 'WIN32', 'GCC_XML','NXOGRE_EXPORTS']
    else:
        defined_symbols = [ '__PYTHONOGRE_BUILD_CODE','LINUX','NX_LINUX', 'NX_DISABLE_FLUIDS', 'OGRE_NONCLIENT_BUILD', 'OGRE_GCC_VISIBILITY', 'GCC_XML']

    if environment._USE_THREADS:
        defined_symbols.append('BOOST_HAS_THREADS')
        defined_symbols.append('BOOST_HAS_WINTHREADS')
    defined_symbols.append( 'VERSION_' + environment.nxogre.version )  
    
    undefined_symbols = []
    #
    # build the core Py++ system from the GCCXML created source
    #    
    mb = module_builder.module_builder_t( [ xml_cached_fc ]
                                          , gccxml_path=environment.gccxml_bin
                                          , working_directory=environment.root_dir
                                          , include_paths=environment.nxogre.include_dirs
                                          , define_symbols=defined_symbols
# #                                           , undefine_symbols = undefined_symbols
                                          , indexing_suite_version=2
                                          , cflags=environment.ogre.cflags
                                           )
    # NOTE THE CHANGE HERE                                           
    mb.constructors().allow_implicit_conversion = False                                           
    ## This module depends on Ogre and physx
    mb.register_module_dependency ( environment.ogre.generated_dir )
    mb.register_module_dependency ( environment.physx.generated_dir )

    mb.BOOST_PYTHON_MAX_ARITY = 25
    mb.classes().always_expose_using_scope = True
    
        
    #
    # We filter (both include and exclude) specific classes and functions that we want to wrap
    # 
    global_ns = mb.global_ns
    global_ns.exclude()
    main_ns = global_ns.namespace( MAIN_NAMESPACE )
    main_ns.include()
    
   
    AutoExclude ( mb )
    ManualExclude ( mb )
    AutoInclude ( mb )
    ManualInclude ( mb )
    # here we fixup functions that expect to modifiy their 'passed' variables    
    common_utils.Auto_Functional_Transformation ( main_ns )  #, special_vars=['::Ogre::Real &','::Ogre::ushort &','size_t &'] )
    ManualTransformations ( mb )
    
    AutoFixes ( mb )
    ManualFixes ( mb )
            
    #
    # We need to tell boost how to handle calling (and returning from) certain functions
    #
    Set_Call_Policies ( mb.global_ns.namespace (MAIN_NAMESPACE) )
    
# #     for op in main_ns.operators():
# #         print "op1", op
# # #         if op.allow_implicit_conversion:
# # #             print "Implicit conversion on operator ", op
# #     print dir(op)
# #     for op in main_ns.constructors():
# #         print "con1", op
# #         if op.allow_implicit_conversion:
# #             print "Implicit conversion on constructor ", op
# #     print dir(op)            
# #     for op in main_ns.free_operators():
# #         print "op2", op
# # #         if op.allow_implicit_conversion:
# # #             print "Implicit conversion on free operator ", op
# #     print dir(op)
            
    #
    # the manual stuff all done here !!!
    #
    hand_made_wrappers.apply( mb )

    NoPropClasses = [""]
    for cls in main_ns.classes():
        if cls.name not in NoPropClasses:
            cls.add_properties( recognizer=ogre_properties.ogre_property_recognizer_t() )
            
    ## add additional version information to the module to help identify it correctly 
    common_utils.addDetailVersion ( mb, environment, environment.nxogre )
    
    
    ##########################################################################################
    #
    # Creating the code. After this step you should not modify/customize declarations.
    #
    ##########################################################################################
    extractor = exdoc.doc_extractor("") # I'm excluding the UTFstring docs as lots about nothing 
    mb.build_code_creator (module_name='_nxogre_' , doc_extractor= extractor )
    
    for inc in environment.nxogre.include_dirs:
        mb.code_creator.user_defined_directories.append(inc )
    mb.code_creator.user_defined_directories.append( environment.nxogre.generated_dir )
    mb.code_creator.replace_included_headers( customization_data.header_files( environment.nxogre.version ) )

    huge_classes = map( mb.class_, customization_data.huge_classes( environment.nxogre.version ) )

    mb.split_module(environment.nxogre.generated_dir, huge_classes,use_files_sum_repository=False)

    ## now we need to ensure a series of headers and additional source files are
    ## copied to the generaated directory..
    common_utils.copyTree ( sourcePath = environment.Config.PATH_NxOgre, 
                            destPath = environment.nxogre.generated_dir, 
                            recursive=False )
def generate_code():  
    messages.disable( 
#           Warnings 1020 - 1031 are all about why Py++ generates wrapper for class X
          messages.W1020
        , messages.W1021
        , messages.W1022
        , messages.W1023
        , messages.W1024
        , messages.W1025
        , messages.W1026
        , messages.W1027
        , messages.W1028
        , messages.W1029
        , messages.W1030
        , messages.W1031
#         , messages.W1035
#         , messages.W1040 
#         , messages.W1038        
#         , messages.W1041
        , messages.W1036 # pointer to Python immutable member
        , messages.W1033 # unnamed variables
        , messages.W1018 # expose unnamed classes
        , messages.W1049 # returns reference to local variable
        , messages.W1014 # unsupported '=' operator
         )
    #
    # Use GCCXML to create the controlling XML file.
    # If the cache file (../cache/*.xml) doesn't exist it gets created, otherwise it just gets loaded
    # NOTE: If you update the source library code you need to manually delete the cache .XML file   
    #
    xml_cached_fc = parser.create_cached_source_fc(
                        os.path.join( environment.bullet.root_dir, "python_bullet.h" )
                        , environment.bullet.cache_file )

    defined_symbols = [ 'BULLET_EXPORTS', '__GCCXML__', '_MSC_VER',
                        '__MINGW32__'   # needed to turn off allocator allignment which boost can't do..
                        
                        ]
    defined_symbols.append( 'VERSION_' + environment.bullet.version )  
    if sys.platform.startswith ( 'linux' ):
        defined_symbols.append('USE_PTHREADS')
    
    #
    # build the core Py++ system from the GCCXML created source
    #    
    mb = module_builder.module_builder_t( [ xml_cached_fc ]
                                          , gccxml_path=environment.gccxml_bin
                                          , working_directory=environment.root_dir
                                          , include_paths=environment.bullet.include_dirs
                                          , define_symbols=defined_symbols
                                          , indexing_suite_version=2
                                          , cflags=environment.bullet.cflags
                                           )
                                           
    # if this module depends on another set it here                                           
    ## mb.register_module_dependency ( environment.ogre.generated_dir )
    
    # normally implicit conversions work OK, however they can cause strange things to happen so safer to leave off
    mb.constructors().allow_implicit_conversion = False                                           
    
    mb.BOOST_PYTHON_MAX_ARITY = 25
    mb.classes().always_expose_using_scope = True
            
    #
    # We filter (both include and exclude) specific classes and functions that we want to wrap
    # 
    global_ns = mb.global_ns
    global_ns.exclude()
    
    if MAIN_NAMESPACE == "" :
        main_ns = global_ns
        main_ns.include()
    else:
        main_ns = global_ns.namespace( MAIN_NAMESPACE )
        main_ns.exclude ()
    
    AutoInclude ( mb, MAIN_NAMESPACE ) ## note we use our own version, not common_utils
    common_utils.AutoExclude ( mb, MAIN_NAMESPACE )
    ManualInclude ( mb )
    # here we fixup functions that expect to modifiy their 'passed' variables    
    ManualTransformations ( mb )
    AutoFixes ( mb, MAIN_NAMESPACE )
    
    #
    # We need to tell boost how to handle calling (and returning from) certain functions
    # Do this earlier than normal as I need to override the default in ManualFixes
    common_utils.Set_DefaultCall_Policies ( main_ns )
    
    ManualFixes ( mb )
    ManualExclude ( mb )
    common_utils.Auto_Functional_Transformation ( main_ns ,special_vars=['btScalar *'] )
    
    
    #
    # the manual stuff all done here !!!
    #
    hand_made_wrappers.apply( mb )

    NoPropClasses = [""]
    for cls in main_ns.classes():
        if cls.name not in NoPropClasses:
            rec = ogre_properties.ogre_property_recognizer_t()
            rec.addSetterType ( 'btScalar' ) # this type is a 'float/double' however we need to tell py++ such so it creates setters
            cls.add_properties( recognizer=rec )
            
    common_utils.Auto_Document( mb, MAIN_NAMESPACE )
            
    ## add additional version information to the module to help identify it correctly 
    common_utils.addDetailVersion ( mb, environment, environment.bullet )

    mem_fun = main_ns.member_function('::btVector3::setX')
    ##print "setter:", property_recognizer_i  (mem_fun)
    if len( mem_fun.arguments ) != 1:
        print 'False1'
    if not declarations.is_void( mem_fun.return_type ):
        print 'False2'
    if mem_fun.has_const:
        print 'False3'
    if mem_fun.overloads:
        print 'False4' 
    print "OK"
            
    ##########################################################################################
    #
    # Creating the code. After this step you should not modify/customize declarations.
    #
    ##########################################################################################
# #     extractor = exdoc.doc_extractor( "Ogre" ) 
# #     mb.build_code_creator (module_name='_ogre_' , doc_extractor= extractor )

    extractor = exdoc.doc_extractor() # I'm excluding the UTFstring docs as lots about nothing 
    mb.build_code_creator (module_name='_bullet_' , doc_extractor= extractor )
    
    for inc in environment.bullet.include_dirs:
        mb.code_creator.user_defined_directories.append(inc )
    mb.code_creator.user_defined_directories.append( environment.bullet.generated_dir )
    mb.code_creator.replace_included_headers( customization_data.header_files( environment.bullet.version ) )

    huge_classes = map( mb.class_, customization_data.huge_classes( environment.bullet.version ) )

    mb.split_module(environment.bullet.generated_dir, huge_classes, use_files_sum_repository=False)

    ## now we need to ensure a series of headers and additional source files are
    ## copied to the generaated directory..
    additional_files=[
            os.path.join( os.path.abspath(os.path.dirname(__file__) ), 'python_bullet_masterlist.h' )	    
            ]
    if environment.isLinux(): #sBulletDNAlen is defined in the cpp file not the header!! 
       additional_files.append ( os.path.join( environment.Config.PATH_Bullet, 'src', 'LinearMath','btSerializer.cpp' ) )
    for sourcefile in additional_files:
        p,filename = os.path.split(sourcefile)
        destfile = os.path.join(environment.bullet.generated_dir, filename )

        if not common_utils.samefile( sourcefile ,destfile ):
            shutil.copy( sourcefile, environment.bullet.generated_dir )
            print "Updated ", filename, "as it was missing or out of date"
def generate_code():  
    messages.disable( 
#           Warnings 1020 - 1031 are all about why Py++ generates wrapper for class X
          messages.W1020
        , messages.W1021
        , messages.W1022
        , messages.W1023
        , messages.W1024
        , messages.W1025
        , messages.W1026
        , messages.W1027
        , messages.W1028
        , messages.W1029
        , messages.W1030
        , messages.W1031
# # #         , messages.W1035
# # #         , messages.W1040 
# # #         , messages.W1038        
# # #         , messages.W1041
# # #         , messages.W1036 # pointer to Python immutable member
# # #         , messages.W1033 # unnamed variables
# # #         , messages.W1018 # expose unnamed classes
# # #         , messages.W1049 # returns reference to local variable
# # #         , messages.W1014 # unsupported '=' operator
         )
    #
    # Use GCCXML to create the controlling XML file.
    # If the cache file (../cache/*.xml) doesn't exist it gets created, otherwise it just gets loaded
    # NOTE: If you update the source library code you need to manually delete the cache .XML file   
    #
    xml_cached_fc = parser.create_cached_source_fc(
                        os.path.join( environment.noise.root_dir, "python_noise.h" )
                        , environment.noise.cache_file )


    defined_symbols = [ 'OGRE_NONCLIENT_BUILD','__PYTHONOGRE_BUILD_CODE' ]
    if environment._USE_THREADS:
        defined_symbols.append('BOOST_HAS_THREADS')
        defined_symbols.append('BOOST_HAS_WINTHREADS')

    defined_symbols.append( 'VERSION_' + environment.noise.version )  
    
    #
    # build the core Py++ system from the GCCXML created source
    #    
    mb = module_builder.module_builder_t( [ xml_cached_fc ]
                                          , gccxml_path=environment.gccxml_bin
                                          , working_directory=environment.root_dir
                                          , include_paths=environment.noise.include_dirs
                                          , define_symbols=defined_symbols
                                          , indexing_suite_version=2
                                          , cflags=environment.noise.cflags
                                           )
    # NOTE THE CHANGE HERE                                           
    mb.constructors().allow_implicit_conversion = False
    
    mb.BOOST_PYTHON_MAX_ARITY = 25
    mb.classes().always_expose_using_scope = True


    global_ns = mb.global_ns
    global_ns.exclude()

    for n in mb.global_ns.namespaces():
        print n._name

    namespaces = ['noise', 'utils', 'model', 'module']
    for n in namespaces:
        global_ns.namespace(n).include()
        common_utils.AutoExclude ( mb, n )

    ## Manual Excludes 
    global_ns.mem_fun('::noise::module::Terrace::GetControlPointArray').exclude()

    ## These generate "<<protected declaration>>\n" and compile fails
    global_ns.mem_fun('::noise::module::Curve::FindInsertionPos').exclude()
    global_ns.mem_fun('::noise::module::Curve::InsertAtPos').exclude()
    global_ns.mem_fun('::noise::module::RidgedMulti::CalcSpectralWeights').exclude()
    global_ns.mem_fun('::noise::module::Terrace::FindInsertionPos').exclude()
    global_ns.mem_fun('::noise::module::Terrace::InsertAtPos').exclude()
    global_ns.mem_fun('::noise::utils::WriterBMP::CalcWidthByteCount').exclude()
    global_ns.mem_fun('::noise::utils::WriterTER::CalcWidthByteCount').exclude()

    for n in namespaces:
        common_utils.AutoInclude ( mb, n)

    ManualInclude ( mb )
    # here we fixup functions that expect to modifiy their 'passed' variables    
    ManualTransformations ( mb )
    
    for n in namespaces:
        AutoFixes ( mb, n )

    ManualFixes ( mb )
    
    ## namespaces 
    namespaces = ['noise', 'model' , 'module', 'utils']

    #
    # We need to tell boost how to handle calling (and returning from) certain functions
    #
    for ns in namespaces:
        common_utils.Set_DefaultCall_Policies (mb.global_ns.namespace(ns))
        common_utils.Auto_Functional_Transformation ( mb.global_ns.namespace(ns) )

    
    
    #
    # the manual stuff all done here !!!
    #
    hand_made_wrappers.apply( mb )

    ## add properties to the 4 namespaces, in a conservative fashion
    for ns in namespaces:
        for cls in mb.global_ns.namespace(ns).classes():
            cls.add_properties( recognizer=ogre_properties.ogre_property_recognizer_t() )
                                          
    ## add additional version information to the module to help identify it correctly 
    common_utils.addDetailVersion ( mb, environment, environment.noise )

   
    ##########################################################################################
    #
    # Creating the code. After this step you should not modify/customize declarations.
    #
    ##########################################################################################
    extractor = exdoc.doc_extractor() # I'm excluding the UTFstring docs as lots about nothing 
    mb.build_code_creator (module_name='_noise_' , doc_extractor= extractor )
    
    for inc in environment.noise.include_dirs:
        mb.code_creator.user_defined_directories.append(inc )
    mb.code_creator.user_defined_directories.append( environment.noise.generated_dir )
    mb.code_creator.replace_included_headers( customization_data.header_files( environment.noise.version ) )

    huge_classes = map( mb.class_, customization_data.huge_classes( environment.noise.version ) )

    mb.split_module(environment.noise.generated_dir, huge_classes, use_files_sum_repository=False)

    ## now we need to ensure a series of headers and additional source files are
    ## copied to the generated directory..
    common_utils.copyTree ( sourcePath = environment.Config.PATH_noise, 
                            destPath = environment.noise.generated_dir, 
                            recursive=False )
Exemple #14
0
# The paths that cmake substitutues in the code_generator_t constructor might
# contain Unicode characters.
# coding: utf-8

import logging
from os.path import exists, join, isdir
from os import getenv
import subprocess
from sys import platform
from pygccxml import declarations
from pyplusplus import module_builder, messages
from pyplusplus.module_builder import call_policies
from pyplusplus.decl_wrappers import print_declarations

# disable some warnings that are mostly harmless
messages.disable( messages.W1014 )
messages.disable( messages.W1023 )
messages.disable( messages.W1040 )

# create a dictionary called "default_replacement" that can be used to replace method
# declaration with another method. The dictionary is indexed by method name,
# either with or without full scope. For each method there is a 2-tuple. The
# first component is a string that tells Boost.Python how to export the
# replacement method. The second component is a string that contains the C++
# code for the replacement method.
default_replacement = {}
# A C++ call like "foo.print(std::cout)" will be replaced with something more
# pythonesque using the special __str__ method: "print(foo)"
default_replacement['print'] = ('def("__str__", &__str__)', """
std::string __str__(%s* obj)
{
Exemple #15
0
    for c in ns.classes(_filter, allow_empty=True):
        classes.add_numpy_construtor(c)
        for b in c.bases:
            b.related_class.exclude()


# FIXME: fix py++ to include our headers before boost python headers
wrap = Wrapper(license='#include "pyhalbe.h"')
module_name = wrap.module_name()
mb = wrap.mb
ns_util = NamespaceUtil()

# Less noise
ns_util.log.setLevel(logging.WARN)
classes.log.setLevel(logging.WARN)
messages.disable(messages.W1043)  # Ugly names, who cares? ...
messages.disable(messages.W1066)  # Not exposed typedefs

# Collect namespaces
ns_hmf = mb.namespace("::HMF")
ns_hmf_hicann = mb.namespace("::HMF::HICANN")
ns_coordinate = mb.namespace("::HMF::Coordinate")
ns_realtime = mb.namespace("::Realtime")
included_ns = [ns_hmf, ns_realtime]

for ns in ['::boost::serialization', '::boost::archive', '::boost::mpi']:
    try:
        mb.namespace(ns).exclude()
    except matchers.declaration_not_found_t:
        pass
def generate_code():  
    messages.disable( 
# # #           Warnings 1020 - 1031 are all about why Py++ generates wrapper for class X
          messages.W1020
        , messages.W1021
        , messages.W1022
        , messages.W1023
        , messages.W1024
        , messages.W1025
        , messages.W1026
        , messages.W1027
        , messages.W1028
        , messages.W1029
        , messages.W1030
        , messages.W1031
# #         , messages.W1035
# #         , messages.W1040 
# #         , messages.W1038        
#         , messages.W1041
        , messages.W1036 # pointer to Python immutable member
# #         , messages.W1033 # unnamed variables
# #         , messages.W1018 # expose unnamed classes
        , messages.W1049 # returns reference to local variable
#         , messages.W1014 # unsupported '=' operator
         )
    #
    # Use GCCXML to create the controlling XML file.
    # If the cache file (../cache/*.xml) doesn't exist it gets created, otherwise it just gets loaded
    # NOTE: If you update the source library code you need to manually delete the cache .XML file   
    #
    xml_cached_fc = parser.create_cached_source_fc(
                        os.path.join( environment.bullet.root_dir, "python_bullet.h" )
                        , environment.bullet.cache_file )

    defined_symbols =  ['BULLET_EXPORTS'] #
    defined_symbols.append( 'VERSION_' + environment.bullet.version )  
    
    #
    # build the core Py++ system from the GCCXML created source
    #    
    mb = module_builder.module_builder_t( [ xml_cached_fc ]
                                          , gccxml_path=environment.gccxml_bin
                                          , working_directory=environment.root_dir
                                          , include_paths=environment.bullet.include_dirs
                                          , define_symbols=defined_symbols
                                          , indexing_suite_version=2
                                          , cflags=environment.bullet.cflags
                                           )
    # NOTE THE CHANGE HERE                                           
    mb.constructors().allow_implicit_conversion = False                                           
    
    mb.BOOST_PYTHON_MAX_ARITY = 25
    mb.classes().always_expose_using_scope = True
    
        
    #
    # We filter (both include and exclude) specific classes and functions that we want to wrap
    # 
    global_ns = mb.global_ns
    global_ns.exclude()
    AutoInclude ( mb )
    
   
    AutoExclude ( mb )
    ManualExclude ( mb )
    ManualInclude ( mb )
    # here we fixup functions that expect to modifiy their 'passed' variables    
    ManualTransformations ( mb )
    
    AutoFixes ( mb )
    ManualFixes ( mb )
            
    #
    # We need to tell boost how to handle calling (and returning from) certain functions
    #
    Set_Call_Policies ( mb.global_ns )
    
    #
    # the manual stuff all done here !!!
    #
    hand_made_wrappers.apply( mb )

    NoPropClasses = [""]
    main_ns = global_ns
#     for cls in main_ns.classes():
#         if cls.name not in NoPropClasses:
#             cls.add_properties( recognizer=ogre_properties.ogre_property_recognizer_t() )
            
    common_utils.add_constants( mb, { 'bullet_version' :  '"%s"' % environment.bullet.version.replace("\n", "\\\n") 
                                      , 'python_version' : '"%s"' % sys.version.replace("\n", "\\\n" ) } )
                                      
    ## need to create a welcome doc string for this...                                  
    common_utils.add_constants( mb, { '__doc__' :  '"bullet DESCRIPTION"' } ) 
    
    
    ##########################################################################################
    #
    # Creating the code. After this step you should not modify/customize declarations.
    #
    ##########################################################################################
    extractor = exdoc.doc_extractor("") # I'm excluding the UTFstring docs as lots about nothing 
    mb.build_code_creator (module_name='_bullet_' , doc_extractor= extractor )
    
    for inc in environment.bullet.include_dirs:
        mb.code_creator.user_defined_directories.append(inc )
    mb.code_creator.user_defined_directories.append( environment.bullet.generated_dir )
    mb.code_creator.replace_included_headers( customization_data.header_files( environment.bullet.version ) )

    huge_classes = map( mb.class_, customization_data.huge_classes( environment.bullet.version ) )

    mb.split_module(environment.bullet.generated_dir, huge_classes, use_files_sum_repository=False)
def generate():
    ### disable unnecessary warnings
    # can't pass function pointer
    messages.disable(messages.W1004)
    # operator not supported
    messages.disable(messages.W1014)
    # py++ will create a wrapper
    messages.disable(messages.W1023, messages.W1025, messages.W1026,
                     messages.W1027, messages.W1031)
    # static pointer member can't be exported
    messages.disable(messages.W1035)
    # immutable pointer can't be exposed
    messages.disable(messages.W1036)
    # pointer to function can't be exposed
    messages.disable(messages.W1036, messages.W1037)
    # can't be overridden in python
    messages.disable(messages.W1049)

    mb = common_utils.createModuleBuilder("python_CEGUI.h",
                                          ["CEGUIBASE_EXPORTS"])
    CEGUI_ns = mb.global_ns.namespace("CEGUI")
    # first thing to do - converters!
    # !!! They have to be registered first, otherwise it will all fail horribly !!!
    common_utils.addStringConverters(mb)
    common_utils.addSupportForString(mb)

    filterDeclarations(mb)
    configureExceptions(mb)

    common_utils.setDefaultCallPolicies(CEGUI_ns)

    ## add additional version information to the module to help identify it correctly
    # todo: this should be done automatically
    common_utils.addVersionInfo(mb, PACKAGE_NAME, PACKAGE_VERSION)

    # Creating code creator. After this step you should not modify/customize declarations.
    mb.build_code_creator(
        module_name=MODULE_NAME,
        doc_extractor=common_utils.createDocumentationExtractor())

    common_utils.writeModule(mb, OUTPUT_DIR)
#!/usr/bin/env python
import sys, os, re, logging, argparse

from pyplusplus.module_builder import call_policies
from pywrap.wrapper import Wrapper
from pywrap import containers, namespaces, matchers, classes, functions
from pywrap.namespace_util import NamespaceUtil
from pygccxml.declarations import templates
from pyplusplus import decl_wrappers, messages

wrap = Wrapper()
mb = wrap.mb

classes.log.setLevel(logging.WARN)
messages.disable(messages.W1043)  # Ugly names
messages.disable(messages.W1066)  # Not exposed typedefs

# propagate constructor "explictness" to python
for cls in mb.classes(allow_empty=True):
    cls.constructors(lambda cpp_func: cpp_func.explicit == True,
                     allow_empty=True).allow_implicit_conversion = False
    for base in classes.get_all_bases(cls):
        base.constructors(lambda cpp_func: cpp_func.explicit is True,
                          allow_empty=True).allow_implicit_conversion = False

ns_coordinate = mb.namespace("::halco::hicann::v2")
ns_common = mb.namespace("::halco::common")
ns_detail = mb.namespace("::halco::common::detail")

for ns in ['::boost::serialization', '::boost::archive', '::boost::mpi']:
    try:
def generate_code():  
    messages.disable( 
#           Warnings 1020 - 1031 are all about why Py++ generates wrapper for class X
          messages.W1020
        , messages.W1021
        , messages.W1022
        , messages.W1023
        , messages.W1024
        , messages.W1025
        , messages.W1026
        , messages.W1027
        , messages.W1028
        , messages.W1029
        , messages.W1030
        , messages.W1031
        , messages.W1035
        , messages.W1040 
        , messages.W1038        
        , messages.W1041
        , messages.W1036 # pointer to Python immutable member
        , messages.W1033 # unnamed variables
        , messages.W1018 # expose unnamed classes
        , messages.W1049 # returns reference to local variable
        , messages.W1014 # unsupported '=' operator
         )
    #
    # Use GCCXML to create the controlling XML file.
    # If the cache file (../cache/*.xml) doesn't exist it gets created, otherwise it just gets loaded
    # NOTE: If you update the source library code you need to manually delete the cache .XML file   
    #
    xml_cached_fc = parser.create_cached_source_fc(
                        os.path.join( environment.ogrertshadersystem.root_dir, "python_ogrertshadersystem.h" )
                        , environment.ogrertshadersystem.cache_file )

    defined_symbols = environment.defined_symbols 
    defined_symbols .append('OGRE_RTSHADERSYSTEM_EXPORTS')
    defined_symbols.append( 'VERSION_' + environment.ogrertshadersystem.version )  
    
    #
    # build the core Py++ system from the GCCXML created source
    #    
    mb = module_builder.module_builder_t( [ xml_cached_fc ]
                                          , gccxml_path=environment.gccxml_bin
                                          , working_directory=environment.root_dir
                                          , include_paths=environment.ogrertshadersystem.include_dirs
                                          , define_symbols=defined_symbols
                                          , indexing_suite_version=2
                                          , cflags=environment.ogrertshadersystem.cflags
                                           )
                                           
    # if this module depends on another set it here                                           
    mb.register_module_dependency ( environment.ogre.generated_dir )
    
    # normally implicit conversions work OK, however they can cause strange things to happen so safer to leave off
    mb.constructors().allow_implicit_conversion = False                                           
    
    mb.BOOST_PYTHON_MAX_ARITY = 25
    mb.classes().always_expose_using_scope = True
            
    #
    # We filter (both include and exclude) specific classes and functions that we want to wrap
    # 
    global_ns = mb.global_ns
    global_ns.exclude()
    main_ns = global_ns.namespace( MAIN_NAMESPACE )
    main_ns.include()
       
    common_utils.AutoExclude ( mb, MAIN_NAMESPACE )
    common_utils.AutoInclude ( mb, MAIN_NAMESPACE )
    ManualInclude ( mb )
    ManualExclude ( mb )
    # here we fixup functions that expect to modifiy their 'passed' variables    
    ManualTransformations ( mb )
    AutoFixes ( mb, MAIN_NAMESPACE )
    ManualFixes ( mb )
    
    common_utils.Auto_Functional_Transformation ( main_ns ) #, special_vars=[]  )
   
    #
    # We need to tell boost how to handle calling (and returning from) certain functions
    #
    common_utils.Set_DefaultCall_Policies ( mb.global_ns.namespace ( MAIN_NAMESPACE ) )
    
    #
    # the manual stuff all done here !!!
    #
    hand_made_wrappers.apply( mb )

    NoPropClasses = [""]
    for cls in main_ns.classes():
        if cls.name not in NoPropClasses:
            cls.add_properties( recognizer=ogre_properties.ogre_property_recognizer_t() )
            
    # THIS MUST BE AFTER Auto_Functional_Transformation
    common_utils.Auto_Document( mb, MAIN_NAMESPACE )
    
    ## add additional version information to the module to help identify it correctly 
    common_utils.addDetailVersion ( mb, environment, environment.ogrertshadersystem )

    ##########################################################################################
    #
    # Creating the code. After this step you should not modify/customize declarations.
    #
    ##########################################################################################
    extractor = exdoc.doc_extractor() # I'm excluding the UTFstring docs as lots about nothing 
    mb.build_code_creator (module_name='_ogrertshadersystem_' , doc_extractor= extractor )
    
    for inc in environment.ogrertshadersystem.include_dirs:
        mb.code_creator.user_defined_directories.append(inc )
    mb.code_creator.user_defined_directories.append( environment.ogrertshadersystem.generated_dir )
    mb.code_creator.replace_included_headers( customization_data.header_files( environment.ogrertshadersystem.version ) )

    huge_classes = map( mb.class_, customization_data.huge_classes( environment.ogrertshadersystem.version ) )

    mb.split_module(environment.ogrertshadersystem.generated_dir, huge_classes, use_files_sum_repository=False)

    ## now we need to ensure a series of headers and additional source files are
    ## copied to the generated directory..
    
#     common_utils.copyTree ( sourcePath = environment.Config.PATH_INCLUDE_ogrertshadersystem, 
#                             destPath = environment.ogrertshadersystem.generated_dir, 
#                             recursive=False )
        
    if environment.ogre.version.startswith("1.7"):
        ## have a code generation issue that needs resolving...
        filesToFix=['CGProgramProcessor.pypp.cpp', 'GLSLProgramProcessor.pypp.cpp','HLSLProgramProcessor.pypp.cpp',
                    'ProgramProcessor.pypp.cpp', 'stdMapRTShaderParameterOperand.pypp.cpp', 
                    'stdMapRTShaderParameterParameter.pypp.cpp',
                    'CGProgramProcessor.pypp.cpp']
        for filename in filesToFix:
            fname = os.path.join( environment.ogrertshadersystem.generated_dir, filename)
            try:
                f = open(fname, 'r')
                buf = f.read()
                f.close()
                print "CHECKING:", fname
                if (" MEMCATEGORY_GENERAL" in buf) or ("<MEMCATEGORY_GENERAL" in buf):
                    buf = buf.replace ( " MEMCATEGORY_GENERAL", " Ogre::MEMCATEGORY_GENERAL")
                    buf = buf.replace ( "<MEMCATEGORY_GENERAL", "<Ogre::MEMCATEGORY_GENERAL")
                    f = open ( fname, 'w+')
                    f.write ( buf )
                    f.close()
                    print "UGLY FIX OK:", fname
            except:
                print "ERROR: Unable to fix:", fname
def generate_code():  
    messages.disable( 
#           Warnings 1020 - 1031 are all about why Py++ generates wrapper for class X
          messages.W1020
        , messages.W1021
        , messages.W1022
        , messages.W1023
        , messages.W1024
        , messages.W1025
        , messages.W1026
        , messages.W1027
        , messages.W1028
        , messages.W1029
        , messages.W1030
        , messages.W1031
        , messages.W1035
        , messages.W1040 
        , messages.W1038        
        , messages.W1041
        , messages.W1036 # pointer to Python immutable member
        , messages.W1033 # unnamed variables
        , messages.W1018 # expose unnamed classes
        , messages.W1049 # returns reference to local variable
        , messages.W1014 # unsupported '=' operator
         )
    #
    # Use GCCXML to create the controlling XML file.
    # If the cache file (../cache/*.xml) doesn't exist it gets created, otherwise it just gets loaded
    # NOTE: If you update the source library code you need to manually delete the cache .XML file   
    #
    xml_cached_fc = parser.create_cached_source_fc(
                        os.path.join( environment.ogreode.root_dir, "python_ogreode.h" )
                        , environment.ogreode.cache_file )

    defined_symbols = ['OGRE_NONCLIENT_BUILD', 'ODE_LIB','__PYTHONOGRE_BUILD_CODE' ]
    defined_symbols.append( 'OGREODE_VERSION_' + environment.ogreode.version )
      
    if environment._USE_THREADS:
        defined_symbols.append('BOOST_HAS_THREADS')
        defined_symbols.append('BOOST_HAS_WINTHREADS')
        
    #
    # build the core Py++ system from the GCCXML created source
    #    
    mb = module_builder.module_builder_t( [ xml_cached_fc ]
                                          , gccxml_path=environment.gccxml_bin
                                          , working_directory=environment.root_dir
                                          , include_paths=environment.ogreode.include_dirs
                                          , define_symbols=defined_symbols
                                          , indexing_suite_version=2
                                          , cflags=environment.ogreode.cflags
                                           )
                                           
    # if this module depends on another set it here                                           
    mb.register_module_dependency ( environment.ogre.generated_dir )
    mb.register_module_dependency ( environment.ode.generated_dir )

    # normally implicit conversions work OK, however they can cause strange things to happen so safer to leave off
    mb.constructors().allow_implicit_conversion = False                                           
    
    mb.BOOST_PYTHON_MAX_ARITY = 25
    mb.classes().always_expose_using_scope = True
            
    #
    # We filter (both include and exclude) specific classes and functions that we want to wrap
    # 
    global_ns = mb.global_ns
    global_ns.exclude()

    query = lambda decl: isinstance( decl, ( declarations.class_t, declarations.class_declaration_t ) ) \
                         and decl.name.startswith( 'dx' )
    mb.global_ns.decls( query ).opaque = True  
    for ns in MAIN_NAMESPACE:
        main_ns = global_ns.namespace( ns )
        main_ns.include()
           
        common_utils.AutoExclude ( mb, ns )
        common_utils.AutoInclude ( mb, ns )
        ManualInclude ( mb, ns )
        # here we fixup functions that expect to modifiy their 'passed' variables    
        ManualTransformations ( mb, ns )
        AutoFixes ( mb, ns )
        ManualFixes ( mb, ns )
        common_utils.Auto_Functional_Transformation ( main_ns )

        #
        # We need to tell boost how to handle calling (and returning from) certain functions
        #
        common_utils.Set_DefaultCall_Policies ( mb.global_ns.namespace ( ns ) )
    ManualExclude ( mb )
    
    #mb.global_ns.class_('::std::list<Ogre::Plane, Ogre::STLAllocator<Ogre::Plane, Ogre::CategorisedAllocPolicy<(Ogre::MemoryCategory)0> > >').include(already_exposed=True)
    try:
        mb.global_ns.class_('::std::list<Ogre::Plane, Ogre::STLAllocator<Ogre::Plane, Ogre::CategorisedAllocPolicy<(Ogre::MemoryCategory)0> > >').exclude()
    except:
        pass
    
    #
    # the manual stuff all done here !!!
    #
    hand_made_wrappers.apply( mb )

    NoPropClasses = [""]
    for cls in main_ns.classes():
        if cls.name not in NoPropClasses:
            cls.add_properties( recognizer=ogre_properties.ogre_property_recognizer_t() )
            
    ## add additional version information to the module to help identify it correctly 
    common_utils.addDetailVersion ( mb, environment, environment.ogreode )

    
    for cls in global_ns.classes():
        if not cls.ignore:
            print cls, cls.decl_string
    for cls in mb.global_ns.namespace("std").classes():
        if not cls.ignore:
            print cls, cls.decl_string
    
    
    ##########################################################################################
    #
    # Creating the code. After this step you should not modify/customize declarations.
    #
    ##########################################################################################
    extractor = exdoc.doc_extractor() # I'm excluding the UTFstring docs as lots about nothing 
    mb.build_code_creator (module_name='_ogreode_' , doc_extractor= extractor )
    
    for inc in environment.ogreode.include_dirs:
        mb.code_creator.user_defined_directories.append(inc )
    mb.code_creator.user_defined_directories.append( environment.ogreode.generated_dir )
    mb.code_creator.replace_included_headers( customization_data.header_files( environment.ogreode.version ) )

    huge_classes = map( mb.class_, customization_data.huge_classes( environment.ogreode.version ) )

    mb.split_module(environment.ogreode.generated_dir, huge_classes, use_files_sum_repository=False)

    if False:
        ## UGLY FIX
        ## we have a class that needs to be removed and for some reason py++ isn't doing it :(
        ##
        for f in  ['StdListPlane.pypp.cpp','StdListPlane.pypp.hpp']:
            fname = os.path.join( environment.ogreode.generated_dir, f)
            os.remove ( fname ) #remove the extra files
            
        # now remove the entries for the stdlistplane class     
        fname = os.path.join( environment.ogreode.generated_dir, '_ogreode_.main.cpp')  
        f = open(fname, 'r')
        buf = f.readlines()
        f.close()
        newbuf  =[]
        for line in buf:
            if ('stdlistplane' not in line ) and ('StdListPlane' not in line):
                newbuf.append(line)
        f = open ( fname, 'w+')
        f.writelines ( newbuf )
        f.close()
def generate_code():  
    messages.disable( 
#           Warnings 1020 - 1031 are all about why Py++ generates wrapper for class X
           messages.W1020
         , messages.W1021
         , messages.W1022
         , messages.W1023
         , messages.W1024
         , messages.W1025
         , messages.W1026
         , messages.W1027
         , messages.W1028
         , messages.W1029
         , messages.W1030
         , messages.W1031
         , messages.W1035
         , messages.W1040 
         , messages.W1038        
         , messages.W1041
#         , messages.W1036 # pointer to Python immutable member
#         , messages.W1033 # unnamed variables
#         , messages.W1018 # expose unnamed classes
#         , messages.W1049 # returns reference to local variable
#         , messages.W1014 # unsupported '=' operator
          )
    #
    # Use GCCXML to create the controlling XML file.
    # If the cache file (../cache/*.xml) doesn't exist it gets created, otherwise it just gets loaded
    # NOTE: If you update the source library code you need to manually delete the cache .XML file   
    #
    xml_cached_fc = parser.create_cached_source_fc(
                        os.path.join( environment.ogrepcz.root_dir, "python_ogrepcz.h" )
                        , environment.ogrepcz.cache_file )

    defined_symbols = [ 'OGRE_NONCLIENT_BUILD', 'OGRE_GCC_VISIBILITY', 'OGRE_PCZPLUGIN_EXPORTS',
                        '__PYTHONOGRE_BUILD_CODE']
    defined_symbols.append( 'VERSION_' + environment.ogrepcz.version )  
    if environment._USE_THREADS:
        defined_symbols.append('BOOST_HAS_THREADS')
        defined_symbols.append('BOOST_HAS_WINTHREADS')

    #
    # build the core Py++ system from the GCCXML created source
    #    
    mb = module_builder.module_builder_t( [ xml_cached_fc ]
                                          , gccxml_path=environment.gccxml_bin
                                          , working_directory=environment.root_dir
                                          , include_paths=environment.ogrepcz.include_dirs
                                          , define_symbols=defined_symbols
                                          , indexing_suite_version=2
                                          , cflags=environment.ogrepcz.cflags
                                           )
                                           
    # if this module depends on another set it here                                           
    mb.register_module_dependency ( environment.ogre.generated_dir )
    
    # normally implicit conversions work OK, however they can cause strange things to happen so safer to leave off
    mb.constructors().allow_implicit_conversion = False                                           
    
    mb.BOOST_PYTHON_MAX_ARITY = 25
    mb.classes().always_expose_using_scope = True
            
    #
    # We filter (both include and exclude) specific classes and functions that we want to wrap
    # 
    global_ns = mb.global_ns
    global_ns.exclude()
    
#     #
#     # I'm assuming that any 'std' classes etc we need will have already been exposed by the Ogre library
#     #
#     std_ns = global_ns.namespace('std')
#     std_ns.include(already_exposed=True) 
    
    # We don't include all of MAIN_NAMESPACE otherwise we get the same full wrapper
    # so instead we include classes with names that start with PCZ
    main_ns = global_ns.namespace( MAIN_NAMESPACE )
# #     main_ns.include( already_exposed = True )  ## force the ogre class to be exposed as well...
    
    for c in main_ns.classes():
        if c.name.startswith ('PCZ') or c.name.startswith ('PCPlane') or  c.name.startswith ('Portal'):
            c.include()
            print "Including ", c, c.already_exposed
            
    for c in ['Portal','PCPlane']:
        main_ns.class_(c).include()
        print "Including ", c            
    
    common_utils.AutoExclude ( mb, MAIN_NAMESPACE )
    ManualInclude ( mb )
    ManualExclude ( mb )
    common_utils.AutoInclude ( mb, MAIN_NAMESPACE )
    # here we fixup functions that expect to modifiy their 'passed' variables    
    ManualTransformations ( mb )
    AutoFixes ( mb, MAIN_NAMESPACE )
    ManualFixes ( mb )
    common_utils.Auto_Functional_Transformation ( main_ns )
    #
    # We need to tell boost how to handle calling (and returning from) certain functions
    #
    common_utils.Set_DefaultCall_Policies ( mb.global_ns.namespace ( MAIN_NAMESPACE ) )
    
    #
    # the manual stuff all done here !!!
    #
    hand_made_wrappers.apply( mb )

    NoPropClasses = [""]
    for cls in main_ns.classes():
        if cls.name not in NoPropClasses:
            cls.add_properties( recognizer=ogre_properties.ogre_property_recognizer_t() )
            
    ## add additional version information to the module to help identify it correctly 
    common_utils.addDetailVersion ( mb, environment, environment.ogrepcz )

    ##########################################################################################
    #
    # Creating the code. After this step you should not modify/customize declarations.
    #
    ##########################################################################################
    extractor = exdoc.doc_extractor() # I'm excluding the UTFstring docs as lots about nothing 
    mb.build_code_creator (module_name='_ogrepcz_' , doc_extractor= extractor )
    
    for inc in environment.ogrepcz.include_dirs:
        mb.code_creator.user_defined_directories.append(inc )
    mb.code_creator.user_defined_directories.append( environment.ogrepcz.generated_dir )
    mb.code_creator.replace_included_headers( customization_data.header_files( environment.ogrepcz.version ) )

    huge_classes = map( mb.class_, customization_data.huge_classes( environment.ogrepcz.version ) )

    mb.split_module(environment.ogrepcz.generated_dir, huge_classes, use_files_sum_repository=False)

    ## now we need to ensure a series of headers and additional source files are
    ## copied to the generated directory..
    
#     common_utils.copyTree ( sourcePath = environment.Config.PATH_INCLUDE_ogrepcz, 
#                             destPath = environment.ogrepcz.generated_dir, 
#                             recursive=False )
    if environment.ogre.version.startswith("1.7"):
        ## have a code generation issue that needs resolving...
        filesToFix=['PCZoneFactoryManager.pypp.cpp']
        for filename in filesToFix:
            fname = os.path.join( environment.ogrepcz.generated_dir, filename)
            try:
                f = open(fname, 'r')
                buf = f.read()
                f.close()
                buf = buf.replace ( " MEMCATEGORY_GENERAL", " Ogre::MEMCATEGORY_GENERAL")
                buf = buf.replace ( "<MEMCATEGORY_GENERAL", "<Ogre::MEMCATEGORY_GENERAL")
                f = open ( fname, 'w+')
                f.write ( buf )
                f.close()
                print "UGLY FIX OK:", fname
            except:
                print "ERROR: Unable to fix:", fname        
def generate_code():  
    messages.disable( 
#           Warnings 1020 - 1031 are all about why Py++ generates wrapper for class X
          messages.W1020
        , messages.W1021
        , messages.W1022
        , messages.W1023
        , messages.W1024
        , messages.W1025
        , messages.W1026
        , messages.W1027
        , messages.W1028
        , messages.W1029
        , messages.W1030
        , messages.W1031
        , messages.W1035
        , messages.W1040 
        , messages.W1038        
#         , messages.W1041
#         , messages.W1036 # pointer to Python immutable member
#         , messages.W1033 # unnamed variables
#         , messages.W1018 # expose unnamed classes
#         , messages.W1049 # returns reference to local variable
#         , messages.W1014 # unsupported '=' operator
         )
    #
    # Use GCCXML to create the controlling XML file.
    # If the cache file (../cache/*.xml) doesn't exist it gets created, otherwise it just gets loaded
    # NOTE: If you update the source library code you need to manually delete the cache .XML file   
    #
    xml_cached_fc = parser.create_cached_source_fc(
                        os.path.join( environment.watermesh.root_dir, "python_watermesh.h" )
                        , environment.watermesh.cache_file )

    defined_symbols = ['OGRE_NONCLIENT_BUILD']
    defined_symbols.append( 'VERSION_' + environment.watermesh.version )  
    
    #
    # build the core Py++ system from the GCCXML created source
    #    
    mb = module_builder.module_builder_t( [ xml_cached_fc ]
                                          , gccxml_path=environment.gccxml_bin
                                          , working_directory=environment.root_dir
                                          , include_paths=environment.watermesh.include_dirs
                                          , define_symbols=defined_symbols
                                          , indexing_suite_version=2
                                          , cflags=environment.watermesh.cflags
                                           )
                                           
    # if this module depends on another set it here                                           
    mb.register_module_dependency ( environment.ogre.generated_dir )
    
    # normally implicit conversions work OK, however they can cause strange things to happen so safer to leave off
    mb.constructors().allow_implicit_conversion = False                                           
    
    mb.BOOST_PYTHON_MAX_ARITY = 25
    mb.classes().always_expose_using_scope = True
            
    #
    # We filter (both include and exclude) specific classes and functions that we want to wrap
    # 
    global_ns = mb.global_ns
    global_ns.exclude()
    main_ns = global_ns.namespace( MAIN_NAMESPACE )
    main_ns.exclude()
       
    common_utils.AutoExclude ( mb, MAIN_NAMESPACE )
    ManualExclude ( mb )
    common_utils.AutoInclude ( mb, MAIN_NAMESPACE )
    ManualInclude ( mb )
    # here we fixup functions that expect to modifiy their 'passed' variables    
    ManualTransformations ( mb )
    AutoFixes ( mb, MAIN_NAMESPACE )
    ManualFixes ( mb )
    common_utils.Auto_Functional_Transformation ( main_ns )
    
    #
    # We need to tell boost how to handle calling (and returning from) certain functions
    #
    common_utils.Set_DefaultCall_Policies ( mb.global_ns.namespace ( MAIN_NAMESPACE ) )
    
    #
    # the manual stuff all done here !!!
    #
    hand_made_wrappers.apply( mb )

    NoPropClasses = [""]
    for cls in main_ns.classes():
        if cls.name not in NoPropClasses:
            cls.add_properties( recognizer=ogre_properties.ogre_property_recognizer_t() )
            
    ## add additional version information to the module to help identify it correctly 
    common_utils.addDetailVersion ( mb, environment, environment.watermesh )

    ##########################################################################################
    #
    # Creating the code. After this step you should not modify/customize declarations.
    #
    ##########################################################################################
    extractor = exdoc.doc_extractor() # I'm excluding the UTFstring docs as lots about nothing 
    mb.build_code_creator (module_name='_watermesh_' , doc_extractor= extractor )
    
    for inc in environment.watermesh.include_dirs:
        mb.code_creator.user_defined_directories.append(inc )
    mb.code_creator.user_defined_directories.append( environment.watermesh.generated_dir )
    mb.code_creator.replace_included_headers( customization_data.header_files( environment.watermesh.version ) )

    huge_classes = map( mb.class_, customization_data.huge_classes( environment.watermesh.version ) )

    mb.split_module(environment.watermesh.generated_dir, huge_classes, use_files_sum_repository=False)

    ## now we need to ensure a series of headers and additional source files are
    ## copied to the generated directory..
    
    common_utils.copyTree ( sourcePath = environment.Config.PATH_watermesh, 
                            destPath = environment.watermesh.generated_dir, 
                            recursive=False )
Exemple #23
0
# Author: Mark Moll

# The paths that cmake substitutues in the code_generator_t constructor might
# contain Unicode characters.
# coding: utf-8

import time
import threading
import sys
from pygccxml import parser
from pyplusplus import module_builder, messages
from pyplusplus.module_builder import call_policies

# disable some warnings that are mostly harmless
messages.disable(messages.W1014)
messages.disable(messages.W1023)
messages.disable(messages.W1040)

# create a dictionary called "default_replacement" that can be used to replace method
# declaration with another method. The dictionary is indexed by method name,
# either with or without full scope. For each method there is a 2-tuple. The
# first component is a string that tells Boost.Python how to export the
# replacement method. The second component is a string that contains the C++
# code for the replacement method.
default_replacement = {}
# A C++ call like "foo.print(std::cout)" will be replaced with something more
# pythonesque using the special __str__ method: "print(foo)"
default_replacement['print'] = ('def("__str__", &__str__)', """
std::string __str__(%s* obj)
{
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'

    if platform.architecture()[
            0] == '64bit' and platform.system() == 'Windows':

        if sys.platform == 'darwin':
            pass
        else:
            defines.append('_WIN64')
            logger.info('Marking win64 for gccxml')

    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")


    mb = module_builder.module_builder_t([xml_cached_fc],
                                         gccxml_path=casterpath,
                                         working_directory=settings.gimli_path,
                                         include_paths=settings.includesPaths,
                                         define_symbols=defines,
                                         indexing_suite_version=2,
                                         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.")
    hand_made_wrappers.apply(mb)

    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',
          ]
    
    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)
            
    mb.calldefs(access_type_matcher_t('protected')).exclude()
    mb.calldefs(access_type_matcher_t('private')).exclude()

    # 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 *',
         '::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 &',
                                              '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")
def generate_code():
    messages.disable( 
#           Warnings 1020 - 1031 are all about why Py++ generates wrapper for class X
          messages.W1020
        , messages.W1021
        , messages.W1022
        , messages.W1023
        , messages.W1024
        , messages.W1025
        , messages.W1026
        , messages.W1027
        , messages.W1028
        , messages.W1029
        , messages.W1030
        , messages.W1031
#         , messages.W1035
#         , messages.W1040 
#         , messages.W1038        
#         , messages.W1041
        , messages.W1036 # pointer to Python immutable member
        , messages.W1033 # unnamed variables
        , messages.W1018 # expose unnamed classes
        , messages.W1049 # returns reference to local variable
        , messages.W1014 # unsupported '=' operator
         )
    xml_cached_fc = parser.create_cached_source_fc(
                        os.path.join( environment.ode.root_dir, "python_ode.h" )
                        , environment.ode.cache_file )

    mb = module_builder.module_builder_t( [ xml_cached_fc ]
                                          , gccxml_path=environment.gccxml_bin
                                          , working_directory=environment.root_dir
                                          , include_paths=environment.ode.include_dirs
                                          , define_symbols=['ode_NONCLIENT_BUILD', 'ODE_LIB']
                                          , indexing_suite_version=2 )

    filter_declarations (mb)
    
    query = lambda decl: isinstance( decl, ( declarations.class_t, declarations.class_declaration_t ) ) \
                         and decl.name.startswith( 'dx' )
    mb.global_ns.decls( query ).opaque = True   
#     mb.global_ns.variable('dSpaceID').opaque=True
                          
#     ## here we adjust for functions that return poiners to ODE "ID's", which are really C structs
#     ## I may have been over agressive in identifing these functions but hopefully not...
#     for func in mb.namespace( 'OgreOde' ).member_functions():  
#         if func.return_type.decl_string.endswith('ID'):
#             print "Setting ", func.name, "to Opaque"
#             func.opaque = True
#             func.call_policies = call_policies.return_value_policy(
#                 call_policies.return_opaque_pointer )
        


    mb.BOOST_PYTHON_MAX_ARITY = 25
    mb.classes().always_expose_using_scope = True
    
    Set_Call_Policies (mb)
    AutoArrayArgs( mb )
    ReturnReals( mb )
    hand_made_wrappers.apply( mb )

    ode_ns = mb.global_ns  ## .namespace ('ode')
    common_utils.add_properties( ode_ns.classes() )

    ## add additional version information to the module to help identify it correctly 
    common_utils.addDetailVersion ( mb, environment, environment.ode )
 
    #Creating code creator. After this step you should not modify/customize declarations.
    extractor = exdoc.doc_extractor("")
    mb.build_code_creator (module_name='_ode_' , doc_extractor= extractor)
    
    for inc in environment.ode.include_dirs:
        mb.code_creator.user_defined_directories.append(inc )
    mb.code_creator.user_defined_directories.append( environment.ode.generated_dir )
    mb.code_creator.replace_included_headers( customization_data.header_files(environment.ode.version) )
    
# #     mb.code_creator.add_include( "__convenience.pypp.hpp" )
# #     mb.code_creator.add_system_header( code_repository.convenience.file_name )

    huge_classes = map( mb.class_, customization_data.huge_classes(environment.ode.version) )

    mb.split_module(environment.ode.generated_dir, huge_classes)

    return_pointee_value_source_path \
        = os.path.join( environment.pyplusplus_install_dir
#                         , 'pyplusplus_dev'
                        , 'pyplusplus'
                        , 'code_repository'
                        , 'return_pointee_value.hpp' )
    if not os.path.exists(return_pointee_value_source_path):
        return_pointee_value_source_path \
            = os.path.join ( os.path.dirname(code_repository.__file__),
                            'return_pointee_value.hpp')
    if not os.path.exists(return_pointee_value_source_path):
        return_pointee_value_source_path \
            = os.path.join ( os.getcwd(),
                            'return_pointee_value.hpp')


    return_pointee_value_target_path \
        = os.path.join( environment.ode.generated_dir, 'return_pointee_value.hpp' )

    if not os.path.exists( return_pointee_value_target_path ):
        shutil.copy( return_pointee_value_source_path, environment.ode.generated_dir )
def generate_code():
    messages.disable(
        #           Warnings 1020 - 1031 are all about why Py++ generates wrapper for class X
        messages.W1020,
        messages.W1021,
        messages.W1022,
        messages.W1023,
        messages.W1024,
        messages.W1025,
        messages.W1026,
        messages.W1027,
        messages.W1028,
        messages.W1029,
        messages.W1030,
        messages.W1031
        #         , messages.W1035
        #         , messages.W1040
        #         , messages.W1038
        #         , messages.W1041
        ,
        messages.W1036,  # pointer to Python immutable member
        messages.W1033,  # unnamed variables
        messages.W1018,  # expose unnamed classes
        messages.W1049,  # returns reference to local variable
        messages.W1014,  # unsupported '=' operator
    )
    #
    # Use GCCXML to create the controlling XML file.
    # If the cache file (../cache/*.xml) doesn't exist it gets created, otherwise it just gets loaded
    # NOTE: If you update the source library code you need to manually delete the cache .XML file
    #
    xml_cached_fc = parser.create_cached_source_fc(
        os.path.join(environment.ogreforests.root_dir, "python_forests.h"), environment.ogreforests.cache_file
    )

    defined_symbols = ["OGRE_NONCLIENT_BUILD", "WIN32", "GCCXML_BUG", "__PYTHONOGRE_BUILD_CODE"]
    undefine_symbols = []
    if environment._USE_THREADS:
        defined_symbols.append("BOOST_HAS_THREADS")
        defined_symbols.append("BOOST_HAS_WINTHREADS")

    defined_symbols.append("VERSION_" + environment.ogreforests.version)

    #
    # build the core Py++ system from the GCCXML created source
    #
    mb = module_builder.module_builder_t(
        [xml_cached_fc],
        gccxml_path=environment.gccxml_bin,
        working_directory=environment.root_dir,
        include_paths=environment.ogreforests.include_dirs,
        define_symbols=defined_symbols,
        indexing_suite_version=2,
        cflags=environment.ogreforests.cflags,
    )

    # if this module depends on another set it here
    ## mb.register_module_dependency ( environment.ogre.generated_dir )

    # normally implicit conversions work OK, however they can cause strange things to happen so safer to leave off
    mb.constructors().allow_implicit_conversion = False
    mb.register_module_dependency(environment.ogre.generated_dir)

    mb.BOOST_PYTHON_MAX_ARITY = 25
    mb.classes().always_expose_using_scope = True

    #
    # We filter (both include and exclude) specific classes and functions that we want to wrap
    #
    global_ns = mb.global_ns
    global_ns.exclude()
    main_ns = global_ns.namespace(MAIN_NAMESPACE)
    main_ns.include()

    common_utils.AutoExclude(mb, MAIN_NAMESPACE)
    ManualExclude(mb)
    common_utils.AutoInclude(mb, MAIN_NAMESPACE)
    ManualInclude(mb)

    # here we fixup functions that expect to modifiy their 'passed' variables and are not autmatically fixed
    ManualTransformations(mb)

    AutoFixes(mb, MAIN_NAMESPACE)
    ManualFixes(mb)
    common_utils.Auto_Functional_Transformation(main_ns)

    common_utils.Auto_Document(mb, MAIN_NAMESPACE)

    ## note change to clear prefix_output as this will force all transforms to be inout (and not 'output') to ensure the arguments are matched
    ## problem with overload virtual fuctions from parent class such as getMetrics in RenderWindow and RenderTarget
    common_utils.Auto_Functional_Transformation(
        main_ns
    )  ##, special_vars=['::Ogre::Real &','::Ogre::ushort &','size_t &']  )

    #
    # We need to tell boost how to handle calling (and returning from) certain functions
    #
    common_utils.Set_DefaultCall_Policies(main_ns)
    for c in main_ns.classes():
        print "CLass", c
    #
    # the manual stuff all done here !!!
    #
    hand_made_wrappers.apply(mb)

    NoPropClasses = [""]
    for cls in main_ns.classes():
        if cls.name not in NoPropClasses:
            cls.add_properties(recognizer=ogre_properties.ogre_property_recognizer_t())

    ## add additional version information to the module to help identify it correctly
    common_utils.addDetailVersion(mb, environment, environment.ogreforests)

    ##########################################################################################
    #
    # Creating the code. After this step you should not modify/customize declarations.
    #
    ##########################################################################################
    extractor = exdoc.doc_extractor()  # I'm excluding the UTFstring docs as lots about nothing
    mb.build_code_creator(module_name="_ogreforests_", doc_extractor=extractor)

    for inc in environment.ogreforests.include_dirs:
        mb.code_creator.user_defined_directories.append(inc)
    mb.code_creator.user_defined_directories.append(environment.ogreforests.generated_dir)
    mb.code_creator.replace_included_headers(customization_data.header_files(environment.ogreforests.version))

    huge_classes = map(mb.class_, customization_data.huge_classes(environment.ogreforests.version))

    mb.split_module(environment.ogreforests.generated_dir, huge_classes, use_files_sum_repository=False)

    ## now we need to ensure a series of headers and additional source files are
    ## copied to the generated directory..
    common_utils.copyTree(
        sourcePath=environment.Config.PATH_INCLUDE_ogreforests,
        destPath=environment.ogreforests.generated_dir,
        recursive=False,
    )
Exemple #27
0
def dopypp(task):

    global included_decls

    # Set the path for importing additional tools
    if not os.path.join(task.srcpath, 'tools', 'waf') in sys.path:
        sys.path.append(os.path.join(task.srcpath, 'tools', 'waf'))

    # Increase recursion limit for tough includes
    sys.setrecursionlimit(sys.getrecursionlimit()*2)

    from pyplusplus import module_builder, messages, utils, code_repository
    from pygccxml import declarations,parser
    from pyplusplus.module_builder import call_policies
    from pypp_utils import TemplateBuilder
    import logging

    # Disable some annoying messages
    if not Logs.verbose:
        module_builder.set_logger_level(logging.FATAL)
        messages.disable(messages.W1023)
        messages.disable(messages.W1025)
        messages.disable(messages.W1026)
        messages.disable(messages.W1027)
        messages.disable(messages.W1031)
        messages.disable(messages.W1043)
    elif Logs.verbose > 2:
        module_builder.set_logger_level(logging.DEBUG)

    ## ????????????????????????????????????? What is this for ?????????????????????????????
    logger_lock.acquire()
    log = logging.getLogger()
    temp_handler = None
    if len(log.handlers) > 0:
        temp_handler = log.handlers[0]
        log.removeHandler(log.handlers[0])
    logger_lock.release()

    # Create source list with proper directories
    sources = map(lambda a: os.path.abspath(os.path.join(task.bldpath, a.srcpath(task.env))), task.inputs)

    # Create include list
    global_includes = task.includes
    global_includes += task.env['CPPPATH']
    global_includes += [os.path.abspath(os.path.join(task.bldpath, i.srcpath(task.env))) for i in task.path_lst]

    try:
        #if int(task.env['CC_VERSION'][1]) >= 3:
            #compilerExec = task.env['CXX_OLD_VERSION'][0]
        #else:
        compilerExec = task.env['CXX'][0]

        # No cache can be used on mac-osx systems, otherwise pygccxml segfaults
        if sys.platform != 'darwin':
            mb = module_builder.module_builder_t(
                                    files=sources
                                    , start_with_declarations = task.start_decls
                                    , define_symbols = task.define_symbols
                                    , working_directory = task.bldpath
                                    , include_paths = global_includes
                                    , compiler = compilerExec
                                    , cache=parser.file_cache_t(os.path.abspath(os.path.join(task.bldpath, task.outputs[0].bldpath(task.env)+'_cache' ))))
        else:
            mb = module_builder.module_builder_t(
                                    files=sources
                                    , start_with_declarations = task.start_decls
                                    , define_symbols = task.define_symbols
                                    , working_directory = task.bldpath
                                    , include_paths = global_includes
                                    , compiler = compilerExec)
    except Exception, e:
        print e
        if temp_handler:
            log.addHandler(temp_handler)
        return 1
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")
def generate():
    ### disable unnecessary warnings
    # can't pass function pointer
    messages.disable(messages.W1004)
    # operator not supported
    messages.disable(messages.W1014)
    # py++ will create a wrapper
    messages.disable(messages.W1023, messages.W1025, messages.W1026, messages.W1027, messages.W1031)
    # static pointer member can't be exported
    messages.disable(messages.W1035)
    # immutable pointer can't be exposed
    messages.disable(messages.W1036)
    # pointer to function can't be exposed
    messages.disable(messages.W1036, messages.W1037)
    # can't be overridden in python
    messages.disable(messages.W1049)

    mb = common_utils.createModuleBuilder("python_CEGUI.h", ["CEGUIBASE_EXPORTS"])
    CEGUI_ns = mb.global_ns.namespace("CEGUI")
    # first thing to do - converters!
    # !!! They have to be registered first, otherwise it will all fail horribly !!!
    common_utils.addStringConverters(mb)
    common_utils.addSupportForString(mb)

    filterDeclarations(mb)
    configureExceptions(mb)

    common_utils.setDefaultCallPolicies(CEGUI_ns)

    ## add additional version information to the module to help identify it correctly
    # todo: this should be done automatically
    common_utils.addVersionInfo(mb, PACKAGE_NAME, PACKAGE_VERSION)

    # Creating code creator. After this step you should not modify/customize declarations.
    mb.build_code_creator(module_name = MODULE_NAME, doc_extractor = common_utils.createDocumentationExtractor())

    common_utils.writeModule(mb, OUTPUT_DIR)