pybank r56 - in trunk: . contrib



Author: johan
Date: Wed Aug 20 18:33:42 2008
New Revision: 56
URL: http://svn.gnome.org/viewvc/pybank?rev=56&view=rev

Log:
Move converts to contrib

Added:
   trunk/contrib/
   trunk/contrib/defs2gidl.py
      - copied unchanged from r55, /trunk/defs2gidl.py
   trunk/contrib/defs2gir.py
Removed:
   trunk/defs2gidl.py

Added: trunk/contrib/defs2gir.py
==============================================================================
--- (empty file)
+++ trunk/contrib/defs2gir.py	Wed Aug 20 18:33:42 2008
@@ -0,0 +1,362 @@
+import sys
+import optparse
+import os
+from xml.etree.ElementTree import Element, ElementTree, SubElement
+
+from codegen.definitions import Parameter, Property, MethodDef
+from codegen.defsparser import DefsParser
+
+def sort_parent_children(objects):
+    objects = list(objects)
+    modified = True
+    while modified:
+        modified = False
+        parent_index = None
+        child_index = None
+        for i, obj in enumerate(objects):
+            if obj.parent == 'GObject':
+                continue
+            if obj.parent not in [info.c_name for info in objects[:i]]:
+                for j, info in enumerate(objects[i+1:]):
+                    if info.c_name == obj.parent:
+                        parent_index = i + 1 + j
+                        child_index = i
+                        break
+                else:
+                    continue
+                break
+        if child_index is not None and parent_index is not None:
+            if child_index != parent_index:
+                objects.insert(child_index, objects.pop(parent_index))
+                modified = True
+    return objects
+
+def macro2symbol(macro):
+    return macro.replace('_TYPE_', '_', 1).lower() + '_get_type'
+
+def indent(elem, level=0):
+    i = "\n" + level*"  "
+    if len(elem):
+        if not elem.text or not elem.text.strip():
+            elem.text = i + "  "
+        for e in elem:
+            indent(e, level+1)
+            if not e.tail or not e.tail.strip():
+                e.tail = i + "  "
+        if not e.tail or not e.tail.strip():
+            e.tail = i
+    else:
+        if level and (not elem.tail or not elem.tail.strip()):
+            elem.tail = i
+
+class UnhandledArgumentType(Exception):
+    pass
+
+
+class DefsImporter(object):
+    def __init__(self, repo, name, library):
+        self._modulename = name
+        self._library = library
+        self._objects = {}
+        self._enums = []
+        self._structs = []
+        self._boxes = []
+        self._interfaces = []
+        self._functions = []
+        self._symbols = {
+            "none": "void",
+            'char': 'gchar',
+            'char*': 'gchar*',
+            'char**': 'gchar**',
+
+            # GLib
+            'GCallback': 'GLib.Callback',
+            'GCompareFunc': 'GLib.CompareFunc',
+            'GDestroyNotify': 'GLib.DestroyNotify',
+            'GList*': 'GLib.List<void*>',
+            'GNode*': 'GLib.Node*',
+            'GOptionGroup*': 'GLib.OptionGroup*',
+            'GQuark': 'GLib.Quark',
+            'GPtrArray*': 'GLib.PtrArray*',
+            'GSList*': 'GLib.SList<void*>',
+            'GScanner*': 'GLib.Scanner*',
+            'GString*': 'GLib.String*',
+            'GTimeVal*': 'GLib.TimeVal*',
+
+            # GObject
+            'GClosure*': 'GLib.Closure*',
+            'GBoxed':  'GLib.Boxed',
+            'GObject': 'GLib.Object',
+            'GObject*': 'GLib.Object*',
+            'GObjectClass*': 'GLib.ObjectClass*',
+            'GParamSpec*': 'GLib.ParamSpec*',
+            'GSignalEmissionHook': 'GLib.SignalEmissionHook',
+            'GSignalMatchType': 'GLib.SignalMatchType',
+            'GTypeDebugFlags': 'GLib.TypeDebugFlags',
+            'GType': 'GLib.GType',
+            'GValue*': 'GLib.Value',
+
+            # Cairo
+            'cairo_t*': 'Cairo.Context*',
+            }
+
+    def parseDefs(self, filename):
+        parser = DefsParser(filename, {})
+        parser.startParsing()
+        self._register_all(parser)
+
+    def registerDefs(self, filename):
+        parser = DefsParser(filename, {})
+        parser.startParsing()
+        self._register_types(parser)
+
+    def _get_objects(self):
+        objects = self._objects.values()
+        return sort_parent_children(objects)
+
+    def _add_symbol(self, definition, value=None):
+        if value is None:
+            value = definition.name
+        if definition.module != self._modulename:
+            value = definition.module + '.' + value
+        self._symbols[definition.c_name] = value
+        self._symbols[definition.c_name + '*'] = value + '*'
+
+    def _register_types(self, parser):
+        definitions = (parser.objects +
+                       parser.boxes +
+                       parser.interfaces +
+                       parser.enums)
+        for definition in definitions:
+            self._add_symbol(definition)
+        for struct in parser.structs:
+            self._add_symbol(struct, struct.c_name)
+
+    def _register_all(self, parser):
+        self._register_types(parser)
+        for obj in parser.objects:
+            obj.methods = []
+            obj.constructor = None
+            self._objects[obj.c_name] = obj
+        for boxed in parser.boxes:
+            boxed.methods = []
+            boxed.constructor = None
+            self._boxes.append(boxed)
+            boxed.parent = "GBoxed"
+            self._objects[boxed.c_name] = boxed
+        for struct in parser.structs:
+            struct.methods = []
+            struct.constructor = None
+            self._structs.append(struct)
+        for func in parser.functions:
+            if isinstance(func, MethodDef):
+                obj = self._objects.get(func.of_object)
+                if obj is not None:
+                    obj.methods.append(func)
+            elif func.is_constructor_of:
+                obj = self._objects.get(func.is_constructor_of)
+                if not obj:
+                    print 'Warning: No object %s' % (func.is_constructor_of,)
+                else:
+                    obj.constructor = func
+            else:
+                self._functions.append(func)
+        for iface in parser.interfaces:
+            iface.methods = []
+            self._interfaces.append(iface)
+        for enum in parser.enums:
+            self._enums.append(enum)
+
+        for definition in parser.boxes:
+            del self._objects[definition.c_name]
+
+    def write(self, output):
+        namespace = Element("namespace")
+        namespace.set("version", "0.1")
+        namespace.set("xmlns", "http://www.gtk.org/introspection/0.1";)
+        namespace.set("xmlns:c", "http://www.gtk.org/introspection/lang/c/0.1";)
+        if self._library:
+            namespace.set("c:dynamic-library", self._library)
+        namespace.set("name", self._modulename)
+
+        for enum_def in self._enums:
+            self._write_enum(namespace, enum_def)
+        for struct_def in self._structs:
+            self._write_struct(namespace, struct_def)
+        for iface_def in self._interfaces:
+            self._write_interface(namespace, iface_def)
+        for object_def in self._get_objects():
+            self._write_object(namespace, object_def)
+        for boxed_def in self._boxes:
+            self._write_boxed(namespace, boxed_def)
+        for func_def in self._functions:
+            self._write_function(namespace, func_def)
+
+        tree = ElementTree(namespace)
+        tree.write(output)
+
+    def _write_enum(self, namespace, enum_def):
+        if enum_def.deftype == "flags":
+            tag_name = "bitfield"
+        else:
+            tag_name = "enumeration"
+        enum = SubElement(namespace, tag_name)
+        enum.set("name", enum_def.name)
+        enum.set("c:type-name", enum_def.c_name)
+        enum.set("c:get-type-func", macro2symbol(enum_def.typecode))
+
+        if not enum_def.values:
+            return
+
+        members = SubElement(enum, "members")
+
+        # FIXME: Invalid values for flags, need to rescan headers
+        #        or compile
+        i = 0
+        for nick, name in enum_def.values:
+            member = SubElement(members, "member")
+            member.set("name", nick.upper().replace('-', '_'))
+            member.set("value", str(i))
+            i += 1
+
+    def _write_object(self, namespace, object_def):
+        modlen = len(self._modulename)
+        object = SubElement(namespace, "class")
+        object.set("name", object_def.c_name[modlen:])
+        object.set("parent", self._convert_param_type(object_def.parent))
+        object.set("c:get-type-func", macro2symbol(object_def.typecode))
+        object.set("c:type-name", object_def.c_name)
+
+        if object_def.constructor:
+            constructors = SubElement(object, "constructors")
+            self._write_function(constructors,
+                                 object_def.constructor,
+                                 isconstructor=True)
+
+        if object_def.methods:
+            methods = SubElement(object, "methods")
+            for method_def in object_def.methods:
+                self._write_function(methods, method_def,
+                                     object_name=object.attrib['name'])
+
+    def _write_interface(self, namespace, iface_def):
+        modlen = len(self._modulename)
+        object = SubElement(namespace, "interface")
+        object.set("name", iface_def.c_name[modlen:])
+        object.set("get-type", macro2symbol(iface_def.typecode))
+        object.set("type-name", iface_def.c_name)
+
+        for method_def in iface_def.methods:
+            self._write_function(iface, method_def)
+
+    def _write_function(self, object, method_def, isconstructor=False,
+                        object_name=None):
+        if isinstance(method_def, MethodDef):
+            tagname = "method"
+        elif isconstructor:
+            tagname = "constructor"
+        else:
+            tagname = "function"
+
+        if tagname == "function":
+            if (method_def.name.endswith('_get_type') and
+                method_def.ret in ["GType", "GtkType"]):
+                return
+
+        method = SubElement(object, tagname)
+        method.set("name", method_def.name)
+        method.set("c:identifier", method_def.c_name)
+
+        if not isconstructor:
+            return_type = SubElement(method, "return-type")
+            try:
+                return_type.set("type", self._convert_param_type(method_def.ret))
+            except UnhandledArgumentType, e:
+                object.remove(method)
+                return
+
+        parameters = SubElement(method, "parameters")
+        for param_def in method_def.params:
+            if isinstance(param_def, Parameter):
+                try:
+                    self._write_param(parameters, param_def)
+                except UnhandledArgumentType, e:
+                    object.remove(method)
+                    return
+            elif isinstance(param_def, Property):
+                print 'properties unsupported for method %s' % (
+                    method_def.c_name,)
+                object.remove(method)
+                return
+
+    def _write_param(self, parameters, param_def):
+        parameter = SubElement(parameters, "parameter")
+        parameter.set("name", param_def.pname)
+        parameter.set("direction", param_def.pdir or 'in')
+
+        ptype = SubElement(parameter, "type")
+        ptype.set("name", self._convert_param_type(param_def.ptype))
+
+    def _write_struct(self, namespace, struct_def):
+        struct = SubElement(namespace, "struct")
+        struct.set("name", struct_def.c_name)
+
+    def _write_boxed(self, namespace, boxed_def):
+        modlen = len(self._modulename)
+        object = SubElement(namespace, "boxed")
+        object.set("name", boxed_def.c_name[modlen:])
+        object.set("get-type", macro2symbol(boxed_def.typecode))
+        object.set("type-name", boxed_def.c_name)
+
+        for method_def in boxed_def.methods:
+            try:
+                self._write_function(object, method_def)
+            except UnhandledArgumentType, e:
+                namespace.remove(object)
+                return
+
+    def _convert_param_type(self, ptype):
+        if ptype is None:
+            return 'void'
+        if ptype.startswith("const-"):
+            ptype = ptype[6:]
+
+        value = self._symbols.get(ptype)
+        if value is not None:
+            return value
+
+        if ptype in ['va_list', 'gchar', 'guchar', 'guchar*', 'gunichar']:
+            raise UnhandledArgumentType
+
+        if '**' in ptype:
+            if not 'gchar' in ptype:
+                raise UnhandledArgumentType
+
+        return ptype
+
+
+def main(args):
+    parser = optparse.OptionParser()
+    parser.add_option("-a", "--add-types", dest="extra_types",
+                      action="append")
+    parser.add_option("-o", "--output", dest="output",
+                      action="store", default=sys.stdout)
+    parser.add_option("-l", "--library", dest="library",
+                      action="store")
+    options, args = parser.parse_args(args)
+
+    modulename = args[1]
+    repo = modulename + '.repo'
+    if os.path.exists(repo):
+        os.unlink(repo)
+
+    imp = DefsImporter(repo, modulename, options.library)
+    if options.extra_types:
+        for filename in options.extra_types:
+            imp.registerDefs(filename)
+    for filename in args[2:]:
+        imp.parseDefs(filename)
+    imp.write(options.output)
+
+if __name__ == "__main__":
+    sys.exit(main(sys.argv))



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]