[seed] Add dbus2js.py helper script (from hp) for generating JavaScript interface descriptions from introsp
- From: Robert Carr <racarr src gnome org>
- To: svn-commits-list gnome org
- Subject: [seed] Add dbus2js.py helper script (from hp) for generating JavaScript interface descriptions from introsp
- Date: Mon, 11 May 2009 21:21:26 -0400 (EDT)
commit 8d93fc2dc3b546e15b4a7254bb75dd560e452abb
Author: Robert Carr <racarr svn gnome org>
Date: Mon May 11 21:21:18 2009 -0400
Add dbus2js.py helper script (from hp) for generating JavaScript interface descriptions from introspection XML
---
modules/dbus/Makefile.am | 2 +
modules/dbus/dbus2js.py | 218 ++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 220 insertions(+), 0 deletions(-)
diff --git a/modules/dbus/Makefile.am b/modules/dbus/Makefile.am
index 5390ab9..ca8e50a 100644
--- a/modules/dbus/Makefile.am
+++ b/modules/dbus/Makefile.am
@@ -1,5 +1,7 @@
if BUILD_DBUS_MODULE
+EXTRA_DIST = dbus2js.py
+
moduledir = $(datadir)/seed
module_DATA = dbus.js lang.js
diff --git a/modules/dbus/dbus2js.py b/modules/dbus/dbus2js.py
new file mode 100755
index 0000000..e8044cb
--- /dev/null
+++ b/modules/dbus/dbus2js.py
@@ -0,0 +1,218 @@
+#! /usr/bin/python
+# Copyright 2009 litl, LLC. All Rights Reserved.
+
+## this file outputs sortof-indented JavaScript,
+## it's semi-readable for use when testing, but
+## when checking in real output, run M-x indent-region
+## in js2-mode
+
+import sys
+import xml.dom.minidom
+import textwrap
+import re
+
+out = sys.stdout
+
+commentWrapper = textwrap.TextWrapper()
+commentWrapper.initial_indent = '// '
+commentWrapper.subsequent_indent = '// '
+
+def getText(nodelist):
+ rc = ""
+ for node in nodelist:
+ if node.nodeType == node.TEXT_NODE:
+ rc = rc + node.data
+ return rc
+
+def getDocstring(node):
+ docstrings = node.getElementsByTagName('tp:docstring')
+ docstring = ''
+ if len(docstrings) > 0 and docstrings[0].parentNode == node:
+ docstring = getText(docstrings[0].childNodes).strip()
+ return re.sub('\s+', ' ', docstring)
+
+def methodAsString(method):
+ dbusName = method.getAttribute("name")
+ args = method.getElementsByTagName("arg")
+ methodDocstring = getDocstring(method)
+ inArgs = ''
+ inArgsComments = ''
+ outArgs = ''
+ outArgsComments = ''
+ for arg in args:
+ argName = arg.getAttribute('name')
+ docstring = getDocstring(arg)
+ tpType = arg.getAttribute('tp:type')
+ if tpType and len(tpType) > 0:
+ docstring = "(" + tpType + ") " + docstring
+ comment = commentWrapper.fill(' ' + argName + ': ' + docstring) + '\n'
+ direction = arg.getAttribute('direction')
+ type = arg.getAttribute('type')
+ if direction == 'in' or (method.tagName == 'signal' and not direction):
+ inArgs += type
+ inArgsComments += comment
+ elif direction == 'out':
+ outArgs += type
+ outArgsComments += comment
+ else:
+ raise Exception("unknown direction " + direction)
+
+ errorComments = ''
+ possibleErrors = method.getElementsByTagName("tp:possible-errors")
+ if possibleErrors:
+ for error in possibleErrors[0].getElementsByTagName("tp:error"):
+ errorName = error.getAttribute("name")
+ docstring = getDocstring(error)
+ errorComments += commentWrapper.fill(' ' + errorName + ' ' + docstring) + '\n'
+
+ if "'" in methodDocstring:
+ # js2-mode gets pissy about unmatched quotes in comments,
+ # it's a bug
+ methodDocstring = methodDocstring.replace("'", "")
+ docComment = commentWrapper.fill(dbusName + ': ' + methodDocstring) + '\n'
+
+ if len(inArgsComments) > 0:
+ inArgsComments = "// In Args:\n" + inArgsComments
+ if len(outArgsComments) > 0:
+ outArgsComments = "// Out Args:\n" + outArgsComments
+ if len(errorComments) > 0:
+ errorComments = "// Errors:\n" + errorComments
+
+ inSig = "inSignature: '%s'" % inArgs
+ outSig = "outSignature: '%s'" % outArgs
+
+ asString = "\n%s%s%s%s\n{ name: '%s', %s, %s }" % \
+ (docComment, inArgsComments, outArgsComments, errorComments,
+ dbusName, inSig, outSig)
+ return asString
+
+def methodsOrSignalsAsString(methodsOrSignals):
+ if len(methodsOrSignals) == 0:
+ return "[]"
+
+ asString = '[\n'
+ for method in methodsOrSignals:
+ asString = asString + ' ' + methodAsString(method) + ',\n'
+
+ asString = asString[:-2] + '\n ]'
+
+ return asString
+
+def propertiesAsString(properties):
+ if len(properties) == 0:
+ return "[]"
+
+ asString = '[\n'
+ for prop in properties:
+ name = prop.getAttribute("name")
+ type = prop.getAttribute("type")
+ tpType = prop.getAttribute("tp:type")
+ access = prop.getAttribute("access")
+ docComment = name + ': '
+ if tpType and len(tpType) > 0:
+ docComment += '(' + tpType + ') ';
+ docComment = '\n' + commentWrapper.fill(docComment + getDocstring(prop))
+ asString += "%s\n\n { name: '%s', signature: '%s', access: '%s' },\n" % \
+ (docComment, name, type, access);
+
+ asString = asString[:-2] + '\n ]'
+
+ return asString
+
+def outputEnums(enums, dbusIfaceName):
+ for e in enums:
+ eName = e.getAttribute('name')
+ out.write('\n// ' + eName + ' in ' + dbusIfaceName + '\n')
+ values = []
+ for val in e.getElementsByTagName('tp:enumvalue'):
+ valSuffix = val.getAttribute('suffix')
+ valValue = val.getAttribute('value')
+ valDocstring = getDocstring(val)
+ values.append((valSuffix, valValue, valDocstring))
+ for val in values:
+ out.write(commentWrapper.fill(' ' + val[0] + ': ' + val[2]) + '\n')
+ out.write('\n')
+ for val in values:
+ out.write('const %s_%s = %s;\n' % (eName, val[0], val[1]))
+ out.write('\n')
+
+def outputFlags(flags, dbusIfaceName):
+ for e in flags:
+ eName = e.getAttribute('name')
+ out.write('\n// ' + eName + ' in ' + dbusIfaceName + '\n')
+ values = []
+ for val in e.getElementsByTagName('tp:flag'):
+ valSuffix = val.getAttribute('suffix')
+ valValue = val.getAttribute('value')
+ valDocstring = getDocstring(val)
+ values.append((valSuffix, valValue, valDocstring))
+ for val in values:
+ out.write(commentWrapper.fill(' ' + val[0] + ': ' + val[2]) + '\n')
+ out.write('\n')
+ for val in values:
+ out.write('const %s_%s = %s;\n' % (eName, val[0], val[1]))
+ out.write('\n')
+
+def outputInterface(iface):
+ dbusIfaceName = iface.getAttribute("name")
+ jsIfaceName = dbusIfaceName.replace('org.freedesktop.', '').replace('.','')
+
+ methods = methodsOrSignalsAsString(iface.getElementsByTagName('method'));
+ signals = methodsOrSignalsAsString(iface.getElementsByTagName('signal'));
+
+ properties = propertiesAsString(iface.getElementsByTagName('property'));
+
+ out.write("""
+var %s = {
+ name: '%s',
+ methods: %s,
+ signals: %s,
+ properties: %s
+};
+""" % (jsIfaceName, dbusIfaceName, methods, signals, properties));
+
+ enums = iface.getElementsByTagName('tp:enum')
+ outputEnums(enums, dbusIfaceName);
+
+ flags = iface.getElementsByTagName('tp:flags')
+ outputFlags(flags, dbusIfaceName);
+
+def outputNode(node):
+ for child in node.childNodes:
+ if child.nodeType != child.ELEMENT_NODE:
+ continue
+ if child.tagName == 'interface':
+ outputInterface(child)
+ else:
+ raise Exception("unknown tag in <node>: " + child.tagName)
+
+out.write("// AUTOMATICALLY GENERATED INTERFACE FILE\n")
+out.write("// Do not edit by hand.\n\n")
+
+for filename in sys.argv[1:]:
+ if filename.endswith('nm-manager-client.xml'):
+ ## nm-manager-client.xml is nm-manager.xml
+ ## with some deprecated stuff removed, to
+ ## generate dbus-glib client bindings. The
+ ## detailed docs and stuff are in nm-manager.xml though.
+ continue
+
+ dom = xml.dom.minidom.parse(filename)
+
+ for child in dom.childNodes:
+ if child.nodeType != child.ELEMENT_NODE:
+ continue
+ if child.tagName == 'node':
+ outputNode(child)
+ elif child.tagName == 'tp:generic-types':
+ enums = child.getElementsByTagName('tp:enum')
+ outputEnums(enums, 'generic-types');
+ flags = child.getElementsByTagName('tp:flags')
+ outputFlags(flags, 'generic-types');
+ elif child.tagName in ['tp:spec', 'tp:title',
+ 'tp:version', 'tp:copyright',
+ 'tp:license', 'xi:include',
+ 'tp:errors' ]:
+ continue
+ else:
+ raise Exception("unknown tag at root: " + child.tagName)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]