home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / C / Applications / Python 1.3 / source code / Tools / modulator / genmodule.py < prev    next >
Encoding:
Python Source  |  1995-12-17  |  4.0 KB  |  160 lines  |  [TEXT/R*ch]

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