[pygccxml-commit] SF.net SVN: pygccxml: [276] pygccxml_dev/pygccxml/parser
Brought to you by:
mbaas,
roman_yakovenko
From: <mb...@us...> - 2006-07-08 14:07:19
|
Revision: 276 Author: mbaas Date: 2006-07-08 07:07:13 -0700 (Sat, 08 Jul 2006) ViewCVS: http://svn.sourceforge.net/pygccxml/?rev=276&view=rev Log Message: ----------- Changed the internal storage for enumerations from dict to list so that the original order of the values is maintained. Modified Paths: -------------- pygccxml_dev/pygccxml/declarations/enumeration.py pygccxml_dev/pygccxml/parser/patcher.py pygccxml_dev/pygccxml/parser/scanner.py Modified: pygccxml_dev/pygccxml/declarations/enumeration.py =================================================================== --- pygccxml_dev/pygccxml/declarations/enumeration.py 2006-07-07 18:44:39 UTC (rev 275) +++ pygccxml_dev/pygccxml/declarations/enumeration.py 2006-07-08 14:07:13 UTC (rev 276) @@ -8,17 +8,35 @@ """ import declaration +import copy +import types class enumeration_t( declaration.declaration_t ): """ describes C++ enum """ def __init__( self, name='', parent=None, values=None ): + """Constructor. + + The items of the list 'values' may either be strings containing + the enumeration value name or tuples (name, numvalue). + + @param name: Enum name + @type name: str + @param parent: Parent declaration + @type parent: declaration_t + @param values: Enumeration values + @type values: list + """ declaration.declaration_t.__init__( self, name, parent ) - if not values: - values = {} - self._values = values # dict name(str) -> value(int) + # A list of tuples (valname(str), valnum(int)). The order of the list should + # be the same as the order in the C/C++ source file. + self._values = [] + + # Initialize values via property access + self.values = values + def __eq__(self, other): if not declaration.declaration_t.__eq__( self, other ): return False @@ -28,9 +46,64 @@ return [self.values] def _get_values(self): - return self._values + return copy.copy(self._values) def _set_values(self, values): - self._values = values + self._values = [] + # None is treated like an empty list + if (values==None): + return + # Check that we have indeed a list... + if type(values)!=list: + raise ValueError, "'values' must be a list (got a %s instead)"%type(values).__name__ + # Append the items individually. This has the effect that there's + # some additional type checking and that a copy of 'values' is stored + # and the caller cannot further manipulate the list via his own reference + for item in values: + if isinstance(item, types.StringTypes): + self.append_value(item) + elif type(item)==tuple: + name,num = item + self.append_value(name, num) + else: + raise ValueError, "'values' contains an invalid item: %s"%item values = property( _get_values, _set_values - , doc="dictionary that contains mapping between name and value, { name(str) : value(int) }") + , doc="""A list of tuples (valname(str), valnum(int)) that contain the enumeration values. + @type: list""") + def append_value(self, valuename, valuenum=None): + """Append another enumeration value to the enum. + + The numeric value may be None in which case it is automatically determined by + increasing the value of the last item. + + When the 'values' attribute is accessed the resulting list will be in the same + order as append_value() was called. + + @param valuename: The name of the value. + @type valuename: str + @param valuenum: The numeric value or None. + @type valuenum: int + """ + # No number given? Then use the previous one + 1 + if valuenum==None: + if len(self._values)==0: + valuenum = 0 + else: + valuenum = self._values[-1][1]+1 + + # Store the new value + self._values.append((valuename, int(valuenum))) + + def has_value_name(self, name): + """Check if this enum has a particular name among its values. + + @param name: Enumeration value name + @type name: str + @return: True if there is an enumeration value with the given name + """ + for val,num in self._values: + if val==name: + return True + return False + + Modified: pygccxml_dev/pygccxml/parser/patcher.py =================================================================== --- pygccxml_dev/pygccxml/parser/patcher.py 2006-07-07 18:44:39 UTC (rev 275) +++ pygccxml_dev/pygccxml/parser/patcher.py 2006-07-08 14:07:13 UTC (rev 276) @@ -56,7 +56,7 @@ type_ = declarations.remove_reference( declarations.remove_cv( arg.type ) ) if not declarations.is_enum( type_ ): return False - return type_.declaration.values.has_key( arg.default_value ) + return type_.declaration.has_value_name( arg.default_value ) def __fix_unqualified_enum( self, func, arg): type_ = declarations.remove_reference( declarations.remove_cv( arg.type ) ) @@ -106,9 +106,11 @@ enums = filter( lambda decl: isinstance( decl, declarations.enumeration_t ) , scope.declarations ) for enum_decl in enums: - if default_value in enum_decl.values.keys(): + valnames = map(lambda x: x[0], enum_decl.values) + valnums = map(lambda x: x[1], enum_decl.values) + if default_value in valnames: return enum_decl - if default_value in enum_decl.values.values(): + if default_value in valnums: return enum_decl else: return None @@ -188,4 +190,4 @@ patcher2 = fix_casting_operator_name_patcher_t( decls ) patcher2.patch_it() return patcher.decls - \ No newline at end of file + Modified: pygccxml_dev/pygccxml/parser/scanner.py =================================================================== --- pygccxml_dev/pygccxml/parser/scanner.py 2006-07-07 18:44:39 UTC (rev 275) +++ pygccxml_dev/pygccxml/parser/scanner.py 2006-07-08 14:07:13 UTC (rev 276) @@ -255,7 +255,9 @@ return self.__decl_factory.create_enumeration( name=enum_name ) def __read_enumeration_value( self, attrs ): - self.__inst.values[attrs.get( XML_AN_NAME, '' )] = attrs[XML_AN_INIT] + name = attrs.get( XML_AN_NAME, '' ) + num = int(attrs[XML_AN_INIT]) + self.__inst.append_value(name, num) def __read_array_type( self, attrs ): type_ = attrs[ XML_AN_TYPE ] This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |