mirror of
https://github.com/python/cpython.git
synced 2025-07-22 18:55:22 +00:00

(with one small bugfix in bgen/bgen/scantools.py) This replaces string module functions with string methods for the stuff in the Tools directory. Several uses of string.letters etc. are still remaining.
160 lines
4.7 KiB
Python
Executable file
160 lines
4.7 KiB
Python
Executable file
#
|
|
# 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)
|