1   
  2   
  3   
  4   
  5   
  6  import os 
  7  import types 
  8  import pprint 
  9  import xml.sax 
 10  import warnings 
 11  import xml.sax.handler 
 12  from pygccxml.declarations import * 
 13  from pygccxml import utils 
 14   
 15   
 16   
 17   
 18   
 19  XML_AN_ABSTRACT = "abstract" 
 20  XML_AN_ACCESS = "access" 
 21  XML_AN_ALIGN = "align" 
 22  XML_AN_ARTIFICIAL = "artificial" 
 23  XML_AN_ATTRIBUTES = "attributes" 
 24  XML_AN_BASE_TYPE = "basetype" 
 25  XML_AN_BASES = "bases" 
 26  XML_AN_BITS = "bits" 
 27  XML_AN_CONST = "const" 
 28  XML_AN_CONTEXT = "context" 
 29  XML_AN_CVS_REVISION = "cvs_revision" 
 30  XML_AN_DEFAULT = "default" 
 31  XML_AN_DEMANGLED = "demangled" 
 32  XML_AN_EXTERN = "extern" 
 33  XML_AN_FILE = "file" 
 34  XML_AN_ID = "id" 
 35  XML_AN_INCOMPLETE = "incomplete" 
 36  XML_AN_INIT = "init" 
 37  XML_AN_LINE = "line" 
 38  XML_AN_MANGLED = "mangled" 
 39  XML_AN_MAX = "max" 
 40  XML_AN_MEMBERS = "members" 
 41  XML_AN_MUTABLE = "mutable" 
 42  XML_AN_NAME = "name" 
 43  XML_AN_OFFSET = "offset" 
 44  XML_AN_PURE_VIRTUAL = "pure_virtual" 
 45  XML_AN_RESTRICT = "restrict" 
 46  XML_AN_RETURNS = "returns" 
 47  XML_AN_SIZE = "size" 
 48  XML_AN_STATIC = "static" 
 49  XML_AN_THROW = "throw" 
 50  XML_AN_TYPE = "type" 
 51  XML_AN_VIRTUAL = "virtual" 
 52  XML_AN_VOLATILE = "volatile" 
 53  XML_NN_ARGUMENT = "Argument" 
 54  XML_NN_ARRAY_TYPE = "ArrayType" 
 55  XML_NN_CASTING_OPERATOR = "Converter" 
 56  XML_NN_CLASS = "Class" 
 57  XML_NN_CONSTRUCTOR = "Constructor" 
 58  XML_NN_CV_QUALIFIED_TYPE = "CvQualifiedType" 
 59  XML_NN_DESTRUCTOR = "Destructor" 
 60  XML_NN_ELLIPSIS = "Ellipsis" 
 61  XML_NN_ENUMERATION = "Enumeration" 
 62  XML_NN_ENUMERATION_VALUE = "EnumValue" 
 63  XML_NN_FIELD = "Field" 
 64  XML_NN_FILE = "File" 
 65  XML_NN_FUNCTION = "Function" 
 66  XML_NN_FUNCTION_TYPE = "FunctionType" 
 67  XML_NN_FUNDAMENTAL_TYPE = "FundamentalType" 
 68  XML_NN_FREE_OPERATOR = "OperatorFunction" 
 69  XML_NN_GCC_XML = "GCC_XML" 
 70  XML_NN_MEMBER_OPERATOR = "OperatorMethod" 
 71  XML_NN_METHOD = "Method" 
 72  XML_NN_METHOD_TYPE = "MethodType" 
 73  XML_NN_NAMESPACE = "Namespace" 
 74  XML_NN_OFFSET_TYPE = "OffsetType" 
 75  XML_NN_POINTER_TYPE = "PointerType" 
 76  XML_NN_REFERENCE_TYPE = "ReferenceType" 
 77  XML_NN_ROOT = "GCC_XML" 
 78  XML_NN_STRUCT = "Struct" 
 79  XML_NN_TYPEDEF = "Typedef" 
 80  XML_NN_UNION = "Union" 
 81  XML_NN_VARIABLE = "Variable" 
 82   
 83 -class scanner_t( xml.sax.handler.ContentHandler ): 
  84 -    def __init__(self, gccxml_file, decl_factory, *args ): 
  85          xml.sax.handler.ContentHandler.__init__(self, *args ) 
 86          self.logger = utils.loggers.gccxml 
 87          self.gccxml_file = gccxml_file 
 88           
 89          self.__readers = { 
 90                 XML_NN_FILE : self.__read_file 
 91                 , XML_NN_NAMESPACE : self.__read_namespace 
 92                 , XML_NN_ENUMERATION : self.__read_enumeration 
 93                 , XML_NN_ENUMERATION_VALUE : self.__read_enumeration_value 
 94                 , XML_NN_ARRAY_TYPE : self.__read_array_type 
 95                 , XML_NN_CV_QUALIFIED_TYPE : self.__read_cv_qualified_type 
 96                 , XML_NN_POINTER_TYPE : self.__read_pointer_type 
 97                 , XML_NN_REFERENCE_TYPE : self.__read_reference_type 
 98                 , XML_NN_FUNDAMENTAL_TYPE : self.__read_fundamental_type 
 99                 , XML_NN_ARGUMENT : self.__read_argument 
100                 , XML_NN_FUNCTION_TYPE : self.__read_function_type 
101                 , XML_NN_METHOD_TYPE : self.__read_method_type 
102                 , XML_NN_OFFSET_TYPE : self.__read_offset_type 
103                 , XML_NN_TYPEDEF : self.__read_typedef 
104                 , XML_NN_VARIABLE : self.__read_variable 
105                 , XML_NN_CLASS : self.__read_class 
106                 , XML_NN_STRUCT : self.__read_struct 
107                 , XML_NN_UNION : self.__read_union 
108                 , XML_NN_FIELD : self.__read_field 
109                 , XML_NN_CASTING_OPERATOR : self.__read_casting_operator 
110                 , XML_NN_CONSTRUCTOR : self.__read_constructor 
111                 , XML_NN_DESTRUCTOR : self.__read_destructor 
112                 , XML_NN_FUNCTION : self.__read_function 
113                 , XML_NN_FREE_OPERATOR : self.__read_free_operator 
114                 , XML_NN_MEMBER_OPERATOR : self.__read_member_operator 
115                 , XML_NN_METHOD : self.__read_method 
116                 , XML_NN_GCC_XML : self.__read_version 
117                 , XML_NN_ELLIPSIS : self.__read_ellipsis 
118          } 
119          self.deep_declarations = [ 
120              XML_NN_CASTING_OPERATOR 
121              , XML_NN_CONSTRUCTOR 
122              , XML_NN_DESTRUCTOR 
123              , XML_NN_ENUMERATION 
124              , XML_NN_FILE 
125              , XML_NN_FUNCTION 
126              , XML_NN_FREE_OPERATOR 
127              , XML_NN_MEMBER_OPERATOR 
128              , XML_NN_METHOD 
129              , XML_NN_FUNCTION_TYPE 
130              , XML_NN_METHOD_TYPE 
131          ] 
132   
133          assert isinstance( decl_factory, decl_factory_t ) 
134          self.__decl_factory = decl_factory 
135   
136           
137          self.__declarations = {} 
138           
139          self.__calldefs = [] 
140           
141          self.__enums = [] 
142           
143          self.__types = {} 
144           
145          self.__files = {} 
146           
147          self.__access = {} 
148           
149          self.__inst = None 
150           
151          self.__members = {} 
152   
153          self.__compiler = None 
 154   
