Update German translation
[glib.git] / gio / gdbus-2.0 / codegen / codegen_main.py
blob57254008d9bcc6907ca8823146c4cdc6448d65df
1 # -*- Mode: Python -*-
3 # GDBus - GLib D-Bus Library
5 # Copyright (C) 2008-2011 Red Hat, Inc.
7 # This library is free software; you can redistribute it and/or
8 # modify it under the terms of the GNU Lesser General Public
9 # License as published by the Free Software Foundation; either
10 # version 2 of the License, or (at your option) any later version.
12 # This library is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 # Lesser General Public License for more details.
17 # You should have received a copy of the GNU Lesser General
18 # Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
20 # Author: David Zeuthen <davidz@redhat.com>
22 import sys
23 import optparse
24 from os import path
26 from . import config
27 from . import utils
28 from . import dbustypes
29 from . import parser
30 from . import codegen
31 from . import codegen_docbook
33 def find_arg(arg_list, arg_name):
34 for a in arg_list:
35 if a.name == arg_name:
36 return a
37 return None
39 def find_method(iface, method):
40 for m in iface.methods:
41 if m.name == method:
42 return m
43 return None
45 def find_signal(iface, signal):
46 for m in iface.signals:
47 if m.name == signal:
48 return m
49 return None
51 def find_prop(iface, prop):
52 for m in iface.properties:
53 if m.name == prop:
54 return m
55 return None
57 def apply_annotation(iface_list, iface, method, signal, prop, arg, key, value):
58 iface_obj = None
59 for i in iface_list:
60 if i.name == iface:
61 iface_obj = i
62 break
64 if iface_obj == None:
65 raise RuntimeError('No interface %s'%iface)
67 target_obj = None
69 if method:
70 method_obj = find_method(iface_obj, method)
71 if method_obj == None:
72 raise RuntimeError('No method %s on interface %s'%(method, iface))
73 if arg:
74 arg_obj = find_arg(method_obj.in_args, arg)
75 if (arg_obj == None):
76 arg_obj = find_arg(method_obj.out_args, arg)
77 if (arg_obj == None):
78 raise RuntimeError('No arg %s on method %s on interface %s'%(arg, method, iface))
79 target_obj = arg_obj
80 else:
81 target_obj = method_obj
82 elif signal:
83 signal_obj = find_signal(iface_obj, signal)
84 if signal_obj == None:
85 raise RuntimeError('No signal %s on interface %s'%(signal, iface))
86 if arg:
87 arg_obj = find_arg(signal_obj.args, arg)
88 if (arg_obj == None):
89 raise RuntimeError('No arg %s on signal %s on interface %s'%(arg, signal, iface))
90 target_obj = arg_obj
91 else:
92 target_obj = signal_obj
93 elif prop:
94 prop_obj = find_prop(iface_obj, prop)
95 if prop_obj == None:
96 raise RuntimeError('No property %s on interface %s'%(prop, iface))
97 target_obj = prop_obj
98 else:
99 target_obj = iface_obj
100 target_obj.annotations.insert(0, dbustypes.Annotation(key, value))
103 def apply_annotations(iface_list, annotation_list):
104 # apply annotations given on the command line
105 for (what, key, value) in annotation_list:
106 pos = what.find('::')
107 if pos != -1:
108 # signal
109 iface = what[0:pos];
110 signal = what[pos + 2:]
111 pos = signal.find('[')
112 if pos != -1:
113 arg = signal[pos + 1:]
114 signal = signal[0:pos]
115 pos = arg.find(']')
116 arg = arg[0:pos]
117 apply_annotation(iface_list, iface, None, signal, None, arg, key, value)
118 else:
119 apply_annotation(iface_list, iface, None, signal, None, None, key, value)
120 else:
121 pos = what.find(':')
122 if pos != -1:
123 # property
124 iface = what[0:pos];
125 prop = what[pos + 1:]
126 apply_annotation(iface_list, iface, None, None, prop, None, key, value)
127 else:
128 pos = what.find('()')
129 if pos != -1:
130 # method
131 combined = what[0:pos]
132 pos = combined.rfind('.')
133 iface = combined[0:pos]
134 method = combined[pos + 1:]
135 pos = what.find('[')
136 if pos != -1:
137 arg = what[pos + 1:]
138 pos = arg.find(']')
139 arg = arg[0:pos]
140 apply_annotation(iface_list, iface, method, None, None, arg, key, value)
141 else:
142 apply_annotation(iface_list, iface, method, None, None, None, key, value)
143 else:
144 # must be an interface
145 iface = what
146 apply_annotation(iface_list, iface, None, None, None, None, key, value)
148 def codegen_main():
149 arg_parser = optparse.OptionParser('%prog [options]')
150 arg_parser.add_option('', '--xml-files', metavar='FILE', action='append',
151 help='D-Bus introspection XML file')
152 arg_parser.add_option('', '--interface-prefix', metavar='PREFIX', default='',
153 help='String to strip from D-Bus interface names for code and docs')
154 arg_parser.add_option('', '--c-namespace', metavar='NAMESPACE', default='',
155 help='The namespace to use for generated C code')
156 arg_parser.add_option('', '--c-generate-object-manager', action='store_true',
157 help='Generate a GDBusObjectManagerClient subclass when generating C code')
158 arg_parser.add_option('', '--generate-c-code', metavar='OUTFILES',
159 help='Generate C code in OUTFILES.[ch]')
160 arg_parser.add_option('', '--c-generate-autocleanup', type='choice', choices=['none', 'objects', 'all'], default='objects',
161 help='Generate autocleanup support')
162 arg_parser.add_option('', '--generate-docbook', metavar='OUTFILES',
163 help='Generate Docbook in OUTFILES-org.Project.IFace.xml')
164 arg_parser.add_option('', '--annotate', nargs=3, action='append', metavar='WHAT KEY VALUE',
165 help='Add annotation (may be used several times)')
166 arg_parser.add_option('', '--output-directory', metavar='OUTDIR', default='',
167 help='Location to output generated files')
168 (opts, args) = arg_parser.parse_args();
170 all_ifaces = []
171 for fname in args:
172 f = open(fname, 'rb')
173 xml_data = f.read()
174 f.close()
175 parsed_ifaces = parser.parse_dbus_xml(xml_data)
176 all_ifaces.extend(parsed_ifaces)
178 if opts.annotate != None:
179 apply_annotations(all_ifaces, opts.annotate)
181 for i in all_ifaces:
182 i.post_process(opts.interface_prefix, opts.c_namespace)
184 docbook = opts.generate_docbook
185 docbook_gen = codegen_docbook.DocbookCodeGenerator(all_ifaces, docbook);
186 if docbook:
187 ret = docbook_gen.generate()
189 c_code = opts.generate_c_code
190 if c_code:
191 outdir = opts.output_directory
192 header_name = c_code + '.h'
193 h = open(path.join(outdir, header_name), 'w')
194 c = open(path.join(outdir, c_code + '.c'), 'w')
195 gen = codegen.CodeGenerator(all_ifaces,
196 opts.c_namespace,
197 opts.interface_prefix,
198 opts.c_generate_object_manager,
199 opts.c_generate_autocleanup,
200 docbook_gen,
201 h, c,
202 header_name)
203 ret = gen.generate()
204 h.close()
205 c.close()
207 sys.exit(0)
209 if __name__ == "__main__":
210 codegen_main()