2003-05-08 Havoc Pennington <hp@pobox.com>
authorHavoc Pennington <hp@redhat.com>
Fri, 9 May 2003 04:15:56 +0000 (04:15 +0000)
committerHavoc Pennington <hp@redhat.com>
Fri, 9 May 2003 04:15:56 +0000 (04:15 +0000)
* dbus/dbus-spawn.c: s/_exit/exit/ because it was keeping gcov
data from getting written, and there wasn't a good reason to
use _exit really.

* test/decode-gcov.c (mark_inside_dbus_build_tests): don't count
dbus_verbose lines in test coverage
(main): add list of functions sorted by # of untested blocks
to the coverage report

* dbus/dbus-mempool.c: put some test-only code in DBUS_BUILD_TESTS

* dbus/dbus-marshal.c (_dbus_marshal_test): extend test coverage

* dbus/dbus-message-handler.c (_dbus_message_handler_test):
extend test coverage

* test/data/auth/cancel.auth-script: test canceling an
authentication

* dbus/Makefile.am: remove dbus-server-debug.[hc] for now, as they
aren't used. in CVS history if we end up needing them.

16 files changed:
ChangeLog
dbus/Makefile.am
dbus/dbus-marshal.c
dbus/dbus-memory.c
dbus/dbus-mempool.c
dbus/dbus-message-handler.c
dbus/dbus-server-debug.c [deleted file]
dbus/dbus-server-debug.h [deleted file]
dbus/dbus-server.c
dbus/dbus-spawn.c
dbus/dbus-transport-debug.c [deleted file]
dbus/dbus-transport-debug.h [deleted file]
dbus/dbus-transport.c
doc/TODO
test/data/auth/cancel.auth-script [new file with mode: 0644]
test/decode-gcov.c

index 1e7b2cc..43321cc 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,27 @@
+2003-05-08  Havoc Pennington  <hp@pobox.com>
+
+       * dbus/dbus-spawn.c: s/_exit/exit/ because it was keeping gcov
+       data from getting written, and there wasn't a good reason to 
+       use _exit really.
+
+       * test/decode-gcov.c (mark_inside_dbus_build_tests): don't count
+       dbus_verbose lines in test coverage
+       (main): add list of functions sorted by # of untested blocks 
+       to the coverage report
+
+       * dbus/dbus-mempool.c: put some test-only code in DBUS_BUILD_TESTS
+
+       * dbus/dbus-marshal.c (_dbus_marshal_test): extend test coverage
+
+       * dbus/dbus-message-handler.c (_dbus_message_handler_test):
+       extend test coverage
+
+       * test/data/auth/cancel.auth-script: test canceling an
+       authentication
+
+       * dbus/Makefile.am: remove dbus-server-debug.[hc] for now, as they
+       aren't used. in CVS history if we end up needing them.
+
 2003-05-04  Havoc Pennington  <hp@pobox.com>
 
        * dbus/dbus-message-handler.c (_dbus_message_handler_test): add
index 3e1e0be..99d49ab 100644 (file)
@@ -46,8 +46,6 @@ DBUS_LIB_SOURCES=                             \
        dbus-resources.h                        \
        dbus-server.c                           \
        dbus-server-protected.h                 \
-       dbus-server-debug.c                     \
-       dbus-server-debug.h                     \
        dbus-server-debug-pipe.c                \
        dbus-server-debug-pipe.h                \
        dbus-server-unix.c                      \
@@ -61,8 +59,6 @@ DBUS_LIB_SOURCES=                             \
        dbus-threads.c                          \
        dbus-transport.c                        \
        dbus-transport.h                        \
-       dbus-transport-debug.c                  \
-       dbus-transport-debug.h                  \
        dbus-transport-protected.h              \
        dbus-transport-unix.c                   \
        dbus-transport-unix.h                   \
index 7841ad3..82de8ff 100644 (file)
@@ -2088,6 +2088,8 @@ _dbus_marshal_test (void)
 #ifdef DBUS_HAVE_INT64
   dbus_int64_t array3[3] = { 0x123ffffffff, 0x456ffffffff, 0x789ffffffff }, *array4;
 #endif
+  char *s;
+  DBusString t;
   
   if (!_dbus_string_init (&str))
     _dbus_assert_not_reached ("failed to init string");
@@ -2140,12 +2142,12 @@ _dbus_marshal_test (void)
   /* Marshal unsigned integers */
   if (!_dbus_marshal_uint64 (&str, DBUS_BIG_ENDIAN, DBUS_UINT64_CONSTANT (0x123456789abc7)))
     _dbus_assert_not_reached ("could not marshal signed integer value");
-  if (!_dbus_demarshal_uint64 (&str, DBUS_BIG_ENDIAN, pos, &pos) == DBUS_UINT64_CONSTANT (0x123456789abc7))
+  if (!(_dbus_demarshal_uint64 (&str, DBUS_BIG_ENDIAN, pos, &pos) == DBUS_UINT64_CONSTANT (0x123456789abc7)))
     _dbus_assert_not_reached ("demarshal failed");
   
   if (!_dbus_marshal_uint64 (&str, DBUS_LITTLE_ENDIAN, DBUS_UINT64_CONSTANT (0x123456789abc7)))
     _dbus_assert_not_reached ("could not marshal signed integer value");
-  if (!_dbus_demarshal_uint64 (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == DBUS_UINT64_CONSTANT (0x123456789abc7))
+  if (!(_dbus_demarshal_uint64 (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == DBUS_UINT64_CONSTANT (0x123456789abc7)))
     _dbus_assert_not_reached ("demarshal failed");
 #endif /* DBUS_HAVE_INT64 */
   
@@ -2186,10 +2188,212 @@ _dbus_marshal_test (void)
   if (len != 3)
     _dbus_assert_not_reached ("Signed integer array lengths differ!\n");
   dbus_free (array4);
+
+  /* set/pack 64-bit integers */
+  _dbus_string_set_length (&str, 8);
+
+  /* signed little */
+  _dbus_marshal_set_int64 (&str, DBUS_LITTLE_ENDIAN,
+                           0, DBUS_INT64_CONSTANT (-0x123456789abc7));
+  
+  _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) ==
+                _dbus_unpack_int64 (DBUS_LITTLE_ENDIAN,
+                                    _dbus_string_get_const_data (&str)));
+
+  /* signed big */
+  _dbus_marshal_set_int64 (&str, DBUS_BIG_ENDIAN,
+                           0, DBUS_INT64_CONSTANT (-0x123456789abc7));
+
+  _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) ==
+                _dbus_unpack_int64 (DBUS_BIG_ENDIAN,
+                                    _dbus_string_get_const_data (&str)));
+
+  /* signed little pack */
+  _dbus_pack_int64 (DBUS_INT64_CONSTANT (-0x123456789abc7),
+                    DBUS_LITTLE_ENDIAN,
+                    _dbus_string_get_data (&str));
+  
+  _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) ==
+                _dbus_unpack_int64 (DBUS_LITTLE_ENDIAN,
+                                    _dbus_string_get_const_data (&str)));
+
+  /* signed big pack */
+  _dbus_pack_int64 (DBUS_INT64_CONSTANT (-0x123456789abc7),
+                    DBUS_BIG_ENDIAN,
+                    _dbus_string_get_data (&str));
+
+  _dbus_assert (DBUS_INT64_CONSTANT (-0x123456789abc7) ==
+                _dbus_unpack_int64 (DBUS_BIG_ENDIAN,
+                                    _dbus_string_get_const_data (&str)));
+
+  /* unsigned little */
+  _dbus_marshal_set_uint64 (&str, DBUS_LITTLE_ENDIAN,
+                            0, DBUS_UINT64_CONSTANT (0x123456789abc7));
+  
+  _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) ==
+                _dbus_unpack_uint64 (DBUS_LITTLE_ENDIAN,
+                                     _dbus_string_get_const_data (&str)));
+
+  /* unsigned big */
+  _dbus_marshal_set_uint64 (&str, DBUS_BIG_ENDIAN,
+                            0, DBUS_UINT64_CONSTANT (0x123456789abc7));
+
+  _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) ==
+                _dbus_unpack_uint64 (DBUS_BIG_ENDIAN,
+                                     _dbus_string_get_const_data (&str)));
+
+  /* unsigned little pack */
+  _dbus_pack_uint64 (DBUS_UINT64_CONSTANT (0x123456789abc7),
+                     DBUS_LITTLE_ENDIAN,
+                     _dbus_string_get_data (&str));
+  
+  _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) ==
+                _dbus_unpack_uint64 (DBUS_LITTLE_ENDIAN,
+                                     _dbus_string_get_const_data (&str)));
+
+  /* unsigned big pack */
+  _dbus_pack_uint64 (DBUS_UINT64_CONSTANT (0x123456789abc7),
+                     DBUS_BIG_ENDIAN,
+                     _dbus_string_get_data (&str));
+
+  _dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) ==
+                _dbus_unpack_uint64 (DBUS_BIG_ENDIAN,
+                                     _dbus_string_get_const_data (&str)));
+  
 #endif
+
+  /* set/pack 32-bit integers */
+  _dbus_string_set_length (&str, 4);
+
+  /* signed little */
+  _dbus_marshal_set_int32 (&str, DBUS_LITTLE_ENDIAN,
+                           0, -0x123456);
   
-  _dbus_string_free (&str);
+  _dbus_assert (-0x123456 ==
+                _dbus_unpack_int32 (DBUS_LITTLE_ENDIAN,
+                                    _dbus_string_get_const_data (&str)));
+
+  /* signed big */
+  _dbus_marshal_set_int32 (&str, DBUS_BIG_ENDIAN,
+                           0, -0x123456);
+
+  _dbus_assert (-0x123456 ==
+                _dbus_unpack_int32 (DBUS_BIG_ENDIAN,
+                                    _dbus_string_get_const_data (&str)));
+
+  /* signed little pack */
+  _dbus_pack_int32 (-0x123456,
+                    DBUS_LITTLE_ENDIAN,
+                    _dbus_string_get_data (&str));
+  
+  _dbus_assert (-0x123456 ==
+                _dbus_unpack_int32 (DBUS_LITTLE_ENDIAN,
+                                    _dbus_string_get_const_data (&str)));
+
+  /* signed big pack */
+  _dbus_pack_int32 (-0x123456,
+                    DBUS_BIG_ENDIAN,
+                    _dbus_string_get_data (&str));
+
+  _dbus_assert (-0x123456 ==
+                _dbus_unpack_int32 (DBUS_BIG_ENDIAN,
+                                    _dbus_string_get_const_data (&str)));
+
+  /* unsigned little */
+  _dbus_marshal_set_uint32 (&str, DBUS_LITTLE_ENDIAN,
+                            0, 0x123456);
+  
+  _dbus_assert (0x123456 ==
+                _dbus_unpack_uint32 (DBUS_LITTLE_ENDIAN,
+                                     _dbus_string_get_const_data (&str)));
+
+  /* unsigned big */
+  _dbus_marshal_set_uint32 (&str, DBUS_BIG_ENDIAN,
+                            0, 0x123456);
+
+  _dbus_assert (0x123456 ==
+                _dbus_unpack_uint32 (DBUS_BIG_ENDIAN,
+                                     _dbus_string_get_const_data (&str)));
+
+  /* unsigned little pack */
+  _dbus_pack_uint32 (0x123456,
+                     DBUS_LITTLE_ENDIAN,
+                     _dbus_string_get_data (&str));
+  
+  _dbus_assert (0x123456 ==
+                _dbus_unpack_uint32 (DBUS_LITTLE_ENDIAN,
+                                     _dbus_string_get_const_data (&str)));
+
+  /* unsigned big pack */
+  _dbus_pack_uint32 (0x123456,
+                     DBUS_BIG_ENDIAN,
+                     _dbus_string_get_data (&str));
+
+  _dbus_assert (0x123456 ==
+                _dbus_unpack_uint32 (DBUS_BIG_ENDIAN,
+                                     _dbus_string_get_const_data (&str)));
+
+
+  /* Strings */
+  
+  _dbus_string_set_length (&str, 0);
+
+  _dbus_marshal_string (&str, DBUS_LITTLE_ENDIAN,
+                        "Hello world");
+  
+  s = _dbus_demarshal_string (&str, DBUS_LITTLE_ENDIAN, 0, NULL);
+  _dbus_assert (strcmp (s, "Hello world") == 0);
+  dbus_free (s);
+
+  _dbus_string_init_const (&t, "Hello world foo");
+  
+  _dbus_marshal_set_string (&str, DBUS_LITTLE_ENDIAN, 0,
+                            &t, _dbus_string_get_length (&t));
+  
+  s = _dbus_demarshal_string (&str, DBUS_LITTLE_ENDIAN, 0, NULL);
+  _dbus_assert (strcmp (s, "Hello world foo") == 0);
+  dbus_free (s);
+
+  _dbus_string_init_const (&t, "Hello");
   
+  _dbus_marshal_set_string (&str, DBUS_LITTLE_ENDIAN, 0,
+                            &t, _dbus_string_get_length (&t));
+  
+  s = _dbus_demarshal_string (&str, DBUS_LITTLE_ENDIAN, 0, NULL);
+  _dbus_assert (strcmp (s, "Hello") == 0);
+  dbus_free (s);
+
+  /* Strings (big endian) */
+  
+  _dbus_string_set_length (&str, 0);
+
+  _dbus_marshal_string (&str, DBUS_BIG_ENDIAN,
+                        "Hello world");
+  
+  s = _dbus_demarshal_string (&str, DBUS_BIG_ENDIAN, 0, NULL);
+  _dbus_assert (strcmp (s, "Hello world") == 0);
+  dbus_free (s);
+
+  _dbus_string_init_const (&t, "Hello world foo");
+  
+  _dbus_marshal_set_string (&str, DBUS_BIG_ENDIAN, 0,
+                            &t, _dbus_string_get_length (&t));
+  
+  s = _dbus_demarshal_string (&str, DBUS_BIG_ENDIAN, 0, NULL);
+  _dbus_assert (strcmp (s, "Hello world foo") == 0);
+  dbus_free (s);
+
+  _dbus_string_init_const (&t, "Hello");
+  
+  _dbus_marshal_set_string (&str, DBUS_BIG_ENDIAN, 0,
+                            &t, _dbus_string_get_length (&t));
+  
+  s = _dbus_demarshal_string (&str, DBUS_BIG_ENDIAN, 0, NULL);
+  _dbus_assert (strcmp (s, "Hello") == 0);
+  dbus_free (s);
+
+  
+  _dbus_string_free (&str);
       
   return TRUE;
 }
index dce1dde..02bc1a4 100644 (file)
@@ -442,7 +442,7 @@ dbus_malloc (size_t bytes)
   
   if (bytes == 0) /* some system mallocs handle this, some don't */
     return NULL;
-#if DBUS_BUILD_TESTS
+#ifdef DBUS_BUILD_TESTS
   else if (fail_size != 0 && bytes > fail_size)
     return NULL;
   else if (guards)
@@ -493,7 +493,7 @@ dbus_malloc0 (size_t bytes)
 
   if (bytes == 0)
     return NULL;
-#if DBUS_BUILD_TESTS
+#ifdef DBUS_BUILD_TESTS
   else if (fail_size != 0 && bytes > fail_size)
     return NULL;
   else if (guards)
@@ -548,7 +548,7 @@ dbus_realloc (void  *memory,
       dbus_free (memory);
       return NULL;
     }
-#if DBUS_BUILD_TESTS
+#ifdef DBUS_BUILD_TESTS
   else if (fail_size != 0 && bytes > fail_size)
     return NULL;
   else if (guards)
