1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
|
#
# Genmodule - A python program to help you build (template) modules.
#
# Usage:
#
# o = genmodule.object()
# o.name = 'dwarve object'
# o.abbrev = 'dw'
# o.funclist = ['new', 'dealloc', 'getattr', 'setattr']
# o.methodlist = ['dig']
#
# m = genmodule.module()
# m.name = 'beings'
# m.abbrev = 'be'
# m.methodlist = ['newdwarve']
# m.objects = [o]
#
# genmodule.write(sys.stdout, m)
#
import sys
import os
import varsubst
error = 'genmodule.error'
#
# Names of functions in the object-description struct.
#
FUNCLIST = ['new', 'tp_dealloc', 'tp_print', 'tp_getattr', 'tp_setattr',
'tp_compare', 'tp_repr', 'tp_hash', 'tp_call', 'tp_str']
TYPELIST = ['tp_as_number', 'tp_as_sequence', 'tp_as_mapping', 'structure']
#
# writer is a base class for the object and module classes
# it contains code common to both.
#
class writer:
def __init__(self):
self._subst = None
def makesubst(self):
if not self._subst:
if not self.__dict__.has_key('abbrev'):
self.abbrev = self.name
self.Abbrev = self.abbrev[0].upper()+self.abbrev[1:]
subst = varsubst.Varsubst(self.__dict__)
subst.useindent(1)
self._subst = subst.subst
def addcode(self, name, fp):
ifp = self.opentemplate(name)
self.makesubst()
d = ifp.read()
d = self._subst(d)
fp.write(d)
def opentemplate(self, name):
for p in sys.path:
fn = os.path.join(p, name)
if os.path.exists(fn):
return open(fn, 'r')
fn = os.path.join(p, 'Templates')
fn = os.path.join(fn, name)
if os.path.exists(fn):
return open(fn, 'r')
raise error, 'Template '+name+' not found for '+self._type+' '+ \
self.name
class module(writer):
_type = 'module'
def writecode(self, fp):
self.addcode('copyright', fp)
self.addcode('module_head', fp)
for o in self.objects:
o.writehead(fp)
for o in self.objects:
o.writebody(fp)
new_ml = ''
for fn in self.methodlist:
self.method = fn
self.addcode('module_method', fp)
new_ml = new_ml + (
'{"%s",\t(PyCFunction)%s_%s,\tMETH_VARARGS,\t%s_%s__doc__},\n'
%(fn, self.abbrev, fn, self.abbrev, fn))
self.methodlist = new_ml
self.addcode('module_tail', fp)
class object(writer):
_type = 'object'
def __init__(self):
self.typelist = []
self.methodlist = []
self.funclist = ['new']
writer.__init__(self)
def writecode(self, fp):
self.addcode('copyright', fp)
self.writehead(fp)
self.writebody(fp)
def writehead(self, fp):
self.addcode('object_head', fp)
def writebody(self, fp):
new_ml = ''
for fn in self.methodlist:
self.method = fn
self.addcode('object_method', fp)
new_ml = new_ml + (
'{"%s",\t(PyCFunction)%s_%s,\tMETH_VARARGS,\t%s_%s__doc__},\n'
%(fn, self.abbrev, fn, self.abbrev, fn))
self.methodlist = new_ml
self.addcode('object_mlist', fp)
# Add getattr if we have methods
if self.methodlist and not 'tp_getattr' in self.funclist:
self.funclist.insert(0, 'tp_getattr')
for fn in FUNCLIST:
setattr(self, fn, '0')
#
# Special case for structure-access objects: put getattr in the
# list of functions but don't generate code for it directly,
# the code is obtained from the object_structure template.
# The same goes for setattr.
#
if 'structure' in self.typelist:
if 'tp_getattr' in self.funclist:
self.funclist.remove('tp_getattr')
if 'tp_setattr' in self.funclist:
self.funclist.remove('tp_setattr')
self.tp_getattr = self.abbrev + '_getattr'
self.tp_setattr = self.abbrev + '_setattr'
for fn in self.funclist:
self.addcode('object_'+fn, fp)
setattr(self, fn, '%s_%s'%(self.abbrev, fn[3:]))
for tn in TYPELIST:
setattr(self, tn, '0')
for tn in self.typelist:
self.addcode('object_'+tn, fp)
setattr(self, tn, '&%s_%s'%(self.abbrev, tn[3:]))
self.addcode('object_tail', fp)
def write(fp, obj):
obj.writecode(fp)
if __name__ == '__main__':
o = object()
o.name = 'dwarve object'
o.abbrev = 'dw'
o.funclist = ['new', 'tp_dealloc']
o.methodlist = ['dig']
m = module()
m.name = 'beings'
m.abbrev = 'be'
m.methodlist = ['newdwarve']
m.objects = [o]
write(sys.stdout, m)
|