diff options
| -rw-r--r-- | ChangeLog | 11 | ||||
| -rw-r--r-- | dbus/Makefile.am | 2 | ||||
| -rw-r--r-- | dbus/dbus-connection.h | 48 | ||||
| -rw-r--r-- | dbus/dbus-message-builder.c | 2 | ||||
| -rw-r--r-- | dbus/dbus-object-tree.c | 609 | ||||
| -rw-r--r-- | dbus/dbus-object-tree.h | 48 | ||||
| -rw-r--r-- | dbus/dbus-string.c | 2 | ||||
| -rw-r--r-- | dbus/dbus-test.c | 6 | ||||
| -rw-r--r-- | dbus/dbus-test.h | 1 | 
9 files changed, 727 insertions, 2 deletions
| @@ -1,3 +1,14 @@ +2003-08-25  Havoc Pennington  <hp@pobox.com> + +        Just noticed that dbus_message_test is hosed, I wonder when I +	broke that. I thought make check was passing earlier... +	 +	* dbus/dbus-object-tree.c: add new "object tree" to match DCOP  +	container tree, will replace most of dbus-object-registry + +	* dbus/dbus-string.c (_dbus_string_append_printf_valist): fix C99 +	screwup +  2003-08-19  Havoc Pennington  <hp@pobox.com>  	* dbus/dbus-message.c (decode_string_field): support FIELD_SENDER diff --git a/dbus/Makefile.am b/dbus/Makefile.am index 3537b935..e59877e6 100644 --- a/dbus/Makefile.am +++ b/dbus/Makefile.am @@ -49,6 +49,8 @@ DBUS_LIB_SOURCES=				\  	dbus-objectid.c				\  	dbus-object-registry.c			\  	dbus-object-registry.h			\ +	dbus-object-tree.c			\ +	dbus-object-tree.h			\  	dbus-pending-call.c			\  	dbus-resources.c			\  	dbus-resources.h			\ diff --git a/dbus/dbus-connection.h b/dbus/dbus-connection.h index ef106524..7204c8ed 100644 --- a/dbus/dbus-connection.h +++ b/dbus/dbus-connection.h @@ -198,6 +198,54 @@ void                  dbus_connection_send_preallocated      (DBusConnection                                                                dbus_uint32_t        *client_serial); +/* Object tree functionality */ + +typedef struct DBusObjectTreeVTable DBusObjectTreeVTable; + +typedef void              (* DBusObjectTreeUnregisterFunction) (DBusConnection  *connection, +                                                                const char     **path, +                                                                void            *user_data); +typedef DBusHandlerResult (* DBusObjectTreeMessageFunction)    (DBusConnection  *connection, +                                                                DBusMessage     *message, +                                                                void            *user_data); +typedef dbus_bool_t       (* DBusObjectTreeSubdirsFunction)    (DBusConnection  *connection, +                                                                const char     **path, +                                                                char          ***subdirs, +                                                                int             *n_subdirs, +                                                                void            *user_data); +typedef dbus_bool_t       (* DBusObjectTreeObjectsFunction)    (DBusConnection  *connection, +                                                                const char     **path, +                                                                DBusObjectID   **object_ids, +                                                                int             *n_object_ids, +                                                                void            *user_data); +typedef dbus_bool_t       (* DBusObjectTreeMethodsFunction)    (DBusConnection  *connection, +                                                                const char     **path, +                                                                DBusObjectID   **object_ids, +                                                                int             *n_object_ids, +                                                                void            *user_data); + +struct DBusObjectTreeVTable +{ +  DBusObjectTreeUnregisterFunction   unregister_function; +  DBusObjectTreeMessageFunction      message_function; +  DBusObjectTreeSubdirsFunction      subdirs_function; +  DBusObjectTreeObjectsFunction      objects_function; +  DBusObjectTreeMethodsFunction      methods_function; +   +  void (* dbus_internal_pad1) (void *); +  void (* dbus_internal_pad2) (void *); +  void (* dbus_internal_pad3) (void *); +  void (* dbus_internal_pad4) (void *); +}; + +dbus_bool_t dbus_connection_register_object_tree   (DBusConnection              *connection, +                                                    const char                 **path, +                                                    const DBusObjectTreeVTable  *vtable, +                                                    void                        *user_data); +void        dbus_connection_unregister_object_tree (DBusConnection              *connection, +                                                    const char                 **path); + +  DBUS_END_DECLS;  #endif /* DBUS_CONNECTION_H */ diff --git a/dbus/dbus-message-builder.c b/dbus/dbus-message-builder.c index 958e57a0..f779c8c1 100644 --- a/dbus/dbus-message-builder.c +++ b/dbus/dbus-message-builder.c @@ -411,7 +411,7 @@ _dbus_message_data_load (DBusString       *dest,            DBusString name;            int message_type; -          if (_dbus_string_get_length (&line) < strlen ("VALID_HEADER ")) +          if (_dbus_string_get_length (&line) < (int) strlen ("VALID_HEADER "))              {                _dbus_warn ("no args to VALID_HEADER\n");                goto parse_failed; diff --git a/dbus/dbus-object-tree.c b/dbus/dbus-object-tree.c new file mode 100644 index 00000000..7f7e6011 --- /dev/null +++ b/dbus/dbus-object-tree.c @@ -0,0 +1,609 @@ +/* -*- mode: C; c-file-style: "gnu" -*- */ +/* dbus-object-tree.c  DBusObjectTree (internals of DBusConnection) + * + * Copyright (C) 2003  Red Hat Inc. + * + * Licensed under the Academic Free License version 1.2 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA + * + */ +#include "dbus-object-tree.h" +#include "dbus-connection-internal.h" +#include "dbus-internals.h" +#include "dbus-hash.h" +#include "dbus-protocol.h" +#include <string.h> +#include <stdlib.h> + +/** + * @defgroup DBusObjectTree A hierarchy of objects with container-contained relationship + * @ingroup  DBusInternals + * @brief DBusObjectTree is used by DBusConnection to track the object tree + * + * Types and functions related to DBusObjectTree. These + * are all internal. + * + * @{ + */ + +typedef struct DBusObjectSubtree DBusObjectSubtree; + +DBusObjectSubtree* _dbus_object_subtree_new   (const char                 **path, +                                               const DBusObjectTreeVTable  *vtable, +                                               void                        *user_data); +void               _dbus_object_subtree_ref   (DBusObjectSubtree           *subtree); +void               _dbus_object_subtree_unref (DBusObjectSubtree           *subtree); + +struct DBusObjectTree +{ +  int                 refcount; +  DBusConnection     *connection; + +  /* Each subtree is a separate malloc block since that +   * lets us refcount them and maybe helps with +   * reentrancy issues when calling back to application code +   */ +  DBusObjectSubtree **subtrees; +  int                 n_subtrees; +  unsigned int        subtrees_sorted : 1; +}; + +struct DBusObjectSubtree +{ +  int                   refcount; +  char                **path; +  int                   n_path_elements; +  DBusObjectTreeVTable  vtable; +  void                 *user_data; +}; + +DBusObjectTree* +_dbus_object_tree_new (DBusConnection *connection) +{ +  DBusObjectTree *tree; +   +  /* the connection passed in here isn't fully constructed, +   * so don't do anything more than store a pointer to +   * it +   */ +   +  tree = dbus_new0 (DBusObjectTree, 1); +  if (tree == NULL) +    goto oom; +   +  tree->refcount = 1; +  tree->connection = connection; +   +  return tree; + + oom: +  if (tree) +    { +      dbus_free (tree); +    } +   +  return NULL; +} + +void +_dbus_object_tree_ref (DBusObjectTree *tree) +{ +  _dbus_assert (tree->refcount > 0); + +  tree->refcount += 1; +} + +void +_dbus_object_tree_unref (DBusObjectTree *tree) +{ +  _dbus_assert (tree->refcount > 0); + +  tree->refcount -= 1; + +  if (tree->refcount == 0) +    { +      if (tree->subtrees) +        { +          int i; +          i = 0; +          while (i < tree->n_subtrees) +            { +              _dbus_object_subtree_unref (tree->subtrees[i]); +              ++i; +            } +        } + +      dbus_free (tree); +    } +} + +static int +path_cmp (const char **path_a, +          const char **path_b) +{ +  /* The comparison is as if the path were flattened +   * into a single string. strcmp() considers +   * a shorter string less than a longer string +   * if the shorter string is the initial part +   * of the longer +   */ +  int i; + +  i = 0; +  while (path_a[i] != NULL) +    { +      int v; +       +      if (path_b[i] == NULL) +        return 1; /* a is longer than b */ + +      _dbus_assert (path_a[i] != NULL); +      _dbus_assert (path_b[i] != NULL); +       +      v = strcmp (path_a[i], path_b[i]); + +      if (v != 0) +        return v; + +      ++i; +    } + +  _dbus_assert (path_a[i] == NULL); +  if (path_b[i] == NULL) +    return 0; +   +  /* b is longer than a */ +  return -1; +} + +static int +subtree_cmp (DBusObjectSubtree *subtree_a, +             DBusObjectSubtree *subtree_b) +{ +  return path_cmp ((const char**) subtree_a->path, +                   (const char**) subtree_b->path); +} + +static int +subtree_qsort_cmp (const void *a, +                   const void *b) +{ +  DBusObjectSubtree **subtree_a_p = (void*) a; +  DBusObjectSubtree **subtree_b_p = (void*) b; + +  return subtree_cmp (*subtree_a_p, *subtree_b_p);   +} + +/* Returns TRUE if a is a subdir of b or vice + * versa. This is the case if one is a subpath + * of the other. + */ +static dbus_bool_t +path_overlaps (const char **path_a, +               const char **path_b) +{ +  int i; + +  i = 0; +  while (path_a[i] != NULL) +    { +      int v; +       +      if (path_b[i] == NULL) +        return TRUE; /* b is subpath of a */ + +      _dbus_assert (path_a[i] != NULL); +      _dbus_assert (path_b[i] != NULL); +       +      v = strcmp (path_a[i], path_b[i]); + +      if (v != 0) +        return FALSE; /* they overlap until here and then are different, +                       * not overlapping +                       */ + +      ++i; +    } + +  /* b is either the same as or a superset of a */ +  _dbus_assert (path_a[i] == NULL); +  return TRUE; +} + +static dbus_bool_t +find_subtree (DBusObjectTree *tree, +              const char    **path, +              int            *idx_p) +{ +  int i; +   +  if (tree->subtrees == NULL) +    return FALSE; +   +  if (!tree->subtrees_sorted) +    { +      qsort (tree->subtrees, +             tree->n_subtrees, +             sizeof (DBusObjectSubtree*), +             subtree_qsort_cmp); +      tree->subtrees_sorted = TRUE; +    } + +  /* FIXME this should be a binary search, +   * as that's the whole point of the sorting +   */ +  i = 0; +  while (i < tree->n_subtrees) +    { +      int v; + +      v = path_cmp (path, +                    (const char**) tree->subtrees[i]->path); +      if (v == 0) +        { +          if (idx_p) +            *idx_p = i; +          return TRUE; +        } +      else if (v > 0) +        return FALSE; +       +      ++i; +    } + +  return FALSE; +} + +#ifndef DBUS_DISABLE_CHECKS +static void +check_overlap (DBusObjectTree *tree, +               const char    **path) +{ +  int i; + +  i = 0; +  while (i < tree->n_subtrees) +    { +      if (path_overlaps (path, (const char**) tree->subtrees[i]->path)) +        { +          _dbus_warn ("New path (path[0] = %s) overlaps old path (path[0] = %s)\n", +                      path[0], tree->subtrees[i]->path[0]); +        } +      ++i; +    } +} +#endif + +/** + * Registers a new subtree in the global object tree. + * + * @param tree the global object tree + * @param path NULL-terminated array of path elements giving path to subtree + * @param vtable the vtable used to traverse this subtree + * @param user_data user data to pass to methods in the vtable + * @returns #FALSE if not enough memory + */ +dbus_bool_t +_dbus_object_tree_register (DBusObjectTree              *tree, +                            const char                 **path, +                            const DBusObjectTreeVTable  *vtable, +                            void                        *user_data) +{ +  DBusObjectSubtree  *subtree; +  DBusObjectSubtree **new_subtrees; +  int new_n_subtrees; + +  _dbus_assert (path != NULL); +#ifndef DBUS_DISABLE_CHECKS +  check_overlap (tree, path); +#endif +  _dbus_assert (path[0] != NULL); +   +  subtree = _dbus_object_subtree_new (path, vtable, user_data); +  if (subtree == NULL) +    return FALSE; +   +  /* FIXME we should do the "double alloc each time" standard thing */ +  new_n_subtrees = tree->n_subtrees + 1; +  new_subtrees = dbus_realloc (tree->subtrees, +                               new_n_subtrees); +  if (new_subtrees == NULL) +    { +      _DBUS_ZERO (subtree->vtable); /* to avoid assertion in unref() */ +      _dbus_object_subtree_unref (subtree); +      return FALSE; +    } + +  tree->subtrees[tree->n_subtrees] = subtree; +  tree->subtrees_sorted = FALSE; +  tree->n_subtrees = new_n_subtrees; +  tree->subtrees = new_subtrees; + +  return TRUE; +} + +/** + * Unregisters an object subtree that was registered with the + * same path. + * + * @param tree the global object tree + * @param path path to the subtree (same as the one passed to _dbus_object_tree_register()) + */ +void +_dbus_object_tree_unregister_and_unlock (DBusObjectTree          *tree, +                                         const char             **path) +{ +  int i; +  DBusObjectSubtree *subtree; + +  _dbus_assert (path != NULL); +  _dbus_assert (path[0] != NULL); +   +  if (!find_subtree (tree, path, &i)) +    { +      _dbus_warn ("Attempted to unregister subtree (path[0] = %s) which isn't registered\n", +                  path[0]); +      return; +    } + +  subtree = tree->subtrees[i]; + +  /* assumes a 0-byte memmove is OK */ +  memmove (&tree->subtrees[i], +           &tree->subtrees[i+1], +           (tree->n_subtrees - i - 1) * sizeof (tree->subtrees[0])); +  tree->n_subtrees -= 1; +   +  _dbus_object_subtree_ref (subtree); + +  /* Unlock and call application code */ +  _dbus_connection_unlock (tree->connection); +   +  if (subtree->vtable.unregister_function) +    { +      (* subtree->vtable.unregister_function) (tree->connection, +                                               (const char**) subtree->path, +                                               subtree->user_data); +      _DBUS_ZERO (subtree->vtable); +    } +} + +/** + * Tries to dispatch a message by directing it to the object tree + * node listed in the message header, if any. + * + * @param tree the global object tree + * @param message the message to dispatch + * @returns whether message was handled successfully + */ +DBusHandlerResult +_dbus_object_tree_dispatch_and_unlock (DBusObjectTree          *tree, +                                       DBusMessage             *message) +{ +   +   +} + +DBusObjectSubtree* +_dbus_object_subtree_new (const char                 **path, +                          const DBusObjectTreeVTable  *vtable, +                          void                        *user_data) +{ +  DBusObjectSubtree *subtree; + +  subtree = dbus_new0 (DBusObjectSubtree, 1); +  if (subtree == NULL) +    goto oom; + +  _dbus_assert (path != NULL); +  _dbus_assert (path[0] != NULL); +   +  subtree->path = _dbus_dup_string_array (path); +  if (subtree->path == NULL) +    goto oom; + +  subtree->vtable = *vtable; +  subtree->user_data = user_data; +   +  subtree->refcount = 1; + +  /* count path elements */ +  while (subtree->path[subtree->n_path_elements]) +    subtree->n_path_elements += 1; +   +  return subtree; + + oom: +  if (subtree) +    { +      dbus_free_string_array (subtree->path); +      dbus_free (subtree); +    } +   +  return NULL; +} + +void +_dbus_object_subtree_ref (DBusObjectSubtree *subtree) +{ +  _dbus_assert (subtree->refcount > 0); + +  subtree->refcount += 1; +} + +void +_dbus_object_subtree_unref (DBusObjectSubtree *subtree) +{ +  _dbus_assert (subtree->refcount > 0); + +  subtree->refcount -= 1; + +  if (subtree->refcount == 0) +    { +      _dbus_assert (subtree->vtable.unregister_function == NULL); +       +      dbus_free_string_array (subtree->path); + +      dbus_free (subtree); +    } +} + +/** @} */ + +#ifdef DBUS_BUILD_TESTS +#include "dbus-test.h" +#include <stdio.h> + +static dbus_bool_t +test_subtree_cmp (const char **path1, +                  const char **path2, +                  int          expected, +                  dbus_bool_t  reverse) +{ +  DBusObjectSubtree *subtree1; +  DBusObjectSubtree *subtree2; +  dbus_bool_t retval; +  DBusObjectTreeVTable vtable; + +  _DBUS_ZERO (vtable); + +  retval = FALSE; +   +  subtree1 = _dbus_object_subtree_new (path1, &vtable, NULL); +  subtree2 = _dbus_object_subtree_new (path2, &vtable, NULL); +  if (subtree1 == NULL || subtree2 == NULL) +    goto out; + +  _dbus_assert (subtree_cmp (subtree1, subtree2) == expected); + +  retval = TRUE; +   + out: + +  if (subtree1) +    _dbus_object_subtree_unref (subtree1); + +  if (subtree2) +    _dbus_object_subtree_unref (subtree2); + +  if (retval && reverse) +    { +      /* Verify that the reverse also holds */ +      if (expected > 0) +        return test_subtree_cmp (path2, path1, -1, FALSE); +      else if (expected < 0) +        return test_subtree_cmp (path2, path1, 1, FALSE); +      else +        return test_subtree_cmp (path2, path1, 0, FALSE); +    } +   +  return retval; +} + +static void +test_path_overlap (const char  **path1, +                   const char  **path2, +                   dbus_bool_t   expected) +{ +  _dbus_assert (path_overlaps (path1, path2) == expected); +  _dbus_assert (path_overlaps (path2, path1) == expected); +} + +static dbus_bool_t +object_tree_test_iteration (void *data) +{ +  const char *path1[] = { "foo", NULL }; +  const char *path2[] = { "foo", "bar", NULL }; +  const char *path3[] = { "foo", "bar", "baz", NULL }; +  const char *path4[] = { "foo", "bar", "boo", NULL }; +  const char *path5[] = { "blah", NULL }; +  DBusObjectSubtree *subtree1; +  DBusObjectSubtree *subtree2; +  DBusObjectTree *tree; + +  tree = NULL; +  subtree1 = NULL; +  subtree2 = NULL; + +  test_path_overlap (path1, path1, TRUE); +  test_path_overlap (path1, path2, TRUE); +  test_path_overlap (path1, path3, TRUE); +  test_path_overlap (path1, path4, TRUE); +  test_path_overlap (path1, path5, FALSE);  + +  test_path_overlap (path2, path2, TRUE); +  test_path_overlap (path2, path3, TRUE); +  test_path_overlap (path2, path4, TRUE); +  test_path_overlap (path2, path5, FALSE); + +  test_path_overlap (path3, path3, TRUE); +  test_path_overlap (path3, path4, FALSE); +  test_path_overlap (path3, path5, FALSE); + +  test_path_overlap (path4, path4, TRUE); +  test_path_overlap (path4, path5, FALSE); + +  test_path_overlap (path5, path5, TRUE); +   +  if (!test_subtree_cmp (path1, path1, 0, TRUE)) +    goto out; +  if (!test_subtree_cmp (path3, path3, 0, TRUE)) +    goto out; +  /* When testing -1, the reverse also gets tested */ +  if (!test_subtree_cmp (path1, path2, -1, TRUE)) +    goto out; +  if (!test_subtree_cmp (path1, path3, -1, TRUE)) +    goto out; +  if (!test_subtree_cmp (path2, path3, -1, TRUE)) +    goto out; +  if (!test_subtree_cmp (path2, path4, -1, TRUE)) +    goto out; +  if (!test_subtree_cmp (path3, path4, -1, TRUE)) +    goto out; +  if (!test_subtree_cmp (path5, path1, -1, TRUE)) +    goto out; +   +  tree = _dbus_object_tree_new (NULL); +  if (tree == NULL) +    goto out; + + out: +  if (subtree1) +    _dbus_object_subtree_unref (subtree1); +  if (subtree2) +    _dbus_object_subtree_unref (subtree2); +  if (tree) +    _dbus_object_tree_unref (tree); +   +  return TRUE; +} + +/** + * @ingroup DBusObjectTree + * Unit test for DBusObjectTree + * @returns #TRUE on success. + */ +dbus_bool_t +_dbus_object_tree_test (void) +{ +  _dbus_test_oom_handling ("object tree", +                           object_tree_test_iteration, +                           NULL); +   +  return TRUE; +} + +#endif /* DBUS_BUILD_TESTS */ diff --git a/dbus/dbus-object-tree.h b/dbus/dbus-object-tree.h new file mode 100644 index 00000000..06033333 --- /dev/null +++ b/dbus/dbus-object-tree.h @@ -0,0 +1,48 @@ +/* -*- mode: C; c-file-style: "gnu" -*- */ +/* dbus-object-tree.h  DBusObjectTree (internals of DBusConnection) + * + * Copyright (C) 2003  Red Hat Inc. + * + * Licensed under the Academic Free License version 1.2 + *  + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + *  + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA + * + */ +#ifndef DBUS_OBJECT_TREE_H +#define DBUS_OBJECT_TREE_H + +#include <dbus/dbus-connection.h> + +DBUS_BEGIN_DECLS; + +typedef struct DBusObjectTree DBusObjectTree; + +DBusObjectTree* _dbus_object_tree_new   (DBusConnection *connection); +void            _dbus_object_tree_ref   (DBusObjectTree *tree); +void            _dbus_object_tree_unref (DBusObjectTree *tree); + +dbus_bool_t       _dbus_object_tree_register              (DBusObjectTree              *tree, +                                                           const char                 **path, +                                                           const DBusObjectTreeVTable  *vtable, +                                                           void                        *user_data); +void              _dbus_object_tree_unregister_and_unlock (DBusObjectTree              *tree, +                                                           const char                 **path); +DBusHandlerResult _dbus_object_tree_dispatch_and_unlock   (DBusObjectTree              *tree, +                                                           DBusMessage                 *message); + + +DBUS_END_DECLS; + +#endif /* DBUS_OBJECT_TREE_H */ diff --git a/dbus/dbus-string.c b/dbus/dbus-string.c index 98b4c60e..75b38b9d 100644 --- a/dbus/dbus-string.c +++ b/dbus/dbus-string.c @@ -1002,9 +1002,9 @@ _dbus_string_append_printf_valist  (DBusString        *str,                                      const char        *format,                                      va_list            args)  { -  DBUS_STRING_PREAMBLE (str);    int len;    char c; +  DBUS_STRING_PREAMBLE (str);    /* Measure the message length without terminating nul */    len = vsnprintf (&c, 1, format, args); diff --git a/dbus/dbus-test.c b/dbus/dbus-test.c index 8a99d179..2ab7fc27 100644 --- a/dbus/dbus-test.c +++ b/dbus/dbus-test.c @@ -112,6 +112,12 @@ dbus_internal_do_not_use_run_tests (const char *test_data_dir)    check_memleaks (); +  printf ("%s: running object tree tests\n", "dbus-test"); +  if (!_dbus_object_tree_test ()) +    die ("object tree"); +   +  check_memleaks (); +      printf ("%s: running object tests\n", "dbus-test");    if (!_dbus_object_test ())      die ("object"); diff --git a/dbus/dbus-test.h b/dbus/dbus-test.h index 276e8f9e..b6c02669 100644 --- a/dbus/dbus-test.h +++ b/dbus/dbus-test.h @@ -56,6 +56,7 @@ dbus_bool_t _dbus_memory_test	       (void);  dbus_bool_t _dbus_object_test          (void);  dbus_bool_t _dbus_object_id_test       (void);  dbus_bool_t _dbus_object_registry_test (void); +dbus_bool_t _dbus_object_tree_test     (void);  dbus_bool_t _dbus_pending_call_test    (const char *test_data_dir);  void        dbus_internal_do_not_use_run_tests         (const char          *test_data_dir); | 
