From 4f2dbeda28ef4792f6897231f6dae52cc62ebc05 Mon Sep 17 00:00:00 2001 From: Bruno da Silva de Oliveira Date: Fri, 19 Sep 2003 23:07:14 +0000 Subject: [PATCH] bugs in Enum and export_values option [SVN r20121] --- pyste/NEWS | 3 ++ pyste/src/Pyste/CppParser.py | 8 ++++- pyste/src/Pyste/EnumExporter.py | 54 ++++++++++++++++++++++++++++++--- pyste/src/Pyste/infos.py | 5 +++ pyste/src/Pyste/pyste.py | 3 +- pyste/tests/enums.pyste | 1 + pyste/tests/enumsUT.py | 14 ++++----- 7 files changed, 75 insertions(+), 13 deletions(-) diff --git a/pyste/NEWS b/pyste/NEWS index 05ae45a8..2cee0c65 100644 --- a/pyste/NEWS +++ b/pyste/NEWS @@ -1,3 +1,6 @@ +19 September 2003 +Better support for unnamed enums, plus they are by default exported to the parent's namespace. Normal enums can have the same behaviour using the function export_values on the Enum object. + 10 September 2003 A new variable is accessible in the Pyste files: INTERFACE_FILE contains the full path of the pyste file. diff --git a/pyste/src/Pyste/CppParser.py b/pyste/src/Pyste/CppParser.py index 33ce7190..526d61e4 100644 --- a/pyste/src/Pyste/CppParser.py +++ b/pyste/src/Pyste/CppParser.py @@ -55,7 +55,7 @@ class CppParser: if not filedir: filedir = '.' includes.insert(0, filedir) - includes = ['-I "%s"' % x for x in includes] + includes = ['-I "%s"' % self.Unixfy(x) for x in includes] return ' '.join(includes) @@ -88,6 +88,10 @@ class CppParser: return temp + def Unixfy(self, path): + return path.replace('\\', '/') + + def ParseWithGCCXML(self, header, tail): '''Parses the given header using gccxml and GCCXMLParser. ''' @@ -103,6 +107,8 @@ class CppParser: defines = self._DefineParams() # call gccxml cmd = 'gccxml %s %s %s -fxml=%s' + filename = self.Unixfy(filename) + xmlfile = self.Unixfy(xmlfile) status = os.system(cmd % (includes, defines, filename, xmlfile)) if status != 0 or not os.path.isfile(xmlfile): raise CppParserError, 'Error executing gccxml' diff --git a/pyste/src/Pyste/EnumExporter.py b/pyste/src/Pyste/EnumExporter.py index d4aabaf4..a9763878 100644 --- a/pyste/src/Pyste/EnumExporter.py +++ b/pyste/src/Pyste/EnumExporter.py @@ -19,15 +19,20 @@ class EnumExporter(Exporter): else: self.enum = None - + TYPE_COUNT = 0 + def Export(self, codeunit, exported_names): if not self.info.exclude: indent = self.INDENT in_indent = self.INDENT*2 rename = self.info.rename or self.enum.name full_name = self.enum.FullName() - if rename == "$_0" or rename == '._0': - full_name = "int" + unnamed_enum = False + if rename.startswith('$_') or rename.startswith('._'): + unnamed_enum = True + self.ExportUniqueInt(codeunit) + full_name = namespaces.pyste + 'UniqueInt<%d>' % EnumExporter.TYPE_COUNT + EnumExporter.TYPE_COUNT += 1 rename = "unnamed" code = indent + namespaces.python code += 'enum_< %s >("%s")\n' % (full_name, rename) @@ -35,9 +40,50 @@ class EnumExporter(Exporter): rename = self.info[name].rename or name value_fullname = self.enum.ValueFullName(name) code += in_indent + '.value("%s", %s)\n' % (rename, value_fullname) + if self.info.export_values or unnamed_enum: + code += in_indent + '.export_values()\n' code += indent + ';\n\n' codeunit.Write('module', code) - exported_names[self.Name()] = 1 + exported_names[self.enum.FullName()] = 1 + + + UNIQUE_INT_EXPORTED = False + + def ExportUniqueInt(self, codeunit): + if not EnumExporter.UNIQUE_INT_EXPORTED: + write = lambda s: codeunit.Write('declaration', s) + write('// Unique type for unnamed enums\n') + write('template\n') + write('struct UniqueInt {\n') + write(' int v;\n') + write(' enum { value=num };\n') + write(' UniqueInt(int v_):\n') + write(' v(v_)\n') + write(' {}\n') + write(' operator int() const\n') + write(' { return v; }\n') + write('};\n') + EnumExporter.UNIQUE_INT_EXPORTED = True + + + #def Export(self, codeunit, exported_names): + # if not self.info.exclude: + # indent = self.INDENT + # in_indent = self.INDENT*2 + # rename = self.info.rename or self.enum.name + # full_name = self.enum.FullName() + # if rename == "$_0" or rename == '._0': + # full_name = "int" + # rename = "unnamed" + # code = indent + namespaces.python + # code += 'enum_< %s >("%s")\n' % (full_name, rename) + # for name in self.enum.values: + # rename = self.info[name].rename or name + # value_fullname = self.enum.ValueFullName(name) + # code += in_indent + '.value("%s", %s)\n' % (rename, value_fullname) + # code += indent + ';\n\n' + # codeunit.Write('module', code) + # exported_names[self.Name()] = 1 def Name(self): diff --git a/pyste/src/Pyste/infos.py b/pyste/src/Pyste/infos.py index bda45615..2985226d 100644 --- a/pyste/src/Pyste/infos.py +++ b/pyste/src/Pyste/infos.py @@ -125,6 +125,7 @@ class EnumInfo(DeclarationInfo): self._Attribute('name', name) self._Attribute('include', include) self._Attribute('exclude', False) + self._Attribute('export_values', False) exporter = EnumExporter(InfoWrapper(self)) if exporter not in exporters.exporters: exporters.exporters.append(exporter) @@ -236,3 +237,7 @@ def add_method(info, name, rename=None): def final(info): info._Attribute('no_override', True) + + +def export_values(info): + info._Attribute('export_values', True) diff --git a/pyste/src/Pyste/pyste.py b/pyste/src/Pyste/pyste.py index 3e595f31..6d95c56e 100644 --- a/pyste/src/Pyste/pyste.py +++ b/pyste/src/Pyste/pyste.py @@ -43,7 +43,7 @@ from CppParser import CppParser, CppParserError import time import declarations -__version__ = '0.9.24' +__version__ = '0.9.25' def RecursiveIncludes(include): 'Return a list containg the include dir and all its subdirectories' @@ -182,6 +182,7 @@ def CreateContext(): context['holder'] = infos.holder context['add_method'] = infos.add_method context['final'] = infos.final + context['export_values'] = infos.export_values # policies context['return_internal_reference'] = return_internal_reference context['with_custodian_and_ward'] = with_custodian_and_ward diff --git a/pyste/tests/enums.pyste b/pyste/tests/enums.pyste index afb94316..c18a1244 100644 --- a/pyste/tests/enums.pyste +++ b/pyste/tests/enums.pyste @@ -1,6 +1,7 @@ h = AllFromHeader('enums.h') rename(h.color.red, 'Red') rename(h.color.blue, 'Blue') +export_values(h.color) rename(h.X.choices.bad, 'Bad') rename(h.X.choices.good, 'Good') rename(h.X.choices, 'Choices') diff --git a/pyste/tests/enumsUT.py b/pyste/tests/enumsUT.py index 4701f217..cd1a8d9e 100644 --- a/pyste/tests/enumsUT.py +++ b/pyste/tests/enumsUT.py @@ -4,16 +4,16 @@ from _enums import * class EnumsTest(unittest.TestCase): def testIt(self): - self.assertEqual(int(color.Red), 0) - self.assertEqual(int(color.Blue), 1) + self.assertEqual(int(Red), 0) + self.assertEqual(int(Blue), 1) self.assertEqual(int(X.Choices.Good), 1) self.assertEqual(int(X.Choices.Bad), 2) - x = X() - self.assertEqual(x.set(x.Choices.Good), 1) - self.assertEqual(x.set(x.Choices.Bad), 2) - self.assertEqual(unnamed.x, 0) - self.assertEqual(unnamed.y, 1) + a = X() + self.assertEqual(a.set(a.Choices.Good), 1) + self.assertEqual(a.set(a.Choices.Bad), 2) + self.assertEqual(x, 0) + self.assertEqual(y, 1) if __name__ == '__main__':