Merge lp:~cjdahlin/libnih/async into lp:libnih/1.0

Proposed by Scott James Remnant (Canonical)
Status: Merged
Merge reported by: Scott James Remnant (Canonical)
Merged at revision: not available
Proposed branch: lp:~cjdahlin/libnih/async
Merge into: lp:libnih/1.0
Diff against target: 4862 lines
3 files modified
ChangeLog (+28/-0)
nih-dbus-tool/tests/test_com.netsplit.Nih.Test_proxy.c (+2162/-0)
nih/nih_dbus_tool.py.OTHER (+2635/-0)
To merge this branch: bzr merge lp:~cjdahlin/libnih/async
Reviewer Review Type Date Requested Status
Scott James Remnant (Canonical) Approve
Review via email: mp+12818@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Scott James Remnant (Canonical) (canonical-scott) wrote :

This got merged and then improved, thanks Casey!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'ChangeLog'
2--- ChangeLog 2009-08-11 10:30:25 +0000
3+++ ChangeLog 2009-10-03 06:00:27 +0000
4@@ -1,3 +1,4 @@
5+<<<<<<< TREE
6 2009-08-11 Scott James Remnant <scott@netsplit.com>
7
8 * nih/test_alloc.h (TEST_ALLOC_NOT_PARENT): Add the opposite test
9@@ -2671,6 +2672,33 @@
10 Fix the test case to not compare a void * with strcmp
11
12 2008-01-29 Casey Dahlin <cdahlin@redhat.com>
13+=======
14+2009-2-09 Casey Dahlin <cdahlin@redhat.com>
15+
16+ * nih/tests/test_com.netsplit.Nih.Test_proxy.c: Even more tests for
17+ async calls.
18+
19+2009-2-01 Casey Dahlin <cdahlin@redhat.com>
20+
21+ * nih/nih_dbus_tool.py (Method.asyncDispatchPrototype): Rename
22+ typedefs for callbacks from NihDBusCallback_foo_method to
23+ FooMethodCallback. Same for Errback.
24+
25+ * nih/nih_dbus_tool.py (Method.asyncDispatchFunction): Check for and
26+ properly handle error returns fron DBus. Also be sure to call the
27+ errback for various memory/parse errors.
28+
29+ * nih/nih_dbus_tool.py (Method.exportTypedefs): More changes for new
30+ typedef names.
31+
32+ * nih/nih_dbus_tool.py (camelate): New function to convert
33+ underscore_delineated to CamelCase.
34+
35+ * nih/tests/test_com.netsplit.Nih.Test_proxy.c: Loads more tests for
36+ async calls.
37+
38+2009-1-29 Casey Dahlin <cdahlin@redhat.com>
39+>>>>>>> MERGE-SOURCE
40
41 * nih/nih_dbus_tool.py (Method.asyncDispatchPrototype): Prototype for
42 new asynchronous dispatch function, explained below.
43
44=== modified file 'nih-dbus-tool/tests/test_com.netsplit.Nih.Test_proxy.c'
45--- nih-dbus-tool/tests/test_com.netsplit.Nih.Test_proxy.c 2009-08-03 15:29:45 +0000
46+++ nih-dbus-tool/tests/test_com.netsplit.Nih.Test_proxy.c 2009-10-03 06:00:27 +0000
47@@ -37,6 +37,7 @@
48 #include <nih/signal.h>
49 #include <nih/main.h>
50 #include <nih/error.h>
51+<<<<<<< TREE
52
53 #include <nih-dbus/dbus_connection.h>
54 #include <nih-dbus/dbus_object.h>
55@@ -50204,6 +50205,2167 @@
56 TEST_DBUS_END (dbus_pid);
57
58 dbus_shutdown ();
59+=======
60+#include <nih/errors.h>
61+
62+#include <nih/dbus.h>
63+
64+#include "com.netsplit.Nih.Test_proxy.h"
65+#include "com.netsplit.Nih.Test_impl.h"
66+
67+
68+static void async_fail_errback (NihDBusProxy *my_proxy, void *userdata);
69+
70+void
71+test_method_dispatch (void)
72+{
73+ DBusConnection *conn;
74+ NihDBusProxy *proxy;
75+ NihError *err;
76+ NihDBusError *dbus_err;
77+ char *output;
78+ uint8_t byte_arg;
79+ int boolean_arg;
80+ int16_t int16_arg;
81+ uint16_t uint16_arg;
82+ int32_t int32_arg;
83+ uint32_t uint32_arg;
84+ int64_t int64_arg;
85+ uint64_t uint64_arg;
86+ double double_arg;
87+ int32_t *int32_array;
88+ char **str_array;
89+ size_t array_len;
90+ int ret;
91+ int called;
92+
93+ TEST_GROUP ("method dispatching");
94+
95+
96+ /* Check that we can make a D-Bus method call, passing in the
97+ * expected arguments and receiving the expected arguments in the
98+ * reply.
99+ */
100+ TEST_FEATURE ("with valid argument");
101+ conn = my_setup ();
102+ proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
103+
104+ output = NULL;
105+
106+ ret = proxy_test_method (proxy, "test data", 0, &output);
107+
108+ TEST_EQ (ret, 0);
109+
110+ TEST_NE_P (output, NULL);
111+ TEST_ALLOC_PARENT (output, proxy);
112+ TEST_EQ_STR (output, "test data");
113+
114+ nih_free (proxy);
115+
116+ my_teardown (conn);
117+
118+
119+ /* Check that we can make an asynchronous D-Bus method call, passing in
120+ * the expected arguments and receiving the expected arguments in the
121+ * callback.
122+ */
123+ TEST_FEATURE ("with valid argument (async)");
124+ conn = my_setup ();
125+ proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
126+
127+ auto void async_with_valid_argument (NihDBusProxy *proxy, void *userdata, char *output);
128+
129+ called = 0;
130+
131+ ret = proxy_test_method_async (proxy, "test data", 0,
132+ async_with_valid_argument, async_fail_errback, "userdata");
133+
134+ TEST_EQ (ret, 0);
135+
136+ void async_with_valid_argument (NihDBusProxy *my_proxy, void *userdata, char *async_output)
137+ {
138+ TEST_NE_P (async_output, NULL);
139+ TEST_ALLOC_PARENT (async_output, proxy);
140+ TEST_EQ_STR (async_output, "test data");
141+ TEST_EQ_STR (userdata, "userdata");
142+ TEST_EQ_P (my_proxy, proxy);
143+ called = 1;
144+ }
145+
146+ while (! called)
147+ dbus_connection_read_write_dispatch (conn, -1);
148+
149+ nih_free (proxy);
150+
151+ my_teardown (conn);
152+
153+
154+ /* Check that if the method call returns a D-Bus error, the async proxy
155+ * call triggers the error handler and sets the appropriate error.
156+ */
157+ TEST_FEATURE ("with returned D-Bus error");
158+ conn = my_setup ();
159+ proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
160+
161+ output = NULL;
162+
163+ ret = proxy_test_method (proxy, "test data", 1, &output);
164+
165+ TEST_LT (ret, 1);
166+
167+ err = nih_error_get ();
168+ TEST_EQ (err->number, NIH_DBUS_ERROR);
169+ TEST_ALLOC_SIZE (err, sizeof (NihDBusError));
170+
171+ dbus_err = (NihDBusError *)err;
172+ TEST_EQ_STR (dbus_err->name, "com.netsplit.Nih.IllegalValue");
173+
174+ nih_free (dbus_err);
175+
176+ nih_free (proxy);
177+
178+ my_teardown (conn);
179+
180+
181+ /* Check that if the method call returns a D-Bus error, the proxy
182+ * call returns a negative number and raises the same D-Bus error.
183+ */
184+ TEST_FEATURE ("with returned D-Bus error (async)");
185+ conn = my_setup ();
186+ proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
187+
188+ output = NULL;
189+
190+ auto void async_with_dbus_error_errback (NihDBusProxy *proxy, void *userdata);
191+
192+ called = 0;
193+
194+ ret = proxy_test_method_async (proxy, "test data", 1, (ProxyTestMethodCallback)async_fail_errback,
195+ async_with_dbus_error_errback,"user data");
196+
197+ TEST_EQ (ret, 0);
198+
199+ void async_with_dbus_error_errback (NihDBusProxy *my_proxy, void *userdata)
200+ {
201+ err = nih_error_get ();
202+ TEST_EQ (err->number, NIH_DBUS_ERROR);
203+ TEST_ALLOC_SIZE (err, sizeof (NihDBusError));
204+
205+ dbus_err = (NihDBusError *)err;
206+ TEST_EQ_STR (dbus_err->name, "com.netsplit.Nih.IllegalValue");
207+ TEST_EQ_STR (userdata, "user data");
208+ TEST_EQ_P (my_proxy, proxy);
209+ called = 1;
210+ }
211+
212+ while (! called)
213+ dbus_connection_read_write_dispatch (conn, -1);
214+
215+ nih_free (dbus_err);
216+
217+ nih_free (proxy);
218+
219+ my_teardown (conn);
220+
221+
222+ /* Check that in out of memory conditions, D-Bus automatically
223+ * repeats the method call so we don't notice on the client side.
224+ */
225+ TEST_FEATURE ("with out of memory error");
226+ conn = my_setup ();
227+ proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
228+
229+ output = NULL;
230+
231+ ret = proxy_test_method (proxy, "test data", 2, &output);
232+
233+ TEST_EQ (ret, 0);
234+
235+ TEST_NE_P (output, NULL);
236+ TEST_ALLOC_PARENT (output, proxy);
237+ TEST_EQ_STR (output, "test data");
238+
239+ nih_free (proxy);
240+
241+ my_teardown (conn);
242+
243+
244+ /* Check that in out of memory conditions, D-Bus automatically
245+ * repeats the method call so we don't notice on the client side, even
246+ * when the call is asynchronous.
247+ */
248+ TEST_FEATURE ("with out of memory error (async)");
249+ conn = my_setup ();
250+ proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
251+
252+ auto void async_with_oom (NihDBusProxy *proxy, void *userdata, char *output);
253+
254+ called = 0;
255+
256+ ret = proxy_test_method_async (proxy, "test data", 2,
257+ async_with_valid_argument, async_fail_errback, "userdata");
258+
259+ TEST_EQ (ret, 0);
260+
261+ void async_with_oom (NihDBusProxy *my_proxy, void *userdata, char *async_output)
262+ {
263+ TEST_NE_P (async_output, NULL);
264+ TEST_ALLOC_PARENT (async_output, proxy);
265+ TEST_EQ_STR (async_output, "test data");
266+ TEST_EQ_STR (userdata, "userdata");
267+ TEST_EQ_P (my_proxy, proxy);
268+ called = 1;
269+ }
270+
271+ while (! called)
272+ dbus_connection_read_write_dispatch (conn, -1);
273+
274+ nih_free (proxy);
275+
276+ my_teardown (conn);
277+
278+
279+ /* Check that an error unknown to D-Bus is turned into a generic
280+ * failed error.
281+ */
282+ TEST_FEATURE ("with unknown error");
283+ conn = my_setup ();
284+ proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
285+
286+ output = NULL;
287+
288+ ret = proxy_test_method (proxy, "test data", 3, &output);
289+
290+ TEST_LT (ret, 1);
291+
292+ err = nih_error_get ();
293+ TEST_EQ (err->number, NIH_DBUS_ERROR);
294+ TEST_ALLOC_SIZE (err, sizeof (NihDBusError));
295+
296+ dbus_err = (NihDBusError *)err;
297+ TEST_EQ_STR (dbus_err->name, DBUS_ERROR_FAILED);
298+
299+ nih_free (dbus_err);
300+
301+ nih_free (proxy);
302+
303+ my_teardown (conn);
304+
305+
306+ /* Check that an error unknown to D-Bus is turned into a generic
307+ * failed error for an async call.
308+ */
309+ TEST_FEATURE ("with unknown error (async)");
310+ conn = my_setup ();
311+ proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
312+
313+ auto void async_with_unknown (NihDBusProxy *proxy, void *userdata);
314+
315+ called = 0;
316+
317+ ret = proxy_test_method_async (proxy, "test data", 3,
318+ (ProxyTestMethodCallback)async_fail_errback, async_with_unknown, "userdata");
319+
320+ TEST_EQ (ret, 0);
321+
322+ void async_with_unknown (NihDBusProxy *my_proxy, void *userdata)
323+ {
324+ err = nih_error_get ();
325+ TEST_EQ (err->number, NIH_DBUS_ERROR);
326+ TEST_ALLOC_SIZE (err, sizeof (NihDBusError));
327+
328+ dbus_err = (NihDBusError *)err;
329+ TEST_EQ_STR (dbus_err->name, DBUS_ERROR_FAILED);
330+
331+ nih_free (dbus_err);
332+
333+ TEST_EQ_STR (userdata, "userdata");
334+ TEST_EQ_P (my_proxy, proxy);
335+ called = 1;
336+ }
337+
338+ while (! called)
339+ dbus_connection_read_write_dispatch (conn, -1);
340+
341+ nih_free (proxy);
342+
343+ my_teardown (conn);
344+
345+
346+ /* Check that the fact the server implementation is asynchronous
347+ * is hidden and the call blocks until the reply comes back anyway.
348+ */
349+ TEST_FEATURE ("with valid argument to async call");
350+ conn = my_setup ();
351+ proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
352+
353+ output = NULL;
354+
355+ ret = proxy_test_async_method (proxy, "test data", 0, &output);
356+
357+ TEST_EQ (ret, 0);
358+
359+ TEST_NE_P (output, NULL);
360+ TEST_ALLOC_PARENT (output, proxy);
361+ TEST_EQ_STR (output, "test data");
362+
363+ nih_free (proxy);
364+
365+ my_teardown (conn);
366+
367+
368+ /* Check that the fact the server implementation is asynchronous
369+ * doesn't affect asynchronous calls from us.
370+ */
371+ TEST_FEATURE ("with valid argument to async call (async)");
372+ conn = my_setup ();
373+ proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
374+
375+ auto void async_with_async (NihDBusProxy *my_proxy, void *userdata, char *async_output);
376+
377+ called = 0;
378+
379+ ret = proxy_test_async_method_async (proxy, "test data", 0,
380+ async_with_async, async_fail_errback, "userdata");
381+
382+ TEST_EQ (ret, 0);
383+
384+ void async_with_async (NihDBusProxy *my_proxy, void *userdata, char *async_output)
385+ {
386+ TEST_NE_P (async_output, NULL);
387+ TEST_ALLOC_PARENT (async_output, proxy);
388+ TEST_EQ_STR (async_output, "test data");
389+ TEST_EQ_STR (userdata, "userdata");
390+ TEST_EQ_P (my_proxy, proxy);
391+ called = 1;
392+ }
393+
394+ while (! called)
395+ dbus_connection_read_write_dispatch (conn, -1);
396+
397+ nih_free (proxy);
398+
399+ my_teardown (conn);
400+
401+
402+ /* Check that an error returned from an asynchronous server-side
403+ * call still comes back as an error.
404+ */
405+ TEST_FEATURE ("with returned D-Bus error from async call");
406+ conn = my_setup ();
407+ proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
408+
409+ output = NULL;
410+
411+ ret = proxy_test_async_method (proxy, "test data", 1, &output);
412+
413+ TEST_LT (ret, 1);
414+
415+ err = nih_error_get ();
416+ TEST_EQ (err->number, NIH_DBUS_ERROR);
417+ TEST_ALLOC_SIZE (err, sizeof (NihDBusError));
418+
419+ dbus_err = (NihDBusError *)err;
420+ TEST_EQ_STR (dbus_err->name, "com.netsplit.Nih.IllegalValue");
421+
422+ nih_free (dbus_err);
423+
424+ nih_free (proxy);
425+
426+ my_teardown (conn);
427+
428+
429+ /* Check that an error returned from an asynchronous server-side
430+ * call still comes back as an error to an async client call.
431+ */
432+ TEST_FEATURE ("with returned D-Bus error from async call (async)");
433+ conn = my_setup ();
434+ proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
435+
436+ auto void async_with_async_err (NihDBusProxy *my_proxy, void *userdata);
437+
438+ called = 0;
439+
440+ ret = proxy_test_async_method_async (proxy, "test data", 1,
441+ (ProxyTestAsyncMethodCallback)async_fail_errback, async_with_async_err, "userdata");
442+
443+ TEST_EQ (ret, 0);
444+
445+ void async_with_async_err (NihDBusProxy *my_proxy, void *userdata)
446+ {
447+ err = nih_error_get ();
448+ TEST_EQ (err->number, NIH_DBUS_ERROR);
449+ TEST_ALLOC_SIZE (err, sizeof (NihDBusError));
450+
451+ dbus_err = (NihDBusError *)err;
452+ TEST_EQ_STR (dbus_err->name, "com.netsplit.Nih.IllegalValue");
453+
454+ nih_free (dbus_err);
455+
456+ TEST_EQ_STR (userdata, "userdata");
457+ TEST_EQ_P (my_proxy, proxy);
458+ called = 1;
459+ }
460+
461+ while (! called)
462+ dbus_connection_read_write_dispatch (conn, -1);
463+
464+ nih_free (proxy);
465+
466+ my_teardown (conn);
467+
468+
469+ /* Check that in out of memory conditions, D-Bus automatically
470+ * repeats the method call so we don't notice on the client side
471+ * even for async server-side calls.
472+ */
473+ TEST_FEATURE ("with out of memory error from async call");
474+ conn = my_setup ();
475+ proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
476+
477+ output = NULL;
478+
479+ ret = proxy_test_async_method (proxy, "test data", 2, &output);
480+
481+ TEST_EQ (ret, 0);
482+
483+ TEST_NE_P (output, NULL);
484+ TEST_ALLOC_PARENT (output, proxy);
485+ TEST_EQ_STR (output, "test data");
486+
487+ nih_free (proxy);
488+
489+ my_teardown (conn);
490+
491+
492+ /* Check that in out of memory conditions, D-Bus automatically
493+ * repeats the method call so we don't notice on the client side
494+ * even for async server-side calls, when our call was async.
495+ */
496+ TEST_FEATURE ("with out of memory error from async call (async)");
497+ conn = my_setup ();
498+ proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
499+
500+ auto void async_with_async_oom (NihDBusProxy *my_proxy, void *userdata, char *async_output);
501+
502+ called = 0;
503+
504+ ret = proxy_test_async_method_async (proxy, "test data", 2,
505+ async_with_async_oom, async_fail_errback, "userdata");
506+
507+ TEST_EQ (ret, 0);
508+
509+ void async_with_async_oom (NihDBusProxy *my_proxy, void *userdata, char *async_output)
510+ {
511+ TEST_NE_P (async_output, NULL);
512+ TEST_ALLOC_PARENT (async_output, proxy);
513+ TEST_EQ_STR (async_output, "test data");
514+ TEST_EQ_STR (userdata, "userdata");
515+ TEST_EQ_P (my_proxy, proxy);
516+ called = 1;
517+ }
518+
519+ while (! called)
520+ dbus_connection_read_write_dispatch (conn, -1);
521+
522+ nih_free (proxy);
523+
524+ my_teardown (conn);
525+
526+
527+ /* Check that an error unknown to D-Bus is turned into a generic
528+ * failed error.
529+ */
530+ TEST_FEATURE ("with unknown error from async call");
531+ conn = my_setup ();
532+ proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
533+
534+ output = NULL;
535+
536+ ret = proxy_test_async_method (proxy, "test data", 3, &output);
537+
538+ TEST_LT (ret, 1);
539+
540+ err = nih_error_get ();
541+ TEST_EQ (err->number, NIH_DBUS_ERROR);
542+ TEST_ALLOC_SIZE (err, sizeof (NihDBusError));
543+
544+ dbus_err = (NihDBusError *)err;
545+ TEST_EQ_STR (dbus_err->name, DBUS_ERROR_FAILED);
546+
547+ nih_free (dbus_err);
548+
549+ nih_free (proxy);
550+
551+ my_teardown (conn);
552+
553+
554+ /* Check that an error unknown to D-Bus is turned into a generic
555+ * failed error for an async call.
556+ */
557+ TEST_FEATURE ("with unknown error from async call (async)");
558+ conn = my_setup ();
559+ proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
560+
561+ auto void async_with_async_unknown (NihDBusProxy *my_proxy, void *userdata);
562+
563+ called = 0;
564+
565+ ret = proxy_test_async_method_async (proxy, "test data", 3,
566+ (ProxyTestAsyncMethodCallback)async_fail_errback, async_with_async_unknown, "userdata");
567+
568+ TEST_EQ (ret, 0);
569+
570+ void async_with_async_unknown (NihDBusProxy *my_proxy, void *userdata)
571+ {
572+ err = nih_error_get ();
573+ TEST_EQ (err->number, NIH_DBUS_ERROR);
574+ TEST_ALLOC_SIZE (err, sizeof (NihDBusError));
575+
576+ dbus_err = (NihDBusError *)err;
577+ TEST_EQ_STR (dbus_err->name, DBUS_ERROR_FAILED);
578+
579+ nih_free (dbus_err);
580+
581+ TEST_EQ_STR (userdata, "userdata");
582+ TEST_EQ_P (my_proxy, proxy);
583+ called = 1;
584+ }
585+
586+ while (! called)
587+ dbus_connection_read_write_dispatch (conn, -1);
588+
589+ nih_free (proxy);
590+
591+ my_teardown (conn);
592+
593+
594+ /* Check that a condition whereby the wrong arguments are returned
595+ * from a method call results in a special illegal arguments error
596+ * being returned.
597+ */
598+ TEST_FEATURE ("with wrong argument type in reply");
599+ conn = my_setup ();
600+ proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
601+
602+ output = NULL;
603+
604+ ret = proxy_test_async_method (proxy, "test data", 4, &output);
605+
606+ TEST_LT (ret, 1);
607+
608+ err = nih_error_get ();
609+ TEST_EQ (err->number, NIH_DBUS_INVALID_ARGS);
610+ nih_free (err);
611+
612+ nih_free (proxy);
613+
614+ my_teardown (conn);
615+
616+
617+ /* Check that a condition whereby the wrong arguments are returned
618+ * from a method call results in a special illegal arguments error
619+ * being passed to the errback.
620+ */
621+ TEST_FEATURE ("with wrong argument type in reply (async)");
622+ conn = my_setup ();
623+ proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
624+
625+ auto void with_wrong_argument_type_in_reply_async (NihDBusProxy *my_proxy, void *userdata);
626+
627+ called = 0;
628+
629+ ret = proxy_test_async_method_async (proxy, "test data", 4,
630+ (ProxyTestAsyncMethodCallback)async_fail_errback,
631+ with_wrong_argument_type_in_reply_async, "userdata");
632+
633+ TEST_EQ (ret, 0);
634+
635+ void with_wrong_argument_type_in_reply_async (NihDBusProxy *my_proxy, void *userdata)
636+ {
637+ err = nih_error_get ();
638+ TEST_EQ (err->number, NIH_DBUS_INVALID_ARGS);
639+ nih_free (err);
640+ TEST_EQ_STR (userdata, "userdata");
641+ TEST_EQ_P (my_proxy, proxy);
642+ called = 1;
643+ }
644+
645+ while (! called)
646+ dbus_connection_read_write_dispatch (conn, -1);
647+
648+ nih_free (proxy);
649+
650+ my_teardown (conn);
651+
652+
653+ /* Check that a condition whereby too many arguments are returned
654+ * from a method call results in a special illegal arguments error
655+ * being returned.
656+ */
657+ TEST_FEATURE ("with too many arguments in reply");
658+ conn = my_setup ();
659+ proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
660+
661+ auto void with_too_many_args_in_reply_async (NihDBusProxy *my_proxy, void *userdata);
662+
663+ called = 0;
664+
665+ ret = proxy_test_async_method_async (proxy, "test data", 5,
666+ (ProxyTestAsyncMethodCallback)async_fail_errback,
667+ with_too_many_args_in_reply_async, "userdata");
668+
669+ TEST_EQ (ret, 0);
670+
671+ void with_too_many_args_in_reply_async (NihDBusProxy *my_proxy, void *userdata)
672+ {
673+ err = nih_error_get ();
674+ TEST_EQ (err->number, NIH_DBUS_INVALID_ARGS);
675+ nih_free (err);
676+ TEST_EQ_STR (userdata, "userdata");
677+ TEST_EQ_P (my_proxy, proxy);
678+ called = 1;
679+ }
680+
681+ while (! called)
682+ dbus_connection_read_write_dispatch (conn, -1);
683+
684+ nih_free (proxy);
685+
686+ my_teardown (conn);
687+
688+
689+ /* Check that a condition whereby too many arguments are returned
690+ * from a method call results in a special illegal arguments error
691+ * being passed to the errback.
692+ */
693+ TEST_FEATURE ("with too many arguments in reply (async)");
694+ conn = my_setup ();
695+ proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
696+
697+ output = NULL;
698+
699+ ret = proxy_test_async_method (proxy, "test data", 5, &output);
700+
701+ TEST_LT (ret, 1);
702+
703+ err = nih_error_get ();
704+ TEST_EQ (err->number, NIH_DBUS_INVALID_ARGS);
705+ nih_free (err);
706+
707+ nih_free (proxy);
708+
709+ my_teardown (conn);
710+
711+
712+ /* Check that a condition whereby arguments are missing from the
713+ * method call return results in a special illegal arguments error
714+ * being returned.
715+ */
716+ TEST_FEATURE ("with missing arguments in reply");
717+ conn = my_setup ();
718+ proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
719+
720+ output = NULL;
721+
722+ ret = proxy_test_async_method (proxy, "test data", 6, &output);
723+
724+ TEST_LT (ret, 1);
725+
726+ err = nih_error_get ();
727+ TEST_EQ (err->number, NIH_DBUS_INVALID_ARGS);
728+ nih_free (err);
729+
730+ nih_free (proxy);
731+
732+ my_teardown (conn);
733+
734+
735+ /* Check that a condition whereby arguments are missing from the
736+ * method call return results in a special illegal arguments error
737+ * being passed to the errback.
738+ */
739+ TEST_FEATURE ("with missing arguments in reply (async)");
740+ conn = my_setup ();
741+ proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
742+
743+ auto void with_missing_args_in_reply_async (NihDBusProxy *my_proxy, void *userdata);
744+
745+ called = 0;
746+
747+ ret = proxy_test_async_method_async (proxy, "test data", 6,
748+ (ProxyTestAsyncMethodCallback)async_fail_errback,
749+ with_missing_args_in_reply_async, "userdata");
750+
751+ TEST_EQ (ret, 0);
752+
753+ void with_missing_args_in_reply_async (NihDBusProxy *my_proxy, void *userdata)
754+ {
755+ err = nih_error_get ();
756+ TEST_EQ (err->number, NIH_DBUS_INVALID_ARGS);
757+ nih_free (err);
758+ TEST_EQ_STR (userdata, "userdata");
759+ TEST_EQ_P (my_proxy, proxy);
760+ called = 1;
761+ }
762+
763+ while (! called)
764+ dbus_connection_read_write_dispatch (conn, -1);
765+
766+ nih_free (proxy);
767+
768+ my_teardown (conn);
769+
770+
771+ /* Check that an input argument of Byte type is dispatched
772+ * correctly.
773+ */
774+ TEST_FEATURE ("with Byte input argument");
775+ conn = my_setup ();
776+ proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
777+
778+ output = NULL;
779+
780+ ret = proxy_byte_to_str (proxy, 65, &output);
781+
782+ TEST_EQ (ret, 0);
783+
784+ TEST_NE_P (output, NULL);
785+ TEST_ALLOC_PARENT (output, proxy);
786+ TEST_EQ_STR (output, "65");
787+
788+ nih_free (proxy);
789+
790+ my_teardown (conn);
791+
792+
793+ /* Check that an input argument of Byte type is dispatched
794+ * correctly by an async call.
795+ */
796+ TEST_FEATURE ("with Byte input argument (async)");
797+ conn = my_setup ();
798+ proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
799+
800+ auto void with_byte_input_argument (NihDBusProxy *my_proxy, char *userdata, char *my_output);
801+
802+ called = 0;
803+ ret = proxy_byte_to_str_async (proxy, 65, (ProxyByteToStrCallback)with_byte_input_argument, async_fail_errback, "user data");
804+
805+ TEST_EQ (ret, 0);
806+
807+ void with_byte_input_argument (NihDBusProxy *my_proxy, char *userdata, char *my_output)
808+ {
809+ TEST_EQ_P (my_proxy, proxy);
810+ TEST_EQ_STR (userdata, "user data");
811+ TEST_NE_P (my_output, NULL);
812+ TEST_ALLOC_PARENT (my_output, proxy);
813+ TEST_EQ_STR (my_output, "65");
814+ called = 1;
815+ }
816+
817+ while (! called)
818+ dbus_connection_read_write_dispatch (conn, -1);
819+
820+ nih_free (proxy);
821+
822+ my_teardown (conn);
823+
824+
825+ /* Check that an output argument of Byte type is marshalled
826+ * correctly.
827+ */
828+ TEST_FEATURE ("with Byte output argument");
829+ conn = my_setup ();
830+ proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
831+
832+ byte_arg = 0;
833+
834+ ret = proxy_str_to_byte (proxy, "65", &byte_arg);
835+
836+ TEST_EQ (ret, 0);
837+
838+ TEST_EQ (byte_arg, 65);
839+
840+ nih_free (proxy);
841+
842+ my_teardown (conn);
843+
844+
845+ /* Check that an output argument of Byte type is marshalled
846+ * correctly for asynchronous calls.
847+ */
848+ TEST_FEATURE ("with Byte output argument (async)");
849+ conn = my_setup ();
850+ proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
851+
852+ auto void with_byte_output_argument (NihDBusProxy *my_proxy, char *userdata, typeof(byte_arg) my_byte_arg);
853+
854+ called = 0;
855+
856+ ret = proxy_str_to_byte_async (proxy, "65", (ProxyStrToByteCallback)with_byte_output_argument, async_fail_errback, "user data");
857+
858+ TEST_EQ (ret, 0);
859+
860+ void with_byte_output_argument (NihDBusProxy *my_proxy, char *userdata, typeof(byte_arg) my_byte_arg)
861+ {
862+ TEST_EQ_P (my_proxy, proxy);
863+ TEST_EQ_STR (userdata, "user data");
864+ TEST_EQ (my_byte_arg, 65);
865+ called = 1;
866+ }
867+
868+ while (! called)
869+ dbus_connection_read_write_dispatch (conn, -1);
870+
871+ nih_free (proxy);
872+
873+ my_teardown (conn);
874+
875+
876+ /* Check that an input argument of Boolean type is dispatched
877+ * correctly.
878+ */
879+ TEST_FEATURE ("with Boolean input argument");
880+ conn = my_setup ();
881+ proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
882+
883+ output = NULL;
884+
885+ ret = proxy_boolean_to_str (proxy, 1, &output);
886+
887+ TEST_EQ (ret, 0);
888+
889+ TEST_NE_P (output, NULL);
890+ TEST_ALLOC_PARENT (output, proxy);
891+ TEST_EQ_STR (output, "True");
892+
893+ nih_free (proxy);
894+
895+ my_teardown (conn);
896+
897+
898+ /* Check that an input argument of Boolean type is dispatched
899+ * correctly for asynchronous calls.
900+ */
901+ TEST_FEATURE ("with Boolean input argument (async)");
902+ conn = my_setup ();
903+ proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
904+
905+ auto void with_boolean_input_argument (NihDBusProxy *proxy, char *userdata, char *output);
906+
907+ called = 0;
908+ ret = proxy_boolean_to_str_async (proxy, 1, (ProxyBooleanToStrCallback)with_boolean_input_argument, async_fail_errback, "user data");
909+
910+ TEST_EQ (ret, 0);
911+
912+ void with_boolean_input_argument (NihDBusProxy *my_proxy, char *userdata, char *my_output)
913+ {
914+ TEST_EQ_STR (userdata, "user data");
915+ TEST_EQ_P (my_proxy, proxy);
916+ TEST_NE_P (my_output, NULL);
917+ TEST_ALLOC_PARENT (my_output, proxy);
918+ TEST_EQ_STR (my_output, "True");
919+
920+ called = 1;
921+ }
922+
923+ while (! called)
924+ dbus_connection_read_write_dispatch (conn, -1);
925+
926+ nih_free (proxy);
927+
928+ my_teardown (conn);
929+
930+
931+ /* Check that an output argument of Boolean type is marshalled
932+ * correctly.
933+ */
934+ TEST_FEATURE ("with Boolean output argument");
935+ conn = my_setup ();
936+ proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
937+
938+ boolean_arg = TRUE;
939+
940+ ret = proxy_str_to_boolean (proxy, "False", &boolean_arg);
941+
942+ TEST_EQ (ret, 0);
943+
944+ TEST_EQ (boolean_arg, FALSE);
945+
946+ nih_free (proxy);
947+
948+ my_teardown (conn);
949+
950+
951+ /* Check that an output argument of Boolean type is marshalled
952+ * correctly for asynchronous calls.
953+ */
954+ TEST_FEATURE ("with Boolean output argument (async)");
955+ conn = my_setup ();
956+ proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
957+
958+ auto void with_boolean_output_argument (NihDBusProxy *my_proxy, char *userdata, typeof(boolean_arg) my_boolean_arg);
959+
960+ called = 0;
961+
962+ ret = proxy_str_to_boolean_async (proxy, "False", (ProxyStrToBooleanCallback)with_boolean_output_argument, async_fail_errback, "user data");
963+
964+ TEST_EQ (ret, 0);
965+
966+ void with_boolean_output_argument (NihDBusProxy *my_proxy, char *userdata, typeof(boolean_arg) my_boolean_arg)
967+ {
968+ TEST_EQ_P (my_proxy, proxy);
969+ TEST_EQ_STR (userdata, "user data");
970+ TEST_EQ (my_boolean_arg, 0);
971+ called = 1;
972+ }
973+
974+ while (! called)
975+ dbus_connection_read_write_dispatch (conn, -1);
976+
977+ nih_free (proxy);
978+
979+ my_teardown (conn);
980+
981+
982+ /* Check that an input argument of Int16 type is dispatched
983+ * correctly.
984+ */
985+ TEST_FEATURE ("with Int16 input argument");
986+ conn = my_setup ();
987+ proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
988+
989+ output = NULL;
990+
991+ ret = proxy_int16_to_str (proxy, 1701, &output);
992+
993+ TEST_EQ (ret, 0);
994+
995+ TEST_NE_P (output, NULL);
996+ TEST_ALLOC_PARENT (output, proxy);
997+ TEST_EQ_STR (output, "1701");
998+
999+ nih_free (proxy);
1000+
1001+ my_teardown (conn);
1002+
1003+
1004+ /* Check that an input argument of Int16 type is dispatched
1005+ * correctly from an asynchronous call.
1006+ */
1007+ TEST_FEATURE ("with Int16 input argument (async)");
1008+ conn = my_setup ();
1009+ proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
1010+
1011+ auto void with_int16_input_argument (NihDBusProxy *proxy, char *userdata, char *output);
1012+
1013+ called = 0;
1014+ ret = proxy_int16_to_str_async (proxy, 1701, (ProxyInt16ToStrCallback)with_int16_input_argument, async_fail_errback, "user data");
1015+
1016+ TEST_EQ (ret, 0);
1017+
1018+ void with_int16_input_argument (NihDBusProxy *my_proxy, char *userdata, char *my_output)
1019+ {
1020+ TEST_EQ_STR (userdata, "user data");
1021+ TEST_EQ_P (my_proxy, proxy);
1022+ TEST_NE_P (my_output, NULL);
1023+ TEST_ALLOC_PARENT (my_output, proxy);
1024+ TEST_EQ_STR (my_output, "1701");
1025+ called = 1;
1026+ }
1027+
1028+ while (! called)
1029+ dbus_connection_read_write_dispatch (conn, -1);
1030+
1031+ nih_free (proxy);
1032+
1033+ my_teardown (conn);
1034+
1035+
1036+ /* Check that an output argument of Int16 type is marshalled
1037+ * correctly.
1038+ */
1039+ TEST_FEATURE ("with Int16 output argument");
1040+ conn = my_setup ();
1041+ proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
1042+
1043+ int16_arg = 0;
1044+
1045+ ret = proxy_str_to_int16 (proxy, "1701", &int16_arg);
1046+
1047+ TEST_EQ (ret, 0);
1048+
1049+ TEST_EQ (int16_arg, 1701);
1050+
1051+ nih_free (proxy);
1052+
1053+ my_teardown (conn);
1054+
1055+
1056+ /* Check that an output argument of Int16 type is marshalled
1057+ * correctly for asynchronous calls.
1058+ */
1059+ TEST_FEATURE ("with Int16 output argument (async)");
1060+ conn = my_setup ();
1061+ proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
1062+
1063+ auto void with_int16_output_argument (NihDBusProxy *my_proxy, char *userdata, typeof(int16_arg) my_int16_arg);
1064+
1065+ called = 0;
1066+
1067+ ret = proxy_str_to_int16_async (proxy, "65", (ProxyStrToInt16Callback)with_int16_output_argument, async_fail_errback, "user data");
1068+
1069+ TEST_EQ (ret, 0);
1070+
1071+ void with_int16_output_argument (NihDBusProxy *my_proxy, char *userdata, typeof(int16_arg) my_int16_arg)
1072+ {
1073+ TEST_EQ_P (my_proxy, proxy);
1074+ TEST_EQ_STR (userdata, "user data");
1075+ TEST_EQ (my_int16_arg, 65);
1076+ called = 1;
1077+ }
1078+
1079+ while (! called)
1080+ dbus_connection_read_write_dispatch (conn, -1);
1081+
1082+ nih_free (proxy);
1083+
1084+ my_teardown (conn);
1085+
1086+
1087+ /* Check that an input argument of UInt16 type is dispatched
1088+ * correctly.
1089+ */
1090+ TEST_FEATURE ("with UInt16 input argument");
1091+ conn = my_setup ();
1092+ proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
1093+
1094+ output = NULL;
1095+
1096+ ret = proxy_uint16_to_str (proxy, 1701, &output);
1097+
1098+ TEST_EQ (ret, 0);
1099+
1100+ TEST_NE_P (output, NULL);
1101+ TEST_ALLOC_PARENT (output, proxy);
1102+ TEST_EQ_STR (output, "1701");
1103+
1104+ nih_free (proxy);
1105+
1106+ my_teardown (conn);
1107+
1108+
1109+ /* Check that an input argument of UInt16 type is dispatched
1110+ * correctly for an asynchronous call.
1111+ */
1112+ TEST_FEATURE ("with UInt16 input argument (async)");
1113+ conn = my_setup ();
1114+ proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
1115+
1116+ auto void with_uint16_input_argument (NihDBusProxy *proxy, char *userdata, char *output);
1117+
1118+ called = 0;
1119+ ret = proxy_uint16_to_str_async (proxy, 1701, (ProxyUint16ToStrCallback)with_uint16_input_argument, async_fail_errback, "user data" );
1120+
1121+ TEST_EQ (ret, 0);
1122+
1123+ void with_uint16_input_argument (NihDBusProxy *my_proxy, char *userdata, char *my_output)
1124+ {
1125+ TEST_EQ_STR (userdata, "user data");
1126+ TEST_EQ_P (my_proxy, proxy);
1127+ TEST_NE_P (my_output, NULL);
1128+ TEST_ALLOC_PARENT (my_output, proxy);
1129+ TEST_EQ_STR (my_output, "1701");
1130+ called = 1;
1131+ }
1132+
1133+ while (! called)
1134+ dbus_connection_read_write_dispatch (conn, -1);
1135+
1136+ nih_free (proxy);
1137+
1138+ my_teardown (conn);
1139+
1140+
1141+ /* Check that an output argument of UInt16 type is marshalled
1142+ * correctly.
1143+ */
1144+ TEST_FEATURE ("with UInt16 output argument");
1145+ conn = my_setup ();
1146+ proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
1147+
1148+ uint16_arg = 0;
1149+
1150+ ret = proxy_str_to_uint16 (proxy, "1701", &uint16_arg);
1151+
1152+ TEST_EQ (ret, 0);
1153+
1154+ TEST_EQ (uint16_arg, 1701);
1155+
1156+ nih_free (proxy);
1157+
1158+ my_teardown (conn);
1159+
1160+
1161+ /* Check that an output argument of UInt16 type is marshalled
1162+ * correctly for asynchronous calls.
1163+ */
1164+ TEST_FEATURE ("with UInt16 output argument (async)");
1165+ conn = my_setup ();
1166+ proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
1167+
1168+ auto void with_uint16_output_argument (NihDBusProxy *my_proxy, char *userdata, typeof(uint16_arg) my_uint16_arg);
1169+
1170+ called = 0;
1171+
1172+ ret = proxy_str_to_uint16_async (proxy, "65", (ProxyStrToUint16Callback)with_uint16_output_argument, async_fail_errback, "user data");
1173+
1174+ TEST_EQ (ret, 0);
1175+
1176+ void with_uint16_output_argument (NihDBusProxy *my_proxy, char *userdata, typeof(uint16_arg) my_uint16_arg)
1177+ {
1178+ TEST_EQ_P (my_proxy, proxy);
1179+ TEST_EQ_STR (userdata, "user data");
1180+ TEST_EQ (my_uint16_arg, 65);
1181+ called = 1;
1182+ }
1183+
1184+ while (! called)
1185+ dbus_connection_read_write_dispatch (conn, -1);
1186+
1187+ nih_free (proxy);
1188+
1189+ my_teardown (conn);
1190+
1191+
1192+ /* Check that an input argument of Int32 type is dispatched
1193+ * correctly.
1194+ */
1195+ TEST_FEATURE ("with Int32 input argument");
1196+ conn = my_setup ();
1197+ proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
1198+
1199+ output = NULL;
1200+
1201+ ret = proxy_int32_to_str (proxy, 1701, &output);
1202+
1203+ TEST_EQ (ret, 0);
1204+
1205+ TEST_NE_P (output, NULL);
1206+ TEST_ALLOC_PARENT (output, proxy);
1207+ TEST_EQ_STR (output, "1701");
1208+
1209+ nih_free (proxy);
1210+
1211+ my_teardown (conn);
1212+
1213+
1214+ /* Check that an input argument of Int32 type is dispatched
1215+ * correctly during an asynchronous call.
1216+ */
1217+ TEST_FEATURE ("with Int32 input argument (async)");
1218+ conn = my_setup ();
1219+ proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
1220+
1221+ auto void with_int32_input_argument (NihDBusProxy *proxy, char *userdata, char *output);
1222+
1223+ called = 0;
1224+ ret = proxy_int32_to_str_async (proxy, 1701, (ProxyInt32ToStrCallback)with_int32_input_argument, async_fail_errback, "user data");
1225+
1226+ TEST_EQ (ret, 0);
1227+
1228+ void with_int32_input_argument (NihDBusProxy *my_proxy, char *userdata, char *my_output)
1229+ {
1230+ TEST_EQ_STR (userdata, "user data");
1231+ TEST_EQ_P (my_proxy, proxy);
1232+ TEST_NE_P (my_output, NULL);
1233+ TEST_ALLOC_PARENT (my_output, proxy);
1234+ TEST_EQ_STR (my_output, "1701");
1235+ called = 1;
1236+ }
1237+
1238+ while (! called)
1239+ dbus_connection_read_write_dispatch (conn, -1);
1240+
1241+ nih_free (proxy);
1242+
1243+ my_teardown (conn);
1244+
1245+
1246+ /* Check that an output argument of Int32 type is marshalled
1247+ * correctly.
1248+ */
1249+ TEST_FEATURE ("with Int32 output argument");
1250+ conn = my_setup ();
1251+ proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
1252+
1253+ int32_arg = 0;
1254+
1255+ ret = proxy_str_to_int32 (proxy, "1701", &int32_arg);
1256+
1257+ TEST_EQ (ret, 0);
1258+
1259+ TEST_EQ (int32_arg, 1701);
1260+
1261+ nih_free (proxy);
1262+
1263+ my_teardown (conn);
1264+
1265+
1266+ /* Check that an output argument of Int32 type is marshalled
1267+ * correctly for asynchronous calls.
1268+ */
1269+ TEST_FEATURE ("with Int32 output argument (async)");
1270+ conn = my_setup ();
1271+ proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
1272+
1273+ auto void with_int32_output_argument (NihDBusProxy *my_proxy, char *userdata, typeof(int32_arg) my_int32_arg);
1274+
1275+ called = 0;
1276+
1277+ ret = proxy_str_to_int32_async (proxy, "65", (ProxyStrToInt32Callback)with_int32_output_argument, async_fail_errback, "user data");
1278+
1279+ TEST_EQ (ret, 0);
1280+
1281+ void with_int32_output_argument (NihDBusProxy *my_proxy, char *userdata, typeof(int32_arg) my_int32_arg)
1282+ {
1283+ TEST_EQ_P (my_proxy, proxy);
1284+ TEST_EQ_STR (userdata, "user data");
1285+ TEST_EQ (my_int32_arg, 65);
1286+ called = 1;
1287+ }
1288+
1289+ while (! called)
1290+ dbus_connection_read_write_dispatch (conn, -1);
1291+
1292+ nih_free (proxy);
1293+
1294+ my_teardown (conn);
1295+
1296+
1297+ /* Check that an input argument of UInt32 type is dispatched
1298+ * correctly.
1299+ */
1300+ TEST_FEATURE ("with UInt32 input argument");
1301+ conn = my_setup ();
1302+ proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
1303+
1304+ output = NULL;
1305+
1306+ ret = proxy_uint32_to_str (proxy, 1701, &output);
1307+
1308+ TEST_EQ (ret, 0);
1309+
1310+ TEST_NE_P (output, NULL);
1311+ TEST_ALLOC_PARENT (output, proxy);
1312+ TEST_EQ_STR (output, "1701");
1313+
1314+ nih_free (proxy);
1315+
1316+ my_teardown (conn);
1317+
1318+
1319+ /* Check that an input argument of UInt32 type is dispatched
1320+ * correctly for an asynchronous call.
1321+ */
1322+ TEST_FEATURE ("with UInt32 input argument (async)");
1323+ conn = my_setup ();
1324+ proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
1325+
1326+ auto void with_uint32_input_argument (NihDBusProxy *proxy, char *userdata, char *output);
1327+
1328+ called = 0;
1329+ ret = proxy_uint32_to_str_async (proxy, 1701, (ProxyUint32ToStrCallback)with_uint32_input_argument, async_fail_errback, "user data" );
1330+
1331+ TEST_EQ (ret, 0);
1332+
1333+ void with_uint32_input_argument (NihDBusProxy *my_proxy, char *userdata, char *my_output)
1334+ {
1335+ TEST_EQ_STR (userdata, "user data");
1336+ TEST_EQ_P (my_proxy, proxy);
1337+ TEST_NE_P (my_output, NULL);
1338+ TEST_ALLOC_PARENT (my_output, proxy);
1339+ TEST_EQ_STR (my_output, "1701");
1340+ called = 1;
1341+ }
1342+
1343+ while (! called)
1344+ dbus_connection_read_write_dispatch (conn, -1);
1345+
1346+ nih_free (proxy);
1347+
1348+ my_teardown (conn);
1349+
1350+
1351+ /* Check that an output argument of UInt32 type is marshalled
1352+ * correctly.
1353+ */
1354+ TEST_FEATURE ("with UInt32 output argument");
1355+ conn = my_setup ();
1356+ proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
1357+
1358+ uint32_arg = 0;
1359+
1360+ ret = proxy_str_to_uint32 (proxy, "1701", &uint32_arg);
1361+
1362+ TEST_EQ (ret, 0);
1363+
1364+ TEST_EQ (uint32_arg, 1701);
1365+
1366+ nih_free (proxy);
1367+
1368+ my_teardown (conn);
1369+
1370+
1371+ /* Check that an output argument of UInt32 type is marshalled
1372+ * correctly for asynchronous calls.
1373+ */
1374+ TEST_FEATURE ("with UInt32 output argument (async)");
1375+ conn = my_setup ();
1376+ proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
1377+
1378+ auto void with_uint32_output_argument (NihDBusProxy *my_proxy, char *userdata, typeof(uint32_arg) my_uint32_arg);
1379+
1380+ called = 0;
1381+
1382+ ret = proxy_str_to_uint32_async (proxy, "65", (ProxyStrToUint32Callback)with_uint32_output_argument, async_fail_errback, "user data");
1383+
1384+ TEST_EQ (ret, 0);
1385+
1386+ void with_uint32_output_argument (NihDBusProxy *my_proxy, char *userdata, typeof(uint32_arg) my_uint32_arg)
1387+ {
1388+ TEST_EQ_P (my_proxy, proxy);
1389+ TEST_EQ_STR (userdata, "user data");
1390+ TEST_EQ (my_uint32_arg, 65);
1391+ called = 1;
1392+ }
1393+
1394+ while (! called)
1395+ dbus_connection_read_write_dispatch (conn, -1);
1396+
1397+ nih_free (proxy);
1398+
1399+ my_teardown (conn);
1400+
1401+
1402+ /* Check that an input argument of Int64 type is dispatched
1403+ * correctly.
1404+ */
1405+ TEST_FEATURE ("with Int64 input argument");
1406+ conn = my_setup ();
1407+ proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
1408+
1409+ output = NULL;
1410+
1411+ ret = proxy_int64_to_str (proxy, 1701, &output);
1412+
1413+ TEST_EQ (ret, 0);
1414+
1415+ TEST_NE_P (output, NULL);
1416+ TEST_ALLOC_PARENT (output, proxy);
1417+ TEST_EQ_STR (output, "1701");
1418+
1419+ nih_free (proxy);
1420+
1421+ my_teardown (conn);
1422+
1423+
1424+ /* Check that an input argument of Int64 type is dispatched
1425+ * correctly for an asynchronous call.
1426+ */
1427+ TEST_FEATURE ("with Int64 input argument (async)");
1428+ conn = my_setup ();
1429+ proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
1430+
1431+ auto void with_int64_input_argument (NihDBusProxy *proxy, char *userdata, char *output);
1432+
1433+ called = 0;
1434+ ret = proxy_int64_to_str_async (proxy, 1701, (ProxyInt64ToStrCallback)with_int64_input_argument, async_fail_errback, "user data" );
1435+
1436+ TEST_EQ (ret, 0);
1437+
1438+ void with_int64_input_argument (NihDBusProxy *my_proxy, char *userdata, char *my_output)
1439+ {
1440+ TEST_EQ_STR (userdata, "user data");
1441+ TEST_EQ_P (my_proxy, proxy);
1442+ TEST_NE_P (my_output, NULL);
1443+ TEST_ALLOC_PARENT (my_output, proxy);
1444+ TEST_EQ_STR (my_output, "1701");
1445+ called = 1;
1446+ }
1447+
1448+ while (! called)
1449+ dbus_connection_read_write_dispatch (conn, -1);
1450+
1451+ nih_free (proxy);
1452+
1453+ my_teardown (conn);
1454+
1455+
1456+ /* Check that an output argument of Int64 type is marshalled
1457+ * correctly.
1458+ */
1459+ TEST_FEATURE ("with Int64 output argument");
1460+ conn = my_setup ();
1461+ proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
1462+
1463+ int64_arg = 0;
1464+
1465+ ret = proxy_str_to_int64 (proxy, "1701", &int64_arg);
1466+
1467+ TEST_EQ (ret, 0);
1468+
1469+ TEST_EQ (int64_arg, 1701);
1470+
1471+ nih_free (proxy);
1472+
1473+ my_teardown (conn);
1474+
1475+
1476+ /* Check that an output argument of Int64 type is marshalled
1477+ * correctly for asynchronous calls.
1478+ */
1479+ TEST_FEATURE ("with Int64 output argument (async)");
1480+ conn = my_setup ();
1481+ proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
1482+
1483+ auto void with_int64_output_argument (NihDBusProxy *my_proxy, char *userdata, typeof(int64_arg) my_int64_arg);
1484+
1485+ called = 0;
1486+
1487+ ret = proxy_str_to_int64_async (proxy, "65", (ProxyStrToInt64Callback)with_int64_output_argument, async_fail_errback, "user data");
1488+
1489+ TEST_EQ (ret, 0);
1490+
1491+ void with_int64_output_argument (NihDBusProxy *my_proxy, char *userdata, typeof(int64_arg) my_int64_arg)
1492+ {
1493+ TEST_EQ_P (my_proxy, proxy);
1494+ TEST_EQ_STR (userdata, "user data");
1495+ TEST_EQ (my_int64_arg, 65);
1496+ called = 1;
1497+ }
1498+
1499+ while (! called)
1500+ dbus_connection_read_write_dispatch (conn, -1);
1501+
1502+ nih_free (proxy);
1503+
1504+ my_teardown (conn);
1505+
1506+
1507+ /* Check that an input argument of UInt64 type is dispatched
1508+ * correctly.
1509+ */
1510+ TEST_FEATURE ("with UInt64 input argument");
1511+ conn = my_setup ();
1512+ proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
1513+
1514+ output = NULL;
1515+
1516+ ret = proxy_uint64_to_str (proxy, 1701, &output);
1517+
1518+ TEST_EQ (ret, 0);
1519+
1520+ TEST_NE_P (output, NULL);
1521+ TEST_ALLOC_PARENT (output, proxy);
1522+ TEST_EQ_STR (output, "1701");
1523+
1524+ nih_free (proxy);
1525+
1526+ my_teardown (conn);
1527+
1528+
1529+ /* Check that an input argument of UInt64 type is dispatched
1530+ * correctly for an asynchronous call.
1531+ */
1532+ TEST_FEATURE ("with UInt64 input argument (async)");
1533+ conn = my_setup ();
1534+ proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
1535+
1536+ auto void with_uint64_input_argument (NihDBusProxy *proxy, char *userdata, char *output);
1537+
1538+ called = 0;
1539+ ret = proxy_uint64_to_str_async (proxy, 1701, (ProxyUint64ToStrCallback)with_uint64_input_argument, async_fail_errback, "user data" );
1540+
1541+ TEST_EQ (ret, 0);
1542+
1543+ void with_uint64_input_argument (NihDBusProxy *my_proxy, char *userdata, char *my_output)
1544+ {
1545+ TEST_EQ_STR (userdata, "user data");
1546+ TEST_EQ_P (my_proxy, proxy);
1547+ TEST_NE_P (my_output, NULL);
1548+ TEST_ALLOC_PARENT (my_output, proxy);
1549+ TEST_EQ_STR (my_output, "1701");
1550+ called = 1;
1551+ }
1552+
1553+ while (! called)
1554+ dbus_connection_read_write_dispatch (conn, -1);
1555+
1556+ nih_free (proxy);
1557+
1558+ my_teardown (conn);
1559+
1560+
1561+ /* Check that an output argument of UInt64 type is marshalled
1562+ * correctly.
1563+ */
1564+ TEST_FEATURE ("with UInt64 output argument");
1565+ conn = my_setup ();
1566+ proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
1567+
1568+ uint64_arg = 0;
1569+
1570+ ret = proxy_str_to_uint64 (proxy, "1701", &uint64_arg);
1571+
1572+ TEST_EQ (ret, 0);
1573+
1574+ TEST_EQ (uint64_arg, 1701);
1575+
1576+ nih_free (proxy);
1577+
1578+ my_teardown (conn);
1579+
1580+
1581+ /* Check that an output argument of UInt64 type is marshalled
1582+ * correctly for asynchronous calls.
1583+ */
1584+ TEST_FEATURE ("with UInt64 output argument (async)");
1585+ conn = my_setup ();
1586+ proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
1587+
1588+ auto void with_uint64_output_argument (NihDBusProxy *my_proxy, char *userdata, typeof(uint64_arg) my_uint64_arg);
1589+
1590+ called = 0;
1591+
1592+ ret = proxy_str_to_uint64_async (proxy, "65", (ProxyStrToUint64Callback)with_uint64_output_argument, async_fail_errback, "user data");
1593+
1594+ TEST_EQ (ret, 0);
1595+
1596+ void with_uint64_output_argument (NihDBusProxy *my_proxy, char *userdata, typeof(uint64_arg) my_uint64_arg)
1597+ {
1598+ TEST_EQ_P (my_proxy, proxy);
1599+ TEST_EQ_STR (userdata, "user data");
1600+ TEST_EQ (my_uint64_arg, 65);
1601+ called = 1;
1602+ }
1603+
1604+ while (! called)
1605+ dbus_connection_read_write_dispatch (conn, -1);
1606+
1607+ nih_free (proxy);
1608+
1609+ my_teardown (conn);
1610+
1611+
1612+ /* Check that an input argument of Double type is dispatched
1613+ * correctly.
1614+ */
1615+ TEST_FEATURE ("with Double input argument");
1616+ conn = my_setup ();
1617+ proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
1618+
1619+ output = NULL;
1620+
1621+ ret = proxy_double_to_str (proxy, 3.141592, &output);
1622+
1623+ TEST_EQ (ret, 0);
1624+
1625+ TEST_NE_P (output, NULL);
1626+ TEST_ALLOC_PARENT (output, proxy);
1627+ TEST_EQ_STR (output, "3.141592");
1628+
1629+ nih_free (proxy);
1630+
1631+ my_teardown (conn);
1632+
1633+
1634+ /* Check that an input argument of Double type is dispatched
1635+ * correctly for an asynchronous call.
1636+ */
1637+ TEST_FEATURE ("with Double input argument (async)");
1638+ conn = my_setup ();
1639+ proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
1640+
1641+ auto void with_double_input_argument (NihDBusProxy *proxy, char *userdata, char *output);
1642+
1643+ called = 0;
1644+ ret = proxy_double_to_str_async (proxy, 3.141592, (ProxyDoubleToStrCallback)with_double_input_argument, async_fail_errback, "user data" );
1645+
1646+ TEST_EQ (ret, 0);
1647+
1648+ void with_double_input_argument (NihDBusProxy *my_proxy, char *userdata, char *my_output)
1649+ {
1650+ TEST_EQ_STR (userdata, "user data");
1651+ TEST_EQ_P (my_proxy, proxy);
1652+ TEST_NE_P (my_output, NULL);
1653+ TEST_ALLOC_PARENT (my_output, proxy);
1654+ TEST_EQ_STR (my_output, "3.141592");
1655+ called = 1;
1656+ }
1657+
1658+ while (! called)
1659+ dbus_connection_read_write_dispatch (conn, -1);
1660+
1661+ nih_free (proxy);
1662+
1663+ my_teardown (conn);
1664+
1665+
1666+ /* Check that an output argument of Double type is marshalled
1667+ * correctly.
1668+ */
1669+ TEST_FEATURE ("with Double output argument");
1670+ conn = my_setup ();
1671+ proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
1672+
1673+ double_arg = 0;
1674+
1675+ ret = proxy_str_to_double (proxy, "3.141592", &double_arg);
1676+
1677+ TEST_EQ (ret, 0);
1678+
1679+ TEST_EQ (double_arg, 3.141592);
1680+
1681+ nih_free (proxy);
1682+
1683+ my_teardown (conn);
1684+
1685+
1686+ /* Check that an output argument of Double type is marshalled
1687+ * correctly for asynchronous calls.
1688+ */
1689+ TEST_FEATURE ("with Double output argument (async)");
1690+ conn = my_setup ();
1691+ proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
1692+
1693+ auto void with_double_output_argument (NihDBusProxy *my_proxy, char *userdata, typeof(double_arg) my_double_arg);
1694+
1695+ called = 0;
1696+
1697+ ret = proxy_str_to_double_async (proxy, "3.141592", (ProxyStrToDoubleCallback)with_double_output_argument, async_fail_errback, "user data");
1698+
1699+ TEST_EQ (ret, 0);
1700+
1701+ void with_double_output_argument (NihDBusProxy *my_proxy, char *userdata, typeof(double_arg) my_double_arg)
1702+ {
1703+ TEST_EQ_P (my_proxy, proxy);
1704+ TEST_EQ_STR (userdata, "user data");
1705+ TEST_EQ (my_double_arg, 3.141592);
1706+ called = 1;
1707+ }
1708+
1709+ while (! called)
1710+ dbus_connection_read_write_dispatch (conn, -1);
1711+
1712+ nih_free (proxy);
1713+
1714+ my_teardown (conn);
1715+
1716+
1717+ /* Check that an input argument of ObjectPath type is dispatched
1718+ * correctly.
1719+ */
1720+ TEST_FEATURE ("with ObjectPath input argument");
1721+ conn = my_setup ();
1722+ proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
1723+
1724+ output = NULL;
1725+
1726+ ret = proxy_object_path_to_str (proxy, "/com/netsplit/Nih", &output);
1727+
1728+ TEST_EQ (ret, 0);
1729+
1730+ TEST_NE_P (output, NULL);
1731+ TEST_ALLOC_PARENT (output, proxy);
1732+ TEST_EQ_STR (output, "/com/netsplit/Nih");
1733+
1734+ nih_free (proxy);
1735+
1736+ my_teardown (conn);
1737+
1738+
1739+ /* Check that an input argument of ObjectPath type is dispatched
1740+ * correctly for an asynchronous call.
1741+ */
1742+ TEST_FEATURE ("with ObjectPath input argument (async)");
1743+ conn = my_setup ();
1744+ proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
1745+
1746+ auto void with_object_path_input_argument (NihDBusProxy *proxy, char *userdata, char *output);
1747+
1748+ called = 0;
1749+ ret = proxy_object_path_to_str_async (proxy, "/com/netsplit/Nih", (ProxyObjectPathToStrCallback)with_object_path_input_argument, async_fail_errback, "user data" );
1750+
1751+ TEST_EQ (ret, 0);
1752+
1753+ void with_object_path_input_argument (NihDBusProxy *my_proxy, char *userdata, char *my_output)
1754+ {
1755+ TEST_EQ_STR (userdata, "user data");
1756+ TEST_EQ_P (my_proxy, proxy);
1757+ TEST_NE_P (my_output, NULL);
1758+ TEST_ALLOC_PARENT (my_output, proxy);
1759+ TEST_EQ_STR (my_output, "/com/netsplit/Nih");
1760+ called = 1;
1761+ }
1762+
1763+ while (! called)
1764+ dbus_connection_read_write_dispatch (conn, -1);
1765+
1766+ nih_free (proxy);
1767+
1768+ my_teardown (conn);
1769+
1770+
1771+ /* Check that an output argument of ObjectPath type is marshalled
1772+ * correctly.
1773+ */
1774+ TEST_FEATURE ("with ObjectPath output argument");
1775+ conn = my_setup ();
1776+ proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
1777+
1778+ output = NULL;
1779+
1780+ ret = proxy_str_to_object_path (proxy, "/com/netsplit/Nih", &output);
1781+
1782+ TEST_EQ (ret, 0);
1783+
1784+ TEST_NE_P (output, NULL);
1785+ TEST_ALLOC_PARENT (output, proxy);
1786+ TEST_EQ_STR (output, "/com/netsplit/Nih");
1787+
1788+ nih_free (proxy);
1789+
1790+ my_teardown (conn);
1791+
1792+
1793+ /* Check that an output argument of ObjectPath type is marshalled
1794+ * correctly for asynchronous calls.
1795+ */
1796+ TEST_FEATURE ("with ObjectPath output argument (async)");
1797+ conn = my_setup ();
1798+ proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
1799+
1800+ auto void with_object_path_output_argument (NihDBusProxy *my_proxy, char *userdata, char *my_object_path_arg);
1801+
1802+ called = 0;
1803+
1804+ ret = proxy_str_to_object_path_async (proxy, "/com/netsplit/Nih", (ProxyStrToObjectPathCallback)with_object_path_output_argument, async_fail_errback, "user data");
1805+
1806+ TEST_EQ (ret, 0);
1807+
1808+ void with_object_path_output_argument (NihDBusProxy *my_proxy, char *userdata, char *my_object_path_arg)
1809+ {
1810+ TEST_EQ_P (my_proxy, proxy);
1811+ TEST_EQ_STR (userdata, "user data");
1812+ TEST_NE_P (my_object_path_arg, NULL);
1813+ TEST_ALLOC_PARENT (my_object_path_arg, proxy);
1814+ TEST_EQ_STR (my_object_path_arg, "/com/netsplit/Nih");
1815+ called = 1;
1816+ }
1817+
1818+ while (! called)
1819+ dbus_connection_read_write_dispatch (conn, -1);
1820+
1821+ nih_free (proxy);
1822+
1823+ my_teardown (conn);
1824+
1825+
1826+ /* Check that an input argument of Signature type is dispatched
1827+ * correctly.
1828+ */
1829+ TEST_FEATURE ("with Signature input argument");
1830+ conn = my_setup ();
1831+ proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
1832+
1833+ output = NULL;
1834+
1835+ ret = proxy_signature_to_str (proxy, "a{sv}", &output);
1836+
1837+ TEST_EQ (ret, 0);
1838+
1839+ TEST_NE_P (output, NULL);
1840+ TEST_ALLOC_PARENT (output, proxy);
1841+ TEST_EQ_STR (output, "a{sv}");
1842+
1843+ nih_free (proxy);
1844+
1845+ my_teardown (conn);
1846+
1847+
1848+ /* Check that an input argument of Signature type is dispatched
1849+ * correctly for an asynchronous call.
1850+ */
1851+ TEST_FEATURE ("with Signature input argument (async)");
1852+ conn = my_setup ();
1853+ proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
1854+
1855+ auto void with_signature_input_argument (NihDBusProxy *proxy, char *userdata, char *output);
1856+
1857+ called = 0;
1858+ ret = proxy_signature_to_str_async (proxy, "a{sv}", (ProxySignatureToStrCallback)with_signature_input_argument, async_fail_errback, "user data" );
1859+
1860+ TEST_EQ (ret, 0);
1861+
1862+ void with_signature_input_argument (NihDBusProxy *my_proxy, char *userdata, char *my_output)
1863+ {
1864+ TEST_EQ_STR (userdata, "user data");
1865+ TEST_EQ_P (my_proxy, proxy);
1866+ TEST_NE_P (my_output, NULL);
1867+ TEST_ALLOC_PARENT (my_output, proxy);
1868+ TEST_EQ_STR (my_output, "a{sv}");
1869+ called = 1;
1870+ }
1871+
1872+ while (! called)
1873+ dbus_connection_read_write_dispatch (conn, -1);
1874+
1875+ nih_free (proxy);
1876+
1877+ my_teardown (conn);
1878+
1879+
1880+ /* Check that an output argument of Signature type is marshalled
1881+ * correctly.
1882+ */
1883+ TEST_FEATURE ("with Signature output argument");
1884+ conn = my_setup ();
1885+ proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
1886+
1887+ output = NULL;
1888+
1889+ ret = proxy_str_to_signature (proxy, "a{sv}", &output);
1890+
1891+ TEST_EQ (ret, 0);
1892+
1893+ TEST_NE_P (output, NULL);
1894+ TEST_ALLOC_PARENT (output, proxy);
1895+ TEST_EQ_STR (output, "a{sv}");
1896+
1897+ nih_free (proxy);
1898+
1899+ my_teardown (conn);
1900+
1901+
1902+ /* Check that an output argument of Signature type is marshalled
1903+ * correctly for asynchronous calls.
1904+ */
1905+ TEST_FEATURE ("with Signature output argument (async)");
1906+ conn = my_setup ();
1907+ proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
1908+
1909+ auto void with_signature_output_argument (NihDBusProxy *my_proxy, char *userdata, char *my_signature_arg);
1910+
1911+ called = 0;
1912+
1913+ ret = proxy_str_to_signature_async (proxy, "a{sv}", (ProxyStrToSignatureCallback)with_signature_output_argument, async_fail_errback, "user data");
1914+
1915+ TEST_EQ (ret, 0);
1916+
1917+ void with_signature_output_argument (NihDBusProxy *my_proxy, char *userdata, char *my_signature_arg)
1918+ {
1919+ TEST_EQ_P (my_proxy, proxy);
1920+ TEST_EQ_STR (userdata, "user data");
1921+ TEST_NE_P (my_signature_arg, NULL);
1922+ TEST_ALLOC_PARENT (my_signature_arg, proxy);
1923+ TEST_EQ_STR (my_signature_arg, "a{sv}");
1924+ called = 1;
1925+ }
1926+
1927+ while (! called)
1928+ dbus_connection_read_write_dispatch (conn, -1);
1929+
1930+ nih_free (proxy);
1931+
1932+ my_teardown (conn);
1933+
1934+
1935+ /* Check that an input argument of Array type with Int32 members
1936+ * is dispatched correctly.
1937+ */
1938+ TEST_FEATURE ("with Int32 Array input argument");
1939+ conn = my_setup ();
1940+ proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
1941+
1942+ int32_array = nih_alloc (NULL, sizeof (int32_t) * 6);
1943+ int32_array[0] = 4;
1944+ int32_array[1] = 8;
1945+ int32_array[2] = 15;
1946+ int32_array[3] = 16;
1947+ int32_array[4] = 23;
1948+ int32_array[5] = 42;
1949+ array_len = 6;
1950+
1951+ output = NULL;
1952+
1953+ ret = proxy_int32_array_to_str (proxy, int32_array, array_len,
1954+ &output);
1955+
1956+ TEST_EQ (ret, 0);
1957+
1958+ TEST_NE_P (output, NULL);
1959+ TEST_ALLOC_PARENT (output, proxy);
1960+ TEST_EQ_STR (output, "4 8 15 16 23 42");
1961+
1962+ nih_free (proxy);
1963+ nih_free (int32_array);
1964+
1965+ my_teardown (conn);
1966+
1967+
1968+ /* Check that an input argument of Array type with Int32 members
1969+ * is dispatched correctly for asynchronous calls.
1970+ */
1971+ TEST_FEATURE ("with Int32 Array input argument (async)");
1972+ conn = my_setup ();
1973+ proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
1974+
1975+ auto void with_int_array_input_argument (NihDBusProxy *proxy, char *userdata, char *output);
1976+
1977+ int32_array = nih_alloc (NULL, sizeof (int32_t) * 6);
1978+ int32_array[0] = 4;
1979+ int32_array[1] = 8;
1980+ int32_array[2] = 15;
1981+ int32_array[3] = 16;
1982+ int32_array[4] = 23;
1983+ int32_array[5] = 42;
1984+ array_len = 6;
1985+
1986+ called = 0;
1987+ ret = proxy_int32_array_to_str_async (proxy, int32_array, array_len,
1988+ (ProxyInt32ArrayToStrCallback)with_int_array_input_argument, async_fail_errback,
1989+ "user data");
1990+
1991+ TEST_EQ (ret, 0);
1992+
1993+ void with_int_array_input_argument (NihDBusProxy *my_proxy, char *userdata, char *my_output)
1994+ {
1995+ TEST_EQ_STR (userdata, "user data");
1996+ TEST_EQ_P (my_proxy, proxy);
1997+ TEST_NE_P (my_output, NULL);
1998+ TEST_ALLOC_PARENT (my_output, proxy);
1999+ TEST_EQ_STR (my_output, "4 8 15 16 23 42");
2000+ called = 1;
2001+ }
2002+
2003+ while (! called)
2004+ dbus_connection_read_write_dispatch (conn, -1);
2005+
2006+ nih_free (proxy);
2007+ nih_free (int32_array);
2008+
2009+ my_teardown (conn);
2010+
2011+
2012+ /* Check that an output argument of Array type with Int32 members
2013+ * is marshalled correctly.
2014+ */
2015+ TEST_FEATURE ("with Int32 Array output argument");
2016+ conn = my_setup ();
2017+ proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
2018+
2019+ int32_array = NULL;
2020+ array_len = 0;
2021+
2022+ ret = proxy_str_to_int32_array (proxy, "4 8 15 16 23 42",
2023+ &int32_array, &array_len);
2024+
2025+ TEST_EQ (ret, 0);
2026+
2027+ TEST_NE_P (int32_array, NULL);
2028+ TEST_ALLOC_PARENT (int32_array, proxy);
2029+ TEST_EQ (array_len, 6);
2030+ TEST_EQ (int32_array[0], 4);
2031+ TEST_EQ (int32_array[1], 8);
2032+ TEST_EQ (int32_array[2], 15);
2033+ TEST_EQ (int32_array[3], 16);
2034+ TEST_EQ (int32_array[4], 23);
2035+ TEST_EQ (int32_array[5], 42);
2036+
2037+ nih_free (proxy);
2038+
2039+ my_teardown (conn);
2040+
2041+
2042+ /* Check that an output argument of Array type with Int32 members
2043+ * is marshalled correctly for asynchronous calls.
2044+ */
2045+ TEST_FEATURE ("with Int32 Array output argument (async)");
2046+ conn = my_setup ();
2047+ proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
2048+
2049+ auto void with_int_array_output_argument (NihDBusProxy *my_proxy, char *userdata, int *my_intarray, int my_len);
2050+
2051+ called = 0;
2052+ ret = proxy_str_to_int32_array_async (proxy, "4 8 15 16 23 42",
2053+ (ProxyStrToInt32ArrayCallback)with_int_array_output_argument, async_fail_errback, "user data");
2054+
2055+ TEST_EQ (ret, 0);
2056+
2057+ void with_int_array_output_argument (NihDBusProxy *my_proxy, char *userdata, int *my_intarray, int my_len)
2058+ {
2059+ TEST_EQ_STR (userdata, "user data");
2060+ TEST_EQ_P (my_proxy, proxy);
2061+ TEST_NE_P (my_intarray, NULL);
2062+ TEST_ALLOC_PARENT (my_intarray, proxy);
2063+ TEST_EQ (my_len, 6);
2064+ TEST_EQ (my_intarray[0], 4);
2065+ TEST_EQ (my_intarray[1], 8);
2066+ TEST_EQ (my_intarray[2], 15);
2067+ TEST_EQ (my_intarray[3], 16);
2068+ TEST_EQ (my_intarray[4], 23);
2069+ TEST_EQ (my_intarray[5], 42);
2070+ called = 1;
2071+ }
2072+
2073+ while (! called)
2074+ dbus_connection_read_write_dispatch (conn, -1);
2075+
2076+ nih_free (proxy);
2077+
2078+ my_teardown (conn);
2079+
2080+
2081+ /* Check that an input argument of Array type with String members
2082+ * is dispatched correctly.
2083+ */
2084+ TEST_FEATURE ("with String Array input argument");
2085+ conn = my_setup ();
2086+ proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
2087+
2088+ str_array = nih_alloc (NULL, sizeof (char *) * 5);
2089+ str_array[0] = "this";
2090+ str_array[1] = "is";
2091+ str_array[2] = "a";
2092+ str_array[3] = "test";
2093+ str_array[4] = NULL;
2094+
2095+ output = NULL;
2096+
2097+ ret = proxy_str_array_to_str (proxy, str_array, &output);
2098+
2099+ TEST_EQ (ret, 0);
2100+
2101+ TEST_NE_P (output, NULL);
2102+ TEST_ALLOC_PARENT (output, proxy);
2103+ TEST_EQ_STR (output, "this is a test");
2104+
2105+ nih_free (proxy);
2106+ nih_free (str_array);
2107+
2108+ my_teardown (conn);
2109+
2110+
2111+ /* Check that an input argument of Array type with String members
2112+ * is dispatched correctly for async calls.
2113+ */
2114+ TEST_FEATURE ("with String Array input argument (async)");
2115+ conn = my_setup ();
2116+ proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
2117+
2118+ auto void with_str_array_input_argument (NihDBusProxy *my_proxy, char *userdata, char *my_output);
2119+
2120+ str_array = nih_alloc (NULL, sizeof (char *) * 5);
2121+ str_array[0] = "this";
2122+ str_array[1] = "is";
2123+ str_array[2] = "a";
2124+ str_array[3] = "test";
2125+ str_array[4] = NULL;
2126+
2127+ called = 0;
2128+ ret = proxy_str_array_to_str_async (proxy, str_array, (ProxyStrArrayToStrCallback)with_str_array_input_argument, async_fail_errback, "user data");
2129+
2130+ TEST_EQ (ret, 0);
2131+
2132+ void with_str_array_input_argument (NihDBusProxy *my_proxy, char *userdata, char *my_output)
2133+ {
2134+ TEST_EQ_STR (userdata, "user data");
2135+ TEST_EQ_P (my_proxy, proxy);
2136+ TEST_NE_P (my_output, NULL);
2137+ TEST_ALLOC_PARENT (my_output, proxy);
2138+ TEST_EQ_STR (my_output, "this is a test");
2139+ called = 1;
2140+ }
2141+
2142+ while (! called)
2143+ dbus_connection_read_write_dispatch (conn, -1);
2144+
2145+ nih_free (proxy);
2146+ nih_free (str_array);
2147+
2148+ my_teardown (conn);
2149+
2150+
2151+ /* Check that an output argument of Array type with String members
2152+ * is marshalled correctly.
2153+ */
2154+ TEST_FEATURE ("with String Array output argument");
2155+ conn = my_setup ();
2156+ proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
2157+
2158+ str_array = NULL;
2159+
2160+ ret = proxy_str_to_str_array (proxy, "this is a test", &str_array);
2161+
2162+ TEST_EQ (ret, 0);
2163+
2164+ TEST_NE_P (str_array, NULL);
2165+ TEST_ALLOC_PARENT (str_array, proxy);
2166+ TEST_EQ_STR (str_array[0], "this");
2167+ TEST_EQ_STR (str_array[1], "is");
2168+ TEST_EQ_STR (str_array[2], "a");
2169+ TEST_EQ_STR (str_array[3], "test");
2170+ TEST_EQ_P (str_array[4], NULL);
2171+
2172+ nih_free (proxy);
2173+
2174+ my_teardown (conn);
2175+
2176+
2177+ /* Check that an output argument of Array type with String members
2178+ * is marshalled correctly for asynchronous calls.
2179+ */
2180+ TEST_FEATURE ("with String Array output argument (async)");
2181+ conn = my_setup ();
2182+ proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
2183+
2184+ auto void with_str_array_output_argument (NihDBusProxy *my_proxy, char *userdata, char **my_str_array);
2185+
2186+ called = 0;
2187+
2188+ ret = proxy_str_to_str_array_async (proxy, "this is a test", (ProxyStrToStrArrayCallback)with_str_array_output_argument, async_fail_errback, "user data");
2189+
2190+ TEST_EQ (ret, 0);
2191+
2192+ void with_str_array_output_argument (NihDBusProxy *my_proxy, char *userdata, char **my_str_array)
2193+ {
2194+ TEST_EQ_STR (userdata, "user data");
2195+ TEST_EQ_P (my_proxy, proxy);
2196+ TEST_NE_P (my_str_array, NULL);
2197+ TEST_ALLOC_PARENT (my_str_array, proxy);
2198+ TEST_EQ_STR (my_str_array[0], "this");
2199+ TEST_EQ_STR (my_str_array[1], "is");
2200+ TEST_EQ_STR (my_str_array[2], "a");
2201+ TEST_EQ_STR (my_str_array[3], "test");
2202+ TEST_EQ_P (my_str_array[4], NULL);
2203+ called = 1;
2204+ }
2205+
2206+ while (! called)
2207+ dbus_connection_read_write_dispatch (conn, -1);
2208+
2209+ nih_free (proxy);
2210+
2211+ my_teardown (conn);
2212+}
2213+
2214+
2215+static void
2216+async_fail_errback (NihDBusProxy *my_proxy, void *userdata)
2217+{
2218+ TEST_FAILED ("Called wrong asynchronous handler");
2219+>>>>>>> MERGE-SOURCE
2220 }
2221
2222
2223
2224=== added file 'nih/nih_dbus_tool.py.OTHER'
2225--- nih/nih_dbus_tool.py.OTHER 1970-01-01 00:00:00 +0000
2226+++ nih/nih_dbus_tool.py.OTHER 2009-10-03 06:00:27 +0000
2227@@ -0,0 +1,2635 @@
2228+#!/usr/bin/env python
2229+# -*- coding: utf-8 -*-
2230+#
2231+# nih_dbus_tool.py - D-Bus binding generation tool
2232+#
2233+# Copyright © 2008 Scott James Remnant <scott@netsplit.com>.
2234+#
2235+# This program is free software; you can redistribute it and/or modify
2236+# it under the terms of the GNU General Public License as published by
2237+# the Free Software Foundation; either version 2 of the License, or
2238+# (at your option) any later version.
2239+#
2240+# This program is distributed in the hope that it will be useful,
2241+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2242+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2243+# GNU General Public License for more details.
2244+#
2245+# You should have received a copy of the GNU General Public License
2246+# along with this program; if not, write to the Free Software
2247+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
2248+
2249+import os
2250+import re
2251+import sys
2252+
2253+from optparse import OptionParser
2254+from xml.etree import ElementTree
2255+
2256+
2257+# Replaced by autoconf-obtained strings
2258+PACKAGE_NAME = "@PACKAGE_NAME@"
2259+PACKAGE_COPYRIGHT = "@PACKAGE_COPYRIGHT@"
2260+
2261+# Prefix for external functions
2262+extern_prefix = "dbus"
2263+
2264+# Generator mode
2265+mode = "object"
2266+
2267+
2268+# Conversion for external C names
2269+NAME_RE = re.compile(r'([a-z0-9])([A-Z])')
2270+
2271+# Namespace for our own tags and attributes
2272+XMLNS = "http://www.netsplit.com/nih/dbus"
2273+
2274+
2275+# arrays of arrays with length (ends up being an array of a struct)
2276+# - instead of using self.type.c_type and name, we should iterate
2277+# over its vars? -- array will have foo_elem and foo_elem_len
2278+#
2279+# struct type
2280+# variant type (at least fallback to requiring them to define the marshal?)
2281+ # - one way might be just to pass a container or fake message?
2282+
2283+# "proxy" mode:
2284+# async function dispatch
2285+# function dispatch with no reply
2286+# configurable timeout, autostart, etc. for function dispatch
2287+# signal marshal
2288+# - called when a signal we're expecting happens, will have a message
2289+# object and will call a handler with that -- need an object equivalent,
2290+# "proxy" likely
2291+
2292+
2293+class DBusType(object):
2294+ """D-Bus type.
2295+
2296+ This abstract class represents the base of all D-Bus types that we
2297+ can handle.
2298+ """
2299+
2300+ @classmethod
2301+ def fromElement(cls, elem):
2302+ name = elem.get("name")
2303+ if name is None:
2304+ raise AttributeError, "Argument name may not be null"
2305+
2306+ type = elem.get("type")
2307+ if type is None:
2308+ raise AttributeError, "Argument type may not be null"
2309+
2310+ direction = elem.get("direction", "in")
2311+ if direction not in ( "in", "out" ):
2312+ raise AttributeError, "Direction must be 'in' or 'out'"
2313+
2314+ type_cls = cls.typeOf(type)
2315+ return type_cls.fromArgument(name, direction)
2316+
2317+ @classmethod
2318+ def fromArgument(cls, name, direction="in"):
2319+ self = cls(name)
2320+ self.direction = direction
2321+
2322+ return self
2323+
2324+ def __init__(self, name):
2325+ self.name = name
2326+
2327+ @classmethod
2328+ def typeOf(cls, code):
2329+ """Return type for given type signature code."""
2330+ if code == "y":
2331+ return DBusByte
2332+ elif code == "b":
2333+ return DBusBoolean
2334+ elif code == "n":
2335+ return DBusInt16
2336+ elif code == "q":
2337+ return DBusUInt16
2338+ elif code == "i":
2339+ return DBusInt32
2340+ elif code == "u":
2341+ return DBusUInt32
2342+ elif code == "x":
2343+ return DBusInt64
2344+ elif code == "t":
2345+ return DBusUInt64
2346+ elif code == "d":
2347+ return DBusDouble
2348+ elif code == "s":
2349+ return DBusString
2350+ elif code == "o":
2351+ return DBusObjectPath
2352+ elif code == "g":
2353+ return DBusSignature
2354+ elif code[0] == "a":
2355+ return DBusArray.forType(cls.typeOf(code[-1]))
2356+ else:
2357+ raise AttributeError, "Unknown or unhandled type '%s'" % code
2358+
2359+ def realType(self, c_type, pointer=False, const=False):
2360+ """Real type.
2361+
2362+ Returns a string containing the C type name for this type, with
2363+ pointer and const modifications added.
2364+ """
2365+ if pointer:
2366+ c_type = pointerify(c_type)
2367+ if const:
2368+ c_type = constify(c_type)
2369+
2370+ return c_type
2371+
2372+ def signature(self, pointer=False, const=False):
2373+ """Type signature.
2374+
2375+ Returns a string containing the D-Bus type signature for this type.
2376+ """
2377+ return None
2378+
2379+ def vars(self, pointer=False, const=False):
2380+ """Variable type and name.
2381+
2382+ Returns a list containing a single tuple of the C type used for this
2383+ type and the name given when creating the instance.
2384+ """
2385+ return []
2386+
2387+ def names(self, pointer=False, const=False):
2388+ """Variable name.
2389+
2390+ Returns a list containing a single string; the name given when creating
2391+ the instance.
2392+ """
2393+ return []
2394+
2395+ def locals(self, pointer=False, const=False):
2396+ """Local variable type and name.
2397+
2398+ Returns a list containing necessary local variables for iteration
2399+ of this type.
2400+ """
2401+ return []
2402+
2403+ def marshal(self, iter_name, parent, type_error, mem_error,
2404+ pointer=False, const=False):
2405+ """Marshalling code.
2406+
2407+ Returns a string containing the code that will marshal from an
2408+ iterator with the name given into a local variable with the
2409+ type and name as returned by vars().
2410+ """
2411+ return None
2412+
2413+ def dispatch(self, iter_name, mem_error,
2414+ pointer=False, const=False):
2415+ """Dispatching code.
2416+
2417+ Returns a string containing the code that will dispatch from a
2418+ local variable with the type and name as returned by vars() to
2419+ an iterator with the name given.
2420+ """
2421+ return None
2422+
2423+
2424+class DBusBasicType(DBusType):
2425+ """D-Bus basic type.
2426+
2427+ This abstract class represents the base of all basic D-Bus types that
2428+ we can handle. These share the code to marshal from a DBusMessage into
2429+ a variable and dispatch from a variable back into a DBusMessage.
2430+ """
2431+
2432+ def signature(self, pointer=False, const=False):
2433+ """Type signature.
2434+
2435+ Returns a string containing the D-Bus type signature for this type.
2436+ """
2437+ return self.dbus_code
2438+
2439+ def vars(self, pointer=False, const=False):
2440+ """Variable type and name.
2441+
2442+ Returns a list containing a single tuple of the C type used for this
2443+ type and the name given when creating the instance.
2444+ """
2445+ return [ ( self.realType(self.c_type, pointer, const), self.name ) ]
2446+
2447+ def names(self, pointer=False, const=False):
2448+ """Variable name.
2449+
2450+ Returns a list containing a single string; the name given when creating
2451+ the instance.
2452+ """
2453+ return [ self.name ]
2454+
2455+ def locals(self, pointer=False, const=False):
2456+ """Local variable type and name.
2457+
2458+ Returns a list containing necessary local variables for iteration
2459+ of this type.
2460+ """
2461+ return []
2462+
2463+ def marshal(self, iter_name, parent, type_error, mem_error,
2464+ pointer=False, const=False):
2465+ """Marshalling code.
2466+
2467+ Returns a string containing the code that will marshal from an
2468+ iterator with the name given into a local variable with the
2469+ type and name as returned by vars().
2470+ """
2471+ name = self.name
2472+ if pointer:
2473+ name = "*%s" % (name, )
2474+
2475+ return """\
2476+if (dbus_message_iter_get_arg_type (&%s) != %s) {
2477+%s
2478+}
2479+
2480+dbus_message_iter_get_basic (&%s, &%s);
2481+
2482+dbus_message_iter_next (&%s);
2483+""" % (iter_name, self.dbus_type, type_error,
2484+ iter_name, name,
2485+ iter_name)
2486+
2487+ def dispatch(self, iter_name, mem_error,
2488+ pointer=False, const=False):
2489+ """Dispatching code.
2490+
2491+ Returns a string containing the code that will dispatch from a
2492+ local variable with the type and name as returned by vars() to
2493+ an iterator with the name given.
2494+ """
2495+ name = self.name
2496+ if pointer:
2497+ name = "*%s" % (name, )
2498+
2499+ return """\
2500+if (! dbus_message_iter_append_basic (&%s, %s, &%s)) {
2501+%s
2502+}
2503+""" % (iter_name, self.dbus_type, name, mem_error)
2504+
2505+
2506+class DBusByte(DBusBasicType):
2507+ """D-Bus byte.
2508+
2509+ This class represents the D-Bus byte type and should be instantiated with
2510+ the name of the variable. It shares marshalling and dispatch code with
2511+ the other basic types.
2512+ """
2513+ c_type = "uint8_t"
2514+ dbus_code = "y"
2515+ dbus_type = "DBUS_TYPE_BYTE"
2516+
2517+class DBusBoolean(DBusBasicType):
2518+ """D-Bus boolean.
2519+
2520+ This class represents the D-Bus boolean type and should be instantiated
2521+ with the name of the variable. It shares marshalling and dispatch code
2522+ with the other basic types.
2523+ """
2524+ c_type = "int"
2525+ dbus_code = "b"
2526+ dbus_type = "DBUS_TYPE_BOOLEAN"
2527+
2528+class DBusInt16(DBusBasicType):
2529+ """D-Bus 16-bit integer.
2530+
2531+ This class represents the D-Bus int16 type and should be instantiated with
2532+ the name of the variable. It shares marshalling and dispatch code with
2533+ the other basic types.
2534+ """
2535+ c_type = "int16_t"
2536+ dbus_code = "n"
2537+ dbus_type = "DBUS_TYPE_INT16"
2538+
2539+class DBusUInt16(DBusBasicType):
2540+ """D-Bus 16-bit unsigned integer.
2541+
2542+ This class represents the D-Bus uint16 type and should be instantiated with
2543+ the name of the variable. It shares marshalling and dispatch code with
2544+ the other basic types.
2545+ """
2546+ c_type = "uint16_t"
2547+ dbus_code = "q"
2548+ dbus_type = "DBUS_TYPE_UINT16"
2549+
2550+class DBusInt32(DBusBasicType):
2551+ """D-Bus 32-bit integer.
2552+
2553+ This class represents the D-Bus int32 type and should be instantiated with
2554+ the name of the variable. It shares marshalling and dispatch code with
2555+ the other basic types.
2556+ """
2557+ c_type = "int32_t"
2558+ dbus_code = "i"
2559+ dbus_type = "DBUS_TYPE_INT32"
2560+
2561+class DBusUInt32(DBusBasicType):
2562+ """D-Bus 32-bit unsigned integer.
2563+
2564+ This class represents the D-Bus uint32 type and should be instantiated with
2565+ the name of the variable. It shares marshalling and dispatch code with
2566+ the other basic types.
2567+ """
2568+ c_type = "uint32_t"
2569+ dbus_code = "u"
2570+ dbus_type = "DBUS_TYPE_UINT32"
2571+
2572+class DBusInt64(DBusBasicType):
2573+ """D-Bus 64-bit integer.
2574+
2575+ This class represents the D-Bus int64 type and should be instantiated with
2576+ the name of the variable. It shares marshalling and dispatch code with
2577+ the other basic types.
2578+ """
2579+ c_type = "int64_t"
2580+ dbus_code = "x"
2581+ dbus_type = "DBUS_TYPE_INT64"
2582+
2583+class DBusUInt64(DBusBasicType):
2584+ """D-Bus 64-bit unsigned integer.
2585+
2586+ This class represents the D-Bus uint64 type and should be instantiated with
2587+ the name of the variable. It shares marshalling and dispatch code with
2588+ the other basic types.
2589+ """
2590+ c_type = "uint64_t"
2591+ dbus_code = "t"
2592+ dbus_type = "DBUS_TYPE_UINT64"
2593+
2594+class DBusDouble(DBusBasicType):
2595+ """D-Bus double.
2596+
2597+ This class represents the D-Bus double type and should be instantiated
2598+ with the name of the variable. It shares marshalling and dispatch code
2599+ with the other basic types.
2600+ """
2601+ c_type = "double"
2602+ dbus_code = "d"
2603+ dbus_type = "DBUS_TYPE_DOUBLE"
2604+
2605+
2606+class DBusStringType(DBusBasicType):
2607+ """D-Bus string type.
2608+
2609+ This abstract class represents the base of all string-derived D-Bus types
2610+ that we can handle. These share the code to marshal from a DBusMessage
2611+ into a variable, the code to dispatch from a variable back into a
2612+ DBusMessage and the same basic C type.
2613+
2614+ They differ from the fundamental basic type in that the marshalled copy
2615+ of the string is not direct from the message, but an allocated copy;
2616+ this is because they cannot be simply passed by value, and may wish to
2617+ be stored.
2618+ """
2619+ c_type = "char *"
2620+
2621+ def locals(self, pointer=False, const=False):
2622+ """Local variable type and name.
2623+
2624+ Returns a list containing necessary local variables for iteration
2625+ of this type.
2626+ """
2627+ return [ ( self.realType(self.c_type, const=const),
2628+ "_".join((self.name, "value")) ) ]
2629+
2630+ def marshal(self, iter_name, parent, type_error, mem_error,
2631+ pointer=False, const=False):
2632+ """Marshalling code.
2633+
2634+ Returns a string containing the code that will marshal from an
2635+ iterator with the name given into a local variable with the
2636+ type and name as returned by vars().
2637+ """
2638+ name = self.name
2639+ if pointer:
2640+ name = "*%s" % (name, )
2641+
2642+ value_name = "_".join((self.name, "value"))
2643+
2644+ return """\
2645+if (dbus_message_iter_get_arg_type (&%s) != %s) {
2646+%s
2647+}
2648+
2649+dbus_message_iter_get_basic (&%s, &%s);
2650+
2651+%s = nih_strdup (%s, %s);
2652+if (! %s) {
2653+%s
2654+}
2655+
2656+dbus_message_iter_next (&%s);
2657+""" % (iter_name, self.dbus_type, type_error,
2658+ iter_name, value_name,
2659+ name, parent, value_name,
2660+ name, mem_error,
2661+ iter_name)
2662+
2663+ def dispatch(self, iter_name, mem_error,
2664+ pointer=False, const=False):
2665+ """Dispatching code.
2666+
2667+ Returns a string containing the code that will dispatch from a
2668+ local variable with the type and name as returned by vars() to
2669+ an iterator with the name given.
2670+ """
2671+ name = self.name
2672+ if pointer:
2673+ name = "*%s" % (name, )
2674+
2675+ value_name = "_".join((self.name, "value"))
2676+
2677+ return """\
2678+%s = %s;
2679+if (! dbus_message_iter_append_basic (&%s, %s, &%s)) {
2680+%s
2681+}
2682+""" % (value_name, name,
2683+ iter_name, self.dbus_type, value_name, mem_error)
2684+
2685+
2686+class DBusString(DBusStringType):
2687+ """D-Bus string.
2688+
2689+ This class represents the D-Bus string type and should be instantiated
2690+ with the name of the variable. It shares marshalling and dispatch code
2691+ and underlying C type with the other string types.
2692+ """
2693+ dbus_type = "DBUS_TYPE_STRING"
2694+ dbus_code = "s"
2695+
2696+class DBusObjectPath(DBusStringType):
2697+ """D-Bus object path.
2698+
2699+ This class represents the D-Bus object path type and should be instantiated
2700+ with the name of the variable. It shares marshalling and dispatch code
2701+ and underlying C type with the other string types.
2702+ """
2703+ dbus_type = "DBUS_TYPE_OBJECT_PATH"
2704+ dbus_code = "o"
2705+
2706+class DBusSignature(DBusStringType):
2707+ """D-Bus type signature.
2708+
2709+ This class represents the D-Bus signature type and should be instantiated
2710+ with the name of the variable. It shares marshalling and dispatch code
2711+ and underlying C type with the other string types.
2712+ """
2713+ dbus_type = "DBUS_TYPE_SIGNATURE"
2714+ dbus_code = "g"
2715+
2716+
2717+class DBusArray(DBusType):
2718+ """D-Bus array.
2719+
2720+ This class represents the D-Bus array type, it should be first
2721+ sub-classed with member_type set to an appropriate other class (the
2722+ forType classmethod can do that for you) and then instantiated with
2723+ the name of the variable.
2724+ """
2725+ dbus_type = "DBUS_TYPE_ARRAY"
2726+ dbus_code = "a"
2727+
2728+ @classmethod
2729+ def forType(cls, type):
2730+ class _DBusArray(DBusArray):
2731+ member_type = type
2732+
2733+ return _DBusArray
2734+
2735+ def __init__(self, name):
2736+ super(DBusArray, self).__init__(name)
2737+
2738+ self.iter_name = "%s_iter" % (self.name,)
2739+ self.len_name = "%s_len" % (self.name,)
2740+ self.loop_name = "%s_p" % (self.name,)
2741+
2742+ self.type = self.member_type("%s_elem" % (self.name, ))
2743+ # FIXME doesn't handle arrays of simple arrays since the length
2744+ # field is lost.
2745+ assert (len(self.type.vars()) == 1)
2746+
2747+ self.c_type = pointerify(self.type.c_type)
2748+
2749+ def signature(self, pointer=False, const=False):
2750+ """Type signature.
2751+
2752+ Returns a string containing the D-Bus type signature for this type.
2753+ """
2754+ return self.dbus_code + self.type.signature()
2755+
2756+ def locals(self, pointer=False, const=False):
2757+ """Local variable type and name.
2758+
2759+ Returns a list containing necessary local variables for iteration
2760+ of this type.
2761+ """
2762+ locals = [ ( "DBusMessageIter", self.iter_name )]
2763+ if self.type.c_type.endswith("*"):
2764+ locals.append(( "size_t", self.len_name ))
2765+
2766+ return locals
2767+
2768+ def vars(self, pointer=False, const=False):
2769+ """Variable type and name.
2770+
2771+ Returns a list containing tuples of C type and name for each type
2772+ within this group.
2773+ """
2774+ vars = [ ( self.realType(self.c_type, pointer, const),
2775+ self.name ) ]
2776+ if not self.type.c_type.endswith("*"):
2777+ vars.append(( self.realType("size_t", pointer, const),
2778+ self.len_name ))
2779+
2780+ return vars
2781+
2782+ def names(self, pointer=False, const=False):
2783+ """Variable name.
2784+
2785+ Returns a list containing a single string; the name given when creating
2786+ the instance.
2787+ """
2788+ names = [ self.name ]
2789+ if not self.type.c_type.endswith("*"):
2790+ names.append(self.len_name)
2791+
2792+ return names
2793+
2794+ def marshal(self, iter_name, parent, type_error, mem_error,
2795+ pointer=False, const=False):
2796+ """Marshalling code.
2797+
2798+ Returns a string containing the code that will marshal from an
2799+ iterator with the name given into local variables with the
2800+ types and names as returned by vars().
2801+ """
2802+ name = self.name
2803+ len_name = self.len_name
2804+ if pointer:
2805+ name = "*%s" % (name, )
2806+ if not self.type.c_type.endswith("*"):
2807+ len_name = "*%s" % (len_name, )
2808+
2809+ code = """\
2810+if (dbus_message_iter_get_arg_type (&%s) != %s) {
2811+%s
2812+}
2813+
2814+if (dbus_message_iter_get_element_type (&%s) != %s) {
2815+%s
2816+}
2817+
2818+dbus_message_iter_recurse (&%s, &%s);
2819+
2820+%s = NULL;
2821+%s = 0;
2822+
2823+while (dbus_message_iter_get_arg_type (&%s) != DBUS_TYPE_INVALID) {
2824+""" % (iter_name, self.dbus_type, type_error,
2825+ iter_name, self.type.dbus_type, type_error,
2826+ iter_name, self.iter_name,
2827+ name, len_name,
2828+ self.iter_name)
2829+
2830+ vars = self.type.vars()
2831+ vars.extend(self.type.locals())
2832+ code += indent(''.join("%s;\n" % var for var in lineup_vars(vars)), 1)
2833+
2834+ code += "\n"
2835+ code += indent(self.type.marshal("%s_iter" % self.name, parent,
2836+ type_error, mem_error), 1)
2837+
2838+ code += "\n"
2839+ code += indent("""\
2840+%s = nih_realloc (%s, %s, sizeof (%s) * ((%s) + 1));
2841+if (! %s) {
2842+%s
2843+}
2844+
2845+(%s)[(%s)++] = %s;
2846+""" % (name, name, parent, self.type.c_type, len_name,
2847+ name, mem_error,
2848+ name, len_name, self.type.name), 1)
2849+
2850+ code += "\n"
2851+ code += """\
2852+}
2853+
2854+dbus_message_iter_next (&%s);
2855+""" % (iter_name, )
2856+
2857+ if self.type.c_type.endswith("*"):
2858+ code += "\n"
2859+ code += """\
2860+%s = nih_realloc (%s, %s, sizeof (%s) * ((%s) + 1));
2861+if (! %s) {
2862+%s
2863+}
2864+
2865+(%s)[(%s)] = NULL;
2866+""" % (name, name, parent, self.type.c_type, len_name,
2867+ name, mem_error,
2868+ name, len_name)
2869+
2870+ return code
2871+
2872+ def dispatch(self, iter_name, mem_error,
2873+ pointer=False, const=False):
2874+ """Dispatching code.
2875+
2876+ Returns a string containing the code that will dispatch from
2877+ local variables with the types and names as returned by vars() to
2878+ an iterator with the name given.
2879+ """
2880+ name = self.name
2881+ len_name = self.len_name
2882+ if pointer:
2883+ name = "*%s" % (name, )
2884+ if not self.type.c_type.endswith("*"):
2885+ len_name = "*%s" % (len_name, )
2886+
2887+ code = """\
2888+if (! dbus_message_iter_open_container (&%s, %s, \"%s\", &%s)) {
2889+%s
2890+}
2891+""" % (iter_name, self.dbus_type, self.type.signature(),
2892+ self.iter_name, mem_error)
2893+
2894+ code += "\n"
2895+ if self.type.c_type.endswith("*"):
2896+ code += """\
2897+%s = 0;
2898+for (%s%s = %s; %s && *%s; %s++) {
2899+""" % (len_name,
2900+ self.realType(self.c_type, const=const), self.loop_name, name,
2901+ self.loop_name, self.loop_name,
2902+ self.loop_name)
2903+ else:
2904+ code += """\
2905+for (%s%s = %s; %s < %s + %s; %s++) {
2906+""" % (self.realType(self.c_type, const=const), self.loop_name, name,
2907+ self.loop_name, name, len_name, self.loop_name)
2908+
2909+ vars = self.type.vars()
2910+ vars.extend(self.type.locals())
2911+ code += indent(''.join("%s;\n" % var for var in lineup_vars(vars)), 1)
2912+
2913+ code += "\n"
2914+ code += indent("""\
2915+%s = *%s;
2916+""" % (self.type.name, self.loop_name), 1)
2917+
2918+ code += "\n"
2919+ code += indent(self.type.dispatch(self.iter_name, mem_error), 1)
2920+
2921+ if self.type.c_type.endswith("*"):
2922+ code += "\n"
2923+ code += indent("""\
2924+(%s)++;
2925+""" % (len_name, ), 1)
2926+
2927+ code += """\
2928+}
2929+
2930+if (! dbus_message_iter_close_container (&%s, &%s)) {
2931+%s
2932+}
2933+""" % (iter_name, self.iter_name, mem_error)
2934+
2935+ return code
2936+
2937+
2938+class DBusGroup(object):
2939+ def __init__(self, types, pointer=False, const=False):
2940+ self.types = types
2941+ self.pointer = pointer
2942+ self.const = const
2943+
2944+ def signature(self):
2945+ """Type signature.
2946+
2947+ Returns a string containing the D-Bus type signature for this type.
2948+ """
2949+ signature = ""
2950+
2951+ for type in self.types:
2952+ signature += type.signature(pointer=self.pointer, const=self.const)
2953+
2954+ return signature
2955+
2956+ def vars(self):
2957+ """Variable type and name.
2958+
2959+ Returns a list containing tuples of C type and name for each type
2960+ within this group.
2961+ """
2962+ vars = []
2963+
2964+ for type in self.types:
2965+ vars.extend(type.vars(pointer=self.pointer, const=self.const))
2966+
2967+ return vars
2968+
2969+ def names(self):
2970+ """Variable names.
2971+
2972+ Returns a list of names of all types in this group.
2973+ """
2974+ names = []
2975+
2976+ for type in self.types:
2977+ names.extend(type.names())
2978+ return names
2979+
2980+ def locals(self):
2981+ """Local variable type and name.
2982+
2983+ Returns a list containing necessary local variables for iteration
2984+ of this type.
2985+ """
2986+ locals = []
2987+
2988+ for type in self.types:
2989+ locals.extend(type.locals(pointer=self.pointer, const=self.const))
2990+
2991+ return locals
2992+
2993+ def marshal(self, iter_name, parent, type_error, mem_error):
2994+ """Marshalling code.
2995+
2996+ Returns a string containing the code that will marshal from an
2997+ iterator with the name given into local variables with the
2998+ types and names as returned by vars().
2999+ """
3000+ code = ""
3001+
3002+ for type in self.types:
3003+ if code:
3004+ code += "\n"
3005+ code += type.marshal(iter_name, parent, type_error, mem_error,
3006+ pointer=self.pointer, const=self.const)
3007+
3008+ if code:
3009+ code += "\n"
3010+ code += """\
3011+if (dbus_message_iter_get_arg_type (&%s) != DBUS_TYPE_INVALID) {
3012+%s
3013+}
3014+""" % (iter_name, type_error)
3015+
3016+ return code
3017+
3018+ def dispatch(self, iter_name, mem_error):
3019+ """Dispatching code.
3020+
3021+ Returns a string containing the code that will dispatch from
3022+ local variables with the types and names as returned by vars() to
3023+ an iterator with the name given.
3024+ """
3025+ code = ""
3026+
3027+ for type in self.types:
3028+ if code:
3029+ code += "\n"
3030+ code += type.dispatch(iter_name, mem_error,
3031+ pointer=self.pointer, const=self.const)
3032+
3033+ return code
3034+
3035+
3036+class Generator(object):
3037+ def staticPrototypes(self):
3038+ """Static prototypes.
3039+
3040+ Returns an array of static function prototypes which are normally
3041+ placed in a block at the top of the source file.
3042+
3043+ Each prototype is a (retval, name, args, attributes) tuple.
3044+ """
3045+ return []
3046+
3047+ def exportTypedefs(self):
3048+ """Exported typedefs.
3049+
3050+ Type definitions that should be placed in the header.
3051+
3052+ Each typedef is the code to define it, including any documentation and
3053+ default value.
3054+ """
3055+ return []
3056+
3057+ def externPrototypes(self):
3058+ """Extern prototypes.
3059+
3060+ Returns an array of extern function prototypes which are normally
3061+ placed in a block at the top of the source file, in lieu of
3062+ missing headers.
3063+
3064+ Each prototype is a (retval, name, args, attributes) tuple.
3065+ """
3066+ return []
3067+
3068+ def variables(self):
3069+ """Variables.
3070+
3071+ Returns an array of both static and exported global variables
3072+ normally placed in a block at the top of the source file.
3073+
3074+ Each variable is the code to define it, including any documentation
3075+ and default value.
3076+ """
3077+ return []
3078+
3079+ def functions(self):
3080+ """Functions.
3081+
3082+ Returns an array of both static and exported functions which
3083+ consistute the bulk of the source file.
3084+
3085+ Each function is the code to define it, including any documentation.
3086+ """
3087+ return []
3088+
3089+ def definitions(self):
3090+ """Definitions.
3091+
3092+ Returns an array of structure and type definitions which are
3093+ normally placed in a block in the header file.
3094+
3095+ Each definition is the code to define it, including any documentation.
3096+ """
3097+ return []
3098+
3099+ def exports(self):
3100+ """Exports.
3101+
3102+ Returns an array of prototypes for exported variables which are
3103+ placed as a block inside the extern part of the header file.
3104+
3105+ Each export is a (type, name) tuple.
3106+ """
3107+ return []
3108+
3109+ def exportPrototypes(self):
3110+ """Function prototypes.
3111+
3112+ Returns an array of exported function prototypes which are normally
3113+ placed in a block inside the extern part of the header file.
3114+
3115+ Each prototype is a (retval, name, args, attributes) tuple.
3116+ """
3117+ return []
3118+
3119+
3120+class Member(Generator):
3121+ def __init__(self, interface, name):
3122+ self.interface = interface
3123+ self.name = name
3124+
3125+ @property
3126+ def c_name(self):
3127+ return self.name
3128+
3129+ @property
3130+ def extern_name(self):
3131+ return "_".join(( extern_prefix,
3132+ NAME_RE.sub("\\1_\\2", self.c_name).lower()))
3133+
3134+
3135+class MemberWithArgs(Member):
3136+ @classmethod
3137+ def fromElement(cls, interface, elem):
3138+ name = elem.get("name")
3139+ if name is None:
3140+ raise AttributeError, "Name may not be null"
3141+
3142+ types = [ DBusType.fromElement(e) for e in elem.findall("arg") ]
3143+
3144+ self = cls(interface, name, types)
3145+ self.style = elem.get(ElementTree.QName(XMLNS, mode), self.style)
3146+ return self
3147+
3148+ def __init__(self, interface, name, types):
3149+ super(MemberWithArgs, self).__init__(interface, name)
3150+
3151+ self.style = "sync"
3152+ self.types = types
3153+
3154+ def argArray(self):
3155+ """Argument array.
3156+
3157+ Returns a string containing code to initialise the array of arguments
3158+ used for nih_dbus_object_new().
3159+ """
3160+ code = """\
3161+static const NihDBusArg %s[] = {
3162+""" % "_".join([ self.interface.c_name, self.c_name, "args" ])
3163+
3164+ array = []
3165+ for type in self.types:
3166+ if type.direction == "in":
3167+ direction = "NIH_DBUS_ARG_IN"
3168+ elif type.direction == "out":
3169+ direction = "NIH_DBUS_ARG_OUT"
3170+
3171+ array.append(( "\"%s\"" % type.name,
3172+ "\"%s\"" % type.signature(),
3173+ direction ))
3174+
3175+ for line in lineup_array(array):
3176+ code += indent("%s,\n" % line, 1)
3177+
3178+ code += """\
3179+ { NULL }
3180+};
3181+"""
3182+ return code
3183+
3184+ def variables(self):
3185+ """Variables.
3186+
3187+ Returns an array of both static and exported global variables
3188+ normally placed in a block at the top of the source file.
3189+
3190+ Each variable is the code to define it, including any documentation
3191+ and default value.
3192+ """
3193+ variables = []
3194+ if mode == "object":
3195+ variables.append(self.argArray())
3196+
3197+ return variables
3198+
3199+
3200+class Method(MemberWithArgs):
3201+ def __init__(self, interface, name, types):
3202+ super(Method, self).__init__(interface, name, types)
3203+
3204+ def marshalPrototype(self):
3205+ """Marshalling function prototype.
3206+
3207+ Returns a (retval, name, args, attributes) tuple for the prototype
3208+ of the marshaller function.
3209+ """
3210+ return ( "static DBusHandlerResult",
3211+ "_".join([ self.interface.c_name, self.c_name, "marshal" ]),
3212+ [ ( "NihDBusObject *", "object" ),
3213+ ( "NihDBusMessage *", "message" ) ],
3214+ None )
3215+
3216+ def marshalFunction(self):
3217+ """Marshalling function.
3218+
3219+ Returns a string containing a marshaller function that takes
3220+ arguments from a D-Bus message, calls a C handler function with
3221+ them passed properly, then constructs a reply if successful.
3222+ """
3223+ in_args = DBusGroup([t for t in self.types if t.direction == "in"])
3224+ out_args = DBusGroup([t for t in self.types if t.direction == "out"])
3225+
3226+ name = "_".join([ self.interface.c_name, self.c_name, "marshal" ])
3227+ code = """\
3228+static DBusHandlerResult
3229+%s (NihDBusObject *object,
3230+%s NihDBusMessage *message)
3231+{
3232+""" % (name, " " * len(name))
3233+
3234+ # Declare local variables for the iterator, reply and those needed
3235+ # for both input and output arguments.
3236+ vars = [ ( "DBusMessageIter", "iter" ),
3237+ ( "DBusMessage *", "reply = NULL" ) ]
3238+ vars.extend(in_args.vars())
3239+ vars.extend(in_args.locals())
3240+ if self.style != "async":
3241+ vars.extend(out_args.vars())
3242+ vars.extend(out_args.locals())
3243+
3244+ code += indent(''.join("%s;\n" % var for var in lineup_vars(vars)), 1)
3245+
3246+ # Pre-amble for the function
3247+ code += "\n"
3248+ code += indent("""\
3249+nih_assert (object != NULL);
3250+nih_assert (message != NULL);
3251+""", 1);
3252+
3253+ # Marshal the input arguments into local variables
3254+ code += "\n"
3255+ code += indent("""\
3256+/* Iterate the arguments to the message and marshal into arguments
3257+ * for our own function call.
3258+ */
3259+dbus_message_iter_init (message->message, &iter);
3260+""", 1)
3261+ code += "\n"
3262+
3263+ mem_error = indent("""\
3264+return DBUS_HANDLER_RESULT_NEED_MEMORY;
3265+""", 1)
3266+ type_error = indent("""\
3267+reply = dbus_message_new_error (message->message, DBUS_ERROR_INVALID_ARGS,
3268+ _("Invalid arguments to %s method"));
3269+if (! reply) {
3270+%s
3271+}
3272+
3273+goto send;
3274+""" % (self.name, mem_error), 1)
3275+ code += indent(in_args.marshal("iter", "message",
3276+ type_error, mem_error), 1)
3277+
3278+ # Construct the function call
3279+ args = [ "object->data", "message" ]
3280+ args.extend(n for t, n in in_args.vars())
3281+ if self.style != "async":
3282+ args.extend("&%s" % n for t, n in out_args.vars())
3283+
3284+ code += "\n"
3285+ code += indent("""\
3286+/* Call the handler function. */
3287+if (%s (%s) < 0) {
3288+ NihError *err;
3289+
3290+ err = nih_error_get ();
3291+ if (err->number == ENOMEM) {
3292+ nih_free (err);
3293+
3294+ return DBUS_HANDLER_RESULT_NEED_MEMORY;
3295+ } else if (err->number == NIH_DBUS_ERROR) {
3296+ NihDBusError *dbus_err = (NihDBusError *)err;
3297+
3298+ reply = dbus_message_new_error (message->message,
3299+ dbus_err->name,
3300+ err->message);
3301+ nih_free (err);
3302+
3303+ if (! reply)
3304+ return DBUS_HANDLER_RESULT_NEED_MEMORY;
3305+
3306+ goto send;
3307+ } else {
3308+ reply = dbus_message_new_error (message->message,
3309+ DBUS_ERROR_FAILED,
3310+ err->message);
3311+ nih_free (err);
3312+
3313+ if (! reply)
3314+ return DBUS_HANDLER_RESULT_NEED_MEMORY;
3315+
3316+ goto send;
3317+ }
3318+}
3319+""" % (self.extern_name, ", ".join(args)), 1)
3320+
3321+ if self.style == "async":
3322+ code += "\n"
3323+ code += indent("return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;\n", 1)
3324+ else:
3325+ # Be well-behaved and make the function return immediately
3326+ # if no reply is expected
3327+ code += "\n"
3328+ code += indent("""\
3329+/* If the sender doesn't care about a reply, don't bother wasting
3330+ * effort constructing and sending one.
3331+ */
3332+if (dbus_message_get_no_reply (message->message))
3333+ return DBUS_HANDLER_RESULT_HANDLED;
3334+""", 1)
3335+
3336+ # Create reply and dispatch the local variables into output
3337+ # arguments
3338+ code += "\n"
3339+ code += indent("""\
3340+/* Construct the reply message */
3341+reply = dbus_message_new_method_return (message->message);
3342+if (! reply)
3343+ return DBUS_HANDLER_RESULT_NEED_MEMORY;
3344+
3345+dbus_message_iter_init_append (reply, &iter);
3346+""", 1)
3347+ code += "\n"
3348+
3349+ mem_error = indent("""\
3350+dbus_message_unref (reply);
3351+return DBUS_HANDLER_RESULT_NEED_MEMORY;
3352+""", 1)
3353+ code += indent(out_args.dispatch("iter", mem_error), 1)
3354+
3355+ # Send the reply
3356+ code += "\nsend:\n"
3357+ code += indent("""\
3358+/* Send the reply, appending it to the outgoing queue. */
3359+if (! dbus_connection_send (message->conn, reply, NULL)) {
3360+ dbus_message_unref (reply);
3361+ return DBUS_HANDLER_RESULT_NEED_MEMORY;
3362+}
3363+
3364+dbus_message_unref (reply);
3365+
3366+return DBUS_HANDLER_RESULT_HANDLED;
3367+""", 1)
3368+
3369+ code += "}\n"
3370+
3371+ return code
3372+
3373+ def handlerPrototype(self):
3374+ """Handler function prototype.
3375+
3376+ Returns a (retval, name, args, attributes) tuple for the prototype
3377+ of the handler function that the user must define.
3378+ """
3379+ in_args = DBusGroup([t for t in self.types if t.direction == "in"],
3380+ const=True)
3381+ out_args = DBusGroup([t for t in self.types if t.direction == "out"],
3382+ pointer=True)
3383+
3384+ vars = [ ("void *", "data"),
3385+ ("NihDBusMessage *", "message") ]
3386+ vars.extend(in_args.vars())
3387+ if self.style != "async":
3388+ vars.extend(out_args.vars())
3389+
3390+ return ( "extern int",
3391+ self.extern_name,
3392+ vars,
3393+ None )
3394+
3395+ def replyPrototype(self):
3396+ """Reply function prototype.
3397+
3398+ Returns a (retval, name, args, attributes) tuple for the prototype
3399+ of the reply function defined for async functions.
3400+ """
3401+ out_args = DBusGroup([t for t in self.types if t.direction == "out"],
3402+ const=True)
3403+
3404+ vars = [("NihDBusMessage *", "message") ]
3405+ vars.extend(out_args.vars())
3406+
3407+ return ( "int",
3408+ "_".join([ self.extern_name, "reply" ]),
3409+ vars,
3410+ None )
3411+
3412+ def replyFunction(self):
3413+ """Reply function.
3414+
3415+ Returns a string containing a reply function that takes its
3416+ arguments and produces a D-Bus message reply.
3417+ """
3418+ out_args = DBusGroup([t for t in self.types if t.direction == "out"],
3419+ const=True)
3420+
3421+ name = "_".join([ self.extern_name, "reply" ])
3422+ vars = [ ( "NihDBusMessage *", "message" ) ]
3423+ vars.extend(out_args.vars())
3424+
3425+ code = "int\n%s (" % (name, )
3426+ code += (",\n" + " " * (len(name) + 2)).join(lineup_vars(vars))
3427+ code += ")\n{\n"
3428+
3429+ # Declare local variables for the iterator and the reply
3430+ vars = [ ( "DBusMessageIter", "iter" ),
3431+ ( "DBusMessage *", "reply = NULL" ) ]
3432+ vars.extend(out_args.locals())
3433+
3434+ code += indent(''.join("%s;\n" % var for var in lineup_vars(vars)), 1)
3435+
3436+ # Pre-amble for the function
3437+ code += "\n"
3438+ code += indent("""\
3439+nih_assert (message != NULL);
3440+""", 1);
3441+
3442+ # Be well-behaved and don't actually send the reply if one is
3443+ # not expected
3444+ code += "\n"
3445+ code += indent("""\
3446+/* If the sender doesn't care about a reply, don't bother wasting
3447+ * effort constructing and sending one.
3448+ */
3449+if (dbus_message_get_no_reply (message->message)) {
3450+ nih_free (message);
3451+ return 0;
3452+}
3453+""", 1)
3454+
3455+ # Create reply and dispatch the local variables into output
3456+ # arguments
3457+ code += "\n"
3458+ code += indent("""\
3459+/* Construct the reply message */
3460+reply = dbus_message_new_method_return (message->message);
3461+if (! reply)
3462+ return -1;
3463+
3464+dbus_message_iter_init_append (reply, &iter);
3465+""", 1)
3466+ code += "\n"
3467+
3468+ mem_error = indent("""\
3469+dbus_message_unref (reply);
3470+return -1;
3471+""", 1)
3472+ code += indent(out_args.dispatch("iter", mem_error), 1)
3473+
3474+ # Send the reply
3475+ code += "\n"
3476+ code += indent("""\
3477+/* Send the reply, appending it to the outgoing queue. */
3478+if (! dbus_connection_send (message->conn, reply, NULL)) {
3479+ dbus_message_unref (reply);
3480+ return -1;
3481+}
3482+
3483+dbus_message_unref (reply);
3484+nih_free (message);
3485+
3486+return 0;
3487+""", 1)
3488+
3489+ code += "}\n"
3490+
3491+ return code
3492+
3493+ def asyncNotifyPrototype(self):
3494+ """Asynchronous dispatch function prototype.
3495+
3496+ Returns a (retval, name, args, attributes) tuple for the prototype
3497+ of the asynchronous dispatch function.
3498+ """
3499+ vars = [ ( "DBusPendingCall *", "call" ),
3500+ ( "NihAsyncNotifyData *", "data" ) ]
3501+
3502+ return ( "static void",
3503+ self.extern_name + "_async_notify",
3504+ vars, ( ) )
3505+
3506+ def asyncDispatchPrototype(self):
3507+ """Asynchronous dispatch function prototype.
3508+
3509+ Returns a (retval, name, args, attributes) tuple for the prototype
3510+ of the asynchronous dispatch function.
3511+ """
3512+ in_args = DBusGroup([t for t in self.types if t.direction == "in"],
3513+ const=True)
3514+ out_args = DBusGroup([t for t in self.types if t.direction == "out"])
3515+
3516+ vars = [ ( "NihDBusProxy *", "proxy" ) ]
3517+ vars.extend(in_args.vars())
3518+ vars += [ ( "%sCallback" % camelate(self.extern_name), "callback" ),
3519+ ( "%sErrback" % camelate(self.extern_name), "errback" ),
3520+ ( "void *", "userdata" ) ]
3521+
3522+ return ( "int",
3523+ self.extern_name + "_async",
3524+ vars,
3525+ ( "warn_unused_result", ) )
3526+
3527+ def dispatchPrototype(self):
3528+ """Dispatch function prototype.
3529+
3530+ Returns a (retval, name, args, attributes) tuple for the prototype
3531+ of the dispatch function.
3532+ """
3533+ in_args = DBusGroup([t for t in self.types if t.direction == "in"],
3534+ const=True)
3535+ out_args = DBusGroup([t for t in self.types if t.direction == "out"],
3536+ pointer=True)
3537+
3538+ vars = [ ( "NihDBusProxy *", "proxy" ) ]
3539+ vars.extend(in_args.vars())
3540+ # FIXME async doesn't have these, but has a callback instead
3541+ vars.extend(out_args.vars())
3542+
3543+ return ( "int",
3544+ self.extern_name,
3545+ vars,
3546+ ( "warn_unused_result", ) )
3547+
3548+ def asyncNotifyFunction(self):
3549+ """Asynchronous notification function.
3550+
3551+ Called when an asynchronously dispatched function returns something.
3552+ Fetches out the arguments and passes them to a user-supplied function.
3553+ """
3554+ out_args = DBusGroup([t for t in self.types if t.direction == "out"])
3555+
3556+ vars = [ ( "DBusPendingCall *", "call" ),
3557+ ( "NihAsyncNotifyData *", "data" ) ]
3558+
3559+ code = "static void\n%s (" % (self.extern_name + "_async_notify", )
3560+ code += (",\n" + " " * (len(self.extern_name + "_async_notify") + 2)).join(lineup_vars(vars))
3561+ code += ")\n{\n"
3562+
3563+ # Declare local variables for the iterator, reply and those needed
3564+ # for both input and output arguments.
3565+ vars = [ ( "DBusMessage *", "reply" ),
3566+ ( "DBusMessageIter", "iter" ),
3567+ ( "int", "type" ) ]
3568+ vars.extend(out_args.locals())
3569+ vars.extend(out_args.vars())
3570+ code += indent(''.join("%s;\n" % var for var in lineup_vars(vars)), 1)
3571+
3572+ # Pre-amble for the function
3573+ code += "\n"
3574+
3575+ code += indent("""\
3576+reply = dbus_pending_call_steal_reply(call);
3577+
3578+nih_assert (reply != NULL);
3579+
3580+type = dbus_message_get_type (reply);
3581+
3582+nih_assert (type == DBUS_MESSAGE_TYPE_METHOD_RETURN ||
3583+ type == DBUS_MESSAGE_TYPE_ERROR);
3584+
3585+if (type == DBUS_MESSAGE_TYPE_ERROR) {
3586+ char *name;
3587+ DBusError error;
3588+
3589+ dbus_error_init (&error);
3590+ dbus_set_error_from_message (&error, reply);
3591+
3592+ if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY)) {
3593+ errno = ENOMEM;
3594+ nih_error_raise_system ();
3595+ } else {
3596+ nih_dbus_error_raise (error.name, error.message);
3597+ }
3598+
3599+ ((%sErrback)data->err_handler)(data->proxy, data->userdata);
3600+
3601+ dbus_error_free (&error);
3602+ goto out;
3603+}
3604+""" % camelate(self.extern_name), 1);
3605+
3606+ # Marshal the reply arguments into output arguments
3607+ code += "\n"
3608+ code += indent("""\
3609+/* Iterate the arguments to the reply and marshal into output
3610+ * arguments from our own function call.
3611+ */
3612+dbus_message_iter_init (reply, &iter);
3613+""", 1);
3614+ code += "\n"
3615+
3616+ mem_error = indent("""\
3617+errno = ENOMEM;
3618+nih_error_raise_system ();
3619+((%sErrback)data->err_handler)(data->proxy, data->userdata);
3620+goto out;
3621+""" % camelate(self.extern_name), 1)
3622+ type_error = indent("""\
3623+nih_error_raise (NIH_DBUS_INVALID_ARGS, NIH_DBUS_INVALID_ARGS_STR);
3624+((%sErrback)data->err_handler)(data->proxy, data->userdata);
3625+goto out;
3626+""" % camelate(self.extern_name), 1);
3627+ code += indent(out_args.marshal("iter", "data->proxy",
3628+ type_error, mem_error), 1)
3629+
3630+ code += "\n\n"
3631+ code += indent("""\
3632+((%sCallback)data->handler)(%s);
3633+""" % (camelate(self.extern_name), ", ".join([ "data->proxy", "data->userdata" ] + out_args.names())), 1)
3634+
3635+ code += "out:\n"
3636+ code += indent("""\
3637+
3638+dbus_message_unref (reply);
3639+dbus_pending_call_unref (call);
3640+
3641+return;
3642+""", 1)
3643+
3644+ code += "}\n"
3645+
3646+ return code
3647+
3648+ def asyncDispatchFunction(self):
3649+ """Asynchronous dispatching function.
3650+
3651+ Returns a string containing a dispatcher function that takes arguments
3652+ identical to those taken by a particular dbus method, and pointers to
3653+ variables where the return values from that method might be stored. Then
3654+ sends a dbus message and waits for a reply to come, and populates the
3655+ reply arguments with the contents of the reply message.
3656+ """
3657+ in_args = DBusGroup([t for t in self.types if t.direction == "in"],
3658+ const=True)
3659+ out_args = DBusGroup([t for t in self.types if t.direction == "out"])
3660+
3661+ vars = [ ( "NihDBusProxy *", "proxy" ) ]
3662+ vars.extend(in_args.vars())
3663+ vars += [ ( "%sCallback" % camelate(self.extern_name), "callback" ),
3664+ ( "%sErrback" % camelate(self.extern_name), "errback" ),
3665+ ( "void *", "userdata" ) ]
3666+
3667+ code = "int\n%s (" % (self.extern_name + "_async", )
3668+ code += (",\n" + " " * (len(self.extern_name + "_async") + 2)).join(lineup_vars(vars))
3669+ code += ")\n{\n"
3670+
3671+ # Declare local variables for the iterator, reply and those needed
3672+ # for both input and output arguments.
3673+ vars = [ ( "DBusMessage *", "message" ),
3674+ ( "DBusMessageIter", "iter" ),
3675+ ( "DBusPendingCall *", "call" ),
3676+ ( "NihAsyncNotifyData *", "data" ) ]
3677+ vars.extend(in_args.locals())
3678+ code += indent(''.join("%s;\n" % var for var in lineup_vars(vars)), 1)
3679+
3680+ # Pre-amble for the function
3681+ code += "\n"
3682+ code += indent("""\
3683+nih_assert (proxy != NULL);
3684+nih_assert ((errback != NULL && callback != NULL) ||
3685+ (errback == NULL && callback == NULL));
3686+""", 1);
3687+
3688+ # Dispatch the input arguments into a new local message
3689+ code += "\n"
3690+ code += indent("""\
3691+message = dbus_message_new_method_call (proxy->name, proxy->path, "%s", "%s");
3692+if (! message)
3693+ nih_return_no_memory_error (-1);
3694+
3695+/* Iterate the arguments to the function and dispatch into
3696+ * message arguments.
3697+ */
3698+dbus_message_iter_init_append (message, &iter);
3699+""" % (self.interface.name, self.name), 1)
3700+ code += "\n"
3701+
3702+ # FIXME autostart?
3703+
3704+ mem_error = indent("""\
3705+dbus_message_unref (message);
3706+nih_return_no_memory_error (-1);
3707+""", 1)
3708+ code += indent(in_args.dispatch("iter", mem_error), 1)
3709+
3710+ # FIXME timeout should be configurable
3711+ # FIXME expect no reply?
3712+ code += "\n"
3713+ code += indent("""\
3714+/* If we don't specify a callback, just finish it now */
3715+if (! callback) {
3716+ dbus_bool_t succ = dbus_connection_send (proxy->conn, message, NULL);
3717+ dbus_message_unref (message);
3718+ if (! succ)
3719+ nih_return_no_memory_error (-1);
3720+ return 0;
3721+}
3722+
3723+/* Send the reply, appending it to the outgoing queue and blocking. */
3724+if (! dbus_connection_send_with_reply (proxy->conn, message, &call, -1)) {
3725+ dbus_message_unref (message);
3726+ nih_return_no_memory_error (-1);
3727+}
3728+
3729+data = nih_new (proxy, NihAsyncNotifyData);
3730+if (! data)
3731+ nih_return_no_memory_error (-1);
3732+
3733+data->proxy = proxy;
3734+data->userdata = userdata;
3735+data->handler = callback;
3736+data->err_handler = errback;
3737+
3738+
3739+dbus_pending_call_set_notify(call, (DBusPendingCallNotifyFunction)%s_async_notify, data, (DBusFreeFunction)nih_free);
3740+
3741+dbus_message_unref (message);
3742+return 0;
3743+""" % self.extern_name, 1);
3744+
3745+ code += "}\n"
3746+
3747+ return code
3748+
3749+ def dispatchFunction(self):
3750+ """Dispatching function.
3751+
3752+ Returns a string containing a dispatcher function that takes arguments
3753+ identical to those taken by a particular dbus method, and pointers to
3754+ variables where the return values from that method might be stored. Then
3755+ sends a dbus message and waits for a reply to come, and populates the
3756+ reply arguments with the contents of the reply message.
3757+ """
3758+ in_args = DBusGroup([t for t in self.types if t.direction == "in"],
3759+ const=True)
3760+ out_args = DBusGroup([t for t in self.types if t.direction == "out"],
3761+ pointer=True)
3762+
3763+ vars = [ ( "NihDBusProxy *", "proxy" ) ]
3764+ vars.extend(in_args.vars())
3765+ # FIXME async doesn't have these, but has a callback instead
3766+ vars.extend(out_args.vars())
3767+
3768+ code = "int\n%s (" % (self.extern_name, )
3769+ code += (",\n" + " " * (len(self.extern_name) + 2)).join(lineup_vars(vars))
3770+ code += ")\n{\n"
3771+
3772+ # Declare local variables for the iterator, reply and those needed
3773+ # for both input and output arguments.
3774+ vars = [ ( "DBusMessage *", "message" ),
3775+ ( "DBusMessageIter", "iter" ),
3776+ ( "DBusMessage *", "reply = NULL" ),
3777+ ( "DBusError", "error" ) ]
3778+ vars.extend(in_args.locals())
3779+ # FIXME not for async
3780+ vars.extend(out_args.locals())
3781+ code += indent(''.join("%s;\n" % var for var in lineup_vars(vars)), 1)
3782+
3783+ # Pre-amble for the function
3784+ code += "\n"
3785+ code += indent("""\
3786+nih_assert (proxy != NULL);
3787+""", 1);
3788+
3789+ # Dispatch the input arguments into a new local message
3790+ code += "\n"
3791+ code += indent("""\
3792+message = dbus_message_new_method_call (proxy->name, proxy->path, "%s", "%s");
3793+if (! message)
3794+ nih_return_no_memory_error (-1);
3795+
3796+/* Iterate the arguments to the function and dispatch into
3797+ * message arguments.
3798+ */
3799+dbus_message_iter_init_append (message, &iter);
3800+""" % (self.interface.name, self.name), 1)
3801+ code += "\n"
3802+
3803+ # FIXME autostart?
3804+
3805+ mem_error = indent("""\
3806+dbus_message_unref (message);
3807+nih_return_no_memory_error (-1);
3808+""", 1)
3809+ code += indent(in_args.dispatch("iter", mem_error), 1)
3810+
3811+ # FIXME timeout should be configurable
3812+ # FIXME expect no reply?
3813+ code += "\n"
3814+ code += indent("""\
3815+dbus_error_init (&error);
3816+
3817+/* Send the reply, appending it to the outgoing queue and blocking. */
3818+reply = dbus_connection_send_with_reply_and_block (proxy->conn, message, -1, &error);
3819+if (! reply) {
3820+ dbus_message_unref (message);
3821+
3822+ if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY)) {
3823+ dbus_error_free (&error);
3824+ nih_return_no_memory_error (-1);
3825+ } else {
3826+ nih_dbus_error_raise (error.name, error.message);
3827+ dbus_error_free (&error);
3828+ return -1;
3829+ }
3830+}
3831+
3832+dbus_message_unref (message);
3833+""", 1);
3834+
3835+ # Marshal the reply arguments into output arguments
3836+ code += "\n"
3837+ code += indent("""\
3838+/* Iterate the arguments to the reply and marshal into output
3839+ * arguments from our own function call.
3840+ */
3841+dbus_message_iter_init (reply, &iter);
3842+""", 1);
3843+ code += "\n"
3844+
3845+ mem_error = indent("""\
3846+dbus_message_unref (reply);
3847+nih_return_no_memory_error (-1);
3848+""", 1)
3849+ type_error = indent("""\
3850+dbus_message_unref (reply);
3851+nih_return_error (-1, NIH_DBUS_INVALID_ARGS, NIH_DBUS_INVALID_ARGS_STR);
3852+""", 1);
3853+ code += indent(out_args.marshal("iter", "proxy",
3854+ type_error, mem_error), 1)
3855+
3856+ code += "\n"
3857+ code += indent("""\
3858+dbus_message_unref (reply);
3859+
3860+return 0;
3861+""", 1)
3862+
3863+ code += "}\n"
3864+
3865+ return code
3866+
3867+ def exportTypedefs(self):
3868+ """Exported typedefs.
3869+
3870+ Type definitions that should be placed in the header.
3871+
3872+ Each typedef is the code to define it, including any documentation and
3873+ default value.
3874+ """
3875+ typedefs = []
3876+ out_args = DBusGroup([t for t in self.types if t.direction == "out"])
3877+ if mode == "proxy":
3878+ typedefs.append( ("void",
3879+ "(*%sCallback)" % camelate(self.extern_name),
3880+ [ ( "NihDBusProxy *", "proxy" ),
3881+ ( "void *", "userdata") ] + out_args.vars()
3882+ ) )
3883+ typedefs.append( ("void",
3884+ "(*%sErrback)" % camelate(self.extern_name),
3885+ [ ( "NihDBusProxy *", "proxy" ),
3886+ ( "void *", "userdata") ]
3887+ ) )
3888+ return typedefs
3889+
3890+ def staticPrototypes(self):
3891+ """Static prototypes.
3892+
3893+ Returns an array of static function prototypes which are normally
3894+ placed in a block at the top of the source file.
3895+
3896+ Each prototype is a (retval, name, args, attributes) tuple.
3897+ """
3898+ prototypes = []
3899+ if mode == "object":
3900+ prototypes.append(self.marshalPrototype())
3901+ else:
3902+ prototypes.append(self.asyncNotifyPrototype())
3903+
3904+ return prototypes
3905+
3906+ def externPrototypes(self):
3907+ """Extern prototypes.
3908+
3909+ Returns an array of extern function prototypes which are normally
3910+ placed in a block at the top of the source file, in lieu of
3911+ missing headers.
3912+
3913+ Each prototype is a (retval, name, args, attributes) tuple.
3914+ """
3915+ prototypes = []
3916+ if mode =="object":
3917+ prototypes.append(self.handlerPrototype())
3918+
3919+ return prototypes
3920+
3921+ def functions(self):
3922+ """Functions.
3923+
3924+ Returns an array of both static and exported functions which
3925+ consistute the bulk of the source file.
3926+
3927+ Each function is the code to define it, including any documentation.
3928+ """
3929+ functions = []
3930+ if mode == "object":
3931+ functions.append(self.marshalFunction())
3932+ if self.style == "async":
3933+ functions.append(self.replyFunction())
3934+ else:
3935+ functions.append(self.dispatchFunction())
3936+ functions.append(self.asyncDispatchFunction())
3937+ functions.append(self.asyncNotifyFunction())
3938+
3939+ return functions
3940+
3941+ def exportPrototypes(self):
3942+ """Function prototypes.
3943+
3944+ Returns an array of exported function prototypes which are normally
3945+ placed in a block inside the extern part of the header file.
3946+
3947+ Each prototype is a (retval, name, args, attributes) tuple.
3948+ """
3949+ prototypes = []
3950+ if mode == "object":
3951+ if self.style == "async":
3952+ prototypes.append(self.replyPrototype())
3953+ else:
3954+ prototypes.append(self.dispatchPrototype())
3955+ prototypes.append(self.asyncDispatchPrototype())
3956+
3957+ return prototypes
3958+
3959+
3960+class Signal(MemberWithArgs):
3961+ def __init__(self, interface, name, types):
3962+ super(Signal, self).__init__(interface, name, types)
3963+
3964+ def dispatchPrototype(self):
3965+ """Dispatch function prototype.
3966+
3967+ Returns a (retval, name, args, attributes) tuple for the prototype
3968+ of the dispatch function.
3969+ """
3970+ args = DBusGroup(self.types, const=True)
3971+
3972+ vars = [ ( "DBusConnection *", "connection" ),
3973+ ( "const char *", "origin_path" ) ]
3974+ vars.extend(args.vars())
3975+
3976+ return ( "int",
3977+ self.extern_name,
3978+ vars,
3979+ ( "warn_unused_result", ) )
3980+
3981+ def dispatchFunction(self):
3982+ """Dispatch function.
3983+
3984+ Returns a string containing a dispatch function that takes puts
3985+ its arguments into a D-Bus message and sends it.
3986+ """
3987+ args = DBusGroup(self.types, const=True)
3988+
3989+ vars = [ ( "DBusConnection *", "connection" ),
3990+ ( "const char *", "origin_path" ) ]
3991+ vars.extend(args.vars())
3992+
3993+ code = "int\n%s (" % (self.extern_name, )
3994+ code += (",\n" + " " * (len(self.extern_name) + 2)).join(lineup_vars(vars))
3995+ code += ")\n{\n"
3996+
3997+ # Declare local variables for the message and iterator
3998+ vars = [ ( "DBusMessage *", "message"),
3999+ ( "DBusMessageIter", "iter" ) ]
4000+ vars.extend(args.locals())
4001+ code += indent(''.join("%s;\n" % var for var in lineup_vars(vars)), 1)
4002+
4003+ # Pre-amble for the function
4004+ code += "\n"
4005+ code += indent("""\
4006+nih_assert (connection != NULL);
4007+nih_assert (origin_path != NULL);
4008+""", 1)
4009+
4010+ # Marshal the arguments into a new local message
4011+ code += "\n"
4012+ code += indent("""\
4013+message = dbus_message_new_signal (origin_path, "%s", "%s");
4014+if (! message)
4015+ return -1;
4016+
4017+/* Iterate the arguments to the function and dispatch into
4018+ * message arguments.
4019+ */
4020+dbus_message_iter_init_append (message, &iter);
4021+""" % (self.interface.name, self.name), 1)
4022+ code += "\n"
4023+
4024+ mem_error = indent("""\
4025+dbus_message_unref (message);
4026+return -1;
4027+""", 1)
4028+ code += indent(args.dispatch("iter", mem_error), 1)
4029+
4030+ code += "\n"
4031+ code += indent("""\
4032+/* Send the reply, appending it to the outgoing queue. */
4033+if (! dbus_connection_send (connection, message, NULL)) {
4034+ dbus_message_unref (message);
4035+ return -1;
4036+}
4037+
4038+dbus_message_unref (message);
4039+
4040+return 0;
4041+""", 1)
4042+
4043+ code += "}\n"
4044+
4045+ return code
4046+
4047+ def functions(self):
4048+ """Functions.
4049+
4050+ Returns an array of both static and exported functions which
4051+ consistute the bulk of the source file.
4052+
4053+ Each function is the code to define it, including any documentation.
4054+ """
4055+ functions = []
4056+ if mode == "object":
4057+ functions.append(self.dispatchFunction())
4058+
4059+ return functions
4060+
4061+ def exportPrototypes(self):
4062+ """Function prototypes.
4063+
4064+ Returns an array of exported function prototypes which are normally
4065+ placed in a block inside the extern part of the header file.
4066+
4067+ Each prototype is a (retval, name, args, attributes) tuple.
4068+ """
4069+ prototypes = []
4070+ if mode == "object":
4071+ prototypes.append(self.dispatchPrototype())
4072+
4073+ return prototypes
4074+
4075+
4076+class Group(Generator):
4077+ def __init__(self, members):
4078+ self.members = members
4079+
4080+ def staticPrototypes(self):
4081+ """Static prototypes.
4082+
4083+ Returns an array of static function prototypes which are normally
4084+ placed in a block at the top of the source file.
4085+
4086+ Each prototype is a (retval, name, args, attributes) tuple.
4087+ """
4088+ prototypes = []
4089+ for member in self.members:
4090+ prototypes.extend(member.staticPrototypes())
4091+
4092+ return prototypes
4093+
4094+ def externPrototypes(self):
4095+ """Extern prototypes.
4096+
4097+ Returns an array of extern function prototypes which are normally
4098+ placed in a block at the top of the source file, in lieu of
4099+ missing headers.
4100+
4101+ Each prototype is a (retval, name, args, attributes) tuple.
4102+ """
4103+ prototypes = []
4104+ for member in self.members:
4105+ prototypes.extend(member.externPrototypes())
4106+
4107+ return prototypes
4108+
4109+ def exportTypedefs(self):
4110+ """Exported typedefs.
4111+
4112+ Type definitions that should be placed in the header.
4113+
4114+ Each typedef is the code to define it, including any documentation and
4115+ default value.
4116+ """
4117+ typedefs = []
4118+ for member in self.members:
4119+ typedefs.extend(member.exportTypedefs())
4120+
4121+ return typedefs
4122+
4123+ def variables(self):
4124+ """Variables.
4125+
4126+ Returns an array of both static and exported global variables
4127+ normally placed in a block at the top of the source file.
4128+
4129+ Each variable is the code to define it, including any documentation
4130+ and default value.
4131+ """
4132+ variables = []
4133+ for member in self.members:
4134+ variables.extend(member.variables())
4135+
4136+ return variables
4137+
4138+ def functions(self):
4139+ """Functions.
4140+
4141+ Returns an array of both static and exported functions which
4142+ consistute the bulk of the source file.
4143+
4144+ Each function is the code to define it, including any documentation.
4145+ """
4146+ functions = []
4147+ for member in self.members:
4148+ functions.extend(member.functions())
4149+
4150+ return functions
4151+
4152+ def definitions(self):
4153+ """Definitions.
4154+
4155+ Returns an array of structure and type definitions which are
4156+ normally placed in a block in the header file.
4157+
4158+ Each definition is the code to define it, including any documentation.
4159+ """
4160+ definitions = []
4161+ for member in self.members:
4162+ definitions.extend(member.definitions())
4163+
4164+ return definitions
4165+
4166+ def exports(self):
4167+ """Exports.
4168+
4169+ Returns an array of prototypes for exported variables which are
4170+ placed as a block inside the extern part of the header file.
4171+
4172+ Each export is a (type, name) tuple.
4173+ """
4174+ exports = []
4175+ for member in self.members:
4176+ exports.extend(member.exports())
4177+
4178+ return exports
4179+
4180+ def exportPrototypes(self):
4181+ """Function prototypes.
4182+
4183+ Returns an array of exported function prototypes which are normally
4184+ placed in a block inside the extern part of the header file.
4185+
4186+ Each prototype is a (retval, name, args, attributes) tuple.
4187+ """
4188+ prototypes = []
4189+ for member in self.members:
4190+ prototypes.extend(member.exportPrototypes())
4191+
4192+ return prototypes
4193+
4194+
4195+class Interface(Group):
4196+ @classmethod
4197+ def fromElement(cls, elem):
4198+ name = elem.get("name")
4199+ if name is None:
4200+ raise AttributeError, "Interface name may not be null"
4201+
4202+ self = cls(name, [])
4203+ for e in elem.findall("method"):
4204+ method = Method.fromElement(self, e)
4205+ self.methods.append(method)
4206+ self.members.append(method)
4207+ for e in elem.findall("signal"):
4208+ signal = Signal.fromElement(self, e)
4209+ self.signals.append(signal)
4210+ self.members.append(signal)
4211+
4212+ return self
4213+
4214+ def __init__(self, name, members):
4215+ super(Interface, self).__init__(members)
4216+
4217+ self.name = name
4218+ self.methods = []
4219+ self.signals = []
4220+
4221+ @property
4222+ def c_name(self):
4223+ return self.name.replace(".", "_")
4224+
4225+ def methodsArray(self):
4226+ """Methods array.
4227+
4228+ Returns a string containing code to initialise the array of methods
4229+ used for nih_dbus_object_new().
4230+ """
4231+ code = """\
4232+const NihDBusMethod %s_methods[] = {
4233+""" % self.c_name
4234+
4235+ array = []
4236+ for method in self.methods:
4237+ if mode == "object":
4238+ func = "%s_marshal" % "_".join([ self.c_name, method.c_name ])
4239+ else:
4240+ func = "NULL"
4241+
4242+ array.append(( "\"%s\"" % method.name,
4243+ func,
4244+ "%s_args" % "_".join([ self.c_name, method.c_name ])))
4245+
4246+ for line in lineup_array(array):
4247+ code += indent("%s,\n" % line, 1)
4248+
4249+ code += """\
4250+ { NULL }
4251+};
4252+"""
4253+ return code
4254+
4255+ def signalsArray(self):
4256+ """Signals array.
4257+
4258+ Returns a string containing code to initialise the array of signals
4259+ used for nih_dbus_object_new().
4260+ """
4261+ code = """\
4262+const NihDBusSignal %s_signals[] = {
4263+""" % self.c_name
4264+
4265+ array = []
4266+ for signal in self.signals:
4267+ array.append(( "\"%s\"" % signal.name,
4268+ "%s_args" % "_".join([ self.c_name, signal.c_name ])))
4269+
4270+ for line in lineup_array(array):
4271+ code += indent("%s,\n" % line, 1)
4272+
4273+ code += """\
4274+ { NULL }
4275+};
4276+"""
4277+ return code
4278+
4279+ def interfacePrototype(self):
4280+ """Interface structure prototype.
4281+
4282+ Returns a (type, name) tuple for the prototype of the interface
4283+ struct.
4284+ """
4285+ return ( "const NihDBusInterface", "%s" % self.c_name )
4286+
4287+ def interfaceStruct(self):
4288+ """Interface structure.
4289+
4290+ Returns a string containing code to define a structure containing
4291+ information about the interface.
4292+ """
4293+ code = """\
4294+const NihDBusInterface %s = {
4295+ \"%s\",
4296+ %s_methods,
4297+ %s_signals,
4298+ NULL
4299+""" % (self.c_name, self.name, self.c_name, self.c_name)
4300+
4301+ code += """\
4302+};
4303+"""
4304+ return code
4305+
4306+ def variables(self):
4307+ """Variables.
4308+
4309+ Returns an array of both static and exported global variables
4310+ normally placed in a block at the top of the source file.
4311+
4312+ Each variable is the code to define it, including any documentation
4313+ and default value.
4314+ """
4315+ variables = super(Interface, self).variables()
4316+ if mode == "object":
4317+ variables.append(self.methodsArray())
4318+ variables.append(self.signalsArray())
4319+ variables.append(self.interfaceStruct())
4320+
4321+ return variables
4322+
4323+ def exports(self):
4324+ """Exports.
4325+
4326+ Returns an array of prototypes for exported variables which are
4327+ placed as a block inside the extern part of the header file.
4328+
4329+ Each export is a (type, name) tuple.
4330+ """
4331+ exports = super(Interface, self).exports()
4332+ if mode == "object":
4333+ exports.append(self.interfacePrototype())
4334+
4335+ return exports
4336+
4337+
4338+class Output(Group):
4339+ def __init__(self, basename, members):
4340+ super(Output, self).__init__(members)
4341+
4342+ self.basename = basename
4343+
4344+ def sourceFile(self):
4345+ """Generate source (.c) file.
4346+
4347+ Returns a string containing the code for the source (.c) file
4348+ of this code group.
4349+ """
4350+ code = """\
4351+/* %s
4352+ *
4353+ * %s - %s
4354+ *
4355+ * %s
4356+ *
4357+ * This program is free software; you can redistribute it and/or modify
4358+ * it under the terms of the GNU General Public License as published by
4359+ * the Free Software Foundation; either version 2 of the License, or
4360+ * (at your option) any later version.
4361+ *
4362+ * This program is distributed in the hope that it will be useful,
4363+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4364+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4365+ * GNU General Public License for more details.
4366+ *
4367+ * You should have received a copy of the GNU General Public License
4368+ * along with this program; if not, write to the Free Software
4369+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
4370+ */
4371+""" % (PACKAGE_NAME, "%s.c" % self.basename, "Auto-generated d-bus bindings",
4372+ PACKAGE_COPYRIGHT)
4373+
4374+ # Usual includes
4375+ if code:
4376+ code += "\n"
4377+ code += """\
4378+#ifdef HAVE_CONFIG_H
4379+# include <config.h>
4380+#endif /* HAVE_CONFIG_H */
4381+
4382+
4383+#include <dbus/dbus.h>
4384+
4385+#include <errno.h>
4386+
4387+#include <nih/macros.h>
4388+#include <nih/alloc.h>
4389+#include <nih/string.h>
4390+#include <nih/logging.h>
4391+#include <nih/error.h>
4392+#include <nih/errors.h>
4393+#include <nih/dbus.h>
4394+
4395+#include "%s.h"
4396+""" % (self.basename, )
4397+ if mode == "proxy":
4398+ if code:
4399+ code += "\n\n"
4400+ code += """\
4401+/**
4402+ * NihAsyncNotifyData:
4403+ * @handler: The user handler that our libnih handler should call,
4404+ * @userdata: Data to pass to @handler,
4405+ * @proxy: The proxy object to which the call was made.
4406+ *
4407+ * This structure contains information that is assembled during an asynchronous
4408+ * method call and passed to the handler on the method's return. It should never
4409+ * be used directly by the user.
4410+ **/
4411+typedef struct nih_async_notify_data {
4412+ void *handler;
4413+ void *err_handler;
4414+ void *userdata;
4415+ NihDBusProxy *proxy;
4416+} NihAsyncNotifyData;"""
4417+ # Extern function prototypes
4418+ protos = self.externPrototypes()
4419+ if protos:
4420+ if code:
4421+ code += "\n\n"
4422+ code += """\
4423+/* Prototypes for handler functions */
4424+"""
4425+ for line in lineup_protos(protos):
4426+ code += line
4427+ code += ";\n"
4428+
4429+ # Static function prototypes
4430+ protos = self.staticPrototypes()
4431+ if protos:
4432+ if code:
4433+ code += "\n\n"
4434+ code += """\
4435+/* Prototypes for static functions */
4436+"""
4437+ for line in lineup_protos(protos):
4438+ code += line
4439+ code += ";\n"
4440+
4441+ # Global variables
4442+ variables = self.variables()
4443+ if variables:
4444+ if code:
4445+ code += "\n"
4446+ for g in variables:
4447+ if code:
4448+ code += "\n"
4449+ code += g
4450+
4451+ # Function definitions
4452+ functions = self.functions()
4453+ if functions:
4454+ if code:
4455+ code += "\n"
4456+ for function in functions:
4457+ if code:
4458+ code += "\n"
4459+ code += function
4460+
4461+ return code
4462+
4463+ def headerFile(self):
4464+ """Generate header (.h) file.
4465+
4466+ Returns a string containing the code for the header (.h) file
4467+ of this code group.
4468+ """
4469+ code = """\
4470+/* %s
4471+ *
4472+ * %s
4473+ *
4474+ * This program is free software; you can redistribute it and/or modify
4475+ * it under the terms of the GNU General Public License as published by
4476+ * the Free Software Foundation; either version 2 of the License, or
4477+ * (at your option) any later version.
4478+ *
4479+ * This program is distributed in the hope that it will be useful,
4480+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4481+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4482+ * GNU General Public License for more details.
4483+ *
4484+ * You should have received a copy of the GNU General Public License
4485+ * along with this program; if not, write to the Free Software
4486+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
4487+ */
4488+""" % (PACKAGE_NAME, PACKAGE_COPYRIGHT)
4489+
4490+ # FIXME include sub-directory name in sentry?
4491+ sentry = "DBUS__%s_H" % self.basename.replace(".", "_").upper()
4492+ if code:
4493+ code += "\n"
4494+ code += """\
4495+#ifndef %s
4496+#define %s
4497+
4498+#include <dbus/dbus.h>
4499+
4500+#include <nih/macros.h>
4501+#include <nih/dbus.h>
4502+""" % (sentry, sentry)
4503+
4504+ # Append structure definitions
4505+ definitions = self.definitions()
4506+ if definitions:
4507+ if code:
4508+ code += "\n"
4509+ for definition in definitions:
4510+ if code:
4511+ code += "\n"
4512+ code += definition
4513+
4514+ # Typedefs
4515+ typedefs = self.exportTypedefs()
4516+ if typedefs:
4517+ if code:
4518+ code += "\n\n"
4519+ for line in lineup_typedefs(typedefs):
4520+ code += line
4521+ code += "\n"
4522+
4523+ # Guard extern prototypes for C++ inclusion
4524+ if code:
4525+ code += "\n\n"
4526+ code += """\
4527+NIH_BEGIN_EXTERN
4528+"""
4529+
4530+ # Line up the variable prototypes together and place in a block
4531+ globals = self.exports()
4532+ if globals:
4533+ if code:
4534+ code += "\n"
4535+ for line in lineup_vars(globals):
4536+ code += line
4537+ code += ";\n"
4538+
4539+ # Line up the function prototypes together and place in a block
4540+ protos = self.exportPrototypes()
4541+ if protos:
4542+ if code:
4543+ code += "\n"
4544+ for line in lineup_protos(protos):
4545+ code += line
4546+ code += ";\n"
4547+
4548+ # End the extern guard and header sentry
4549+ if code:
4550+ code += "\n"
4551+ code += """\
4552+NIH_END_EXTERN
4553+
4554+#endif /* %s */
4555+""" % (sentry)
4556+
4557+ return code
4558+
4559+
4560+# Complex:
4561+# s (struct) -> pointer to a struct of a defined type (named after func + arg)
4562+# e.g. typedef struct job_find_by_name_what {
4563+# ...
4564+# } JobFindByNameWhat;
4565+#
4566+# dbus_message_iter_recurse (ITER, SUB)
4567+# OK = dbus_message_iter_close_container (ITER, SUB)
4568+#
4569+# dbus_message_iter_open_container (ITER, TYPE, NULL, SUB)
4570+# OK = dbus_message_iter_close_container (ITER, SUB)
4571+#
4572+# thus we can make arrays of it too :-)
4573+# struct-in-struct can just get arbitrary names
4574+#
4575+#
4576+# Annoying"
4577+# v (variant) -> seems to be a problem
4578+# has a type signature then the data
4579+#
4580+# e (dict) -> problem for now (should be NihHash really)
4581+# always arrays a{..}
4582+# first type is basic
4583+# second type is any (including struct)
4584+
4585+
4586+def lineup_vars(vars):
4587+ """Lineup variable lists.
4588+
4589+ Returns an array of lines of C code to declare each of the variables
4590+ in vars, which should be an array of (type, name) tuples. The
4591+ declarations will be lined up in a pretty fashion.
4592+
4593+ It is up to the caller to add appropriate line-endings.
4594+ """
4595+ exp_vars = []
4596+ for type, name in vars:
4597+ basic = type.rstrip("*")
4598+ pointers = type[len(basic):]
4599+ basic = basic.rstrip()
4600+ exp_vars.append(( basic, pointers, name ))
4601+
4602+ if not exp_vars:
4603+ return []
4604+
4605+ max_basic = max(len(b) for b,p,n in exp_vars)
4606+ max_pointers = max(len(p) for b,p,n in exp_vars)
4607+
4608+ lines = []
4609+ for basic, pointers, name in exp_vars:
4610+ code = basic.ljust(max_basic)
4611+ code += pointers.rjust(max_pointers + 1)
4612+ code += name
4613+
4614+ lines.append(code)
4615+
4616+ return lines
4617+
4618+def typedef_lineup_prefix(type):
4619+ """Pads a type name on the left so indent starts past (*
4620+
4621+ If a string begins with (* returns it. If it begins with * pad it on the
4622+ left with one space. If it begins with 0 pad with two spaces.
4623+ """
4624+ if type.startswith("(*"):
4625+ return type
4626+ if type.startswith("*"):
4627+ return " " + type
4628+ return " " + type
4629+
4630+def lineup_typedefs(typedefs):
4631+ """ Lineup typedef lists.
4632+
4633+ Returns an array of lines of C code to declare each of the typedefs
4634+ in typedefs, which should be an array of (type, name, args)
4635+ """
4636+ defs = []
4637+ max_type = max(len(t) for t,n,a in typedefs)
4638+ max_name = max(len(typedef_lineup_prefix(n)) for t,n,a in typedefs)
4639+
4640+ for type,name,args in typedefs:
4641+ code = "typedef "
4642+ code += type.ljust(max_type+1)
4643+ code += typedef_lineup_prefix(name).ljust(max_name+1)
4644+ code += "("
4645+ code += ", ".join("%s%s%s" % (type, not type.endswith("*") and " " or "",
4646+ name) for type,name in args)
4647+ code += ");"
4648+ defs.append(code)
4649+
4650+ return defs
4651+
4652+def lineup_protos(protos):
4653+ """Lineup prototype lists.
4654+
4655+ Returns an array of lines of C code to declare each of the prototypes
4656+ in protos, which should be an array of (retval, name, args, attributes)
4657+ tuples. The declarations will be lined up in a pretty fashion.
4658+
4659+ It is up to the caller to add appropriate line-endings.
4660+ """
4661+ if not protos:
4662+ return []
4663+
4664+ max_retval = max(len(r) for r,n,a,at in protos)
4665+ max_name = max(len(n) for r,n,a,at in protos)
4666+
4667+ if not [ True for r,n,a,at in protos if r.endswith("*") ]:
4668+ max_retval += 1
4669+
4670+ lines = []
4671+ for retval, name, args, attributes in protos:
4672+ code = retval.ljust(max_retval)
4673+ code += name.ljust(max_name + 1)
4674+ code += "("
4675+ # FIXME split arguments over multiple lines maybe?
4676+ code += ", ".join("%s%s%s" % (type, not type.endswith("*") and " " or "",
4677+ name) for type,name in args)
4678+ code += ")"
4679+ if attributes:
4680+ code += "\n\t__attribute__ ((" + ", ".join(attributes) + "))"
4681+
4682+ lines.append(code)
4683+
4684+ return lines
4685+
4686+def camelate(string):
4687+ """Make a _-delimited string CamelCase.
4688+
4689+ Not much else to say.
4690+ """
4691+ return "".join([ x.capitalize() for x in string.split("_") ])
4692+
4693+def lineup_array(array):
4694+ """Lineup array definitions.
4695+
4696+ Returns an array of lines of C code to declare each of the array struct
4697+ definitions in array, which should be an array of tuples for each structure
4698+ member. The declarations will be lined up in a pretty fashion.
4699+
4700+ It is up to the caller to add appropriate line-endings.
4701+ """
4702+ if not array:
4703+ return []
4704+
4705+ max_len = [ max(len(entry[i]) for entry in array)
4706+ for i in range(0, len(array[0])) ]
4707+
4708+ lines = []
4709+ for entry in array:
4710+ code = "{ "
4711+
4712+ for i, str in enumerate(entry):
4713+ if i < len(array[0]) - 1:
4714+ code += (str + ", ").ljust(max_len[i] + 2)
4715+ else:
4716+ code += str.ljust(max_len[i])
4717+
4718+ code += " }"
4719+
4720+ lines.append(code)
4721+
4722+ return lines
4723+
4724+
4725+def indent(str, level):
4726+ """Increase indent of string.
4727+
4728+ Returns the string with each line indented to the given level of tabs.
4729+ """
4730+ output = ""
4731+ for line in str.splitlines(True):
4732+ if len(line.strip()):
4733+ output += ("\t" * level) + line
4734+ else:
4735+ output += line
4736+ return output
4737+
4738+
4739+def pointerify(type):
4740+ """Turn C type into a pointer.
4741+
4742+ Returns the string for a pointer to the given C type.
4743+ """
4744+ if type.endswith("*"):
4745+ return type + "*"
4746+ else:
4747+ return type + " *"
4748+
4749+def constify(type):
4750+ """Type C pointer type into a const pointer.
4751+
4752+ Returns the string modified so that the pointer is a const pointer.
4753+ """
4754+ if not type.endswith("*"):
4755+ return type
4756+
4757+ if type[:-1].endswith("*"):
4758+ return type[:-1] + " const *"
4759+ else:
4760+ return "const " + type
4761+
4762+
4763+def main():
4764+ global options
4765+ global extern_prefix
4766+ global mode
4767+
4768+ usage = "%prog [OPTION]... XMLFILE"
4769+ description = """\
4770+XMLFILE is a valid XML file containing information about one or more interfaces
4771+in the D-Bus Introspection format, except that the top-level node may be
4772+interface as well as node.
4773+
4774+C code to marshal methods and dispatch signals (if --mode is object) or to
4775+dispatch methods and marshal signals (if --mode is proxy) is written to
4776+a .c and .h file in the current directory with the same base name as XMLFILE,
4777+or to that specified by --output.
4778+"""
4779+
4780+ parser = OptionParser(usage, description=description)
4781+ parser.add_option("--mode", type="string", metavar="MODE",
4782+ default="object",
4783+ help="Output mode: object, or proxy [default: %default]")
4784+ parser.add_option("-o", "--output", type="string", metavar="FILENAME",
4785+ help="Write C source to FILENAME, header alongside")
4786+ parser.add_option("--prefix", type="string", metavar="PREFIX",
4787+ default="dbus",
4788+ help="Prefix for externally supplied C functions [default: %default]")
4789+
4790+ (options, args) = parser.parse_args()
4791+ if len(args) != 1:
4792+ parser.error("incorrect number of arguments")
4793+ if options.mode not in ("object", "proxy"):
4794+ parser.error("invalid mode")
4795+
4796+ extern_prefix = options.prefix
4797+ mode = options.mode
4798+
4799+ # Figure out input and output filenames based on arguments; try and
4800+ # do the right thing in most circumstances
4801+ xml_filename = args.pop(0)
4802+ if options.output:
4803+ (root, ext) = os.path.splitext(options.output)
4804+ if ext and ext != ".h":
4805+ source_filename = options.output
4806+ else:
4807+ source_filename = os.path.extsep.join(( root, "c" ))
4808+
4809+ header_filename = os.path.extsep.join (( root, "h"))
4810+ basename = os.path.basename(root)
4811+ else:
4812+ basename = os.path.splitext(os.path.basename(xml_filename))[0]
4813+ source_filename = os.path.extsep.join(( basename, "c" ))
4814+ header_filename = os.path.extsep.join(( basename, "h" ))
4815+
4816+ (head, tail) = os.path.split(source_filename)
4817+ tmp_source_filename = os.path.join(head, ".%s.tmp" % tail)
4818+
4819+ (head, tail) = os.path.split(header_filename)
4820+ tmp_header_filename = os.path.join(head, ".%s.tmp" % tail)
4821+
4822+
4823+ # Parse the XML file into an ElementTree
4824+ tree = ElementTree.parse(xml_filename)
4825+ elem = tree.getroot()
4826+
4827+ # Walk the tree to find interfaces
4828+ interfaces = []
4829+ if elem.tag == "interface":
4830+ interfaces.append(Interface.fromElement(elem))
4831+ else:
4832+ for iface_e in elem.findall("interface"):
4833+ interfaces.append(Interface.fromElement(iface_e))
4834+
4835+ # Generate and write output
4836+ o = Output(basename, interfaces)
4837+ try:
4838+ f = open(tmp_source_filename, "w")
4839+ try:
4840+ print >>f, o.sourceFile()
4841+ finally:
4842+ f.close()
4843+
4844+ f = open(tmp_header_filename, "w")
4845+ try:
4846+ print >>f, o.headerFile()
4847+ finally:
4848+ f.close()
4849+
4850+ os.rename(tmp_source_filename, source_filename)
4851+ os.rename(tmp_header_filename, header_filename)
4852+ except:
4853+ if os.path.exists(tmp_source_filename):
4854+ os.unlink(tmp_source_filename)
4855+ if os.path.exists(tmp_header_filename):
4856+ os.unlink(tmp_header_filename)
4857+
4858+ raise
4859+
4860+
4861+if __name__ == "__main__":
4862+ main()

Subscribers

People subscribed via source and target branches

to all changes:
to status/vote changes: