home *** CD-ROM | disk | FTP | other *** search
/ Hackers Magazine 57 / CdHackersMagazineNr57.iso / Software / Multimedia / k3d-setup-0.7.11.0.exe / lib / site-packages / gtk-2.0 / codegen / definitions.py < prev    next >
Encoding:
Python Source  |  2007-11-01  |  20.9 KB  |  548 lines

  1. # -*- Mode: Python; py-indent-offset: 4 -*-
  2. import copy
  3. import sys
  4.  
  5. def get_valid_scheme_definitions(defs):
  6.     return [x for x in defs if isinstance(x, tuple) and len(x) >= 2]
  7.  
  8. def unescape(s):
  9.     s = s.replace('\r\n', '\\r\\n').replace('\t', '\\t')
  10.     return s.replace('\r', '\\r').replace('\n', '\\n')
  11.  
  12. def make_docstring(lines):
  13.     return "(char *) " + '\n'.join(['"%s"' % unescape(s) for s in lines])
  14.  
  15. # New Parameter class, wich emulates a tuple for compatibility reasons
  16. class Parameter(object):
  17.     def __init__(self, ptype, pname, pdflt, pnull, pdir=None):
  18.         self.ptype = ptype
  19.         self.pname = pname
  20.         self.pdflt = pdflt
  21.         self.pnull = pnull
  22.         self.pdir = pdir
  23.  
  24.     def __len__(self): return 4
  25.     def __getitem__(self, i):
  26.         return (self.ptype, self.pname, self.pdflt, self.pnull)[i]
  27.  
  28.     def merge(self, old):
  29.         if old.pdflt is not None:
  30.             self.pdflt = old.pdflt
  31.         if old.pnull is not None:
  32.             self.pnull = old.pnull
  33.  
  34. # Parameter for property based constructors
  35. class Property(object):
  36.     def __init__(self, pname, optional, argname):
  37.         self.pname = pname
  38.         self.optional = optional
  39.         self.argname = argname
  40.  
  41.     def merge(self, old):
  42.         if old.optional is not None:
  43.             self.optional = old.optional
  44.         if old.argname is not None:
  45.             self.argname = old.argname
  46.  
  47.  
  48. class Definition:
  49.     docstring = "NULL"
  50.     def __init__(self, *args):
  51.         """Create a new defs object of this type.  The arguments are the
  52.         components of the definition"""
  53.         raise RuntimeError, "this is an abstract class"
  54.     def merge(self, old):
  55.         """Merge in customisations from older version of definition"""
  56.         raise RuntimeError, "this is an abstract class"
  57.     def write_defs(self, fp=sys.stdout):
  58.         """write out this definition in defs file format"""
  59.         raise RuntimeError, "this is an abstract class"
  60.  
  61.     def guess_return_value_ownership(self):
  62.         "return 1 if caller owns return value"
  63.         if getattr(self, 'is_constructor_of', False):
  64.             self.caller_owns_return = True
  65.         elif self.ret in ('char*', 'gchar*', 'string'):
  66.             self.caller_owns_return = True
  67.         else:
  68.             self.caller_owns_return = False
  69.  
  70.  
  71. class ObjectDef(Definition):
  72.     def __init__(self, name, *args):
  73.         self.name = name
  74.         self.module = None
  75.         self.parent = None
  76.         self.c_name = None
  77.         self.typecode = None
  78.         self.fields = []
  79.         self.implements = []
  80.         self.class_init_func = None
  81.         self.has_new_constructor_api = False
  82.         for arg in get_valid_scheme_definitions(args):
  83.             if arg[0] == 'in-module':
  84.                 self.module = arg[1]
  85.             elif arg[0] == 'docstring':
  86.                 self.docstring = make_docstring(arg[1:])
  87.             elif arg[0] == 'parent':
  88.                 self.parent = arg[1]
  89.             elif arg[0] == 'c-name':
  90.                 self.c_name = arg[1]
  91.             elif arg[0] == 'gtype-id':
  92.                 self.typecode = arg[1]
  93.             elif arg[0] == 'fields':
  94.                 for parg in arg[1:]:
  95.                     self.fields.append((parg[0], parg[1]))
  96.             elif arg[0] == 'implements':
  97.                 self.implements.append(arg[1])
  98.     def merge(self, old):
  99.         # currently the .h parser doesn't try to work out what fields of
  100.         # an object structure should be public, so we just copy the list
  101.         # from the old version ...
  102.         self.fields = old.fields
  103.         self.implements = old.implements
  104.     def write_defs(self, fp=sys.stdout):
  105.         fp.write('(define-object ' + self.name + '\n')
  106.         if self.module:
  107.             fp.write('  (in-module "' + self.module + '")\n')
  108.         if self.parent != (None, None):
  109.             fp.write('  (parent "' + self.parent + '")\n')
  110.         for interface in self.implements:
  111.             fp.write('  (implements "' + interface + '")\n')
  112.         if self.c_name:
  113.             fp.write('  (c-name "' + self.c_name + '")\n')
  114.         if self.typecode:
  115.             fp.write('  (gtype-id "' + self.typecode + '")\n')
  116.         if self.fields:
  117.             fp.write('  (fields\n')
  118.             for (ftype, fname) in self.fields:
  119.                 fp.write('    \'("' + ftype + '" "' + fname + '")\n')
  120.             fp.write('  )\n')
  121.         fp.write(')\n\n')
  122.  
  123. class InterfaceDef(Definition):
  124.     def __init__(self, name, *args):
  125.         self.name = name
  126.         self.module = None
  127.         self.c_name = None
  128.         self.typecode = None
  129.         self.vtable = None
  130.         self.fields = []
  131.         self.interface_info = None
  132.         for arg in get_valid_scheme_definitions(args):
  133.             if arg[0] == 'in-module':
  134.                 self.module = arg[1]
  135.             elif arg[0] == 'docstring':
  136.                 self.docstring = make_docstring(arg[1:])
  137.             elif arg[0] == 'c-name':
  138.                 self.c_name = arg[1]
  139.             elif arg[0] == 'gtype-id':
  140.                 self.typecode = arg[1]
  141.             elif arg[0] == 'vtable':
  142.                 self.vtable = arg[1]
  143.         if self.vtable is None:
  144.             self.vtable = self.c_name + "Iface"
  145.     def write_defs(self, fp=sys.stdout):
  146.         fp.write('(define-interface ' + self.name + '\n')
  147.         if self.module:
  148.             fp.write('  (in-module "' + self.module + '")\n')
  149.         if self.c_name:
  150.             fp.write('  (c-name "' + self.c_name + '")\n')
  151.         if self.typecode:
  152.             fp.write('  (gtype-id "' + self.typecode + '")\n')
  153.         fp.write(')\n\n')
  154.  
  155. class EnumDef(Definition):
  156.     def __init__(self, name, *args):
  157.         self.deftype = 'enum'
  158.         self.name = name
  159.         self.in_module = None
  160.         self.c_name = None
  161.         self.typecode = None
  162.         self.values = []
  163.         for arg in get_valid_scheme_definitions(args):
  164.             if arg[0] == 'in-module':
  165.                 self.in_module = arg[1]
  166.             elif arg[0] == 'c-name':
  167.                 self.c_name = arg[1]
  168.             elif arg[0] == 'gtype-id':
  169.                 self.typecode = arg[1]
  170.             elif arg[0] == 'values':
  171.                 for varg in arg[1:]:
  172.                     self.values.append((varg[0], varg[1]))
  173.     def merge(self, old):
  174.         pass
  175.     def write_defs(self, fp=sys.stdout):
  176.         fp.write('(define-' + self.deftype + ' ' + self.name + '\n')
  177.         if self.in_module:
  178.             fp.write('  (in-module "' + self.in_module + '")\n')
  179.         fp.write('  (c-name "' + self.c_name + '")\n')
  180.         fp.write('  (gtype-id "' + self.typecode + '")\n')
  181.         if self.values:
  182.             fp.write('  (values\n')
  183.             for name, val in self.values:
  184.                 fp.write('    \'("' + name + '" "' + val + '")\n')
  185.             fp.write('  )\n')
  186.         fp.write(')\n\n')
  187.  
  188. class FlagsDef(EnumDef):
  189.     def __init__(self, *args):
  190.         apply(EnumDef.__init__, (self,) + args)
  191.         self.deftype = 'flags'
  192.  
  193. class BoxedDef(Definition):
  194.     def __init__(self, name, *args):
  195.         self.name = name
  196.         self.module = None
  197.         self.c_name = None
  198.         self.typecode = None
  199.         self.copy = None
  200.         self.release = None
  201.         self.fields = []
  202.         for arg in get_valid_scheme_definitions(args):
  203.             if arg[0] == 'in-module':
  204.                 self.module = arg[1]
  205.             elif arg[0] == 'c-name':
  206.                 self.c_name = arg[1]
  207.             elif arg[0] == 'gtype-id':
  208.                 self.typecode = arg[1]
  209.             elif arg[0] == 'copy-func':
  210.                 self.copy = arg[1]
  211.             elif arg[0] == 'release-func':
  212.                 self.release = arg[1]
  213.             elif arg[0] == 'fields':
  214.                 for parg in arg[1:]:
  215.                     self.fields.append((parg[0], parg[1]))
  216.     def merge(self, old):
  217.         # currently the .h parser doesn't try to work out what fields of
  218.         # an object structure should be public, so we just copy the list
  219.         # from the old version ...
  220.         self.fields = old.fields
  221.     def write_defs(self, fp=sys.stdout):
  222.         fp.write('(define-boxed ' + self.name + '\n')
  223.         if self.module:
  224.             fp.write('  (in-module "' + self.module + '")\n')
  225.         if self.c_name:
  226.             fp.write('  (c-name "' + self.c_name + '")\n')
  227.         if self.typecode:
  228.             fp.write('  (gtype-id "' + self.typecode + '")\n')
  229.         if self.copy:
  230.             fp.write('  (copy-func "' + self.copy + '")\n')
  231.         if self.release:
  232.             fp.write('  (release-func "' + self.release + '")\n')
  233.         if self.fields:
  234.             fp.write('  (fields\n')
  235.             for (ftype, fname) in self.fields:
  236.                 fp.write('    \'("' + ftype + '" "' + fname + '")\n')
  237.             fp.write('  )\n')
  238.         fp.write(')\n\n')
  239.  
  240. class PointerDef(Definition):
  241.     def __init__(self, name, *args):
  242.         self.name = name
  243.         self.module = None
  244.         self.c_name = None
  245.         self.typecode = None
  246.         self.fields = []
  247.         for arg in get_valid_scheme_definitions(args):
  248.             if arg[0] == 'in-module':
  249.                 self.module = arg[1]
  250.             elif arg[0] == 'c-name':
  251.                 self.c_name = arg[1]
  252.             elif arg[0] == 'gtype-id':
  253.                 self.typecode = arg[1]
  254.             elif arg[0] == 'fields':
  255.                 for parg in arg[1:]:
  256.                     self.fields.append((parg[0], parg[1]))
  257.     def merge(self, old):
  258.         # currently the .h parser doesn't try to work out what fields of
  259.         # an object structure should be public, so we just copy the list
  260.         # from the old version ...
  261.         self.fields = old.fields
  262.     def write_defs(self, fp=sys.stdout):
  263.         fp.write('(define-pointer ' + self.name + '\n')
  264.         if self.module:
  265.             fp.write('  (in-module "' + self.module + '")\n')
  266.         if self.c_name:
  267.             fp.write('  (c-name "' + self.c_name + '")\n')
  268.         if self.typecode:
  269.             fp.write('  (gtype-id "' + self.typecode + '")\n')
  270.         if self.fields:
  271.             fp.write('  (fields\n')
  272.             for (ftype, fname) in self.fields:
  273.                 fp.write('    \'("' + ftype + '" "' + fname + '")\n')
  274.             fp.write('  )\n')
  275.         fp.write(')\n\n')
  276.  
  277. class MethodDefBase(Definition):
  278.     def __init__(self, name, *args):
  279.         dump = 0
  280.         self.name = name
  281.         self.ret = None
  282.         self.caller_owns_return = None
  283.         self.unblock_threads = None
  284.         self.c_name = None
  285.         self.typecode = None
  286.         self.of_object = None
  287.         self.params = [] # of form (type, name, default, nullok)
  288.         self.varargs = 0
  289.         self.deprecated = None
  290.         for arg in get_valid_scheme_definitions(args):
  291.             if arg[0] == 'of-object':
  292.                 self.of_object = arg[1]
  293.             elif arg[0] == 'docstring':
  294.                 self.docstring = make_docstring(arg[1:])
  295.             elif arg[0] == 'c-name':
  296.                 self.c_name = arg[1]
  297.             elif arg[0] == 'gtype-id':
  298.                 self.typecode = arg[1]
  299.             elif arg[0] == 'return-type':
  300.                 self.ret = arg[1]
  301.             elif arg[0] == 'caller-owns-return':
  302.                 self.caller_owns_return = arg[1] in ('t', '#t')
  303.             elif arg[0] == 'unblock-threads':
  304.                 self.unblock_threads = arg[1] in ('t', '#t')
  305.             elif arg[0] == 'parameters':
  306.                 for parg in arg[1:]:
  307.                     ptype = parg[0]
  308.                     pname = parg[1]
  309.                     pdflt = None
  310.                     pnull = 0
  311.                     pdir = None
  312.                     for farg in parg[2:]:
  313.                         assert isinstance(farg, tuple)
  314.                         if farg[0] == 'default':
  315.                             pdflt = farg[1]
  316.                         elif farg[0] == 'null-ok':
  317.                             pnull = 1
  318.                         elif farg[0] == 'direction':
  319.                             pdir = farg[1]
  320.                     self.params.append(Parameter(ptype, pname, pdflt, pnull, pdir))
  321.             elif arg[0] == 'varargs':
  322.                 self.varargs = arg[1] in ('t', '#t')
  323.             elif arg[0] == 'deprecated':
  324.                 self.deprecated = arg[1]
  325.             else:
  326.                 sys.stderr.write("Warning: %s argument unsupported.\n"
  327.                                  % (arg[0]))
  328.                 dump = 1
  329.         if dump:
  330.             self.write_defs(sys.stderr)
  331.  
  332.         if self.caller_owns_return is None and self.ret is not None:
  333.             self.guess_return_value_ownership()
  334.  
  335.     def merge(self, old, parmerge):
  336.         self.caller_owns_return = old.caller_owns_return
  337.         self.varargs = old.varargs
  338.         # here we merge extra parameter flags accross to the new object.
  339.         if not parmerge:
  340.             self.params = copy.deepcopy(old.params)
  341.             return
  342.         for i in range(len(self.params)):
  343.             ptype, pname, pdflt, pnull = self.params[i]
  344.             for p2 in old.params:
  345.                 if p2[1] == pname:
  346.                     self.params[i] = (ptype, pname, p2[2], p2[3])
  347.                     break
  348.     def _write_defs(self, fp=sys.stdout):
  349.         if self.of_object != (None, None):
  350.             fp.write('  (of-object "' + self.of_object + '")\n')
  351.         if self.c_name:
  352.             fp.write('  (c-name "' + self.c_name + '")\n')
  353.         if self.typecode:
  354.             fp.write('  (gtype-id "' + self.typecode + '")\n')
  355.         if self.caller_owns_return:
  356.             fp.write('  (caller-owns-return #t)\n')
  357.         if self.unblock_threads:
  358.             fp.write('  (unblock_threads #t)\n')
  359.         if self.ret:
  360.             fp.write('  (return-type "' + self.ret + '")\n')
  361.         if self.deprecated:
  362.             fp.write('  (deprecated "' + self.deprecated + '")\n')
  363.         if self.params:
  364.             fp.write('  (parameters\n')
  365.             for ptype, pname, pdflt, pnull in self.params:
  366.                 fp.write('    \'("' + ptype + '" "' + pname +'"')
  367.                 if pdflt: fp.write(' (default "' + pdflt + '")')
  368.                 if pnull: fp.write(' (null-ok)')
  369.                 fp.write(')\n')
  370.             fp.write('  )\n')
  371.         if self.varargs:
  372.             fp.write('  (varargs #t)\n')
  373.         fp.write(')\n\n')
  374.  
  375.  
  376. class MethodDef(MethodDefBase):
  377.     def __init__(self, name, *args):
  378.         MethodDefBase.__init__(self, name, *args)
  379.         for item in ('c_name', 'of_object'):
  380.             if self.__dict__[item] == None:
  381.                 self.write_defs(sys.stderr)
  382.                 raise RuntimeError, "definition missing required %s" % (item,)
  383.  
  384.     def write_defs(self, fp=sys.stdout):
  385.         fp.write('(define-method ' + self.name + '\n')
  386.         self._write_defs(fp)
  387.  
  388. class VirtualDef(MethodDefBase):
  389.     def write_defs(self, fp=sys.stdout):
  390.         fp.write('(define-virtual ' + self.name + '\n')
  391.         self._write_defs(fp)
  392.  
  393. class FunctionDef(Definition):
  394.     def __init__(self, name, *args):
  395.         dump = 0
  396.         self.name = name
  397.         self.in_module = None
  398.         self.is_constructor_of = None
  399.         self.ret = None
  400.         self.caller_owns_return = None
  401.         self.unblock_threads = None
  402.         self.c_name = None
  403.         self.typecode = None
  404.         self.params = [] # of form (type, name, default, nullok)
  405.         self.varargs = 0
  406.         self.deprecated = None
  407.         for arg in get_valid_scheme_definitions(args):
  408.             if arg[0] == 'in-module':
  409.                 self.in_module = arg[1]
  410.             elif arg[0] == 'docstring':
  411.                 self.docstring = make_docstring(arg[1:])
  412.             elif arg[0] == 'is-constructor-of':
  413.                 self.is_constructor_of = arg[1]
  414.             elif arg[0] == 'c-name':
  415.                 self.c_name = arg[1]
  416.             elif arg[0] == 'gtype-id':
  417.                 self.typecode = arg[1]
  418.             elif arg[0] == 'return-type':
  419.                 self.ret = arg[1]
  420.             elif arg[0] == 'caller-owns-return':
  421.                 self.caller_owns_return = arg[1] in ('t', '#t')
  422.             elif arg[0] == 'unblock-threads':
  423.                 self.unblock_threads = arg[1] in ('t', '#t')
  424.             elif arg[0] == 'parameters':
  425.                 for parg in arg[1:]:
  426.                     ptype = parg[0]
  427.                     pname = parg[1]
  428.                     pdflt = None
  429.                     pnull = 0
  430.                     for farg in parg[2:]:
  431.                         if farg[0] == 'default':
  432.                             pdflt = farg[1]
  433.                         elif farg[0] == 'null-ok':
  434.                             pnull = 1
  435.                     self.params.append(Parameter(ptype, pname, pdflt, pnull))
  436.             elif arg[0] == 'properties':
  437.                 if self.is_constructor_of is None:
  438.                     print >> sys.stderr, "Warning: (properties ...) "\
  439.                           "is only valid for constructors"
  440.                 for prop in arg[1:]:
  441.                     pname = prop[0]
  442.                     optional = False
  443.                     argname = pname
  444.                     for farg in prop[1:]:
  445.                         if farg[0] == 'optional':
  446.                             optional = True
  447.                         elif farg[0] == 'argname':
  448.                             argname = farg[1]
  449.                     self.params.append(Property(pname, optional, argname))
  450.             elif arg[0] == 'varargs':
  451.                 self.varargs = arg[1] in ('t', '#t')
  452.             elif arg[0] == 'deprecated':
  453.                 self.deprecated = arg[1]
  454.             else:
  455.                 sys.stderr.write("Warning: %s argument unsupported\n"
  456.                                  % (arg[0],))
  457.                 dump = 1
  458.         if dump:
  459.             self.write_defs(sys.stderr)
  460.  
  461.         if self.caller_owns_return is None and self.ret is not None:
  462.             self.guess_return_value_ownership()
  463.         for item in ('c_name',):
  464.             if self.__dict__[item] == None:
  465.                 self.write_defs(sys.stderr)
  466.                 raise RuntimeError, "definition missing required %s" % (item,)
  467.  
  468.     _method_write_defs = MethodDef.__dict__['write_defs']
  469.  
  470.     def merge(self, old, parmerge):
  471.         self.caller_owns_return = old.caller_owns_return
  472.         self.varargs = old.varargs
  473.         if not parmerge:
  474.             self.params = copy.deepcopy(old.params)
  475.             return
  476.         # here we merge extra parameter flags accross to the new object.
  477.         def merge_param(param):
  478.             for old_param in old.params:
  479.                 if old_param.pname == param.pname:
  480.                     if isinstance(old_param, Property):
  481.                         # h2def never scans Property's, therefore if
  482.                         # we have one it was manually written, so we
  483.                         # keep it.
  484.                         return copy.deepcopy(old_param)
  485.                     else:
  486.                         param.merge(old_param)
  487.                         return param
  488.             raise RuntimeError, "could not find %s in old_parameters %r" % (
  489.                 param.pname, [p.pname for p in old.params])
  490.         try:
  491.             self.params = map(merge_param, self.params)
  492.         except RuntimeError:
  493.             # parameter names changed and we can't find a match; it's
  494.             # safer to keep the old parameter list untouched.
  495.             self.params = copy.deepcopy(old.params)
  496.  
  497.         if not self.is_constructor_of:
  498.             try:
  499.                 self.is_constructor_of = old.is_constructor_of
  500.             except AttributeError:
  501.                 pass
  502.         if isinstance(old, MethodDef):
  503.             self.name = old.name
  504.             # transmogrify from function into method ...
  505.             self.write_defs = self._method_write_defs
  506.             self.of_object = old.of_object
  507.             del self.params[0]
  508.     def write_defs(self, fp=sys.stdout):
  509.         fp.write('(define-function ' + self.name + '\n')
  510.         if self.in_module:
  511.             fp.write('  (in-module "' + self.in_module + '")\n')
  512.         if self.is_constructor_of:
  513.             fp.write('  (is-constructor-of "' + self.is_constructor_of +'")\n')
  514.         if self.c_name:
  515.             fp.write('  (c-name "' + self.c_name + '")\n')
  516.         if self.typecode:
  517.             fp.write('  (gtype-id "' + self.typecode + '")\n')
  518.         if self.caller_owns_return:
  519.             fp.write('  (caller-owns-return #t)\n')
  520.         if self.unblock_threads:
  521.             fp.write('  (unblock-threads #t)\n')
  522.         if self.ret:
  523.             fp.write('  (return-type "' + self.ret + '")\n')
  524.         if self.deprecated:
  525.             fp.write('  (deprecated "' + self.deprecated + '")\n')
  526.         if self.params:
  527.             if isinstance(self.params[0], Parameter):
  528.                 fp.write('  (parameters\n')
  529.                 for ptype, pname, pdflt, pnull in self.params:
  530.                     fp.write('    \'("' + ptype + '" "' + pname +'"')
  531.                     if pdflt: fp.write(' (default "' + pdflt + '")')
  532.                     if pnull: fp.write(' (null-ok)')
  533.                     fp.write(')\n')
  534.                 fp.write('  )\n')
  535.             elif isinstance(self.params[0], Property):
  536.                 fp.write('  (properties\n')
  537.                 for prop in self.params:
  538.                     fp.write('    \'("' + prop.pname +'"')
  539.                     if prop.optional: fp.write(' (optional)')
  540.                     fp.write(')\n')
  541.                 fp.write('  )\n')
  542.             else:
  543.                 assert False, "strange parameter list %r" % self.params[0]
  544.         if self.varargs:
  545.             fp.write('  (varargs #t)\n')
  546.  
  547.         fp.write(')\n\n')
  548.