Package pyplusplus :: Package code_creators :: Module global_variable |

# Source Code for Module pyplusplus.code_creators.global_variable

      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 pygccxml
      8  import algorithm
      9  import code_creator
     10  import declaration_based
     11  import registration_based
     12  from pygccxml import declarations
     13  from pyplusplus import code_repository
     14  from pyplusplus import decl_wrappers
     15
     16 -class global_variable_base_t( registration_based.registration_based_t
     17                                , declaration_based.declaration_based_t ):
     18      """
     19      Base class for all global variables code creators. Mainly exists to
     20      simplify file writers algorithms.
     21      """
     22 -    def __init__(self, variable, wrapper=None ):
     23          registration_based.registration_based_t.__init__( self )
     24          declaration_based.declaration_based_t.__init__( self, declaration=variable)
     25          self._wrapper = wrapper
     26
     27 -    def _get_wrapper( self ):
     28          return self._wrapper
     29 -    def _set_wrapper( self, new_wrapper ):
     30          self._wrapper = new_wrapper
     31      wrapper = property( _get_wrapper, _set_wrapper )
     32
     33 -    def _get_system_headers_impl( self ):
     34          return []
     35
     36 -class global_variable_t( global_variable_base_t ):
     37      """
     38      Creates boost.python code that exposes global variable.
     39      """
     40 -    def __init__(self, variable ):
     41          global_variable_base_t.__init__( self, variable=variable )
     42
     43 -    def _create_impl(self):
     44          if self.declaration.already_exposed:
     45              return ''
     46
     47          assert isinstance( self.declaration, pygccxml.declarations.variable_t )
     48          result = []
     49          result.append( algorithm.create_identifier( self, '::boost::python::scope' ) )
     50          result.append( '().attr("%s")' % self.alias )
     51          dtype = self.declaration.type
     52          if decl_wrappers.python_traits.is_immutable( dtype ) \
     53             or pygccxml.declarations.is_const( dtype ) \
     54             or pygccxml.declarations.smart_pointer_traits.is_smart_pointer( dtype ):
     55              result.append( ' = %s;' % self.decl_identifier )
     56          else:
     57              obj_identifier = algorithm.create_identifier( self, '::boost::python::object' )
     58              ref_identifier = algorithm.create_identifier( self, '::boost::ref' )
     59              result.append( ' = %s( %s( %s ) );' % ( obj_identifier, ref_identifier, self.decl_identifier ) )
     60          return ''.join( result )
     61
     62 -class array_gv_t( global_variable_base_t ):
     63      """
     64      Creates boost.python code that exposes array global variable.
     65      """
     66
     67      _PARAM_SEPARATOR = ', '
     68 -    def __init__(self, variable, wrapper ):
     69          global_variable_base_t.__init__( self, variable=variable, wrapper=wrapper )
     70
     71 -    def _get_system_headers_impl( self ):
     72          return []
     73
     74 -    def _create_impl( self ):
     75          if self.declaration.already_exposed:
     76              return ''
     77
     78          answer = []
     79          answer.append( algorithm.create_identifier( self, '::boost::python::scope' ) )
     80          answer.append( '().attr("%s")' % self.alias )
     81          answer.append( ' = ' )
     82          answer.append( self.wrapper.wrapper_creator_full_name )
     83          answer.append( '();' )
     84          return ''.join( answer )
     85
     86 -class array_gv_wrapper_t( code_creator.code_creator_t
     87                            , declaration_based.declaration_based_t ):
     88      """
     89      Creates C++ code that register array class.
     90      """
     91
     92 -    def __init__(self, variable ):
     93          code_creator.code_creator_t.__init__( self )
     94          declaration_based.declaration_based_t.__init__( self, declaration=variable)
     95
     96 -    def _get_wrapper_type( self ):
     97          ns_name = code_repository.array_1.namespace
     98          if declarations.is_const( self.declaration.type ):
     99              class_name = 'const_array_1_t'
    100          else:
    101              class_name = 'array_1_t'
    102
    103          decl_string = declarations.templates.join(
    104                '::'.join( [ns_name, class_name] )
    105              , [ declarations.array_item_type( self.declaration.type ).decl_string
    106                  , str( declarations.array_size( self.declaration.type ) )
    107          ])
    108
    109          return declarations.dummy_type_t( decl_string )
    110      wrapper_type = property( _get_wrapper_type )
    111
    112 -    def _get_wrapper_creator_type(self):
    113          return declarations.free_function_type_t.create_decl_string(
    114                  return_type=self.wrapper_type
    115                  , arguments_types=[]
    116                  , with_defaults=False)
    117      wrapper_creator_type = property( _get_wrapper_creator_type )
    118
    119 -    def _get_wrapper_creator_name(self):
    120          return '_'.join( [self.declaration.name, 'wrapper'] )
    121      wrapper_creator_name = property( _get_wrapper_creator_name )
    122
    123 -    def _create_namespaces(self):
    124          ns_names = declarations.declaration_path( self.declaration.parent )
    125          if len(ns_names) >= 1 and ns_names[0] == '::':
    126              ns_names = ns_names[1:]
    127          return ns_names
    128
    129 -    def _get_wrapper_creator_full_name(self):
    130          names = self._create_namespaces()
    131          names.append( self.wrapper_creator_name )
    132          return '::'.join( names )
    133      wrapper_creator_full_name = property( _get_wrapper_creator_full_name )
    134
    135 -    def _create_namespaces_name(self):
    136          temp = []
    137          for ns_name in self._create_namespaces():
    138              temp.append( ''.join( ['namespace ', ns_name, '{ '] ) )
    139          return ''.join( temp )
    140
    141 -    def _create_impl( self ):
    142          if self.declaration.already_exposed:
    143              return ''
    144
    145          answer = [self._create_namespaces_name()]
    146          answer.append( self.wrapper_type.decl_string )
    147          answer.append( ''.join([ self.wrapper_creator_name, '(){']) )
    148          temp = ''.join([ 'return '
    149                           , self.wrapper_type.decl_string
    150                           , '( '
    151                           , declarations.full_name( self.declaration )
    152                           , ' );'])
    153          answer.append( self.indent( temp ) )
    154          answer.append('}')
    155          answer.append( '}' * len( self._create_namespaces() ) )
    156          return os.linesep.join( answer )
    157
    158 -    def _get_system_headers_impl( self ):
    159          return [code_repository.array_1.file_name]
    160
    161 -class global_variable_addressof_t( global_variable_base_t ):
    162      """
    163      Creates boost.python code that exposes address of global variable.
    164
    165      This functionality is pretty powerful if you use it with "ctypes" -
    166      standard package.
    167      """
    168 -    def __init__(self, variable ):
    169          global_variable_base_t.__init__( self, variable=variable )
    170
    171 -    def _create_impl(self):
    172          if self.declaration.already_exposed:
    173              return ''
    174
    175          assert isinstance( self.declaration, pygccxml.declarations.variable_t )
    176          result = []
    177          #TODO: porting to 64Bit is welcome
    178          result.append( algorithm.create_identifier( self, '::boost::python::scope' ) )
    179          result.append( '().attr("%s")' % self.alias )
    180          result.append( ' = boost::uint32_t( boost::addressof( %s ) );' % self.decl_identifier )
    181          return ''.join( result )
    182
    183 -    def _get_system_headers_impl( self ):
    184          return [code_repository.ctypes_integration.file_name]
    185