Package pyplusplus :: Package code_creators :: Module code_creator |

# Source Code for Module pyplusplus.code_creators.code_creator

      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 types
      8
      9 -class code_creator_t(object):
     10      """
     11      code_creator_t is the base class for all code creators.
     12
     13      This class defines the interface that every code creator should implement.
     14      Also it provides few convenience functions.
     15
     16      The purpose of a code creator is the generation of a block of C++
     17      source code as it will appear in the final source code for the
     18      extension module. The source code is obtained by calling the L{create()}
     19      method. Derived classes must implement the L{_create_impl()} method
     20      which is called by the create() method.
     21      """
     22      PYPLUSPLUS_NS_NAME = 'pyplusplus'
     23      __INDENTATION = '    '
     24      LINE_LENGTH = 80
     25      PARAM_SEPARATOR = ', '
     26 -    def __init__(self):
     27          """Constructor.
     28
     29          @param parent: Parent code creator.
     30          @type parent: code_creator_t
     31          """
     32          object.__init__(self)
     33          self._parent = None
     34          self._target_configuration = None
     35          self._works_on_instance = True
     36
     37
     38 -    def _get_works_on_instance(self):
     39          return self._works_on_instance
     40 -    def _set_works_on_instance(self, works_on_instance):
     41          self._works_on_instance = works_on_instance
     42      works_on_instance = property( _get_works_on_instance, _set_works_on_instance )
     43
     44 -    def _get_parent( self ):
     45          return self._parent
     46 -    def _set_parent( self, new_parent ):
     47          if new_parent:
     48              assert isinstance( new_parent, code_creator_t )
     49          self._parent = new_parent
     50      """parent - reference to parent code creator"""
     51      parent = property( _get_parent, _set_parent,
     52                         doc="""Parent code creator or None if this is the root node.
     53                         @type: L{code_creator_t}
     54                         """)
     55
     56 -    def _get_target_configuration( self ):
     57          return self._target_configuration
     58 -    def _set_target_configuration( self, config ):
     59          self._target_configuration = config
     60      """target_configuration - reference to target_configuration_t class instance"""
     61      target_configuration = property( _get_target_configuration, _set_target_configuration,
     62                                       doc="""Target configuration.
     63                                       @type: L{target_configuration_t}
     64                                       """)
     65
     66 -    def _get_top_parent(self):
     67          parent = self.parent
     68          me = self
     69          while True:
     70              if not parent:
     71                  return me
     72              else:
     73                  me = parent
     74                  parent = me.parent
     75      """top_parent - reference to top parent code creator"""
     76      top_parent = property( _get_top_parent,
     77                             doc="""Root of the code creator tree.
     78                             @type: L{code_creator_t}
     79                             """)
     80
     81 -    def _create_impl(self):
     82          """
     83          function that all derived classes should implement. This function
     84          actually creates code and returns it. Return value of this function is
     85          string.
     86
     87          @rtype: str
     88          """
     89          raise NotImplementedError()
     90
     91 -    def create(self):
     92          """
     93          this function should be used in order to get code that should be
     94          generated.
     95
     96          @returns: Returns a text block of C++ source code.
     97          @rtype: str
     98          """
     99          code = self._create_impl()
    100          assert isinstance( code, types.StringTypes )
    101          return self.beautify( code )
    102
    103      @staticmethod
    104 -    def unique_headers( headers ):
    105          used = set()
    106          uheaders = []
    107          for h in headers:
    108              if h not in used:
    109                  used.add( h )
    110                  uheaders.append( h )
    111          return uheaders
    112
    113 -    def _get_system_headers_impl( self ):
    114          """Return list of system header files the generated code depends on"""
    115          raise NotImplementedError(self.__class__.__name__)
    116
    117 -    def get_system_headers( self, recursive=False, unique=False ):
    118          files = [ "boost/python.hpp" ]
    119          files.extend( self._get_system_headers_impl() )
    120          files = filter( None, files)
    121          if unique:
    122              files = self.unique_headers( files )
    123          return files
    124
    125 -    def beautify( self, code ):
    126          """
    127          function that returns code without leading and trailing whitespaces.
    128
    129          @param code: A code block with C++ source code.
    130          @type code: str
    131          @rtype: str
    132          """
    133          assert isinstance( code, types.StringTypes )
    134          return code.strip()
    135
    136      @staticmethod
    137 -    def indent( code, size=1 ):
    138          """
    139          function that implements code indent algorithm.
    140
    141          @param code: C++ code block.
    142          @type code: str
    143          @param size: The number of indentation levels that the code is shifted
    144          @type size: int
    145          @returns: Returns indented source code
    146          @rtype: str
    147          """
    148          assert isinstance( code, types.StringTypes )
    149          return code_creator_t.__INDENTATION * size\
    150                 + code.replace( os.linesep
    151                                 , os.linesep + code_creator_t.__INDENTATION * size )
    152
    153      @staticmethod
    154 -    def unindent( code ):
    155          """
    156          function that implements code unindent algorithm.
    157
    158          @param code: C++ code block.
    159          @type code: str
    160          @rtype: str
    161          """
    162          assert isinstance( code, types.StringTypes )
    163          if code.startswith(code_creator_t.__INDENTATION):
    164              code = code[ len( code_creator_t.__INDENTATION ):]
    165          return code.replace( os.linesep + code_creator_t.__INDENTATION
    166                                 , os.linesep )
    167
    168      @staticmethod
    169 -    def is_comment( line ):
    170          """
    171          function that returns true if content of the line is comment, otherwise
    172          false.
    173
    174          @param line: C++ source code
    175          @type line: str
    176          @rtype: bool
    177          """
    178          assert isinstance( line, types.StringTypes )
    179          l = line.lstrip()
    180          return l.startswith( '//' ) or l.startswith( '/*' )
    181