Ejemplo n.º 1
0
    def create_default(self):
        cntrl = self.controller.default_controller

        make_object = algorithm.create_identifier(
            self, 'pyplusplus::call_policies::make_object')
        make_tuple = algorithm.create_identifier(self,
                                                 'boost::python::make_tuple')

        tmpl_values = dict()

        tmpl_values['unique_function_name'] = self.default_name()
        tmpl_values['return_type'] = cntrl.wrapper_return_type.decl_string
        tmpl_values['arg_declarations'] = self.args_default_declaration()
        tmpl_values['wrapper_class'] = self.parent.wrapper_alias
        tmpl_values['wrapped_class'] = declarations.full_name(
            self.declaration.parent)
        tmpl_values['wrapped_inst'] = cntrl.inst_arg.name
        tmpl_values['wrapped_inst_constness'] = ''
        if declarations.is_const(
                declarations.remove_reference(cntrl.inst_arg.type)):
            tmpl_values['wrapped_inst_constness'] = 'const'

        decl_vars = cntrl.variables[:]
        if not declarations.is_void(self.declaration.return_type):
            decl_vars.append(cntrl.result_variable)
        tmpl_values['declare_variables'] \
            = os.linesep + os.linesep.join( map( lambda var: self.indent( var.declare_var_string() )
                                                 , decl_vars ) )

        tmpl_values['pre_call'] = os.linesep + self.indent(
            os.linesep.join(cntrl.pre_call))

        tmpl_values['save_result'] = ''
        if not declarations.is_void(self.declaration.return_type):
            tmpl_tmp = '%(result_var_name)s = '
            if declarations.is_reference(self.declaration.return_type):
                tmpl_tmp = tmpl_tmp + '&'
            tmpl_values['save_result'] = tmpl_tmp % dict(
                result_var_name=cntrl.result_variable.name)

        tmpl_values['function_name'] = self.declaration.name
        tmpl_values['arg_expressions'] = self.PARAM_SEPARATOR.join(
            cntrl.arg_expressions)
        return_stmt_creator = calldef_utils.return_stmt_creator_t(
            self, cntrl, cntrl.result_variable, cntrl.return_variables)

        tmpl_values['post_call'] = os.linesep + self.indent(
            os.linesep.join(cntrl.post_call))
        if return_stmt_creator.pre_return_code:
            tmpl_values['post_call'] \
                = os.linesep.join([ tmpl_values['post_call']
                                    , self.indent( return_stmt_creator.pre_return_code )])
        tmpl_values['return'] = os.linesep + self.indent(
            return_stmt_creator.statement)

        f_def = cntrl.template.substitute(tmpl_values)
        return remove_duplicate_linesep(f_def)
