Package pyplusplus :: Package utils

Source Code for Package pyplusplus.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  """ 
  7  This module is a collection of unrelated algorithms, that works on code creators 
  8  tree. 
  9  """ 
 10  import os 
 11  import math 
 12  from pygccxml import declarations 
 13  from pyplusplus import code_creators   
14 15 -class missing_call_policies:
16 @staticmethod
17 - def _selector( creator ):
18 if not isinstance( creator, code_creators.declaration_based_t ): 19 return False 20 if not isinstance( creator.declaration, declarations.calldef_t ): 21 return False 22 if isinstance( creator.declaration, declarations.constructor_t ): 23 return False 24 return hasattr(creator, 'call_policies') and not creator.call_policies
25 26 @staticmethod
27 - def print_( extmodule ):
28 creators = filter( missing_call_policies._selector 29 , code_creators.make_flatten_generator( extmodule.creators ) ) 30 for creator in creators: 31 print creator.declaration.__class__.__name__, ': ', declarations.full_name( creator.declaration ) 32 print ' *** MISSING CALL POLICY', creator.declaration.function_type().decl_string 33 print
34 35 @staticmethod
36 - def exclude( extmodule ):
41
42 -def split_sequence(seq, bucket_size):
43 #split sequence to buckets, where every will contain maximum bucket_size items 44 seq_len = len( seq ) 45 if seq_len <= bucket_size: 46 return [ seq ] 47 buckets = [] 48 num_of_buckets = int( math.ceil( float( seq_len ) / bucket_size ) ) 49 for i in range(num_of_buckets): 50 from_ = i * bucket_size 51 to = min( ( i + 1) * bucket_size, seq_len ) 52 buckets.append( seq[ from_ : to ] ) 53 return buckets
54
55 56 -class exposed_decls_db_t( object ):
57 DEFAULT_FILE_NAME = 'exposed_decl.pypp.txt'
58 - class row_t( declarations.decl_visitor_t ):
59 FIELD_DELIMITER = '@' 60 EXPOSED_DECL_SIGN = '+' 61 UNEXPOSED_DECL_SIGN = '~' 62 CALLDEF_SIGNATURE_DELIMITER = '#' 63
64 - def __init__( self, decl_or_string ):
65 self.key = '' 66 self.signature = '' 67 self.exposed_sign = '' 68 self.normalized_name = '' 69 if isinstance( decl_or_string, declarations.declaration_t ): 70 self.__init_from_decl( decl_or_string ) 71 else: 72 self.__init_from_str( decl_or_string )
73
74 - def find_out_normalized_name( self, decl ):
75 if decl.name: 76 return decl.partial_name 77 elif decl.location:#unnamed enums, classes, unions 78 return str( decl.location.as_tuple() ) 79 elif isinstance( decl, declarations.namespace_t ): 80 return '' #I don't really care about unnamed namespaces 81 else: #this should nevere happen 82 raise RuntimeError( "Unable to create normalized name for declaration: " + str(decl))
83
84 - def __init_from_str( self, row ):
85 self.exposed_sign, self.key, self.normalized_name, self.signature \ 86 = row.split( self.FIELD_DELIMITER )
87
88 - def update_key( self, cls ):
89 self.key = cls.__name__
90
91 - def __init_from_decl( self, decl ):
92 if decl.ignore: 93 self.exposed_sign = self.UNEXPOSED_DECL_SIGN 94 else: 95 self.exposed_sign = self.EXPOSED_DECL_SIGN 96 97 self.update_key( decl.__class__ ) 98 99 self.signature = decl.create_decl_string( with_defaults=False ) 100 if isinstance( decl, declarations.calldef_t ): 101 self.signature = self.signature + decl.function_type().decl_string 102 103 self.normalized_name = self.find_out_normalized_name( decl )
104
105 - def __str__( self ):
106 return self.FIELD_DELIMITER.join([ self.exposed_sign 107 , self.key 108 , self.normalized_name 109 , self.signature])
110
111 - def does_refer_same_decl( self, other ):
112 return self.key == other.key \ 113 and self.signature == other.signature \ 114 and self.normalized_name == other.normalized_name
115
116 - def __init__( self ):
117 self.__registry = {} # key : { name : set(row) } 118 self.__row_delimiter = os.linesep
119
120 - def save( self, fpath ):
121 if os.path.isdir( fpath ): 122 fpath = os.path.join( fpath, self.DEFAULT_FILE_NAME ) 123 f = file( fpath, 'w+b' ) 124 for name2rows in self.__registry.itervalues(): 125 for rows in name2rows.itervalues(): 126 for row in rows: 127 f.write( '%s%s' % ( str(row), self.__row_delimiter ) ) 128 f.close()
129
130 - def load( self, fpath ):
131 if os.path.isdir( fpath ): 132 fpath = os.path.join( fpath, self.DEFAULT_FILE_NAME ) 133 f = file( fpath, 'r+b' ) 134 for line in f: 135 row = self.row_t( line.replace( self.__row_delimiter, '' ) ) 136 self.__update_registry( row )
137
138 - def __update_registry( self, row ):
139 if not self.__registry.has_key( row.key ): 140 self.__registry[ row.key ] = { row.normalized_name : [row] } 141 else: 142 if not self.__registry[ row.key ].has_key( row.normalized_name ): 143 self.__registry[ row.key ][row.normalized_name] = [row] 144 else: 145 self.__registry[ row.key ][row.normalized_name].append(row)
146
147 - def __find_row_in_registry( self, row ):
148 try: 149 decls = filter( lambda rrow: rrow.does_refer_same_decl( row ) 150 , self.__registry[ row.key ][ row.normalized_name ] ) 151 if decls: 152 return decls[0] 153 else: 154 return None 155 except KeyError: 156 return None
157
158 - def __find_in_registry( self, decl ):
159 row = self.row_t( decl ) 160 found = self.__find_row_in_registry( row ) 161 if found: 162 return found 163 if isinstance( decl, declarations.class_t ): 164 row.update_key( declarations.class_declaration_t ) 165 found = self.__find_row_in_registry( row ) 166 if found: 167 return found 168 if isinstance( decl, declarations.class_declaration_t ): 169 row.update_key( declarations.class_t ) 170 found = self.__find_row_in_registry( row ) 171 if found: 172 return found 173 return None
174
175 - def is_exposed( self, decl ):
176 row = self.__find_in_registry( decl) 177 return row and self.row_t.EXPOSED_DECL_SIGN == row.exposed_sign
178
179 - def update_decls( self, global_ns ):
180 for decl in global_ns.decls(): 181 row = self.__find_in_registry( decl ) 182 if not row: 183 continue 184 if self.row_t.EXPOSED_DECL_SIGN == row.exposed_sign: 185 decl.ignore = False 186 decl.already_exposed = True 187 else: 188 decl.ignore = True 189 decl.already_exposed = False
190
191 - def register_decls( self, global_ns, special_decls ):
192 """register decls in the database 193 194 global_ns - reference to the global namespace object 195 special_decls - set of declarations, which were exposed, even so they 196 were not ``included``. For example std containers. 197 """ 198 for decl in global_ns.decls(): 199 row = self.row_t( decl ) 200 if decl in special_decls: 201 row.exposed_sign = row.EXPOSED_DECL_SIGN 202 self.__update_registry( row )
203