def is_related( t1, t2 ): """Check whether two types\\classes t1 and t2 could introduce the problem""" if declarations.is_pointer( t1 ) and declarations.is_pointer( t2 ): return registration_order.is_related( declarations.remove_pointer( t1 ) , declarations.remove_pointer( t2 ) ) elif declarations.is_pointer( t1 ) and not declarations.is_pointer( t2 ): t1 = declarations.remove_cv( declarations.remove_pointer( t1 ) ) t2 = declarations.remove_cv( t2 ) if declarations.is_same( t1, t2 ): return 1 elif not declarations.is_pointer( t1 ) and declarations.is_pointer( t2 ): t1 = declarations.remove_cv( t1 ) t2 = declarations.remove_cv( declarations.remove_pointer( t2 ) ) if declarations.is_same( t1, t2 ): return -1 else: #not is_pointer( t1 ) and not is_pointer( t2 ): if declarations.is_integral( t1 ) and not declarations.is_bool( t1 ) \ and declarations.is_bool( t2 ): return -1 elif declarations.is_bool( t1 ) \ and declarations.is_integral( t2 ) and not declarations.is_bool( t2 ): return 1 else: pass return None
def filter_decls(mb): mb.global_ns.exclude() fx_ns = mb.namespace( 'FX' ) fx_ns.include() fx_ns.decls( declarations_to_exclude.is_excluded ).exclude() fx_ns.decls( lambda decl: decl.name.startswith('FXIPCMsgHolder') ).exclude() fx_ns.namespace( 'Pol' ).exclude() fx_ns.decls( files_to_exclude.is_excluded ).exclude() fx_ns.class_( 'QValueList<FX::Pol::knowReferrers::ReferrerEntry>').exclude() try: fx_ns.variables( 'metaClass').exclude() except: pass try: fx_ns.class_( 'QPtrVector<FX::Generic::BoundFunctorV>').exclude() except: pass #Niall? wrapper for this function could not be compiled #TnFXSQLDBStatement = fx_ns.class_( 'TnFXSQLDBStatement' ) #TnFXSQLDBStatement.member_function( name='bind', arg_types=[None,None,None] ).exclude() for func in fx_ns.calldefs(): #I want to exclude all functions that returns pointer to pointer #and returns pointer to fundamental type if declarations.is_pointer( func.return_type ): temp = declarations.remove_pointer( func.return_type ) if declarations.is_fundamental( temp ) and not declarations.is_const(temp): func.exclude() temp = declarations.remove_cv( func.return_type ) temp = declarations.remove_pointer( temp ) if declarations.is_pointer( temp ): func.exclude()
def is_related(t1, t2): """Check whether two types\\classes t1 and t2 could introduce the problem""" if declarations.is_pointer(t1) and declarations.is_pointer(t2): return registration_order.is_related( declarations.remove_pointer(t1), declarations.remove_pointer(t2)) elif declarations.is_pointer(t1) and not declarations.is_pointer(t2): t1 = declarations.remove_cv(declarations.remove_pointer(t1)) t2 = declarations.remove_cv(t2) if declarations.is_same(t1, t2): return 1 elif not declarations.is_pointer(t1) and declarations.is_pointer(t2): t1 = declarations.remove_cv(t1) t2 = declarations.remove_cv(declarations.remove_pointer(t2)) if declarations.is_same(t1, t2): return -1 else: #not is_pointer( t1 ) and not is_pointer( t2 ): if declarations.is_integral( t1 ) and not declarations.is_bool( t1 ) \ and declarations.is_bool( t2 ): return -1 elif declarations.is_bool( t1 ) \ and declarations.is_integral( t2 ) and not declarations.is_bool( t2 ): return 1 else: pass return None
def test_function_pointer(self): """ Test working with pointers and function pointers. """ decls = parser.parse([self.header], self.config) global_ns = declarations.get_global_namespace(decls) # Test on a function pointer criteria = declarations.variable_matcher(name="func1") variables = declarations.matcher.find(criteria, global_ns) self.assertTrue(variables[0].name == "func1") self.assertTrue( isinstance(variables[0].decl_type, declarations.pointer_t)) self.assertTrue( str(variables[0].decl_type) == "void (*)( int,double )") self.assertTrue( declarations.is_calldef_pointer(variables[0].decl_type)) self.assertTrue( isinstance(declarations.remove_pointer(variables[0].decl_type), declarations.free_function_type_t)) # Get the function (free_function_type_t) and test the return and # argument types function = variables[0].decl_type.base self.assertTrue(isinstance(function.return_type, declarations.void_t)) self.assertTrue( isinstance(function.arguments_types[0], declarations.int_t)) self.assertTrue( isinstance(function.arguments_types[1], declarations.double_t)) # Test on a normal pointer criteria = declarations.variable_matcher(name="myPointer") variables = declarations.matcher.find(criteria, global_ns) self.assertTrue(variables[0].name == "myPointer") self.assertTrue( isinstance(variables[0].decl_type, declarations.pointer_t)) self.assertFalse( declarations.is_calldef_pointer(variables[0].decl_type)) self.assertTrue( isinstance(declarations.remove_pointer(variables[0].decl_type), declarations.volatile_t)) # Test on function pointer in struct (x8) for d in global_ns.declarations: if d.name == "x8": self.assertTrue( isinstance(d.decl_type, declarations.pointer_t)) self.assertTrue(declarations.is_calldef_pointer(d.decl_type)) self.assertTrue( isinstance( declarations.remove_pointer(d.decl_type), declarations.member_function_type_t)) self.assertTrue( str(declarations.remove_pointer(d.decl_type)) == "void ( ::some_struct_t::* )( )")
def _exportable_impl(self): if self.transformations: # It is possible that the function asked for the user attention. # The user paid attention and created a transformation. # Py++ should be silent in this case. return "" if not self.parent.name: return messages.W1057 % str(self) all_types = [arg.type for arg in self.arguments] all_types.append(self.return_type) for some_type in all_types: if isinstance(some_type, declarations.ellipsis_t): return messages.W1053 % str(self) units = declarations.decompose_type(some_type) ptr2functions = filter(lambda unit: isinstance(unit, declarations.calldef_type_t), units) if ptr2functions: return messages.W1004 # Function that take as agrument some instance of non public class # will not be exported. Same to the return variable if isinstance(units[-1], declarations.declarated_t): dtype = units[-1] if isinstance(dtype.declaration.parent, declarations.class_t): if dtype.declaration not in dtype.declaration.parent.public_members: return messages.W1005 no_ref = declarations.remove_reference(some_type) no_ptr = declarations.remove_pointer(no_ref) no_const = declarations.remove_const(no_ptr) if declarations.is_array(no_const): return messages.W1006 return self._exportable_impl_derived()
def remove_ref_or_ptr(type_): if declarations.is_pointer(type_): return declarations.remove_pointer(type_) elif declarations.is_reference(type_): return declarations.remove_reference(type_) else: raise TypeError('Type should be reference or pointer, got %s.' % type_)
def _exportable_impl(self): if not self.name: return messages.W1033 if self.bits == 0 and self.name == "": return messages.W1034 if declarations.is_array( self.type) and declarations.array_size(self.type) < 1: return messages.W1045 type_ = declarations.remove_alias(self.type) type_ = declarations.remove_const(type_) if declarations.is_pointer(type_): if self.type_qualifiers.has_static: return messages.W1035 if python_traits.is_immutable(type_.base): return messages.W1036 units = declarations.decompose_type(type_) ptr2functions = filter( lambda unit: isinstance(unit, declarations.calldef_type_t), units) if ptr2functions: return messages.W1037 type_ = declarations.remove_pointer(type_) if declarations.class_traits.is_my_case(type_): cls = declarations.class_traits.get_declaration(type_) if not cls.name: return messages.W1038 if isinstance(self.parent, declarations.class_t): if self.access_type != declarations.ACCESS_TYPES.PUBLIC: return messages.W1039 return ''
def remove_ref_or_ptr( type_ ): if declarations.is_pointer( type_ ): return declarations.remove_pointer( type_ ) elif declarations.is_reference( type_ ): return declarations.remove_reference( type_ ) else: raise TypeError( 'Type should be reference or pointer, got %s.' % type_ )
def _update_containers_db( self, type_ ): #will return True is type was treated type_ = declarations.remove_alias( type_ ) type_ = declarations.remove_pointer( type_ ) type_ = declarations.remove_reference( type_ ) type_ = declarations.remove_cv( type_ ) type_ = declarations.remove_declarated( type_ ) class_traits = declarations.class_traits class_declaration_traits = declarations.class_declaration_traits if not class_traits.is_my_case( type_ ) and not class_declaration_traits.is_my_case( type_ ): return False if class_traits.is_my_case( type_ ): container_cls = class_traits.get_declaration( type_ ) else: container_cls = class_declaration_traits.get_declaration( type_ ) if None is container_cls.indexing_suite: return False try: #check extraction of element type from container container_cls.indexing_suite.element_type except RuntimeError: decls_logger = _logging_.loggers.declarations if not messages.filter_disabled_msgs([messages.W1042], container_cls.disabled_messages ): return #user disabled property warning decls_logger.warn( "%s;%s" % ( container_cls, messages.W1042 ) ) self.__containers.add( container_cls ) return True
def _exportable_impl( self ): if self.transformations: #It is possible that the function asked for the user attention. #The user paid attention and created a transformation. #Py++ should be silent in this case. return '' if not self.parent.name: return messages.W1057 % str( self ) all_types = [ arg.decl_type for arg in self.arguments ] all_types.append( self.return_type ) for some_type in all_types: if isinstance( some_type, declarations.ellipsis_t ): return messages.W1053 % str( self ) units = declarations.decompose_type( some_type ) ptr2functions = [unit for unit in units if isinstance( unit, declarations.calldef_type_t )] if ptr2functions: return messages.W1004 #Function that take as agrument some instance of non public class #will not be exported. Same to the return variable if isinstance( units[-1], declarations.declarated_t ): dtype = units[-1] if isinstance( dtype.declaration.parent, declarations.class_t ): if dtype.declaration not in dtype.declaration.parent.public_members: return messages.W1005 no_ref = declarations.remove_reference( some_type ) no_ptr = declarations.remove_pointer( no_ref ) no_const = declarations.remove_const( no_ptr ) if declarations.is_array( no_const ): return messages.W1006 return self._exportable_impl_derived()
def _update_containers_db(self, type_): #will return True is type was treated type_ = declarations.remove_alias(type_) type_ = declarations.remove_pointer(type_) type_ = declarations.remove_reference(type_) type_ = declarations.remove_cv(type_) type_ = declarations.remove_declarated(type_) class_traits = declarations.class_traits class_declaration_traits = declarations.class_declaration_traits if not class_traits.is_my_case( type_) and not class_declaration_traits.is_my_case(type_): return False if class_traits.is_my_case(type_): container_cls = class_traits.get_declaration(type_) else: container_cls = class_declaration_traits.get_declaration(type_) if None is container_cls.indexing_suite: return False try: #check extraction of element type from container container_cls.indexing_suite.element_type except RuntimeError: decls_logger = _logging_.loggers.declarations if not messages.filter_disabled_msgs( [messages.W1042], container_cls.disabled_messaged): return #user disabled property warning decls_logger.warn("%s;%s" % (container_cls, messages.W1042)) self.__containers.add(container_cls) return True
def _exportable_impl( self ): if not self.parent.name: return messages.W1057 % str( self ) all_types = [ arg.type for arg in self.arguments ] all_types.append( self.return_type ) for some_type in all_types: if isinstance( some_type, declarations.ellipsis_t ): return messages.W1053 % str( self ) units = declarations.decompose_type( some_type ) ptr2functions = filter( lambda unit: isinstance( unit, declarations.calldef_type_t ) , units ) if ptr2functions: return messages.W1004 #Function that take as agrument some instance of non public class #will not be exported. Same to the return variable if isinstance( units[-1], declarations.declarated_t ): dtype = units[-1] if isinstance( dtype.declaration.parent, declarations.class_t ): if dtype.declaration not in dtype.declaration.parent.public_members: return messages.W1005 no_ref = declarations.remove_reference( some_type ) no_ptr = declarations.remove_pointer( no_ref ) no_const = declarations.remove_const( no_ptr ) if declarations.is_array( no_const ): return messages.W1006 return self._exportable_impl_derived()
def _exportable_impl( self ): if not self.name: return messages.W1033 if self.bits == 0 and self.name == "": return messages.W1034 if declarations.is_array( self.type ) and declarations.array_size( self.type ) < 1: return messages.W1045 type_ = declarations.remove_alias( self.type ) type_ = declarations.remove_const( type_ ) if declarations.is_pointer( type_ ): if self.type_qualifiers.has_static: return messages.W1035 if python_traits.is_immutable( type_.base ): return messages.W1036 units = declarations.decompose_type( type_ ) ptr2functions = filter( lambda unit: isinstance( unit, declarations.calldef_type_t ) , units ) if ptr2functions: return messages.W1037 type_ = declarations.remove_pointer( type_ ) if declarations.class_traits.is_my_case( type_ ): cls = declarations.class_traits.get_declaration( type_ ) if not cls.name: return messages.W1038 if isinstance( self.parent, declarations.class_t ): if self.access_type != declarations.ACCESS_TYPES.PUBLIC: return messages.W1039 return ''
def check_type_compatibility( self, fget, fset ): #algorithms allows "const" differences between types t1 = fget.return_type t2 = fset.arguments[0].type if declarations.is_same( t1, t2 ): return True elif declarations.is_pointer( t1 ) and declarations.is_pointer( t2 ): t1 = declarations.remove_cv( declarations.remove_pointer( t1 ) ) t2 = declarations.remove_cv( declarations.remove_pointer( t2 ) ) return declarations.is_same( t1, t2 ) elif declarations.is_reference( t1 ) and declarations.is_reference( t2 ): t1 = declarations.remove_cv( declarations.remove_reference( t1 ) ) t2 = declarations.remove_cv( declarations.remove_reference( t2 ) ) return declarations.is_same( t1, t2 ) else: return False
def __configure_sealed(self, controller): w_arg = controller.find_wrapper_arg(self.arg.name) naked_type = declarations.remove_pointer(self.arg.type) naked_type = declarations.remove_declarated(naked_type) w_arg.type = declarations.dummy_type_t('std::auto_ptr< %s >' % naked_type.decl_string) controller.modify_arg_expression(self.arg_index, w_arg.name + '.release()')
def has_unnamed_type( self, var ): type_ = declarations.remove_pointer( var.type ) #~ type_ = declarations.remove_declarated( type_ ) if declarations.class_traits.is_my_case( type_ ): cls = declarations.class_traits.get_declaration( type_ ) return bool( not cls.name ) else: return False
def check_type_compatibility(self, fget, fset): #algorithms allows "const" differences between types t1 = fget.return_type t2 = fset.arguments[0].decl_type if declarations.is_same(t1, t2): return True elif declarations.is_pointer(t1) and declarations.is_pointer(t2): t1 = declarations.remove_cv(declarations.remove_pointer(t1)) t2 = declarations.remove_cv(declarations.remove_pointer(t2)) return declarations.is_same(t1, t2) elif declarations.is_reference(t1) and declarations.is_reference(t2): t1 = declarations.remove_cv(declarations.remove_reference(t1)) t2 = declarations.remove_cv(declarations.remove_reference(t2)) return declarations.is_same(t1, t2) else: return False
def has_unnamed_type(self, var): type_ = declarations.remove_pointer(var.type) #~ type_ = declarations.remove_declarated( type_ ) if declarations.class_traits.is_my_case(type_): cls = declarations.class_traits.get_declaration(type_) return bool(not cls.name) else: return False
def _exportable_impl(self): if not self.parent.name and self.is_wrapper_needed(): #return messages.W1057 % str( self ) return messages.W1058 % str(self) if not self.name: return messages.W1033 if self.bits == 0 and self.name == "": return messages.W1034 if not self.expose_address: if declarations.is_array( self.type) and declarations.array_size(self.type) < 1: return messages.W1045 type_ = declarations.remove_alias(self.type) type_ = declarations.remove_const(type_) if declarations.is_pointer(type_): if not self.expose_address and self.type_qualifiers.has_static: return messages.W1035 if not self.expose_address and python_traits.is_immutable( type_.base): return messages.W1036 units = declarations.decompose_type(type_) ptr2functions = [ unit for unit in units if isinstance(unit, declarations.calldef_type_t) ] if ptr2functions: return messages.W1037 type_ = declarations.remove_pointer(type_) if declarations.class_traits.is_my_case(type_): cls = declarations.class_traits.get_declaration(type_) if not cls.name: return messages.W1038 #if cls.class_type == declarations.CLASS_TYPES.UNION: # return messages.W1061 % ( str( self ), str( cls ) ) if isinstance(self.parent, declarations.class_t): if self.access_type != declarations.ACCESS_TYPES.PUBLIC: return messages.W1039 if declarations.is_array(type_): item_type = declarations.array_item_type(type_) if declarations.is_pointer(item_type): item_type_no_ptr = declarations.remove_pointer(item_type) if python_traits.is_immutable(item_type_no_ptr): return messages.W1056 return ''
def _exportable_impl( self ): if not self.parent.name and self.is_wrapper_needed(): #return messages.W1057 % str( self ) return messages.W1058 % str( self ) if not self.name: return messages.W1033 if self.bits == 0 and self.name == "": return messages.W1034 if not self.expose_address: if declarations.is_array( self.type ) and declarations.array_size( self.type ) < 1: return messages.W1045 type_ = declarations.remove_alias( self.type ) type_ = declarations.remove_const( type_ ) if declarations.is_pointer( type_ ): if not self.expose_address and self.type_qualifiers.has_static: return messages.W1035 if not self.expose_address and python_traits.is_immutable( type_.base ): return messages.W1036 units = declarations.decompose_type( type_ ) ptr2functions = filter( lambda unit: isinstance( unit, declarations.calldef_type_t ) , units ) if ptr2functions: return messages.W1037 type_ = declarations.remove_pointer( type_ ) if declarations.class_traits.is_my_case( type_ ): cls = declarations.class_traits.get_declaration( type_ ) if not cls.name: return messages.W1038 #if cls.class_type == declarations.CLASS_TYPES.UNION: # return messages.W1061 % ( str( self ), str( cls ) ) if isinstance( self.parent, declarations.class_t ): if self.access_type != declarations.ACCESS_TYPES.PUBLIC: return messages.W1039 if declarations.is_array( type_ ): item_type = declarations.array_item_type( type_ ) if declarations.is_pointer( item_type ): item_type_no_ptr = declarations.remove_pointer( item_type ) if python_traits.is_immutable( item_type_no_ptr ): return messages.W1056 return ''
def __should_be_exposed_by_address_only(self): type_ = declarations.remove_alias( self.decl_type ) type_ = declarations.remove_const( type_ ) type_ = declarations.remove_pointer( type_ ) if not declarations.class_traits.is_my_case( type_ ): return False cls = declarations.class_traits.get_declaration( type_ ) if cls.class_type == declarations.CLASS_TYPES.UNION: return True elif not cls.name: return True else: return False
def return_range(function, get_size_class, value_policies=None): """create `Py++` defined return_range call policies code generator""" r_type = function.return_type if not declarations.is_pointer(r_type): raise TypeError('Function "%s" return type should be pointer, got "%s"' % r_type.decl_string) value_type = declarations.remove_pointer(r_type) if None is value_policies: if python_traits.is_immutable(value_type): value_policies = default_call_policies() else: raise RuntimeError("return_range call policies requieres specification of value_policies") return return_range_t(get_size_class, value_type, value_policies)
def __should_be_exposed_by_address_only(self): type_ = declarations.remove_alias( self.type ) type_ = declarations.remove_const( type_ ) type_ = declarations.remove_pointer( type_ ) if not declarations.class_traits.is_my_case( type_ ): return False cls = declarations.class_traits.get_declaration( type_ ) if cls.class_type == declarations.CLASS_TYPES.UNION: return True elif not cls.name: return True else: return False
def applyDefaultReturnPolicies(functions): for f in functions: if not f.call_policies: return_type = f.return_type if declarations.is_reference(return_type) or declarations.is_pointer(return_type): type_info = return_type type_info = declarations.remove_pointer(type_info) type_info = declarations.remove_reference(type_info) type_info = declarations.remove_const(type_info) # Se il tipo non e' esposto (potrebbe essere una classe, ma non ci sono informazioni perche' la dichiarazione non e' stata incontrata), viene gestito tramite return_opaque_pointer if declarations.is_class(type_info): f.call_policies = call_policies.return_value_policy(call_policies.reference_existing_object) else: f.call_policies = call_policies.return_value_policy(call_policies.return_opaque_pointer)
def visit_pointer( self ): no_ptr = declarations.remove_const( declarations.remove_pointer( self.user_type ) ) if declarations.is_same( declarations.char_t(), no_ptr ) and self.treat_char_ptr_as_binary_data == False: return "ctypes.c_char_p" elif declarations.is_same( declarations.wchar_t(), no_ptr ) and self.treat_char_ptr_as_binary_data == False: return "ctypes.c_wchar_p" elif declarations.is_same( declarations.void_t(), no_ptr ): return "ctypes.c_void_p" else: base_visitor = self.create_converter( self.user_type.base ) internal_type_str = declarations.apply_visitor( base_visitor, base_visitor.user_type ) if declarations.is_calldef_pointer( self.user_type ): return internal_type_str else: return "ctypes.POINTER( %s )" % internal_type_str
def return_range(function, get_size_class, value_policies=None): """create Py++ defined return_range call policies code generator""" r_type = function.return_type if not declarations.is_pointer(r_type): raise TypeError( 'Function "%s" return type should be pointer, got "%s"' % r_type.decl_string) value_type = declarations.remove_pointer(r_type) if None is value_policies: if python_traits.is_immutable(value_type): value_policies = default_call_policies() else: raise RuntimeError( "return_range call policies requieres specification of value_policies" ) return return_range_t(get_size_class, value_type, value_policies)
def expose_member_as_ndarray1d(klass, member_name, array_size): klass.include_files.append( "ndarray.hpp") z = klass.var(member_name) z.exclude() elem_type = _D.array_item_type(z.type) if _D.is_array(z.type) else _D.remove_pointer(z.type) klass.add_declaration_code(''' static sdcpp::ndarray CLASS_NAME_get_CLASS_NAME_MEMBER_NAME( CLASS_TYPE const & inst ){ return sdcpp::new_ndarray1d(ARRAY_SIZE, sdcpp::dtypeof< ELEM_TYPE >(), (void *)(inst.MEMBER_NAME)); } '''.replace("MEMBER_NAME", member_name) \ .replace("CLASS_NAME", klass.alias) \ .replace("CLASS_TYPE", klass.pds) \ .replace("ELEM_TYPE", elem_type.partial_decl_string) \ .replace("ARRAY_SIZE", str(array_size))) klass.add_registration_code('add_property( "MEMBER_NAME", &::CLASS_NAME_get_CLASS_NAME_MEMBER_NAME )' \ .replace("MEMBER_NAME", member_name).replace("CLASS_NAME", klass.alias))
def expose_member_as_ndarray1d(klass, member_name, array_size): klass.include_files.append("ndarray.hpp") z = klass.var(member_name) z.exclude() elem_type = _D.array_item_type(z.type) if _D.is_array( z.type) else _D.remove_pointer(z.type) klass.add_declaration_code(''' static sdcpp::ndarray CLASS_NAME_get_CLASS_NAME_MEMBER_NAME( CLASS_TYPE const & inst ){ return sdcpp::new_ndarray1d(ARRAY_SIZE, sdcpp::dtypeof< ELEM_TYPE >(), (void *)(inst.MEMBER_NAME)); } '''.replace("MEMBER_NAME", member_name) \ .replace("CLASS_NAME", klass.alias) \ .replace("CLASS_TYPE", klass.pds) \ .replace("ELEM_TYPE", elem_type.partial_decl_string) \ .replace("ARRAY_SIZE", str(array_size))) klass.add_registration_code('add_property( "MEMBER_NAME", &::CLASS_NAME_get_CLASS_NAME_MEMBER_NAME )' \ .replace("MEMBER_NAME", member_name).replace("CLASS_NAME", klass.alias))
def find_out_opaque_decl( type_, ensure_opaque_decl ): naked_type = declarations.remove_cv( type_ ) if not declarations.is_pointer( naked_type ): return None naked_type = declarations.remove_pointer( declarations.remove_cv( type_ ) ) if decl_wrappers.python_traits.is_immutable( naked_type ): return None#immutable types could not be opaque decl = None if declarations.is_class( naked_type ): decl = declarations.class_traits.get_declaration( naked_type ) elif declarations.is_class_declaration( naked_type ):#class declaration: decl = declarations.class_declaration_traits.get_declaration( naked_type ) else: return None if ensure_opaque_decl: if decl.opaque: return decl else: return None else: return decl
def visit_pointer(self): no_ptr = declarations.remove_const( declarations.remove_pointer(self.user_type)) if declarations.is_same( declarations.char_t(), no_ptr) and self.treat_char_ptr_as_binary_data == False: return "ctypes.c_char_p" elif declarations.is_same( declarations.wchar_t(), no_ptr) and self.treat_char_ptr_as_binary_data == False: return "ctypes.c_wchar_p" elif declarations.is_same(declarations.void_t(), no_ptr): return "ctypes.c_void_p" else: base_visitor = self.create_converter(self.user_type.base) internal_type_str = declarations.apply_visitor( base_visitor, base_visitor.user_type) if declarations.is_calldef_pointer(self.user_type): return internal_type_str else: return "ctypes.POINTER( %s )" % internal_type_str
def find_out_opaque_decl(type_, ensure_opaque_decl): naked_type = declarations.remove_cv(type_) if not declarations.is_pointer(naked_type): return None naked_type = declarations.remove_pointer(declarations.remove_cv(type_)) if decl_wrappers.python_traits.is_immutable(naked_type): return None #immutable types could not be opaque decl = None if declarations.is_class(naked_type): decl = declarations.class_traits.get_declaration(naked_type) elif declarations.is_class_declaration(naked_type): #class declaration: decl = declarations.class_declaration_traits.get_declaration( naked_type) else: return None if ensure_opaque_decl: if decl.opaque: return decl else: return None else: return decl
def _exportable_impl( self ): all_types = [ arg.type for arg in self.arguments ] all_types.append( self.return_type ) for some_type in all_types: units = declarations.decompose_type( some_type ) ptr2functions = filter( lambda unit: isinstance( unit, declarations.calldef_type_t ) , units ) if ptr2functions: return messages.W1004 #Function that take as agrument some instance of non public class #will not be exported. Same to the return variable if isinstance( units[-1], declarations.declarated_t ): dtype = units[-1] if isinstance( dtype.declaration.parent, declarations.class_t ): if dtype.declaration not in dtype.declaration.parent.public_members: return messages.W1005 no_ref = declarations.remove_reference( some_type ) no_ptr = declarations.remove_pointer( no_ref ) no_const = declarations.remove_const( no_ptr ) if declarations.is_array( no_const ): return messages.W1006 return self._exportable_impl_derived()
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
def __find_out_is_read_only(self): type_ = declarations.remove_alias( self.type ) if isinstance( type_, declarations.const_t ): return True if declarations.is_pointer( type_ ): type_ = declarations.remove_pointer( type_ ) if declarations.is_reference( type_ ): type_ = declarations.remove_reference( type_ ) if isinstance( type_, declarations.const_t ): return True if self.apply_smart_ptr_wa: return False #all smart pointers has assign operator if isinstance( type_, declarations.declarated_t ) \ and isinstance( type_.declaration, declarations.class_t ) \ and not declarations.has_public_assign( type_.declaration ): return True return False
def __find_out_is_read_only(self): type_ = declarations.remove_alias( self.decl_type ) if isinstance( type_, declarations.const_t ): return True if declarations.is_pointer( type_ ): type_ = declarations.remove_pointer( type_ ) if declarations.is_reference( type_ ): type_ = declarations.remove_reference( type_ ) if isinstance( type_, declarations.const_t ): return True if self.apply_smart_ptr_wa: return False #all smart pointers has assign operator if isinstance( type_, declarations.declarated_t ) \ and isinstance( type_.declaration, declarations.class_t ) \ and not declarations.has_public_assign( type_.declaration ): return True return False
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
def __configure_sealed( self, controller ): w_arg = controller.find_wrapper_arg( self.arg.name ) naked_type = declarations.remove_pointer( self.arg.type ) naked_type = declarations.remove_declarated( naked_type ) w_arg.type = declarations.dummy_type_t( 'std::auto_ptr< %s >' % naked_type.decl_string ) controller.modify_arg_expression(self.arg_index, w_arg.name + '.release()' )
def is_double_ptr(type_): # check for X** if not declarations.is_pointer(type_): return False base = declarations.remove_pointer(type_) return declarations.is_pointer(base)
print(str(base), type(base)) # > 'int', <class 'pygccxml.declarations.cpptypes.int_t'> # We can also directly do this in one step: base = declarations.remove_cv(cv1.decl_type) print(str(base), type(base)) # > 'int', <class 'pygccxml.declarations.cpptypes.int_t'> # As for consts, the const and volatile are on the right hand side # (by convention), and always in the same order cv2 = global_namespace.variable("cv2") print(str(cv2.decl_type), type(cv2.decl_type)) # > 'int const volatile', <class 'pygccxml.declarations.cpptypes.volatile_t'> # And a last example with a pointer_t: cptr1 = global_namespace.variable("cptr1") print(str(cptr1.decl_type), type(cptr1.decl_type)) # > 'int const * const', <class 'pygccxml.declarations.cpptypes.const_t'>) base = declarations.remove_const(cptr1.decl_type) print(str(base), type(base)) # > 'int const *', <class 'pygccxml.declarations.cpptypes.pointer_t'> base = declarations.remove_pointer(base) print(str(base), type(base)) # > 'int const', <class 'pygccxml.declarations.cpptypes.const_t'>) base = declarations.remove_const(base) print(str(base), type(base)) # > 'int', <class 'pygccxml.declarations.cpptypes.int_t'>)
def get_pointee( self, sp_instantiation ): #sp_instantiation - reference to SharedPtr<XXX> #returns reference to XXX type/declaration no_ptr = declarations.remove_pointer( sp_instantiation.variable ('pRep').type ) no_alias = declarations.remove_alias( no_ptr ) return declarations.remove_declarated( no_alias )
# Print the name of the function pointer print(function_ptr.name) # > myFuncPointer # Print the type of the declaration print(function_ptr.decl_type) # > void (*)( int,double ) # Print the real type of the declaration (it's just a pointer) print(type(function_ptr.decl_type)) # > <class 'pygccxml.declarations.cpptypes.pointer_t'> # Check if this is a function pointer print(declarations.is_calldef_pointer(function_ptr.decl_type)) # > True # Remove the pointer part, to access the function's type f_type = declarations.remove_pointer(function_ptr.decl_type) # Print the type print(type(f_type)) # > <class 'pygccxml.declarations.cpptypes.free_function_type_t'> # Print the return type and the arguments of the function print(f_type.return_type) # > void # Print the return type and the arguments print(str(f_type.arguments_types[0]), str(f_type.arguments_types[1])) # > int, double
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, "...")
print("My type is: " + str(a.decl_type)) # > My type is: int const # If we print real python type: print("My type is : " + str(type(a.decl_type))) # > My type is: <class 'pygccxml.declarations.cpptypes.const_t'> # Types are nested in pygccxml. This means that you will get information # about the first type only. You can access the "base" type by removing # the const part: print("My base type is: " + str(type(declarations.remove_const(a.decl_type)))) # > My base type is: <class 'pygccxml.declarations.cpptypes.int_t'> # You use the is_const function to check for a type: print("Is 'a' a const ?: " + str(declarations.is_const(a.decl_type))) # > Is 'a' a const ?: True # A more complex example with variable b: b = ns.variables()[1] print("My type is: " + str(type(b.decl_type))) # > My type is: <class 'pygccxml.declarations.cpptypes.pointer_t'> print("My type is: " + str( type( declarations.remove_const( declarations.remove_volatile( declarations.remove_pointer(b.decl_type)))))) # > My type is: <class 'pygccxml.declarations.cpptypes.int_t'> # The declarations module contains much more methods allowing you to # navigate the nested types list.
print("My type is: " + str(a.decl_type)) # > My type is: int const # If we print real python type: print("My type is : " + str(type(a.decl_type))) # > My type is: <class 'pygccxml.declarations.cpptypes.const_t'> # Types are nested in pygccxml. This means that you will get information # about the first type only. You can access the "base" type by removing # the const part: print("My base type is: " + str(type(declarations.remove_const(a.decl_type)))) # > My base type is: <class 'pygccxml.declarations.cpptypes.int_t'> # You use the is_const function to check for a type: print("Is 'a' a const ?: " + str(declarations.is_const(a.decl_type))) # > Is 'a' a const ?: True # A more complex example with variable b: b = ns.variables()[1] print("My type is: " + str(type(b.decl_type))) # > My type is: <class 'pygccxml.declarations.cpptypes.pointer_t'> print("My type is: " + str(type( declarations.remove_const( declarations.remove_volatile( declarations.remove_pointer(b.decl_type)))))) # > My type is: <class 'pygccxml.declarations.cpptypes.int_t'> # The declarations module contains much more methods allowing you to # navigate the nested types list.
def is_double_ptr( type_ ): #check for X** if not declarations.is_pointer( type_ ): return False base = declarations.remove_pointer( type_ ) return declarations.is_pointer( base )