# Copyright Bruno da Silva de Oliveira 2003. Use, modification and # distribution is subject to the Boost Software License, Version 1.0. # (See accompanying file LICENSE_1_0.txt or copy at # http://www.boost.org/LICENSE_1_0.txt) import os.path import copy import exporters from ClassExporter import ClassExporter from FunctionExporter import FunctionExporter from EnumExporter import EnumExporter from HeaderExporter import HeaderExporter from VarExporter import VarExporter from CodeExporter import CodeExporter from exporterutils import FunctionWrapper from utils import makeid import warnings #============================================================================== # DeclarationInfo #============================================================================== class DeclarationInfo: def __init__(self, otherInfo=None): self.__infos = {} self.__attributes = {} if otherInfo is not None: self.__infos = copy.deepcopy(otherInfo.__infos) self.__attributes = copy.deepcopy(otherInfo.__attributes) def __getitem__(self, name): 'Used to access sub-infos' if name.startswith('__'): raise AttributeError default = DeclarationInfo() default._Attribute('name', name) return self.__infos.setdefault(name, default) def __getattr__(self, name): return self[name] def _Attribute(self, name, value=None): if value is None: # get value return self.__attributes.get(name) else: # set value self.__attributes[name] = value def AddExporter(self, exporter): # this was causing a much serious bug, as reported by Niall Douglas: # another solution must be found! #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, exporter_class = FunctionExporter): DeclarationInfo.__init__(self, otherOption) self._Attribute('name', name) self._Attribute('include', include) self._Attribute('exclude', False) # create a FunctionExporter exporter = exporter_class(InfoWrapper(self), tail) self.AddExporter(exporter) #============================================================================== # ClassInfo #============================================================================== class ClassInfo(DeclarationInfo): 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 = exporter_class(InfoWrapper(self), tail) self.AddExporter(exporter) #============================================================================== # templates #============================================================================== def GenerateName(name, type_list): name = name.replace('::', '_') names = [name] + type_list return makeid('_'.join(names)) class ClassTemplateInfo(DeclarationInfo): 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): if not rename: rename = GenerateName(self._Attribute('name'), type_list) # generate code to instantiate the template types = ', '.join(type_list) tail = 'typedef %s< %s > %s;\n' % (self._Attribute('name'), types, rename) tail += 'void __instantiate_%s()\n' % rename tail += '{ sizeof(%s); }\n\n' % rename # create a ClassInfo class_ = ClassInfo(rename, self._Attribute('include'), tail, self, exporter_class = self._exporter_class) return class_ def __call__(self, types, rename=None): if isinstance(types, str): types = types.split() return self.Instantiate(types, rename) #============================================================================== # EnumInfo #============================================================================== class EnumInfo(DeclarationInfo): 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 = exporter_class(InfoWrapper(self)) self.AddExporter(exporter) #============================================================================== # HeaderInfo #============================================================================== class HeaderInfo(DeclarationInfo): def __init__(self, include, exporter_class = HeaderExporter): warnings.warn('AllFromHeader is not working in all cases in the current version.') DeclarationInfo.__init__(self) self._Attribute('include', include) exporter = exporter_class(InfoWrapper(self)) self.AddExporter(exporter) #============================================================================== # VarInfo #============================================================================== class VarInfo(DeclarationInfo): def __init__(self, name, include, exporter_class = VarExporter): DeclarationInfo.__init__(self) self._Attribute('name', name) self._Attribute('include', include) exporter = exporter_class(InfoWrapper(self)) self.AddExporter(exporter) #============================================================================== # CodeInfo #============================================================================== class CodeInfo(DeclarationInfo): def __init__(self, code, section, exporter_class = CodeExporter): DeclarationInfo.__init__(self) self._Attribute('code', code) self._Attribute('section', section) exporter = exporter_class(InfoWrapper(self)) self.AddExporter(exporter) #============================================================================== # InfoWrapper #============================================================================== class InfoWrapper: 'Provides a nicer interface for a info' def __init__(self, info): self.__dict__['_info'] = info # so __setattr__ is not called def __getitem__(self, name): return InfoWrapper(self._info[name]) def __getattr__(self, name): return self._info._Attribute(name) def __setattr__(self, name, value): self._info._Attribute(name, value) #============================================================================== # Functions #============================================================================== def exclude(info): info._Attribute('exclude', True) def set_policy(info, policy): info._Attribute('policy', policy) def rename(info, name): info._Attribute('rename', name) def set_wrapper(info, wrapper): if isinstance(wrapper, str): wrapper = FunctionWrapper(wrapper) info._Attribute('wrapper', wrapper) def instantiate(template, types, rename=None): if isinstance(types, str): types = types.split() return template.Instantiate(types, rename) def use_shared_ptr(info): info._Attribute('smart_ptr', 'boost::shared_ptr< %s >') def use_auto_ptr(info): info._Attribute('smart_ptr', 'std::auto_ptr< %s >') def holder(info, function): msg = "Expected a callable that accepts one string argument." assert callable(function), msg info._Attribute('holder', function) def add_method(info, name, rename=None): added = info._Attribute('__added__') if added is None: info._Attribute('__added__', [(name, rename)]) else: added.append((name, rename)) def class_code(info, code): added = info._Attribute('__code__') if added is None: info._Attribute('__code__', [code]) else: added.append(code) def final(info): info._Attribute('no_override', True) def export_values(info): info._Attribute('export_values', True)