__all__ = ['CLine', 'Keyword', 'CTypeSpec', 'CDeclarator', 'CDeclaration', 'CArgument', 'CCode', 'CFunction', 'CSource', 'CHeader', 'CStdHeader'] from base import Component from utils import Line, Code, FileSource class CLine(Line): pass class Keyword(CLine): pass class CInitExpr(CLine): pass class CTypeSpec(CLine): """ >>> i = CTypeSpec('int') >>> print i.generate() int >>> print i.as_ptr().generate() int* """ def as_ptr(self): return self.__class__(self.generate()+'*') class CDeclarator(Component): """ >>> CDeclarator('name').generate() 'name' >>> CDeclarator('name','0').generate() 'name = 0' """ container_options = dict( Initializer = dict(default='',prefix=' = ', skip_prefix_when_empty=True, ignore_empty_content = True ), ScalarInitializer = dict(default='',prefix=' = ', skip_prefix_when_empty=True, ignore_empty_content = True ), SequenceInitializer = dict(default='',prefix=' = {\n', skip_prefix_when_empty=True, suffix='}', skip_suffix_when_empty=True, ignore_empty_content = True, separator = ',\n', use_indent=True, ), StringInitializer = dict(default='',prefix=' = "', skip_prefix_when_empty=True, suffix='"', skip_suffix_when_empty=True, ignore_empty_content = True, separator='\\n"\n"', replace_map = {'\n':'\\n'}, use_firstline_indent = True, ), ) default_component_class_name = 'CInitExpr' component_container_map = dict( CInitExpr = 'Initializer' ) def __repr__(self): return '%s(%s)' % (self.__class__.__name__, ', '.join(map(repr,[self.name]+[c for (c,l) in self.components]))) def initialize(self, name, *initvalues, **options): self.name = name self.is_string = options.get('is_string', None) if self.is_string: assert not options.get('is_scalar', None) self.is_scalar = False else: if name.endswith(']'): self.is_scalar = False else: self.is_scalar = options.get('is_scalar', True) map(self.add, initvalues) return self def update_containers(self): if self.is_scalar: self.container_ScalarInitializer += self.container_Initializer self.template = '%(name)s%(ScalarInitializer)s' elif self.is_string: self.container_StringInitializer += self.container_Initializer self.template = '%(name)s%(StringInitializer)s' elif len(self.containers)>1 or not self.is_scalar: self.container_SequenceInitializer += self.container_Initializer self.template = '%(name)s%(SequenceInitializer)s' else: self.container_ScalarInitializer += self.container_Initializer self.template = '%(name)s%(ScalarInitializer)s' class CDeclaration(Component): """ >>> d = CDeclaration('int', 'a') >>> print d.generate() int a >>> d += 'b' >>> print d.generate() int a, b >>> d += CDeclarator('c',1) >>> print d.generate() int a, b, c = 1 """ template = '%(CTypeSpec)s %(CDeclarator)s' container_options = dict( CTypeSpec = dict(default='int', separator=' '), CDeclarator = dict(default='', separator=', '), ) component_container_map = dict( CTypeSpec = 'CTypeSpec', CDeclarator = 'CDeclarator', ) default_component_class_name = 'CDeclarator' def __repr__(self): return '%s(%s)' % (self.__class__.__name__, ', '.join(map(repr,[c for (c,l) in self.components]))) def initialize(self, ctype, *declarators, **options): ctype = CTypeSpec(ctype) self.ctype = ctype self.add(ctype) map(self.add, declarators) return self class CArgument(CDeclaration): def initialize(self, name, ctype, **options): return CDeclaration.initialize(self, ctype, name, **options) class CCode(Code): parent_container_options = dict(default='', use_indent=True, ignore_empty_content=True) class CFunction(Component): """ >>> f = CFunction('foo') >>> print f.generate() int foo(void) { } >>> f += Keyword('static') >>> f += CArgument('a', 'int') >>> f += 'a = 2;' >>> print f.generate() static int foo(int a) { a = 2; } >>> f += CArgument('b', 'float') >>> f += CDeclaration('float', 'c') >>> f += CDeclaration('float', CDeclarator('d','3.0')) >>> print f.generate() static int foo(int a, float b) { float c; float d = 3.0; a = 2; } """ template = '''\ %(CSpecifier)s %(CTypeSpec)s %(name)s(%(CArgument)s) { %(CDeclaration)s %(CBody)s }''' container_options = dict( CArgument = dict(separator=', ', default='void'), CDeclaration = dict(default='', use_indent=True, ignore_empty_content=True, separator = ';\n', suffix=';', skip_suffix_when_empty=True), CBody = dict(default='', use_indent=True, ignore_empty_content=True), CTypeSpec = dict(default='int', separator = ' ', ignore_empty_content=True), CSpecifier = dict(default='', separator = ' ', ignore_empty_content = True) ) component_container_map = dict( CArgument = 'CArgument', CDeclaration = 'CDeclaration', CCode = 'CBody', CTypeSpec = 'CTypeSpec', Keyword = 'CSpecifier', ) default_component_class_name = 'CCode' def initialize(self, name, rctype='int', *components, **options): self.name = name rctype = CTypeSpec(rctype) self.rctype = rctype self.add(rctype) map(self.add, components) if options: self.warning('%s unused options: %s\n' % (self.__class__.__name__, options)) return self def __repr__(self): return '%s(%s)' % (self.__class__.__name__, ', '.join(map(repr,[self.name, self.rctype]+[c for (c,l) in self.components]))) class CHeader(CLine): """ >>> h = CHeader('noddy.h') >>> print h.generate() #include "noddy.h" """ template = '#include "%(line)s"' class CStdHeader(CHeader): template = '#include <%(line)s>' class CSource(FileSource): """ >>> s = CSource('foo.c') >>> print s.generate() #doctest: +ELLIPSIS /* -*- c -*- */ /* This file 'foo.c' is generated using ExtGen tool from NumPy version ... ExtGen is developed by Pearu Peterson . For more information see http://www.scipy.org/ExtGen/ . */ #ifdef __cplusplus extern "C" { #endif #ifdef __cplusplus } #endif """ container_options = dict( CHeader = dict(default='', prefix='\n/* CHeader */\n', skip_prefix_when_empty=True), CTypeDef = dict(default='', prefix='\n/* CTypeDef */\n', skip_prefix_when_empty=True), CProto = dict(default='', prefix='\n/* CProto */\n', skip_prefix_when_empty=True), CDefinition = dict(default='', prefix='\n/* CDefinition */\n', skip_prefix_when_empty=True), CDeclaration = dict(default='', separator=';\n', suffix=';', prefix='\n/* CDeclaration */\n', skip_prefix_when_empty=True), CMainProgram = dict(default='', prefix='\n/* CMainProgram */\n', skip_prefix_when_empty=True), ) template_c_header = '''\ /* -*- c -*- */ /* This file %(path)r is generated using ExtGen tool from NumPy version %(numpy_version)s. ExtGen is developed by Pearu Peterson . For more information see http://www.scipy.org/ExtGen/ . */''' template = template_c_header + ''' #ifdef __cplusplus extern \"C\" { #endif %(CHeader)s %(CTypeDef)s %(CProto)s %(CDefinition)s %(CDeclaration)s %(CMainProgram)s #ifdef __cplusplus } #endif ''' component_container_map = dict( CHeader = 'CHeader', CFunction = 'CDefinition', CDeclaration = 'CDeclaration', ) def _test(): import doctest doctest.testmod() if __name__ == "__main__": _test()