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 _get_exported_var_type( self ): type_ = declarations.remove_reference( self.declaration.type ) type_ = declarations.remove_const( type_ ) if python_traits.is_immutable( type_ ): return type_ else: return self.declaration.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 _exportable_impl(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 __configure_sealed(self, controller): global _seq2arr w_buffer_arg = controller.find_wrapper_arg( self.buffer_arg.name ) w_buffer_arg.type = declarations.dummy_type_t( "boost::python::object" ) controller.remove_wrapper_arg( self.size_arg.name ) size_var = controller.declare_variable( declarations.remove_const( self.size_arg.type ) , self.size_arg.name , ' = boost::python::len(%s)' % w_buffer_arg.name ) # Declare a variable that will hold the C array... buffer_var = controller.declare_variable( declarations.dummy_type_t( "std::vector< %s >" % self.buffer_item_type.decl_string ) , "native_" + self.buffer_arg.name ) controller.add_pre_call_code( '%s.reserve( %s );' % ( buffer_var, size_var ) ) copy_pylist2arr = _seq2vector.substitute( type=self.buffer_item_type , pylist=w_buffer_arg.name , native_array=buffer_var ) controller.add_pre_call_code( copy_pylist2arr ) controller.modify_arg_expression( self.buffer_arg_index, '&%s[0]' % buffer_var ) controller.modify_arg_expression( self.size_arg_index, '%s' % size_var )
def _get_exported_var_type( self ): type_ = declarations.remove_reference( self.declaration.type ) type_ = declarations.remove_const( type_ ) if python_traits.is_immutable( type_ ): return type_ else: return self.declaration.type
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 __configure_sealed(self, controller): global _seq2arr w_buffer_arg = controller.find_wrapper_arg( self.buffer_arg.name ) w_buffer_arg.type = declarations.dummy_type_t( "boost::python::object" ) controller.remove_wrapper_arg( self.size_arg.name ) size_var = controller.declare_variable( declarations.remove_const( self.size_arg.type ) , self.size_arg.name , ' = boost::python::len(%s)' % w_buffer_arg.name ) # Declare a variable that will hold the C array... buffer_var = controller.declare_variable( declarations.dummy_type_t( "std::vector< %s >" % self.buffer_item_type.decl_string ) , "native_" + self.buffer_arg.name ) controller.add_pre_call_code( '%s.reserve( %s );' % ( buffer_var, size_var ) ) copy_pylist2arr = _seq2vector.substitute( type=self.buffer_item_type , pylist=w_buffer_arg.name , native_array=buffer_var ) controller.add_pre_call_code( copy_pylist2arr ) controller.modify_arg_expression( self.buffer_arg_index, '&%s[0]' % buffer_var ) controller.modify_arg_expression( self.size_arg_index, '%s' % size_var )
def __init__(self, function, buffer_arg_ref, size_arg_ref): """Constructor. :param buffer_arg_ref: "reference" to the buffer argument :param buffer_arg_ref: "reference" to argument, which holds buffer size """ transformer.transformer_t.__init__(self, function) self.buffer_arg = self.get_argument(buffer_arg_ref) self.buffer_arg_index = self.function.arguments.index(self.buffer_arg) self.size_arg = self.get_argument(size_arg_ref) self.size_arg_index = self.function.arguments.index(self.size_arg) if not is_ptr_or_array(self.buffer_arg.type): raise ValueError( '%s\nin order to use "input_c_buffer" transformation, "buffer" argument %s type must be a array or a pointer (got %s).' ) % (function, self.buffer_arg.name, self.buffer_arg.type) if not declarations.is_integral(self.size_arg.type): raise ValueError( '%s\nin order to use "input_c_buffer" transformation, "size" argument %s type must be an integral type (got %s).' ) % (function, self.size_arg.name, self.size_arg.type) self.buffer_item_type = declarations.remove_const(declarations.array_item_type(self.buffer_arg.type))
def add_decl_desc(decl): try: # assume there are some docs for the declaration desc_list = dict_decl_name_to_desc[(decl.parent.name, decl.name)] desc_count = len(desc_list)-1 reference = desc_list[desc_count] except KeyError: desc_list = None desc_count = 0 reference = None try: # assume decl is a function for a in decl.arguments: if not a.name in decl._args_docs: continue arg = a.name add_decl_boost_doc(decl, "Argument '%s':" % arg) for z in decl._args_docs[arg]: add_decl_boost_doc(decl, " "+z) if decl._output_args: # get the return value and output arguments return_list = [] if decl.return_type.partial_decl_string!='void': return_type = _D.remove_const(_D.remove_reference(decl.return_type)) pds = unique_pds(return_type.partial_decl_string) pds = current_sb.get_registered_decl_name(pds) return_list.append("(%s)" % pds) return_list.extend([x.name for x in decl._output_args]) # document it add_decl_boost_doc(decl, "Returns:") s = "" for r in return_list: s += r+", " s = s[:-2] if len(return_list) > 1: s = " ("+s+")" else: s = " "+s add_decl_boost_doc(decl, s) except AttributeError: pass if reference is not None: add_decl_boost_doc(decl, " "+reference, False, word_wrap=False) add_decl_boost_doc(decl, "Reference:", False) try: # assume decl is a function alias = decl.transformations[0].alias if len(decl.transformations) > 0 else decl.alias if alias != decl.name: add_decl_boost_doc(decl, " "+decl.name, False) add_decl_boost_doc(decl, "Wrapped function:", False) except AttributeError: pass for i in xrange(desc_count-1, -1, -1): add_decl_boost_doc(decl, desc_list[i], False)
def remove_const_from_reference(type): "Helper to avoid compile errors with const-reference-protected-destructor argument types" if not type_traits.is_reference(type): return type nonref = declarations.remove_reference(type) if not type_traits.is_const(nonref): return type nonconst = declarations.remove_const(nonref) return cpptypes.reference_t(nonconst)
def remove_const_from_reference(type): "Helper to avoid compile errors with const-reference-protected-destructor argument types" if not type_traits.is_reference(type): return type nonref = declarations.remove_reference(type) if not type_traits.is_const(nonref): return type nonconst = declarations.remove_const(nonref) return cpptypes.reference_t(nonconst)
def visit_reference( self ): no_ref = declarations.remove_const( declarations.remove_reference( self.user_type ) ) if declarations.is_same( declarations.char_t(), no_ref ): return "ctypes.c_char_p" elif declarations.is_same( declarations.wchar_t(), no_ref ): return "ctypes.c_wchar_p" elif declarations.is_same( declarations.void_t(), no_ref ): 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 ) return "ctypes.POINTER( %s )" % internal_type_str
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 __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 visit_reference(self): no_ref = declarations.remove_const( declarations.remove_reference(self.user_type)) if declarations.is_same(declarations.char_t(), no_ref): return "ctypes.c_char_p" elif declarations.is_same(declarations.wchar_t(), no_ref): return "ctypes.c_wchar_p" elif declarations.is_same(declarations.void_t(), no_ref): 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) return "ctypes.POINTER( %s )" % internal_type_str
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 _get_call_policies(self): if self.__call_policies: return self.__call_policies if self.container_traits not in declarations.sequential_container_traits: # TODO: find out why map's don't like the policy return self.__call_policies element_type = None try: element_type = self.element_type except: return if declarations.is_const(element_type): element_type = declarations.remove_const(element_type) if declarations.is_pointer(element_type): self.__call_policies = call_policies.return_internal_reference() return self.__call_policies
def _get_call_policies( self ): if self.__call_policies: return self.__call_policies if self.container_traits not in declarations.sequential_container_traits: #TODO: find out why map's don't like the policy return self.__call_policies element_type = None try: element_type = self.element_type except: return if declarations.is_const( element_type ): element_type = declarations.remove_const( element_type ) if declarations.is_pointer( element_type ): self.__call_policies = call_policies.return_internal_reference() return self.__call_policies
def str_from_ostream(ns): """ Finds all free operators, then exposes only the ones with classes currently exposed then Py++ can do the rest. """ for oper in ns.free_operators('<<'): rtype = declarations.remove_declarated( declarations.remove_reference(oper.return_type)) type_or_decl = declarations.remove_declarated( declarations.remove_const( declarations.remove_reference(oper.arguments[1].type))) if not isinstance(type_or_decl, declarations.declaration_t): continue if type_or_decl.ignore == False: decl_logger.info("Exposing operator<<: " + str(oper)) oper.include()
def __init__(self, function, arg_ref, size): """Constructor. @param size: The fixed size of the input array @type size: int """ transformer.transformer_t.__init__( self, function ) self.arg = self.get_argument( arg_ref ) self.arg_index = self.function.arguments.index( self.arg ) if not is_ptr_or_array( self.arg.type ): raise ValueError( '%s\nin order to use "input_array" transformation, argument %s type must be a array or a pointer (got %s).' ) \ % ( function, self.arg.name, self.arg.type) self.array_size = size self.array_item_type = declarations.remove_const( declarations.array_item_type( self.arg.type ) )
def __init__(self, function, arg_ref, size): """Constructor. @param size: The fixed size of the input array @type size: int """ transformer.transformer_t.__init__( self, function ) self.arg = self.get_argument( arg_ref ) self.arg_index = self.function.arguments.index( self.arg ) if not is_ptr_or_array( self.arg.type ): raise ValueError( '%s\nin order to use "input_array" transformation, argument %s type must be a array or a pointer (got %s).' ) \ % ( function, self.arg.name, self.arg.type) self.array_size = size self.array_item_type = declarations.remove_const( declarations.array_item_type( self.arg.type ) )
def str_from_ostream(ns): """ Finds all free operators, then exposes only the ones with classes currently exposed then Py++ can do the rest. """ for oper in ns.free_operators( '<<' ): rtype = declarations.remove_declarated( declarations.remove_reference( oper.return_type ) ) type_or_decl = declarations.remove_declarated( declarations.remove_const( declarations.remove_reference( oper.arguments[1].type))) if not isinstance( type_or_decl, declarations.declaration_t ): continue if type_or_decl.ignore == False: decl_logger.info("Exposing operator<<: " + str(oper)) oper.include()
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 __init__(self, function, arg_ref, rows, columns): """Constructor. :param rows, columns: The fixed size of the input matrix :type rows, columns: int """ transformer.transformer_t.__init__( self, function ) self.arg = self.get_argument( arg_ref ) self.arg_index = self.function.arguments.index( self.arg ) if not is_ptr_or_array( self.arg.type ): raise ValueError( '%s\nin order to use "input_matrix" transformation, argument %s type must be a array or a pointer (got %s).' ) \ % ( function, self.arg.name, self.arg.type) self.rows = rows self.columns = columns self.matrix_item_type = declarations.remove_const( declarations.array_item_type( declarations.array_item_type( self.arg.type ) ) )
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()
def __init__(self, function, arg_ref, size): """Constructor. :param maxsize: The maximum string size we will allow... :type maxsize: int """ transformer.transformer_t.__init__( self, function ) self.arg = self.get_argument( arg_ref ) self.arg_index = self.function.arguments.index( self.arg ) if not is_ptr_or_array( self.arg.type ): raise ValueError( '%s\nin order to use "input_array" transformation, argument %s type must be a array or a pointer (got %s).' ) \ % ( function, self.arg.name, self.arg.type) self.max_size = size self.array_item_type = declarations.remove_const( declarations.array_item_type( self.arg.type ) ) self.array_item_rawtype = declarations.remove_cv( self.arg.type ) self.array_item_rawtype = declarations.pointer_t( self.array_item_type )
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 _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
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 __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()
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 __init__(self, function, buffer_arg_ref, size_arg_ref): """Constructor. :param buffer_arg_ref: "reference" to the buffer argument :param buffer_arg_ref: "reference" to argument, which holds buffer size """ transformer.transformer_t.__init__( self, function ) self.buffer_arg = self.get_argument( buffer_arg_ref ) self.buffer_arg_index = self.function.arguments.index( self.buffer_arg ) self.size_arg = self.get_argument( size_arg_ref ) self.size_arg_index = self.function.arguments.index( self.size_arg ) if not is_ptr_or_array( self.buffer_arg.type ): raise ValueError( '%s\nin order to use "input_c_buffer" transformation, "buffer" argument %s type must be a array or a pointer (got %s).' ) \ % ( function, self.buffer_arg.name, self.buffer_arg.type) if not declarations.is_integral( self.size_arg.type ): raise ValueError( '%s\nin order to use "input_c_buffer" transformation, "size" argument %s type must be an integral type (got %s).' ) \ % ( function, self.size_arg.name, self.size_arg.type) self.buffer_item_type = declarations.remove_const( declarations.array_item_type( self.buffer_arg.type ) )
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 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, "...")
def tt( type_ ): type_ = declarations.remove_reference( type_ ) type_ = declarations.remove_const( type_ ) return declarations.reference_t( type_ )
def tt(type_): type_ = declarations.remove_reference(type_) type_ = declarations.remove_const(type_) return declarations.reference_t(type_)
def add_decl_desc(decl): try: # assume there are some docs for the declaration desc_list = dict_decl_name_to_desc[(decl.parent.name, decl.name)] desc_count = len(desc_list) - 1 reference = desc_list[desc_count] except KeyError: desc_list = None desc_count = 0 reference = None try: # assume decl is a function for a in decl.arguments: if not a.name in decl._args_docs: continue arg = a.name add_decl_boost_doc(decl, "Argument '%s':" % arg) for z in decl._args_docs[arg]: add_decl_boost_doc(decl, " " + z) if decl._output_args: # get the return value and output arguments return_list = [] if decl.return_type.partial_decl_string != 'void': return_type = _D.remove_const( _D.remove_reference(decl.return_type)) pds = unique_pds(return_type.partial_decl_string) pds = current_sb.get_registered_decl_name(pds) return_list.append("(%s)" % pds) return_list.extend([x.name for x in decl._output_args]) # document it add_decl_boost_doc(decl, "Returns:") s = "" for r in return_list: s += r + ", " s = s[:-2] if len(return_list) > 1: s = " (" + s + ")" else: s = " " + s add_decl_boost_doc(decl, s) except AttributeError: pass if reference is not None: add_decl_boost_doc(decl, " " + reference, False, word_wrap=False) add_decl_boost_doc(decl, "Reference:", False) try: # assume decl is a function alias = decl.transformations[0].alias if len( decl.transformations) > 0 else decl.alias if alias != decl.name: add_decl_boost_doc(decl, " " + decl.name, False) add_decl_boost_doc(decl, "Wrapped function:", False) except AttributeError: pass for i in xrange(desc_count - 1, -1, -1): add_decl_boost_doc(decl, desc_list[i], False)
a = ns.variables()[0] print("My name is: " + a.name) # > My name is: a 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 c++ file we want to parse filename = "example.hpp" filename = this_module_dir_path + "/" + filename decls = parser.parse([filename], xml_generator_config) global_namespace = declarations.get_global_namespace(decls) c1 = global_namespace.variable("c1") print(str(c1), type(c1)) # > 'c1 [variable]', <class 'pygccxml.declarations.variable.variable_t'> print(str(c1.decl_type), type(c1.decl_type)) # > 'int const', <class 'pygccxml.declarations.cpptypes.const_t'> base = declarations.remove_const(c1.decl_type) print(str(base), type(base)) # > 'int', <class 'pygccxml.declarations.cpptypes.int_t'> c2 = global_namespace.variable("c2") print(str(c2.decl_type), type(c2.decl_type)) # > 'int const', <class 'pygccxml.declarations.cpptypes.const_t'> # Even if the declaration was defined as 'const int', pygccxml will always # output the const qualifier (and some other qualifiers) on the right hand # side (by convention). cv1 = global_namespace.variable("cv1") print(str(cv1.decl_type), type(cv1.decl_type)) # > 'int const volatile', <class 'pygccxml.declarations.cpptypes.volatile_t'> # Remove one level:
'::ushort': 'uint16', 'short unsigned int': 'uint16', '::schar': 'int8', 'signed char': 'int8', '::uchar': 'uint8', 'unsigned char': 'uint8', 'bool': 'bool', } # FileStorage's 'write' functions for z in sb.mb.free_funs(lambda x: x.name=='write' and \ x.arguments[0].type.partial_decl_string.startswith('::cv::FileStorage')): z.include() if len(z.arguments) > 2 and \ z.arguments[1].type.partial_decl_string.startswith('::std::string'): t = D.remove_const(D.remove_reference(z.arguments[2].type)) else: t = D.remove_const(D.remove_reference(z.arguments[1].type)) name = 'write_'+C_to_Python_name_dict[t.partial_decl_string] z._transformer_kwds['alias'] = name z.alias = name # FileNode's 'read' functions for z in sb.mb.free_funs(lambda x: x.name=='read' and \ x.arguments[0].type.partial_decl_string.startswith('::cv::FileNode')): z.include() if z.arguments[1].name=='keypoints': z._transformer_creators.append(FT.arg_output('keypoints')) else: z._transformer_creators.append(FT.output(z.arguments[1].name)) FT.doc_output(z, z.arguments[1])
a = ns.variables()[0] print("My name is: " + a.name) # > My name is: a 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))))))
'::ushort': 'uint16', 'short unsigned int': 'uint16', '::schar': 'int8', 'signed char': 'int8', '::uchar': 'uint8', 'unsigned char': 'uint8', 'bool': 'bool', } # FileStorage's 'write' functions for z in sb.mb.free_funs(lambda x: x.name=='write' and \ x.arguments[0].type.partial_decl_string.startswith('::cv::FileStorage')): z.include() if len(z.arguments) > 2 and \ z.arguments[1].type.partial_decl_string.startswith('::std::string'): t = D.remove_const(D.remove_reference(z.arguments[2].type)) else: t = D.remove_const(D.remove_reference(z.arguments[1].type)) name = 'write_' + C_to_Python_name_dict[t.partial_decl_string] z._transformer_kwds['alias'] = name z.alias = name # FileNode's 'read' functions for z in sb.mb.free_funs(lambda x: x.name=='read' and \ x.arguments[0].type.partial_decl_string.startswith('::cv::FileNode')): z.include() if z.arguments[1].name == 'keypoints': z._transformer_creators.append(FT.arg_output('keypoints')) else: z._transformer_creators.append(FT.output(z.arguments[1].name)) FT.doc_output(z, z.arguments[1])