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

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

This got merged and then improved, thanks Casey!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'ChangeLog'
--- ChangeLog 2009-08-11 10:30:25 +0000
+++ ChangeLog 2009-10-03 06:00:27 +0000
@@ -1,3 +1,4 @@
1<<<<<<< TREE
12009-08-11 Scott James Remnant <scott@netsplit.com>22009-08-11 Scott James Remnant <scott@netsplit.com>
23
3 * nih/test_alloc.h (TEST_ALLOC_NOT_PARENT): Add the opposite test4 * nih/test_alloc.h (TEST_ALLOC_NOT_PARENT): Add the opposite test
@@ -2671,6 +2672,33 @@
2671 Fix the test case to not compare a void * with strcmp2672 Fix the test case to not compare a void * with strcmp
26722673
26732008-01-29 Casey Dahlin <cdahlin@redhat.com>26742008-01-29 Casey Dahlin <cdahlin@redhat.com>
2675=======
26762009-2-09 Casey Dahlin <cdahlin@redhat.com>
2677
2678 * nih/tests/test_com.netsplit.Nih.Test_proxy.c: Even more tests for
2679 async calls.
2680
26812009-2-01 Casey Dahlin <cdahlin@redhat.com>
2682
2683 * nih/nih_dbus_tool.py (Method.asyncDispatchPrototype): Rename
2684 typedefs for callbacks from NihDBusCallback_foo_method to
2685 FooMethodCallback. Same for Errback.
2686
2687 * nih/nih_dbus_tool.py (Method.asyncDispatchFunction): Check for and
2688 properly handle error returns fron DBus. Also be sure to call the
2689 errback for various memory/parse errors.
2690
2691 * nih/nih_dbus_tool.py (Method.exportTypedefs): More changes for new
2692 typedef names.
2693
2694 * nih/nih_dbus_tool.py (camelate): New function to convert
2695 underscore_delineated to CamelCase.
2696
2697 * nih/tests/test_com.netsplit.Nih.Test_proxy.c: Loads more tests for
2698 async calls.
2699
27002009-1-29 Casey Dahlin <cdahlin@redhat.com>
2701>>>>>>> MERGE-SOURCE
26742702
2675 * nih/nih_dbus_tool.py (Method.asyncDispatchPrototype): Prototype for2703 * nih/nih_dbus_tool.py (Method.asyncDispatchPrototype): Prototype for
2676 new asynchronous dispatch function, explained below.2704 new asynchronous dispatch function, explained below.
26772705
=== modified file 'nih-dbus-tool/tests/test_com.netsplit.Nih.Test_proxy.c'
--- nih-dbus-tool/tests/test_com.netsplit.Nih.Test_proxy.c 2009-08-03 15:29:45 +0000
+++ nih-dbus-tool/tests/test_com.netsplit.Nih.Test_proxy.c 2009-10-03 06:00:27 +0000
@@ -37,6 +37,7 @@
37#include <nih/signal.h>37#include <nih/signal.h>
38#include <nih/main.h>38#include <nih/main.h>
39#include <nih/error.h>39#include <nih/error.h>
40<<<<<<< TREE
4041
41#include <nih-dbus/dbus_connection.h>42#include <nih-dbus/dbus_connection.h>
42#include <nih-dbus/dbus_object.h>43#include <nih-dbus/dbus_object.h>
@@ -50204,6 +50205,2167 @@
50204 TEST_DBUS_END (dbus_pid);50205 TEST_DBUS_END (dbus_pid);
5020550206
50206 dbus_shutdown ();50207 dbus_shutdown ();
50208=======
50209#include <nih/errors.h>
50210
50211#include <nih/dbus.h>
50212
50213#include "com.netsplit.Nih.Test_proxy.h"
50214#include "com.netsplit.Nih.Test_impl.h"
50215
50216
50217static void async_fail_errback (NihDBusProxy *my_proxy, void *userdata);
50218
50219void
50220test_method_dispatch (void)
50221{
50222 DBusConnection *conn;
50223 NihDBusProxy *proxy;
50224 NihError *err;
50225 NihDBusError *dbus_err;
50226 char *output;
50227 uint8_t byte_arg;
50228 int boolean_arg;
50229 int16_t int16_arg;
50230 uint16_t uint16_arg;
50231 int32_t int32_arg;
50232 uint32_t uint32_arg;
50233 int64_t int64_arg;
50234 uint64_t uint64_arg;
50235 double double_arg;
50236 int32_t *int32_array;
50237 char **str_array;
50238 size_t array_len;
50239 int ret;
50240 int called;
50241
50242 TEST_GROUP ("method dispatching");
50243
50244
50245 /* Check that we can make a D-Bus method call, passing in the
50246 * expected arguments and receiving the expected arguments in the
50247 * reply.
50248 */
50249 TEST_FEATURE ("with valid argument");
50250 conn = my_setup ();
50251 proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
50252
50253 output = NULL;
50254
50255 ret = proxy_test_method (proxy, "test data", 0, &output);
50256
50257 TEST_EQ (ret, 0);
50258
50259 TEST_NE_P (output, NULL);
50260 TEST_ALLOC_PARENT (output, proxy);
50261 TEST_EQ_STR (output, "test data");
50262
50263 nih_free (proxy);
50264
50265 my_teardown (conn);
50266
50267
50268 /* Check that we can make an asynchronous D-Bus method call, passing in
50269 * the expected arguments and receiving the expected arguments in the
50270 * callback.
50271 */
50272 TEST_FEATURE ("with valid argument (async)");
50273 conn = my_setup ();
50274 proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
50275
50276 auto void async_with_valid_argument (NihDBusProxy *proxy, void *userdata, char *output);
50277
50278 called = 0;
50279
50280 ret = proxy_test_method_async (proxy, "test data", 0,
50281 async_with_valid_argument, async_fail_errback, "userdata");
50282
50283 TEST_EQ (ret, 0);
50284
50285 void async_with_valid_argument (NihDBusProxy *my_proxy, void *userdata, char *async_output)
50286 {
50287 TEST_NE_P (async_output, NULL);
50288 TEST_ALLOC_PARENT (async_output, proxy);
50289 TEST_EQ_STR (async_output, "test data");
50290 TEST_EQ_STR (userdata, "userdata");
50291 TEST_EQ_P (my_proxy, proxy);
50292 called = 1;
50293 }
50294
50295 while (! called)
50296 dbus_connection_read_write_dispatch (conn, -1);
50297
50298 nih_free (proxy);
50299
50300 my_teardown (conn);
50301
50302
50303 /* Check that if the method call returns a D-Bus error, the async proxy
50304 * call triggers the error handler and sets the appropriate error.
50305 */
50306 TEST_FEATURE ("with returned D-Bus error");
50307 conn = my_setup ();
50308 proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
50309
50310 output = NULL;
50311
50312 ret = proxy_test_method (proxy, "test data", 1, &output);
50313
50314 TEST_LT (ret, 1);
50315
50316 err = nih_error_get ();
50317 TEST_EQ (err->number, NIH_DBUS_ERROR);
50318 TEST_ALLOC_SIZE (err, sizeof (NihDBusError));
50319
50320 dbus_err = (NihDBusError *)err;
50321 TEST_EQ_STR (dbus_err->name, "com.netsplit.Nih.IllegalValue");
50322
50323 nih_free (dbus_err);
50324
50325 nih_free (proxy);
50326
50327 my_teardown (conn);
50328
50329
50330 /* Check that if the method call returns a D-Bus error, the proxy
50331 * call returns a negative number and raises the same D-Bus error.
50332 */
50333 TEST_FEATURE ("with returned D-Bus error (async)");
50334 conn = my_setup ();
50335 proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
50336
50337 output = NULL;
50338
50339 auto void async_with_dbus_error_errback (NihDBusProxy *proxy, void *userdata);
50340
50341 called = 0;
50342
50343 ret = proxy_test_method_async (proxy, "test data", 1, (ProxyTestMethodCallback)async_fail_errback,
50344 async_with_dbus_error_errback,"user data");
50345
50346 TEST_EQ (ret, 0);
50347
50348 void async_with_dbus_error_errback (NihDBusProxy *my_proxy, void *userdata)
50349 {
50350 err = nih_error_get ();
50351 TEST_EQ (err->number, NIH_DBUS_ERROR);
50352 TEST_ALLOC_SIZE (err, sizeof (NihDBusError));
50353
50354 dbus_err = (NihDBusError *)err;
50355 TEST_EQ_STR (dbus_err->name, "com.netsplit.Nih.IllegalValue");
50356 TEST_EQ_STR (userdata, "user data");
50357 TEST_EQ_P (my_proxy, proxy);
50358 called = 1;
50359 }
50360
50361 while (! called)
50362 dbus_connection_read_write_dispatch (conn, -1);
50363
50364 nih_free (dbus_err);
50365
50366 nih_free (proxy);
50367
50368 my_teardown (conn);
50369
50370
50371 /* Check that in out of memory conditions, D-Bus automatically
50372 * repeats the method call so we don't notice on the client side.
50373 */
50374 TEST_FEATURE ("with out of memory error");
50375 conn = my_setup ();
50376 proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
50377
50378 output = NULL;
50379
50380 ret = proxy_test_method (proxy, "test data", 2, &output);
50381
50382 TEST_EQ (ret, 0);
50383
50384 TEST_NE_P (output, NULL);
50385 TEST_ALLOC_PARENT (output, proxy);
50386 TEST_EQ_STR (output, "test data");
50387
50388 nih_free (proxy);
50389
50390 my_teardown (conn);
50391
50392
50393 /* Check that in out of memory conditions, D-Bus automatically
50394 * repeats the method call so we don't notice on the client side, even
50395 * when the call is asynchronous.
50396 */
50397 TEST_FEATURE ("with out of memory error (async)");
50398 conn = my_setup ();
50399 proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
50400
50401 auto void async_with_oom (NihDBusProxy *proxy, void *userdata, char *output);
50402
50403 called = 0;
50404
50405 ret = proxy_test_method_async (proxy, "test data", 2,
50406 async_with_valid_argument, async_fail_errback, "userdata");
50407
50408 TEST_EQ (ret, 0);
50409
50410 void async_with_oom (NihDBusProxy *my_proxy, void *userdata, char *async_output)
50411 {
50412 TEST_NE_P (async_output, NULL);
50413 TEST_ALLOC_PARENT (async_output, proxy);
50414 TEST_EQ_STR (async_output, "test data");
50415 TEST_EQ_STR (userdata, "userdata");
50416 TEST_EQ_P (my_proxy, proxy);
50417 called = 1;
50418 }
50419
50420 while (! called)
50421 dbus_connection_read_write_dispatch (conn, -1);
50422
50423 nih_free (proxy);
50424
50425 my_teardown (conn);
50426
50427
50428 /* Check that an error unknown to D-Bus is turned into a generic
50429 * failed error.
50430 */
50431 TEST_FEATURE ("with unknown error");
50432 conn = my_setup ();
50433 proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
50434
50435 output = NULL;
50436
50437 ret = proxy_test_method (proxy, "test data", 3, &output);
50438
50439 TEST_LT (ret, 1);
50440
50441 err = nih_error_get ();
50442 TEST_EQ (err->number, NIH_DBUS_ERROR);
50443 TEST_ALLOC_SIZE (err, sizeof (NihDBusError));
50444
50445 dbus_err = (NihDBusError *)err;
50446 TEST_EQ_STR (dbus_err->name, DBUS_ERROR_FAILED);
50447
50448 nih_free (dbus_err);
50449
50450 nih_free (proxy);
50451
50452 my_teardown (conn);
50453
50454
50455 /* Check that an error unknown to D-Bus is turned into a generic
50456 * failed error for an async call.
50457 */
50458 TEST_FEATURE ("with unknown error (async)");
50459 conn = my_setup ();
50460 proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
50461
50462 auto void async_with_unknown (NihDBusProxy *proxy, void *userdata);
50463
50464 called = 0;
50465
50466 ret = proxy_test_method_async (proxy, "test data", 3,
50467 (ProxyTestMethodCallback)async_fail_errback, async_with_unknown, "userdata");
50468
50469 TEST_EQ (ret, 0);
50470
50471 void async_with_unknown (NihDBusProxy *my_proxy, void *userdata)
50472 {
50473 err = nih_error_get ();
50474 TEST_EQ (err->number, NIH_DBUS_ERROR);
50475 TEST_ALLOC_SIZE (err, sizeof (NihDBusError));
50476
50477 dbus_err = (NihDBusError *)err;
50478 TEST_EQ_STR (dbus_err->name, DBUS_ERROR_FAILED);
50479
50480 nih_free (dbus_err);
50481
50482 TEST_EQ_STR (userdata, "userdata");
50483 TEST_EQ_P (my_proxy, proxy);
50484 called = 1;
50485 }
50486
50487 while (! called)
50488 dbus_connection_read_write_dispatch (conn, -1);
50489
50490 nih_free (proxy);
50491
50492 my_teardown (conn);
50493
50494
50495 /* Check that the fact the server implementation is asynchronous
50496 * is hidden and the call blocks until the reply comes back anyway.
50497 */
50498 TEST_FEATURE ("with valid argument to async call");
50499 conn = my_setup ();
50500 proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
50501
50502 output = NULL;
50503
50504 ret = proxy_test_async_method (proxy, "test data", 0, &output);
50505
50506 TEST_EQ (ret, 0);
50507
50508 TEST_NE_P (output, NULL);
50509 TEST_ALLOC_PARENT (output, proxy);
50510 TEST_EQ_STR (output, "test data");
50511
50512 nih_free (proxy);
50513
50514 my_teardown (conn);
50515
50516
50517 /* Check that the fact the server implementation is asynchronous
50518 * doesn't affect asynchronous calls from us.
50519 */
50520 TEST_FEATURE ("with valid argument to async call (async)");
50521 conn = my_setup ();
50522 proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
50523
50524 auto void async_with_async (NihDBusProxy *my_proxy, void *userdata, char *async_output);
50525
50526 called = 0;
50527
50528 ret = proxy_test_async_method_async (proxy, "test data", 0,
50529 async_with_async, async_fail_errback, "userdata");
50530
50531 TEST_EQ (ret, 0);
50532
50533 void async_with_async (NihDBusProxy *my_proxy, void *userdata, char *async_output)
50534 {
50535 TEST_NE_P (async_output, NULL);
50536 TEST_ALLOC_PARENT (async_output, proxy);
50537 TEST_EQ_STR (async_output, "test data");
50538 TEST_EQ_STR (userdata, "userdata");
50539 TEST_EQ_P (my_proxy, proxy);
50540 called = 1;
50541 }
50542
50543 while (! called)
50544 dbus_connection_read_write_dispatch (conn, -1);
50545
50546 nih_free (proxy);
50547
50548 my_teardown (conn);
50549
50550
50551 /* Check that an error returned from an asynchronous server-side
50552 * call still comes back as an error.
50553 */
50554 TEST_FEATURE ("with returned D-Bus error from async call");
50555 conn = my_setup ();
50556 proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
50557
50558 output = NULL;
50559
50560 ret = proxy_test_async_method (proxy, "test data", 1, &output);
50561
50562 TEST_LT (ret, 1);
50563
50564 err = nih_error_get ();
50565 TEST_EQ (err->number, NIH_DBUS_ERROR);
50566 TEST_ALLOC_SIZE (err, sizeof (NihDBusError));
50567
50568 dbus_err = (NihDBusError *)err;
50569 TEST_EQ_STR (dbus_err->name, "com.netsplit.Nih.IllegalValue");
50570
50571 nih_free (dbus_err);
50572
50573 nih_free (proxy);
50574
50575 my_teardown (conn);
50576
50577
50578 /* Check that an error returned from an asynchronous server-side
50579 * call still comes back as an error to an async client call.
50580 */
50581 TEST_FEATURE ("with returned D-Bus error from async call (async)");
50582 conn = my_setup ();
50583 proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
50584
50585 auto void async_with_async_err (NihDBusProxy *my_proxy, void *userdata);
50586
50587 called = 0;
50588
50589 ret = proxy_test_async_method_async (proxy, "test data", 1,
50590 (ProxyTestAsyncMethodCallback)async_fail_errback, async_with_async_err, "userdata");
50591
50592 TEST_EQ (ret, 0);
50593
50594 void async_with_async_err (NihDBusProxy *my_proxy, void *userdata)
50595 {
50596 err = nih_error_get ();
50597 TEST_EQ (err->number, NIH_DBUS_ERROR);
50598 TEST_ALLOC_SIZE (err, sizeof (NihDBusError));
50599
50600 dbus_err = (NihDBusError *)err;
50601 TEST_EQ_STR (dbus_err->name, "com.netsplit.Nih.IllegalValue");
50602
50603 nih_free (dbus_err);
50604
50605 TEST_EQ_STR (userdata, "userdata");
50606 TEST_EQ_P (my_proxy, proxy);
50607 called = 1;
50608 }
50609
50610 while (! called)
50611 dbus_connection_read_write_dispatch (conn, -1);
50612
50613 nih_free (proxy);
50614
50615 my_teardown (conn);
50616
50617
50618 /* Check that in out of memory conditions, D-Bus automatically
50619 * repeats the method call so we don't notice on the client side
50620 * even for async server-side calls.
50621 */
50622 TEST_FEATURE ("with out of memory error from async call");
50623 conn = my_setup ();
50624 proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
50625
50626 output = NULL;
50627
50628 ret = proxy_test_async_method (proxy, "test data", 2, &output);
50629
50630 TEST_EQ (ret, 0);
50631
50632 TEST_NE_P (output, NULL);
50633 TEST_ALLOC_PARENT (output, proxy);
50634 TEST_EQ_STR (output, "test data");
50635
50636 nih_free (proxy);
50637
50638 my_teardown (conn);
50639
50640
50641 /* Check that in out of memory conditions, D-Bus automatically
50642 * repeats the method call so we don't notice on the client side
50643 * even for async server-side calls, when our call was async.
50644 */
50645 TEST_FEATURE ("with out of memory error from async call (async)");
50646 conn = my_setup ();
50647 proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
50648
50649 auto void async_with_async_oom (NihDBusProxy *my_proxy, void *userdata, char *async_output);
50650
50651 called = 0;
50652
50653 ret = proxy_test_async_method_async (proxy, "test data", 2,
50654 async_with_async_oom, async_fail_errback, "userdata");
50655
50656 TEST_EQ (ret, 0);
50657
50658 void async_with_async_oom (NihDBusProxy *my_proxy, void *userdata, char *async_output)
50659 {
50660 TEST_NE_P (async_output, NULL);
50661 TEST_ALLOC_PARENT (async_output, proxy);
50662 TEST_EQ_STR (async_output, "test data");
50663 TEST_EQ_STR (userdata, "userdata");
50664 TEST_EQ_P (my_proxy, proxy);
50665 called = 1;
50666 }
50667
50668 while (! called)
50669 dbus_connection_read_write_dispatch (conn, -1);
50670
50671 nih_free (proxy);
50672
50673 my_teardown (conn);
50674
50675
50676 /* Check that an error unknown to D-Bus is turned into a generic
50677 * failed error.
50678 */
50679 TEST_FEATURE ("with unknown error from async call");
50680 conn = my_setup ();
50681 proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
50682
50683 output = NULL;
50684
50685 ret = proxy_test_async_method (proxy, "test data", 3, &output);
50686
50687 TEST_LT (ret, 1);
50688
50689 err = nih_error_get ();
50690 TEST_EQ (err->number, NIH_DBUS_ERROR);
50691 TEST_ALLOC_SIZE (err, sizeof (NihDBusError));
50692
50693 dbus_err = (NihDBusError *)err;
50694 TEST_EQ_STR (dbus_err->name, DBUS_ERROR_FAILED);
50695
50696 nih_free (dbus_err);
50697
50698 nih_free (proxy);
50699
50700 my_teardown (conn);
50701
50702
50703 /* Check that an error unknown to D-Bus is turned into a generic
50704 * failed error for an async call.
50705 */
50706 TEST_FEATURE ("with unknown error from async call (async)");
50707 conn = my_setup ();
50708 proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
50709
50710 auto void async_with_async_unknown (NihDBusProxy *my_proxy, void *userdata);
50711
50712 called = 0;
50713
50714 ret = proxy_test_async_method_async (proxy, "test data", 3,
50715 (ProxyTestAsyncMethodCallback)async_fail_errback, async_with_async_unknown, "userdata");
50716
50717 TEST_EQ (ret, 0);
50718
50719 void async_with_async_unknown (NihDBusProxy *my_proxy, void *userdata)
50720 {
50721 err = nih_error_get ();
50722 TEST_EQ (err->number, NIH_DBUS_ERROR);
50723 TEST_ALLOC_SIZE (err, sizeof (NihDBusError));
50724
50725 dbus_err = (NihDBusError *)err;
50726 TEST_EQ_STR (dbus_err->name, DBUS_ERROR_FAILED);
50727
50728 nih_free (dbus_err);
50729
50730 TEST_EQ_STR (userdata, "userdata");
50731 TEST_EQ_P (my_proxy, proxy);
50732 called = 1;
50733 }
50734
50735 while (! called)
50736 dbus_connection_read_write_dispatch (conn, -1);
50737
50738 nih_free (proxy);
50739
50740 my_teardown (conn);
50741
50742
50743 /* Check that a condition whereby the wrong arguments are returned
50744 * from a method call results in a special illegal arguments error
50745 * being returned.
50746 */
50747 TEST_FEATURE ("with wrong argument type in reply");
50748 conn = my_setup ();
50749 proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
50750
50751 output = NULL;
50752
50753 ret = proxy_test_async_method (proxy, "test data", 4, &output);
50754
50755 TEST_LT (ret, 1);
50756
50757 err = nih_error_get ();
50758 TEST_EQ (err->number, NIH_DBUS_INVALID_ARGS);
50759 nih_free (err);
50760
50761 nih_free (proxy);
50762
50763 my_teardown (conn);
50764
50765
50766 /* Check that a condition whereby the wrong arguments are returned
50767 * from a method call results in a special illegal arguments error
50768 * being passed to the errback.
50769 */
50770 TEST_FEATURE ("with wrong argument type in reply (async)");
50771 conn = my_setup ();
50772 proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
50773
50774 auto void with_wrong_argument_type_in_reply_async (NihDBusProxy *my_proxy, void *userdata);
50775
50776 called = 0;
50777
50778 ret = proxy_test_async_method_async (proxy, "test data", 4,
50779 (ProxyTestAsyncMethodCallback)async_fail_errback,
50780 with_wrong_argument_type_in_reply_async, "userdata");
50781
50782 TEST_EQ (ret, 0);
50783
50784 void with_wrong_argument_type_in_reply_async (NihDBusProxy *my_proxy, void *userdata)
50785 {
50786 err = nih_error_get ();
50787 TEST_EQ (err->number, NIH_DBUS_INVALID_ARGS);
50788 nih_free (err);
50789 TEST_EQ_STR (userdata, "userdata");
50790 TEST_EQ_P (my_proxy, proxy);
50791 called = 1;
50792 }
50793
50794 while (! called)
50795 dbus_connection_read_write_dispatch (conn, -1);
50796
50797 nih_free (proxy);
50798
50799 my_teardown (conn);
50800
50801
50802 /* Check that a condition whereby too many arguments are returned
50803 * from a method call results in a special illegal arguments error
50804 * being returned.
50805 */
50806 TEST_FEATURE ("with too many arguments in reply");
50807 conn = my_setup ();
50808 proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
50809
50810 auto void with_too_many_args_in_reply_async (NihDBusProxy *my_proxy, void *userdata);
50811
50812 called = 0;
50813
50814 ret = proxy_test_async_method_async (proxy, "test data", 5,
50815 (ProxyTestAsyncMethodCallback)async_fail_errback,
50816 with_too_many_args_in_reply_async, "userdata");
50817
50818 TEST_EQ (ret, 0);
50819
50820 void with_too_many_args_in_reply_async (NihDBusProxy *my_proxy, void *userdata)
50821 {
50822 err = nih_error_get ();
50823 TEST_EQ (err->number, NIH_DBUS_INVALID_ARGS);
50824 nih_free (err);
50825 TEST_EQ_STR (userdata, "userdata");
50826 TEST_EQ_P (my_proxy, proxy);
50827 called = 1;
50828 }
50829
50830 while (! called)
50831 dbus_connection_read_write_dispatch (conn, -1);
50832
50833 nih_free (proxy);
50834
50835 my_teardown (conn);
50836
50837
50838 /* Check that a condition whereby too many arguments are returned
50839 * from a method call results in a special illegal arguments error
50840 * being passed to the errback.
50841 */
50842 TEST_FEATURE ("with too many arguments in reply (async)");
50843 conn = my_setup ();
50844 proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
50845
50846 output = NULL;
50847
50848 ret = proxy_test_async_method (proxy, "test data", 5, &output);
50849
50850 TEST_LT (ret, 1);
50851
50852 err = nih_error_get ();
50853 TEST_EQ (err->number, NIH_DBUS_INVALID_ARGS);
50854 nih_free (err);
50855
50856 nih_free (proxy);
50857
50858 my_teardown (conn);
50859
50860
50861 /* Check that a condition whereby arguments are missing from the
50862 * method call return results in a special illegal arguments error
50863 * being returned.
50864 */
50865 TEST_FEATURE ("with missing arguments in reply");
50866 conn = my_setup ();
50867 proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
50868
50869 output = NULL;
50870
50871 ret = proxy_test_async_method (proxy, "test data", 6, &output);
50872
50873 TEST_LT (ret, 1);
50874
50875 err = nih_error_get ();
50876 TEST_EQ (err->number, NIH_DBUS_INVALID_ARGS);
50877 nih_free (err);
50878
50879 nih_free (proxy);
50880
50881 my_teardown (conn);
50882
50883
50884 /* Check that a condition whereby arguments are missing from the
50885 * method call return results in a special illegal arguments error
50886 * being passed to the errback.
50887 */
50888 TEST_FEATURE ("with missing arguments in reply (async)");
50889 conn = my_setup ();
50890 proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
50891
50892 auto void with_missing_args_in_reply_async (NihDBusProxy *my_proxy, void *userdata);
50893
50894 called = 0;
50895
50896 ret = proxy_test_async_method_async (proxy, "test data", 6,
50897 (ProxyTestAsyncMethodCallback)async_fail_errback,
50898 with_missing_args_in_reply_async, "userdata");
50899
50900 TEST_EQ (ret, 0);
50901
50902 void with_missing_args_in_reply_async (NihDBusProxy *my_proxy, void *userdata)
50903 {
50904 err = nih_error_get ();
50905 TEST_EQ (err->number, NIH_DBUS_INVALID_ARGS);
50906 nih_free (err);
50907 TEST_EQ_STR (userdata, "userdata");
50908 TEST_EQ_P (my_proxy, proxy);
50909 called = 1;
50910 }
50911
50912 while (! called)
50913 dbus_connection_read_write_dispatch (conn, -1);
50914
50915 nih_free (proxy);
50916
50917 my_teardown (conn);
50918
50919
50920 /* Check that an input argument of Byte type is dispatched
50921 * correctly.
50922 */
50923 TEST_FEATURE ("with Byte input argument");
50924 conn = my_setup ();
50925 proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
50926
50927 output = NULL;
50928
50929 ret = proxy_byte_to_str (proxy, 65, &output);
50930
50931 TEST_EQ (ret, 0);
50932
50933 TEST_NE_P (output, NULL);
50934 TEST_ALLOC_PARENT (output, proxy);
50935 TEST_EQ_STR (output, "65");
50936
50937 nih_free (proxy);
50938
50939 my_teardown (conn);
50940
50941
50942 /* Check that an input argument of Byte type is dispatched
50943 * correctly by an async call.
50944 */
50945 TEST_FEATURE ("with Byte input argument (async)");
50946 conn = my_setup ();
50947 proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
50948
50949 auto void with_byte_input_argument (NihDBusProxy *my_proxy, char *userdata, char *my_output);
50950
50951 called = 0;
50952 ret = proxy_byte_to_str_async (proxy, 65, (ProxyByteToStrCallback)with_byte_input_argument, async_fail_errback, "user data");
50953
50954 TEST_EQ (ret, 0);
50955
50956 void with_byte_input_argument (NihDBusProxy *my_proxy, char *userdata, char *my_output)
50957 {
50958 TEST_EQ_P (my_proxy, proxy);
50959 TEST_EQ_STR (userdata, "user data");
50960 TEST_NE_P (my_output, NULL);
50961 TEST_ALLOC_PARENT (my_output, proxy);
50962 TEST_EQ_STR (my_output, "65");
50963 called = 1;
50964 }
50965
50966 while (! called)
50967 dbus_connection_read_write_dispatch (conn, -1);
50968
50969 nih_free (proxy);
50970
50971 my_teardown (conn);
50972
50973
50974 /* Check that an output argument of Byte type is marshalled
50975 * correctly.
50976 */
50977 TEST_FEATURE ("with Byte output argument");
50978 conn = my_setup ();
50979 proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
50980
50981 byte_arg = 0;
50982
50983 ret = proxy_str_to_byte (proxy, "65", &byte_arg);
50984
50985 TEST_EQ (ret, 0);
50986
50987 TEST_EQ (byte_arg, 65);
50988
50989 nih_free (proxy);
50990
50991 my_teardown (conn);
50992
50993
50994 /* Check that an output argument of Byte type is marshalled
50995 * correctly for asynchronous calls.
50996 */
50997 TEST_FEATURE ("with Byte output argument (async)");
50998 conn = my_setup ();
50999 proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
51000
51001 auto void with_byte_output_argument (NihDBusProxy *my_proxy, char *userdata, typeof(byte_arg) my_byte_arg);
51002
51003 called = 0;
51004
51005 ret = proxy_str_to_byte_async (proxy, "65", (ProxyStrToByteCallback)with_byte_output_argument, async_fail_errback, "user data");
51006
51007 TEST_EQ (ret, 0);
51008
51009 void with_byte_output_argument (NihDBusProxy *my_proxy, char *userdata, typeof(byte_arg) my_byte_arg)
51010 {
51011 TEST_EQ_P (my_proxy, proxy);
51012 TEST_EQ_STR (userdata, "user data");
51013 TEST_EQ (my_byte_arg, 65);
51014 called = 1;
51015 }
51016
51017 while (! called)
51018 dbus_connection_read_write_dispatch (conn, -1);
51019
51020 nih_free (proxy);
51021
51022 my_teardown (conn);
51023
51024
51025 /* Check that an input argument of Boolean type is dispatched
51026 * correctly.
51027 */
51028 TEST_FEATURE ("with Boolean input argument");
51029 conn = my_setup ();
51030 proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
51031
51032 output = NULL;
51033
51034 ret = proxy_boolean_to_str (proxy, 1, &output);
51035
51036 TEST_EQ (ret, 0);
51037
51038 TEST_NE_P (output, NULL);
51039 TEST_ALLOC_PARENT (output, proxy);
51040 TEST_EQ_STR (output, "True");
51041
51042 nih_free (proxy);
51043
51044 my_teardown (conn);
51045
51046
51047 /* Check that an input argument of Boolean type is dispatched
51048 * correctly for asynchronous calls.
51049 */
51050 TEST_FEATURE ("with Boolean input argument (async)");
51051 conn = my_setup ();
51052 proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
51053
51054 auto void with_boolean_input_argument (NihDBusProxy *proxy, char *userdata, char *output);
51055
51056 called = 0;
51057 ret = proxy_boolean_to_str_async (proxy, 1, (ProxyBooleanToStrCallback)with_boolean_input_argument, async_fail_errback, "user data");
51058
51059 TEST_EQ (ret, 0);
51060
51061 void with_boolean_input_argument (NihDBusProxy *my_proxy, char *userdata, char *my_output)
51062 {
51063 TEST_EQ_STR (userdata, "user data");
51064 TEST_EQ_P (my_proxy, proxy);
51065 TEST_NE_P (my_output, NULL);
51066 TEST_ALLOC_PARENT (my_output, proxy);
51067 TEST_EQ_STR (my_output, "True");
51068
51069 called = 1;
51070 }
51071
51072 while (! called)
51073 dbus_connection_read_write_dispatch (conn, -1);
51074
51075 nih_free (proxy);
51076
51077 my_teardown (conn);
51078
51079
51080 /* Check that an output argument of Boolean type is marshalled
51081 * correctly.
51082 */
51083 TEST_FEATURE ("with Boolean output argument");
51084 conn = my_setup ();
51085 proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
51086
51087 boolean_arg = TRUE;
51088
51089 ret = proxy_str_to_boolean (proxy, "False", &boolean_arg);
51090
51091 TEST_EQ (ret, 0);
51092
51093 TEST_EQ (boolean_arg, FALSE);
51094
51095 nih_free (proxy);
51096
51097 my_teardown (conn);
51098
51099
51100 /* Check that an output argument of Boolean type is marshalled
51101 * correctly for asynchronous calls.
51102 */
51103 TEST_FEATURE ("with Boolean output argument (async)");
51104 conn = my_setup ();
51105 proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
51106
51107 auto void with_boolean_output_argument (NihDBusProxy *my_proxy, char *userdata, typeof(boolean_arg) my_boolean_arg);
51108
51109 called = 0;
51110
51111 ret = proxy_str_to_boolean_async (proxy, "False", (ProxyStrToBooleanCallback)with_boolean_output_argument, async_fail_errback, "user data");
51112
51113 TEST_EQ (ret, 0);
51114
51115 void with_boolean_output_argument (NihDBusProxy *my_proxy, char *userdata, typeof(boolean_arg) my_boolean_arg)
51116 {
51117 TEST_EQ_P (my_proxy, proxy);
51118 TEST_EQ_STR (userdata, "user data");
51119 TEST_EQ (my_boolean_arg, 0);
51120 called = 1;
51121 }
51122
51123 while (! called)
51124 dbus_connection_read_write_dispatch (conn, -1);
51125
51126 nih_free (proxy);
51127
51128 my_teardown (conn);
51129
51130
51131 /* Check that an input argument of Int16 type is dispatched
51132 * correctly.
51133 */
51134 TEST_FEATURE ("with Int16 input argument");
51135 conn = my_setup ();
51136 proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
51137
51138 output = NULL;
51139
51140 ret = proxy_int16_to_str (proxy, 1701, &output);
51141
51142 TEST_EQ (ret, 0);
51143
51144 TEST_NE_P (output, NULL);
51145 TEST_ALLOC_PARENT (output, proxy);
51146 TEST_EQ_STR (output, "1701");
51147
51148 nih_free (proxy);
51149
51150 my_teardown (conn);
51151
51152
51153 /* Check that an input argument of Int16 type is dispatched
51154 * correctly from an asynchronous call.
51155 */
51156 TEST_FEATURE ("with Int16 input argument (async)");
51157 conn = my_setup ();
51158 proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
51159
51160 auto void with_int16_input_argument (NihDBusProxy *proxy, char *userdata, char *output);
51161
51162 called = 0;
51163 ret = proxy_int16_to_str_async (proxy, 1701, (ProxyInt16ToStrCallback)with_int16_input_argument, async_fail_errback, "user data");
51164
51165 TEST_EQ (ret, 0);
51166
51167 void with_int16_input_argument (NihDBusProxy *my_proxy, char *userdata, char *my_output)
51168 {
51169 TEST_EQ_STR (userdata, "user data");
51170 TEST_EQ_P (my_proxy, proxy);
51171 TEST_NE_P (my_output, NULL);
51172 TEST_ALLOC_PARENT (my_output, proxy);
51173 TEST_EQ_STR (my_output, "1701");
51174 called = 1;
51175 }
51176
51177 while (! called)
51178 dbus_connection_read_write_dispatch (conn, -1);
51179
51180 nih_free (proxy);
51181
51182 my_teardown (conn);
51183
51184
51185 /* Check that an output argument of Int16 type is marshalled
51186 * correctly.
51187 */
51188 TEST_FEATURE ("with Int16 output argument");
51189 conn = my_setup ();
51190 proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
51191
51192 int16_arg = 0;
51193
51194 ret = proxy_str_to_int16 (proxy, "1701", &int16_arg);
51195
51196 TEST_EQ (ret, 0);
51197
51198 TEST_EQ (int16_arg, 1701);
51199
51200 nih_free (proxy);
51201
51202 my_teardown (conn);
51203
51204
51205 /* Check that an output argument of Int16 type is marshalled
51206 * correctly for asynchronous calls.
51207 */
51208 TEST_FEATURE ("with Int16 output argument (async)");
51209 conn = my_setup ();
51210 proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
51211
51212 auto void with_int16_output_argument (NihDBusProxy *my_proxy, char *userdata, typeof(int16_arg) my_int16_arg);
51213
51214 called = 0;
51215
51216 ret = proxy_str_to_int16_async (proxy, "65", (ProxyStrToInt16Callback)with_int16_output_argument, async_fail_errback, "user data");
51217
51218 TEST_EQ (ret, 0);
51219
51220 void with_int16_output_argument (NihDBusProxy *my_proxy, char *userdata, typeof(int16_arg) my_int16_arg)
51221 {
51222 TEST_EQ_P (my_proxy, proxy);
51223 TEST_EQ_STR (userdata, "user data");
51224 TEST_EQ (my_int16_arg, 65);
51225 called = 1;
51226 }
51227
51228 while (! called)
51229 dbus_connection_read_write_dispatch (conn, -1);
51230
51231 nih_free (proxy);
51232
51233 my_teardown (conn);
51234
51235
51236 /* Check that an input argument of UInt16 type is dispatched
51237 * correctly.
51238 */
51239 TEST_FEATURE ("with UInt16 input argument");
51240 conn = my_setup ();
51241 proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
51242
51243 output = NULL;
51244
51245 ret = proxy_uint16_to_str (proxy, 1701, &output);
51246
51247 TEST_EQ (ret, 0);
51248
51249 TEST_NE_P (output, NULL);
51250 TEST_ALLOC_PARENT (output, proxy);
51251 TEST_EQ_STR (output, "1701");
51252
51253 nih_free (proxy);
51254
51255 my_teardown (conn);
51256
51257
51258 /* Check that an input argument of UInt16 type is dispatched
51259 * correctly for an asynchronous call.
51260 */
51261 TEST_FEATURE ("with UInt16 input argument (async)");
51262 conn = my_setup ();
51263 proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
51264
51265 auto void with_uint16_input_argument (NihDBusProxy *proxy, char *userdata, char *output);
51266
51267 called = 0;
51268 ret = proxy_uint16_to_str_async (proxy, 1701, (ProxyUint16ToStrCallback)with_uint16_input_argument, async_fail_errback, "user data" );
51269
51270 TEST_EQ (ret, 0);
51271
51272 void with_uint16_input_argument (NihDBusProxy *my_proxy, char *userdata, char *my_output)
51273 {
51274 TEST_EQ_STR (userdata, "user data");
51275 TEST_EQ_P (my_proxy, proxy);
51276 TEST_NE_P (my_output, NULL);
51277 TEST_ALLOC_PARENT (my_output, proxy);
51278 TEST_EQ_STR (my_output, "1701");
51279 called = 1;
51280 }
51281
51282 while (! called)
51283 dbus_connection_read_write_dispatch (conn, -1);
51284
51285 nih_free (proxy);
51286
51287 my_teardown (conn);
51288
51289
51290 /* Check that an output argument of UInt16 type is marshalled
51291 * correctly.
51292 */
51293 TEST_FEATURE ("with UInt16 output argument");
51294 conn = my_setup ();
51295 proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
51296
51297 uint16_arg = 0;
51298
51299 ret = proxy_str_to_uint16 (proxy, "1701", &uint16_arg);
51300
51301 TEST_EQ (ret, 0);
51302
51303 TEST_EQ (uint16_arg, 1701);
51304
51305 nih_free (proxy);
51306
51307 my_teardown (conn);
51308
51309
51310 /* Check that an output argument of UInt16 type is marshalled
51311 * correctly for asynchronous calls.
51312 */
51313 TEST_FEATURE ("with UInt16 output argument (async)");
51314 conn = my_setup ();
51315 proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
51316
51317 auto void with_uint16_output_argument (NihDBusProxy *my_proxy, char *userdata, typeof(uint16_arg) my_uint16_arg);
51318
51319 called = 0;
51320
51321 ret = proxy_str_to_uint16_async (proxy, "65", (ProxyStrToUint16Callback)with_uint16_output_argument, async_fail_errback, "user data");
51322
51323 TEST_EQ (ret, 0);
51324
51325 void with_uint16_output_argument (NihDBusProxy *my_proxy, char *userdata, typeof(uint16_arg) my_uint16_arg)
51326 {
51327 TEST_EQ_P (my_proxy, proxy);
51328 TEST_EQ_STR (userdata, "user data");
51329 TEST_EQ (my_uint16_arg, 65);
51330 called = 1;
51331 }
51332
51333 while (! called)
51334 dbus_connection_read_write_dispatch (conn, -1);
51335
51336 nih_free (proxy);
51337
51338 my_teardown (conn);
51339
51340
51341 /* Check that an input argument of Int32 type is dispatched
51342 * correctly.
51343 */
51344 TEST_FEATURE ("with Int32 input argument");
51345 conn = my_setup ();
51346 proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
51347
51348 output = NULL;
51349
51350 ret = proxy_int32_to_str (proxy, 1701, &output);
51351
51352 TEST_EQ (ret, 0);
51353
51354 TEST_NE_P (output, NULL);
51355 TEST_ALLOC_PARENT (output, proxy);
51356 TEST_EQ_STR (output, "1701");
51357
51358 nih_free (proxy);
51359
51360 my_teardown (conn);
51361
51362
51363 /* Check that an input argument of Int32 type is dispatched
51364 * correctly during an asynchronous call.
51365 */
51366 TEST_FEATURE ("with Int32 input argument (async)");
51367 conn = my_setup ();
51368 proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
51369
51370 auto void with_int32_input_argument (NihDBusProxy *proxy, char *userdata, char *output);
51371
51372 called = 0;
51373 ret = proxy_int32_to_str_async (proxy, 1701, (ProxyInt32ToStrCallback)with_int32_input_argument, async_fail_errback, "user data");
51374
51375 TEST_EQ (ret, 0);
51376
51377 void with_int32_input_argument (NihDBusProxy *my_proxy, char *userdata, char *my_output)
51378 {
51379 TEST_EQ_STR (userdata, "user data");
51380 TEST_EQ_P (my_proxy, proxy);
51381 TEST_NE_P (my_output, NULL);
51382 TEST_ALLOC_PARENT (my_output, proxy);
51383 TEST_EQ_STR (my_output, "1701");
51384 called = 1;
51385 }
51386
51387 while (! called)
51388 dbus_connection_read_write_dispatch (conn, -1);
51389
51390 nih_free (proxy);
51391
51392 my_teardown (conn);
51393
51394
51395 /* Check that an output argument of Int32 type is marshalled
51396 * correctly.
51397 */
51398 TEST_FEATURE ("with Int32 output argument");
51399 conn = my_setup ();
51400 proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
51401
51402 int32_arg = 0;
51403
51404 ret = proxy_str_to_int32 (proxy, "1701", &int32_arg);
51405
51406 TEST_EQ (ret, 0);
51407
51408 TEST_EQ (int32_arg, 1701);
51409
51410 nih_free (proxy);
51411
51412 my_teardown (conn);
51413
51414
51415 /* Check that an output argument of Int32 type is marshalled
51416 * correctly for asynchronous calls.
51417 */
51418 TEST_FEATURE ("with Int32 output argument (async)");
51419 conn = my_setup ();
51420 proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
51421
51422 auto void with_int32_output_argument (NihDBusProxy *my_proxy, char *userdata, typeof(int32_arg) my_int32_arg);
51423
51424 called = 0;
51425
51426 ret = proxy_str_to_int32_async (proxy, "65", (ProxyStrToInt32Callback)with_int32_output_argument, async_fail_errback, "user data");
51427
51428 TEST_EQ (ret, 0);
51429
51430 void with_int32_output_argument (NihDBusProxy *my_proxy, char *userdata, typeof(int32_arg) my_int32_arg)
51431 {
51432 TEST_EQ_P (my_proxy, proxy);
51433 TEST_EQ_STR (userdata, "user data");
51434 TEST_EQ (my_int32_arg, 65);
51435 called = 1;
51436 }
51437
51438 while (! called)
51439 dbus_connection_read_write_dispatch (conn, -1);
51440
51441 nih_free (proxy);
51442
51443 my_teardown (conn);
51444
51445
51446 /* Check that an input argument of UInt32 type is dispatched
51447 * correctly.
51448 */
51449 TEST_FEATURE ("with UInt32 input argument");
51450 conn = my_setup ();
51451 proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
51452
51453 output = NULL;
51454
51455 ret = proxy_uint32_to_str (proxy, 1701, &output);
51456
51457 TEST_EQ (ret, 0);
51458
51459 TEST_NE_P (output, NULL);
51460 TEST_ALLOC_PARENT (output, proxy);
51461 TEST_EQ_STR (output, "1701");
51462
51463 nih_free (proxy);
51464
51465 my_teardown (conn);
51466
51467
51468 /* Check that an input argument of UInt32 type is dispatched
51469 * correctly for an asynchronous call.
51470 */
51471 TEST_FEATURE ("with UInt32 input argument (async)");
51472 conn = my_setup ();
51473 proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
51474
51475 auto void with_uint32_input_argument (NihDBusProxy *proxy, char *userdata, char *output);
51476
51477 called = 0;
51478 ret = proxy_uint32_to_str_async (proxy, 1701, (ProxyUint32ToStrCallback)with_uint32_input_argument, async_fail_errback, "user data" );
51479
51480 TEST_EQ (ret, 0);
51481
51482 void with_uint32_input_argument (NihDBusProxy *my_proxy, char *userdata, char *my_output)
51483 {
51484 TEST_EQ_STR (userdata, "user data");
51485 TEST_EQ_P (my_proxy, proxy);
51486 TEST_NE_P (my_output, NULL);
51487 TEST_ALLOC_PARENT (my_output, proxy);
51488 TEST_EQ_STR (my_output, "1701");
51489 called = 1;
51490 }
51491
51492 while (! called)
51493 dbus_connection_read_write_dispatch (conn, -1);
51494
51495 nih_free (proxy);
51496
51497 my_teardown (conn);
51498
51499
51500 /* Check that an output argument of UInt32 type is marshalled
51501 * correctly.
51502 */
51503 TEST_FEATURE ("with UInt32 output argument");
51504 conn = my_setup ();
51505 proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
51506
51507 uint32_arg = 0;
51508
51509 ret = proxy_str_to_uint32 (proxy, "1701", &uint32_arg);
51510
51511 TEST_EQ (ret, 0);
51512
51513 TEST_EQ (uint32_arg, 1701);
51514
51515 nih_free (proxy);
51516
51517 my_teardown (conn);
51518
51519
51520 /* Check that an output argument of UInt32 type is marshalled
51521 * correctly for asynchronous calls.
51522 */
51523 TEST_FEATURE ("with UInt32 output argument (async)");
51524 conn = my_setup ();
51525 proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
51526
51527 auto void with_uint32_output_argument (NihDBusProxy *my_proxy, char *userdata, typeof(uint32_arg) my_uint32_arg);
51528
51529 called = 0;
51530
51531 ret = proxy_str_to_uint32_async (proxy, "65", (ProxyStrToUint32Callback)with_uint32_output_argument, async_fail_errback, "user data");
51532
51533 TEST_EQ (ret, 0);
51534
51535 void with_uint32_output_argument (NihDBusProxy *my_proxy, char *userdata, typeof(uint32_arg) my_uint32_arg)
51536 {
51537 TEST_EQ_P (my_proxy, proxy);
51538 TEST_EQ_STR (userdata, "user data");
51539 TEST_EQ (my_uint32_arg, 65);
51540 called = 1;
51541 }
51542
51543 while (! called)
51544 dbus_connection_read_write_dispatch (conn, -1);
51545
51546 nih_free (proxy);
51547
51548 my_teardown (conn);
51549
51550
51551 /* Check that an input argument of Int64 type is dispatched
51552 * correctly.
51553 */
51554 TEST_FEATURE ("with Int64 input argument");
51555 conn = my_setup ();
51556 proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
51557
51558 output = NULL;
51559
51560 ret = proxy_int64_to_str (proxy, 1701, &output);
51561
51562 TEST_EQ (ret, 0);
51563
51564 TEST_NE_P (output, NULL);
51565 TEST_ALLOC_PARENT (output, proxy);
51566 TEST_EQ_STR (output, "1701");
51567
51568 nih_free (proxy);
51569
51570 my_teardown (conn);
51571
51572
51573 /* Check that an input argument of Int64 type is dispatched
51574 * correctly for an asynchronous call.
51575 */
51576 TEST_FEATURE ("with Int64 input argument (async)");
51577 conn = my_setup ();
51578 proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
51579
51580 auto void with_int64_input_argument (NihDBusProxy *proxy, char *userdata, char *output);
51581
51582 called = 0;
51583 ret = proxy_int64_to_str_async (proxy, 1701, (ProxyInt64ToStrCallback)with_int64_input_argument, async_fail_errback, "user data" );
51584
51585 TEST_EQ (ret, 0);
51586
51587 void with_int64_input_argument (NihDBusProxy *my_proxy, char *userdata, char *my_output)
51588 {
51589 TEST_EQ_STR (userdata, "user data");
51590 TEST_EQ_P (my_proxy, proxy);
51591 TEST_NE_P (my_output, NULL);
51592 TEST_ALLOC_PARENT (my_output, proxy);
51593 TEST_EQ_STR (my_output, "1701");
51594 called = 1;
51595 }
51596
51597 while (! called)
51598 dbus_connection_read_write_dispatch (conn, -1);
51599
51600 nih_free (proxy);
51601
51602 my_teardown (conn);
51603
51604
51605 /* Check that an output argument of Int64 type is marshalled
51606 * correctly.
51607 */
51608 TEST_FEATURE ("with Int64 output argument");
51609 conn = my_setup ();
51610 proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
51611
51612 int64_arg = 0;
51613
51614 ret = proxy_str_to_int64 (proxy, "1701", &int64_arg);
51615
51616 TEST_EQ (ret, 0);
51617
51618 TEST_EQ (int64_arg, 1701);
51619
51620 nih_free (proxy);
51621
51622 my_teardown (conn);
51623
51624
51625 /* Check that an output argument of Int64 type is marshalled
51626 * correctly for asynchronous calls.
51627 */
51628 TEST_FEATURE ("with Int64 output argument (async)");
51629 conn = my_setup ();
51630 proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
51631
51632 auto void with_int64_output_argument (NihDBusProxy *my_proxy, char *userdata, typeof(int64_arg) my_int64_arg);
51633
51634 called = 0;
51635
51636 ret = proxy_str_to_int64_async (proxy, "65", (ProxyStrToInt64Callback)with_int64_output_argument, async_fail_errback, "user data");
51637
51638 TEST_EQ (ret, 0);
51639
51640 void with_int64_output_argument (NihDBusProxy *my_proxy, char *userdata, typeof(int64_arg) my_int64_arg)
51641 {
51642 TEST_EQ_P (my_proxy, proxy);
51643 TEST_EQ_STR (userdata, "user data");
51644 TEST_EQ (my_int64_arg, 65);
51645 called = 1;
51646 }
51647
51648 while (! called)
51649 dbus_connection_read_write_dispatch (conn, -1);
51650
51651 nih_free (proxy);
51652
51653 my_teardown (conn);
51654
51655
51656 /* Check that an input argument of UInt64 type is dispatched
51657 * correctly.
51658 */
51659 TEST_FEATURE ("with UInt64 input argument");
51660 conn = my_setup ();
51661 proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
51662
51663 output = NULL;
51664
51665 ret = proxy_uint64_to_str (proxy, 1701, &output);
51666
51667 TEST_EQ (ret, 0);
51668
51669 TEST_NE_P (output, NULL);
51670 TEST_ALLOC_PARENT (output, proxy);
51671 TEST_EQ_STR (output, "1701");
51672
51673 nih_free (proxy);
51674
51675 my_teardown (conn);
51676
51677
51678 /* Check that an input argument of UInt64 type is dispatched
51679 * correctly for an asynchronous call.
51680 */
51681 TEST_FEATURE ("with UInt64 input argument (async)");
51682 conn = my_setup ();
51683 proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
51684
51685 auto void with_uint64_input_argument (NihDBusProxy *proxy, char *userdata, char *output);
51686
51687 called = 0;
51688 ret = proxy_uint64_to_str_async (proxy, 1701, (ProxyUint64ToStrCallback)with_uint64_input_argument, async_fail_errback, "user data" );
51689
51690 TEST_EQ (ret, 0);
51691
51692 void with_uint64_input_argument (NihDBusProxy *my_proxy, char *userdata, char *my_output)
51693 {
51694 TEST_EQ_STR (userdata, "user data");
51695 TEST_EQ_P (my_proxy, proxy);
51696 TEST_NE_P (my_output, NULL);
51697 TEST_ALLOC_PARENT (my_output, proxy);
51698 TEST_EQ_STR (my_output, "1701");
51699 called = 1;
51700 }
51701
51702 while (! called)
51703 dbus_connection_read_write_dispatch (conn, -1);
51704
51705 nih_free (proxy);
51706
51707 my_teardown (conn);
51708
51709
51710 /* Check that an output argument of UInt64 type is marshalled
51711 * correctly.
51712 */
51713 TEST_FEATURE ("with UInt64 output argument");
51714 conn = my_setup ();
51715 proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
51716
51717 uint64_arg = 0;
51718
51719 ret = proxy_str_to_uint64 (proxy, "1701", &uint64_arg);
51720
51721 TEST_EQ (ret, 0);
51722
51723 TEST_EQ (uint64_arg, 1701);
51724
51725 nih_free (proxy);
51726
51727 my_teardown (conn);
51728
51729
51730 /* Check that an output argument of UInt64 type is marshalled
51731 * correctly for asynchronous calls.
51732 */
51733 TEST_FEATURE ("with UInt64 output argument (async)");
51734 conn = my_setup ();
51735 proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
51736
51737 auto void with_uint64_output_argument (NihDBusProxy *my_proxy, char *userdata, typeof(uint64_arg) my_uint64_arg);
51738
51739 called = 0;
51740
51741 ret = proxy_str_to_uint64_async (proxy, "65", (ProxyStrToUint64Callback)with_uint64_output_argument, async_fail_errback, "user data");
51742
51743 TEST_EQ (ret, 0);
51744
51745 void with_uint64_output_argument (NihDBusProxy *my_proxy, char *userdata, typeof(uint64_arg) my_uint64_arg)
51746 {
51747 TEST_EQ_P (my_proxy, proxy);
51748 TEST_EQ_STR (userdata, "user data");
51749 TEST_EQ (my_uint64_arg, 65);
51750 called = 1;
51751 }
51752
51753 while (! called)
51754 dbus_connection_read_write_dispatch (conn, -1);
51755
51756 nih_free (proxy);
51757
51758 my_teardown (conn);
51759
51760
51761 /* Check that an input argument of Double type is dispatched
51762 * correctly.
51763 */
51764 TEST_FEATURE ("with Double input argument");
51765 conn = my_setup ();
51766 proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
51767
51768 output = NULL;
51769
51770 ret = proxy_double_to_str (proxy, 3.141592, &output);
51771
51772 TEST_EQ (ret, 0);
51773
51774 TEST_NE_P (output, NULL);
51775 TEST_ALLOC_PARENT (output, proxy);
51776 TEST_EQ_STR (output, "3.141592");
51777
51778 nih_free (proxy);
51779
51780 my_teardown (conn);
51781
51782
51783 /* Check that an input argument of Double type is dispatched
51784 * correctly for an asynchronous call.
51785 */
51786 TEST_FEATURE ("with Double input argument (async)");
51787 conn = my_setup ();
51788 proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
51789
51790 auto void with_double_input_argument (NihDBusProxy *proxy, char *userdata, char *output);
51791
51792 called = 0;
51793 ret = proxy_double_to_str_async (proxy, 3.141592, (ProxyDoubleToStrCallback)with_double_input_argument, async_fail_errback, "user data" );
51794
51795 TEST_EQ (ret, 0);
51796
51797 void with_double_input_argument (NihDBusProxy *my_proxy, char *userdata, char *my_output)
51798 {
51799 TEST_EQ_STR (userdata, "user data");
51800 TEST_EQ_P (my_proxy, proxy);
51801 TEST_NE_P (my_output, NULL);
51802 TEST_ALLOC_PARENT (my_output, proxy);
51803 TEST_EQ_STR (my_output, "3.141592");
51804 called = 1;
51805 }
51806
51807 while (! called)
51808 dbus_connection_read_write_dispatch (conn, -1);
51809
51810 nih_free (proxy);
51811
51812 my_teardown (conn);
51813
51814
51815 /* Check that an output argument of Double type is marshalled
51816 * correctly.
51817 */
51818 TEST_FEATURE ("with Double output argument");
51819 conn = my_setup ();
51820 proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
51821
51822 double_arg = 0;
51823
51824 ret = proxy_str_to_double (proxy, "3.141592", &double_arg);
51825
51826 TEST_EQ (ret, 0);
51827
51828 TEST_EQ (double_arg, 3.141592);
51829
51830 nih_free (proxy);
51831
51832 my_teardown (conn);
51833
51834
51835 /* Check that an output argument of Double type is marshalled
51836 * correctly for asynchronous calls.
51837 */
51838 TEST_FEATURE ("with Double output argument (async)");
51839 conn = my_setup ();
51840 proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
51841
51842 auto void with_double_output_argument (NihDBusProxy *my_proxy, char *userdata, typeof(double_arg) my_double_arg);
51843
51844 called = 0;
51845
51846 ret = proxy_str_to_double_async (proxy, "3.141592", (ProxyStrToDoubleCallback)with_double_output_argument, async_fail_errback, "user data");
51847
51848 TEST_EQ (ret, 0);
51849
51850 void with_double_output_argument (NihDBusProxy *my_proxy, char *userdata, typeof(double_arg) my_double_arg)
51851 {
51852 TEST_EQ_P (my_proxy, proxy);
51853 TEST_EQ_STR (userdata, "user data");
51854 TEST_EQ (my_double_arg, 3.141592);
51855 called = 1;
51856 }
51857
51858 while (! called)
51859 dbus_connection_read_write_dispatch (conn, -1);
51860
51861 nih_free (proxy);
51862
51863 my_teardown (conn);
51864
51865
51866 /* Check that an input argument of ObjectPath type is dispatched
51867 * correctly.
51868 */
51869 TEST_FEATURE ("with ObjectPath input argument");
51870 conn = my_setup ();
51871 proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
51872
51873 output = NULL;
51874
51875 ret = proxy_object_path_to_str (proxy, "/com/netsplit/Nih", &output);
51876
51877 TEST_EQ (ret, 0);
51878
51879 TEST_NE_P (output, NULL);
51880 TEST_ALLOC_PARENT (output, proxy);
51881 TEST_EQ_STR (output, "/com/netsplit/Nih");
51882
51883 nih_free (proxy);
51884
51885 my_teardown (conn);
51886
51887
51888 /* Check that an input argument of ObjectPath type is dispatched
51889 * correctly for an asynchronous call.
51890 */
51891 TEST_FEATURE ("with ObjectPath input argument (async)");
51892 conn = my_setup ();
51893 proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
51894
51895 auto void with_object_path_input_argument (NihDBusProxy *proxy, char *userdata, char *output);
51896
51897 called = 0;
51898 ret = proxy_object_path_to_str_async (proxy, "/com/netsplit/Nih", (ProxyObjectPathToStrCallback)with_object_path_input_argument, async_fail_errback, "user data" );
51899
51900 TEST_EQ (ret, 0);
51901
51902 void with_object_path_input_argument (NihDBusProxy *my_proxy, char *userdata, char *my_output)
51903 {
51904 TEST_EQ_STR (userdata, "user data");
51905 TEST_EQ_P (my_proxy, proxy);
51906 TEST_NE_P (my_output, NULL);
51907 TEST_ALLOC_PARENT (my_output, proxy);
51908 TEST_EQ_STR (my_output, "/com/netsplit/Nih");
51909 called = 1;
51910 }
51911
51912 while (! called)
51913 dbus_connection_read_write_dispatch (conn, -1);
51914
51915 nih_free (proxy);
51916
51917 my_teardown (conn);
51918
51919
51920 /* Check that an output argument of ObjectPath type is marshalled
51921 * correctly.
51922 */
51923 TEST_FEATURE ("with ObjectPath output argument");
51924 conn = my_setup ();
51925 proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
51926
51927 output = NULL;
51928
51929 ret = proxy_str_to_object_path (proxy, "/com/netsplit/Nih", &output);
51930
51931 TEST_EQ (ret, 0);
51932
51933 TEST_NE_P (output, NULL);
51934 TEST_ALLOC_PARENT (output, proxy);
51935 TEST_EQ_STR (output, "/com/netsplit/Nih");
51936
51937 nih_free (proxy);
51938
51939 my_teardown (conn);
51940
51941
51942 /* Check that an output argument of ObjectPath type is marshalled
51943 * correctly for asynchronous calls.
51944 */
51945 TEST_FEATURE ("with ObjectPath output argument (async)");
51946 conn = my_setup ();
51947 proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
51948
51949 auto void with_object_path_output_argument (NihDBusProxy *my_proxy, char *userdata, char *my_object_path_arg);
51950
51951 called = 0;
51952
51953 ret = proxy_str_to_object_path_async (proxy, "/com/netsplit/Nih", (ProxyStrToObjectPathCallback)with_object_path_output_argument, async_fail_errback, "user data");
51954
51955 TEST_EQ (ret, 0);
51956
51957 void with_object_path_output_argument (NihDBusProxy *my_proxy, char *userdata, char *my_object_path_arg)
51958 {
51959 TEST_EQ_P (my_proxy, proxy);
51960 TEST_EQ_STR (userdata, "user data");
51961 TEST_NE_P (my_object_path_arg, NULL);
51962 TEST_ALLOC_PARENT (my_object_path_arg, proxy);
51963 TEST_EQ_STR (my_object_path_arg, "/com/netsplit/Nih");
51964 called = 1;
51965 }
51966
51967 while (! called)
51968 dbus_connection_read_write_dispatch (conn, -1);
51969
51970 nih_free (proxy);
51971
51972 my_teardown (conn);
51973
51974
51975 /* Check that an input argument of Signature type is dispatched
51976 * correctly.
51977 */
51978 TEST_FEATURE ("with Signature input argument");
51979 conn = my_setup ();
51980 proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
51981
51982 output = NULL;
51983
51984 ret = proxy_signature_to_str (proxy, "a{sv}", &output);
51985
51986 TEST_EQ (ret, 0);
51987
51988 TEST_NE_P (output, NULL);
51989 TEST_ALLOC_PARENT (output, proxy);
51990 TEST_EQ_STR (output, "a{sv}");
51991
51992 nih_free (proxy);
51993
51994 my_teardown (conn);
51995
51996
51997 /* Check that an input argument of Signature type is dispatched
51998 * correctly for an asynchronous call.
51999 */
52000 TEST_FEATURE ("with Signature input argument (async)");
52001 conn = my_setup ();
52002 proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
52003
52004 auto void with_signature_input_argument (NihDBusProxy *proxy, char *userdata, char *output);
52005
52006 called = 0;
52007 ret = proxy_signature_to_str_async (proxy, "a{sv}", (ProxySignatureToStrCallback)with_signature_input_argument, async_fail_errback, "user data" );
52008
52009 TEST_EQ (ret, 0);
52010
52011 void with_signature_input_argument (NihDBusProxy *my_proxy, char *userdata, char *my_output)
52012 {
52013 TEST_EQ_STR (userdata, "user data");
52014 TEST_EQ_P (my_proxy, proxy);
52015 TEST_NE_P (my_output, NULL);
52016 TEST_ALLOC_PARENT (my_output, proxy);
52017 TEST_EQ_STR (my_output, "a{sv}");
52018 called = 1;
52019 }
52020
52021 while (! called)
52022 dbus_connection_read_write_dispatch (conn, -1);
52023
52024 nih_free (proxy);
52025
52026 my_teardown (conn);
52027
52028
52029 /* Check that an output argument of Signature type is marshalled
52030 * correctly.
52031 */
52032 TEST_FEATURE ("with Signature output argument");
52033 conn = my_setup ();
52034 proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
52035
52036 output = NULL;
52037
52038 ret = proxy_str_to_signature (proxy, "a{sv}", &output);
52039
52040 TEST_EQ (ret, 0);
52041
52042 TEST_NE_P (output, NULL);
52043 TEST_ALLOC_PARENT (output, proxy);
52044 TEST_EQ_STR (output, "a{sv}");
52045
52046 nih_free (proxy);
52047
52048 my_teardown (conn);
52049
52050
52051 /* Check that an output argument of Signature type is marshalled
52052 * correctly for asynchronous calls.
52053 */
52054 TEST_FEATURE ("with Signature output argument (async)");
52055 conn = my_setup ();
52056 proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
52057
52058 auto void with_signature_output_argument (NihDBusProxy *my_proxy, char *userdata, char *my_signature_arg);
52059
52060 called = 0;
52061
52062 ret = proxy_str_to_signature_async (proxy, "a{sv}", (ProxyStrToSignatureCallback)with_signature_output_argument, async_fail_errback, "user data");
52063
52064 TEST_EQ (ret, 0);
52065
52066 void with_signature_output_argument (NihDBusProxy *my_proxy, char *userdata, char *my_signature_arg)
52067 {
52068 TEST_EQ_P (my_proxy, proxy);
52069 TEST_EQ_STR (userdata, "user data");
52070 TEST_NE_P (my_signature_arg, NULL);
52071 TEST_ALLOC_PARENT (my_signature_arg, proxy);
52072 TEST_EQ_STR (my_signature_arg, "a{sv}");
52073 called = 1;
52074 }
52075
52076 while (! called)
52077 dbus_connection_read_write_dispatch (conn, -1);
52078
52079 nih_free (proxy);
52080
52081 my_teardown (conn);
52082
52083
52084 /* Check that an input argument of Array type with Int32 members
52085 * is dispatched correctly.
52086 */
52087 TEST_FEATURE ("with Int32 Array input argument");
52088 conn = my_setup ();
52089 proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
52090
52091 int32_array = nih_alloc (NULL, sizeof (int32_t) * 6);
52092 int32_array[0] = 4;
52093 int32_array[1] = 8;
52094 int32_array[2] = 15;
52095 int32_array[3] = 16;
52096 int32_array[4] = 23;
52097 int32_array[5] = 42;
52098 array_len = 6;
52099
52100 output = NULL;
52101
52102 ret = proxy_int32_array_to_str (proxy, int32_array, array_len,
52103 &output);
52104
52105 TEST_EQ (ret, 0);
52106
52107 TEST_NE_P (output, NULL);
52108 TEST_ALLOC_PARENT (output, proxy);
52109 TEST_EQ_STR (output, "4 8 15 16 23 42");
52110
52111 nih_free (proxy);
52112 nih_free (int32_array);
52113
52114 my_teardown (conn);
52115
52116
52117 /* Check that an input argument of Array type with Int32 members
52118 * is dispatched correctly for asynchronous calls.
52119 */
52120 TEST_FEATURE ("with Int32 Array input argument (async)");
52121 conn = my_setup ();
52122 proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
52123
52124 auto void with_int_array_input_argument (NihDBusProxy *proxy, char *userdata, char *output);
52125
52126 int32_array = nih_alloc (NULL, sizeof (int32_t) * 6);
52127 int32_array[0] = 4;
52128 int32_array[1] = 8;
52129 int32_array[2] = 15;
52130 int32_array[3] = 16;
52131 int32_array[4] = 23;
52132 int32_array[5] = 42;
52133 array_len = 6;
52134
52135 called = 0;
52136 ret = proxy_int32_array_to_str_async (proxy, int32_array, array_len,
52137 (ProxyInt32ArrayToStrCallback)with_int_array_input_argument, async_fail_errback,
52138 "user data");
52139
52140 TEST_EQ (ret, 0);
52141
52142 void with_int_array_input_argument (NihDBusProxy *my_proxy, char *userdata, char *my_output)
52143 {
52144 TEST_EQ_STR (userdata, "user data");
52145 TEST_EQ_P (my_proxy, proxy);
52146 TEST_NE_P (my_output, NULL);
52147 TEST_ALLOC_PARENT (my_output, proxy);
52148 TEST_EQ_STR (my_output, "4 8 15 16 23 42");
52149 called = 1;
52150 }
52151
52152 while (! called)
52153 dbus_connection_read_write_dispatch (conn, -1);
52154
52155 nih_free (proxy);
52156 nih_free (int32_array);
52157
52158 my_teardown (conn);
52159
52160
52161 /* Check that an output argument of Array type with Int32 members
52162 * is marshalled correctly.
52163 */
52164 TEST_FEATURE ("with Int32 Array output argument");
52165 conn = my_setup ();
52166 proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
52167
52168 int32_array = NULL;
52169 array_len = 0;
52170
52171 ret = proxy_str_to_int32_array (proxy, "4 8 15 16 23 42",
52172 &int32_array, &array_len);
52173
52174 TEST_EQ (ret, 0);
52175
52176 TEST_NE_P (int32_array, NULL);
52177 TEST_ALLOC_PARENT (int32_array, proxy);
52178 TEST_EQ (array_len, 6);
52179 TEST_EQ (int32_array[0], 4);
52180 TEST_EQ (int32_array[1], 8);
52181 TEST_EQ (int32_array[2], 15);
52182 TEST_EQ (int32_array[3], 16);
52183 TEST_EQ (int32_array[4], 23);
52184 TEST_EQ (int32_array[5], 42);
52185
52186 nih_free (proxy);
52187
52188 my_teardown (conn);
52189
52190
52191 /* Check that an output argument of Array type with Int32 members
52192 * is marshalled correctly for asynchronous calls.
52193 */
52194 TEST_FEATURE ("with Int32 Array output argument (async)");
52195 conn = my_setup ();
52196 proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
52197
52198 auto void with_int_array_output_argument (NihDBusProxy *my_proxy, char *userdata, int *my_intarray, int my_len);
52199
52200 called = 0;
52201 ret = proxy_str_to_int32_array_async (proxy, "4 8 15 16 23 42",
52202 (ProxyStrToInt32ArrayCallback)with_int_array_output_argument, async_fail_errback, "user data");
52203
52204 TEST_EQ (ret, 0);
52205
52206 void with_int_array_output_argument (NihDBusProxy *my_proxy, char *userdata, int *my_intarray, int my_len)
52207 {
52208 TEST_EQ_STR (userdata, "user data");
52209 TEST_EQ_P (my_proxy, proxy);
52210 TEST_NE_P (my_intarray, NULL);
52211 TEST_ALLOC_PARENT (my_intarray, proxy);
52212 TEST_EQ (my_len, 6);
52213 TEST_EQ (my_intarray[0], 4);
52214 TEST_EQ (my_intarray[1], 8);
52215 TEST_EQ (my_intarray[2], 15);
52216 TEST_EQ (my_intarray[3], 16);
52217 TEST_EQ (my_intarray[4], 23);
52218 TEST_EQ (my_intarray[5], 42);
52219 called = 1;
52220 }
52221
52222 while (! called)
52223 dbus_connection_read_write_dispatch (conn, -1);
52224
52225 nih_free (proxy);
52226
52227 my_teardown (conn);
52228
52229
52230 /* Check that an input argument of Array type with String members
52231 * is dispatched correctly.
52232 */
52233 TEST_FEATURE ("with String Array input argument");
52234 conn = my_setup ();
52235 proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
52236
52237 str_array = nih_alloc (NULL, sizeof (char *) * 5);
52238 str_array[0] = "this";
52239 str_array[1] = "is";
52240 str_array[2] = "a";
52241 str_array[3] = "test";
52242 str_array[4] = NULL;
52243
52244 output = NULL;
52245
52246 ret = proxy_str_array_to_str (proxy, str_array, &output);
52247
52248 TEST_EQ (ret, 0);
52249
52250 TEST_NE_P (output, NULL);
52251 TEST_ALLOC_PARENT (output, proxy);
52252 TEST_EQ_STR (output, "this is a test");
52253
52254 nih_free (proxy);
52255 nih_free (str_array);
52256
52257 my_teardown (conn);
52258
52259
52260 /* Check that an input argument of Array type with String members
52261 * is dispatched correctly for async calls.
52262 */
52263 TEST_FEATURE ("with String Array input argument (async)");
52264 conn = my_setup ();
52265 proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
52266
52267 auto void with_str_array_input_argument (NihDBusProxy *my_proxy, char *userdata, char *my_output);
52268
52269 str_array = nih_alloc (NULL, sizeof (char *) * 5);
52270 str_array[0] = "this";
52271 str_array[1] = "is";
52272 str_array[2] = "a";
52273 str_array[3] = "test";
52274 str_array[4] = NULL;
52275
52276 called = 0;
52277 ret = proxy_str_array_to_str_async (proxy, str_array, (ProxyStrArrayToStrCallback)with_str_array_input_argument, async_fail_errback, "user data");
52278
52279 TEST_EQ (ret, 0);
52280
52281 void with_str_array_input_argument (NihDBusProxy *my_proxy, char *userdata, char *my_output)
52282 {
52283 TEST_EQ_STR (userdata, "user data");
52284 TEST_EQ_P (my_proxy, proxy);
52285 TEST_NE_P (my_output, NULL);
52286 TEST_ALLOC_PARENT (my_output, proxy);
52287 TEST_EQ_STR (my_output, "this is a test");
52288 called = 1;
52289 }
52290
52291 while (! called)
52292 dbus_connection_read_write_dispatch (conn, -1);
52293
52294 nih_free (proxy);
52295 nih_free (str_array);
52296
52297 my_teardown (conn);
52298
52299
52300 /* Check that an output argument of Array type with String members
52301 * is marshalled correctly.
52302 */
52303 TEST_FEATURE ("with String Array output argument");
52304 conn = my_setup ();
52305 proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
52306
52307 str_array = NULL;
52308
52309 ret = proxy_str_to_str_array (proxy, "this is a test", &str_array);
52310
52311 TEST_EQ (ret, 0);
52312
52313 TEST_NE_P (str_array, NULL);
52314 TEST_ALLOC_PARENT (str_array, proxy);
52315 TEST_EQ_STR (str_array[0], "this");
52316 TEST_EQ_STR (str_array[1], "is");
52317 TEST_EQ_STR (str_array[2], "a");
52318 TEST_EQ_STR (str_array[3], "test");
52319 TEST_EQ_P (str_array[4], NULL);
52320
52321 nih_free (proxy);
52322
52323 my_teardown (conn);
52324
52325
52326 /* Check that an output argument of Array type with String members
52327 * is marshalled correctly for asynchronous calls.
52328 */
52329 TEST_FEATURE ("with String Array output argument (async)");
52330 conn = my_setup ();
52331 proxy = nih_dbus_proxy_new (NULL, conn, NULL, "/com/netsplit/Nih");
52332
52333 auto void with_str_array_output_argument (NihDBusProxy *my_proxy, char *userdata, char **my_str_array);
52334
52335 called = 0;
52336
52337 ret = proxy_str_to_str_array_async (proxy, "this is a test", (ProxyStrToStrArrayCallback)with_str_array_output_argument, async_fail_errback, "user data");
52338
52339 TEST_EQ (ret, 0);
52340
52341 void with_str_array_output_argument (NihDBusProxy *my_proxy, char *userdata, char **my_str_array)
52342 {
52343 TEST_EQ_STR (userdata, "user data");
52344 TEST_EQ_P (my_proxy, proxy);
52345 TEST_NE_P (my_str_array, NULL);
52346 TEST_ALLOC_PARENT (my_str_array, proxy);
52347 TEST_EQ_STR (my_str_array[0], "this");
52348 TEST_EQ_STR (my_str_array[1], "is");
52349 TEST_EQ_STR (my_str_array[2], "a");
52350 TEST_EQ_STR (my_str_array[3], "test");
52351 TEST_EQ_P (my_str_array[4], NULL);
52352 called = 1;
52353 }
52354
52355 while (! called)
52356 dbus_connection_read_write_dispatch (conn, -1);
52357
52358 nih_free (proxy);
52359
52360 my_teardown (conn);
52361}
52362
52363
52364static void
52365async_fail_errback (NihDBusProxy *my_proxy, void *userdata)
52366{
52367 TEST_FAILED ("Called wrong asynchronous handler");
52368>>>>>>> MERGE-SOURCE
50207}52369}
5020852370
5020952371
5021052372
=== added file 'nih/nih_dbus_tool.py.OTHER'
--- nih/nih_dbus_tool.py.OTHER 1970-01-01 00:00:00 +0000
+++ nih/nih_dbus_tool.py.OTHER 2009-10-03 06:00:27 +0000
@@ -0,0 +1,2635 @@
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3#
4# nih_dbus_tool.py - D-Bus binding generation tool
5#
6# Copyright © 2008 Scott James Remnant <scott@netsplit.com>.
7#
8# This program is free software; you can redistribute it and/or modify
9# it under the terms of the GNU General Public License as published by
10# the Free Software Foundation; either version 2 of the License, or
11# (at your option) any later version.
12#
13# This program is distributed in the hope that it will be useful,
14# but WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16# GNU General Public License for more details.
17#
18# You should have received a copy of the GNU General Public License
19# along with this program; if not, write to the Free Software
20# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21
22import os
23import re
24import sys
25
26from optparse import OptionParser
27from xml.etree import ElementTree
28
29
30# Replaced by autoconf-obtained strings
31PACKAGE_NAME = "@PACKAGE_NAME@"
32PACKAGE_COPYRIGHT = "@PACKAGE_COPYRIGHT@"
33
34# Prefix for external functions
35extern_prefix = "dbus"
36
37# Generator mode
38mode = "object"
39
40
41# Conversion for external C names
42NAME_RE = re.compile(r'([a-z0-9])([A-Z])')
43
44# Namespace for our own tags and attributes
45XMLNS = "http://www.netsplit.com/nih/dbus"
46
47
48# arrays of arrays with length (ends up being an array of a struct)
49# - instead of using self.type.c_type and name, we should iterate
50# over its vars? -- array will have foo_elem and foo_elem_len
51#
52# struct type
53# variant type (at least fallback to requiring them to define the marshal?)
54 # - one way might be just to pass a container or fake message?
55
56# "proxy" mode:
57# async function dispatch
58# function dispatch with no reply
59# configurable timeout, autostart, etc. for function dispatch
60# signal marshal
61# - called when a signal we're expecting happens, will have a message
62# object and will call a handler with that -- need an object equivalent,
63# "proxy" likely
64
65
66class DBusType(object):
67 """D-Bus type.
68
69 This abstract class represents the base of all D-Bus types that we
70 can handle.
71 """
72
73 @classmethod
74 def fromElement(cls, elem):
75 name = elem.get("name")
76 if name is None:
77 raise AttributeError, "Argument name may not be null"
78
79 type = elem.get("type")
80 if type is None:
81 raise AttributeError, "Argument type may not be null"
82
83 direction = elem.get("direction", "in")
84 if direction not in ( "in", "out" ):
85 raise AttributeError, "Direction must be 'in' or 'out'"
86
87 type_cls = cls.typeOf(type)
88 return type_cls.fromArgument(name, direction)
89
90 @classmethod
91 def fromArgument(cls, name, direction="in"):
92 self = cls(name)
93 self.direction = direction
94
95 return self
96
97 def __init__(self, name):
98 self.name = name
99
100 @classmethod
101 def typeOf(cls, code):
102 """Return type for given type signature code."""
103 if code == "y":
104 return DBusByte
105 elif code == "b":
106 return DBusBoolean
107 elif code == "n":
108 return DBusInt16
109 elif code == "q":
110 return DBusUInt16
111 elif code == "i":
112 return DBusInt32
113 elif code == "u":
114 return DBusUInt32
115 elif code == "x":
116 return DBusInt64
117 elif code == "t":
118 return DBusUInt64
119 elif code == "d":
120 return DBusDouble
121 elif code == "s":
122 return DBusString
123 elif code == "o":
124 return DBusObjectPath
125 elif code == "g":
126 return DBusSignature
127 elif code[0] == "a":
128 return DBusArray.forType(cls.typeOf(code[-1]))
129 else:
130 raise AttributeError, "Unknown or unhandled type '%s'" % code
131
132 def realType(self, c_type, pointer=False, const=False):
133 """Real type.
134
135 Returns a string containing the C type name for this type, with
136 pointer and const modifications added.
137 """
138 if pointer:
139 c_type = pointerify(c_type)
140 if const:
141 c_type = constify(c_type)
142
143 return c_type
144
145 def signature(self, pointer=False, const=False):
146 """Type signature.
147
148 Returns a string containing the D-Bus type signature for this type.
149 """
150 return None
151
152 def vars(self, pointer=False, const=False):
153 """Variable type and name.
154
155 Returns a list containing a single tuple of the C type used for this
156 type and the name given when creating the instance.
157 """
158 return []
159
160 def names(self, pointer=False, const=False):
161 """Variable name.
162
163 Returns a list containing a single string; the name given when creating
164 the instance.
165 """
166 return []
167
168 def locals(self, pointer=False, const=False):
169 """Local variable type and name.
170
171 Returns a list containing necessary local variables for iteration
172 of this type.
173 """
174 return []
175
176 def marshal(self, iter_name, parent, type_error, mem_error,
177 pointer=False, const=False):
178 """Marshalling code.
179
180 Returns a string containing the code that will marshal from an
181 iterator with the name given into a local variable with the
182 type and name as returned by vars().
183 """
184 return None
185
186 def dispatch(self, iter_name, mem_error,
187 pointer=False, const=False):
188 """Dispatching code.
189
190 Returns a string containing the code that will dispatch from a
191 local variable with the type and name as returned by vars() to
192 an iterator with the name given.
193 """
194 return None
195
196
197class DBusBasicType(DBusType):
198 """D-Bus basic type.
199
200 This abstract class represents the base of all basic D-Bus types that
201 we can handle. These share the code to marshal from a DBusMessage into
202 a variable and dispatch from a variable back into a DBusMessage.
203 """
204
205 def signature(self, pointer=False, const=False):
206 """Type signature.
207
208 Returns a string containing the D-Bus type signature for this type.
209 """
210 return self.dbus_code
211
212 def vars(self, pointer=False, const=False):
213 """Variable type and name.
214
215 Returns a list containing a single tuple of the C type used for this
216 type and the name given when creating the instance.
217 """
218 return [ ( self.realType(self.c_type, pointer, const), self.name ) ]
219
220 def names(self, pointer=False, const=False):
221 """Variable name.
222
223 Returns a list containing a single string; the name given when creating
224 the instance.
225 """
226 return [ self.name ]
227
228 def locals(self, pointer=False, const=False):
229 """Local variable type and name.
230
231 Returns a list containing necessary local variables for iteration
232 of this type.
233 """
234 return []
235
236 def marshal(self, iter_name, parent, type_error, mem_error,
237 pointer=False, const=False):
238 """Marshalling code.
239
240 Returns a string containing the code that will marshal from an
241 iterator with the name given into a local variable with the
242 type and name as returned by vars().
243 """
244 name = self.name
245 if pointer:
246 name = "*%s" % (name, )
247
248 return """\
249if (dbus_message_iter_get_arg_type (&%s) != %s) {
250%s
251}
252
253dbus_message_iter_get_basic (&%s, &%s);
254
255dbus_message_iter_next (&%s);
256""" % (iter_name, self.dbus_type, type_error,
257 iter_name, name,
258 iter_name)
259
260 def dispatch(self, iter_name, mem_error,
261 pointer=False, const=False):
262 """Dispatching code.
263
264 Returns a string containing the code that will dispatch from a
265 local variable with the type and name as returned by vars() to
266 an iterator with the name given.
267 """
268 name = self.name
269 if pointer:
270 name = "*%s" % (name, )
271
272 return """\
273if (! dbus_message_iter_append_basic (&%s, %s, &%s)) {
274%s
275}
276""" % (iter_name, self.dbus_type, name, mem_error)
277
278
279class DBusByte(DBusBasicType):
280 """D-Bus byte.
281
282 This class represents the D-Bus byte type and should be instantiated with
283 the name of the variable. It shares marshalling and dispatch code with
284 the other basic types.
285 """
286 c_type = "uint8_t"
287 dbus_code = "y"
288 dbus_type = "DBUS_TYPE_BYTE"
289
290class DBusBoolean(DBusBasicType):
291 """D-Bus boolean.
292
293 This class represents the D-Bus boolean type and should be instantiated
294 with the name of the variable. It shares marshalling and dispatch code
295 with the other basic types.
296 """
297 c_type = "int"
298 dbus_code = "b"
299 dbus_type = "DBUS_TYPE_BOOLEAN"
300
301class DBusInt16(DBusBasicType):
302 """D-Bus 16-bit integer.
303
304 This class represents the D-Bus int16 type and should be instantiated with
305 the name of the variable. It shares marshalling and dispatch code with
306 the other basic types.
307 """
308 c_type = "int16_t"
309 dbus_code = "n"
310 dbus_type = "DBUS_TYPE_INT16"
311
312class DBusUInt16(DBusBasicType):
313 """D-Bus 16-bit unsigned integer.
314
315 This class represents the D-Bus uint16 type and should be instantiated with
316 the name of the variable. It shares marshalling and dispatch code with
317 the other basic types.
318 """
319 c_type = "uint16_t"
320 dbus_code = "q"
321 dbus_type = "DBUS_TYPE_UINT16"
322
323class DBusInt32(DBusBasicType):
324 """D-Bus 32-bit integer.
325
326 This class represents the D-Bus int32 type and should be instantiated with
327 the name of the variable. It shares marshalling and dispatch code with
328 the other basic types.
329 """
330 c_type = "int32_t"
331 dbus_code = "i"
332 dbus_type = "DBUS_TYPE_INT32"
333
334class DBusUInt32(DBusBasicType):
335 """D-Bus 32-bit unsigned integer.
336
337 This class represents the D-Bus uint32 type and should be instantiated with
338 the name of the variable. It shares marshalling and dispatch code with
339 the other basic types.
340 """
341 c_type = "uint32_t"
342 dbus_code = "u"
343 dbus_type = "DBUS_TYPE_UINT32"
344
345class DBusInt64(DBusBasicType):
346 """D-Bus 64-bit integer.
347
348 This class represents the D-Bus int64 type and should be instantiated with
349 the name of the variable. It shares marshalling and dispatch code with
350 the other basic types.
351 """
352 c_type = "int64_t"
353 dbus_code = "x"
354 dbus_type = "DBUS_TYPE_INT64"
355
356class DBusUInt64(DBusBasicType):
357 """D-Bus 64-bit unsigned integer.
358
359 This class represents the D-Bus uint64 type and should be instantiated with
360 the name of the variable. It shares marshalling and dispatch code with
361 the other basic types.
362 """
363 c_type = "uint64_t"
364 dbus_code = "t"
365 dbus_type = "DBUS_TYPE_UINT64"
366
367class DBusDouble(DBusBasicType):
368 """D-Bus double.
369
370 This class represents the D-Bus double type and should be instantiated
371 with the name of the variable. It shares marshalling and dispatch code
372 with the other basic types.
373 """
374 c_type = "double"
375 dbus_code = "d"
376 dbus_type = "DBUS_TYPE_DOUBLE"
377
378
379class DBusStringType(DBusBasicType):
380 """D-Bus string type.
381
382 This abstract class represents the base of all string-derived D-Bus types
383 that we can handle. These share the code to marshal from a DBusMessage
384 into a variable, the code to dispatch from a variable back into a
385 DBusMessage and the same basic C type.
386
387 They differ from the fundamental basic type in that the marshalled copy
388 of the string is not direct from the message, but an allocated copy;
389 this is because they cannot be simply passed by value, and may wish to
390 be stored.
391 """
392 c_type = "char *"
393
394 def locals(self, pointer=False, const=False):
395 """Local variable type and name.
396
397 Returns a list containing necessary local variables for iteration
398 of this type.
399 """
400 return [ ( self.realType(self.c_type, const=const),
401 "_".join((self.name, "value")) ) ]
402
403 def marshal(self, iter_name, parent, type_error, mem_error,
404 pointer=False, const=False):
405 """Marshalling code.
406
407 Returns a string containing the code that will marshal from an
408 iterator with the name given into a local variable with the
409 type and name as returned by vars().
410 """
411 name = self.name
412 if pointer:
413 name = "*%s" % (name, )
414
415 value_name = "_".join((self.name, "value"))
416
417 return """\
418if (dbus_message_iter_get_arg_type (&%s) != %s) {
419%s
420}
421
422dbus_message_iter_get_basic (&%s, &%s);
423
424%s = nih_strdup (%s, %s);
425if (! %s) {
426%s
427}
428
429dbus_message_iter_next (&%s);
430""" % (iter_name, self.dbus_type, type_error,
431 iter_name, value_name,
432 name, parent, value_name,
433 name, mem_error,
434 iter_name)
435
436 def dispatch(self, iter_name, mem_error,
437 pointer=False, const=False):
438 """Dispatching code.
439
440 Returns a string containing the code that will dispatch from a
441 local variable with the type and name as returned by vars() to
442 an iterator with the name given.
443 """
444 name = self.name
445 if pointer:
446 name = "*%s" % (name, )
447
448 value_name = "_".join((self.name, "value"))
449
450 return """\
451%s = %s;
452if (! dbus_message_iter_append_basic (&%s, %s, &%s)) {
453%s
454}
455""" % (value_name, name,
456 iter_name, self.dbus_type, value_name, mem_error)
457
458
459class DBusString(DBusStringType):
460 """D-Bus string.
461
462 This class represents the D-Bus string type and should be instantiated
463 with the name of the variable. It shares marshalling and dispatch code
464 and underlying C type with the other string types.
465 """
466 dbus_type = "DBUS_TYPE_STRING"
467 dbus_code = "s"
468
469class DBusObjectPath(DBusStringType):
470 """D-Bus object path.
471
472 This class represents the D-Bus object path type and should be instantiated
473 with the name of the variable. It shares marshalling and dispatch code
474 and underlying C type with the other string types.
475 """
476 dbus_type = "DBUS_TYPE_OBJECT_PATH"
477 dbus_code = "o"
478
479class DBusSignature(DBusStringType):
480 """D-Bus type signature.
481
482 This class represents the D-Bus signature type and should be instantiated
483 with the name of the variable. It shares marshalling and dispatch code
484 and underlying C type with the other string types.
485 """
486 dbus_type = "DBUS_TYPE_SIGNATURE"
487 dbus_code = "g"
488
489
490class DBusArray(DBusType):
491 """D-Bus array.
492
493 This class represents the D-Bus array type, it should be first
494 sub-classed with member_type set to an appropriate other class (the
495 forType classmethod can do that for you) and then instantiated with
496 the name of the variable.
497 """
498 dbus_type = "DBUS_TYPE_ARRAY"
499 dbus_code = "a"
500
501 @classmethod
502 def forType(cls, type):
503 class _DBusArray(DBusArray):
504 member_type = type
505
506 return _DBusArray
507
508 def __init__(self, name):
509 super(DBusArray, self).__init__(name)
510
511 self.iter_name = "%s_iter" % (self.name,)
512 self.len_name = "%s_len" % (self.name,)
513 self.loop_name = "%s_p" % (self.name,)
514
515 self.type = self.member_type("%s_elem" % (self.name, ))
516 # FIXME doesn't handle arrays of simple arrays since the length
517 # field is lost.
518 assert (len(self.type.vars()) == 1)
519
520 self.c_type = pointerify(self.type.c_type)
521
522 def signature(self, pointer=False, const=False):
523 """Type signature.
524
525 Returns a string containing the D-Bus type signature for this type.
526 """
527 return self.dbus_code + self.type.signature()
528
529 def locals(self, pointer=False, const=False):
530 """Local variable type and name.
531
532 Returns a list containing necessary local variables for iteration
533 of this type.
534 """
535 locals = [ ( "DBusMessageIter", self.iter_name )]
536 if self.type.c_type.endswith("*"):
537 locals.append(( "size_t", self.len_name ))
538
539 return locals
540
541 def vars(self, pointer=False, const=False):
542 """Variable type and name.
543
544 Returns a list containing tuples of C type and name for each type
545 within this group.
546 """
547 vars = [ ( self.realType(self.c_type, pointer, const),
548 self.name ) ]
549 if not self.type.c_type.endswith("*"):
550 vars.append(( self.realType("size_t", pointer, const),
551 self.len_name ))
552
553 return vars
554
555 def names(self, pointer=False, const=False):
556 """Variable name.
557
558 Returns a list containing a single string; the name given when creating
559 the instance.
560 """
561 names = [ self.name ]
562 if not self.type.c_type.endswith("*"):
563 names.append(self.len_name)
564
565 return names
566
567 def marshal(self, iter_name, parent, type_error, mem_error,
568 pointer=False, const=False):
569 """Marshalling code.
570
571 Returns a string containing the code that will marshal from an
572 iterator with the name given into local variables with the
573 types and names as returned by vars().
574 """
575 name = self.name
576 len_name = self.len_name
577 if pointer:
578 name = "*%s" % (name, )
579 if not self.type.c_type.endswith("*"):
580 len_name = "*%s" % (len_name, )
581
582 code = """\
583if (dbus_message_iter_get_arg_type (&%s) != %s) {
584%s
585}
586
587if (dbus_message_iter_get_element_type (&%s) != %s) {
588%s
589}
590
591dbus_message_iter_recurse (&%s, &%s);
592
593%s = NULL;
594%s = 0;
595
596while (dbus_message_iter_get_arg_type (&%s) != DBUS_TYPE_INVALID) {
597""" % (iter_name, self.dbus_type, type_error,
598 iter_name, self.type.dbus_type, type_error,
599 iter_name, self.iter_name,
600 name, len_name,
601 self.iter_name)
602
603 vars = self.type.vars()
604 vars.extend(self.type.locals())
605 code += indent(''.join("%s;\n" % var for var in lineup_vars(vars)), 1)
606
607 code += "\n"
608 code += indent(self.type.marshal("%s_iter" % self.name, parent,
609 type_error, mem_error), 1)
610
611 code += "\n"
612 code += indent("""\
613%s = nih_realloc (%s, %s, sizeof (%s) * ((%s) + 1));
614if (! %s) {
615%s
616}
617
618(%s)[(%s)++] = %s;
619""" % (name, name, parent, self.type.c_type, len_name,
620 name, mem_error,
621 name, len_name, self.type.name), 1)
622
623 code += "\n"
624 code += """\
625}
626
627dbus_message_iter_next (&%s);
628""" % (iter_name, )
629
630 if self.type.c_type.endswith("*"):
631 code += "\n"
632 code += """\
633%s = nih_realloc (%s, %s, sizeof (%s) * ((%s) + 1));
634if (! %s) {
635%s
636}
637
638(%s)[(%s)] = NULL;
639""" % (name, name, parent, self.type.c_type, len_name,
640 name, mem_error,
641 name, len_name)
642
643 return code
644
645 def dispatch(self, iter_name, mem_error,
646 pointer=False, const=False):
647 """Dispatching code.
648
649 Returns a string containing the code that will dispatch from
650 local variables with the types and names as returned by vars() to
651 an iterator with the name given.
652 """
653 name = self.name
654 len_name = self.len_name
655 if pointer:
656 name = "*%s" % (name, )
657 if not self.type.c_type.endswith("*"):
658 len_name = "*%s" % (len_name, )
659
660 code = """\
661if (! dbus_message_iter_open_container (&%s, %s, \"%s\", &%s)) {
662%s
663}
664""" % (iter_name, self.dbus_type, self.type.signature(),
665 self.iter_name, mem_error)
666
667 code += "\n"
668 if self.type.c_type.endswith("*"):
669 code += """\
670%s = 0;
671for (%s%s = %s; %s && *%s; %s++) {
672""" % (len_name,
673 self.realType(self.c_type, const=const), self.loop_name, name,
674 self.loop_name, self.loop_name,
675 self.loop_name)
676 else:
677 code += """\
678for (%s%s = %s; %s < %s + %s; %s++) {
679""" % (self.realType(self.c_type, const=const), self.loop_name, name,
680 self.loop_name, name, len_name, self.loop_name)
681
682 vars = self.type.vars()
683 vars.extend(self.type.locals())
684 code += indent(''.join("%s;\n" % var for var in lineup_vars(vars)), 1)
685
686 code += "\n"
687 code += indent("""\
688%s = *%s;
689""" % (self.type.name, self.loop_name), 1)
690
691 code += "\n"
692 code += indent(self.type.dispatch(self.iter_name, mem_error), 1)
693
694 if self.type.c_type.endswith("*"):
695 code += "\n"
696 code += indent("""\
697(%s)++;
698""" % (len_name, ), 1)
699
700 code += """\
701}
702
703if (! dbus_message_iter_close_container (&%s, &%s)) {
704%s
705}
706""" % (iter_name, self.iter_name, mem_error)
707
708 return code
709
710
711class DBusGroup(object):
712 def __init__(self, types, pointer=False, const=False):
713 self.types = types
714 self.pointer = pointer
715 self.const = const
716
717 def signature(self):
718 """Type signature.
719
720 Returns a string containing the D-Bus type signature for this type.
721 """
722 signature = ""
723
724 for type in self.types:
725 signature += type.signature(pointer=self.pointer, const=self.const)
726
727 return signature
728
729 def vars(self):
730 """Variable type and name.
731
732 Returns a list containing tuples of C type and name for each type
733 within this group.
734 """
735 vars = []
736
737 for type in self.types:
738 vars.extend(type.vars(pointer=self.pointer, const=self.const))
739
740 return vars
741
742 def names(self):
743 """Variable names.
744
745 Returns a list of names of all types in this group.
746 """
747 names = []
748
749 for type in self.types:
750 names.extend(type.names())
751 return names
752
753 def locals(self):
754 """Local variable type and name.
755
756 Returns a list containing necessary local variables for iteration
757 of this type.
758 """
759 locals = []
760
761 for type in self.types:
762 locals.extend(type.locals(pointer=self.pointer, const=self.const))
763
764 return locals
765
766 def marshal(self, iter_name, parent, type_error, mem_error):
767 """Marshalling code.
768
769 Returns a string containing the code that will marshal from an
770 iterator with the name given into local variables with the
771 types and names as returned by vars().
772 """
773 code = ""
774
775 for type in self.types:
776 if code:
777 code += "\n"
778 code += type.marshal(iter_name, parent, type_error, mem_error,
779 pointer=self.pointer, const=self.const)
780
781 if code:
782 code += "\n"
783 code += """\
784if (dbus_message_iter_get_arg_type (&%s) != DBUS_TYPE_INVALID) {
785%s
786}
787""" % (iter_name, type_error)
788
789 return code
790
791 def dispatch(self, iter_name, mem_error):
792 """Dispatching code.
793
794 Returns a string containing the code that will dispatch from
795 local variables with the types and names as returned by vars() to
796 an iterator with the name given.
797 """
798 code = ""
799
800 for type in self.types:
801 if code:
802 code += "\n"
803 code += type.dispatch(iter_name, mem_error,
804 pointer=self.pointer, const=self.const)
805
806 return code
807
808
809class Generator(object):
810 def staticPrototypes(self):
811 """Static prototypes.
812
813 Returns an array of static function prototypes which are normally
814 placed in a block at the top of the source file.
815
816 Each prototype is a (retval, name, args, attributes) tuple.
817 """
818 return []
819
820 def exportTypedefs(self):
821 """Exported typedefs.
822
823 Type definitions that should be placed in the header.
824
825 Each typedef is the code to define it, including any documentation and
826 default value.
827 """
828 return []
829
830 def externPrototypes(self):
831 """Extern prototypes.
832
833 Returns an array of extern function prototypes which are normally
834 placed in a block at the top of the source file, in lieu of
835 missing headers.
836
837 Each prototype is a (retval, name, args, attributes) tuple.
838 """
839 return []
840
841 def variables(self):
842 """Variables.
843
844 Returns an array of both static and exported global variables
845 normally placed in a block at the top of the source file.
846
847 Each variable is the code to define it, including any documentation
848 and default value.
849 """
850 return []
851
852 def functions(self):
853 """Functions.
854
855 Returns an array of both static and exported functions which
856 consistute the bulk of the source file.
857
858 Each function is the code to define it, including any documentation.
859 """
860 return []
861
862 def definitions(self):
863 """Definitions.
864
865 Returns an array of structure and type definitions which are
866 normally placed in a block in the header file.
867
868 Each definition is the code to define it, including any documentation.
869 """
870 return []
871
872 def exports(self):
873 """Exports.
874
875 Returns an array of prototypes for exported variables which are
876 placed as a block inside the extern part of the header file.
877
878 Each export is a (type, name) tuple.
879 """
880 return []
881
882 def exportPrototypes(self):
883 """Function prototypes.
884
885 Returns an array of exported function prototypes which are normally
886 placed in a block inside the extern part of the header file.
887
888 Each prototype is a (retval, name, args, attributes) tuple.
889 """
890 return []
891
892
893class Member(Generator):
894 def __init__(self, interface, name):
895 self.interface = interface
896 self.name = name
897
898 @property
899 def c_name(self):
900 return self.name
901
902 @property
903 def extern_name(self):
904 return "_".join(( extern_prefix,
905 NAME_RE.sub("\\1_\\2", self.c_name).lower()))
906
907
908class MemberWithArgs(Member):
909 @classmethod
910 def fromElement(cls, interface, elem):
911 name = elem.get("name")
912 if name is None:
913 raise AttributeError, "Name may not be null"
914
915 types = [ DBusType.fromElement(e) for e in elem.findall("arg") ]
916
917 self = cls(interface, name, types)
918 self.style = elem.get(ElementTree.QName(XMLNS, mode), self.style)
919 return self
920
921 def __init__(self, interface, name, types):
922 super(MemberWithArgs, self).__init__(interface, name)
923
924 self.style = "sync"
925 self.types = types
926
927 def argArray(self):
928 """Argument array.
929
930 Returns a string containing code to initialise the array of arguments
931 used for nih_dbus_object_new().
932 """
933 code = """\
934static const NihDBusArg %s[] = {
935""" % "_".join([ self.interface.c_name, self.c_name, "args" ])
936
937 array = []
938 for type in self.types:
939 if type.direction == "in":
940 direction = "NIH_DBUS_ARG_IN"
941 elif type.direction == "out":
942 direction = "NIH_DBUS_ARG_OUT"
943
944 array.append(( "\"%s\"" % type.name,
945 "\"%s\"" % type.signature(),
946 direction ))
947
948 for line in lineup_array(array):
949 code += indent("%s,\n" % line, 1)
950
951 code += """\
952 { NULL }
953};
954"""
955 return code
956
957 def variables(self):
958 """Variables.
959
960 Returns an array of both static and exported global variables
961 normally placed in a block at the top of the source file.
962
963 Each variable is the code to define it, including any documentation
964 and default value.
965 """
966 variables = []
967 if mode == "object":
968 variables.append(self.argArray())
969
970 return variables
971
972
973class Method(MemberWithArgs):
974 def __init__(self, interface, name, types):
975 super(Method, self).__init__(interface, name, types)
976
977 def marshalPrototype(self):
978 """Marshalling function prototype.
979
980 Returns a (retval, name, args, attributes) tuple for the prototype
981 of the marshaller function.
982 """
983 return ( "static DBusHandlerResult",
984 "_".join([ self.interface.c_name, self.c_name, "marshal" ]),
985 [ ( "NihDBusObject *", "object" ),
986 ( "NihDBusMessage *", "message" ) ],
987 None )
988
989 def marshalFunction(self):
990 """Marshalling function.
991
992 Returns a string containing a marshaller function that takes
993 arguments from a D-Bus message, calls a C handler function with
994 them passed properly, then constructs a reply if successful.
995 """
996 in_args = DBusGroup([t for t in self.types if t.direction == "in"])
997 out_args = DBusGroup([t for t in self.types if t.direction == "out"])
998
999 name = "_".join([ self.interface.c_name, self.c_name, "marshal" ])
1000 code = """\
1001static DBusHandlerResult
1002%s (NihDBusObject *object,
1003%s NihDBusMessage *message)
1004{
1005""" % (name, " " * len(name))
1006
1007 # Declare local variables for the iterator, reply and those needed
1008 # for both input and output arguments.
1009 vars = [ ( "DBusMessageIter", "iter" ),
1010 ( "DBusMessage *", "reply = NULL" ) ]
1011 vars.extend(in_args.vars())
1012 vars.extend(in_args.locals())
1013 if self.style != "async":
1014 vars.extend(out_args.vars())
1015 vars.extend(out_args.locals())
1016
1017 code += indent(''.join("%s;\n" % var for var in lineup_vars(vars)), 1)
1018
1019 # Pre-amble for the function
1020 code += "\n"
1021 code += indent("""\
1022nih_assert (object != NULL);
1023nih_assert (message != NULL);
1024""", 1);
1025
1026 # Marshal the input arguments into local variables
1027 code += "\n"
1028 code += indent("""\
1029/* Iterate the arguments to the message and marshal into arguments
1030 * for our own function call.
1031 */
1032dbus_message_iter_init (message->message, &iter);
1033""", 1)
1034 code += "\n"
1035
1036 mem_error = indent("""\
1037return DBUS_HANDLER_RESULT_NEED_MEMORY;
1038""", 1)
1039 type_error = indent("""\
1040reply = dbus_message_new_error (message->message, DBUS_ERROR_INVALID_ARGS,
1041 _("Invalid arguments to %s method"));
1042if (! reply) {
1043%s
1044}
1045
1046goto send;
1047""" % (self.name, mem_error), 1)
1048 code += indent(in_args.marshal("iter", "message",
1049 type_error, mem_error), 1)
1050
1051 # Construct the function call
1052 args = [ "object->data", "message" ]
1053 args.extend(n for t, n in in_args.vars())
1054 if self.style != "async":
1055 args.extend("&%s" % n for t, n in out_args.vars())
1056
1057 code += "\n"
1058 code += indent("""\
1059/* Call the handler function. */
1060if (%s (%s) < 0) {
1061 NihError *err;
1062
1063 err = nih_error_get ();
1064 if (err->number == ENOMEM) {
1065 nih_free (err);
1066
1067 return DBUS_HANDLER_RESULT_NEED_MEMORY;
1068 } else if (err->number == NIH_DBUS_ERROR) {
1069 NihDBusError *dbus_err = (NihDBusError *)err;
1070
1071 reply = dbus_message_new_error (message->message,
1072 dbus_err->name,
1073 err->message);
1074 nih_free (err);
1075
1076 if (! reply)
1077 return DBUS_HANDLER_RESULT_NEED_MEMORY;
1078
1079 goto send;
1080 } else {
1081 reply = dbus_message_new_error (message->message,
1082 DBUS_ERROR_FAILED,
1083 err->message);
1084 nih_free (err);
1085
1086 if (! reply)
1087 return DBUS_HANDLER_RESULT_NEED_MEMORY;
1088
1089 goto send;
1090 }
1091}
1092""" % (self.extern_name, ", ".join(args)), 1)
1093
1094 if self.style == "async":
1095 code += "\n"
1096 code += indent("return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;\n", 1)
1097 else:
1098 # Be well-behaved and make the function return immediately
1099 # if no reply is expected
1100 code += "\n"
1101 code += indent("""\
1102/* If the sender doesn't care about a reply, don't bother wasting
1103 * effort constructing and sending one.
1104 */
1105if (dbus_message_get_no_reply (message->message))
1106 return DBUS_HANDLER_RESULT_HANDLED;
1107""", 1)
1108
1109 # Create reply and dispatch the local variables into output
1110 # arguments
1111 code += "\n"
1112 code += indent("""\
1113/* Construct the reply message */
1114reply = dbus_message_new_method_return (message->message);
1115if (! reply)
1116 return DBUS_HANDLER_RESULT_NEED_MEMORY;
1117
1118dbus_message_iter_init_append (reply, &iter);
1119""", 1)
1120 code += "\n"
1121
1122 mem_error = indent("""\
1123dbus_message_unref (reply);
1124return DBUS_HANDLER_RESULT_NEED_MEMORY;
1125""", 1)
1126 code += indent(out_args.dispatch("iter", mem_error), 1)
1127
1128 # Send the reply
1129 code += "\nsend:\n"
1130 code += indent("""\
1131/* Send the reply, appending it to the outgoing queue. */
1132if (! dbus_connection_send (message->conn, reply, NULL)) {
1133 dbus_message_unref (reply);
1134 return DBUS_HANDLER_RESULT_NEED_MEMORY;
1135}
1136
1137dbus_message_unref (reply);
1138
1139return DBUS_HANDLER_RESULT_HANDLED;
1140""", 1)
1141
1142 code += "}\n"
1143
1144 return code
1145
1146 def handlerPrototype(self):
1147 """Handler function prototype.
1148
1149 Returns a (retval, name, args, attributes) tuple for the prototype
1150 of the handler function that the user must define.
1151 """
1152 in_args = DBusGroup([t for t in self.types if t.direction == "in"],
1153 const=True)
1154 out_args = DBusGroup([t for t in self.types if t.direction == "out"],
1155 pointer=True)
1156
1157 vars = [ ("void *", "data"),
1158 ("NihDBusMessage *", "message") ]
1159 vars.extend(in_args.vars())
1160 if self.style != "async":
1161 vars.extend(out_args.vars())
1162
1163 return ( "extern int",
1164 self.extern_name,
1165 vars,
1166 None )
1167
1168 def replyPrototype(self):
1169 """Reply function prototype.
1170
1171 Returns a (retval, name, args, attributes) tuple for the prototype
1172 of the reply function defined for async functions.
1173 """
1174 out_args = DBusGroup([t for t in self.types if t.direction == "out"],
1175 const=True)
1176
1177 vars = [("NihDBusMessage *", "message") ]
1178 vars.extend(out_args.vars())
1179
1180 return ( "int",
1181 "_".join([ self.extern_name, "reply" ]),
1182 vars,
1183 None )
1184
1185 def replyFunction(self):
1186 """Reply function.
1187
1188 Returns a string containing a reply function that takes its
1189 arguments and produces a D-Bus message reply.
1190 """
1191 out_args = DBusGroup([t for t in self.types if t.direction == "out"],
1192 const=True)
1193
1194 name = "_".join([ self.extern_name, "reply" ])
1195 vars = [ ( "NihDBusMessage *", "message" ) ]
1196 vars.extend(out_args.vars())
1197
1198 code = "int\n%s (" % (name, )
1199 code += (",\n" + " " * (len(name) + 2)).join(lineup_vars(vars))
1200 code += ")\n{\n"
1201
1202 # Declare local variables for the iterator and the reply
1203 vars = [ ( "DBusMessageIter", "iter" ),
1204 ( "DBusMessage *", "reply = NULL" ) ]
1205 vars.extend(out_args.locals())
1206
1207 code += indent(''.join("%s;\n" % var for var in lineup_vars(vars)), 1)
1208
1209 # Pre-amble for the function
1210 code += "\n"
1211 code += indent("""\
1212nih_assert (message != NULL);
1213""", 1);
1214
1215 # Be well-behaved and don't actually send the reply if one is
1216 # not expected
1217 code += "\n"
1218 code += indent("""\
1219/* If the sender doesn't care about a reply, don't bother wasting
1220 * effort constructing and sending one.
1221 */
1222if (dbus_message_get_no_reply (message->message)) {
1223 nih_free (message);
1224 return 0;
1225}
1226""", 1)
1227
1228 # Create reply and dispatch the local variables into output
1229 # arguments
1230 code += "\n"
1231 code += indent("""\
1232/* Construct the reply message */
1233reply = dbus_message_new_method_return (message->message);
1234if (! reply)
1235 return -1;
1236
1237dbus_message_iter_init_append (reply, &iter);
1238""", 1)
1239 code += "\n"
1240
1241 mem_error = indent("""\
1242dbus_message_unref (reply);
1243return -1;
1244""", 1)
1245 code += indent(out_args.dispatch("iter", mem_error), 1)
1246
1247 # Send the reply
1248 code += "\n"
1249 code += indent("""\
1250/* Send the reply, appending it to the outgoing queue. */
1251if (! dbus_connection_send (message->conn, reply, NULL)) {
1252 dbus_message_unref (reply);
1253 return -1;
1254}
1255
1256dbus_message_unref (reply);
1257nih_free (message);
1258
1259return 0;
1260""", 1)
1261
1262 code += "}\n"
1263
1264 return code
1265
1266 def asyncNotifyPrototype(self):
1267 """Asynchronous dispatch function prototype.
1268
1269 Returns a (retval, name, args, attributes) tuple for the prototype
1270 of the asynchronous dispatch function.
1271 """
1272 vars = [ ( "DBusPendingCall *", "call" ),
1273 ( "NihAsyncNotifyData *", "data" ) ]
1274
1275 return ( "static void",
1276 self.extern_name + "_async_notify",
1277 vars, ( ) )
1278
1279 def asyncDispatchPrototype(self):
1280 """Asynchronous dispatch function prototype.
1281
1282 Returns a (retval, name, args, attributes) tuple for the prototype
1283 of the asynchronous dispatch function.
1284 """
1285 in_args = DBusGroup([t for t in self.types if t.direction == "in"],
1286 const=True)
1287 out_args = DBusGroup([t for t in self.types if t.direction == "out"])
1288
1289 vars = [ ( "NihDBusProxy *", "proxy" ) ]
1290 vars.extend(in_args.vars())
1291 vars += [ ( "%sCallback" % camelate(self.extern_name), "callback" ),
1292 ( "%sErrback" % camelate(self.extern_name), "errback" ),
1293 ( "void *", "userdata" ) ]
1294
1295 return ( "int",
1296 self.extern_name + "_async",
1297 vars,
1298 ( "warn_unused_result", ) )
1299
1300 def dispatchPrototype(self):
1301 """Dispatch function prototype.
1302
1303 Returns a (retval, name, args, attributes) tuple for the prototype
1304 of the dispatch function.
1305 """
1306 in_args = DBusGroup([t for t in self.types if t.direction == "in"],
1307 const=True)
1308 out_args = DBusGroup([t for t in self.types if t.direction == "out"],
1309 pointer=True)
1310
1311 vars = [ ( "NihDBusProxy *", "proxy" ) ]
1312 vars.extend(in_args.vars())
1313 # FIXME async doesn't have these, but has a callback instead
1314 vars.extend(out_args.vars())
1315
1316 return ( "int",
1317 self.extern_name,
1318 vars,
1319 ( "warn_unused_result", ) )
1320
1321 def asyncNotifyFunction(self):
1322 """Asynchronous notification function.
1323
1324 Called when an asynchronously dispatched function returns something.
1325 Fetches out the arguments and passes them to a user-supplied function.
1326 """
1327 out_args = DBusGroup([t for t in self.types if t.direction == "out"])
1328
1329 vars = [ ( "DBusPendingCall *", "call" ),
1330 ( "NihAsyncNotifyData *", "data" ) ]
1331
1332 code = "static void\n%s (" % (self.extern_name + "_async_notify", )
1333 code += (",\n" + " " * (len(self.extern_name + "_async_notify") + 2)).join(lineup_vars(vars))
1334 code += ")\n{\n"
1335
1336 # Declare local variables for the iterator, reply and those needed
1337 # for both input and output arguments.
1338 vars = [ ( "DBusMessage *", "reply" ),
1339 ( "DBusMessageIter", "iter" ),
1340 ( "int", "type" ) ]
1341 vars.extend(out_args.locals())
1342 vars.extend(out_args.vars())
1343 code += indent(''.join("%s;\n" % var for var in lineup_vars(vars)), 1)
1344
1345 # Pre-amble for the function
1346 code += "\n"
1347
1348 code += indent("""\
1349reply = dbus_pending_call_steal_reply(call);
1350
1351nih_assert (reply != NULL);
1352
1353type = dbus_message_get_type (reply);
1354
1355nih_assert (type == DBUS_MESSAGE_TYPE_METHOD_RETURN ||
1356 type == DBUS_MESSAGE_TYPE_ERROR);
1357
1358if (type == DBUS_MESSAGE_TYPE_ERROR) {
1359 char *name;
1360 DBusError error;
1361
1362 dbus_error_init (&error);
1363 dbus_set_error_from_message (&error, reply);
1364
1365 if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY)) {
1366 errno = ENOMEM;
1367 nih_error_raise_system ();
1368 } else {
1369 nih_dbus_error_raise (error.name, error.message);
1370 }
1371
1372 ((%sErrback)data->err_handler)(data->proxy, data->userdata);
1373
1374 dbus_error_free (&error);
1375 goto out;
1376}
1377""" % camelate(self.extern_name), 1);
1378
1379 # Marshal the reply arguments into output arguments
1380 code += "\n"
1381 code += indent("""\
1382/* Iterate the arguments to the reply and marshal into output
1383 * arguments from our own function call.
1384 */
1385dbus_message_iter_init (reply, &iter);
1386""", 1);
1387 code += "\n"
1388
1389 mem_error = indent("""\
1390errno = ENOMEM;
1391nih_error_raise_system ();
1392((%sErrback)data->err_handler)(data->proxy, data->userdata);
1393goto out;
1394""" % camelate(self.extern_name), 1)
1395 type_error = indent("""\
1396nih_error_raise (NIH_DBUS_INVALID_ARGS, NIH_DBUS_INVALID_ARGS_STR);
1397((%sErrback)data->err_handler)(data->proxy, data->userdata);
1398goto out;
1399""" % camelate(self.extern_name), 1);
1400 code += indent(out_args.marshal("iter", "data->proxy",
1401 type_error, mem_error), 1)
1402
1403 code += "\n\n"
1404 code += indent("""\
1405((%sCallback)data->handler)(%s);
1406""" % (camelate(self.extern_name), ", ".join([ "data->proxy", "data->userdata" ] + out_args.names())), 1)
1407
1408 code += "out:\n"
1409 code += indent("""\
1410
1411dbus_message_unref (reply);
1412dbus_pending_call_unref (call);
1413
1414return;
1415""", 1)
1416
1417 code += "}\n"
1418
1419 return code
1420
1421 def asyncDispatchFunction(self):
1422 """Asynchronous dispatching function.
1423
1424 Returns a string containing a dispatcher function that takes arguments
1425 identical to those taken by a particular dbus method, and pointers to
1426 variables where the return values from that method might be stored. Then
1427 sends a dbus message and waits for a reply to come, and populates the
1428 reply arguments with the contents of the reply message.
1429 """
1430 in_args = DBusGroup([t for t in self.types if t.direction == "in"],
1431 const=True)
1432 out_args = DBusGroup([t for t in self.types if t.direction == "out"])
1433
1434 vars = [ ( "NihDBusProxy *", "proxy" ) ]
1435 vars.extend(in_args.vars())
1436 vars += [ ( "%sCallback" % camelate(self.extern_name), "callback" ),
1437 ( "%sErrback" % camelate(self.extern_name), "errback" ),
1438 ( "void *", "userdata" ) ]
1439
1440 code = "int\n%s (" % (self.extern_name + "_async", )
1441 code += (",\n" + " " * (len(self.extern_name + "_async") + 2)).join(lineup_vars(vars))
1442 code += ")\n{\n"
1443
1444 # Declare local variables for the iterator, reply and those needed
1445 # for both input and output arguments.
1446 vars = [ ( "DBusMessage *", "message" ),
1447 ( "DBusMessageIter", "iter" ),
1448 ( "DBusPendingCall *", "call" ),
1449 ( "NihAsyncNotifyData *", "data" ) ]
1450 vars.extend(in_args.locals())
1451 code += indent(''.join("%s;\n" % var for var in lineup_vars(vars)), 1)
1452
1453 # Pre-amble for the function
1454 code += "\n"
1455 code += indent("""\
1456nih_assert (proxy != NULL);
1457nih_assert ((errback != NULL && callback != NULL) ||
1458 (errback == NULL && callback == NULL));
1459""", 1);
1460
1461 # Dispatch the input arguments into a new local message
1462 code += "\n"
1463 code += indent("""\
1464message = dbus_message_new_method_call (proxy->name, proxy->path, "%s", "%s");
1465if (! message)
1466 nih_return_no_memory_error (-1);
1467
1468/* Iterate the arguments to the function and dispatch into
1469 * message arguments.
1470 */
1471dbus_message_iter_init_append (message, &iter);
1472""" % (self.interface.name, self.name), 1)
1473 code += "\n"
1474
1475 # FIXME autostart?
1476
1477 mem_error = indent("""\
1478dbus_message_unref (message);
1479nih_return_no_memory_error (-1);
1480""", 1)
1481 code += indent(in_args.dispatch("iter", mem_error), 1)
1482
1483 # FIXME timeout should be configurable
1484 # FIXME expect no reply?
1485 code += "\n"
1486 code += indent("""\
1487/* If we don't specify a callback, just finish it now */
1488if (! callback) {
1489 dbus_bool_t succ = dbus_connection_send (proxy->conn, message, NULL);
1490 dbus_message_unref (message);
1491 if (! succ)
1492 nih_return_no_memory_error (-1);
1493 return 0;
1494}
1495
1496/* Send the reply, appending it to the outgoing queue and blocking. */
1497if (! dbus_connection_send_with_reply (proxy->conn, message, &call, -1)) {
1498 dbus_message_unref (message);
1499 nih_return_no_memory_error (-1);
1500}
1501
1502data = nih_new (proxy, NihAsyncNotifyData);
1503if (! data)
1504 nih_return_no_memory_error (-1);
1505
1506data->proxy = proxy;
1507data->userdata = userdata;
1508data->handler = callback;
1509data->err_handler = errback;
1510
1511
1512dbus_pending_call_set_notify(call, (DBusPendingCallNotifyFunction)%s_async_notify, data, (DBusFreeFunction)nih_free);
1513
1514dbus_message_unref (message);
1515return 0;
1516""" % self.extern_name, 1);
1517
1518 code += "}\n"
1519
1520 return code
1521
1522 def dispatchFunction(self):
1523 """Dispatching function.
1524
1525 Returns a string containing a dispatcher function that takes arguments
1526 identical to those taken by a particular dbus method, and pointers to
1527 variables where the return values from that method might be stored. Then
1528 sends a dbus message and waits for a reply to come, and populates the
1529 reply arguments with the contents of the reply message.
1530 """
1531 in_args = DBusGroup([t for t in self.types if t.direction == "in"],
1532 const=True)
1533 out_args = DBusGroup([t for t in self.types if t.direction == "out"],
1534 pointer=True)
1535
1536 vars = [ ( "NihDBusProxy *", "proxy" ) ]
1537 vars.extend(in_args.vars())
1538 # FIXME async doesn't have these, but has a callback instead
1539 vars.extend(out_args.vars())
1540
1541 code = "int\n%s (" % (self.extern_name, )
1542 code += (",\n" + " " * (len(self.extern_name) + 2)).join(lineup_vars(vars))
1543 code += ")\n{\n"
1544
1545 # Declare local variables for the iterator, reply and those needed
1546 # for both input and output arguments.
1547 vars = [ ( "DBusMessage *", "message" ),
1548 ( "DBusMessageIter", "iter" ),
1549 ( "DBusMessage *", "reply = NULL" ),
1550 ( "DBusError", "error" ) ]
1551 vars.extend(in_args.locals())
1552 # FIXME not for async
1553 vars.extend(out_args.locals())
1554 code += indent(''.join("%s;\n" % var for var in lineup_vars(vars)), 1)
1555
1556 # Pre-amble for the function
1557 code += "\n"
1558 code += indent("""\
1559nih_assert (proxy != NULL);
1560""", 1);
1561
1562 # Dispatch the input arguments into a new local message
1563 code += "\n"
1564 code += indent("""\
1565message = dbus_message_new_method_call (proxy->name, proxy->path, "%s", "%s");
1566if (! message)
1567 nih_return_no_memory_error (-1);
1568
1569/* Iterate the arguments to the function and dispatch into
1570 * message arguments.
1571 */
1572dbus_message_iter_init_append (message, &iter);
1573""" % (self.interface.name, self.name), 1)
1574 code += "\n"
1575
1576 # FIXME autostart?
1577
1578 mem_error = indent("""\
1579dbus_message_unref (message);
1580nih_return_no_memory_error (-1);
1581""", 1)
1582 code += indent(in_args.dispatch("iter", mem_error), 1)
1583
1584 # FIXME timeout should be configurable
1585 # FIXME expect no reply?
1586 code += "\n"
1587 code += indent("""\
1588dbus_error_init (&error);
1589
1590/* Send the reply, appending it to the outgoing queue and blocking. */
1591reply = dbus_connection_send_with_reply_and_block (proxy->conn, message, -1, &error);
1592if (! reply) {
1593 dbus_message_unref (message);
1594
1595 if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY)) {
1596 dbus_error_free (&error);
1597 nih_return_no_memory_error (-1);
1598 } else {
1599 nih_dbus_error_raise (error.name, error.message);
1600 dbus_error_free (&error);
1601 return -1;
1602 }
1603}
1604
1605dbus_message_unref (message);
1606""", 1);
1607
1608 # Marshal the reply arguments into output arguments
1609 code += "\n"
1610 code += indent("""\
1611/* Iterate the arguments to the reply and marshal into output
1612 * arguments from our own function call.
1613 */
1614dbus_message_iter_init (reply, &iter);
1615""", 1);
1616 code += "\n"
1617
1618 mem_error = indent("""\
1619dbus_message_unref (reply);
1620nih_return_no_memory_error (-1);
1621""", 1)
1622 type_error = indent("""\
1623dbus_message_unref (reply);
1624nih_return_error (-1, NIH_DBUS_INVALID_ARGS, NIH_DBUS_INVALID_ARGS_STR);
1625""", 1);
1626 code += indent(out_args.marshal("iter", "proxy",
1627 type_error, mem_error), 1)
1628
1629 code += "\n"
1630 code += indent("""\
1631dbus_message_unref (reply);
1632
1633return 0;
1634""", 1)
1635
1636 code += "}\n"
1637
1638 return code
1639
1640 def exportTypedefs(self):
1641 """Exported typedefs.
1642
1643 Type definitions that should be placed in the header.
1644
1645 Each typedef is the code to define it, including any documentation and
1646 default value.
1647 """
1648 typedefs = []
1649 out_args = DBusGroup([t for t in self.types if t.direction == "out"])
1650 if mode == "proxy":
1651 typedefs.append( ("void",
1652 "(*%sCallback)" % camelate(self.extern_name),
1653 [ ( "NihDBusProxy *", "proxy" ),
1654 ( "void *", "userdata") ] + out_args.vars()
1655 ) )
1656 typedefs.append( ("void",
1657 "(*%sErrback)" % camelate(self.extern_name),
1658 [ ( "NihDBusProxy *", "proxy" ),
1659 ( "void *", "userdata") ]
1660 ) )
1661 return typedefs
1662
1663 def staticPrototypes(self):
1664 """Static prototypes.
1665
1666 Returns an array of static function prototypes which are normally
1667 placed in a block at the top of the source file.
1668
1669 Each prototype is a (retval, name, args, attributes) tuple.
1670 """
1671 prototypes = []
1672 if mode == "object":
1673 prototypes.append(self.marshalPrototype())
1674 else:
1675 prototypes.append(self.asyncNotifyPrototype())
1676
1677 return prototypes
1678
1679 def externPrototypes(self):
1680 """Extern prototypes.
1681
1682 Returns an array of extern function prototypes which are normally
1683 placed in a block at the top of the source file, in lieu of
1684 missing headers.
1685
1686 Each prototype is a (retval, name, args, attributes) tuple.
1687 """
1688 prototypes = []
1689 if mode =="object":
1690 prototypes.append(self.handlerPrototype())
1691
1692 return prototypes
1693
1694 def functions(self):
1695 """Functions.
1696
1697 Returns an array of both static and exported functions which
1698 consistute the bulk of the source file.
1699
1700 Each function is the code to define it, including any documentation.
1701 """
1702 functions = []
1703 if mode == "object":
1704 functions.append(self.marshalFunction())
1705 if self.style == "async":
1706 functions.append(self.replyFunction())
1707 else:
1708 functions.append(self.dispatchFunction())
1709 functions.append(self.asyncDispatchFunction())
1710 functions.append(self.asyncNotifyFunction())
1711
1712 return functions
1713
1714 def exportPrototypes(self):
1715 """Function prototypes.
1716
1717 Returns an array of exported function prototypes which are normally
1718 placed in a block inside the extern part of the header file.
1719
1720 Each prototype is a (retval, name, args, attributes) tuple.
1721 """
1722 prototypes = []
1723 if mode == "object":
1724 if self.style == "async":
1725 prototypes.append(self.replyPrototype())
1726 else:
1727 prototypes.append(self.dispatchPrototype())
1728 prototypes.append(self.asyncDispatchPrototype())
1729
1730 return prototypes
1731
1732
1733class Signal(MemberWithArgs):
1734 def __init__(self, interface, name, types):
1735 super(Signal, self).__init__(interface, name, types)
1736
1737 def dispatchPrototype(self):
1738 """Dispatch function prototype.
1739
1740 Returns a (retval, name, args, attributes) tuple for the prototype
1741 of the dispatch function.
1742 """
1743 args = DBusGroup(self.types, const=True)
1744
1745 vars = [ ( "DBusConnection *", "connection" ),
1746 ( "const char *", "origin_path" ) ]
1747 vars.extend(args.vars())
1748
1749 return ( "int",
1750 self.extern_name,
1751 vars,
1752 ( "warn_unused_result", ) )
1753
1754 def dispatchFunction(self):
1755 """Dispatch function.
1756
1757 Returns a string containing a dispatch function that takes puts
1758 its arguments into a D-Bus message and sends it.
1759 """
1760 args = DBusGroup(self.types, const=True)
1761
1762 vars = [ ( "DBusConnection *", "connection" ),
1763 ( "const char *", "origin_path" ) ]
1764 vars.extend(args.vars())
1765
1766 code = "int\n%s (" % (self.extern_name, )
1767 code += (",\n" + " " * (len(self.extern_name) + 2)).join(lineup_vars(vars))
1768 code += ")\n{\n"
1769
1770 # Declare local variables for the message and iterator
1771 vars = [ ( "DBusMessage *", "message"),
1772 ( "DBusMessageIter", "iter" ) ]
1773 vars.extend(args.locals())
1774 code += indent(''.join("%s;\n" % var for var in lineup_vars(vars)), 1)
1775
1776 # Pre-amble for the function
1777 code += "\n"
1778 code += indent("""\
1779nih_assert (connection != NULL);
1780nih_assert (origin_path != NULL);
1781""", 1)
1782
1783 # Marshal the arguments into a new local message
1784 code += "\n"
1785 code += indent("""\
1786message = dbus_message_new_signal (origin_path, "%s", "%s");
1787if (! message)
1788 return -1;
1789
1790/* Iterate the arguments to the function and dispatch into
1791 * message arguments.
1792 */
1793dbus_message_iter_init_append (message, &iter);
1794""" % (self.interface.name, self.name), 1)
1795 code += "\n"
1796
1797 mem_error = indent("""\
1798dbus_message_unref (message);
1799return -1;
1800""", 1)
1801 code += indent(args.dispatch("iter", mem_error), 1)
1802
1803 code += "\n"
1804 code += indent("""\
1805/* Send the reply, appending it to the outgoing queue. */
1806if (! dbus_connection_send (connection, message, NULL)) {
1807 dbus_message_unref (message);
1808 return -1;
1809}
1810
1811dbus_message_unref (message);
1812
1813return 0;
1814""", 1)
1815
1816 code += "}\n"
1817
1818 return code
1819
1820 def functions(self):
1821 """Functions.
1822
1823 Returns an array of both static and exported functions which
1824 consistute the bulk of the source file.
1825
1826 Each function is the code to define it, including any documentation.
1827 """
1828 functions = []
1829 if mode == "object":
1830 functions.append(self.dispatchFunction())
1831
1832 return functions
1833
1834 def exportPrototypes(self):
1835 """Function prototypes.
1836
1837 Returns an array of exported function prototypes which are normally
1838 placed in a block inside the extern part of the header file.
1839
1840 Each prototype is a (retval, name, args, attributes) tuple.
1841 """
1842 prototypes = []
1843 if mode == "object":
1844 prototypes.append(self.dispatchPrototype())
1845
1846 return prototypes
1847
1848
1849class Group(Generator):
1850 def __init__(self, members):
1851 self.members = members
1852
1853 def staticPrototypes(self):
1854 """Static prototypes.
1855
1856 Returns an array of static function prototypes which are normally
1857 placed in a block at the top of the source file.
1858
1859 Each prototype is a (retval, name, args, attributes) tuple.
1860 """
1861 prototypes = []
1862 for member in self.members:
1863 prototypes.extend(member.staticPrototypes())
1864
1865 return prototypes
1866
1867 def externPrototypes(self):
1868 """Extern prototypes.
1869
1870 Returns an array of extern function prototypes which are normally
1871 placed in a block at the top of the source file, in lieu of
1872 missing headers.
1873
1874 Each prototype is a (retval, name, args, attributes) tuple.
1875 """
1876 prototypes = []
1877 for member in self.members:
1878 prototypes.extend(member.externPrototypes())
1879
1880 return prototypes
1881
1882 def exportTypedefs(self):
1883 """Exported typedefs.
1884
1885 Type definitions that should be placed in the header.
1886
1887 Each typedef is the code to define it, including any documentation and
1888 default value.
1889 """
1890 typedefs = []
1891 for member in self.members:
1892 typedefs.extend(member.exportTypedefs())
1893
1894 return typedefs
1895
1896 def variables(self):
1897 """Variables.
1898
1899 Returns an array of both static and exported global variables
1900 normally placed in a block at the top of the source file.
1901
1902 Each variable is the code to define it, including any documentation
1903 and default value.
1904 """
1905 variables = []
1906 for member in self.members:
1907 variables.extend(member.variables())
1908
1909 return variables
1910
1911 def functions(self):
1912 """Functions.
1913
1914 Returns an array of both static and exported functions which
1915 consistute the bulk of the source file.
1916
1917 Each function is the code to define it, including any documentation.
1918 """
1919 functions = []
1920 for member in self.members:
1921 functions.extend(member.functions())
1922
1923 return functions
1924
1925 def definitions(self):
1926 """Definitions.
1927
1928 Returns an array of structure and type definitions which are
1929 normally placed in a block in the header file.
1930
1931 Each definition is the code to define it, including any documentation.
1932 """
1933 definitions = []
1934 for member in self.members:
1935 definitions.extend(member.definitions())
1936
1937 return definitions
1938
1939 def exports(self):
1940 """Exports.
1941
1942 Returns an array of prototypes for exported variables which are
1943 placed as a block inside the extern part of the header file.
1944
1945 Each export is a (type, name) tuple.
1946 """
1947 exports = []
1948 for member in self.members:
1949 exports.extend(member.exports())
1950
1951 return exports
1952
1953 def exportPrototypes(self):
1954 """Function prototypes.
1955
1956 Returns an array of exported function prototypes which are normally
1957 placed in a block inside the extern part of the header file.
1958
1959 Each prototype is a (retval, name, args, attributes) tuple.
1960 """
1961 prototypes = []
1962 for member in self.members:
1963 prototypes.extend(member.exportPrototypes())
1964
1965 return prototypes
1966
1967
1968class Interface(Group):
1969 @classmethod
1970 def fromElement(cls, elem):
1971 name = elem.get("name")
1972 if name is None:
1973 raise AttributeError, "Interface name may not be null"
1974
1975 self = cls(name, [])
1976 for e in elem.findall("method"):
1977 method = Method.fromElement(self, e)
1978 self.methods.append(method)
1979 self.members.append(method)
1980 for e in elem.findall("signal"):
1981 signal = Signal.fromElement(self, e)
1982 self.signals.append(signal)
1983 self.members.append(signal)
1984
1985 return self
1986
1987 def __init__(self, name, members):
1988 super(Interface, self).__init__(members)
1989
1990 self.name = name
1991 self.methods = []
1992 self.signals = []
1993
1994 @property
1995 def c_name(self):
1996 return self.name.replace(".", "_")
1997
1998 def methodsArray(self):
1999 """Methods array.
2000
2001 Returns a string containing code to initialise the array of methods
2002 used for nih_dbus_object_new().
2003 """
2004 code = """\
2005const NihDBusMethod %s_methods[] = {
2006""" % self.c_name
2007
2008 array = []
2009 for method in self.methods:
2010 if mode == "object":
2011 func = "%s_marshal" % "_".join([ self.c_name, method.c_name ])
2012 else:
2013 func = "NULL"
2014
2015 array.append(( "\"%s\"" % method.name,
2016 func,
2017 "%s_args" % "_".join([ self.c_name, method.c_name ])))
2018
2019 for line in lineup_array(array):
2020 code += indent("%s,\n" % line, 1)
2021
2022 code += """\
2023 { NULL }
2024};
2025"""
2026 return code
2027
2028 def signalsArray(self):
2029 """Signals array.
2030
2031 Returns a string containing code to initialise the array of signals
2032 used for nih_dbus_object_new().
2033 """
2034 code = """\
2035const NihDBusSignal %s_signals[] = {
2036""" % self.c_name
2037
2038 array = []
2039 for signal in self.signals:
2040 array.append(( "\"%s\"" % signal.name,
2041 "%s_args" % "_".join([ self.c_name, signal.c_name ])))
2042
2043 for line in lineup_array(array):
2044 code += indent("%s,\n" % line, 1)
2045
2046 code += """\
2047 { NULL }
2048};
2049"""
2050 return code
2051
2052 def interfacePrototype(self):
2053 """Interface structure prototype.
2054
2055 Returns a (type, name) tuple for the prototype of the interface
2056 struct.
2057 """
2058 return ( "const NihDBusInterface", "%s" % self.c_name )
2059
2060 def interfaceStruct(self):
2061 """Interface structure.
2062
2063 Returns a string containing code to define a structure containing
2064 information about the interface.
2065 """
2066 code = """\
2067const NihDBusInterface %s = {
2068 \"%s\",
2069 %s_methods,
2070 %s_signals,
2071 NULL
2072""" % (self.c_name, self.name, self.c_name, self.c_name)
2073
2074 code += """\
2075};
2076"""
2077 return code
2078
2079 def variables(self):
2080 """Variables.
2081
2082 Returns an array of both static and exported global variables
2083 normally placed in a block at the top of the source file.
2084
2085 Each variable is the code to define it, including any documentation
2086 and default value.
2087 """
2088 variables = super(Interface, self).variables()
2089 if mode == "object":
2090 variables.append(self.methodsArray())
2091 variables.append(self.signalsArray())
2092 variables.append(self.interfaceStruct())
2093
2094 return variables
2095
2096 def exports(self):
2097 """Exports.
2098
2099 Returns an array of prototypes for exported variables which are
2100 placed as a block inside the extern part of the header file.
2101
2102 Each export is a (type, name) tuple.
2103 """
2104 exports = super(Interface, self).exports()
2105 if mode == "object":
2106 exports.append(self.interfacePrototype())
2107
2108 return exports
2109
2110
2111class Output(Group):
2112 def __init__(self, basename, members):
2113 super(Output, self).__init__(members)
2114
2115 self.basename = basename
2116
2117 def sourceFile(self):
2118 """Generate source (.c) file.
2119
2120 Returns a string containing the code for the source (.c) file
2121 of this code group.
2122 """
2123 code = """\
2124/* %s
2125 *
2126 * %s - %s
2127 *
2128 * %s
2129 *
2130 * This program is free software; you can redistribute it and/or modify
2131 * it under the terms of the GNU General Public License as published by
2132 * the Free Software Foundation; either version 2 of the License, or
2133 * (at your option) any later version.
2134 *
2135 * This program is distributed in the hope that it will be useful,
2136 * but WITHOUT ANY WARRANTY; without even the implied warranty of
2137 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2138 * GNU General Public License for more details.
2139 *
2140 * You should have received a copy of the GNU General Public License
2141 * along with this program; if not, write to the Free Software
2142 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
2143 */
2144""" % (PACKAGE_NAME, "%s.c" % self.basename, "Auto-generated d-bus bindings",
2145 PACKAGE_COPYRIGHT)
2146
2147 # Usual includes
2148 if code:
2149 code += "\n"
2150 code += """\
2151#ifdef HAVE_CONFIG_H
2152# include <config.h>
2153#endif /* HAVE_CONFIG_H */
2154
2155
2156#include <dbus/dbus.h>
2157
2158#include <errno.h>
2159
2160#include <nih/macros.h>
2161#include <nih/alloc.h>
2162#include <nih/string.h>
2163#include <nih/logging.h>
2164#include <nih/error.h>
2165#include <nih/errors.h>
2166#include <nih/dbus.h>
2167
2168#include "%s.h"
2169""" % (self.basename, )
2170 if mode == "proxy":
2171 if code:
2172 code += "\n\n"
2173 code += """\
2174/**
2175 * NihAsyncNotifyData:
2176 * @handler: The user handler that our libnih handler should call,
2177 * @userdata: Data to pass to @handler,
2178 * @proxy: The proxy object to which the call was made.
2179 *
2180 * This structure contains information that is assembled during an asynchronous
2181 * method call and passed to the handler on the method's return. It should never
2182 * be used directly by the user.
2183 **/
2184typedef struct nih_async_notify_data {
2185 void *handler;
2186 void *err_handler;
2187 void *userdata;
2188 NihDBusProxy *proxy;
2189} NihAsyncNotifyData;"""
2190 # Extern function prototypes
2191 protos = self.externPrototypes()
2192 if protos:
2193 if code:
2194 code += "\n\n"
2195 code += """\
2196/* Prototypes for handler functions */
2197"""
2198 for line in lineup_protos(protos):
2199 code += line
2200 code += ";\n"
2201
2202 # Static function prototypes
2203 protos = self.staticPrototypes()
2204 if protos:
2205 if code:
2206 code += "\n\n"
2207 code += """\
2208/* Prototypes for static functions */
2209"""
2210 for line in lineup_protos(protos):
2211 code += line
2212 code += ";\n"
2213
2214 # Global variables
2215 variables = self.variables()
2216 if variables:
2217 if code:
2218 code += "\n"
2219 for g in variables:
2220 if code:
2221 code += "\n"
2222 code += g
2223
2224 # Function definitions
2225 functions = self.functions()
2226 if functions:
2227 if code:
2228 code += "\n"
2229 for function in functions:
2230 if code:
2231 code += "\n"
2232 code += function
2233
2234 return code
2235
2236 def headerFile(self):
2237 """Generate header (.h) file.
2238
2239 Returns a string containing the code for the header (.h) file
2240 of this code group.
2241 """
2242 code = """\
2243/* %s
2244 *
2245 * %s
2246 *
2247 * This program is free software; you can redistribute it and/or modify
2248 * it under the terms of the GNU General Public License as published by
2249 * the Free Software Foundation; either version 2 of the License, or
2250 * (at your option) any later version.
2251 *
2252 * This program is distributed in the hope that it will be useful,
2253 * but WITHOUT ANY WARRANTY; without even the implied warranty of
2254 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2255 * GNU General Public License for more details.
2256 *
2257 * You should have received a copy of the GNU General Public License
2258 * along with this program; if not, write to the Free Software
2259 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
2260 */
2261""" % (PACKAGE_NAME, PACKAGE_COPYRIGHT)
2262
2263 # FIXME include sub-directory name in sentry?
2264 sentry = "DBUS__%s_H" % self.basename.replace(".", "_").upper()
2265 if code:
2266 code += "\n"
2267 code += """\
2268#ifndef %s
2269#define %s
2270
2271#include <dbus/dbus.h>
2272
2273#include <nih/macros.h>
2274#include <nih/dbus.h>
2275""" % (sentry, sentry)
2276
2277 # Append structure definitions
2278 definitions = self.definitions()
2279 if definitions:
2280 if code:
2281 code += "\n"
2282 for definition in definitions:
2283 if code:
2284 code += "\n"
2285 code += definition
2286
2287 # Typedefs
2288 typedefs = self.exportTypedefs()
2289 if typedefs:
2290 if code:
2291 code += "\n\n"
2292 for line in lineup_typedefs(typedefs):
2293 code += line
2294 code += "\n"
2295
2296 # Guard extern prototypes for C++ inclusion
2297 if code:
2298 code += "\n\n"
2299 code += """\
2300NIH_BEGIN_EXTERN
2301"""
2302
2303 # Line up the variable prototypes together and place in a block
2304 globals = self.exports()
2305 if globals:
2306 if code:
2307 code += "\n"
2308 for line in lineup_vars(globals):
2309 code += line
2310 code += ";\n"
2311
2312 # Line up the function prototypes together and place in a block
2313 protos = self.exportPrototypes()
2314 if protos:
2315 if code:
2316 code += "\n"
2317 for line in lineup_protos(protos):
2318 code += line
2319 code += ";\n"
2320
2321 # End the extern guard and header sentry
2322 if code:
2323 code += "\n"
2324 code += """\
2325NIH_END_EXTERN
2326
2327#endif /* %s */
2328""" % (sentry)
2329
2330 return code
2331
2332
2333# Complex:
2334# s (struct) -> pointer to a struct of a defined type (named after func + arg)
2335# e.g. typedef struct job_find_by_name_what {
2336# ...
2337# } JobFindByNameWhat;
2338#
2339# dbus_message_iter_recurse (ITER, SUB)
2340# OK = dbus_message_iter_close_container (ITER, SUB)
2341#
2342# dbus_message_iter_open_container (ITER, TYPE, NULL, SUB)
2343# OK = dbus_message_iter_close_container (ITER, SUB)
2344#
2345# thus we can make arrays of it too :-)
2346# struct-in-struct can just get arbitrary names
2347#
2348#
2349# Annoying"
2350# v (variant) -> seems to be a problem
2351# has a type signature then the data
2352#
2353# e (dict) -> problem for now (should be NihHash really)
2354# always arrays a{..}
2355# first type is basic
2356# second type is any (including struct)
2357
2358
2359def lineup_vars(vars):
2360 """Lineup variable lists.
2361
2362 Returns an array of lines of C code to declare each of the variables
2363 in vars, which should be an array of (type, name) tuples. The
2364 declarations will be lined up in a pretty fashion.
2365
2366 It is up to the caller to add appropriate line-endings.
2367 """
2368 exp_vars = []
2369 for type, name in vars:
2370 basic = type.rstrip("*")
2371 pointers = type[len(basic):]
2372 basic = basic.rstrip()
2373 exp_vars.append(( basic, pointers, name ))
2374
2375 if not exp_vars:
2376 return []
2377
2378 max_basic = max(len(b) for b,p,n in exp_vars)
2379 max_pointers = max(len(p) for b,p,n in exp_vars)
2380
2381 lines = []
2382 for basic, pointers, name in exp_vars:
2383 code = basic.ljust(max_basic)
2384 code += pointers.rjust(max_pointers + 1)
2385 code += name
2386
2387 lines.append(code)
2388
2389 return lines
2390
2391def typedef_lineup_prefix(type):
2392 """Pads a type name on the left so indent starts past (*
2393
2394 If a string begins with (* returns it. If it begins with * pad it on the
2395 left with one space. If it begins with 0 pad with two spaces.
2396 """
2397 if type.startswith("(*"):
2398 return type
2399 if type.startswith("*"):
2400 return " " + type
2401 return " " + type
2402
2403def lineup_typedefs(typedefs):
2404 """ Lineup typedef lists.
2405
2406 Returns an array of lines of C code to declare each of the typedefs
2407 in typedefs, which should be an array of (type, name, args)
2408 """
2409 defs = []
2410 max_type = max(len(t) for t,n,a in typedefs)
2411 max_name = max(len(typedef_lineup_prefix(n)) for t,n,a in typedefs)
2412
2413 for type,name,args in typedefs:
2414 code = "typedef "
2415 code += type.ljust(max_type+1)
2416 code += typedef_lineup_prefix(name).ljust(max_name+1)
2417 code += "("
2418 code += ", ".join("%s%s%s" % (type, not type.endswith("*") and " " or "",
2419 name) for type,name in args)
2420 code += ");"
2421 defs.append(code)
2422
2423 return defs
2424
2425def lineup_protos(protos):
2426 """Lineup prototype lists.
2427
2428 Returns an array of lines of C code to declare each of the prototypes
2429 in protos, which should be an array of (retval, name, args, attributes)
2430 tuples. The declarations will be lined up in a pretty fashion.
2431
2432 It is up to the caller to add appropriate line-endings.
2433 """
2434 if not protos:
2435 return []
2436
2437 max_retval = max(len(r) for r,n,a,at in protos)
2438 max_name = max(len(n) for r,n,a,at in protos)
2439
2440 if not [ True for r,n,a,at in protos if r.endswith("*") ]:
2441 max_retval += 1
2442
2443 lines = []
2444 for retval, name, args, attributes in protos:
2445 code = retval.ljust(max_retval)
2446 code += name.ljust(max_name + 1)
2447 code += "("
2448 # FIXME split arguments over multiple lines maybe?
2449 code += ", ".join("%s%s%s" % (type, not type.endswith("*") and " " or "",
2450 name) for type,name in args)
2451 code += ")"
2452 if attributes:
2453 code += "\n\t__attribute__ ((" + ", ".join(attributes) + "))"
2454
2455 lines.append(code)
2456
2457 return lines
2458
2459def camelate(string):
2460 """Make a _-delimited string CamelCase.
2461
2462 Not much else to say.
2463 """
2464 return "".join([ x.capitalize() for x in string.split("_") ])
2465
2466def lineup_array(array):
2467 """Lineup array definitions.
2468
2469 Returns an array of lines of C code to declare each of the array struct
2470 definitions in array, which should be an array of tuples for each structure
2471 member. The declarations will be lined up in a pretty fashion.
2472
2473 It is up to the caller to add appropriate line-endings.
2474 """
2475 if not array:
2476 return []
2477
2478 max_len = [ max(len(entry[i]) for entry in array)
2479 for i in range(0, len(array[0])) ]
2480
2481 lines = []
2482 for entry in array:
2483 code = "{ "
2484
2485 for i, str in enumerate(entry):
2486 if i < len(array[0]) - 1:
2487 code += (str + ", ").ljust(max_len[i] + 2)
2488 else:
2489 code += str.ljust(max_len[i])
2490
2491 code += " }"
2492
2493 lines.append(code)
2494
2495 return lines
2496
2497
2498def indent(str, level):
2499 """Increase indent of string.
2500
2501 Returns the string with each line indented to the given level of tabs.
2502 """
2503 output = ""
2504 for line in str.splitlines(True):
2505 if len(line.strip()):
2506 output += ("\t" * level) + line
2507 else:
2508 output += line
2509 return output
2510
2511
2512def pointerify(type):
2513 """Turn C type into a pointer.
2514
2515 Returns the string for a pointer to the given C type.
2516 """
2517 if type.endswith("*"):
2518 return type + "*"
2519 else:
2520 return type + " *"
2521
2522def constify(type):
2523 """Type C pointer type into a const pointer.
2524
2525 Returns the string modified so that the pointer is a const pointer.
2526 """
2527 if not type.endswith("*"):
2528 return type
2529
2530 if type[:-1].endswith("*"):
2531 return type[:-1] + " const *"
2532 else:
2533 return "const " + type
2534
2535
2536def main():
2537 global options
2538 global extern_prefix
2539 global mode
2540
2541 usage = "%prog [OPTION]... XMLFILE"
2542 description = """\
2543XMLFILE is a valid XML file containing information about one or more interfaces
2544in the D-Bus Introspection format, except that the top-level node may be
2545interface as well as node.
2546
2547C code to marshal methods and dispatch signals (if --mode is object) or to
2548dispatch methods and marshal signals (if --mode is proxy) is written to
2549a .c and .h file in the current directory with the same base name as XMLFILE,
2550or to that specified by --output.
2551"""
2552
2553 parser = OptionParser(usage, description=description)
2554 parser.add_option("--mode", type="string", metavar="MODE",
2555 default="object",
2556 help="Output mode: object, or proxy [default: %default]")
2557 parser.add_option("-o", "--output", type="string", metavar="FILENAME",
2558 help="Write C source to FILENAME, header alongside")
2559 parser.add_option("--prefix", type="string", metavar="PREFIX",
2560 default="dbus",
2561 help="Prefix for externally supplied C functions [default: %default]")
2562
2563 (options, args) = parser.parse_args()
2564 if len(args) != 1:
2565 parser.error("incorrect number of arguments")
2566 if options.mode not in ("object", "proxy"):
2567 parser.error("invalid mode")
2568
2569 extern_prefix = options.prefix
2570 mode = options.mode
2571
2572 # Figure out input and output filenames based on arguments; try and
2573 # do the right thing in most circumstances
2574 xml_filename = args.pop(0)
2575 if options.output:
2576 (root, ext) = os.path.splitext(options.output)
2577 if ext and ext != ".h":
2578 source_filename = options.output
2579 else:
2580 source_filename = os.path.extsep.join(( root, "c" ))
2581
2582 header_filename = os.path.extsep.join (( root, "h"))
2583 basename = os.path.basename(root)
2584 else:
2585 basename = os.path.splitext(os.path.basename(xml_filename))[0]
2586 source_filename = os.path.extsep.join(( basename, "c" ))
2587 header_filename = os.path.extsep.join(( basename, "h" ))
2588
2589 (head, tail) = os.path.split(source_filename)
2590 tmp_source_filename = os.path.join(head, ".%s.tmp" % tail)
2591
2592 (head, tail) = os.path.split(header_filename)
2593 tmp_header_filename = os.path.join(head, ".%s.tmp" % tail)
2594
2595
2596 # Parse the XML file into an ElementTree
2597 tree = ElementTree.parse(xml_filename)
2598 elem = tree.getroot()
2599
2600 # Walk the tree to find interfaces
2601 interfaces = []
2602 if elem.tag == "interface":
2603 interfaces.append(Interface.fromElement(elem))
2604 else:
2605 for iface_e in elem.findall("interface"):
2606 interfaces.append(Interface.fromElement(iface_e))
2607
2608 # Generate and write output
2609 o = Output(basename, interfaces)
2610 try:
2611 f = open(tmp_source_filename, "w")
2612 try:
2613 print >>f, o.sourceFile()
2614 finally:
2615 f.close()
2616
2617 f = open(tmp_header_filename, "w")
2618 try:
2619 print >>f, o.headerFile()
2620 finally:
2621 f.close()
2622
2623 os.rename(tmp_source_filename, source_filename)
2624 os.rename(tmp_header_filename, header_filename)
2625 except:
2626 if os.path.exists(tmp_source_filename):
2627 os.unlink(tmp_source_filename)
2628 if os.path.exists(tmp_header_filename):
2629 os.unlink(tmp_header_filename)
2630
2631 raise
2632
2633
2634if __name__ == "__main__":
2635 main()

Subscribers

People subscribed via source and target branches

to all changes:
to status/vote changes: