Пример #1
0
 def _generate_constructor(self):
     result = []
     result.append( '(' )
     result.append( ' "%s"' % self.alias )
     if self.documentation:
         result.append( ', %s' % self.documentation )
     used_init = None
     inits = filter( lambda x: isinstance( x, calldef.constructor_t ), self.creators )
     if ( self.declaration.is_abstract \
          or not declarations.has_any_non_copyconstructor(self.declaration) ) \
        and not self.wrapper \
        or ( declarations.has_destructor( self.declaration )
             and not declarations.has_public_destructor( self.declaration ) ):
         #TODO: or self.declaration has public constructor and destructor
         result.append( ", " )
         result.append( algorithm.create_identifier( self, '::boost::python::no_init' ) )
     elif not declarations.has_trivial_constructor( self.declaration ):
         if inits:
             used_init = inits[0]
             result.append( ", " )
             result.append( used_init.create_init_code() )
         elif self.declaration.indexing_suite:
             pass #in this case all constructors are exposed by indexing suite
         else:#it is possible to class to have public accessed constructor
              #that could not be exported by boost.python library
              #for example constructor takes as argument pointer to function
             result.append( ", " )
             result.append( algorithm.create_identifier( self, '::boost::python::no_init' ) )
     else:
         pass
     result.append( ' )' )
     return ( ''.join( result ), used_init )
Пример #2
0
    def _get_no_init( self ):
        if None is self._no_init and False == bool( self.indexing_suite ):
            #select all public constructors and exclude copy constructor
            cs = self.constructors( lambda c: not c.is_copy_constructor and c.access_type == 'public'
                                    , recursive=False, allow_empty=True )

            has_suitable_constructor = bool( cs )
            if cs and len(cs) == 1 and cs[0].is_trivial_constructor and self.find_noncopyable_vars():
                has_suitable_constructor = False

            has_nonpublic_destructor = declarations.has_destructor( self ) \
                                       and not declarations.has_public_destructor( self )

            trivial_constructor = self.find_trivial_constructor()

            if has_nonpublic_destructor \
               or ( self.is_abstract and not self.is_wrapper_needed() ) \
               or not has_suitable_constructor:
                self._no_init = True
            elif not trivial_constructor or trivial_constructor.access_type != 'public':
                exportable_cs = [c for c in cs if c.exportable and c.ignore == False]
                if not exportable_cs:
                    self._no_init = True
            else:
                pass
        if None is self._no_init:
            self._no_init = False
        return self._no_init
Пример #3
0
    def _get_no_init(self):
        if None is self._no_init and False == bool(self.indexing_suite):
            #select all public constructors and exclude copy constructor
            cs = self.constructors(lambda c: not c.is_copy_constructor and c.
                                   access_type == 'public',
                                   recursive=False,
                                   allow_empty=True)

            has_suitable_constructor = bool(cs)
            if cs and len(cs) == 1 and cs[
                    0].is_trivial_constructor and self.find_noncopyable_vars():
                has_suitable_constructor = False

            has_nonpublic_destructor = declarations.has_destructor( self ) \
                                       and not declarations.has_public_destructor( self )

            trivial_constructor = self.find_trivial_constructor()

            if has_nonpublic_destructor \
               or ( self.is_abstract and not self.is_wrapper_needed() ) \
               or not has_suitable_constructor:
                self._no_init = True
            elif not trivial_constructor or trivial_constructor.access_type != 'public':
                exportable_cs = filter(
                    lambda c: c.exportable and c.ignore == False, cs)
                if not exportable_cs:
                    self._no_init = True
            else:
                pass
        if None is self._no_init:
            self._no_init = False
        return self._no_init
Пример #4
0
 def customize(self, mb):
     access_type_matcher = declarations.access_type_matcher_t
     mb.global_ns.include()
     mb.classes(access_type_matcher('protected')).exclude()
     mb.vars(access_type_matcher('protected')).exclude()
     mb.class_(lambda d: d.name.startswith('buffered_value')).exclude()
     for cls in mb.classes():
         if declarations.has_destructor(cls) \
            and cls.calldef(lambda d: d.name.startswith('~'), recursive=False).access_type == 'protected':
             print('protected destructor: ', str(cls))
             cls.constructors().exclude()
             cls.noncopyable = True
Пример #5
0
 def customize(self, mb ):
     access_type_matcher = declarations.access_type_matcher_t
     mb.global_ns.include()
     mb.classes( access_type_matcher('protected') ).exclude()
     mb.vars( access_type_matcher('protected') ).exclude()
     mb.class_( lambda d: d.name.startswith( 'buffered_value' ) ).exclude()
     for cls in mb.classes():
         if declarations.has_destructor(cls) \
            and cls.calldef(lambda d: d.name.startswith('~'), recursive=False).access_type == 'protected':
             print 'protected destructor: ', str( cls )
             cls.constructors().exclude()
             cls.noncopyable =  True
Пример #6
0
    def __call__(self, variable, hint=None):
        if not isinstance(variable, declarations.variable_t):
            return None

        assert hint in ('get', 'set')

        if not declarations.is_reference(variable.decl_type):
            return None

        no_ref = declarations.remove_reference(variable.decl_type)
        base_type = declarations.remove_const(no_ref)
        if python_traits.is_immutable(base_type):
            #the relevant code creator will generate code, that will return this member variable
            #by value
            return decl_wrappers.default_call_policies()

        if not isinstance(base_type, declarations.declarated_t):
            return None

        base_type = declarations.remove_alias(base_type)
        declaration = base_type.declaration

        if declarations.is_class_declaration(declaration):
            return None

        if declaration.is_abstract:
            return None
        if declarations.has_destructor(
                declaration
        ) and not declarations.has_public_destructor(declaration):
            return None
        if not declarations.has_copy_constructor(declaration):
            return None
        if hint == 'get':
            #if we rich this line, it means that we are able to create an obect using
            #copy constructor.
            if declarations.is_const(no_ref):
                return decl_wrappers.return_value_policy(
                    decl_wrappers.copy_const_reference)
            else:
                return decl_wrappers.return_value_policy(
                    decl_wrappers.copy_non_const_reference)
        else:
            return decl_wrappers.default_call_policies()
Пример #7
0
    def _get_has_setter( self ):
        if declarations.is_const( declarations.remove_reference( self.declaration.type ) ):
            return False
        elif python_traits.is_immutable( self._get_exported_var_type() ):
            return True
        else:
            pass

        no_ref = declarations.remove_reference( self.declaration.type )
        no_const = declarations.remove_const( no_ref )
        base_type = declarations.remove_alias( no_const )
        if not isinstance( base_type, declarations.declarated_t ):
            return True #TODO ????
        decl = base_type.declaration
        if decl.is_abstract:
            return False
        if declarations.has_destructor( decl ) and not declarations.has_public_destructor( decl ):
            return False
        if not declarations.has_copy_constructor(decl):
            return False
        return True
    def _get_has_setter( self ):
        if declarations.is_const( declarations.remove_reference( self.declaration.type ) ):
            return False
        elif python_traits.is_immutable( self._get_exported_var_type() ):
            return True
        else:
            pass

        no_ref = declarations.remove_reference( self.declaration.type )
        no_const = declarations.remove_const( no_ref )
        base_type = declarations.remove_alias( no_const )
        if not isinstance( base_type, declarations.declarated_t ):
            return True #TODO ????
        decl = base_type.declaration
        if decl.is_abstract:
            return False
        if declarations.has_destructor( decl ) and not declarations.has_public_destructor( decl ):
            return False
        if not declarations.has_copy_constructor(decl):
            return False
        return True
Пример #9
0
    def __call__( self, variable, hint=None ):
        if not isinstance( variable, declarations.variable_t ):
            return None

        assert hint in ( 'get', 'set' )
        
        if not declarations.is_reference( variable.type ):
            return None
        
        no_ref = declarations.remove_reference( variable.type )
        base_type = declarations.remove_const( no_ref )
        if python_traits.is_immutable( base_type ):
            #the relevant code creator will generate code, that will return this member variable
            #by value
            return decl_wrappers.default_call_policies()
        
        if not isinstance( base_type, declarations.declarated_t ):
            return None
        
        base_type = declarations.remove_alias( base_type )
        decl = base_type.declaration
        
        if declarations.is_class_declaration( decl ):
            return None
        
        if decl.is_abstract:
            return None
        if declarations.has_destructor( decl ) and not declarations.has_public_destructor( decl ): 
            return None
        if not declarations.has_copy_constructor(decl):
            return None
        if hint == 'get':
            #if we rich this line, it means that we are able to create an obect using
            #copy constructor. 
            if declarations.is_const( no_ref ):
                return decl_wrappers.return_value_policy( decl_wrappers.copy_const_reference )
            else:
                return decl_wrappers.return_value_policy( decl_wrappers.copy_non_const_reference )
        else:
            return decl_wrappers.default_call_policies()
Пример #10
0
 def _generate_constructor(self):
     result = []
     result.append('(')
     result.append(' "%s"' % self.alias)
     if self.documentation:
         result.append(', %s' % self.documentation)
     used_init = None
     inits = filter(lambda x: isinstance(x, calldef.constructor_t),
                    self.creators)
     if ( self.declaration.is_abstract \
          or not declarations.has_any_non_copyconstructor(self.declaration) ) \
        and not self.wrapper \
        or ( declarations.has_destructor( self.declaration )
             and not declarations.has_public_destructor( self.declaration ) ):
         #TODO: or self.declaration has public constructor and destructor
         result.append(", ")
         result.append(
             algorithm.create_identifier(self, '::boost::python::no_init'))
     elif not declarations.has_trivial_constructor(self.declaration):
         if inits:
             used_init = inits[0]
             result.append(", ")
             result.append(used_init.create_init_code())
         elif self.declaration.indexing_suite:
             pass  #in this case all constructors are exposed by indexing suite
         else:  #it is possible to class to have public accessed constructor
             #that could not be exported by boost.python library
             #for example constructor takes as argument pointer to function
             result.append(", ")
             result.append(
                 algorithm.create_identifier(self,
                                             '::boost::python::no_init'))
     else:
         pass
     result.append(' )')
     return (''.join(result), used_init)
Пример #11
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, "...")