| Trees | Indices | Help |
|
|---|
|
|
1 # Copyright 2006 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 # Initial author: Matthias Baas
7
8 """This module contains the standard argument policy objects.
9
10 The following policies are available:
11
12 - L{output_t}
13 - L{input_t}
14 - L{inout_t}
15 - L{input_array_t}
16 - L{output_array_t}
17 - L{type_modifier_t}
18 """
19 import os
20 import string
21 import transformer
22 import controllers
23 from pygccxml import declarations
24 from pyplusplus import code_repository
25
26 #TODO: pointers should be checked for NULL
27
30
33
35 if declarations.is_pointer( type_ ):
36 return declarations.remove_pointer( type_ )
37 elif declarations.is_reference( type_ ):
38 return declarations.remove_reference( type_ )
39 else:
40 raise TypeError( 'Type should be reference or pointer, got %s.' % type_ )
41
42
43 # output_t
45 """Handles a single output variable.
46
47 The specified variable is removed from the argument list and is turned
48 into a return value.
49
50 void getValue(int& v) -> v = getValue()
51 """
52
54 transformer.transformer_t.__init__( self, function )
55 """Constructor.
56
57 The specified argument must be a reference or a pointer.
58
59 @param arg_ref: Index of the argument that is an output value (the first arg has index 1).
60 @type arg_ref: int
61 """
62 self.arg = self.get_argument( arg_ref )
63 self.arg_index = self.function.arguments.index( self.arg )
64
65 if not is_ref_or_ptr( self.arg.type ):
66 raise ValueError( '%s\nin order to use "output" transformation, argument %s type must be a reference or a pointer (got %s).' ) \
67 % ( function, self.arg_ref.name, arg.type)
68
70 return "output(%d)"%(self.arg.name)
71
73 """Returns list of header files that transformer generated code depends on."""
74 return [ code_repository.convenience.file_name ]
75
77 #removing arg from the function wrapper definition
78 controller.remove_wrapper_arg( self.arg.name )
79 #declaring new variable, which will keep result
80 var_name = controller.declare_variable( remove_ref_or_ptr( self.arg.type ), self.arg.name )
81 #adding just declared variable to the original function call expression
82 controller.modify_arg_expression( self.arg_index, var_name )
83 #adding the variable to return variables list
84 controller.return_variable( var_name )
85
87 self.__configure_sealed( controller )
88
90 controller.remove_py_arg( self.arg_index )
91 tmpl = string.Template(
92 '$name = boost::python::extract< $type >( pyplus_conv::get_out_argument( $py_result, "$name" ) );' )
93 store_py_result_in_arg = tmpl.substitute( name=self.arg.name
94 , type=remove_ref_or_ptr( self.arg.type ).decl_string
95 , py_result=controller.py_result_variable.name )
96 controller.add_py_post_call_code( store_py_result_in_arg )
97
99 self.__configure_sealed( controller )
100
102 self.__configure_sealed( controller )
103
105 self.__configure_v_mem_fun_default( controller.default_controller )
106 self.__configure_v_mem_fun_override( controller.override_controller )
107
108 # input_t
110 """Change/modify type of the argument.
111
112 Right now compiler should be able to use implicit conversion
113 """
114
116 """Constructor.
117
118 modifier is callable, which take the type of the argument and should return
119 new type
120 """
121 transformer.transformer_t.__init__( self, function )
122 self.arg = self.get_argument( arg_ref )
123 self.arg_index = self.function.arguments.index( self.arg )
124 self.modifier = modifier
125
127 return "type_modifier(%s)" % self.arg.name
128
130 w_arg = controller.find_wrapper_arg( self.arg.name )
131 w_arg.type = self.modifier( self.arg.type )
132 if not declarations.is_convertible( w_arg.type, self.arg.type ):
133 casting_code = 'reinterpret_cast< %s >( %s )' % ( self.arg.type, w_arg.name )
134 controller.modify_arg_expression(self.arg_index, casting_code)
135
137 self.__configure_sealed( controller )
138
140 self.__configure_sealed( controller )
141
143 self.__configure_sealed( controller )
144
147
151
152 # input_t
154 """Handles a single input variable.
155
156 The reference on the specified variable is removed.
157
158 void setValue(int& v) -> setValue(v)
159 """
160
162 """Constructor.
163
164 The specified argument must be a reference or a pointer.
165
166 @param idx: Index of the argument that is an output value (the first arg has index 1).
167 @type idx: int
168 """
169 type_modifier_t.__init__( self, function, arg_ref, remove_ref_or_ptr )
170
171 if not is_ref_or_ptr( self.arg.type ):
172 raise ValueError( '%s\nin order to use "input" transformation, argument %s type must be a reference or a pointer (got %s).' ) \
173 % ( function, self.arg_ref.name, arg.type)
174
176 return "input(%s)"%(self.arg.name)
177
178 # input_t
180 """Handles a single input variable.
181
182 Replaces the actual argument type with some integral type, so you
183 can use ctypes package.
184
185 void do_smth(int** image) -> do_smth(unsigned int addressof_image)
186
187 """
188
190 """Constructor.
191
192 The specified argument must be a reference or a pointer.
193
194 @param idx: Index of the argument that is an output value (the first arg has index 1).
195 @type idx: int
196 """
197 modifier = lambda type_: declarations.FUNDAMENTAL_TYPES[ 'unsigned int' ]
198 type_modifier_t.__init__( self, function, arg_ref, modifier )
199
200 if not is_ptr_or_array( self.arg.type ):
201 raise ValueError( '%s\nin order to use "from_address_t" transformation, argument %s type must be a pointer or a array (got %s).' ) \
202 % ( function, self.arg_ref.name, arg.type)
203
205 return "from_address(%s)"%(self.arg.name)
206
207 # inout_t
209 """Handles a single input/output variable.
210
211 void foo(int& v) -> v = foo(v)
212 """
213
215 """Constructor.
216
217 The specified argument must be a reference or a pointer.
218
219 @param idx: Index of the argument that is an in/out value (the first arg has index 1).
220 @type idx: int
221 """
222 transformer.transformer_t.__init__( self, function )
223 self.arg = self.get_argument( arg_ref )
224 self.arg_index = self.function.arguments.index( self.arg )
225
226 if not is_ref_or_ptr( self.arg.type ):
227 raise ValueError( '%s\nin order to use "inout" transformation, argument %s type must be a reference or a pointer (got %s).' ) \
228 % ( function, self.arg_ref.name, arg.type)
229
231 return "inout(%s)"%(self.arg.name)
232
234 w_arg = controller.find_wrapper_arg( self.arg.name )
235 w_arg.type = remove_ref_or_ptr( self.arg.type )
236 #adding the variable to return variables list
237 controller.return_variable( w_arg.name )
238
240 self.__configure_sealed( controller )
241
243 tmpl = string.Template(
244 '$name = boost::python::extract< $type >( pyplus_conv::get_out_argument( $py_result, "$name" ) );' )
245 store_py_result_in_arg = tmpl.substitute( name=self.arg.name
246 , type=remove_ref_or_ptr( self.arg.type ).decl_string
247 , py_result=controller.py_result_variable.name )
248 controller.add_py_post_call_code( store_py_result_in_arg )
249
251 self.__configure_sealed( controller )
252
254 self.__configure_sealed( controller )
255
257 self.__configure_v_mem_fun_override( controller.override_controller )
258 self.__configure_v_mem_fun_default( controller.default_controller )
259
261 """Returns list of header files that transformer generated code depends on."""
262 return [ code_repository.convenience.file_name ]
263
264
265 _seq2arr = string.Template( os.linesep.join([
266 'pyplus_conv::ensure_uniform_sequence< $type >( $pylist, $array_size );'
267 , 'pyplus_conv::copy_sequence( $pylist, pyplus_conv::array_inserter( $native_array, $array_size ) );']))
268
269 _seq2vector = string.Template( os.linesep.join([
270 'pyplus_conv::ensure_uniform_sequence< $type >( $pylist );'
271 , 'pyplus_conv::copy_sequence( $pylist, std::back_inserter( $native_array), boost::type< $type >() );']))
272
273 _arr2seq = string.Template(
274 'pyplus_conv::copy_container( $native_array, $native_array + $array_size, pyplus_conv::list_inserter( $pylist ) );' )
275
277 """Handles an input array with fixed size.
278
279 void setVec3(double* v) -> setVec3(object v)
280 # v must be a sequence of 3 floats
281 """
282
284 """Constructor.
285
286 @param size: The fixed size of the input array
287 @type size: int
288 """
289 transformer.transformer_t.__init__( self, function )
290
291 self.arg = self.get_argument( arg_ref )
292 self.arg_index = self.function.arguments.index( self.arg )
293
294 if not is_ptr_or_array( self.arg.type ):
295 raise ValueError( '%s\nin order to use "input_array" transformation, argument %s type must be a array or a pointer (got %s).' ) \
296 % ( function, self.arg.name, self.arg.type)
297
298 self.array_size = size
299 self.array_item_type = declarations.remove_const( declarations.array_item_type( self.arg.type ) )
300
303
305 """Returns list of header files that transformer generated code depends on."""
306 return [ code_repository.convenience.file_name ]
307
309 global _seq2arr
310 w_arg = controller.find_wrapper_arg( self.arg.name )
311 w_arg.type = declarations.dummy_type_t( "boost::python::object" )
312
313 # Declare a variable that will hold the C array...
314 native_array = controller.declare_variable( self.array_item_type
315 , "native_" + self.arg.name
316 , '[%d]' % self.array_size )
317
318 copy_pylist2arr = _seq2arr.substitute( type=self.array_item_type
319 , pylist=w_arg.name
320 , array_size=self.array_size
321 , native_array=native_array )
322
323 controller.add_pre_call_code( copy_pylist2arr )
324
325 controller.modify_arg_expression( self.arg_index, native_array )
326
328 self.__configure_sealed( controller )
329
331 global _arr2seq
332 pylist = controller.declare_py_variable( declarations.dummy_type_t( 'boost::python::list' )
333 , 'py_' + self.arg.name )
334
335 copy_arr2pylist = _arr2seq.substitute( native_array=self.arg.name
336 , array_size=self.array_size
337 , pylist=pylist )
338
339 controller.add_py_pre_call_code( copy_arr2pylist )
340
342 self.__configure_sealed( controller )
343
345 self.__configure_sealed( controller )
346
348 self.__configure_v_mem_fun_override( controller.override_controller )
349 self.__configure_v_mem_fun_default( controller.default_controller )
350
351
352 # s - static
354 """Handles an output array of a fixed size.
355
356 void getVec3(double* v) -> v = getVec3()
357 # v will be a list with 3 floats
358 """
359
361 """Constructor.
362
363 @param idx: Index of the argument that is an output array (the first arg has index 1).
364 @type idx: int
365 @param size: The fixed size of the output array
366 @type size: int
367 """
368 transformer.transformer_t.__init__( self, function )
369 self.arg = self.get_argument( arg_ref )
370 self.arg_index = self.function.arguments.index( self.arg )
371
372 if not is_ptr_or_array( self.arg.type ):
373 raise ValueError( '%s\nin order to use "input_array" transformation, argument %s type must be a array or a pointer (got %s).' ) \
374 % ( function, self.arg.name, self.arg.type)
375
376 self.array_size = size
377 self.array_item_type = declarations.array_item_type( self.arg.type )
378
381
383 """Returns list of header files that transformer generated code depends on."""
384 return [ code_repository.convenience.file_name ]
385
387 global _arr2seq
388 #removing arg from the function wrapper definition
389 controller.remove_wrapper_arg( self.arg.name )
390
391 # Declare a variable that will hold the C array...
392 native_array = controller.declare_variable( self.array_item_type
393 , "native_" + self.arg.name
394 , '[%d]' % self.array_size )
395
396 #adding just declared variable to the original function call expression
397 controller.modify_arg_expression( self.arg_index, native_array )
398
399 # Declare a Python list which will receive the output...
400 pylist = controller.declare_variable( declarations.dummy_type_t( "boost::python::list" )
401 , 'py_' + self.arg.name )
402
403 copy_arr2pylist = _arr2seq.substitute( native_array=native_array
404 , array_size=self.array_size
405 , pylist=pylist )
406
407 controller.add_post_call_code( copy_arr2pylist )
408
409 #adding the variable to return variables list
410 controller.return_variable( pylist )
411
413 self.__configure_sealed( controller )
414
416 global _seq2arr
417 seq = controller.declare_py_variable( declarations.dummy_type_t( 'boost::python::object' )
418 , 'py_' + self.arg.name )
419 controller.remove_py_arg( self.arg_index )
420 tmpl = string.Template( '$seq = pyplus_conv::get_out_argument( $py_result, "$name" );' )
421 get_ref_to_seq = tmpl.substitute( seq=seq
422 , py_result=controller.py_result_variable.name
423 , name=self.arg.name )
424 controller.add_py_post_call_code( get_ref_to_seq )
425
426 copy_pylist2arr = _seq2arr.substitute( type=self.array_item_type
427 , pylist=seq
428 , array_size=self.array_size
429 , native_array=self.arg.name )
430 controller.add_py_post_call_code( copy_pylist2arr )
431
433 self.__configure_sealed( controller )
434
436 self.__configure_sealed( controller )
437
439 self.__configure_v_mem_fun_override( controller.override_controller )
440 self.__configure_v_mem_fun_default( controller.default_controller )
441
442
444 """Handles an input of C buffere:
445
446 void write( byte *buffer, int size ) -> void write( python sequence )
447 """
448
450 """Constructor.
451
452 @param buffer_arg_ref: "reference" to the buffer argument
453 @param buffer_arg_ref: "reference" to argument, which holds buffer size
454 """
455 transformer.transformer_t.__init__( self, function )
456
457 self.buffer_arg = self.get_argument( buffer_arg_ref )
458 self.buffer_arg_index = self.function.arguments.index( self.buffer_arg )
459
460 self.size_arg = self.get_argument( size_arg_ref )
461 self.size_arg_index = self.function.arguments.index( self.size_arg )
462
463 if not is_ptr_or_array( self.buffer_arg.type ):
464 raise ValueError( '%s\nin order to use "input_c_buffer" transformation, "buffer" argument %s type must be a array or a pointer (got %s).' ) \
465 % ( function, self.buffer_arg.name, self.buffer_arg.type)
466
467 if not declarations.is_integral( self.size_arg.type ):
468 raise ValueError( '%s\nin order to use "input_c_buffer" transformation, "size" argument %s type must be an integral type (got %s).' ) \
469 % ( function, self.size_arg.name, self.size_arg.type)
470
471 self.buffer_item_type = declarations.remove_const( declarations.array_item_type( self.buffer_arg.type ) )
472
474 return "input_c_buffer(buffer arg=%s, size arg=%s)" \
475 % ( self.buffer_arg.name, self.size_arg.name)
476
478 """Returns list of header files that transformer generated code depends on."""
479 return [ code_repository.convenience.file_name, '<vector>', '<iterator>' ]
480
482 global _seq2arr
483 w_buffer_arg = controller.find_wrapper_arg( self.buffer_arg.name )
484 w_buffer_arg.type = declarations.dummy_type_t( "boost::python::object" )
485
486 controller.remove_wrapper_arg( self.size_arg.name )
487
488 size_var = controller.declare_variable(
489 declarations.remove_const( self.size_arg.type )
490 , self.size_arg.name
491 , ' = boost::python::len(%s)' % w_buffer_arg.name )
492
493 # Declare a variable that will hold the C array...
494 buffer_var = controller.declare_variable(
495 declarations.dummy_type_t( "std::vector< %s >" % self.buffer_item_type.decl_string )
496 , "native_" + self.buffer_arg.name )
497
498 controller.add_pre_call_code( '%s.reserve( %s );' % ( buffer_var, size_var ) )
499
500 copy_pylist2arr = _seq2vector.substitute( type=self.buffer_item_type
501 , pylist=w_buffer_arg.name
502 , native_array=buffer_var )
503
504 controller.add_pre_call_code( copy_pylist2arr )
505
506 controller.modify_arg_expression( self.buffer_arg_index, '&%s[0]' % buffer_var )
507 controller.modify_arg_expression( self.size_arg_index, '%s' % size_var )
508
510 self.__configure_sealed( controller )
511
514 #global _arr2seq
515 #pylist = controller.declare_py_variable( declarations.dummy_type_t( 'boost::python::list' )
516 #, 'py_' + self.arg.name )
517
518 #copy_arr2pylist = _arr2seq.substitute( native_array=self.arg.name
519 #, array_size=self.array_size
520 #, pylist=pylist )
521
522 #controller.add_py_pre_call_code( copy_arr2pylist )
523
525 self.__configure_sealed( controller )
526
528 self.__configure_sealed( controller )
529
531 self.__configure_v_mem_fun_override( controller.override_controller )
532 self.__configure_v_mem_fun_default( controller.default_controller )
533
534
536 """see http://boost.org/libs/python/doc/v2/faq.html#ownership
537 """
539 """Constructor."""
540 transformer.transformer_t.__init__( self, function )
541 self.arg = self.get_argument( arg_ref )
542 self.arg_index = self.function.arguments.index( self.arg )
543 if not declarations.is_pointer( self.arg.type ):
544 raise ValueError( '%s\nin order to use "transfer ownership" transformation, argument %s type must be a pointer (got %s).' ) \
545 % ( function, self.arg_ref.name, arg.type)
546
548 return "transfer_ownership(%s)" % self.arg.name
549
551 w_arg = controller.find_wrapper_arg( self.arg.name )
552 naked_type = declarations.remove_pointer( self.arg.type )
553 naked_type = declarations.remove_declarated( naked_type )
554 w_arg.type = declarations.dummy_type_t( 'std::auto_ptr< %s >' % naked_type.decl_string )
555 controller.modify_arg_expression(self.arg_index, w_arg.name + '.release()' )
556
558 self.__configure_sealed( controller )
559
561 self.__configure_sealed( controller )
562
564 self.__configure_sealed( controller )
565
568
569 #TODO: FT for constructor
570 #~ def configure_constructor( self, controller ):
571 #~ self.__configure_sealed( controller )
572
576
| Trees | Indices | Help |
|
|---|
| Generated by Epydoc 3.0.1 on Mon Oct 20 08:51:36 2008 | http://epydoc.sourceforge.net |