| Trees | Indices | Help | 
 | 
|---|
|  | 
  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  """defines a class that writes L{code_creators.module_t} to multiple files, the class 
  7  also splits huge C++ classes to few source files 
  8  """ 
  9   
 10  import os 
 11  import writer 
 12  import multiple_files 
 13  from pygccxml import declarations 
 14  from pyplusplus import decl_wrappers 
 15  from pyplusplus import code_creators 
 16  from pyplusplus import utils as pypp_utils 
 17   
 18  #TODO: to add namespace_alias_t classes 
 20      """ 
 21      This class will split code, generated for huge classes, to few files. 
 22      Next strategy will be used: 
 23      1. New directory with class alias name will be created. 
 24      2. pyplusplus will generate 
 25         wrapper header - header that will contain code generated for class wrappers 
 26         classes h/cpp - will contain registration code for internal classes 
 27         memfun h/cpp - will contain registration code for member functions 
 28   
 29         alias + _main h/cpp this class will contain main registration function. 
 30      """ 
 31   
 32 -    def __init__( self 
 33                    , extmodule 
 34                    , directory_path 
 35                    , huge_classes 
 36                    , num_of_functions_per_file=20 
 37                    , files_sum_repository=None 
 38                    , encoding='ascii'): 
 39          multiple_files.multiple_files_t.__init__(self 
 40                                                   , extmodule 
 41                                                   , directory_path 
 42                                                   , files_sum_repository=files_sum_repository 
 43                                                   , encoding=encoding) 
 44          self.huge_classes = huge_classes 
 45          self.num_of_functions_per_file = num_of_functions_per_file 
 46          self.internal_splitters = [ 
 47              self.split_internal_enums 
 48              , self.split_internal_unnamed_enums 
 49              , self.split_internal_classes 
 50              , self.split_internal_memfuns 
 51              , self.split_internal_v_memfuns 
 52              , self.split_internal_pv_memfuns 
 53              , self.split_internal_protected_memfuns 
 54              #not supported yet 
 55              #, self.split_internal_member_variables 
 56          ] 
 57   
 60   
 63   
 65          answer = [] 
 66          if self.extmodule.license: 
 67              answer.append( self.extmodule.license.create() ) 
 68   
 69          creators = [class_creator] 
 70          if class_creator.wrapper: 
 71              creators.append( class_creator.wrapper ) 
 72               
 73          answer.append( self.create_include_code( creators ) ) 
 74          answer.append( '' ) 
 75          answer.append( self.create_namespaces_code( creators ) ) 
 76   
 77          if class_creator.wrapper: 
 78              answer.append( class_creator.wrapper.create() ) 
 79              class_creator.wrapper.create = lambda: '' 
 80   
 81          answer.append( '' ) 
 82          answer.append( class_creator.create_typedef_code() ) 
 83   
 84          code = os.linesep.join( answer ) 
 85          wrapper_code = self.create_header( self.create_base_fname(class_creator, 'wrapper'), code ) 
 86          header_file = os.path.join( self.directory_path, self.wrapper_header(class_creator) ) 
 87          self.write_file( header_file, wrapper_code ) 
 88   
 90          file_path = os.path.join( self.directory_path 
 91                                    , self.create_base_fname( class_creator, pattern ) ) 
 92   
 93          function_name = 'register_%(cls_alias)s_%(pattern)s' \ 
 94                          % { 'cls_alias' : class_creator.alias, 'pattern' : pattern } 
 95   
 96          function_decl = 'void %(fname)s( %(exposer_type)s& %(var_name)s )' \ 
 97                          % { 'fname' : function_name 
 98                              , 'exposer_type' : class_creator.typedef_name 
 99                              , 'var_name' : class_creator.class_var_name } 
100   
101          #writting header file 
102          header_code = [ '#include "%s"' % self.wrapper_header( class_creator ) ] 
103          header_code.append( '' ) 
104          header_code.append( function_decl + ';' ) 
105          self.write_file( file_path + self.HEADER_EXT 
106                           , self.create_header( class_creator.alias + '_' + pattern 
107                                                 , os.linesep.join(header_code) ) ) 
108   
109          #writting source file 
110          source_code = [] 
111          if self.extmodule.license: 
112              source_code.append( self.extmodule.license.create() ) 
113   
114          #relevant header file 
115          head_headers = [ self.create_base_fname( class_creator, pattern + self.HEADER_EXT ) ] 
116          source_code.append( self.create_include_code( creators, tail_headers=head_headers ) ) 
117   
118          source_code.append( '' ) 
119          source_code.append( self.create_namespaces_code( creators ) ) 
120   
121          for creator in creators: 
122              for decl_creator in self.associated_decl_creators( creator ): 
123                  source_code.append( '' ) 
124                  source_code.append( decl_creator.create() ) 
125                  if not isinstance( decl_creator, self.ref_count_creators ): 
126                      decl_creator.create = lambda: '' 
127   
128          # Write the register() function... 
129          source_code.append( '' ) 
130          source_code.append( '%s{' % function_decl ) 
131          source_code.append( '' ) 
132          for index, creator in enumerate( creators ): 
133              source_code.append( code_creators.code_creator_t.indent( creator.create() ) ) 
134              source_code.append( '' ) 
135              if 0 == index: 
136                  creator.create = lambda: function_name + '(%s);' % class_creator.class_var_name 
137              else: 
138                  creator.create = lambda: '' 
139          source_code.append( '}' ) 
140          self.write_file( file_path + self.SOURCE_EXT, os.linesep.join( source_code ) ) 
141   
143          """Write all enumerations into a separate .h/.cpp file. 
144          """ 
145          enums_creators = filter( lambda x: isinstance(x, code_creators.enum_t ) 
146                                   , class_creator.creators ) 
147          self.split_internal_creators( class_creator, enums_creators, 'enums' ) 
148          return 'enums' 
149   
151          creators = filter( lambda x: isinstance(x, code_creators.unnamed_enum_t ) 
152                             , class_creator.creators ) 
153          self.split_internal_creators( class_creator, creators, 'unnamed_enums' ) 
154          return 'unnamed_enums' 
155   
157          creators = filter( lambda x: isinstance(x, calldef_types ), class_creator.creators ) 
158          grouped_creators = pypp_utils.split_sequence( creators, self.num_of_functions_per_file ) 
159          if len( grouped_creators ) == 1: 
160              for creator in creators: 
161                  creator.works_on_instance = False 
162              self.split_internal_creators( class_creator, creators, pattern ) 
163              return pattern 
164          else: 
165              patterns = [] 
166              for index, group in enumerate( grouped_creators ): 
167                  pattern_tmp = pattern + str( index ) 
168                  patterns.append( pattern_tmp ) 
169                  for creator in group: 
170                      creator.works_on_instance = False 
171                  self.split_internal_creators( class_creator, group, pattern_tmp ) 
172              return patterns 
173   
175          calldef_types = ( code_creators.mem_fun_t, code_creators.mem_fun_overloads_t ) 
176          return self.split_internal_calldefs( class_creator, calldef_types, 'memfuns' ) 
177   
179          calldef_types = ( code_creators.mem_fun_v_t ) 
180          return self.split_internal_calldefs( class_creator, calldef_types, 'memfuns_virtual' ) 
181   
183          calldef_types = ( code_creators.mem_fun_pv_t ) 
184          return self.split_internal_calldefs( class_creator, calldef_types, 'memfuns_pvirtual' ) 
185   
187          calldef_types = ( 
188              code_creators.mem_fun_protected_t 
189              , code_creators.mem_fun_protected_s_t 
190              , code_creators.mem_fun_protected_v_t 
191              , code_creators.mem_fun_protected_pv_t ) 
192          return self.split_internal_calldefs( class_creator, calldef_types, 'protected_memfuns' ) 
193   
195          class_types = ( code_creators.class_t, code_creators.class_declaration_t ) 
196          creators = filter( lambda x: isinstance(x, class_types ), class_creator.creators ) 
197          self.split_internal_creators( class_creator, creators, 'classes' ) 
198          return 'classes' 
199   
201          creators = filter( lambda x: isinstance(x, code_creators.member_variable_base_t) 
202                             , class_creator.creators ) 
203          self.split_internal_creators( class_creator, creators, 'memvars' ) 
204          return 'memvars' 
205   
207          if not class_creator.declaration in self.huge_classes: 
208              return super( class_multiple_files_t, self ).split_class_impl( class_creator ) 
209   
210          class_creator.declaration.always_expose_using_scope = True 
211   
212          function_name = 'register_%s_class' % class_creator.alias 
213          file_path = os.path.join( self.directory_path, class_creator.alias ) 
214          # Write the .h file... 
215          header_name = file_path + self.HEADER_EXT 
216          self.write_file( header_name 
217                           , self.create_header( class_creator.alias 
218                                                 , self.create_function_code( function_name ) ) ) 
219   
220          self.write_wrapper( class_creator ) 
221   
222          tail_headers = [] 
223          for splitter in self.internal_splitters: 
224              pattern = splitter( class_creator ) 
225              if not pattern: 
226                  continue 
227              if isinstance( pattern, str ): 
228                  tail_headers.append( self.create_base_fname( class_creator, pattern + self.HEADER_EXT ) ) 
229              else: 
230                  assert( isinstance( pattern, list ) ) 
231                  for p in pattern: 
232                      tail_headers.append( self.create_base_fname( class_creator, p + self.HEADER_EXT ) ) 
233          #writting source file 
234          source_code = [] 
235          if self.extmodule.license: 
236              source_code.append( self.extmodule.license.create() ) 
237   
238          source_code.append( self.create_include_code( [class_creator], tail_headers=tail_headers ) ) 
239   
240          source_code.append( '' ) 
241          source_code.append( self.create_namespaces_code( [class_creator] ) ) 
242   
243          for creator in class_creator.associated_decl_creators: 
244              source_code.append( '' ) 
245              source_code.append( creator.create() ) 
246              if not isinstance( creator, self.ref_count_creators ): 
247                  creator.create = lambda: '' 
248   
249          # Write the register() function... 
250          source_code.append( '' ) 
251          source_code.append( 'void %s(){' % function_name ) 
252          source_code.append( '' ) 
253          source_code.append( class_creator.create() ) 
254          source_code.append( '' ) 
255          source_code.append( '}' ) 
256          self.write_file( file_path + self.SOURCE_EXT, os.linesep.join( source_code ) ) 
257   
258          # Replace the create() method so that only the register() method is called 
259          # (this is called later for the main source file). 
260          class_creator.create = lambda: function_name +'();' 
261          self.include_creators.append( code_creators.include_t( header_name ) ) 
262          self.split_header_names.append(header_name) 
263          self.split_method_names.append(function_name) 
264   
| Trees | Indices | Help | 
 | 
|---|
| Generated by Epydoc 3.0.1 on Mon Oct 20 08:51:34 2008 | http://epydoc.sourceforge.net |