symbian-qemu-0.9.1-12/python-2.6.1/Tools/modulator/genmodule.py
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     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 
       
    24 error = 'genmodule.error'
       
    25 
       
    26 #
       
    27 # Names of functions in the object-description struct.
       
    28 #
       
    29 FUNCLIST = ['new', 'tp_dealloc', 'tp_print', 'tp_getattr', 'tp_setattr',
       
    30             'tp_compare', 'tp_repr', 'tp_hash', 'tp_call', 'tp_str']
       
    31 TYPELIST = ['tp_as_number', 'tp_as_sequence', 'tp_as_mapping', 'structure']
       
    32 
       
    33 #
       
    34 # writer is a base class for the object and module classes
       
    35 # it contains code common to both.
       
    36 #
       
    37 class writer:
       
    38     def __init__(self):
       
    39         self._subst = None
       
    40 
       
    41     def makesubst(self):
       
    42         if not self._subst:
       
    43             if not self.__dict__.has_key('abbrev'):
       
    44                 self.abbrev = self.name
       
    45             self.Abbrev = self.abbrev[0].upper()+self.abbrev[1:]
       
    46             subst = varsubst.Varsubst(self.__dict__)
       
    47             subst.useindent(1)
       
    48             self._subst = subst.subst
       
    49 
       
    50     def addcode(self, name, fp):
       
    51         ifp = self.opentemplate(name)
       
    52         self.makesubst()
       
    53         d = ifp.read()
       
    54         d = self._subst(d)
       
    55         fp.write(d)
       
    56 
       
    57     def opentemplate(self, name):
       
    58         for p in sys.path:
       
    59             fn = os.path.join(p, name)
       
    60             if os.path.exists(fn):
       
    61                 return open(fn, 'r')
       
    62             fn = os.path.join(p, 'Templates')
       
    63             fn = os.path.join(fn, name)
       
    64             if os.path.exists(fn):
       
    65                 return open(fn, 'r')
       
    66         raise error, 'Template '+name+' not found for '+self._type+' '+ \
       
    67                      self.name
       
    68 
       
    69 class module(writer):
       
    70     _type = 'module'
       
    71 
       
    72     def writecode(self, fp):
       
    73         self.addcode('copyright', fp)
       
    74         self.addcode('module_head', fp)
       
    75         for o in self.objects:
       
    76             o.writehead(fp)
       
    77         for o in self.objects:
       
    78             o.writebody(fp)
       
    79         new_ml = ''
       
    80         for fn in self.methodlist:
       
    81             self.method = fn
       
    82             self.addcode('module_method', fp)
       
    83             new_ml = new_ml + (
       
    84                       '{"%s",\t(PyCFunction)%s_%s,\tMETH_VARARGS,\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 + (
       
   111                       '{"%s",\t(PyCFunction)%s_%s,\tMETH_VARARGS,\t%s_%s__doc__},\n'
       
   112                       %(fn, self.abbrev, fn, self.abbrev, fn))
       
   113         self.methodlist = new_ml
       
   114         self.addcode('object_mlist', fp)
       
   115 
       
   116         # Add getattr if we have methods
       
   117         if self.methodlist and not 'tp_getattr' in self.funclist:
       
   118             self.funclist.insert(0, 'tp_getattr')
       
   119 
       
   120         for fn in FUNCLIST:
       
   121             setattr(self, fn, '0')
       
   122 
       
   123         #
       
   124         # Special case for structure-access objects: put getattr in the
       
   125         # list of functions but don't generate code for it directly,
       
   126         # the code is obtained from the object_structure template.
       
   127         # The same goes for setattr.
       
   128         #
       
   129         if 'structure' in self.typelist:
       
   130             if 'tp_getattr' in self.funclist:
       
   131                 self.funclist.remove('tp_getattr')
       
   132             if 'tp_setattr' in self.funclist:
       
   133                 self.funclist.remove('tp_setattr')
       
   134             self.tp_getattr = self.abbrev + '_getattr'
       
   135             self.tp_setattr = self.abbrev + '_setattr'
       
   136         for fn in self.funclist:
       
   137             self.addcode('object_'+fn, fp)
       
   138             setattr(self, fn, '%s_%s'%(self.abbrev, fn[3:]))
       
   139         for tn in TYPELIST:
       
   140             setattr(self, tn, '0')
       
   141         for tn in self.typelist:
       
   142             self.addcode('object_'+tn, fp)
       
   143             setattr(self, tn, '&%s_%s'%(self.abbrev, tn[3:]))
       
   144         self.addcode('object_tail', fp)
       
   145 
       
   146 def write(fp, obj):
       
   147     obj.writecode(fp)
       
   148 
       
   149 if __name__ == '__main__':
       
   150     o = object()
       
   151     o.name = 'dwarve object'
       
   152     o.abbrev = 'dw'
       
   153     o.funclist = ['new', 'tp_dealloc']
       
   154     o.methodlist = ['dig']
       
   155     m = module()
       
   156     m.name = 'beings'
       
   157     m.abbrev = 'be'
       
   158     m.methodlist = ['newdwarve']
       
   159     m.objects = [o]
       
   160     write(sys.stdout, m)