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>
28 from . import dbustypes
31 from . import codegen_docbook
33 def find_arg(arg_list
, arg_name
):
35 if a
.name
== arg_name
:
39 def find_method(iface
, method
):
40 for m
in iface
.methods
:
45 def find_signal(iface
, signal
):
46 for m
in iface
.signals
:
51 def find_prop(iface
, prop
):
52 for m
in iface
.properties
:
57 def apply_annotation(iface_list
, iface
, method
, signal
, prop
, arg
, key
, value
):
65 raise RuntimeError('No interface %s'%iface
)
70 method_obj
= find_method(iface_obj
, method
)
71 if method_obj
== None:
72 raise RuntimeError('No method %s on interface %s'%(method
, iface
))
74 arg_obj
= find_arg(method_obj
.in_args
, arg
)
76 arg_obj
= find_arg(method_obj
.out_args
, arg
)
78 raise RuntimeError('No arg %s on method %s on interface %s'%(arg
, method
, iface
))
81 target_obj
= method_obj
83 signal_obj
= find_signal(iface_obj
, signal
)
84 if signal_obj
== None:
85 raise RuntimeError('No signal %s on interface %s'%(signal
, iface
))
87 arg_obj
= find_arg(signal_obj
.args
, arg
)
89 raise RuntimeError('No arg %s on signal %s on interface %s'%(arg
, signal
, iface
))
92 target_obj
= signal_obj
94 prop_obj
= find_prop(iface_obj
, prop
)
96 raise RuntimeError('No property %s on interface %s'%(prop
, iface
))
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('::')
110 signal
= what
[pos
+ 2:]
111 pos
= signal
.find('[')
113 arg
= signal
[pos
+ 1:]
114 signal
= signal
[0:pos
]
117 apply_annotation(iface_list
, iface
, None, signal
, None, arg
, key
, value
)
119 apply_annotation(iface_list
, iface
, None, signal
, None, None, key
, value
)
125 prop
= what
[pos
+ 1:]
126 apply_annotation(iface_list
, iface
, None, None, prop
, None, key
, value
)
128 pos
= what
.find('()')
131 combined
= what
[0:pos
]
132 pos
= combined
.rfind('.')
133 iface
= combined
[0:pos
]
134 method
= combined
[pos
+ 1:]
140 apply_annotation(iface_list
, iface
, method
, None, None, arg
, key
, value
)
142 apply_annotation(iface_list
, iface
, method
, None, None, None, key
, value
)
144 # must be an interface
146 apply_annotation(iface_list
, iface
, None, None, None, None, key
, value
)
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();
172 f
= open(fname
, 'rb')
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
)
182 i
.post_process(opts
.interface_prefix
, opts
.c_namespace
)
184 docbook
= opts
.generate_docbook
185 docbook_gen
= codegen_docbook
.DocbookCodeGenerator(all_ifaces
, docbook
);
187 ret
= docbook_gen
.generate()
189 c_code
= opts
.generate_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
,
197 opts
.interface_prefix
,
198 opts
.c_generate_object_manager
,
199 opts
.c_generate_autocleanup
,
209 if __name__
== "__main__":