/** * nih_error_push_context: * * Creates a new context in which errors can occur without disturbing any * previous unhandled error, useful for touring a particular piece of * processing that handles its own errors and may be triggered as a result * of another error. **/ void nih_error_push_context (void) { NihErrorCtx *new_context; nih_error_init (); new_context = NIH_MUST (nih_new (context_stack, NihErrorCtx)); nih_list_init (&new_context->entry); new_context->error = NULL; nih_list_add (context_stack, &new_context->entry); }
/** * session_new: * @parent: parent, * @chroot: full chroot path, * @user: user id. * * Create a new session. * * Return new Session, or NULL on error. **/ Session * session_new (const void *parent, const char *chroot, uid_t user) { Session *session; nih_assert ((chroot != NULL) || (user != 0)); session_init (); session = nih_new (parent, Session); if (! session) return NULL; nih_list_init (&session->entry); if (chroot) { session->chroot = nih_strdup (session, chroot); if (! session->chroot) { nih_free (session); return NULL; } } else { session->chroot = NULL; } session->user = user; session->conf_path = NULL; nih_alloc_set_destructor (session, nih_list_destroy); nih_list_add (sessions, &session->entry); return session; }
void test_free (void) { void * ptr1; void * ptr2; Parent *parent; int ret; TEST_FUNCTION ("nih_free"); /* Check that nih_free works if the block has no parent. The * destructor should get called and nih_free should return that * return value. */ TEST_FEATURE ("with no parent"); ptr1 = nih_alloc (NULL, 10); nih_alloc_set_destructor (ptr1, destructor_called); destructor_was_called = 0; ret = nih_free (ptr1); TEST_TRUE (destructor_was_called); TEST_EQ (ret, 2); /* Check that nih_free works if the block has a parent. The * destructor should get called and nih_free should return that * return value. */ TEST_FEATURE ("with parent"); ptr2 = nih_alloc (NULL, 20); ptr1 = nih_alloc (ptr2, 10); nih_alloc_set_destructor (ptr1, destructor_called); destructor_was_called = 0; ret = nih_free (ptr1); TEST_TRUE (destructor_was_called); TEST_EQ (ret, 2); nih_free (ptr2); /* Check that the destructor on any children also gets called, which * is as good a indication as any that the children are being freed. */ TEST_FEATURE ("with destructor on child"); ptr1 = nih_alloc (NULL, 10); ptr2 = nih_alloc (ptr1, 10); nih_alloc_set_destructor (ptr2, child_destructor_called); child_destructor_was_called = 0; ret = nih_free (ptr1); TEST_TRUE (child_destructor_was_called); TEST_EQ (ret, 0); /* Check that both destructors on parent and children are called, * and that the return value from nih_free is that of the parent's. */ TEST_FEATURE ("with child and destructors"); ptr1 = nih_alloc (NULL, 10); ptr2 = nih_alloc (ptr1, 10); nih_alloc_set_destructor (ptr1, destructor_called); nih_alloc_set_destructor (ptr2, child_destructor_called); destructor_was_called = 0; child_destructor_was_called = 0; ret = nih_free (ptr1); TEST_TRUE (destructor_was_called); TEST_TRUE (child_destructor_was_called); TEST_EQ (ret, 2); /* Check that a child of an object may be included in a sibling * linked list allocated earlier. At the point the child destructor * is called, the sibling must not have been freed otherwise it * cannot cut itself out. */ TEST_FEATURE ("with child in older sibling list"); parent = nih_new (NULL, Parent); __nih_malloc = my_list_head_malloc; parent->list = nih_new (parent, NihList); nih_list_init (parent->list); __nih_malloc = malloc; parent->child = nih_new (parent, Child); nih_list_init (&parent->child->entry); nih_list_add (parent->list, &parent->child->entry); nih_alloc_set_destructor (parent->child, child_destructor_test); __nih_free = my_list_head_free; nih_free (parent); __nih_free = free; /* Check that a child of an object may be included in a sibling * linked list allocated later. At the point the child destructor * is called, the sibling must not have been freed otherwise it * cannot cut itself out. */ TEST_FEATURE ("with child in younger sibling list"); parent = nih_new (NULL, Parent); parent->child = nih_new (parent, Child); nih_list_init (&parent->child->entry); __nih_malloc = my_list_head_malloc; parent->list = nih_new (parent, NihList); nih_list_init (parent->list); __nih_malloc = malloc; nih_list_add (parent->list, &parent->child->entry); nih_alloc_set_destructor (parent->child, child_destructor_test); __nih_free = my_list_head_free; nih_free (parent); __nih_free = free; }
void test_output (void) { FILE * source; FILE * header; Node * node = NULL; Interface * interface = NULL; Method * method = NULL; Signal * signal = NULL; Argument * argument = NULL; Property * property = NULL; int ret; NihError * err; TEST_FUNCTION ("output"); source = tmpfile (); header = tmpfile (); /* Check that we can generate a valid source file and accompanying * header file for a node in proxy mode. */ TEST_FEATURE ("with proxy"); TEST_ALLOC_FAIL { TEST_ALLOC_SAFE { node = node_new (NULL, NULL); interface = interface_new (node, "com.netsplit.Nih.Test"); interface->symbol = "test"; nih_list_add (&node->interfaces, &interface->entry); method = method_new (interface, "Poke"); method->symbol = "poke"; nih_list_add (&interface->methods, &method->entry); argument = argument_new (method, "address", "u", NIH_DBUS_ARG_IN); argument->symbol = "address"; nih_list_add (&method->arguments, &argument->entry); argument = argument_new (method, "value", "s", NIH_DBUS_ARG_IN); argument->symbol = "value"; nih_list_add (&method->arguments, &argument->entry); method = method_new (interface, "Peek"); method->symbol = "peek"; nih_list_add (&interface->methods, &method->entry); argument = argument_new (method, "address", "u", NIH_DBUS_ARG_IN); argument->symbol = "address"; nih_list_add (&method->arguments, &argument->entry); argument = argument_new (method, "value", "s", NIH_DBUS_ARG_OUT); argument->symbol = "value"; nih_list_add (&method->arguments, &argument->entry); method = method_new (interface, "IsValidAddress"); method->symbol = "is_valid_address"; nih_list_add (&interface->methods, &method->entry); argument = argument_new (method, "address", "u", NIH_DBUS_ARG_IN); argument->symbol = "address"; nih_list_add (&method->arguments, &argument->entry); signal = signal_new (interface, "Bounce"); signal->symbol = "bounce"; nih_list_add (&interface->signals, &signal->entry); argument = argument_new (signal, "height", "u", NIH_DBUS_ARG_OUT); argument->symbol = "height"; nih_list_add (&signal->arguments, &argument->entry); argument = argument_new (signal, "velocity", "i", NIH_DBUS_ARG_OUT); argument->symbol = "velocity"; nih_list_add (&signal->arguments, &argument->entry); signal = signal_new (interface, "Exploded"); signal->symbol = "exploded"; nih_list_add (&interface->signals, &signal->entry); property = property_new (interface, "colour", "s", NIH_DBUS_READWRITE); property->symbol = "colour"; nih_list_add (&interface->properties, &property->entry); property = property_new (interface, "size", "u", NIH_DBUS_READ); property->symbol = "size"; nih_list_add (&interface->properties, &property->entry); property = property_new (interface, "touch", "b", NIH_DBUS_WRITE); property->symbol = "touch"; nih_list_add (&interface->properties, &property->entry); interface = interface_new (node, "com.netsplit.Nih.Foo"); interface->symbol = "foo"; nih_list_add (&node->interfaces, &interface->entry); method = method_new (interface, "Bing"); method->symbol = "bing"; nih_list_add (&interface->methods, &method->entry); signal = signal_new (interface, "NewResult"); signal->symbol = "new_result"; nih_list_add (&interface->signals, &signal->entry); property = property_new (interface, "preferences", "(us)", NIH_DBUS_READWRITE); property->symbol = "preferences"; nih_list_add (&interface->properties, &property->entry); } ret = output ("test.c", fileno (source), "test.h", fileno (header), "my", node, FALSE); rewind (source); rewind (header); if (test_alloc_failed) { TEST_LT (ret, 0); err = nih_error_get (); TEST_EQ (err->number, ENOMEM); nih_free (err); TEST_FILE_RESET (source); TEST_FILE_RESET (header); nih_free (node); continue; } TEST_EQ (ret, 0); TEST_EXPECTED_FILE (source, "test_output_proxy_standard.c"); TEST_EXPECTED_FILE (header, "test_output_proxy_standard.h"); nih_free (node); } /* Check that when there are no interfaces, a valid empty source * and header file are generated. */ TEST_FEATURE ("with proxy but no interfaces"); TEST_ALLOC_FAIL { TEST_ALLOC_SAFE { node = node_new (NULL, NULL); } ret = output ("test.c", fileno (source), "test.h", fileno (header), "my", node, FALSE); rewind (source); rewind (header); if (test_alloc_failed) { TEST_LT (ret, 0); err = nih_error_get (); TEST_EQ (err->number, ENOMEM); nih_free (err); TEST_FILE_RESET (source); TEST_FILE_RESET (header); nih_free (node); continue; } TEST_EQ (ret, 0); TEST_EXPECTED_FILE (source, "test_output_proxy_no_interfaces.c"); TEST_EXPECTED_FILE (header, "test_output_proxy_no_interfaces.h"); nih_free (node); } /* Check that we can generate a valid source file and accompanying * header file for a node in object mode. */ TEST_FEATURE ("with object"); TEST_ALLOC_FAIL { TEST_ALLOC_SAFE { node = node_new (NULL, NULL); interface = interface_new (node, "com.netsplit.Nih.Test"); interface->symbol = "test"; nih_list_add (&node->interfaces, &interface->entry); method = method_new (interface, "Poke"); method->symbol = "poke"; nih_list_add (&interface->methods, &method->entry); argument = argument_new (method, "address", "u", NIH_DBUS_ARG_IN); argument->symbol = "address"; nih_list_add (&method->arguments, &argument->entry); argument = argument_new (method, "value", "s", NIH_DBUS_ARG_IN); argument->symbol = "value"; nih_list_add (&method->arguments, &argument->entry); method = method_new (interface, "Peek"); method->symbol = "peek"; method->async = TRUE; nih_list_add (&interface->methods, &method->entry); argument = argument_new (method, "address", "u", NIH_DBUS_ARG_IN); argument->symbol = "address"; nih_list_add (&method->arguments, &argument->entry); argument = argument_new (method, "value", "s", NIH_DBUS_ARG_OUT); argument->symbol = "value"; nih_list_add (&method->arguments, &argument->entry); method = method_new (interface, "IsValidAddress"); method->symbol = "is_valid_address"; nih_list_add (&interface->methods, &method->entry); argument = argument_new (method, "address", "u", NIH_DBUS_ARG_IN); argument->symbol = "address"; nih_list_add (&method->arguments, &argument->entry); argument = argument_new (method, "is_valid", "b", NIH_DBUS_ARG_OUT); argument->symbol = "is_valid"; nih_list_add (&method->arguments, &argument->entry); signal = signal_new (interface, "Bounce"); signal->symbol = "bounce"; nih_list_add (&interface->signals, &signal->entry); argument = argument_new (signal, "height", "u", NIH_DBUS_ARG_OUT); argument->symbol = "height"; nih_list_add (&signal->arguments, &argument->entry); argument = argument_new (signal, "velocity", "i", NIH_DBUS_ARG_OUT); argument->symbol = "velocity"; nih_list_add (&signal->arguments, &argument->entry); signal = signal_new (interface, "Exploded"); signal->symbol = "exploded"; nih_list_add (&interface->signals, &signal->entry); property = property_new (interface, "colour", "s", NIH_DBUS_READWRITE); property->symbol = "colour"; nih_list_add (&interface->properties, &property->entry); property = property_new (interface, "size", "u", NIH_DBUS_READ); property->symbol = "size"; nih_list_add (&interface->properties, &property->entry); property = property_new (interface, "touch", "b", NIH_DBUS_WRITE); property->symbol = "touch"; nih_list_add (&interface->properties, &property->entry); interface = interface_new (node, "com.netsplit.Nih.Foo"); interface->symbol = "foo"; nih_list_add (&node->interfaces, &interface->entry); method = method_new (interface, "Bing"); method->symbol = "bing"; nih_list_add (&interface->methods, &method->entry); signal = signal_new (interface, "NewResult"); signal->symbol = "new_result"; nih_list_add (&interface->signals, &signal->entry); property = property_new (interface, "preferences", "(us)", NIH_DBUS_READWRITE); property->symbol = "preferences"; nih_list_add (&interface->properties, &property->entry); } ret = output ("test.c", fileno (source), "test.h", fileno (header), "my", node, TRUE); rewind (source); rewind (header); if (test_alloc_failed) { TEST_LT (ret, 0); err = nih_error_get (); TEST_EQ (err->number, ENOMEM); nih_free (err); TEST_FILE_RESET (source); TEST_FILE_RESET (header); nih_free (node); continue; } TEST_EQ (ret, 0); TEST_EXPECTED_FILE (source, "test_output_object_standard.c"); TEST_EXPECTED_FILE (header, "test_output_object_standard.h"); nih_free (node); } /* Check that when there are no interfaces, a valid empty source * and header file are generated. */ TEST_FEATURE ("with object but no interfaces"); TEST_ALLOC_FAIL { TEST_ALLOC_SAFE { node = node_new (NULL, NULL); } ret = output ("test.c", fileno (source), "test.h", fileno (header), "my", node, TRUE); rewind (source); rewind (header); if (test_alloc_failed) { TEST_LT (ret, 0); err = nih_error_get (); TEST_EQ (err->number, ENOMEM); nih_free (err); TEST_FILE_RESET (source); TEST_FILE_RESET (header); nih_free (node); continue; } TEST_EQ (ret, 0); TEST_EXPECTED_FILE (source, "test_output_object_no_interfaces.c"); TEST_EXPECTED_FILE (header, "test_output_object_no_interfaces.h"); nih_free (node); } fclose (source); fclose (header); }
int main (int argc, char *argv[]) { NihList prototypes; NihList typedefs; NihList structs; nih_local Interface *interface = NULL; nih_local Property * property = NULL; nih_local char * code = NULL; nih_local char * block = NULL; printf ("#include <dbus/dbus.h>\n" "\n" "#include <nih/macros.h>\n" "#include <nih/alloc.h>\n" "#include <nih/string.h>\n" "#include <nih/logging.h>\n" "#include <nih/error.h>\n" "\n" "#include <nih-dbus/dbus_error.h>\n" "#include <nih-dbus/dbus_message.h>\n" "#include <nih-dbus/dbus_object.h>\n" "#include <nih-dbus/dbus_pending_data.h>\n" "#include <nih-dbus/dbus_proxy.h>\n" "#include <nih-dbus/errors.h>\n" "\n" "#include \"tests/interface_code.h\"\n" "\n" "\n"); interface = interface_new (NULL, "com.netsplit.Nih.Test"); interface->symbol = NULL; property = property_new (interface, "name", "s", NIH_DBUS_READWRITE); property->symbol = nih_strdup (property, "name"); nih_list_add (&interface->properties, &property->entry); property = property_new (interface, "size", "u", NIH_DBUS_READWRITE); property->symbol = nih_strdup (property, "size"); nih_list_add (&interface->properties, &property->entry); nih_list_init (&prototypes); nih_list_init (&structs); interface->name = "com.netsplit.Nih.TestA"; code = interface_proxy_get_all_function (NULL, "my", interface, &prototypes, &structs); printf ("extern void my_com_netsplit_Nih_TestA_get_all_notify (DBusPendingCall *pending_call, " "NihDBusPendingData *pending_data);\n"); printf ("\n"); printf ("%s" "\n", code); nih_list_init (&prototypes); nih_list_init (&typedefs); nih_list_init (&structs); interface->name = "com.netsplit.Nih.Test"; code = interface_proxy_get_all_notify_function (NULL, "my", interface, &prototypes, &typedefs, &structs); printf ("%s", code); printf ("\n" "\n"); nih_list_init (&prototypes); nih_list_init (&structs); code = interface_proxy_get_all_sync_function (NULL, "my", interface, &prototypes, &structs); printf ("%s" "\n", code); return 0; }