pybank r56 - in trunk: . contrib
- From: johan svn gnome org
- To: svn-commits-list gnome org
- Subject: pybank r56 - in trunk: . contrib
- Date: Wed, 20 Aug 2008 18:33:43 +0000 (UTC)
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]