Ejemplo n.º 2
0
    def create_default(self):
        cntrl = self.controller.default_controller

        make_object = algorithm.create_identifier( self, 'pyplusplus::call_policies::make_object' )
        make_tuple = algorithm.create_identifier( self, 'boost::python::make_tuple' )
        
        tmpl_values = dict()

        tmpl_values['unique_function_name'] = self.default_name()
        tmpl_values['return_type'] = cntrl.wrapper_return_type.decl_string
        tmpl_values['arg_declarations'] = self.args_default_declaration()        
        tmpl_values['wrapper_class'] = self.parent.wrapper_alias
        tmpl_values['wrapped_class'] = declarations.full_name( self.declaration.parent )
        tmpl_values['wrapped_inst'] = cntrl.inst_arg.name
        tmpl_values['wrapped_inst_constness'] = ''
        if declarations.is_const( declarations.remove_reference( cntrl.inst_arg.type ) ):
            tmpl_values['wrapped_inst_constness'] = 'const'
            
        decl_vars = cntrl.variables[:]
        if not declarations.is_void( self.declaration.return_type ):
            decl_vars.append( cntrl.result_variable )
        tmpl_values['declare_variables'] \
            = os.linesep + os.linesep.join( map( lambda var: self.indent( var.declare_var_string() )
                                                 , decl_vars ) )
                
        tmpl_values['pre_call'] = os.linesep + self.indent( os.linesep.join( cntrl.pre_call ) )

        tmpl_values['save_result'] = ''
        if not declarations.is_void( self.declaration.return_type ):
            tmpl_tmp = '%(result_var_name)s = '
            if declarations.is_reference( self.declaration.return_type ):
                tmpl_tmp = tmpl_tmp + '&'
            tmpl_values['save_result'] = tmpl_tmp % dict( result_var_name=cntrl.result_variable.name )

        tmpl_values['function_name'] = self.declaration.name
        tmpl_values['arg_expressions'] = self.PARAM_SEPARATOR.join( cntrl.arg_expressions )
        return_stmt_creator = calldef_utils.return_stmt_creator_t( self
                                    , cntrl
                                    , cntrl.result_variable
                                    , cntrl.return_variables )

        tmpl_values['post_call'] = os.linesep + self.indent( os.linesep.join( cntrl.post_call ) )
        if return_stmt_creator.pre_return_code:
            tmpl_values['post_call'] \
                = os.linesep.join([ tmpl_values['post_call']
                                    , self.indent( return_stmt_creator.pre_return_code )])
        tmpl_values['return'] = os.linesep + self.indent( return_stmt_creator.statement )
            
        f_def = cntrl.template.substitute(tmpl_values)
        return remove_duplicate_linesep( f_def )
 def restype_code(self):
     if not declarations.is_void(self.ftype.return_type):
         return ctypes_formatter.as_ctype(
             self.ftype.return_type,
             self.top_parent.treat_char_ptr_as_binary_data)
     else:
         return ''
Ejemplo n.º 4
0
    def statement( self ):      
        if None is self.__return_stmt:
            stmt = ''
            bpl_object = algorithm.create_identifier( self.__creator, 'boost::python::object' )            
            make_tuple = algorithm.create_identifier( self.__creator, 'boost::python::make_tuple' )            
            make_object = algorithm.create_identifier( self.__creator, 'pyplusplus::call_policies::make_object' )

            if not declarations.is_void( self.__function.return_type ):
                if self.__function.call_policies.is_default():
                    self.__return_vars.insert( 0, self.__result_var.name )
                else:
                    self.__return_vars.insert( 0
                            , declarations.call_invocation.join( 
                                declarations.templates.join( make_object
                                                            , [self.__call_policy_alias, self.__result_var.type.decl_string] )
                                , [self.__result_var.name] ) )
            
            if 0 == len( self.__return_vars ):
                pass
            elif 1 == len( self.__return_vars ):
                stmt = bpl_object + '( %s )' % self.__return_vars[ 0 ]
            else: # 1 < 
                stmt = declarations.call_invocation.join( make_tuple, self.__return_vars )
                if self.__creator.LINE_LENGTH < len( stmt ):
                    stmt = declarations.call_invocation.join( 
                                  make_tuple
                                , self.__return_vars
                                , os.linesep + self.__creator.indent( self.__creator.PARAM_SEPARATOR, 6 ) )
                    
            if stmt:
                stmt = 'return ' + stmt + ';'
            self.__return_stmt = stmt
        return self.__return_stmt
Ejemplo n.º 5
0
    def statement( self ):
        if None is self.__return_stmt:
            stmt = ''
            bpl_object = algorithm.create_identifier( self.__creator, 'boost::python::object' )
            make_tuple = algorithm.create_identifier( self.__creator, 'boost::python::make_tuple' )
            make_object = algorithm.create_identifier( self.__creator, 'pyplusplus::call_policies::make_object' )

            if not declarations.is_void( self.__function.return_type ):
                if self.__function.call_policies.is_default():
                    self.__return_vars.insert( 0, self.__result_var.name )
                else:
                    self.__return_vars.insert( 0
                            , declarations.call_invocation.join(
                                declarations.templates.join( make_object
                                                            , [self.__call_policy_alias, self.__result_var.type.decl_string] )
                                , [self.__result_var.name] ) )

            if 0 == len( self.__return_vars ):
                pass
            elif 1 == len( self.__return_vars ):
                stmt = bpl_object + '( %s )' % self.__return_vars[ 0 ]
            else: # 1 <
                stmt = declarations.call_invocation.join( make_tuple, self.__return_vars )
                if self.__creator.LINE_LENGTH < len( stmt ):
                    stmt = declarations.call_invocation.join(
                                  make_tuple
                                , self.__return_vars
                                , os.linesep + self.__creator.indent( self.__creator.PARAM_SEPARATOR, 6 ) )

            if stmt:
                stmt = 'return ' + stmt + ';'
            self.__return_stmt = stmt
        return self.__return_stmt
