mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 02:15:10 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			161 lines
		
	
	
	
		
			4.8 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable file
		
	
	
	
	
			
		
		
	
	
			161 lines
		
	
	
	
		
			4.8 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
 | |
| import string
 | |
| 
 | |
| 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 = string.upper(self.abbrev[0])+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)
 | 