index 5074c7d..a53a488 100644 (file)
@@ -207,6 +207,7 @@ _dbus_mem_pool_free (DBusMemPool *pool)
 void*
 _dbus_mem_pool_alloc (DBusMemPool *pool)
 {
+#ifdef DBUS_BUILD_TESTS
   if (_dbus_disable_mem_pools ())
     {
       DBusMemBlock *block;
@@ -239,6 +240,7 @@ _dbus_mem_pool_alloc (DBusMemPool *pool)
         return NULL;
     }
   else
+#endif
     {
       if (_dbus_decrement_fail_alloc_counter ())
         {
@@ -334,6 +336,7 @@ dbus_bool_t
 _dbus_mem_pool_dealloc (DBusMemPool *pool,
                         void        *element)
 {
+#ifdef DBUS_BUILD_TESTS
   if (_dbus_disable_mem_pools ())
     {
       DBusMemBlock *block;
@@ -371,6 +374,7 @@ _dbus_mem_pool_dealloc (DBusMemPool *pool,
       return FALSE;
     }
   else
+#endif
     {
       DBusFreedElement *freed;
       
index 0b44e13..a978ba0 100644 (file)
@@ -359,6 +359,10 @@ _dbus_message_handler_test (const char *test_data_dir)
   if (dbus_message_handler_get_data (handler) != TEST_DATA)
     _dbus_assert_not_reached ("got wrong data");
 
+  dbus_message_handler_set_data (handler, NULL, NULL);
+  if (dbus_message_handler_get_data (handler) != NULL)
+    _dbus_assert_not_reached ("got wrong data after set");  
+  
   dbus_message_handler_set_function (handler, NULL);
   _dbus_assert (handler->function == NULL);
 
diff --git a/dbus/dbus-server-debug.c b/dbus/dbus-server-debug.c
deleted file mode 100644 (file)
index 1cb4ee2..0000000
+++ /dev/null
@@ -1,269 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu" -*- */
-/* dbus-server-debug.h In-proc debug server implementation 
- *
- * Copyright (C) 2003  CodeFactory AB
- *
- * 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-internals.h"
-#include "dbus-server-debug.h"
-#include "dbus-transport-debug.h"
-#include "dbus-connection-internal.h"
-#include "dbus-hash.h"
-
-#ifdef DBUS_BUILD_TESTS
-
-/**
- * @defgroup DBusServerDebug DBusServerDebug
- * @ingroup  DBusInternals
- * @brief In-process debug server used in unit tests.
- *
- * Types and functions related to DBusServerDebug.
- * This is used for unit testing.
- *
- * @{
- */
-
-/**
- * Default timeout interval when reading or writing.
- */
-#define DEFAULT_INTERVAL 1
-
-/**
- * Opaque object representing a debug server implementation.
- */
-typedef struct DBusServerDebug DBusServerDebug;
-
-/**
- * Implementation details of DBusServerDebug. All members
- * are private.
- */
-struct DBusServerDebug
-{
-  DBusServer base;  /**< Parent class members. */
-
-  char *name; /**< Server name. */
-};
-
-/* Not thread safe, but OK since we don't use
- * threads in the bus
- */
-static DBusHashTable *server_hash;
-
-static void
-debug_finalize (DBusServer *server)
-{
-}
-
-static void
-debug_disconnect (DBusServer *server)
-{
-}
-
-static DBusServerVTable debug_vtable = {
-  debug_finalize,
-  debug_disconnect
-};
-
-/**
- * Looks up a server by its name.
- *
- * @param server_name the server name.
- * @returns the server, or #NULL if none exists.
- */
-DBusServer*
-_dbus_server_debug_lookup (const char *server_name)
-{
-  if (!server_hash)
-    return NULL;
-
-  return _dbus_hash_table_lookup_string (server_hash, server_name);
-}
-
-/**
- * Creates a new debug server.
- *
- * @param server_name the name of the server.
- * @param error address where an error can be returned.
- * @returns a new server, or #NULL on failure.
- */
-DBusServer*
-_dbus_server_debug_new (const char     *server_name,
-                        DBusError      *error)
-{
-  DBusServerDebug *debug_server;
-  DBusString address;
-  
-  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
-  
-  if (!server_hash)
-    {
-      server_hash = _dbus_hash_table_new (DBUS_HASH_STRING, NULL, NULL);
-
-      if (!server_hash)
-       {
-         dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
-         return NULL;
-       }
-    }
-
-  if (_dbus_hash_table_lookup_string (server_hash, server_name) != NULL)
-    {
-      dbus_set_error (error, DBUS_ERROR_ADDRESS_IN_USE,
-                      NULL);
-      return NULL;
-    }
-  
-  debug_server = dbus_new0 (DBusServerDebug, 1);
-
-  if (debug_server == NULL)
-    return NULL;
-
-  if (!_dbus_string_init (&address))
-    goto nomem_0;
-
-  if (!_dbus_string_append (&address, "debug:name=") ||
-      !_dbus_string_append (&address, server_name))
-    goto nomem_1;
-  
-  debug_server->name = _dbus_strdup (server_name);
-  if (debug_server->name == NULL)
-    goto nomem_1;
-  
-  if (!_dbus_server_init_base (&debug_server->base,
-                              &debug_vtable,
-                               &address))
-    goto nomem_2;
-
-  if (!_dbus_hash_table_insert_string (server_hash,
-                                      debug_server->name,
-                                      debug_server))
-    goto nomem_3;
-
-  _dbus_string_free (&address);
-  
-  return (DBusServer *)debug_server;
-
- nomem_3:
-  _dbus_server_finalize_base (&debug_server->base);
- nomem_2:
-  dbus_free (debug_server->name);
- nomem_1:
-  _dbus_string_free (&address);
- nomem_0:
-  dbus_free (debug_server);
-
-  dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
-  
-  return NULL;
-}
-
-typedef struct
-{
-  DBusServer *server;
-  DBusTransport *transport;
-  DBusTimeout *timeout;
-} ServerAndTransport;
-
-static dbus_bool_t
-handle_new_client (void *data)
-{
-  ServerAndTransport *st = data;
-  DBusTransport *transport;
-  DBusConnection *connection;
-
-  _dbus_verbose ("  new debug client transport %p connecting to server\n",
-                 st->transport);
-  
-  transport = _dbus_transport_debug_server_new (st->transport);
-  if (transport == NULL)
-    return FALSE;
-
-  connection = _dbus_connection_new_for_transport (transport);
-  _dbus_transport_unref (transport);
-
-  if (connection == NULL)
-    return FALSE;
-
-  /* See if someone wants to handle this new connection,
-   * self-referencing for paranoia
-   */
-  if (st->server->new_connection_function)
-    {
-      dbus_server_ref (st->server);
-      
-      (* st->server->new_connection_function) (st->server, connection,
-                                              st->server->new_connection_data);
-      dbus_server_unref (st->server);
-    }
-
-  _dbus_server_remove_timeout (st->server, st->timeout);
-  
-  /* If no one grabbed a reference, the connection will die. */
-  dbus_connection_unref (connection);
-
-  /* killing timeout frees both "st" and "timeout" */
-  _dbus_timeout_unref (st->timeout);
-
-  return TRUE;
-}
-
-/**
- * Tells the server to accept a transport so the transport
- * can send messages to it.
- *
- * @param server the server
- * @param transport the transport
- * @returns #TRUE on success.
- */
-dbus_bool_t
-_dbus_server_debug_accept_transport (DBusServer     *server,
-                                    DBusTransport  *transport)
-{
-  ServerAndTransport *st = NULL;
-
-  st = dbus_new (ServerAndTransport, 1);
-  if (st == NULL)
-    return FALSE;
-
-  st->transport = transport;
-  st->server = server;
-  
-  st->timeout = _dbus_timeout_new (DEFAULT_INTERVAL, handle_new_client, st,
-                                   dbus_free);
-
-  if (st->timeout == NULL)
-    goto failed;
-
-  if (!_dbus_server_add_timeout (server, st->timeout))
-    goto failed;
-  
-  return TRUE;
-
- failed:
-  if (st->timeout)
-    _dbus_timeout_unref (st->timeout);
-  dbus_free (st);
-  return FALSE;
-}
-
-/** @} */
-
-#endif /* DBUS_BUILD_TESTS */
-
diff --git a/dbus/dbus-server-debug.h b/dbus/dbus-server-debug.h
deleted file mode 100644 (file)
index 788267d..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu" -*- */
-/* dbus-server-debug.h In-proc debug server implementation 
- *
- * Copyright (C) 2003  CodeFactory AB
- *
- * 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_SERVER_DEBUG_H
-#define DBUS_SERVER_DEBUG_H
-
-#include <dbus/dbus-internals.h>
-#include <dbus/dbus-server-protected.h>
-#include <dbus/dbus-transport.h>
-
-DBUS_BEGIN_DECLS;
-
-DBusServer* _dbus_server_debug_new              (const char     *server_name,
-                                                 DBusError      *error);
-DBusServer* _dbus_server_debug_lookup           (const char     *server_name);
-dbus_bool_t _dbus_server_debug_accept_transport (DBusServer     *server,
-                                                DBusTransport  *transport);
-
-
-DBUS_END_DECLS;
-
-#endif /* DBUS_SERVER_DEBUG_H */
index 72a60d0..e62c028 100644 (file)
@@ -24,7 +24,6 @@
 #include "dbus-server.h"
 #include "dbus-server-unix.h"
 #ifdef DBUS_BUILD_TESTS
-#include "dbus-server-debug.h"
 #include "dbus-server-debug-pipe.h"
 #endif
 #include "dbus-address.h"
@@ -389,19 +388,6 @@ dbus_server_listen (const char     *address,
            break;
        }
 #ifdef DBUS_BUILD_TESTS
-      else if (strcmp (method, "debug") == 0)
-       {
-         const char *name = dbus_address_entry_get_value (entries[i], "name");
-
-         if (name == NULL)
-            {
-              address_problem_type = "debug";
-              address_problem_field = "name";
-              goto bad_address;
-            }
-
-         server = _dbus_server_debug_new (name, error);
-       }
       else if (strcmp (method, "debug-pipe") == 0)
        {
          const char *name = dbus_address_entry_get_value (entries[i], "name");
index 5a36703..179b9f9 100644 (file)
@@ -765,7 +765,7 @@ do_write (int fd, const void *buf, size_t count)
       else
         {
           _dbus_warn ("Failed to write data to pipe!\n");
-          _exit (1); /* give up, we suck */
+          exit (1); /* give up, we suck */
         }
     }
   else
@@ -783,7 +783,7 @@ write_err_and_exit (int fd, int msg)
   do_write (fd, &msg, sizeof (msg));
   do_write (fd, &en, sizeof (en));
   
-  _exit (1);
+  exit (1);
 }
 
 static void
@@ -803,7 +803,7 @@ write_status_and_exit (int fd, int status)
   do_write (fd, &msg, sizeof (msg));
   do_write (fd, &status, sizeof (status));
   
-  _exit (0);
+  exit (0);
 }
 
 static void
@@ -868,7 +868,7 @@ check_babysit_events (pid_t grandchild_pid,
       /* This isn't supposed to happen. */
       _dbus_warn ("unexpected waitpid() failure in check_babysit_events(): %s\n",
                   _dbus_strerror (errno));
-      _exit (1);
+      exit (1);
     }
   else if (ret == grandchild_pid)
     {
@@ -881,7 +881,7 @@ check_babysit_events (pid_t grandchild_pid,
     {
       _dbus_warn ("waitpid() reaped pid %d that we've never heard of\n",
                   (int) ret);
-      _exit (1);
+      exit (1);
     }
 
   if (revents & _DBUS_POLLIN)
@@ -893,7 +893,7 @@ check_babysit_events (pid_t grandchild_pid,
     {
       /* Parent is gone, so we just exit */
       _dbus_verbose ("babysitter got POLLERR or POLLHUP from parent\n");
-      _exit (0);
+      exit (0);
     }
 }
 
@@ -928,7 +928,7 @@ babysit (pid_t grandchild_pid,
   if (pipe (sigchld_pipe) < 0)
     {
       _dbus_warn ("Not enough file descriptors to create pipe in babysitter process\n");
-      _exit (1);
+      exit (1);
     }
 
   babysit_sigchld_pipe = sigchld_pipe[WRITE_END];
@@ -966,7 +966,7 @@ babysit (pid_t grandchild_pid,
         }
     }
   
-  _exit (1);
+  exit (1);
 }
 
 /**
diff --git a/dbus/dbus-transport-debug.c b/dbus/dbus-transport-debug.c
deleted file mode 100644 (file)
index 5b250d7..0000000
+++ /dev/null
@@ -1,394 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu" -*- */
-/* dbus-transport-debug.c In-proc debug subclass of DBusTransport
- *
- * Copyright (C) 2003  CodeFactory AB
- * 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-internals.h"
-#include "dbus-connection-internal.h"
-#include "dbus-transport-protected.h"
-#include "dbus-transport-debug.h"
-#include "dbus-server-debug.h"
-#include "dbus-list.h"
-
-#ifdef DBUS_BUILD_TESTS
-
-/**
- * @defgroup DBusTransportDebug DBusTransportDebug
- * @ingroup  DBusInternals
- * @brief In-process debug transport used in unit tests.
- *
- * Types and functions related to DBusTransportDebug.
- * This is used for unit testing.
- *
- * @{
- */
-
-/**
- * Default timeout interval when reading or writing.
- */
-#define DEFAULT_INTERVAL 1
-
-/**
- * Hack due to lack of OOM handling in a couple places.
- * Need to alloc timeout permanently and enabled/disable so
- * that check_timeout won't fail in messages_pending
- */
-#define WAIT_FOR_MEMORY() _dbus_sleep_milliseconds (250)
-
-static dbus_bool_t check_timeout (DBusTransport *transport);
-
-/**
- * Opaque object representing a debug transport.
- *
- */
-typedef struct DBusTransportDebug DBusTransportDebug;
-
-/**
- * Implementation details of DBusTransportDebug. All members are private.
- */
-struct DBusTransportDebug
-{
-  DBusTransport base;                   /**< Parent instance */
-
-  DBusTimeout *timeout;                 /**< Timeout for moving messages. */
-  
-  DBusTransport *other_end;             /**< The transport that this transport is connected to. */
-
-  unsigned int timeout_added : 1;       /**< Whether timeout has been added */
-};
-
-/* move messages in both directions */
-static dbus_bool_t
-move_messages (DBusTransport *transport)
-{
-  DBusTransportDebug *debug_transport = (DBusTransportDebug*) transport;
-  
-  if (transport->disconnected)
-    return TRUE;
-
-  while (!transport->disconnected &&
-        _dbus_connection_have_messages_to_send (transport->connection))
-    {
-      DBusMessage *message, *copy;
-      
-      message = _dbus_connection_get_message_to_send (transport->connection);
-      _dbus_assert (message != NULL);
-      
-      copy = dbus_message_copy (message);
-      if (copy == NULL)
-        return FALSE;
-        
-      _dbus_message_lock (message);
-      
-      _dbus_connection_message_sent (transport->connection,
-                                    message);
-
-      _dbus_verbose ("   -->transporting message %s from %s %p to %s %p\n",
-                     dbus_message_get_name (copy),
-                     transport->is_server ? "server" : "client",
-                     transport->connection,
-                     debug_transport->other_end->is_server ? "server" : "client",
-                     debug_transport->other_end->connection);
-      
-      _dbus_connection_queue_received_message (debug_transport->other_end->connection,
-                                               copy);
-      dbus_message_unref (copy);
-    }
-
-  if (debug_transport->other_end &&
-      !debug_transport->other_end->disconnected &&
-      _dbus_connection_have_messages_to_send (debug_transport->other_end->connection))
-    {
-      if (!move_messages (debug_transport->other_end))
-        return FALSE;
-    }
-  
-  return TRUE;
-}
-
-static dbus_bool_t
-timeout_handler (void *data)
-{
-  DBusTransport *transport = data;
-  
-  if (!move_messages (transport))
-    return FALSE;
-
-  if (!check_timeout (transport))
-    return FALSE;
-
-  return TRUE;
-}
-
-static dbus_bool_t
-check_timeout (DBusTransport *transport)
-{
-  DBusTransportDebug *debug_transport = (DBusTransportDebug*) transport;
-  
-  if (transport->connection &&
-      transport->authenticated &&
-      (transport->messages_need_sending ||
-       (debug_transport->other_end &&
-        debug_transport->other_end->messages_need_sending)))
-    {
-      if (!debug_transport->timeout_added)
-        {
-          /* FIXME this can be fixed now, by enabling/disabling
-           * the timeout instead of adding it here
-           */
-          if (!_dbus_connection_add_timeout (transport->connection,
-                                             debug_transport->timeout))
-            return FALSE;
-          debug_transport->timeout_added = TRUE;
-        }
-    }
-  else
-    {
-      if (debug_transport->timeout_added)
-        {
-          _dbus_connection_remove_timeout (transport->connection,
-                                           debug_transport->timeout);
-          debug_transport->timeout_added = FALSE;
-        }
-    }
-
-  return TRUE;
-}
-
-static void
-debug_finalize (DBusTransport *transport)
-{
-  DBusTransportDebug *debug_transport = (DBusTransportDebug*) transport;
-  
-  if (debug_transport->timeout_added)
-    _dbus_connection_remove_timeout (transport->connection,
-                                     debug_transport->timeout);
-  
-  if (debug_transport->other_end)
-    {
-      _dbus_transport_disconnect (debug_transport->other_end);
-      debug_transport->other_end = NULL;
-    }
-  
-  _dbus_transport_finalize_base (transport);  
-
-  _dbus_timeout_unref (debug_transport->timeout);
-  
-  dbus_free (transport);
-}
-
-static dbus_bool_t
-debug_handle_watch (DBusTransport *transport,
-                   DBusWatch     *watch,
-                   unsigned int   flags)
-{
-  return TRUE;
-}
-
-static void
-debug_disconnect (DBusTransport *transport)
-{
-}
-
-static dbus_bool_t
-debug_connection_set (DBusTransport *transport)
-{
-  if (!check_timeout (transport))
-    return FALSE;
-  return TRUE;
-}
-
-static void
-debug_messages_pending (DBusTransport *transport,
-                       int            messages_pending)
-{
-  while (!check_timeout (transport))
-    WAIT_FOR_MEMORY ();
-}
-
-static void
-debug_do_iteration (DBusTransport *transport,
-                   unsigned int   flags,
-                   int            timeout_milliseconds)
-{
-  move_messages (transport);
-}
-
-static void
-debug_live_messages_changed (DBusTransport *transport)
-{
-}
-
-static DBusTransportVTable debug_vtable = {
-  debug_finalize,
-  debug_handle_watch,
-  debug_disconnect,
-  debug_connection_set,
-  debug_messages_pending,
-  debug_do_iteration,
-  debug_live_messages_changed
-};
-
-static dbus_bool_t
-create_timeout_object (DBusTransportDebug *debug_transport)
-{
-  debug_transport->timeout = _dbus_timeout_new (DEFAULT_INTERVAL,
-                                                timeout_handler,
-                                                debug_transport, NULL);
-  
-  return debug_transport->timeout != NULL;
-}
-
-/**
- * Creates a new debug server transport.
- *
- * @param client the client transport that the server transport
- * should use.
- * @returns a new debug transport
- */
-DBusTransport*
-_dbus_transport_debug_server_new (DBusTransport *client)
-{
-  DBusTransportDebug *debug_transport;
-
-  debug_transport = dbus_new0 (DBusTransportDebug, 1);
-  
-  if (debug_transport == NULL)
-    return NULL;
-
-  if (!_dbus_transport_init_base (&debug_transport->base,
-                                 &debug_vtable,
-                                 TRUE, NULL))
-    {
-      dbus_free (debug_transport);
-      return NULL;
-    }
-
-  if (!create_timeout_object (debug_transport))
-    {
-      _dbus_transport_finalize_base (&debug_transport->base);      
-      dbus_free (debug_transport);
-      return NULL;
-    }
-  
-  debug_transport->base.authenticated = TRUE;
-
-  /* Connect the two transports */
-  debug_transport->other_end = client;
-  ((DBusTransportDebug *)client)->other_end = (DBusTransport *)debug_transport;
-
-  _dbus_verbose ("  new debug server transport %p created, other end %p\n",
-                 debug_transport, debug_transport->other_end);
-  
-  return (DBusTransport *)debug_transport;
-}
-
-/**
- * Creates a new debug client transport.
- *
- * @param server_name name of the server transport that
- * the client should try to connect to.
- * @param error address where an error can be returned.
- * @returns a new transport, or #NULL on failure. 
- */
-DBusTransport*
-_dbus_transport_debug_client_new (const char     *server_name,
-                                 DBusError      *error)
-{
-  DBusServer *debug_server;
-  DBusTransportDebug *debug_transport;
-  DBusString address;
-  
-  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
-  
-  debug_server = _dbus_server_debug_lookup (server_name);
-
-  if (!debug_server)
-    {
-      dbus_set_error (error, DBUS_ERROR_NO_SERVER, NULL);
-      return NULL;
-    }
-
-  if (!_dbus_string_init (&address))
-    {
-      dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
-      return NULL;
-    }
-
-  if (!_dbus_string_append (&address, "debug-pipe:name=") ||
-      !_dbus_string_append (&address, server_name))
-    {
-      dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
-      _dbus_string_free (&address);
-      return NULL;
-    }
-  
-  debug_transport = dbus_new0 (DBusTransportDebug, 1);
-  if (debug_transport == NULL)
-    {
-      dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
-      _dbus_string_free (&address);
-      return NULL;
-    }
-
-  if (!_dbus_transport_init_base (&debug_transport->base,
-                                 &debug_vtable,
-                                 FALSE, &address))
-    {
-      dbus_free (debug_transport);
-      dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
-      _dbus_string_free (&address);
-      return NULL;
-    }
-
-  _dbus_string_free (&address);
-  
-  if (!create_timeout_object (debug_transport))
-    {
-      _dbus_transport_finalize_base (&debug_transport->base);
-      dbus_free (debug_transport);
-      dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
-      return NULL;
-    }
-  
-  if (!_dbus_server_debug_accept_transport (debug_server,
-                                            (DBusTransport *)debug_transport))
-    {
-      _dbus_timeout_unref (debug_transport->timeout);
-      _dbus_transport_finalize_base (&debug_transport->base);
-      dbus_free (debug_transport);
-      dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
-      return NULL;
-    }
-
-  /* FIXME: Prolly wrong to do this. */
-  debug_transport->base.authenticated = TRUE;
-
-  _dbus_verbose ("  new debug client transport %p created, other end %p\n",
-                 debug_transport, debug_transport->other_end);
-  
-  return (DBusTransport *)debug_transport;
-}
-
-/** @} */
-
-#endif /* DBUS_BUILD_TESTS */
diff --git a/dbus/dbus-transport-debug.h b/dbus/dbus-transport-debug.h
deleted file mode 100644 (file)
index ced9509..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu" -*- */
-/* dbus-transport-debug.h Debug in-proc subclass of DBusTransport
- *
- * Copyright (C) 2003  CodeFactory AB
- *
- * 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_TRANSPORT_DEBUG_H
-#define DBUS_TRANSPORT_DEBUG_H
-
-#include <dbus/dbus-transport.h>
-
-DBUS_BEGIN_DECLS;
-
-DBusTransport* _dbus_transport_debug_server_new (DBusTransport  *client);
-DBusTransport* _dbus_transport_debug_client_new (const char     *server_name,
-                                                 DBusError      *error);
-
-DBUS_END_DECLS;
-
-#endif /* DBUS_TRANSPORT_DEBUG_H */
index 2332256..af1cb42 100644 (file)
@@ -28,7 +28,6 @@
 #include "dbus-auth.h"
 #include "dbus-address.h"
 #ifdef DBUS_BUILD_TESTS
-#include "dbus-transport-debug.h"
 #include "dbus-server-debug-pipe.h"
 #endif
 
@@ -288,19 +287,6 @@ _dbus_transport_open (const char     *address,
          transport = _dbus_transport_new_for_tcp_socket (host, lport, &tmp_error);
        }
 #ifdef DBUS_BUILD_TESTS
-      else if (strcmp (method, "debug") == 0)
-       {
-         const char *name = dbus_address_entry_get_value (entries[i], "name");
-
-         if (name == NULL)
-            {
-              address_problem_type = "debug";
-              address_problem_field = "name";
-              goto bad_address;
-            }
-          
-          transport = _dbus_transport_debug_client_new (name, &tmp_error);
-       }
       else if (strcmp (method, "debug-pipe") == 0)
        {
          const char *name = dbus_address_entry_get_value (entries[i], "name");
index 5411351..b323145 100644 (file)
--- a/doc/TODO
+++ b/doc/TODO
@@ -13,9 +13,6 @@
    that involve the properties of the source or destination
    connection.
 
- - Implement all the needed resource limits to keep clients from
-   killing the message bus.
-
  - Automatic service activation, should probably be done through a message flag.
 
  - Disconnecting the remote end on invalid UTF-8 is probably not a good 
diff --git a/test/data/auth/cancel.auth-script b/test/data/auth/cancel.auth-script
new file mode 100644 (file)
index 0000000..a99c612
--- /dev/null
@@ -0,0 +1,19 @@
+## this tests canceling EXTERNAL
+
+SERVER
+SEND 'AUTH EXTERNAL USERID_BASE64'
+EXPECT_COMMAND OK
+EXPECT_STATE WAITING_FOR_INPUT
+SEND 'CANCEL'
+EXPECT_COMMAND REJECTED
+EXPECT_STATE WAITING_FOR_INPUT
+
+## now start over and see if it works
+SEND 'AUTH EXTERNAL USERID_BASE64'
+EXPECT_COMMAND OK
+EXPECT_STATE WAITING_FOR_INPUT
+SEND 'BEGIN'
+EXPECT_STATE AUTHENTICATED
+
+
+
index 1ebba30..d13340e 100644 (file)
@@ -1197,14 +1197,17 @@ mark_inside_dbus_build_tests (File  *f)
   while (i < f->n_lines)
     {
       Line *l = &f->lines[i];
+      dbus_bool_t is_verbose;
+
+      is_verbose = strstr (l->text, "_dbus_verbose") != NULL;
 
       if (inside_depth == 0)
         {
           const char *a, *b;
           
-          a = strstr (l->text, "#ifdef");
+          a = strstr (l->text, "#if");
           b = strstr (l->text, "DBUS_BUILD_TESTS");
-          if (a && b)
+          if (a && b && (a < b))
             inside_depth += 1;
         }
       else
@@ -1215,7 +1218,7 @@ mark_inside_dbus_build_tests (File  *f)
             inside_depth -= 1;
         }
 
-      if (inside_depth > 0)
+      if (inside_depth > 0 || is_verbose)
         {
           /* Mark the line and its blocks */
           DBusList *blink;
@@ -1243,6 +1246,41 @@ mark_inside_dbus_build_tests (File  *f)
   while (link != NULL)
     {
       Function *func = link->data;
+
+      /* The issue is that some blocks aren't associated with a source line.
+       * Assume they are inside/outside tests according to the source
+       * line of the preceding block. For the first block, make it
+       * match the first following block with a line associated.
+       */
+      if (func->block_graph[0].lines == NULL)
+        {
+          /* find first following line */
+          i = 1;
+          while (i < func->n_blocks)
+            {
+              if (func->block_graph[i].lines != NULL)
+                {
+                  func->block_graph[0].inside_dbus_build_tests =
+                    func->block_graph[i].inside_dbus_build_tests;
+                  break;
+                }
+              
+              ++i;
+            }
+        }
+
+      /* Now mark all blocks but the first */
+      i = 1;
+      while (i < func->n_blocks)
+        {
+          if (func->block_graph[i].lines == NULL)
+            {
+              func->block_graph[i].inside_dbus_build_tests =
+                func->block_graph[i-1].inside_dbus_build_tests;
+            }
+          
+          ++i;
+        }
       
       i = 0;
       while (i < func->n_blocks)
@@ -1733,7 +1771,7 @@ print_untested_functions (File *f)
 
   if (!found)
     return;
-
+  
   printf ("Untested functions in %s\n", f->name);
   printf ("=======\n");
   
@@ -1800,6 +1838,92 @@ print_poorly_tested_functions (File  *f,
   printf ("\n");
 }
 
+static int
+func_cmp (const void *a,
+          const void *b)
+{
+  Function *af = *(Function**) a;
+  Function *bf = *(Function**) b;
+  int a_untested = af->n_nontest_blocks - af->n_nontest_blocks_executed;
+  int b_untested = bf->n_nontest_blocks - bf->n_nontest_blocks_executed;
+  
+  /* Sort by number of untested blocks */
+  return b_untested - a_untested;
+}
+
+static void
+print_n_untested_blocks_by_function (File  *f,
+                                     Stats *stats)
+{
+  DBusList *link;
+  Function **funcs;
+  int n_found;
+  int i;
+  
+  n_found = 0;
+  link = _dbus_list_get_first_link (&f->functions);
+  while (link != NULL)
+    {
+      Function *func = link->data;
+
+      if (func->n_nontest_blocks_executed <
+          func->n_nontest_blocks)
+        n_found += 1;
+      
+      link = _dbus_list_get_next_link (&f->functions, link);
+    }
+
+  if (n_found == 0)
+    return;
+
+  /* make an array so we can use qsort */
+  
+  funcs = dbus_new (Function*, n_found);
+  if (funcs == NULL)
+    return;
+  
+  i = 0;
+  link = _dbus_list_get_first_link (&f->functions);
+  while (link != NULL)
+    {
+      Function *func = link->data;
+
+      if (func->n_nontest_blocks_executed <
+          func->n_nontest_blocks)
+        {
+          funcs[i] = func;
+          ++i;
+        }
+
+      link = _dbus_list_get_next_link (&f->functions, link);
+    }
+
+  _dbus_assert (i == n_found);
+  
+  qsort (funcs, n_found, sizeof (Function*),
+         func_cmp);
+  
+  printf ("Incomplete functions in %s\n", f->name);
+  printf ("=======\n");
+
+  i = 0;
+  while (i < n_found)
+    {
+      Function *func = funcs[i];
+
+      printf ("  %s (%d/%d untested blocks)\n",
+              func->name,
+              func->n_nontest_blocks - func->n_nontest_blocks_executed,
+              func->n_nontest_blocks);
+      
+      ++i;
+    }
+
+  dbus_free (funcs);
+
+  printf ("\n");
+}
+
 static void
 print_stats (Stats      *stats,
              const char *of_what)
@@ -1813,7 +1937,7 @@ print_stats (Stats      *stats,
           stats->n_blocks_executed,
           stats->n_blocks);
 
-  printf ("     (ignored %d blocks inside DBUS_BUILD_TESTS)\n",
+  printf ("     (ignored %d blocks of test-only/debug-only code)\n",
           stats->n_blocks_inside_dbus_build_tests);
       
   printf ("  %g%% functions executed (%d of %d)\n",
@@ -1827,7 +1951,7 @@ print_stats (Stats      *stats,
           completely,
           stats->n_functions);
 
-  printf ("     (ignored %d functions inside DBUS_BUILD_TESTS)\n",
+  printf ("     (ignored %d functions of test-only/debug-only code)\n",
           stats->n_functions_inside_dbus_build_tests);
       
   printf ("  %g%% lines executed (%d of %d)\n",
@@ -1841,7 +1965,7 @@ print_stats (Stats      *stats,
           completely,
           stats->n_lines);
 
-  printf ("     (ignored %d lines inside DBUS_BUILD_TESTS)\n",
+  printf ("     (ignored %d lines of test-only/debug-only code)\n",
           stats->n_lines_inside_dbus_build_tests);
 
   printf ("\n");
@@ -2035,6 +2159,16 @@ main (int argc, char **argv)
           
           link = _dbus_list_get_next_link (&files, link);
         }
+
+      link = _dbus_list_get_first_link (&files);
+      while (link != NULL)
+        {
+          File *f = link->data;
+          
+          print_n_untested_blocks_by_function (f, &stats);
+          
+          link = _dbus_list_get_next_link (&files, link);
+        }
     }
   
   return 0;