Ejemplo n.º 6
0
def AddWrapReg( mb, cls_name, declaration, args_mod_in ):
    if type(cls_name) != str:
        cls = cls_name
        cls_name = cls.name # or alias?
    else:
        cls = mb.class_(cls_name)
    
    # Create a wrapper class inst
    wrapper = calldef.mem_fun_v_wrapper_t( declaration )

    template = []
    
    # NOTE: Comparing directly gives problems
    template.append( '%(override)s func_%(alias)s = this->get_override( "%(alias)s" );' )
    template.append( 'if( func_%(alias)s.ptr() != Py_None )' )
    template.append( wrapper.indent('try {' ) )
    template.append( wrapper.indent(wrapper.indent('%(return_)sfunc_%(alias)s( %(args_mod_in)s );' ) ) )
    template.append( wrapper.indent('} catch(...) {') )
    template.append( wrapper.indent(wrapper.indent('PyErr_Print();')) )
    template.append( wrapper.indent(wrapper.indent('%(return_)sthis->%(wrapped_class)s::%(name)s( %(args)s );') ) )
    template.append( wrapper.indent( '}' ) )    
    template.append( 'else' )
    template.append( wrapper.indent('%(return_)sthis->%(wrapped_class)s::%(name)s( %(args)s );') )
    
    template = os.linesep.join( template )

    return_ = ''
    if not declarations.is_void( wrapper.declaration.return_type ):
        return_ = 'return '
        
    answer = [ wrapper.create_declaration(wrapper.declaration.partial_name) + '{' ]
    answer.append( wrapper.indent( 
        template % {
            'override' : wrapper.override_identifier()
            , 'name' : wrapper.declaration.partial_name
            , 'alias' : wrapper.declaration.alias
            , 'return_' : return_
            , 'args' : wrapper.function_call_args()
            , 'args_mod_in' : GenerateArgNames(args_mod_in)
            , 'wrapped_class' : wrapper.wrapped_class_identifier()
        }      
    ) )
    answer.append( '}' )
    cls.add_wrapper_code( 
        os.linesep.join( answer )
    )
    
    # Add default body
    cls.add_wrapper_code( wrapper.create_default_function() )
    
    # Add registration code
    reg = calldef.mem_fun_v_t( declaration, wrapper )
    # WTF, why does it needs to be a code_creator instance. It only uses it for full_name
    cc = hackcodecreator_t(cls_name+'_wrapper')      
    wrapper.parent = cc
    cls.add_registration_code( reg._create_impl(), True )
Ejemplo n.º 7
0
    def is_setter( self, mem_fun ):
#        print "IN IS_SETTER", mem_fun
        if len( mem_fun.arguments ) != 1:
            return False
        if not declarations.is_void( mem_fun.return_type ):
            return False
        if mem_fun.has_const:
            return False
#        print "RETURNING TRUE"    
        return True
Ejemplo n.º 8
0
 def wrapper_return_type( self ):
     return_vars_count = len( self.return_variables )
     if not declarations.is_void( self.function.return_type ):
         return_vars_count += 1
     if 0 == return_vars_count:
         return self.function.return_type #return type is void
     elif 1 == return_vars_count:
         return declarations.dummy_type_t( 'boost::python::object' )
     else:
         return declarations.dummy_type_t( 'boost::python::tuple' )
