diff --git a/pyste/NEWS b/pyste/NEWS index 355d1b97..5d12e14a 100644 --- a/pyste/NEWS +++ b/pyste/NEWS @@ -1,3 +1,6 @@ +23 October 2003 +Fixed bug where a class would appear more than one in the generated code. + 6 October 2003 Fixed bug reported by Niall Douglas (using his patch) about UniqueInt not appearing correctly with --multiple. diff --git a/pyste/src/Pyste/ClassExporter.py b/pyste/src/Pyste/ClassExporter.py index c680383c..32dcef58 100644 --- a/pyste/src/Pyste/ClassExporter.py +++ b/pyste/src/Pyste/ClassExporter.py @@ -598,7 +598,7 @@ class ClassExporter(Exporter): nested_info = self.info[nested_class.name] nested_info.include = self.info.include nested_info.name = nested_class.FullName() - exporter = ClassExporter(nested_info) + exporter = self.__class__(nested_info) exporter.SetDeclarations(self.declarations) codeunit = SingleCodeUnit(None, None) exporter.Export(codeunit, exported_names) diff --git a/pyste/src/Pyste/SingleCodeUnit.py b/pyste/src/Pyste/SingleCodeUnit.py index b02ba384..19a689be 100644 --- a/pyste/src/Pyste/SingleCodeUnit.py +++ b/pyste/src/Pyste/SingleCodeUnit.py @@ -17,6 +17,7 @@ class SingleCodeUnit: Represents a cpp file, where other objects can write in one of the predefined sections. The avaiable sections are: + pchinclude - The pre-compiled header area include - The include area of the cpp file declaration - The part before the module definition module - Inside the BOOST_PYTHON_MODULE macro @@ -28,6 +29,8 @@ class SingleCodeUnit: # define the avaiable sections self.code = {} # include section + self.code['pchinclude'] = '' + # include section self.code['include'] = '' # declaration section (inside namespace) self.code['declaration'] = '' @@ -74,15 +77,17 @@ class SingleCodeUnit: fout.write('\n') # includes # boost.python header - fout.write(left_equals('Boost Includes')) - fout.write('#include \n') - # include numerical boost for int64 definitions - fout.write('#include \n') - if settings.msvc: - # include precompiled header directive + if self.code['pchinclude']: + fout.write(left_equals('PCH')) + fout.write(self.code['pchinclude']+'\n') fout.write('#ifdef _MSC_VER\n') fout.write('#pragma hdrstop\n') - fout.write('#endif\n') + fout.write('#endif\n') + else: + fout.write(left_equals('Boost Includes')) + fout.write('#include \n') + # include numerical boost for int64 definitions + fout.write('#include \n') fout.write('\n') # other includes if self.code['include']: diff --git a/pyste/src/Pyste/exporters.py b/pyste/src/Pyste/exporters.py index 8d62c8b1..0d2d147f 100644 --- a/pyste/src/Pyste/exporters.py +++ b/pyste/src/Pyste/exporters.py @@ -8,3 +8,5 @@ exporters = [] current_interface = None # the current interface file being processed +importing = False # whetever we are now importing a pyste file. + # exporters created here shouldn't export themselves diff --git a/pyste/src/Pyste/infos.py b/pyste/src/Pyste/infos.py index 661d79b7..9ae76e38 100644 --- a/pyste/src/Pyste/infos.py +++ b/pyste/src/Pyste/infos.py @@ -51,21 +51,27 @@ class DeclarationInfo: self.__attributes[name] = value + def AddExporter(self, exporter): + if not exporters.importing: + if exporter not in exporters.exporters: + exporters.exporters.append(exporter) + exporter.interface_file = exporters.current_interface + + #============================================================================== # FunctionInfo #============================================================================== class FunctionInfo(DeclarationInfo): - def __init__(self, name, include, tail=None, otherOption=None): + def __init__(self, name, include, tail=None, otherOption=None, + exporter_class = FunctionExporter): DeclarationInfo.__init__(self, otherOption) self._Attribute('name', name) self._Attribute('include', include) self._Attribute('exclude', False) # create a FunctionExporter - exporter = FunctionExporter(InfoWrapper(self), tail) - if exporter not in exporters.exporters: - exporters.exporters.append(exporter) - exporter.interface_file = exporters.current_interface + exporter = exporter_class(InfoWrapper(self), tail) + self.AddExporter(exporter) #============================================================================== @@ -73,16 +79,15 @@ class FunctionInfo(DeclarationInfo): #============================================================================== class ClassInfo(DeclarationInfo): - def __init__(self, name, include, tail=None, otherInfo=None): + def __init__(self, name, include, tail=None, otherInfo=None, + exporter_class = ClassExporter): DeclarationInfo.__init__(self, otherInfo) self._Attribute('name', name) self._Attribute('include', include) self._Attribute('exclude', False) # create a ClassExporter - exporter = ClassExporter(InfoWrapper(self), tail) - if exporter not in exporters.exporters: - exporters.exporters.append(exporter) - exporter.interface_file = exporters.current_interface + exporter = exporter_class(InfoWrapper(self), tail) + self.AddExporter(exporter) #============================================================================== @@ -96,10 +101,12 @@ def GenerateName(name, type_list): class ClassTemplateInfo(DeclarationInfo): - def __init__(self, name, include): + def __init__(self, name, include, + exporter_class = ClassExporter): DeclarationInfo.__init__(self) self._Attribute('name', name) self._Attribute('include', include) + self._exporter_class = exporter_class def Instantiate(self, type_list, rename=None): @@ -111,7 +118,8 @@ class ClassTemplateInfo(DeclarationInfo): tail += 'void __instantiate_%s()\n' % rename tail += '{ sizeof(%s); }\n\n' % rename # create a ClassInfo - class_ = ClassInfo(rename, self._Attribute('include'), tail, self) + class_ = ClassInfo(rename, self._Attribute('include'), tail, self, + exporter_class = self._exporter_class) return class_ @@ -125,16 +133,14 @@ class ClassTemplateInfo(DeclarationInfo): #============================================================================== class EnumInfo(DeclarationInfo): - def __init__(self, name, include): + def __init__(self, name, include, exporter_class = EnumExporter): DeclarationInfo.__init__(self) 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) - exporter.interface_file = exporters.current_interface + exporter = exporter_class(InfoWrapper(self)) + self.AddExporter(exporter) #============================================================================== @@ -142,13 +148,11 @@ class EnumInfo(DeclarationInfo): #============================================================================== class HeaderInfo(DeclarationInfo): - def __init__(self, include): + def __init__(self, include, exporter_class = HeaderExporter): DeclarationInfo.__init__(self) self._Attribute('include', include) - exporter = HeaderExporter(InfoWrapper(self)) - if exporter not in exporters.exporters: - exporters.exporters.append(exporter) - exporter.interface_file = exporters.current_interface + exporter = exporter_class(InfoWrapper(self)) + self.AddExporter(exporter) #============================================================================== @@ -156,14 +160,12 @@ class HeaderInfo(DeclarationInfo): #============================================================================== class VarInfo(DeclarationInfo): - def __init__(self, name, include): + def __init__(self, name, include, exporter_class = VarExporter): DeclarationInfo.__init__(self) self._Attribute('name', name) self._Attribute('include', include) - exporter = VarExporter(InfoWrapper(self)) - if exporter not in exporters.exporters: - exporters.exporters.append(exporter) - exporter.interface_file = exporters.current_interface + exporter = exporter_class(InfoWrapper(self)) + self.AddExporter(exporter) #============================================================================== @@ -171,14 +173,12 @@ class VarInfo(DeclarationInfo): #============================================================================== class CodeInfo(DeclarationInfo): - def __init__(self, code, section): + def __init__(self, code, section, exporter_class = CodeExporter): DeclarationInfo.__init__(self) self._Attribute('code', code) self._Attribute('section', section) - exporter = CodeExporter(InfoWrapper(self)) - if exporter not in exporters.exporters: - exporters.exporters.append(exporter) - exporter.interface_file = exporters.current_interface + exporter = exporter_class(InfoWrapper(self)) + self.AddExporter(exporter) #============================================================================== diff --git a/pyste/src/Pyste/pyste.py b/pyste/src/Pyste/pyste.py index 237ce1c9..91ed4e50 100644 --- a/pyste/src/Pyste/pyste.py +++ b/pyste/src/Pyste/pyste.py @@ -51,7 +51,7 @@ from CppParser import CppParser, CppParserError import time import declarations -__version__ = '0.9.27' +__version__ = '0.9.28' def RecursiveIncludes(include): 'Return a list containg the include dir and all its subdirectories' @@ -182,15 +182,21 @@ def ParseArguments(): ProcessIncludes(includes) return includes, defines, module, out, files, multiple, cache_dir, create_cache, generate_main + +def PCHInclude(*headers): + code = '\n'.join(['#include <%s>' % x for x in headers]) + infos.CodeInfo(code, 'pchinclude') + def CreateContext(): 'create the context where a interface file will be executed' context = {} - context['Import'] = ExecuteInterface + context['Import'] = Import # infos context['Function'] = infos.FunctionInfo context['Class'] = infos.ClassInfo context['Include'] = lambda header: infos.CodeInfo('#include <%s>\n' % header, 'include') + context['PCHInclude'] = PCHInclude context['Template'] = infos.ClassTemplateInfo context['Enum'] = infos.EnumInfo context['AllFromHeader'] = infos.HeaderInfo @@ -279,6 +285,12 @@ def ExecuteInterface(interface): execfile(interface, context) exporters.current_interface = old_interface + +def Import(interface): + exporters.importing = True + ExecuteInterface(interface) + exporters.importing = False + def JoinTails(exports): '''Returns a dict of {(interface, header): tail}, where tail is the diff --git a/pyste/src/Pyste/utils.py b/pyste/src/Pyste/utils.py index 766bcb9a..23b3b2a7 100644 --- a/pyste/src/Pyste/utils.py +++ b/pyste/src/Pyste/utils.py @@ -44,7 +44,9 @@ def makeid(name): def remove_duplicated_lines(text): includes = text.splitlines() d = dict([(include, 0) for include in includes]) - return '\n'.join(d.keys()) + includes = d.keys() + includes.sort() + return '\n'.join(includes) #==============================================================================