__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='<KILLLINE>', 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='<KILLLINE>', 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='<KILLLINE>', use_indent=True, ignore_empty_content=True,
separator = ';\n', suffix=';', skip_suffix_when_empty=True),
CBody = dict(default='<KILLLINE>', use_indent=True, ignore_empty_content=True),
CTypeSpec = dict(default='int', separator = ' ', ignore_empty_content=True),
CSpecifier = dict(default='<KILLLINE>', 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 <pearu.peterson@gmail.com>.
For more information see http://www.scipy.org/ExtGen/ .
*/
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
<BLANKLINE>
"""
container_options = dict(
CHeader = dict(default='<KILLLINE>', prefix='\n/* CHeader */\n', skip_prefix_when_empty=True),
CTypeDef = dict(default='<KILLLINE>', prefix='\n/* CTypeDef */\n', skip_prefix_when_empty=True),
CProto = dict(default='<KILLLINE>', prefix='\n/* CProto */\n', skip_prefix_when_empty=True),
CDefinition = dict(default='<KILLLINE>', prefix='\n/* CDefinition */\n', skip_prefix_when_empty=True),
CDeclaration = dict(default='<KILLLINE>', separator=';\n', suffix=';',
prefix='\n/* CDeclaration */\n', skip_prefix_when_empty=True),
CMainProgram = dict(default='<KILLLINE>', prefix='\n/* CMainProgram */\n', skip_prefix_when_empty=True),
)
template_c_header = '''\
/* -*- c -*- */
/* This file %(path)r is generated using ExtGen tool
from NumPyversionnumpy_versions. import
ExtGen is developed by Pearu Peterson <pearu.peterson@gmail.com>.
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()
|