Ejemplo n.º 9
0
 def wrapper_return_type(self):
     return_vars_count = len(self.return_variables)
     if not declarations.is_void(self.function.return_type):
         return_vars_count += 1
     if 0 == return_vars_count:
         return self.function.return_type  #return type is void
     elif 1 == return_vars_count:
         return declarations.dummy_type_t('boost::python::object')
     else:
         return declarations.dummy_type_t('boost::python::tuple')
Ejemplo n.º 10
0
 def is_setter( self, mem_fun ):
     if len( mem_fun.arguments ) != 1:
         return False
     if not declarations.is_void( mem_fun.return_type ):
         return False
     if mem_fun.has_const:
         return False
     if mem_fun.overloads:
         return False            
     return True
Ejemplo n.º 11
0
 def is_setter(self, mem_fun):
     if len(mem_fun.arguments) != 1:
         return False
     if not declarations.is_void(mem_fun.return_type):
         return False
     if mem_fun.has_const:
         return False
     if mem_fun.overloads:
         return False
     return True
Ejemplo n.º 12
0
    def create_fun_definition(self):
        cntrl = self.controller

        make_object = algorithm.create_identifier(
            self, 'pyplusplus::call_policies::make_object')
        make_tuple = algorithm.create_identifier(self,
                                                 'boost::python::make_tuple')

        tmpl_values = dict()

        tmpl_values['unique_function_name'] = self.wrapper_name()
        tmpl_values[
            'return_type'] = self.controller.wrapper_return_type.decl_string
        tmpl_values['arg_declarations'] = self.args_declaration()

        tmpl_values['declare_variables'] \
            = os.linesep + os.linesep.join( map( lambda var: self.indent( var.declare_var_string() )
                                                 , cntrl.variables ) )

        tmpl_values['pre_call'] = os.linesep + self.indent(
            os.linesep.join(cntrl.pre_call))

        tmpl_values['save_result'] = ''
        if not declarations.is_void(self.declaration.return_type):
            tmpl_tmp = '%(type)s %(name)s = '
            if declarations.is_reference(self.declaration.return_type):
                tmpl_tmp = tmpl_tmp + '&'

            tmpl_values['save_result'] = tmpl_tmp \
                                         % { 'type': cntrl.result_variable.type.decl_string
                                             , 'name' : cntrl.result_variable.name }

        tmpl_values['function_name'] = self.resolve_function_ref()
        tmpl_values['arg_expressions'] = self.PARAM_SEPARATOR.join(
            cntrl.arg_expressions)
        return_stmt_creator = calldef_utils.return_stmt_creator_t(
            self, self.controller, self.controller.result_variable,
            self.controller.return_variables)

        tmpl_values['post_call'] = os.linesep + self.indent(
            os.linesep.join(cntrl.post_call))
        if return_stmt_creator.pre_return_code:
            tmpl_values['post_call'] \
                = os.linesep.join([ tmpl_values['post_call']
                                    , self.indent( return_stmt_creator.pre_return_code )])
        tmpl_values['return'] = os.linesep + self.indent(
            return_stmt_creator.statement)

        f_def = self.controller.template.substitute(tmpl_values)
        return remove_duplicate_linesep(f_def)
Ejemplo n.º 13
0
 def pre_return_code(self):
     if None is self.__pre_return_code:
         if declarations.is_void( self.__function.return_type ) \
            and ( self.__function.call_policies.is_default() \
                  or False == bool( self.__controller.return_variables ) ):
             self.__pre_return_code = ''
         elif self.__function.call_policies.is_default():
             self.__pre_return_code = ''
         else:
             c_p_typedef = 'typedef %s %s;' \
                           % ( self.__function.call_policies.create_template_arg( self.__creator )
                               , self.__call_policy_alias )
             self.__pre_return_code = c_p_typedef
     return self.__pre_return_code
Ejemplo n.º 14
0
 def pre_return_code( self ):
     if None is self.__pre_return_code:
         if declarations.is_void( self.__function.return_type ) \
            and ( self.__function.call_policies.is_default() \
                  or False == bool( self.__controller.return_variables ) ):
             self.__pre_return_code = ''
         elif self.__function.call_policies.is_default():
             self.__pre_return_code = ''
         else:
             c_p_typedef = 'typedef %s %s;' \
                           % ( self.__function.call_policies.create_template_arg( self.__creator )
                               , self.__call_policy_alias )
             self.__pre_return_code = c_p_typedef
     return self.__pre_return_code
