Package pyplusplus :: Package code_creators :: Module calldef_utils

Source Code for Module pyplusplus.code_creators.calldef_utils

  1  # Copyright 2004-2008 Roman Yakovenko 
  2  # Distributed under the Boost Software License, Version 1.0. (See 
  3  # accompanying file LICENSE_1_0.txt or copy at 
  4  # http://www.boost.org/LICENSE_1_0.txt) 
  5   
  6  import os 
  7  import algorithm 
  8  import code_creator 
  9  from pygccxml import declarations 
 10  from pyplusplus import decl_wrappers 
 11  #virtual functions that returns const reference to something 
 12  #could not be overriden by Python. The reason is simple: 
 13  #in boost::python::override::operator(...) result of marshaling 
 14  #(Python 2 C++) is saved on stack, after functions returns the result 
 15  #will be reference to no where - access violetion. 
 16  #For example see temporal variable tester 
 17   
 18  use_enum_workaround = False 
19 20 -class argument_utils_t:
21 22 PARAM_SEPARATOR = code_creator.code_creator_t.PARAM_SEPARATOR 23
24 - def __init__( self, declaration, identifier_creator, arguments=None ):
25 self.__decl = declaration 26 if None is arguments: 27 arguments = self.__decl.arguments 28 self.__args = arguments 29 self.__id_creator = identifier_creator
30
31 - def __should_use_enum_wa( self, arg ):
32 global use_enum_workaround 33 if not declarations.is_enum( arg.type ): 34 return False 35 if use_enum_workaround: 36 return True 37 #enum belongs to the class we are working on 38 if self.__decl.parent is declarations.enum_declaration( arg.type ).parent \ 39 and isinstance( self.__decl, declarations.constructor_t ): 40 return True 41 return False
42
43 - def keywords_args(self):
44 if not self.__args: 45 return '' 46 boost_arg = self.__id_creator( '::boost::python::arg' ) 47 boost_obj = self.__id_creator( '::boost::python::object' ) 48 result = ['( '] 49 for arg in self.__args: 50 if 1 < len( result ): 51 result.append( self.PARAM_SEPARATOR ) 52 result.append( boost_arg ) 53 result.append( '("%s")' % arg.name ) 54 if self.__decl.use_default_arguments and arg.default_value: 55 if not declarations.is_pointer( arg.type ) or arg.default_value != '0': 56 arg_type_no_alias = declarations.remove_alias( arg.type ) 57 if declarations.is_fundamental( arg_type_no_alias ) \ 58 and declarations.is_integral( arg_type_no_alias ) \ 59 and not arg.default_value.startswith( arg_type_no_alias.decl_string ): 60 result.append( '=(%s)(%s)' % ( arg_type_no_alias.partial_decl_string 61 , arg.default_value ) ) 62 elif self.__should_use_enum_wa( arg ): 63 #Work around for bug/missing functionality in boost.python. 64 #registration order 65 result.append( '=(long)(%s)' % arg.default_value ) 66 else: 67 result.append( '=%s' % arg.default_value ) 68 else: 69 result.append( '=%s()' % boost_obj ) 70 result.append( ' )' ) 71 return ''.join( result )
72
73 - def argument_name( self, index ):
74 arg = self.__args[ index ] 75 if arg.name: 76 return arg.name 77 else: 78 return 'p%d' % index
79
80 - def args_declaration( self ):
81 args = [] 82 for index, arg in enumerate( self.__args ): 83 result = arg.type.partial_decl_string + ' ' + self.argument_name(index) 84 if arg.default_value: 85 result += '=%s' % arg.default_value 86 args.append( result ) 87 if len( args ) == 1: 88 return args[ 0 ] 89 return self.PARAM_SEPARATOR.join( args )
90
91 - def call_args( self ):
92 params = [] 93 for index, arg in enumerate( self.__args ): 94 params.append( decl_wrappers.python_traits.call_traits( arg.type ) 95 % self.argument_name( index ) ) 96 return ', '.join( params )
97
98 -class return_stmt_creator_t( object ):
99 - def __init__( self, creator, controller, result_var, return_vars ):
100 object.__init__( self ) 101 self.__creator = creator 102 self.__controller = controller 103 self.__function = controller.function 104 self.__return_vars = return_vars[:] 105 self.__pre_return_code = None 106 self.__return_stmt = None 107 self.__result_var = result_var 108 self.__call_policy_alias = controller.register_variable_name( 'call_policies_t' )
109 110 @property
111 - def pre_return_code( self ):
112 if None is self.__pre_return_code: 113 if declarations.is_void( self.__function.return_type ) \ 114 and ( self.__function.call_policies.is_default() \ 115 or False == bool( self.__controller.return_variables ) ): 116 self.__pre_return_code = '' 117 elif self.__function.call_policies.is_default(): 118 self.__pre_return_code = '' 119 else: 120 c_p_typedef = 'typedef %s %s;' \ 121 % ( self.__function.call_policies.create_template_arg( self.__creator ) 122 , self.__call_policy_alias ) 123 self.__pre_return_code = c_p_typedef 124 return self.__pre_return_code
125 126 @property
127 - def statement( self ):
128 if None is self.__return_stmt: 129 stmt = '' 130 bpl_object = algorithm.create_identifier( self.__creator, 'boost::python::object' ) 131 make_tuple = algorithm.create_identifier( self.__creator, 'boost::python::make_tuple' ) 132 make_object = algorithm.create_identifier( self.__creator, 'pyplusplus::call_policies::make_object' ) 133 134 if not declarations.is_void( self.__function.return_type ): 135 if self.__function.call_policies.is_default(): 136 self.__return_vars.insert( 0, self.__result_var.name ) 137 else: 138 self.__return_vars.insert( 0 139 , declarations.call_invocation.join( 140 declarations.templates.join( make_object 141 , [self.__call_policy_alias, self.__result_var.type.decl_string] ) 142 , [self.__result_var.name] ) ) 143 144 if 0 == len( self.__return_vars ): 145 pass 146 elif 1 == len( self.__return_vars ): 147 stmt = bpl_object + '( %s )' % self.__return_vars[ 0 ] 148 else: # 1 < 149 stmt = declarations.call_invocation.join( make_tuple, self.__return_vars ) 150 if self.__creator.LINE_LENGTH < len( stmt ): 151 stmt = declarations.call_invocation.join( 152 make_tuple 153 , self.__return_vars 154 , os.linesep + self.__creator.indent( self.__creator.PARAM_SEPARATOR, 6 ) ) 155 156 if stmt: 157 stmt = 'return ' + stmt + ';' 158 self.__return_stmt = stmt 159 return self.__return_stmt
160