cinap_lenrekadd hg and python4bb9e2215 years agoHistory
160 lines · 4.7 KB · Python
RawDownload
## 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 sysimport osimport 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)