Ejemplo n.º 15
0
    def create_override(self):
        cntrl = self.controller.override_controller

        tmpl_values = dict()
        tmpl_values['return_type'] = self.declaration.return_type.decl_string
        tmpl_values['function_name'] = self.declaration.name
        tmpl_values['arg_declarations'] = self.args_override_declaration()
        tmpl_values['constness'] = ''
        if self.declaration.has_const:
            tmpl_values['constness'] = ' const '
        tmpl_values['throw'] = self.throw_specifier_code()
        tmpl_values['py_function_var'] = cntrl.py_function_var
        tmpl_values['function_alias'] = self.declaration.alias
        tmpl_values['declare_py_variables'] \
            = os.linesep + os.linesep.join( map( lambda var: self.indent( var.declare_var_string(), 2 )
                                                 , cntrl.py_variables ) )

        tmpl_values['py_pre_call'] = os.linesep + self.indent(
            os.linesep.join(cntrl.py_pre_call), 2)
        tmpl_values['py_post_call'] = os.linesep + self.indent(
            os.linesep.join(cntrl.py_post_call), 2)
        tmpl_values['py_arg_expressions'] = ''
        if cntrl.py_arg_expressions:
            tmpl_values['py_arg_expressions'] \
                = ', ' + self.PARAM_SEPARATOR.join( cntrl.py_arg_expressions )

        tmpl_values[
            'save_py_result'] = "bpl::object %s = " % cntrl.py_result_variable.name
        tmpl_values['py_return'] = ''
        tmpl_values['cpp_return'] = ''
        if not declarations.is_void(self.declaration.return_type):
            tmpl_values['py_return'] \
                = 'return bpl::extract< %(type)s >( pyplus_conv::get_out_argument( %(py_result)s, 0 ) );' \
                  % { 'type' : self.declaration.return_type.decl_string
                    , 'py_result' : cntrl.py_result_variable.name }
            tmpl_values['cpp_return'] = 'return '

        tmpl_values['wrapped_class'] = self.wrapped_class_identifier()

        arg_utils = calldef_utils.argument_utils_t(
            self.declaration, algorithm.make_id_creator(self),
            self.declaration.arguments)
        tmpl_values['cpp_arg_expressions'] = arg_utils.call_args()

        f_def_code = cntrl.template.substitute(tmpl_values)
        return remove_duplicate_linesep(f_def_code)
Ejemplo n.º 16
0
    def create_fun_definition(self):
        cntrl = self.controller

        make_object = algorithm.create_identifier( self, 'pyplusplus::call_policies::make_object' )
        make_tuple = algorithm.create_identifier( self, 'boost::python::make_tuple' )
        
        tmpl_values = dict()

        tmpl_values['unique_function_name'] = self.wrapper_name()
        tmpl_values['return_type'] = self.controller.wrapper_return_type.decl_string
        tmpl_values['arg_declarations'] = self.args_declaration()
        
        tmpl_values['declare_variables'] \
            = os.linesep + os.linesep.join( map( lambda var: self.indent( var.declare_var_string() )
                                                 , cntrl.variables ) )
                
        tmpl_values['pre_call'] = os.linesep + self.indent( os.linesep.join( cntrl.pre_call ) )

        tmpl_values['save_result'] = ''
        if not declarations.is_void( self.declaration.return_type ):
            tmpl_tmp = '%(type)s %(name)s = '
            if declarations.is_reference( self.declaration.return_type ):
                tmpl_tmp = tmpl_tmp + '&'

            tmpl_values['save_result'] = tmpl_tmp \
                                         % { 'type': cntrl.result_variable.type.decl_string
                                             , 'name' : cntrl.result_variable.name }

        tmpl_values['function_name'] = self.resolve_function_ref()
        tmpl_values['arg_expressions'] = self.PARAM_SEPARATOR.join( cntrl.arg_expressions )
        return_stmt_creator = calldef_utils.return_stmt_creator_t( self
                                    , self.controller
                                    , self.controller.result_variable
                                    , self.controller.return_variables )

        tmpl_values['post_call'] = os.linesep + self.indent( os.linesep.join( cntrl.post_call ) )
        if return_stmt_creator.pre_return_code:
            tmpl_values['post_call'] \
                = os.linesep.join([ tmpl_values['post_call']
                                    , self.indent( return_stmt_creator.pre_return_code )])
        tmpl_values['return'] = os.linesep + self.indent( return_stmt_creator.statement )
            
        f_def = self.controller.template.substitute(tmpl_values)
        return remove_duplicate_linesep( f_def )
Ejemplo n.º 17
0
    def create_override(self):
        cntrl = self.controller.override_controller       
        
        tmpl_values = dict()
        tmpl_values['return_type' ] = self.declaration.return_type.decl_string 
        tmpl_values['function_name'] = self.declaration.name
        tmpl_values['arg_declarations'] = self.args_override_declaration()
        tmpl_values['constness'] = ''
        if self.declaration.has_const:
            tmpl_values['constness'] = ' const '
        tmpl_values['throw'] = self.throw_specifier_code()        
        tmpl_values['py_function_var'] = cntrl.py_function_var
        tmpl_values['function_alias'] = self.declaration.alias
        tmpl_values['declare_py_variables'] \
            = os.linesep + os.linesep.join( map( lambda var: self.indent( var.declare_var_string(), 2 )
                                                 , cntrl.py_variables ) )

        tmpl_values['py_pre_call'] = os.linesep + self.indent( os.linesep.join( cntrl.py_pre_call ), 2 )
        tmpl_values['py_post_call'] = os.linesep + self.indent( os.linesep.join( cntrl.py_post_call ), 2 )
        tmpl_values['py_arg_expressions'] = ''
        if cntrl.py_arg_expressions:
            tmpl_values['py_arg_expressions'] \
                = ', ' + self.PARAM_SEPARATOR.join( cntrl.py_arg_expressions )
            
        tmpl_values['save_py_result'] = "bpl::object %s = " % cntrl.py_result_variable.name
        tmpl_values['py_return'] = ''
        tmpl_values['cpp_return'] = ''
        if not declarations.is_void( self.declaration.return_type ):
            tmpl_values['py_return'] \
                = 'return bpl::extract< %(type)s >( pyplus_conv::get_out_argument( %(py_result)s, 0 ) );' \
                  % { 'type' : self.declaration.return_type.decl_string
                    , 'py_result' : cntrl.py_result_variable.name }
            tmpl_values['cpp_return'] = 'return '

        tmpl_values['wrapped_class'] = self.wrapped_class_identifier()

        arg_utils = calldef_utils.argument_utils_t( self.declaration
                                                   , algorithm.make_id_creator( self )
                                                   , self.declaration.arguments )
        tmpl_values['cpp_arg_expressions'] = arg_utils.call_args()

        f_def_code = cntrl.template.substitute(tmpl_values)
        return remove_duplicate_linesep( f_def_code )
Ejemplo n.º 18
0
def check_args_exportable ( function, ns ):
    """ Look at each argument in the function and determine that we have exported it 
    or it's a special.
    """
    ret = True
    Specials = ['::Ogre::String']
    for a in function.arguments:
        rawarg =  declarations.remove_declarated(
            declarations.remove_const( 
                declarations.remove_reference( 
                    declarations.remove_pointer ( a.type ))))
                                               
        ## now check if the arg is a fundemental type (int float etc), a void
        ##  or a special ..
        if declarations.is_arithmetic (rawarg)\
                or declarations.is_void(rawarg)\
                or declarations.is_enum(rawarg):
            pass
        elif 'Ogre::' in a.type.decl_string: # assume it's a class and needs checking
            name = a.type.decl_string.split()[0] # let's grab the actual class name
            if name in Specials:  # we know that the classes in specials DO exist 
                pass
            else:
                try:
                    tcls = ns.class_(name)
                    if not tcls.exportable or tcls.ignore or type ( tcls.parent ) != decl_wrappers.namespace_wrapper.namespace_t: 
##                        print "check_args_exportable: NOT EXPORTABLE:", tcls, tcls.exportable, tcls.ignore , type ( tcls.parent )  
                        ret = False
                        break
                    else:
                        pass # print name, "IS exportable"
                except:
                    print "check_args_exportable: unable to find:", name
                    ret = False
        else:
            print "check_args_exportable: NOT SURE...", a, a.type, type(a.type)
        
    return ret            
Ejemplo n.º 19
0
def ManualFixes ( mb ):    

    global_ns = mb.global_ns
    main_ns = global_ns
    funcs = [
           '::ssgBranch::getByName'
           ,'::ssgBranch::getByPath'
           ,'::ssgEntity::getByName'
           ,'::ssgEntity::getByPath'
        ]
#     for f in funcs:  
#         main_ns.member_functions(f).call_policies = call_policies.default_call_policies()

    # bug in Py++  where is uses the wrong call policies on a transformed function
    for fun in main_ns.member_functions(allow_empty=True):
        if fun.transformations:
            if declarations.is_pointer(fun.return_type ) :
                rawarg =  declarations.remove_declarated(
                        declarations.remove_const( 
                            declarations.remove_reference( 
                                declarations.remove_pointer ( fun.return_type ))))
                if not declarations.is_arithmetic (rawarg) and not declarations.is_void(rawarg):
                    fun.call_policies = call_policies.default_call_policies()
                    print "Changed call policies on ", fun
Ejemplo n.º 20
0
 def restype_code(self):
     if not declarations.is_void( self.ftype.return_type ):
         return ctypes_formatter.as_ctype( self.ftype.return_type, self.top_parent.treat_char_ptr_as_binary_data )
     else:
         return ''
Ejemplo n.º 21
0
def Auto_Functional_Transformation ( mb, ignore_funs=[], special_vars=[]): 
    toprocess = []   
    aliases={}
    for fun in mb.member_functions(allow_empty=True):
        toprocess.append( fun )
    for fun in mb.free_functions(allow_empty=True):
        toprocess.append( fun )
    for fun in toprocess:
        fun_demangled = fun.demangled  # need to check as extern functions don't have demangled name...
        if fun_demangled: 
#         try:   # ugly wrapping in a try :(    
            fullname = fun.demangled.split('(')[0]
            if fullname not in ignore_funs and not fun.ignore:
                outputonly = False
                arg_position = 0
                trans=[]
                desc=""
                ft_type = None
                ctypes_conversion = False
                for arg in fun.arguments:
                    rawarg =  declarations.remove_declarated(
                        declarations.remove_const( 
                            declarations.remove_reference( 
                                declarations.remove_pointer ( arg.type ))))
                                               
                    
                    ## now check if the arg is a fundemental type (int float etc), a void
                    ##  or a special ..
                    if declarations.is_arithmetic (rawarg)\
                            or declarations.is_void(rawarg)\
                            or arg.type.decl_string in special_vars:
                        if declarations.is_pointer(arg.type):   #we convert any pointers to unsigned int's
                            # now look to see if it's a char * and if so we treat it as a string..
