#
# 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)