156          xml.sax.parse( self.gccxml_file, self ) 
 157   
159           
160          members_mapping = {} 
161          for gccxml_id, members in self.__members.iteritems(): 
162              decl = self.__declarations.get( gccxml_id, None ) 
163              if not decl or not isinstance( decl, scopedef_t): 
164                  continue 
165              members_mapping[ id( decl ) ] = members 
166          self.__members = members_mapping 
 167   
170   
172          return self.__calldefs 
 173   
176   
179   
182   
185   
187          return self.__members 
 188   
191   
194   
196          try: 
197              if name not in self.__readers: 
198                  return 
199              obj = self.__readers[name]( attrs ) 
200              if not obj: 
201                  return  
202                          
203              if name in self.deep_declarations: 
204                  self.__inst = obj 
205              self.__read_access( attrs ) 
206              element_id = attrs.get(XML_AN_ID, None) 
207              if isinstance( obj, declaration_t ): 
208                  obj.compiler = self.__compiler 
209                  self.__update_membership( attrs ) 
210                  self.__declarations[ element_id ] = obj 
211                  if not isinstance( obj, namespace_t ): 
212                      self.__read_location( obj, attrs ) 
213                  if isinstance( obj, class_t): 
214                      self.__read_bases( obj, attrs ) 
215                  self.__read_artificial(obj, attrs) 
216                  self.__read_mangled( obj, attrs) 
217                  self.__read_demangled( obj, attrs) 
218                  self.__read_attributes(obj, attrs) 
219   
220              elif isinstance( obj, type_t ): 
221                  self.__types[ element_id ] = obj 
222                  self.__read_byte_size(obj, attrs) 
223                  self.__read_byte_align(obj, attrs) 
224              elif isinstance( obj, types.StringTypes ): 
225                  self.__files[ element_id ] = obj 
226              else: 
227                  self.logger.warning( 'Unknown object type has been found.' 
228                                       + ' Please report this bug to pygccxml development team.' ) 
229          except Exception, error: 
230              msg = 'error occured, while parsing element with name "%s" and attrs "%s".' 
231              msg = msg + os.linesep + 'Error: %s.' % str( error ) 
232              self.logger.error( msg % ( name, pprint.pformat( attrs.keys() ) ) ) 
233              raise 
 234   
236          if name in self.deep_declarations: 
237              self.__inst = None 
 238   
241   
249   
252   
255   
258   
261   
264   
267   
270   
275   
280   
285   
288   
291   
293          ns_name = attrs.get( XML_AN_NAME, '' ) 
294          if '.' in ns_name: 
295               
296               
297               
298              ns_name = '' 
299          return self.__decl_factory.create_namespace( name=ns_name ) 
 300   
302          enum_name = attrs.get( XML_AN_NAME, '' ) 
303          if '$_' in enum_name or '._' in enum_name: 
304               
305              enum_name = '' 
306          decl = self.__decl_factory.create_enumeration( name=enum_name ) 
307          self.__read_byte_size(decl, attrs) 
308          self.__read_byte_align(decl, attrs) 
309          self.__enums.append( decl ) 
310          return decl 
 311   
316   
318           
319           
320          numeric_suffix_letters = 'UuLlFf' 
321          for s in numeric_suffix_letters: 
322              value_as_str = value_as_str.replace( s, '' ) 
323          try: 
324              return int( value_as_str ) 
325          except ValueError: 
326              try: 
327                  return int( value_as_str, 16 ) 
328              except ValueError: 
329                  return None 
 330   
339   
349   
352   
355   
357          try: 
358              return FUNDAMENTAL_TYPES[ attrs.get( XML_AN_NAME, '' ) ] 
359          except KeyError: 
360              raise RuntimeError( "pygccxml error: unable to find fundamental type with name '%s'." 
361                                  % attrs.get( XML_AN_NAME, '' ) ) 
 362   
370   
383   
390   
408   
422   
424          answer = free_function_type_t() 
425          self.__read_calldef( answer, attrs, False ) 
426          return answer 
 427   
429          answer = member_function_type_t() 
430          self.__read_member_function( answer, attrs, False ) 
431          return answer 
 432   
435   
437          type_qualifiers = type_qualifiers_t() 
438          type_qualifiers.has_mutable = attrs.get(XML_AN_MUTABLE, False) 
439          type_qualifiers.has_static = attrs.get(XML_AN_EXTERN, False) 
440          bits = attrs.get( XML_AN_BITS, None ) 
441          if bits: 
442              bits = int( bits ) 
443          decl = self.__decl_factory.create_variable( name=attrs.get( XML_AN_NAME, '' ) 
444                                                      , type=attrs[XML_AN_TYPE] 
445                                                      , type_qualifiers=type_qualifiers 
446                                                      , value=attrs.get( XML_AN_INIT, None ) 
447                                                      , bits=bits) 
448          self.__read_byte_offset(decl, attrs) 
449          return decl 
 450   
451      __read_field = __read_variable  
452   
469   
472   
475   
478   
483   
488   
490          gfunction = self.__decl_factory.create_free_function() 
491          self.__read_calldef( gfunction, attrs, True ) 
492          return gfunction 
 493   
495          mfunction = self.__decl_factory.create_member_function() 
496          self.__read_member_function( mfunction, attrs, True ) 
497          return mfunction 
 498   
500          destructor = self.__decl_factory.create_destructor() 
501          self.__read_member_function( destructor, attrs, True ) 
502          destructor.name = '~' + destructor.name 
503          return destructor 
 504   
513   
522