# #                             print "**" , declarations.remove_alias( rawarg ), declarations.type_traits.create_cv_types( declarations.cpptypes.char_t())
                            if declarations.remove_alias( rawarg ) in declarations.type_traits.create_cv_types( declarations.cpptypes.char_t() ): 
                                print ("MATCHED CString", fun)
                                trans.append( ft.input_c_string(arg_position, 4096 ) )
                                desc = desc +"Argument: "+arg.name+ "( pos:" + str(arg_position) + " - " +\
                                    arg.type.decl_string + " ) takes a python string. \\n"
                                ctypes_conversion = True                                
                                ctypes_arg = arg.type.decl_string.split()[0]
                                ft_type = 'CTYPES'
                            else:
                                trans.append( ft.modify_type(arg_position,_ReturnUnsignedInt ) )
                                desc = desc +"Argument: "+arg.name+ "( pos:" + str(arg_position) + " - " +\
                                    arg.type.decl_string + " ) takes a CTypes.addressof(xx). \\n"
                                ctypes_conversion = True                                
                                ctypes_arg = arg.type.decl_string.split()[0]
                                ft_type = 'CTYPES'
                        elif declarations.is_reference(arg.type)and not declarations.is_const(declarations.remove_reference( arg.type)):  # seen functions passing const ref's 
                            trans.append( ft.inout(arg_position ) )
                            desc = desc + "Argument: "+arg.name+ "( pos:" + str(arg_position) + " - " +\
                                arg.type.decl_string + " ) converted to an input/output (change to return types).\\n"
                            ft_type = 'INOUT'                                
                        elif declarations.is_reference(arg.type):
                            print ("Warning: - possible code change.", fun,arg," not wrapped as const reference to base type invalid")
                        else:
                            pass # it isn't a pointer or reference so doesn't need wrapping
                    else:
                        pass # it's not a var we need to handle
                    arg_position += 1
                if trans:
                    const_return = False #  declarations.is_const(fun)
                    if fun.decl_string.endswith('const'):
                        const_return=True
                    simple_return = declarations.is_arithmetic(fun.return_type) or declarations.is_void(fun.return_type)
                    nonpublic_destructor = declarations.is_class(fun.parent) and declarations.has_destructor(fun.parent) and\
                            not declarations.has_public_destructor(fun.parent)
                
                    if fun.documentation or fun.transformations:   # it's already be tweaked:
                        print ("AUTOFT ERROR: Duplicate Tranforms.", fun, fun.documentation)
                        
                    # if the class has a protected destruction AND the return value is const or a non arithmatic value then exclude it.
                    elif nonpublic_destructor and const_return:
                        print ("AUTOFT ERROR Const: Parent has non public destructor and const return.", fun.parent.name, fun.return_type.decl_string, fun)
                        fun.documentation="Python-Ogre Warning: function required transformation - not possible due to non public destructor and const return value.."
                    elif nonpublic_destructor and not simple_return:
                        print ("AUTOFT ERROR Const: Parent has non public destructor and complex return value.", fun.parent.name, fun.return_type.decl_string, fun)
                        fun.documentation="Python-Ogre Warning: function required transformation - not possible due to non public destructor and complex return value.."
                    else:
                        new_alias = fun.name
                        if ctypes_conversion:   # only manage name changes if ctypes changing
                            # now lets look for a duplicate function name with the same number arguments
                            f= [None]*len(fun.arguments)
                            s = mb.member_functions("::" + fullname, arg_types=f, allow_empty=True)
                            if len (s) > 1: 
                                # there are duplicate names so need to create something unique
                                ctypes_arg = ctypes_arg.replace("::", "_") # to clean up function names...
                                new_alias = fun.name + ctypes_arg[0].upper() + ctypes_arg[1:]
                                # now for REAL ugly code -- we have faked a new alias and it may not be unique
                                # so we track previous alias + class name to ensure unique names are generated
                                keyname = fullname + new_alias # we use the full class + function name + alias as the key
                                if keyname in aliases: # already exists, need to fake another version..
                                    new_alias = new_alias + "_" + str( aliases[keyname] )
                                    aliases[keyname] = aliases[keyname] + 1
                                else:
                                    aliases[keyname] = 1   
                                desc = desc + "\\\nWARNING FUNCTION NAME CHANGE - from "+fun.name + " -- " + fun.decl_string +" to " + new_alias + " \\n"                                    
                                print ("INFO: Adjusting Alias as multiple overlapping functions:", new_alias)
                            
                        print ("AUTOFT OK: Tranformed ", fun.return_type.decl_string, fun, "(",new_alias,")")
                        fun.add_transformation ( * trans ,  **{"alias":new_alias}  )
                        fun.documentation = docit ("Auto Modified Arguments:",
                                                        desc, "...")
Ejemplo n.º 22
0
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"