Changeset View
Changeset View
Standalone View
Standalone View
tools/qt-svc-gen.py
Show All 15 Lines | |||||
16 | # You should have received a copy of the GNU Lesser General Public | 16 | # You should have received a copy of the GNU Lesser General Public | ||
17 | # License along with this library; if not, write to the Free Software | 17 | # License along with this library; if not, write to the Free Software | ||
18 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | 18 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
19 | 19 | | |||
20 | from sys import argv | 20 | from sys import argv | ||
21 | import xml.dom.minidom | 21 | import xml.dom.minidom | ||
22 | import codecs | 22 | import codecs | ||
23 | from getopt import gnu_getopt | 23 | from getopt import gnu_getopt | ||
24 | import functools | ||||
24 | 25 | | |||
25 | from libtpcodegen import NS_TP, get_descendant_text, get_by_path | 26 | from libtpcodegen import NS_TP, get_descendant_text, get_by_path | ||
26 | from libqtcodegen import binding_from_usage, extract_arg_or_member_info, format_docstring, gather_externals, gather_custom_lists, get_headerfile_cmd, get_qt_name, qt_identifier_escape, RefRegistry | 27 | from libqtcodegen import binding_from_usage, extract_arg_or_member_info, format_docstring, gather_externals, gather_custom_lists, get_headerfile_cmd, get_qt_name, qt_identifier_escape, RefRegistry | ||
27 | 28 | | |||
28 | # TODO generate docstrings | 29 | # TODO generate docstrings | ||
29 | 30 | | |||
30 | def to_lower_camel_case(s): | 31 | def to_lower_camel_case(s): | ||
31 | if len(s) <= 1: | 32 | if len(s) <= 1: | ||
Show All 24 Lines | 51 | try: | |||
56 | self.realinclude = opts.get('--realinclude', None) | 57 | self.realinclude = opts.get('--realinclude', None) | ||
57 | self.mocinclude = opts.get('--mocinclude', None) | 58 | self.mocinclude = opts.get('--mocinclude', None) | ||
58 | self.prettyinclude = opts.get('--prettyinclude') | 59 | self.prettyinclude = opts.get('--prettyinclude') | ||
59 | self.extraincludes = opts.get('--extraincludes', None) | 60 | self.extraincludes = opts.get('--extraincludes', None) | ||
60 | self.must_define = opts.get('--must-define', None) | 61 | self.must_define = opts.get('--must-define', None) | ||
61 | self.visibility = opts.get('--visibility', '') | 62 | self.visibility = opts.get('--visibility', '') | ||
62 | ifacedom = xml.dom.minidom.parse(opts['--ifacexml']) | 63 | ifacedom = xml.dom.minidom.parse(opts['--ifacexml']) | ||
63 | specdom = xml.dom.minidom.parse(opts['--specxml']) | 64 | specdom = xml.dom.minidom.parse(opts['--specxml']) | ||
64 | except KeyError, k: | 65 | except KeyError as k: | ||
65 | assert False, 'Missing required parameter %s' % k.args[0] | 66 | assert False, 'Missing required parameter %s' % k.args[0] | ||
66 | 67 | | |||
67 | if not self.realinclude: | 68 | if not self.realinclude: | ||
68 | self.realinclude = self.headerfile | 69 | self.realinclude = self.headerfile | ||
69 | 70 | | |||
70 | self.hs = [] | 71 | self.hs = [] | ||
71 | self.bs = [] | 72 | self.bs = [] | ||
72 | self.ifacenodes = ifacedom.getElementsByTagName('node') | 73 | self.ifacenodes = ifacedom.getElementsByTagName('node') | ||
▲ Show 20 Lines • Show All 57 Lines • ▼ Show 20 Line(s) | 128 | """) | |||
130 | for ns in self.namespace.split('::'): | 131 | for ns in self.namespace.split('::'): | ||
131 | self.hb("""\ | 132 | self.hb("""\ | ||
132 | namespace %s | 133 | namespace %s | ||
133 | { | 134 | { | ||
134 | """ % ns) | 135 | """ % ns) | ||
135 | 136 | | |||
136 | # Output interface proxies | 137 | # Output interface proxies | ||
137 | def ifacenodecmp(x, y): | 138 | def ifacenodecmp(x, y): | ||
138 | xname, yname = [self.namespace + '::' + node.getAttribute('name').replace('/', '').replace('_', '') + 'Adaptor' for node in x, y] | 139 | xname, yname = [self.namespace + '::' + node.getAttribute('name').replace('/', '').replace('_', '') + 'Adaptor' for node in (x, y)] | ||
139 | 140 | | |||
140 | return cmp(xname, yname) | 141 | return (xname > yname) - (xname < yname) | ||
141 | 142 | | |||
142 | self.ifacenodes.sort(cmp=ifacenodecmp) | 143 | self.ifacenodes.sort(key=functools.cmp_to_key(ifacenodecmp)) | ||
143 | for ifacenode in self.ifacenodes: | 144 | for ifacenode in self.ifacenodes: | ||
144 | self.do_ifacenode(ifacenode) | 145 | self.do_ifacenode(ifacenode) | ||
145 | 146 | | |||
146 | # End namespace | 147 | # End namespace | ||
147 | self.hb(''.join(['\n}' for ns in self.namespace.split('::')])) | 148 | self.hb(''.join(['\n}' for ns in self.namespace.split('::')])) | ||
148 | 149 | | |||
149 | # Write output to files | 150 | # Write output to files | ||
150 | (codecs.getwriter('utf-8')(open(self.headerfile, 'w'))).write(''.join(self.hs)) | 151 | (codecs.getwriter('utf-8')(open(self.headerfile, 'wb'))).write(''.join(self.hs)) | ||
151 | (codecs.getwriter('utf-8')(open(self.implfile, 'w'))).write(''.join(self.bs)) | 152 | (codecs.getwriter('utf-8')(open(self.implfile, 'wb'))).write(''.join(self.bs)) | ||
152 | 153 | | |||
153 | def do_ifacenode(self, ifacenode): | 154 | def do_ifacenode(self, ifacenode): | ||
154 | # Extract info | 155 | # Extract info | ||
155 | name = ifacenode.getAttribute('name').replace('/', '').replace('_', '') + 'Adaptor' | 156 | name = ifacenode.getAttribute('name').replace('/', '').replace('_', '') + 'Adaptor' | ||
156 | iface, = get_by_path(ifacenode, 'interface') | 157 | iface, = get_by_path(ifacenode, 'interface') | ||
157 | dbusname = iface.getAttribute('name') | 158 | dbusname = iface.getAttribute('name') | ||
158 | props = get_by_path(iface, 'property') | 159 | props = get_by_path(iface, 'property') | ||
159 | methods = get_by_path(iface, 'method') | 160 | methods = get_by_path(iface, 'method') | ||
▲ Show 20 Lines • Show All 138 Lines • ▼ Show 20 Line(s) | |||||
298 | """ % {'name': name}) | 299 | """ % {'name': name}) | ||
299 | else: | 300 | else: | ||
300 | self.h("""\ | 301 | self.h("""\ | ||
301 | " <method name=\\"%(name)s\\">\\n" | 302 | " <method name=\\"%(name)s\\">\\n" | ||
302 | """ % {'name': name}) | 303 | """ % {'name': name}) | ||
303 | 304 | | |||
304 | outindex = 0 | 305 | outindex = 0 | ||
305 | inindex = 0 | 306 | inindex = 0 | ||
306 | for i in xrange(len(argnames)): | 307 | for i in range(len(argnames)): | ||
307 | assert argnames[i] != None, 'Name missing from argument at index %d for signal %s' % (i, name) | 308 | assert argnames[i] != None, 'Name missing from argument at index %d for signal %s' % (i, name) | ||
308 | 309 | | |||
309 | argbinding = argbindings[i] | 310 | argbinding = argbindings[i] | ||
310 | argname = argnames[i] | 311 | argname = argnames[i] | ||
311 | argsig = args[i].getAttribute('type') | 312 | argsig = args[i].getAttribute('type') | ||
312 | argdirection = args[i].getAttribute('direction') | 313 | argdirection = args[i].getAttribute('direction') | ||
313 | 314 | | |||
314 | # QtDBus requires annotating a{sv} | 315 | # QtDBus requires annotating a{sv} | ||
Show All 38 Lines | 353 | if not argnames: | |||
353 | self.h("""\ | 354 | self.h("""\ | ||
354 | " <signal name=\\"%(name)s\\"/>\\n" | 355 | " <signal name=\\"%(name)s\\"/>\\n" | ||
355 | """ % {'name': name}) | 356 | """ % {'name': name}) | ||
356 | else: | 357 | else: | ||
357 | self.h("""\ | 358 | self.h("""\ | ||
358 | " <signal name=\\"%(name)s\\">\\n" | 359 | " <signal name=\\"%(name)s\\">\\n" | ||
359 | """ % {'name': name}) | 360 | """ % {'name': name}) | ||
360 | 361 | | |||
361 | for i in xrange(len(argnames)): | 362 | for i in range(len(argnames)): | ||
362 | assert argnames[i] != None, 'Name missing from argument at index %d for signal %s' % (i, name) | 363 | assert argnames[i] != None, 'Name missing from argument at index %d for signal %s' % (i, name) | ||
363 | 364 | | |||
364 | argbinding = argbindings[i] | 365 | argbinding = argbindings[i] | ||
365 | argname = argnames[i] | 366 | argname = argnames[i] | ||
366 | argsig = args[i].getAttribute('type') | 367 | argsig = args[i].getAttribute('type') | ||
367 | 368 | | |||
368 | if not argbinding.custom_type: | 369 | if not argbinding.custom_type: | ||
369 | self.h("""\ | 370 | self.h("""\ | ||
Show All 18 Lines | 387 | """) | |||
388 | def do_mic_typedefs(self, methods): | 389 | def do_mic_typedefs(self, methods): | ||
389 | for method in methods: | 390 | for method in methods: | ||
390 | name = method.getAttribute('name') | 391 | name = method.getAttribute('name') | ||
391 | args = get_by_path(method, 'arg') | 392 | args = get_by_path(method, 'arg') | ||
392 | argnames, argdocstrings, argbindings = extract_arg_or_member_info(args, self.custom_lists, | 393 | argnames, argdocstrings, argbindings = extract_arg_or_member_info(args, self.custom_lists, | ||
393 | self.externals, self.typesnamespace, self.refs, ' * ') | 394 | self.externals, self.typesnamespace, self.refs, ' * ') | ||
394 | 395 | | |||
395 | outargs = [] | 396 | outargs = [] | ||
396 | for i in xrange(len(args)): | 397 | for i in range(len(args)): | ||
397 | if args[i].getAttribute('direction') == 'out': | 398 | if args[i].getAttribute('direction') == 'out': | ||
398 | outargs.append(i) | 399 | outargs.append(i) | ||
399 | 400 | | |||
400 | if outargs: | 401 | if outargs: | ||
401 | outargtypes = ', '.join([argbindings[i].val for i in outargs]) | 402 | outargtypes = ', '.join([argbindings[i].val for i in outargs]) | ||
402 | else: | 403 | else: | ||
403 | outargtypes = '' | 404 | outargtypes = '' | ||
404 | 405 | | |||
▲ Show 20 Lines • Show All 109 Lines • ▼ Show 20 Line(s) | 512 | def do_method(self, ifacename, method): | |||
514 | args = get_by_path(method, 'arg') | 515 | args = get_by_path(method, 'arg') | ||
515 | argnames, argdocstrings, argbindings = extract_arg_or_member_info(args, self.custom_lists, | 516 | argnames, argdocstrings, argbindings = extract_arg_or_member_info(args, self.custom_lists, | ||
516 | self.externals, self.typesnamespace, self.refs, ' * ') | 517 | self.externals, self.typesnamespace, self.refs, ' * ') | ||
517 | docstring = format_docstring(method, self.refs, ' * ').replace('*/', '*/') | 518 | docstring = format_docstring(method, self.refs, ' * ').replace('*/', '*/') | ||
518 | 519 | | |||
519 | inargs = [] | 520 | inargs = [] | ||
520 | outargs = [] | 521 | outargs = [] | ||
521 | 522 | | |||
522 | for i in xrange(len(args)): | 523 | for i in range(len(args)): | ||
523 | if args[i].getAttribute('direction') == 'out': | 524 | if args[i].getAttribute('direction') == 'out': | ||
524 | outargs.append(i) | 525 | outargs.append(i) | ||
525 | else: | 526 | else: | ||
526 | inargs.append(i) | 527 | inargs.append(i) | ||
527 | assert argnames[i] != None, 'No argument name for input argument at index %d for method %s' % (i, name) | 528 | assert argnames[i] != None, 'No argument name for input argument at index %d for method %s' % (i, name) | ||
528 | 529 | | |||
529 | if outargs: | 530 | if outargs: | ||
530 | rettype = argbindings[outargs[0]].val | 531 | rettype = argbindings[outargs[0]].val | ||
▲ Show 20 Lines • Show All 67 Lines • ▼ Show 20 Line(s) | |||||
598 | """ % {'rettype': rettype, | 599 | """ % {'rettype': rettype, | ||
599 | 'name': name, | 600 | 'name': name, | ||
600 | 'params': params | 601 | 'params': params | ||
601 | }) | 602 | }) | ||
602 | 603 | | |||
603 | self.b(""" | 604 | self.b(""" | ||
604 | %(rettype)s %(ifacename)s::%(name)s(%(params)s) | 605 | %(rettype)s %(ifacename)s::%(name)s(%(params)s) | ||
605 | { | 606 | { | ||
606 | if (!adaptee()->metaObject()->indexOfMethod("%(adaptee_name)s(%(normalized_adaptee_params)s)") == -1) { | 607 | if (adaptee()->metaObject()->indexOfMethod("%(adaptee_name)s(%(normalized_adaptee_params)s)") < 0) { | ||
607 | dbusConnection().send(dbusMessage.createErrorReply(TP_QT_ERROR_NOT_IMPLEMENTED, QLatin1String("Not implemented"))); | 608 | dbusConnection().send(dbusMessage.createErrorReply(TP_QT_ERROR_NOT_IMPLEMENTED, QLatin1String("Not implemented"))); | ||
608 | """ % {'rettype': rettype, | 609 | """ % {'rettype': rettype, | ||
609 | 'ifacename': ifacename, | 610 | 'ifacename': ifacename, | ||
610 | 'name': name, | 611 | 'name': name, | ||
611 | 'adaptee_name': adaptee_name, | 612 | 'adaptee_name': adaptee_name, | ||
612 | 'normalized_adaptee_params': normalized_adaptee_params, | 613 | 'normalized_adaptee_params': normalized_adaptee_params, | ||
613 | 'params': params, | 614 | 'params': params, | ||
614 | }) | 615 | }) | ||
▲ Show 20 Lines • Show All 46 Lines • ▼ Show 20 Line(s) | 659 | """ % {'rettype': rettype}) | |||
661 | 662 | | |||
662 | def do_signal(self, signal): | 663 | def do_signal(self, signal): | ||
663 | name = signal.getAttribute('name') | 664 | name = signal.getAttribute('name') | ||
664 | adaptee_name = to_lower_camel_case(signal.getAttribute('tp:name-for-bindings')) | 665 | adaptee_name = to_lower_camel_case(signal.getAttribute('tp:name-for-bindings')) | ||
665 | argnames, argdocstrings, argbindings = extract_arg_or_member_info(get_by_path(signal, | 666 | argnames, argdocstrings, argbindings = extract_arg_or_member_info(get_by_path(signal, | ||
666 | 'arg'), self.custom_lists, self.externals, self.typesnamespace, self.refs, ' * ') | 667 | 'arg'), self.custom_lists, self.externals, self.typesnamespace, self.refs, ' * ') | ||
667 | params = ', '.join(['%s %s' % (binding.inarg, param_name) for binding, param_name in zip(argbindings, argnames)]) | 668 | params = ', '.join(['%s %s' % (binding.inarg, param_name) for binding, param_name in zip(argbindings, argnames)]) | ||
668 | 669 | | |||
669 | for i in xrange(len(argnames)): | 670 | for i in range(len(argnames)): | ||
670 | assert argnames[i] != None, 'Name missing from argument at index %d for signal %s' % (i, name) | 671 | assert argnames[i] != None, 'Name missing from argument at index %d for signal %s' % (i, name) | ||
671 | 672 | | |||
672 | self.h("""\ | 673 | self.h("""\ | ||
673 | /** | 674 | /** | ||
674 | * Represents the exported D-Bus signal \\c %(name)s on this object. | 675 | * Represents the exported D-Bus signal \\c %(name)s on this object. | ||
675 | * | 676 | * | ||
676 | * Adaptees should export this signal as a Qt signal with the following signature: | 677 | * Adaptees should export this signal as a Qt signal with the following signature: | ||
677 | * void %(adaptee_name)s(%(params)s); | 678 | * void %(adaptee_name)s(%(params)s); | ||
678 | * | 679 | * | ||
679 | * The adaptee signal will be automatically relayed as a D-Bus signal once emitted. | 680 | * The adaptee signal will be automatically relayed as a D-Bus signal once emitted. | ||
680 | * | 681 | * | ||
681 | """ % {'name': name, | 682 | """ % {'name': name, | ||
682 | 'adaptee_name': adaptee_name, | 683 | 'adaptee_name': adaptee_name, | ||
683 | 'params': params | 684 | 'params': params | ||
684 | }) | 685 | }) | ||
685 | 686 | | |||
686 | for i in xrange(len(argnames)): | 687 | for i in range(len(argnames)): | ||
687 | assert argnames[i] != None, 'Name missing from argument at index %d for signal %s' % (i, name) | 688 | assert argnames[i] != None, 'Name missing from argument at index %d for signal %s' % (i, name) | ||
688 | if argdocstrings[i]: | 689 | if argdocstrings[i]: | ||
689 | self.h("""\ | 690 | self.h("""\ | ||
690 | * \\param %s | 691 | * \\param %s | ||
691 | %s\ | 692 | %s\ | ||
692 | """ % (argnames[i], argdocstrings[i])) | 693 | """ % (argnames[i], argdocstrings[i])) | ||
693 | 694 | | |||
694 | self.h("""\ | 695 | self.h("""\ | ||
▲ Show 20 Lines • Show All 48 Lines • Show Last 20 Lines |