| 
									
										
										
										
											1995-03-02 14:05:29 +00:00
										 |  |  | # | 
					
						
							|  |  |  | # 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', | 
					
						
							| 
									
										
										
										
											1998-04-10 19:15:27 +00:00
										 |  |  |             'tp_compare', 'tp_repr', 'tp_hash', 'tp_call', 'tp_str'] | 
					
						
							| 
									
										
										
										
											1995-03-02 14:05:29 +00:00
										 |  |  | 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): | 
					
						
							| 
									
										
										
										
											1998-04-10 19:15:27 +00:00
										 |  |  |         self._subst = None | 
					
						
							| 
									
										
										
										
											1995-03-02 14:05:29 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def makesubst(self): | 
					
						
							| 
									
										
										
										
											1998-04-10 19:15:27 +00:00
										 |  |  |         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 | 
					
						
							| 
									
										
										
										
											1995-03-02 14:05:29 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def addcode(self, name, fp): | 
					
						
							| 
									
										
										
										
											1998-04-10 19:15:27 +00:00
										 |  |  |         ifp = self.opentemplate(name) | 
					
						
							|  |  |  |         self.makesubst() | 
					
						
							|  |  |  |         d = ifp.read() | 
					
						
							|  |  |  |         d = self._subst(d) | 
					
						
							|  |  |  |         fp.write(d) | 
					
						
							| 
									
										
										
										
											1995-03-02 14:05:29 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def opentemplate(self, name): | 
					
						
							| 
									
										
										
										
											1998-04-10 19:15:27 +00:00
										 |  |  |         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 | 
					
						
							|  |  |  |          | 
					
						
							| 
									
										
										
										
											1995-03-02 14:05:29 +00:00
										 |  |  | class module(writer): | 
					
						
							|  |  |  |     _type = 'module' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def writecode(self, fp): | 
					
						
							| 
									
										
										
										
											1998-04-10 19:15:27 +00:00
										 |  |  |         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) | 
					
						
							| 
									
										
										
										
											1995-03-02 14:05:29 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | class object(writer): | 
					
						
							|  |  |  |     _type = 'object' | 
					
						
							|  |  |  |     def __init__(self): | 
					
						
							| 
									
										
										
										
											1998-04-10 19:15:27 +00:00
										 |  |  |         self.typelist = [] | 
					
						
							|  |  |  |         self.methodlist = [] | 
					
						
							|  |  |  |         self.funclist = ['new'] | 
					
						
							|  |  |  |         writer.__init__(self) | 
					
						
							| 
									
										
										
										
											1995-03-02 14:05:29 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def writecode(self, fp): | 
					
						
							| 
									
										
										
										
											1998-04-10 19:15:27 +00:00
										 |  |  |         self.addcode('copyright', fp) | 
					
						
							|  |  |  |         self.writehead(fp) | 
					
						
							|  |  |  |         self.writebody(fp) | 
					
						
							| 
									
										
										
										
											1995-03-02 14:05:29 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def writehead(self, fp): | 
					
						
							| 
									
										
										
										
											1998-04-10 19:15:27 +00:00
										 |  |  |         self.addcode('object_head', fp) | 
					
						
							| 
									
										
										
										
											1995-03-02 14:05:29 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def writebody(self, fp): | 
					
						
							| 
									
										
										
										
											1998-04-10 19:15:27 +00:00
										 |  |  |         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) | 
					
						
							| 
									
										
										
										
											1995-03-02 14:05:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-04-10 19:15:27 +00:00
										 |  |  |         # 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') | 
					
						
							| 
									
										
										
										
											1995-03-02 14:05:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-04-10 19:15:27 +00:00
										 |  |  |         # | 
					
						
							|  |  |  |         # 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) | 
					
						
							| 
									
										
										
										
											1995-03-02 14:05:29 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 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) |