Merge lp://staging/~cjdahlin/libnih/async into lp://staging/libnih/1.0
- async
- Merge into trunk
Proposed by
Scott James Remnant (Canonical)
Status: | Merged |
---|---|
Merge reported by: | Scott James Remnant (Canonical) |
Merged at revision: | not available |
Proposed branch: | lp://staging/~cjdahlin/libnih/async |
Merge into: | lp://staging/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://staging/~cjdahlin/libnih/async |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Scott James Remnant (Canonical) | Approve | ||
Review via email: mp+12818@code.staging.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
Revision history for this message
Scott James Remnant (Canonical) (canonical-scott) wrote : | # |
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() |
This got merged and then improved, thanks Casey!