r3936 - in trunk/birnet: . tests



Author: timj
Date: 2006-10-06 12:54:11 -0400 (Fri, 06 Oct 2006)
New Revision: 3936

Added:
   trunk/birnet/birnet-zintern.cc
   trunk/birnet/birnet.hh
   trunk/birnet/birnetmsg.cc
   trunk/birnet/birnetmsg.hh
   trunk/birnet/birnetutils.cc
   trunk/birnet/birnetutils.hh
Removed:
   trunk/birnet/birnet-zintern.c
   trunk/birnet/birnet.h
   trunk/birnet/birnetmsg.c
   trunk/birnet/birnetmsg.h
   trunk/birnet/birnetutils.c
   trunk/birnet/birnetutils.h
Modified:
   trunk/birnet/ChangeLog
   trunk/birnet/Makefile.am
   trunk/birnet/birnettests.h
   trunk/birnet/birnetutilsxx.cc
   trunk/birnet/birnetutilsxx.hh
   trunk/birnet/tests/infotest.cc
Log:
Fri Oct  6 18:53:30 2006  Tim Janik  <timj gtk org>

        * birnet.hh: renamed from birnet.h.

        * tests/ring.cc:
        * birnetring.[hc]: removed, moved to sfi/ as SfiRing.

        * birnetutilsxx.hh, birnetutilsxx.cc: hide implementation of ref_diag().

        * birnetutils.hh, birnetutils.cc: renamed and ported to C++ from
        birnetutils.h and birnetutils.c. changed callers.

        * birnetthread.c: ported from BirnetRing to GSList.

        * birnet-zintern.cc: C++ fixes. changed callers.

        * birnettests.h: removed C function definitions.

        * birnetmsg.hh, birnetmsg.cc: implement messaging API akeleton for C++.

        * birnetmsg.[hc]: removed. (implementation moved to Sfi)




Modified: trunk/birnet/ChangeLog
===================================================================
--- trunk/birnet/ChangeLog	2006-10-05 15:52:43 UTC (rev 3935)
+++ trunk/birnet/ChangeLog	2006-10-06 16:54:11 UTC (rev 3936)
@@ -1,10 +1,25 @@
-Tue Oct  3 17:26:50 2006  Tim Janik  <timj gtk org>
+Fri Oct  6 18:53:30 2006  Tim Janik  <timj gtk org>
 
+	* birnet.hh: renamed from birnet.h.
+
 	* tests/ring.cc:
 	* birnetring.[hc]: removed, moved to sfi/ as SfiRing.
 
+	* birnetutilsxx.hh, birnetutilsxx.cc: hide implementation of ref_diag().
+
+	* birnetutils.hh, birnetutils.cc: renamed and ported to C++ from
+	birnetutils.h and birnetutils.c. changed callers.
+
 	* birnetthread.c: ported from BirnetRing to GSList.
 
+	* birnet-zintern.cc: C++ fixes. changed callers.
+
+	* birnettests.h: removed C function definitions.
+
+	* birnetmsg.hh, birnetmsg.cc: implement messaging API akeleton for C++.
+
+	* birnetmsg.[hc]: removed. (implementation moved to Sfi)
+
 Sun Oct  1 13:31:47 2006  Tim Janik  <timj gtk org>
 
 	* birnetutilsxx.hh: added Deletable docs.

Modified: trunk/birnet/Makefile.am
===================================================================
--- trunk/birnet/Makefile.am	2006-10-05 15:52:43 UTC (rev 3935)
+++ trunk/birnet/Makefile.am	2006-10-06 16:54:11 UTC (rev 3936)
@@ -9,25 +9,25 @@
 GLIB_MKENUMS    = glib-mkenums
 
 birnet_headers = $(strip 		\
-	birnet.h			\
+	birnet.hh			\
 	birnetcore.h			\
 	birnetcpu.h			\
-	birnetmsg.h			\
+	birnetmsg.hh			\
 	birnetsignal.hh                 \
 	birnettests.h			\
 	birnetthread.h			\
 	birnetthreadxx.hh		\
-	birnetutils.h			\
+	birnetutils.hh			\
 	birnetutilsxx.hh		\
 )
 birnet_sources = $(strip 		\
 	birnetcore.c			\
 	birnetcpu.c			\
-	birnetmsg.c			\
+	birnetmsg.cc			\
 	birnetsignal.cc                 \
 	birnetthread.c			\
 	birnetthreadxx.cc		\
-	birnetutils.c			\
+	birnetutils.cc			\
 	birnetutilsxx.cc		\
 )
 birnet_private_headers = $(strip 	\
@@ -85,6 +85,15 @@
 	&& echo "#define BIRNET_BINARY_AGE		(@BIRNET_BINARY_AGE@)"			>> xgen-$(@F) \
 	&& echo "#define BIRNET_INTERFACE_AGE		(@BIRNET_INTERFACE_AGE@)"		>> xgen-$(@F) \
 	&& echo ""										>> xgen-$(@F) \
+	&& echo "/* log domain */"								>> xgen-$(@F) \
+	&& echo "#ifndef BIRNET_LOG_DOMAIN"							>> xgen-$(@F) \
+	&& echo "#ifdef  G_LOG_DOMAIN"								>> xgen-$(@F) \
+	&& echo "#define BIRNET_LOG_DOMAIN  G_LOG_DOMAIN"					>> xgen-$(@F) \
+	&& echo "#else"										>> xgen-$(@F) \
+	&& echo "#define BIRNET_LOG_DOMAIN  ((const char*) 0)"					>> xgen-$(@F) \
+	&& echo "#endif"									>> xgen-$(@F) \
+	&& echo "#endif"									>> xgen-$(@F) \
+	&& echo ""										>> xgen-$(@F) \
 	&& echo "/* version checks */"								>> xgen-$(@F) \
 	&& echo "#define BIRNET_CHECK_VERSION(major,minor,micro)	\\"			>> xgen-$(@F) \
 	&& echo "  (BIRNET_MAJOR_VERSION > (major) || \\"					>> xgen-$(@F) \
@@ -120,6 +129,6 @@
 
 noinst_PROGRAMS = birnet-zintern
 progs_ldadd     = libbirnet.o $(BIRNET_LIBS) -lm
-birnet_zintern_SOURCES = birnet-zintern.c dummy.cc
+birnet_zintern_SOURCES = birnet-zintern.cc
 birnet_zintern_LDADD   = $(progs_ldadd)
 birnet_zintern_DEPS    = $(progs_deps)

Deleted: trunk/birnet/birnet-zintern.c
===================================================================
--- trunk/birnet/birnet-zintern.c	2006-10-05 15:52:43 UTC (rev 3935)
+++ trunk/birnet/birnet-zintern.c	2006-10-06 16:54:11 UTC (rev 3936)
@@ -1,234 +0,0 @@
-/* birnet-zintern - small C source compression utility
- * Copyright (C) 2003-2006 Tim Janik
- *
- * 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 <birnet/birnet.h>
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <zlib.h>
-
-static gboolean use_compression = FALSE;
-static gboolean use_base_name = FALSE;
-
-typedef struct {
-  guint    pos;
-  gboolean pad;
-} Config;
-static Config config_init = { 0, 0 };
-
-static inline void
-print_uchar (Config *config,
-	     guint8 d)
-{
-  if (config->pos > 70)
-    {
-      printf ("\"\n  \"");
-      config->pos = 3;
-      config->pad = FALSE;
-    }
-  if (d < 33 || d > 126 || d == '?')
-    {
-      printf ("\\%o", d);
-      config->pos += 1 + 1 + (d > 7) + (d > 63);
-      config->pad = d < 64;
-      return;
-    }
-  if (d == '\\')
-    {
-      printf ("\\\\");
-      config->pos += 2;
-    }
-  else if (d == '"')
-    {
-      printf ("\\\"");
-      config->pos += 2;
-    }
-  else if (config->pad && d >= '0' && d <= '9')
-    {
-      printf ("\"\"");
-      printf ("%c", d);
-      config->pos += 3;
-    }
-  else
-    {
-      printf ("%c", d);
-      config->pos += 1;
-    }
-  config->pad = FALSE;
-  return;
-}
-
-#define to_upper(c)     ((c) >='a' && (c) <='z' ? (c) - 'a' + 'A' : (c))
-#define is_alnum(c)     (((c) >='A' && (c) <='Z') || ((c) >='a' && (c) <='z') || ((c) >='0' && (c) <='9'))
-static gchar*
-to_cupper (const gchar *istring)
-{
-  gchar *string = g_strdup (istring), *s = string;
-  while (*s)
-    {
-      if (is_alnum (*s))
-        *s = to_upper (*s);
-      else
-        *s = '_';
-      s++;
-    }
-  return string;
-}
-
-static void
-gen_zfile (const gchar *name,
-	   const gchar *file)
-{
-  FILE *f = fopen (file, "r");
-  guint8 *data = NULL;
-  guint i, dlen = 0, mlen = 0;
-  Bytef *cdata;
-  uLongf clen;
-  gchar *fname = use_base_name ? g_path_get_basename (file) : g_strdup (file);
-  Config config;
-  if (!f)
-    g_error ("failed to open \"%s\": %s", file, g_strerror (errno));
-  do
-    {
-      if (mlen <= dlen + 1024)
-	{
-	  mlen += 8192;
-	  data = g_realloc (data, mlen);
-	}
-      dlen += fread (data + dlen, 1, mlen - dlen, f);
-    }
-  while (!feof (f));
-
-  if (ferror (f))
-    g_error ("failed to read from \"%s\": %s", file, g_strerror (errno));
-
-  if (use_compression)
-    {
-      int result;
-      gchar *err;
-      clen = dlen + dlen / 100 + 64;
-      cdata = g_malloc (clen);
-      result = compress2 (cdata, &clen, data, dlen, Z_BEST_COMPRESSION);
-      switch (result)
-	{
-	case Z_OK:
-	  err = NULL;
-	  break;
-	case Z_MEM_ERROR:
-	  err = "out of memory";
-	  break;
-	case Z_BUF_ERROR:
-	  err = "insufficient buffer size";
-	  break;
-	default:
-	  err = "unknown error";
-	  break;
-	}
-      if (err)
-	g_error ("while compressing \"%s\": %s", file, err);
-    }
-  else
-    {
-      clen = dlen;
-      cdata = data;
-    }
-
-  g_print ("/* birnet-zintern file dump of %s */\n", file);
-
-  config = config_init;
-  printf ("#define %s_NAME \"", to_cupper (name));
-  for (i = 0; fname[i]; i++)
-    print_uchar (&config, fname[i]);
-  printf ("\"\n");
-
-  printf ("#define %s_SIZE (%u)\n", to_cupper (name), dlen);
-
-  config = config_init;
-  printf ("static const unsigned char %s_DATA[%lu + 1] =\n", to_cupper (name), clen);
-  printf ("( \"");
-  for (i = 0; i < clen; i++)
-    print_uchar (&config, cdata[i]);
-  printf ("\");\n");
-
-  fclose (f);
-  g_free (fname);
-  g_free (data);
-  if (cdata != data)
-    g_free (cdata);
-}
-
-static gint
-help (gchar *arg)
-{
-  g_printerr ("usage: birnet-zintern [-h] [-b] [-z] [[name file]...]\n");
-  g_printerr ("  -h  Print usage information\n");
-  g_printerr ("  -b  Strip directories from file names\n");
-  g_printerr ("  -z  Compress data blocks with libz\n");
-  g_printerr ("Parse (name, file) pairs and generate C source\n");
-  g_printerr ("containing inlined data blocks of the files given.\n");
-  return arg != NULL;
-}
-
-int
-main (gint   argc,
-      gchar *argv[])
-{
-  GSList *plist = NULL;
-  guint i;
-
-  BirnetInitValue ivalues[] = {
-    { "stand-alone", "true" },
-    { NULL }
-  };
-  birnet_init_extended (&argc, &argv, NULL, ivalues);
-
-  for (i = 1; i < argc; i++)
-    {
-      if (strcmp ("-z", argv[i]) == 0)
-	{
-	  use_compression = TRUE;
-	}
-      else if (strcmp ("-b", argv[i]) == 0)
-	{
-	  use_base_name = TRUE;
-	}
-      else if (strcmp ("-h", argv[i]) == 0)
-	{
-	  return help (NULL);
-	}
-      else
-	plist = g_slist_append (plist, argv[i]);
-    }
-  
-  if (argc <= 1)
-    return help (NULL);
-
-  while (plist && plist->next)
-    {
-      const gchar *file, *name = plist->data;
-      GSList *tmp = plist;
-      plist = tmp->next;
-      g_slist_free_1 (tmp);
-      file = plist->data;
-      tmp = plist;
-      plist = tmp->next;
-      g_slist_free_1 (tmp);
-      gen_zfile (name, file);
-    }
-
-  return 0;
-}

Copied: trunk/birnet/birnet-zintern.cc (from rev 3931, trunk/birnet/birnet-zintern.c)
===================================================================
--- trunk/birnet/birnet-zintern.c	2006-10-03 17:04:26 UTC (rev 3931)
+++ trunk/birnet/birnet-zintern.cc	2006-10-06 16:54:11 UTC (rev 3936)
@@ -0,0 +1,233 @@
+/* birnet-zintern - small C source compression utility
+ * Copyright (C) 2003-2006 Tim Janik
+ *
+ * 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 <birnet/birnet.hh>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <zlib.h>
+
+static gboolean use_compression = FALSE;
+static gboolean use_base_name = FALSE;
+
+typedef struct {
+  guint    pos;
+  gboolean pad;
+} Config;
+static Config config_init = { 0, 0 };
+
+static inline void
+print_uchar (Config *config,
+	     guint8 d)
+{
+  if (config->pos > 70)
+    {
+      printf ("\"\n  \"");
+      config->pos = 3;
+      config->pad = FALSE;
+    }
+  if (d < 33 || d > 126 || d == '?')
+    {
+      printf ("\\%o", d);
+      config->pos += 1 + 1 + (d > 7) + (d > 63);
+      config->pad = d < 64;
+      return;
+    }
+  if (d == '\\')
+    {
+      printf ("\\\\");
+      config->pos += 2;
+    }
+  else if (d == '"')
+    {
+      printf ("\\\"");
+      config->pos += 2;
+    }
+  else if (config->pad && d >= '0' && d <= '9')
+    {
+      printf ("\"\"");
+      printf ("%c", d);
+      config->pos += 3;
+    }
+  else
+    {
+      printf ("%c", d);
+      config->pos += 1;
+    }
+  config->pad = FALSE;
+  return;
+}
+
+#define to_upper(c)     ((c) >='a' && (c) <='z' ? (c) - 'a' + 'A' : (c))
+#define is_alnum(c)     (((c) >='A' && (c) <='Z') || ((c) >='a' && (c) <='z') || ((c) >='0' && (c) <='9'))
+static gchar*
+to_cupper (const gchar *istring)
+{
+  gchar *string = g_strdup (istring), *s = string;
+  while (*s)
+    {
+      if (is_alnum (*s))
+        *s = to_upper (*s);
+      else
+        *s = '_';
+      s++;
+    }
+  return string;
+}
+
+static void
+gen_zfile (const gchar *name,
+	   const gchar *file)
+{
+  FILE *f = fopen (file, "r");
+  guint8 *data = NULL;
+  guint i, dlen = 0, mlen = 0;
+  Bytef *cdata;
+  uLongf clen;
+  gchar *fname = use_base_name ? g_path_get_basename (file) : g_strdup (file);
+  Config config;
+  if (!f)
+    g_error ("failed to open \"%s\": %s", file, g_strerror (errno));
+  do
+    {
+      if (mlen <= dlen + 1024)
+	{
+	  mlen += 8192;
+	  data = g_renew (uint8, data, mlen);
+	}
+      dlen += fread (data + dlen, 1, mlen - dlen, f);
+    }
+  while (!feof (f));
+
+  if (ferror (f))
+    g_error ("failed to read from \"%s\": %s", file, g_strerror (errno));
+
+  if (use_compression)
+    {
+      int result;
+      const char *err;
+      clen = dlen + dlen / 100 + 64;
+      cdata = g_new (uint8, clen);
+      result = compress2 (cdata, &clen, data, dlen, Z_BEST_COMPRESSION);
+      switch (result)
+	{
+	case Z_OK:
+	  err = NULL;
+	  break;
+	case Z_MEM_ERROR:
+	  err = "out of memory";
+	  break;
+	case Z_BUF_ERROR:
+	  err = "insufficient buffer size";
+	  break;
+	default:
+	  err = "unknown error";
+	  break;
+	}
+      if (err)
+	g_error ("while compressing \"%s\": %s", file, err);
+    }
+  else
+    {
+      clen = dlen;
+      cdata = data;
+    }
+
+  g_print ("/* birnet-zintern file dump of %s */\n", file);
+
+  config = config_init;
+  printf ("#define %s_NAME \"", to_cupper (name));
+  for (i = 0; fname[i]; i++)
+    print_uchar (&config, fname[i]);
+  printf ("\"\n");
+
+  printf ("#define %s_SIZE (%u)\n", to_cupper (name), dlen);
+
+  config = config_init;
+  printf ("static const unsigned char %s_DATA[%lu + 1] =\n", to_cupper (name), clen);
+  printf ("( \"");
+  for (i = 0; i < clen; i++)
+    print_uchar (&config, cdata[i]);
+  printf ("\");\n");
+
+  fclose (f);
+  g_free (fname);
+  g_free (data);
+  if (cdata != data)
+    g_free (cdata);
+}
+
+static gint
+help (gchar *arg)
+{
+  g_printerr ("usage: birnet-zintern [-h] [-b] [-z] [[name file]...]\n");
+  g_printerr ("  -h  Print usage information\n");
+  g_printerr ("  -b  Strip directories from file names\n");
+  g_printerr ("  -z  Compress data blocks with libz\n");
+  g_printerr ("Parse (name, file) pairs and generate C source\n");
+  g_printerr ("containing inlined data blocks of the files given.\n");
+  return arg != NULL;
+}
+
+int
+main (gint   argc,
+      gchar *argv[])
+{
+  GSList *plist = NULL;
+
+  BirnetInitValue ivalues[] = {
+    { "stand-alone", "true" },
+    { NULL }
+  };
+  birnet_init_extended (&argc, &argv, NULL, ivalues);
+
+  for (int i = 1; i < argc; i++)
+    {
+      if (strcmp ("-z", argv[i]) == 0)
+	{
+	  use_compression = TRUE;
+	}
+      else if (strcmp ("-b", argv[i]) == 0)
+	{
+	  use_base_name = TRUE;
+	}
+      else if (strcmp ("-h", argv[i]) == 0)
+	{
+	  return help (NULL);
+	}
+      else
+	plist = g_slist_append (plist, argv[i]);
+    }
+  
+  if (argc <= 1)
+    return help (NULL);
+
+  while (plist && plist->next)
+    {
+      const char *name = (char*) plist->data;
+      GSList *tmp = plist;
+      plist = tmp->next;
+      g_slist_free_1 (tmp);
+      const char *file = (char*) plist->data;
+      tmp = plist;
+      plist = tmp->next;
+      g_slist_free_1 (tmp);
+      gen_zfile (name, file);
+    }
+
+  return 0;
+}

Deleted: trunk/birnet/birnet.h
===================================================================
--- trunk/birnet/birnet.h	2006-10-05 15:52:43 UTC (rev 3935)
+++ trunk/birnet/birnet.h	2006-10-06 16:54:11 UTC (rev 3936)
@@ -1,37 +0,0 @@
-/* Birnet
- * Copyright (C) 2006 Tim Janik
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General
- * Public License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-#ifndef __BIRNET_H__
-#define __BIRNET_H__
-
-#include <birnet/birnetconfig.h>
-#include <birnet/birnetcore.h>
-#include <birnet/birnetcpu.h>
-
-#include <birnet/birnetutils.h>
-#include <birnet/birnetmsg.h>
-#include <birnet/birnetthread.h>
-
-#ifdef	__cplusplus
-#include <birnet/birnetutilsxx.hh>
-#include <birnet/birnetsignal.hh>
-#include <birnet/birnetthreadxx.hh>
-#endif	/* __cplusplus */
-
-#endif /* __BIRNET_H__ */
-/* vim:set ts=8 sts=2 sw=2: */

Copied: trunk/birnet/birnet.hh (from rev 3931, trunk/birnet/birnet.h)
===================================================================
--- trunk/birnet/birnet.h	2006-10-03 17:04:26 UTC (rev 3931)
+++ trunk/birnet/birnet.hh	2006-10-06 16:54:11 UTC (rev 3936)
@@ -0,0 +1,35 @@
+/* Birnet
+ * Copyright (C) 2006 Tim Janik
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef __BIRNET_H__
+#define __BIRNET_H__
+
+#include <birnet/birnetconfig.h>
+#include <birnet/birnetcore.h>
+#include <birnet/birnetcpu.h>
+
+#include <birnet/birnetutils.hh>
+#include <birnet/birnetmsg.hh>
+#include <birnet/birnetthread.h>
+
+#include <birnet/birnetutilsxx.hh>
+#include <birnet/birnetsignal.hh>
+#include <birnet/birnetthreadxx.hh>
+
+#endif /* __BIRNET_H__ */
+/* vim:set ts=8 sts=2 sw=2: */

Deleted: trunk/birnet/birnetmsg.c
===================================================================
--- trunk/birnet/birnetmsg.c	2006-10-05 15:52:43 UTC (rev 3935)
+++ trunk/birnet/birnetmsg.c	2006-10-06 16:54:11 UTC (rev 3936)
@@ -1,821 +0,0 @@
-/* BirnetMsg
- * Copyright (C) 2002-2006 Tim Janik
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General
- * Public License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-#include "birnetmsg.h"
-#include "birnetthread.h"
-#include <unistd.h>
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <syslog.h>
-
-#ifndef _ // FIXME
-#define _(x) x
-#endif
-
-typedef struct {
-  gchar            *ident;
-  gchar            *label;
-  BirnetMsgType     default_type;
-  BirnetMsgLogFlags log_flags : 16;
-  guint             disabled : 1;
-} MsgType;
-
-
-/* --- variables --- */
-static BirnetMutex       logging_mutex;
-static GQuark            quark_log_handler = 0;
-static GQuark            quark_msg_bits = 0;
-static guint             n_msg_types = 0;
-static MsgType          *msg_types = NULL;
-guint8 * volatile        birnet_msg_flags = NULL;
-volatile guint           birnet_msg_flags_max = 0;
-static guint             stdlog_syslog_priority = 0; // LOG_USER | LOG_INFO;
-static bool              stdlog_to_stderr = TRUE;
-static FILE             *stdlog_file = NULL;
-
-/* --- prototypoes --- */
-static void     birnet_log_msg_process     (const BirnetMessage *msgp);
-static void     birnet_msg_type_set        (BirnetMsgType     mtype,
-                                            BirnetMsgLogFlags log_flags,
-                                            bool           enabled);
-
-/* --- functions --- */
-static void
-birnet_msg_type_init_internals (void)
-{
-  static volatile guint initialized = FALSE;
-  if (initialized || !birnet_atomic_uint_compare_and_swap (&initialized, FALSE, TRUE))
-    return;
-  guint mtype;
-  /* BIRNET_MSG_NONE (always disabled) */
-  mtype = birnet_msg_type_register ("none", 0, NULL);
-  g_assert (mtype == BIRNET_MSG_NONE);
-  birnet_msg_type_set (BIRNET_MSG_NONE, 0, FALSE);
-  /* BIRNET_MSG_FATAL (always enabled) */
-  mtype = birnet_msg_type_register ("fatal", 1, _("Fatal Error"));
-  g_assert (mtype == BIRNET_MSG_FATAL);
-  birnet_msg_type_set (BIRNET_MSG_FATAL, BIRNET_MSG_TO_STDERR | BIRNET_MSG_TO_STDLOG | BIRNET_MSG_TO_HANDLER, TRUE);
-  /* BIRNET_MSG_ERROR (enabled) */
-  mtype = birnet_msg_type_register ("error", 1, _("Error"));
-  g_assert (mtype == BIRNET_MSG_ERROR);
-  birnet_msg_type_set (BIRNET_MSG_ERROR, BIRNET_MSG_TO_STDERR | BIRNET_MSG_TO_STDLOG | BIRNET_MSG_TO_HANDLER, TRUE);
-  /* BIRNET_MSG_WARNING (enabled) */
-  mtype = birnet_msg_type_register ("warning", 1, _("Warning"));
-  g_assert (mtype == BIRNET_MSG_WARNING);
-  birnet_msg_type_set (BIRNET_MSG_WARNING, BIRNET_MSG_TO_STDERR | BIRNET_MSG_TO_STDLOG | BIRNET_MSG_TO_HANDLER, TRUE);
-  /* BIRNET_MSG_SCRIPT (enabled) */
-  mtype = birnet_msg_type_register ("script", 1, _("Script"));
-  g_assert (mtype == BIRNET_MSG_SCRIPT);
-  birnet_msg_type_set (BIRNET_MSG_SCRIPT, BIRNET_MSG_TO_STDERR | BIRNET_MSG_TO_STDLOG | BIRNET_MSG_TO_HANDLER, TRUE);
-  /* BIRNET_MSG_INFO (enabled) */
-  mtype = birnet_msg_type_register ("info", 1, _("Information"));
-  g_assert (mtype == BIRNET_MSG_INFO);
-  birnet_msg_type_set (BIRNET_MSG_INFO, BIRNET_MSG_TO_STDERR | BIRNET_MSG_TO_STDLOG | BIRNET_MSG_TO_HANDLER, TRUE);
-  /* BIRNET_MSG_DIAG (enabled) */
-  mtype = birnet_msg_type_register ("diag", 1, _("Diagnostic"));
-  g_assert (mtype == BIRNET_MSG_DIAG);
-  birnet_msg_type_set (BIRNET_MSG_DIAG, BIRNET_MSG_TO_STDERR | BIRNET_MSG_TO_STDLOG, TRUE);
-  /* BIRNET_MSG_DEBUG (disabled) */
-  mtype = birnet_msg_type_register ("debug", 0, "Debug");
-  g_assert (mtype == BIRNET_MSG_DEBUG);
-  birnet_msg_type_set (BIRNET_MSG_DEBUG, BIRNET_MSG_TO_STDERR, FALSE);
-}
-
-void
-_birnet_init_logging (void)
-{
-  g_assert (quark_log_handler == 0);
-  quark_log_handler = g_quark_from_static_string ("BirnetMsgHandler");
-  quark_msg_bits = g_quark_from_static_string ("BirnetMsgBit-threadlist");
-  birnet_mutex_init (&logging_mutex);
-  birnet_msg_type_init_internals();
-}
-
-static inline void
-msg_type_set_intern (BirnetMsgType     mtype,
-                     BirnetMsgLogFlags log_flags,
-                     bool              enabled,
-                     bool              uncouple_default)
-{
-  if (mtype < n_msg_types)
-    {
-      msg_types[mtype].log_flags = log_flags;
-      msg_types[mtype].disabled = !enabled;
-      enabled = msg_types[mtype].log_flags && !msg_types[mtype].disabled;
-      if (enabled)
-        birnet_msg_flags[mtype / 8] |= 1 << mtype % 8;
-      else
-        birnet_msg_flags[mtype / 8] &= ~(1 << mtype % 8);
-      if (uncouple_default)
-        msg_types[mtype].default_type = mtype;
-    }
-}
-
-static void
-birnet_msg_type_set (BirnetMsgType     mtype,
-                     BirnetMsgLogFlags log_flags,
-                     bool              enabled)
-{
-  msg_type_set_intern (mtype, log_flags, enabled, TRUE);
-  guint i;
-  for (i = mtype + 1; i < n_msg_types; i++)
-    if (msg_types[i].default_type == mtype)
-      msg_type_set_intern (mtype, log_flags, enabled, FALSE);
-}
-
-/**
- * @param ident	message identifier
- * @param default_ouput	an existing BirnetMsgType or FALSE or TRUE
- * @param label	a translated version of @a ident
- * @return		message type id
- *
- * Register a new message type with identifier @a ident and user digestible
- * name @a label. If this function is called multiple times with the same
- * identifier, the type id acquired by the first call will be returned
- * and the other arguments are ignored.
- * As long as the new message type isn't configured individually via
- * birnet_msg_enable(), birnet_msg_allow() or their complements, it shares
- * the configuration of @a default_ouput. If FALSE or TRUE is passed as
- * @a default_ouput, this corresponds to BIRNET_MSG_NONE or BIRNET_MSG_FATAL
- * respectively which are unconfigrable and always have their output
- * disabled or enabled respectively.
- * As an exception to the rest of the message API, this function may be
- * called before birnet_init(). However note, that MT-safety is only ensured
- * for calls occouring after birnet_init().
- * This function is MT-safe and may be called from any thread.
- */
-BirnetMsgType
-birnet_msg_type_register (const gchar   *ident,
-                          BirnetMsgType  default_ouput, /* FALSE, TRUE, BIRNET_MSG_* */
-                          const gchar   *label)
-{
-  /* ensure standard types are registered */
-  birnet_msg_type_init_internals();
-  /* check arguments */
-  g_return_val_if_fail (ident != NULL, 0);
-  if (default_ouput >= n_msg_types)
-    default_ouput = 0;
-  /* support concurrency after _birnet_init_logging() */
-  bool     need_unlock = FALSE;
-  if (quark_log_handler)
-    {
-      birnet_mutex_lock (&logging_mutex);
-      need_unlock = TRUE;
-    }
-  /* allow duplicate registration */
-  guint i;
-  for (i = BIRNET_MSG_LAST; i < n_msg_types; i++)
-    if (strcmp (ident, msg_types[i].ident) == 0)
-      {
-        /* found duplicate */
-        if (need_unlock)
-          birnet_mutex_unlock (&logging_mutex);
-        return i;
-      }
-  /* add new message type */
-  guint mtype = n_msg_types++;
-  msg_types = g_renew (MsgType, msg_types, n_msg_types);
-  memset (&msg_types[mtype], 0, sizeof (msg_types[mtype]));
-  guint old_flags_size = (mtype + 7) / 8;
-  guint new_flags_size = (n_msg_types + 7) / 8;
-  if (old_flags_size < new_flags_size)
-    {
-      guint8 *msg_flags = g_new (guint8, new_flags_size);
-      memcpy (msg_flags, (guint8*) birnet_msg_flags, sizeof (msg_flags[0]) * old_flags_size);
-      msg_flags[new_flags_size - 1] = 0;
-      guint8 *old_msg_flags = birnet_msg_flags;
-      /* we are holding a lock in the multi-threaded case so no need for compare_and_swap */
-      typedef guint8* X;
-      birnet_atomic_pointer_set ((void*) &birnet_msg_flags, msg_flags);
-      // FIXME: birnet_msg_flags should be registered as hazard pointer so we don't g_free() while other threads read old_msg_flags[*]
-      g_free (old_msg_flags);
-    }
-  msg_types[mtype].ident = g_strdup (ident);
-  msg_types[mtype].label = g_strdup (label);
-  birnet_msg_type_set (mtype, msg_types[default_ouput].log_flags, !msg_types[default_ouput].disabled);
-  msg_types[mtype].default_type = default_ouput;
-  birnet_atomic_uint_set (&birnet_msg_flags_max, mtype); /* only ever grows */
-  /* out of here */
-  if (need_unlock)
-    birnet_mutex_unlock (&logging_mutex);
-  return mtype;
-}
-
-static void
-key_list_change (const char *string,
-                 bool        flag_value)
-{
-  guint i, n;
-  /* ensure all keywords are enclosed in ':' */
-  char *s = g_strconcat (":", string, ":", NULL);
-  /* allow ',' seperation and collapse spaces */
-  for (i = 0, n = 0; s[i]; i++)
-    if (s[i] == ',')
-      s[n++] = ':';
-    else if (s[i] != ' ' && s[i] != '\t' && s[i] != '\n' && s[i] != '\r')
-      s[n++] = s[i];
-  s[n] = 0;
-  /* handle :all: special case */
-  if (strstr (s, ":all:"))
-    {
-      g_free (s);
-      for (i = BIRNET_MSG_DEBUG; i < n_msg_types; i++)
-        birnet_msg_type_set (i, msg_types[i].log_flags, flag_value);
-      return;
-    }
-  
-  /* walk all kyes */
-  char *k = s + 1;
-  char *p = strchr (k, ':');
-  while (p)
-    {
-      if (k < p)
-	{
-	  *p = 0;
-          for (i = BIRNET_MSG_DEBUG; i < n_msg_types; i++)
-            if (strcmp (k, msg_types[i].ident) == 0)
-              break;
-          if (i < n_msg_types)
-            birnet_msg_type_set (i, msg_types[i].log_flags, flag_value);
-	}
-      k = p + 1;
-      p = strchr (k, ':');
-    }
-  g_free (s);
-}
-
-void
-birnet_msg_allow (const char *key)
-{
-  birnet_mutex_lock (&logging_mutex);
-  if (key)
-    key_list_change (key, TRUE);
-  birnet_mutex_unlock (&logging_mutex);
-  
-#if 0
-  guint i;
-  for (i = 0; i < n_msg_types; i++)
-    g_printerr ("% 2d) %s: disabled=%d log_flags=0x%x label=%s cache=%d\n", i,
-                msg_types[i].ident, msg_types[i].disabled,
-                msg_types[i].log_flags, msg_types[i].label,
-                birnet_msg_check (i));
-#endif
-}
-
-void
-birnet_msg_deny (const char *key)
-{
-  birnet_mutex_lock (&logging_mutex);
-  if (key)
-    key_list_change (key, FALSE);
-  birnet_mutex_unlock (&logging_mutex);
-}
-
-void
-birnet_msg_enable (BirnetMsgType mtype)
-{
-  birnet_mutex_lock (&logging_mutex);
-  if (mtype > 1 && mtype < n_msg_types)
-    birnet_msg_type_set (mtype, msg_types[mtype].log_flags, TRUE);
-  birnet_mutex_unlock (&logging_mutex);
-}
-
-void
-birnet_msg_disable (BirnetMsgType mtype)
-{
-  birnet_mutex_lock (&logging_mutex);
-  if (mtype > 1 && mtype < n_msg_types)
-    birnet_msg_type_set (mtype, msg_types[mtype].log_flags, FALSE);
-  birnet_mutex_unlock (&logging_mutex);
-}
-
-void
-birnet_msg_type_configure (BirnetMsgType        mtype,
-                           BirnetMsgLogFlags    channel_mask,
-                           const gchar         *dummy_filename)
-{
-  birnet_mutex_lock (&logging_mutex);
-  if (mtype > 1 && mtype < n_msg_types)
-    birnet_msg_type_set (mtype, channel_mask, !msg_types[mtype].disabled);
-  birnet_mutex_unlock (&logging_mutex);
-}
-
-void
-birnet_msg_configure_stdlog (bool              stdlog_to_stderr_bool,
-                             const char       *stdlog_filename,
-                             guint             syslog_priority) /* if != 0, stdlog to syslog */
-{
-  birnet_mutex_lock (&logging_mutex);
-  stdlog_to_stderr = stdlog_to_stderr_bool != 0;
-  stdlog_syslog_priority = syslog_priority;
-  if (stdlog_file && stdlog_file != stdout)
-    fclose (stdlog_file);
-  stdlog_file = NULL;
-  if (stdlog_filename && strcmp (stdlog_filename, "-") == 0)
-    stdlog_file = stdout;
-  else if (stdlog_filename)
-    stdlog_file = fopen (stdlog_filename, "a");
-  birnet_mutex_unlock (&logging_mutex);
-}
-
-/**
- * @param type	message type, e.g. BIRNET_MSG_ERROR, BIRNET_MSG_WARNING, BIRNET_MSG_INFO, etc...
- * @return		message identifier
- *
- * Retrive the string identifying the message type @a type. For invalid
- * (non registered) message types, NULL is returned.
- * This function is MT-safe and may be called from any thread.
- */
-const gchar*
-birnet_msg_type_ident (BirnetMsgType mtype)
-{
-  const gchar *string = NULL;
-  birnet_mutex_lock (&logging_mutex);
-  if (mtype >= 0 && mtype < n_msg_types)
-    string = msg_types[mtype].ident;
-  birnet_mutex_unlock (&logging_mutex);
-  return string;
-}
-
-/**
- * @param type	message type, e.g. BIRNET_MSG_ERROR, BIRNET_MSG_WARNING, BIRNET_MSG_INFO, etc...
- * @return		translated message identifier or NULL
- *
- * Retrive the label identifying the message type @a type. Usually,
- * this is a translated version of birnet_msg_type_ident() or NULL
- * if non was registered with the message type.
- * This function is MT-safe and may be called from any thread.
- */
-const gchar*
-birnet_msg_type_label (BirnetMsgType mtype)
-{
-  const gchar *string = NULL;
-  birnet_mutex_lock (&logging_mutex);
-  if (mtype >= 0 && mtype < n_msg_types)
-    string = msg_types[mtype].label;
-  birnet_mutex_unlock (&logging_mutex);
-  return string;
-}
-
-/**
- * @param ident	message identifier, e.g. "error", "warning", "info", etc...
- * @return		corresponding BirnetMsgType or 0
- *
- * Find the message type correspondign to @a ident. If no message
- * type was found 0 is returned (note that 0 is also the value of
- * BIRNET_MSG_NONE).
- * This function is MT-safe and may be called from any thread.
- */
-BirnetMsgType
-birnet_msg_type_lookup (const gchar *ident)
-{
-  g_return_val_if_fail (ident != NULL, 0);
-  guint i;
-  birnet_mutex_lock (&logging_mutex);
-  for (i = 0; i < n_msg_types; i++)
-    if (strcmp (ident, msg_types[i].ident) == 0)
-      break;
-  if (i >= n_msg_types)
-    i = 0;
-  birnet_mutex_unlock (&logging_mutex);
-  return i;
-}
-
-/**
- * @param handler	a valid BirnetMsgHandler or NULL
- *
- * Set the handler function for messages logged in the current
- * thread. If NULL is specified as handler, the standard handler
- * will be used. For handler implementations that require an extra
- * data argument, see birnet_thread_set_qdata().
- * This function is MT-safe and may be called from any thread.
- */
-void
-birnet_msg_set_thread_handler (BirnetMsgHandler handler)
-{
-  birnet_thread_set_qdata (quark_log_handler, handler);
-}
-
-/**
- * @param message	a valid BirnetMessage
- *
- * This is the standard message handler, it produces @a message
- * in a prominent way on stderr.
- * This function is MT-safe and may be called from any thread.
- */
-void
-birnet_msg_default_handler (const BirnetMessage *msg)
-{
-  const gchar *level_name = birnet_msg_type_label (msg->type);
-  g_printerr ("********************************************************************************\n");
-  if (msg->log_domain)
-    g_printerr ("** %s-%s: %s\n", msg->log_domain, level_name, msg->title ? msg->title : "");
-  else
-    g_printerr ("** %s: %s\n", level_name, msg->title ? msg->title : "");
-  if (msg->primary)
-    g_printerr ("** %s\n", msg->primary);
-  if (msg->secondary)
-    {
-      GString *gstring = g_string_new (msg->secondary);
-      guint i;
-      for (i = 0; i < gstring->len; i++)
-        if (gstring->str[i] == '\n')
-          g_string_insert (gstring, i + 1, "**   ");
-      g_printerr ("**   %s\n", gstring->str);
-      g_string_free (gstring, TRUE);
-    }
-  if (msg->details)
-    {
-      GString *gstring = g_string_new (msg->details);
-      guint i;
-      for (i = 0; i < gstring->len; i++)
-        if (gstring->str[i] == '\n')
-          g_string_insert (gstring, i + 1, "** > ");
-      g_printerr ("** > %s\n", gstring->str);
-      g_string_free (gstring, TRUE);
-    }
-  if (msg->config_check)
-    g_printerr ("** [X] %s\n", msg->config_check);
-  g_printerr ("********************************************************************************\n");
-}
-
-typedef struct LogBit LogBit;
-struct LogBit {
-  BirnetMsgBit bit;
-  void    (*data_free) (void*);
-  LogBit   *next;
-};
-
-static void
-free_lbits (LogBit *first)
-{
-  while (first)
-    {
-      LogBit *current = first;
-      first = current->next;
-      if (current->data_free)
-        current->data_free (current->bit.data);
-      g_free (current);
-    }
-}
-
-/**
- * @param log_domain    log domain
- * @param level         one of BIRNET_MSG_ERROR, BIRNET_MSG_WARNING, BIRNET_MSG_INFO, BIRNET_MSG_DIAG or BIRNET_MSG_DEBUG
- * @param format        printf-like format
- * @param ...           printf-like arguments
- *
- * Log a message through BIRNETs logging mechanism. The current
- * value of errno is preserved around calls to this function.
- * Usually this function isn't used directly, but through one
- * of birnet_debug(), birnet_diag(), birnet_info(), birnet_warn() or birnet_error().
- * The @a log_domain indicates the calling module and relates to
- * G_LOG_DOMAIN as used by g_log().
- * This function is MT-safe and may be called from any thread.
- */
-void
-birnet_msg_log_printf (const char       *log_domain,
-                       BirnetMsgType     mtype,
-                       const char       *format,
-                       ...)
-{
-  gint saved_errno = errno;
-  /* construct message */
-  BirnetMessage msg = { 0, };
-  msg.type = mtype;
-  msg.log_domain = (char*) log_domain;
-  va_list args;
-  va_start (args, format);
-  msg.primary = g_strdup_vprintf (format, args);
-  va_end (args);
-  msg.config_check = NULL;
-  /* handle message */
-  LogBit *lbit_list = birnet_thread_steal_qdata (quark_msg_bits);
-  birnet_log_msg_process (&msg);
-  g_free (msg.primary);
-  free_lbits (lbit_list); /* purge thread local msg bit list */
-  errno = saved_errno;
-}
-
-/**
- * @param log_domain    log domain
- * @param mtype         one of BIRNET_MSG_ERROR, BIRNET_MSG_WARNING, BIRNET_MSG_INFO, BIRNET_MSG_DIAG
- * @param lbit1         msg bit
- * @param lbit2         msg bit
- * @param ...           list of more msg bits, NULL terminated
- *
- * Log a message through BIRNETs logging mechanism. The current value of errno
- * is preserved around calls to this function. Usually this function isn't
- * used directly, but birnet_log_msg() is called instead which does not require
- * NULL termination of its argument list and automates the @a log_domain argument.
- * The @a log_domain indicates the calling module and relates to G_LOG_DOMAIN
- * as used by g_log().
- * The msg bit arguments passed in form various parts of the log message, the
- * following macro set is provided to construct the parts from printf-style
- * argument lists:
- * - BIRNET_MSG_TITLE(): format message title
- * - BIRNET_MSG_TEXT1(): format primary message (also BIRNET_MSG_PRIMARY())
- * - BIRNET_MSG_TEXT2(): format secondary message, optional (also BIRNET_MSG_SECONDARY())
- * - BIRNET_MSG_TEXT3(): format details of the message, optional (also BIRNET_MSG_DETAIL())
- * - BIRNET_MSG_CHECK(): format configuration check statement to enable/disable log messages of this type.
- * This function is MT-safe and may be called from any thread.
- */
-void
-birnet_msg_log_elist (const char     *log_domain,
-                      BirnetMsgType   mtype,       /* BIRNET_MSG_DEBUG is not really useful here */
-                      BirnetMsgBit   *lbit1,
-                      BirnetMsgBit   *lbit2,
-                      ...)
-{
-  gint saved_errno = errno;
-  guint n = 0;
-  BirnetMsgBit **bits = NULL;
-  /* collect msg bits */
-  if (lbit1)
-    {
-      bits = g_renew (BirnetMsgBit*, bits, n + 1);
-      bits[n++] = lbit1;
-      BirnetMsgBit *lbit = lbit2;
-      va_list args;
-      va_start (args, lbit2);
-      while (lbit)
-        {
-          bits = g_renew (BirnetMsgBit*, bits, n + 1);
-          bits[n++] = lbit;
-          lbit = va_arg (args, BirnetMsgBit*);
-        }
-      va_end (args);
-    }
-  bits = g_renew (BirnetMsgBit*, bits, n + 1);
-  bits[n] = NULL;
-  birnet_msg_log_trampoline (log_domain, mtype, bits, birnet_log_msg_process);
-  g_free (bits);
-  errno = saved_errno;
-}
-
-static inline char*
-log_msg_concat (char       *former,
-                const char *next)
-{
-  if (former && !next)
-    return former;
-  if (!former && next)
-    return g_strdup (next);
-  char *result = g_strconcat (former, "\n", next, NULL);
-  g_free (former);
-  return result;
-}
-
-static inline void
-msg_apply_bit (BirnetMessage *msg,
-               BirnetMsgBit  *lbit)
-{
-  gsize ltype = (gsize) lbit->owner;
-  if (ltype < 256)
-    {
-      switch (ltype)
-        {
-        case '0': msg->title = log_msg_concat (msg->title, lbit->data);               break;
-        case '1': msg->primary = log_msg_concat (msg->primary, lbit->data);           break;
-        case '2': msg->secondary = log_msg_concat (msg->secondary, lbit->data);       break;
-        case '3': msg->details = log_msg_concat (msg->details, lbit->data);           break;
-        case 'c': msg->config_check = log_msg_concat (msg->config_check, lbit->data); break;
-        }
-    }
-  else
-    {
-      guint i = msg->n_msg_bits++;
-      msg->msg_bits = g_renew (BirnetMsgBit*, msg->msg_bits, msg->n_msg_bits);
-      msg->msg_bits[i] = lbit;
-    }
-}
-
-/**
- * @param log_domain	log domain
- * @param mtype	one of BIRNET_MSG_ERROR, BIRNET_MSG_WARNING, BIRNET_MSG_INFO, BIRNET_MSG_DIAG
- * @param lbit1	msg bit
- * @param lbit2	msg bit
- * @param lbitargs	va_list list of more msg bits, NULL terminated
- * @param handler	message handler
- * @param vbitlist	NULL terminated array of msg bits
- *
- * Construct a log message from the arguments given and let @a handler process
- * it. This function performs no logging on its own, it is used internally by
- * birnet_log_msg_elist() to collect arguments and construct a message. All logging
- * functionality has to be implemented by @a handler. Note that all thread-local
- * msg bits are deleted after invokation of this funtcion, so all msg bits
- * created in the current thread are invalid after calling this function.
- * Direct use of this function is not recommended except for implementations
- * of logging mechanisms.
- * This function is MT-safe and may be called from any thread.
- */
-void
-birnet_msg_log_trampoline (const char        *log_domain,
-                           BirnetMsgType      mtype,       /* BIRNET_MSG_DEBUG is not really useful here */
-                           BirnetMsgBit     **lbits,
-                           BirnetMsgHandler   handler)
-{
-  gint saved_errno = errno;
-  /* construct message */
-  BirnetMessage msg = { 0, };
-  msg.type = mtype;
-  msg.log_domain = (char*) log_domain;
-  /* apply msg bits */
-  if (lbits)
-    {
-      guint j;
-      for (j = 0; lbits[j]; j++)
-        msg_apply_bit (&msg, lbits[j]);
-    }
-  /* reset thread local msg bit list */
-  LogBit *lbit_list = birnet_thread_steal_qdata (quark_msg_bits);
-  /* handle message */
-  if (!handler)
-    handler = birnet_log_msg_process;
-  handler (&msg);
-  /* clean up */
-  g_free (msg.title);
-  g_free (msg.primary);
-  g_free (msg.secondary);
-  g_free (msg.details);
-  g_free (msg.config_check);
-  g_free (msg.msg_bits);
-  free_lbits (lbit_list);
-  /* restore errno */
-  errno = saved_errno;
-}
-
-BirnetMsgBit*
-birnet_msg_bit_appoint (gconstpointer   owner,
-                        gpointer        data,
-                        void          (*data_free) (gpointer))
-{
-  gint saved_errno = errno;
-  LogBit *lbit = g_new0 (LogBit, 1);
-  lbit->bit.owner = owner;
-  lbit->bit.data = data;
-  lbit->data_free = data_free;
-  lbit->next = birnet_thread_steal_qdata (quark_msg_bits);
-  birnet_thread_set_qdata_full (quark_msg_bits, lbit, (GDestroyNotify) free_lbits);
-  errno = saved_errno;
-  return &lbit->bit;
-}
-
-BirnetMsgBit*
-birnet_msg_bit_printf (guint8      msg_bit_type,
-                       const char *format,
-                       ...)
-{
-  gint saved_errno = errno;
-  va_list args;
-  va_start (args, format);
-  gchar *string = g_strdup_vprintf (format, args);
-  va_end (args);
-  errno = saved_errno;
-  return birnet_msg_bit_appoint ((void*) (gsize) msg_bit_type, string, g_free);
-}
-
-static const gchar*
-prgname (bool     maystrip)
-{
-  const gchar *pname = g_get_prgname();
-  if (pname && maystrip)
-    {
-      const gchar *p = strrchr (pname, '/');
-      pname = p ? p + 1 : pname;
-    }
-  return pname;
-}
-
-static char*
-log_prefix (const char  *prg_name,
-            guint        pid,
-            const char  *log_domain,
-            const char  *label,
-            const char  *ident)
-{
-  GString *gstring = g_string_new (prg_name);
-  if (pid)
-    g_string_append_printf (gstring, "[%u]", pid);
-  if (gstring->len)
-    g_string_append (gstring, ":");
-  if (log_domain)
-    g_string_append (gstring, log_domain);
-  if (log_domain && label)
-    g_string_append (gstring, "-");
-  if (label)
-    g_string_append (gstring, label);
-  if (ident)
-    {
-      if (log_domain || label)
-        g_string_append_printf (gstring, "(%s)", ident);
-      else
-        g_string_append (gstring, ident);
-    }
-  if (log_domain || label || ident)
-    g_string_append (gstring, ":");
-  /* more components can come here */
-  /* ... */
-  if (gstring->str[gstring->len - 1] == ':') /* strip final ':' */
-    gstring->str[gstring->len - 1] = 0;
-  return g_string_free (gstring, FALSE);
-}
-
-static guint
-birnet_msg_type_actions (BirnetMsgType mtype)
-{
-  guint actions = 0;
-  birnet_mutex_lock (&logging_mutex);
-  if (mtype >= 0 && mtype < n_msg_types &&
-      !msg_types[mtype].disabled)
-    actions = msg_types[mtype].log_flags;
-  birnet_mutex_unlock (&logging_mutex);
-  return actions;
-}
-
-static void
-birnet_log_msg_process (const BirnetMessage *msgp)
-{
-  const BirnetMessage msg = *msgp;
-  /* determine log actions */
-  guint actions = birnet_msg_type_actions (msg.type);
-  const char *ident = birnet_msg_type_ident (msg.type);
-  const char *label = birnet_msg_type_label (msg.type);
-  /* log to syslog */
-  if ((msg.primary || msg.secondary) && stdlog_syslog_priority && (actions & BIRNET_MSG_TO_STDLOG))
-    {
-      char *prefix = log_prefix (NULL, 0, msg.log_domain, NULL, ident);
-      if (msg.title && FALSE) // skip title in syslog
-        syslog (stdlog_syslog_priority, "%s:0: %s\n", prefix, msg.title);
-      if (msg.primary)
-        syslog (stdlog_syslog_priority, "%s:1: %s\n", prefix, msg.primary);
-      if (msg.secondary)
-        syslog (stdlog_syslog_priority, "%s:2: %s\n", prefix, msg.secondary);
-      if (msg.details && FALSE) // skip details in syslog
-        syslog (stdlog_syslog_priority, "%s:3: %s\n", prefix, msg.details);
-      g_free (prefix);
-    }
-  /* log to stderr */
-  bool tostderr = (actions & BIRNET_MSG_TO_STDERR) != 0;
-  tostderr |= (actions & BIRNET_MSG_TO_STDLOG) && stdlog_to_stderr;
-  if ((msg.primary || msg.secondary) && tostderr)
-    {
-      bool   is_debug = msg.type == BIRNET_MSG_DEBUG, is_diag = msg.type == BIRNET_MSG_DIAG;
-      gchar *prefix = log_prefix (prgname (is_debug),                                   /* strip prgname path for debugging */
-                                  birnet_thread_self_pid(),                                /* always print pid */
-                                  is_debug ? NULL : msg.log_domain,                     /* print domain except when debugging */
-                                  is_debug || is_diag ? NULL : label,                   /* print translated message type execpt for debug/diagnosis */
-                                  is_debug ? ident : NULL);                             /* print identifier if debugging */
-      if (msg.title)
-        fprintf (stderr, "%s:0: %s\n", prefix, msg.title);
-      if (msg.primary)
-        fprintf (stderr, "%s:1: %s\n", prefix, msg.primary);
-      if (msg.secondary)
-        fprintf (stderr, "%s:2: %s\n", prefix, msg.secondary);
-      if (msg.details)
-        fprintf (stderr, "%s:3: %s\n", prefix, msg.details);
-      g_free (prefix);
-    }
-  /* log to logfile */
-  if (stdlog_file && (actions & BIRNET_MSG_TO_STDLOG))
-    {
-      char *prefix = log_prefix (prgname (FALSE),                                       /* printf fully qualified program name */
-                                 birnet_thread_self_pid(),                                 /* always print pid */
-                                 msg.log_domain,                                        /* always print log domain */
-                                 NULL,                                                  /* skip translated message type */
-                                 ident);                                                /* print machine readable message type */
-      if (msg.title)
-        fprintf (stdlog_file, "%s:0: %s\n", prefix, msg.title);
-      if (msg.primary)
-        fprintf (stdlog_file, "%s:1: %s\n", prefix, msg.primary);
-      if (msg.secondary)
-        fprintf (stdlog_file, "%s:2: %s\n", prefix, msg.secondary);
-      if (msg.details)
-        fprintf (stdlog_file, "%s:3: %s\n", prefix, msg.details);
-      g_free (prefix);
-    }
-  /* log to log handler */
-  if (actions & BIRNET_MSG_TO_HANDLER)
-    {
-      BirnetMsgHandler log_handler = birnet_thread_get_qdata (quark_log_handler);
-      if (!log_handler)
-        log_handler = birnet_msg_default_handler;
-      log_handler (&msg);
-    }
-}

Added: trunk/birnet/birnetmsg.cc
===================================================================
--- trunk/birnet/birnetmsg.cc	2006-10-05 15:52:43 UTC (rev 3935)
+++ trunk/birnet/birnetmsg.cc	2006-10-06 16:54:11 UTC (rev 3936)
@@ -0,0 +1,54 @@
+/* Birnet
+ * Copyright (C) 2006 Tim Janik
+ * 
+ * This library is free software; you can redistribute it and/or 
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#include "birnetmsg.hh"
+
+namespace Birnet {
+
+Msg::Part::Part() :
+  ptype (0)
+{}
+
+void
+Msg::Part::setup (uint8       _ptype,
+                  String      smsg)
+{
+  ptype = _ptype;
+  string = smsg;
+}
+
+void
+Msg::Part::setup (uint8       _ptype,
+                  const char *format,
+                  va_list     varargs)
+{
+  char *s = g_strdup_vprintf (format, varargs);
+  setup (_ptype, String (s));
+  g_free (s);
+}
+
+const Msg::Part &Msg::empty_part = Part();
+
+void
+Msg::display (const char         *domain,
+              const vector<Part> &parts)
+{
+  // FIXME: implement Msg::display()
+}
+
+} // Birnet

Deleted: trunk/birnet/birnetmsg.h
===================================================================
--- trunk/birnet/birnetmsg.h	2006-10-05 15:52:43 UTC (rev 3935)
+++ trunk/birnet/birnetmsg.h	2006-10-06 16:54:11 UTC (rev 3936)
@@ -1,154 +0,0 @@
-/* BirnetMsg
- * Copyright (C) 2002-2006 Tim Janik
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General
- * Public License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-#ifndef __BIRNET_MSG_H__
-#define __BIRNET_MSG_H__
-
-#include <birnet/birnetthread.h>
-
-G_BEGIN_DECLS
-
-typedef enum {
-  BIRNET_MSG_NONE = 0,     /* always off */
-  BIRNET_MSG_FATAL,        /* always on */
-  BIRNET_MSG_ERROR,
-  BIRNET_MSG_WARNING,
-  BIRNET_MSG_SCRIPT,
-  BIRNET_MSG_INFO,
-  BIRNET_MSG_DIAG,
-  BIRNET_MSG_DEBUG,
-  BIRNET_MSG_LAST
-} BirnetMsgType;
-
-/* --- standard logging --- */
-#define birnet_fatal(        ...)          birnet_msg_checked (BIRNET_LOG_DOMAIN, BIRNET_MSG_FATAL, __VA_ARGS__)
-#define birnet_error(        ...)          birnet_msg_checked (BIRNET_LOG_DOMAIN, BIRNET_MSG_ERROR,   __VA_ARGS__)
-#define birnet_warning(      ...)          birnet_msg_checked (BIRNET_LOG_DOMAIN, BIRNET_MSG_WARNING, __VA_ARGS__)
-#define birnet_info(         ...)          birnet_msg_checked (BIRNET_LOG_DOMAIN, BIRNET_MSG_INFO, __VA_ARGS__)
-#define birnet_diag(         ...)          birnet_msg_checked (BIRNET_LOG_DOMAIN, BIRNET_MSG_DIAG, __VA_ARGS__)
-#define birnet_debug(   lvl, ...)          birnet_msg_checked (BIRNET_LOG_DOMAIN, lvl, __VA_ARGS__)
-#define birnet_nodebug( lvl, ...)          do { /* nothing */ } while (0)
-
-/* --- user interface messages --- */
-#define birnet_msg_log(level, ...)         birnet_msg_log_elist (BIRNET_LOG_DOMAIN, level, __VA_ARGS__, NULL)
-#define BIRNET_MSG_TEXT0(...)              birnet_msg_bit_printf ('0', __VA_ARGS__) /* message title */
-#define BIRNET_MSG_TEXT1(...)              birnet_msg_bit_printf ('1', __VA_ARGS__) /* primary message */
-#define BIRNET_MSG_TEXT2(...)              birnet_msg_bit_printf ('2', __VA_ARGS__) /* secondary message */
-#define BIRNET_MSG_TEXT3(...)              birnet_msg_bit_printf ('3', __VA_ARGS__) /* message details */
-#define BIRNET_MSG_CHECK(...)              birnet_msg_bit_printf ('c', __VA_ARGS__) /* user switch */
-#define BIRNET_MSG_TITLE                   BIRNET_MSG_TEXT0 /* alias */
-#define BIRNET_MSG_PRIMARY                 BIRNET_MSG_TEXT1 /* alias */
-#define BIRNET_MSG_SECONDARY               BIRNET_MSG_TEXT2 /* alias */
-#define BIRNET_MSG_DETAIL                  BIRNET_MSG_TEXT3 /* alias */
-
-/* --- config and handler API --- */
-typedef enum {
-  BIRNET_MSG_TO_STDERR     = 1,
-  BIRNET_MSG_TO_STDLOG     = 2,
-  BIRNET_MSG_TO_HANDLER    = 4,
-} BirnetMsgLogFlags;
-typedef struct  BirnetMessage                       BirnetMessage;
-typedef void  (*BirnetMsgHandler)                  (const BirnetMessage *message);
-static inline
-bool            birnet_msg_check                   (BirnetMsgType        mtype);
-void            birnet_msg_enable                  (BirnetMsgType        mtype);
-void            birnet_msg_disable                 (BirnetMsgType        mtype);
-void            birnet_msg_allow                   (const gchar      	*ident_list);
-void            birnet_msg_deny                    (const gchar      	*ident_list);
-void            birnet_msg_set_thread_handler      (BirnetMsgHandler     handler);
-void            birnet_msg_default_handler         (const BirnetMessage *message);
-BirnetMsgType   birnet_msg_type_lookup             (const gchar      	*ident);
-const gchar*    birnet_msg_type_ident              (BirnetMsgType        mtype);
-const gchar*    birnet_msg_type_label              (BirnetMsgType        mtype);
-void            birnet_msg_type_configure          (BirnetMsgType        mtype,
-						    BirnetMsgLogFlags    channel_mask,
-						    const gchar      	*dummy_filename);
-void            birnet_msg_configure_stdlog        (bool             	 stdlog_to_stderr,
-						    const char       	*stdlog_filename,
-						    guint            	 syslog_priority); /* if != 0, stdlog to syslog */
-BirnetMsgType   birnet_msg_type_register           (const gchar      	*ident,
-						    BirnetMsgType        default_ouput, /* FALSE, TRUE, ... */
-						    const gchar      	*label);
-/* automatic registration */
-#define BIRNET_MSG_TYPE_DEFINE(variable, ident, default_ouput, label) BIRNET_MSG_TYPE__DEF (variable, ident, default_ouput, label)
-
-/* --- logging internals --- */
-typedef struct BirnetMsgBit BirnetMsgBit;
-struct BirnetMessage {
-  gchar         *log_domain;
-  BirnetMsgType  type;
-  char          *title;         /* translated */
-  char          *primary;       /* translated */
-  char          *secondary;     /* translated */
-  char          *details;       /* translated */
-  char          *config_check;  /* translated */
-  guint          n_msg_bits;
-  BirnetMsgBit **msg_bits;
-};
-struct BirnetMsgBit {
-  gconstpointer  owner;
-  gpointer       data;
-};
-
-void            birnet_msg_log_printf              (const char       *log_domain,
-						    BirnetMsgType     mtype,
-						    const char       *format,
-						    ...) G_GNUC_PRINTF (3, 4);
-void            birnet_msg_log_elist               (const char       *log_domain,
-						    BirnetMsgType     mtype,
-						    BirnetMsgBit     *lbit1,
-						    BirnetMsgBit     *lbit2,
-						    ...);
-void            birnet_msg_log_trampoline          (const char       *log_domain,
-						    BirnetMsgType     mtype,
-						    BirnetMsgBit    **lbits,
-						    BirnetMsgHandler  handler);
-BirnetMsgBit*   birnet_msg_bit_appoint             (gconstpointer     owner,
-						    gpointer          data,
-						    void            (*data_free) (void*));
-BirnetMsgBit*   birnet_msg_bit_printf              (guint8            msg_bit_type,
-						    const char       *format,
-						    ...) G_GNUC_PRINTF (2, 3);
-void            _birnet_init_logging               (void);
-static inline bool    
-birnet_msg_check (BirnetMsgType mtype)
-{
-  extern guint8 * volatile birnet_msg_flags;
-  extern volatile guint    birnet_msg_flags_max;
-  if (mtype >= 0 && (unsigned) mtype <= birnet_msg_flags_max)
-    return 0 != (birnet_msg_flags[mtype / 8] & (1 << mtype % 8));
-  return 0;
-}
-
-/* --- internal macros --- */
-#ifndef BIRNET_LOG_DOMAIN
-#define BIRNET_LOG_DOMAIN  G_LOG_DOMAIN
-#endif
-#define birnet_msg_checked( dom, lvl, ...)  \
-  do { BirnetMsgType __mt = lvl; if (birnet_msg_check (__mt)) birnet_msg_log_printf (dom, __mt, __VA_ARGS__); } while (0)
-#define BIRNET_MSG_TYPE__DEF(variable, identifier, default_ouput, label) \
-  BirnetMsgType variable = (BirnetMsgType) 0; \
-  static void BIRNET_CONSTRUCTOR \
-  BIRNET_CPP_PASTE4 (__birnet_msg_type__init, __LINE__, __, variable) (void) \
-  { variable = birnet_msg_type_register (identifier, default_ouput, label); }
-
-G_END_DECLS
-
-#endif /* __BIRNET_MSG_H__ */
-
-/* vim:set ts=8 sts=2 sw=2: */

Added: trunk/birnet/birnetmsg.hh
===================================================================
--- trunk/birnet/birnetmsg.hh	2006-10-05 15:52:43 UTC (rev 3935)
+++ trunk/birnet/birnetmsg.hh	2006-10-06 16:54:11 UTC (rev 3936)
@@ -0,0 +1,106 @@
+/* Birnet
+ * Copyright (C) 2006 Tim Janik
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef __BIRNET_MSG_HH__
+#define __BIRNET_MSG_HH__
+
+#include <birnet/birnetcore.h>
+#include <birnet/birnetutilsxx.hh> // FIXME: need String in core.hh
+
+namespace Birnet {
+
+/* --- messaging --- */
+struct Msg {
+  typedef enum {
+    ERROR       = 'E',
+    WARNING     = 'W',
+    INFO        = 'I',
+    DEBUG       = 'D',
+  } Type;
+  struct Part {
+    String string;
+    uint8  ptype;
+  public:
+    explicit            Part();
+  protected:
+    void                setup (uint8       ptype,
+                               String      smsg);
+    void                setup (uint8       ptype,
+                               const char *format,
+                               va_list     varargs);
+  };
+  struct Text0 : public Part {  /* message title */
+    Text0 (const char *format, ...) G_GNUC_PRINTF (2, 3)    { va_list a; va_start (a, format); setup ('0', format, a); va_end (a); }
+    Text0 (const String &s)                                 { setup ('0', s); }
+  };
+  struct Text1 : public Part {  /* primary message */
+    Text1 (const char *format, ...) G_GNUC_PRINTF (2, 3)    { va_list a; va_start (a, format); setup ('1', format, a); va_end (a); }
+    Text1 (const String &s)                                 { setup ('1', s); }
+  };
+  struct Text2 : public Part {  /* secondary message (lengthy) */
+    Text2 (const char *format, ...) G_GNUC_PRINTF (2, 3)    { va_list a; va_start (a, format); setup ('2', format, a); va_end (a); }
+    Text2 (const String &s)                                 { setup ('2', s); }
+  };
+  struct Text3 : public Part {  /* message details */
+    Text3 (const char *format, ...) G_GNUC_PRINTF (2, 3)    { va_list a; va_start (a, format); setup ('3', format, a); va_end (a); }
+    Text3 (const String &s)                                 { setup ('3', s); }
+  };
+  struct Check : public Part {  /* user switch */
+    Check (const char *format, ...) G_GNUC_PRINTF (2, 3)    { va_list a; va_start (a, format); setup ('c', format, a); va_end (a); }
+    Check (const String &s)                                 { setup ('c', s); }
+  };
+  typedef Text0 Title;          /* message title */
+  typedef Text1 Primary;        /* primary message */
+  typedef Text2 Secondary;      /* secondary message (lengthy) */
+  typedef Text3 Detail;         /* message details */
+  static inline void display (Type        message_type,
+                              const Part &p0 = empty_part,
+                              const Part &p1 = empty_part,
+                              const Part &p2 = empty_part,
+                              const Part &p3 = empty_part,
+                              const Part &p4 = empty_part);
+protected:
+  static const Part   &empty_part;
+  static void display (const char         *domain,
+                       const vector<Part> &parts);
+  /* FIXME: allow installing of handler for vector<Part&> */
+  BIRNET_PRIVATE_CLASS_COPY (Msg);
+};
+
+/* --- inline implementation --- */
+inline void
+Msg::display (Type        message_type,
+              const Part &p0,
+              const Part &p1,
+              const Part &p2,
+              const Part &p3,
+              const Part &p4)
+{
+  vector<Part> parts;
+  parts.push_back (p0);
+  parts.push_back (p1);
+  parts.push_back (p2);
+  parts.push_back (p3);
+  parts.push_back (p4);
+  display (BIRNET_LOG_DOMAIN, parts);
+}
+
+} // Birnet
+
+#endif /* __BIRNET_MSG_HH__ */
+/* vim:set ts=8 sts=2 sw=2: */

Modified: trunk/birnet/birnettests.h
===================================================================
--- trunk/birnet/birnettests.h	2006-10-05 15:52:43 UTC (rev 3935)
+++ trunk/birnet/birnettests.h	2006-10-06 16:54:11 UTC (rev 3936)
@@ -1,4 +1,4 @@
-/* Birnet
+/* BirnetTests - Utilities for writing test programs
  * Copyright (C) 2006 Tim Janik
  * Copyright (C) 2006 Stefan Westerfeld
  *
@@ -17,8 +17,16 @@
  * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
  * Boston, MA 02111-1307, USA.
  */
-#include <birnet/birnet.h>
+#ifdef  __cplusplus
+#include <birnet/birnet.hh>
+#else
+#include <birnet/birnetconfig.h>
+#endif
 
+/* this file may be included by C programs */
+
+#include <glib.h>
+
 BIRNET_EXTERN_C_BEGIN();
 
 /* === auxillary macros for test programs === */
@@ -31,12 +39,6 @@
 #  define U_(x)		(x)
 #endif
 
-/* --- initialization --- */
-static inline void birnet_init_test (int*, char***);
-static inline void birnet_test_intro (const char *postfix,
-				      const char *format,
-				      ...) G_GNUC_PRINTF (2, 3);
-
 /* --- macros --- */
 /* macros used for testing.
  * note that g_print() does fflush(stdout) automatically.
@@ -44,7 +46,7 @@
  * of programs which generate output on stdout.
  */
 #ifdef	TEST_VERBOSE
-#define TSTART(...)	birnet_test_intro (":\n", __VA_ARGS__)		/* test intro */
+#define TSTART(...)	TSTART_impl (":\n", __VA_ARGS__)		/* test intro */
 #define TOK()           do { g_printerr ("OK.\n"); } while (0)		/* subtest OK */
 #define TICK()          TOK()						/* subtest OK */
 #define TACK()          do { g_printerr ("ACK.\n"); } while (0)		/* alternate OK */
@@ -54,7 +56,7 @@
 #define	TERROR(...)	TERROR_impl ("FAIL.\n", __VA_ARGS__)		/* test error, abort */
 #define TDONE()         do { g_printerr ("DONE.\n"); } while (0)	/* test outro */
 #else
-#define TSTART(...)	birnet_test_intro (": [", __VA_ARGS__)		/* test intro */
+#define TSTART(...)	TSTART_impl (": [", __VA_ARGS__)		/* test intro */
 #define TOK()           do { g_printerr ("-"); } while (0)		/* subtest OK */
 #define TICK()          TOK()						/* subtest OK */
 #define TACK()          do { g_printerr ("+"); } while (0)		/* alternate OK */
@@ -66,6 +68,12 @@
 #endif
 
 /* --- macro details --- */
+#define TSTART_impl(postfix, ...)	do {		\
+  char *_test_name_ = g_strdup_printf (__VA_ARGS__);	\
+  g_printerr ("%s%s", _test_name_, postfix);		\
+  g_free (_test_name_);					\
+} while (0)
+
 #define TASSERT_impl(mark, code, show)	do {		\
   if (code) {						\
     if (show >= 2)					\
@@ -138,42 +146,24 @@
   dups;                                                                                 \
 })
 
-/* --- implmentation details --- */
+/* --- C++ test initialization --- */
+#ifdef  __cplusplus
 static inline void
-birnet_test_intro (const char *postfix,
-		   const char *format,
-		   ...)
-{
-  va_list args;
-  va_start (args, format);
-  char *msg = g_strdup_vprintf (format, args);
-  va_end (args);
-  g_printerr ("%s%s", msg, postfix);
-  g_free (msg);
-}
-
-static inline void
-birnet_test_setup()
-{
-  birnet_init_settings->stand_alone |= true;
-  unsigned int flags = g_log_set_always_fatal ((GLogLevelFlags) G_LOG_FATAL_MASK);
-  g_log_set_always_fatal ((GLogLevelFlags) (flags | G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL));
-  g_printerr ("TEST: %s\n", g_get_prgname());
-}
-
-/* initialization functions for tests */
-static inline void
 birnet_init_test (int    *argc,
 		  char ***argv)
 {
+  /* check that NULL is defined to __null in C++ on 64bit */
+  BIRNET_ASSERT (sizeof (NULL) == sizeof (void*));
+  /* normal initialization */
   BirnetInitValue ivalues[] = {
     { "stand-alone", "true" },
     { NULL }
   };
   birnet_init_extended (argc, argv, NULL, ivalues);
-  birnet_test_setup();
-  /* some runtime checks are best to have here */
-  BIRNET_ASSERT (sizeof (NULL) == sizeof (void*)); // check that NULL is defined to __null in C++ on 64bit
+  unsigned int flags = g_log_set_always_fatal ((GLogLevelFlags) G_LOG_FATAL_MASK);
+  g_log_set_always_fatal ((GLogLevelFlags) (flags | G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL));
+  g_printerr ("TEST: %s\n", g_get_prgname());
 }
+#endif
 
 BIRNET_EXTERN_C_END();

Deleted: trunk/birnet/birnetutils.c
===================================================================
--- trunk/birnet/birnetutils.c	2006-10-05 15:52:43 UTC (rev 3935)
+++ trunk/birnet/birnetutils.c	2006-10-06 16:54:11 UTC (rev 3936)
@@ -1,502 +0,0 @@
-/* Birnet
- * Copyright (C) 2006 Tim Janik
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General
- * Public License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-#include "birnetutils.h"
-#include "birnetmsg.h"
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <wchar.h>
-
-#ifndef _
-#define _(string)       (string)        // FIXME
-#endif
-
-/* --- url handling --- */
-bool
-birnet_url_test_show (const char *url)
-{
-  static struct {
-    const char   *prg, *arg1, *prefix, *postfix;
-    volatile bool disabled;
-  } www_browsers[] = {
-    /* program */               /* arg1 */      /* prefix+URL+postfix */
-    /* system browser launchers */
-    { "sensible-browser",       NULL,           "", "" },
-    { "x-www-browser",          NULL,           "", "" },
-    { "htmlview",               NULL,           "", "" },
-    /* portable browser launchers */
-    { "xdg-open",               NULL,           "", "" },
-#if 1
-    /* desktop browser launchers */
-    { "gnome-open",             NULL,           "", "" },
-    { "kfmclient",              "openURL",      "", "" },
-    { "gnome-moz-remote",       "--newwin"      "", "" },
-    /* specific browser programs */
-    { "firefox",                NULL,           "", "" },
-    { "mozilla-firefox",        NULL,           "", "" },
-    { "mozilla",                NULL,           "", "" },
-    { "opera",                  "-newwindow",   "", "" },
-    { "konqueror",              NULL,           "", "" },
-#endif
-    /* above, we give system browser launchers precedence over xdg-open
-     * (especially the debian sensible-browser script), because xdg-open
-     * tends to exhibit bugs in desktop browser launchers still (e.g.
-     * gnome-open not honouring the users browser setting for file:///
-     * urls).
-     */
-  };
-  uint i;
-  for (i = 0; i < G_N_ELEMENTS (www_browsers); i++)
-    if (!www_browsers[i].disabled)
-      {
-        char *args[128] = { 0, };
-        uint n = 0;
-        args[n++] = (char*) www_browsers[i].prg;
-        if (www_browsers[i].arg1)
-          args[n++] = (char*) www_browsers[i].arg1;
-        char *string = g_strconcat (www_browsers[i].prefix, url, www_browsers[i].postfix, NULL);
-        args[n] = string;
-        GError *error = NULL;
-        bool success = g_spawn_async (NULL, /* cwd */
-                                      args,
-                                      NULL, /* envp */
-                                      G_SPAWN_SEARCH_PATH,
-                                      NULL, /* child_setup() */
-                                      NULL, /* user_data */
-                                      NULL, /* child_pid */
-                                      &error);
-        g_free (string);
-        // g_printerr ("show \"%s\": %s: %s\n", url, args[0], error ? error->message : "Ok");
-        g_clear_error (&error);
-        if (success)
-          return TRUE;
-        www_browsers[i].disabled = true;
-      }
-  /* reset disabled states if no browser could be found */
-  for (i = 0; i < G_N_ELEMENTS (www_browsers); i++)
-    www_browsers[i].disabled = false;
-  return false;
-}
-
-static void
-browser_launch_warning (const char *url)
-{
-  birnet_msg_log (BIRNET_MSG_WARNING,
-                  BIRNET_MSG_TITLE (_("Launch Web Browser")),
-                  BIRNET_MSG_TEXT1 (_("Failed to launch a web browser executable")),
-                  BIRNET_MSG_TEXT2 (_("No suitable web browser executable could be found to be executed and to display the URL: %s"), url),
-                  BIRNET_MSG_CHECK (_("Show messages about web browser launch problems")));
-}
-
-void
-birnet_url_show (const char *url)
-{
-  bool success = birnet_url_test_show (url);
-  if (!success)
-    browser_launch_warning (url);
-}
-
-static void
-unlink_file_name (gpointer data)
-{
-  char *file_name = data;
-  while (unlink (file_name) < 0 && errno == EINTR);
-  g_free (file_name);
-}
-
-static const gchar*
-birnet_url_create_redirect (const char    *url,
-                            const char    *url_title,
-                            const char    *cookie)
-{
-  const char *ver = "0.5";
-  gchar *tname = NULL;
-  gint fd = -1;
-  while (fd < 0)
-    {
-      g_free (tname);
-      tname = g_strdup_printf ("/tmp/Url%08X%04X.html", (int) lrand48(), getpid());
-      fd = open (tname, O_WRONLY | O_CREAT | O_EXCL, 00600);
-      if (fd < 0 && errno != EEXIST)
-        {
-          g_free (tname);
-          return NULL;
-        }
-    }
-  char *text = g_strdup_printf ("<!DOCTYPE HTML SYSTEM>\n"
-                                "<html><head>\n"
-                                "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\n"
-                                "<meta http-equiv=\"refresh\" content=\"0; URL=%s\">\n"
-                                "<meta http-equiv=\"set-cookie\" content=\"%s\">\n"
-                                "<title>%s</title>\n"
-                                "</head><body>\n"
-                                "<h1>%s</h1>\n"
-                                "<b>Document Redirection</b><br>\n"
-                                "Your browser is being redirected.\n"
-                                "If it does not support automatic redirections, try <a href=\"%s\">%s</a>.\n"
-                                "<hr>\n"
-                                "<address>BirnetUrl/%s file redirect</address>\n"
-                                "</body></html>\n",
-                                url, cookie, url_title, url_title, url, url, ver);
-  int w, c, l = strlen (text);
-  do
-    w = write (fd, text, l);
-  while (w < 0 && errno == EINTR);
-  g_free (text);
-  do
-    c = close (fd);
-  while (c < 0 && errno == EINTR);
-  if (w != l || c < 0)
-    {
-      while (unlink (tname) < 0 && errno == EINTR)
-        {}
-      g_free (tname);
-      return NULL;
-    }
-  birnet_cleanup_add (60 * 1000, unlink_file_name, tname); /* free tname */
-  return tname;
-}
-
-bool
-birnet_url_test_show_with_cookie (const char *url,
-                                  const char *url_title,
-                                  const char *cookie)
-{
-  const char *redirect = birnet_url_create_redirect (url, url_title, cookie);
-  if (redirect)
-    return birnet_url_test_show (redirect);
-  else
-    return birnet_url_test_show (url);
-}
-
-void
-birnet_url_show_with_cookie (const char *url,
-                             const char *url_title,
-                             const char *cookie)
-{
-  bool success = birnet_url_test_show_with_cookie (url, url_title, cookie);
-  if (!success)
-    browser_launch_warning (url);
-}
-
-/* --- cleanups --- */
-typedef struct {
-  uint           id;
-  GDestroyNotify handler;
-  void          *data;
-} Cleanup;
-
-static BIRNET_MUTEX_DECLARE_INITIALIZED (cleanup_mutex);
-static GSList *cleanup_list = NULL;
-
-static void
-birnet_cleanup_exec_Lm (Cleanup *cleanup)
-{
-  cleanup_list = g_slist_remove (cleanup_list, cleanup);
-  g_source_remove (cleanup->id);
-  GDestroyNotify handler = cleanup->handler;
-  void *data = cleanup->data;
-  g_free (cleanup);
-  birnet_mutex_unlock (&cleanup_mutex);
-  handler (data);
-  birnet_mutex_lock (&cleanup_mutex);
-}
-
-/**
- * Force all cleanup handlers (see birnet_cleanup_add()) to be immediately
- * executed. This function should be called at program exit to execute
- * cleanup handlers which have timeouts that have not yet expired.
- */
-void
-birnet_cleanup_force_handlers (void)
-{
-  birnet_mutex_lock (&cleanup_mutex);
-  while (cleanup_list)
-    birnet_cleanup_exec_Lm (cleanup_list->data);
-  birnet_mutex_unlock (&cleanup_mutex);
-}
-
-static gboolean
-birnet_cleanup_exec (gpointer data)
-{
-  birnet_mutex_lock (&cleanup_mutex);
-  birnet_cleanup_exec_Lm (data);
-  birnet_mutex_unlock (&cleanup_mutex);
-  return FALSE;
-}
-
-/**
- * @param timeout_ms    timeout in milliseconds
- * @param handler       cleanup handler to run
- * @param data          cleanup handler data
- *
- * Register a cleanup handler, the @a handler is guaranteed to be run
- * asyncronously (i.e. not from within birnet_cleanup_add()). The cleanup
- * handler will be called as soon as @a timeout_ms has elapsed or
- * birnet_cleanup_force_handlers() is called.
- */
-uint
-birnet_cleanup_add (guint          timeout_ms,
-                    GDestroyNotify handler,
-                    void          *data)
-{
-  Cleanup *cleanup = g_new0 (Cleanup, 1);
-  cleanup->handler = handler;
-  cleanup->data = data;
-  cleanup->id = g_timeout_add (timeout_ms, birnet_cleanup_exec, cleanup);
-  birnet_mutex_lock (&cleanup_mutex);
-  cleanup_list = g_slist_prepend (cleanup_list, cleanup);
-  birnet_mutex_unlock (&cleanup_mutex);
-  return cleanup->id;
-}
-
-/* --- string utils --- */
-void
-birnet_memset4 (guint32        *mem,
-                guint32         filler,
-                guint           length)
-{
-  BIRNET_STATIC_ASSERT (sizeof (*mem) == 4);
-  BIRNET_STATIC_ASSERT (sizeof (filler) == 4);
-  BIRNET_STATIC_ASSERT (sizeof (wchar_t) == 4);
-  wmemset ((wchar_t*) mem, filler, length);
-}
-
-/* --- memory utils --- */
-void*
-birnet_malloc_aligned (gsize	  total_size,
-		       gsize	  alignment,
-		       guint8	**free_pointer)
-{
-  uint8 *aligned_mem = g_malloc (total_size);
-  *free_pointer = aligned_mem;
-  if (!alignment || !(ptrdiff_t) aligned_mem % alignment)
-    return aligned_mem;
-  g_free (aligned_mem);
-  aligned_mem = g_malloc (total_size + alignment - 1);
-  *free_pointer = aligned_mem;
-  if ((ptrdiff_t) aligned_mem % alignment)
-    aligned_mem += alignment - (ptrdiff_t) aligned_mem % alignment;
-  return aligned_mem;
-}
-
-/* --- file testing --- */
-static int
-errno_check_file (const char *file_name,
-                  const char *mode)
-{
-  uint access_mask = 0, nac = 0;
-  
-  if (strchr (mode, 'e'))       /* exists */
-    nac++, access_mask |= F_OK;
-  if (strchr (mode, 'r'))       /* readable */
-    nac++, access_mask |= R_OK;
-  if (strchr (mode, 'w'))       /* writable */
-    nac++, access_mask |= W_OK;
-  bool check_exec = strchr (mode, 'x') != NULL;
-  if (check_exec)               /* executable */
-    nac++, access_mask |= X_OK;
-  
-  /* on some POSIX systems, X_OK may succeed for root without any
-   * executable bits set, so we also check via stat() below.
-   */
-  if (nac && access (file_name, access_mask) < 0)
-    return -errno;
-  
-  bool check_file = strchr (mode, 'f') != NULL;     /* open as file */
-  bool check_dir  = strchr (mode, 'd') != NULL;     /* open as directory */
-  bool check_link = strchr (mode, 'l') != NULL;     /* open as link */
-  bool check_char = strchr (mode, 'c') != NULL;     /* open as character device */
-  bool check_block = strchr (mode, 'b') != NULL;    /* open as block device */
-  bool check_pipe = strchr (mode, 'p') != NULL;     /* open as pipe */
-  bool check_socket = strchr (mode, 's') != NULL;   /* open as socket */
-  
-  if (check_exec || check_file || check_dir || check_link || check_char || check_block || check_pipe || check_socket)
-    {
-      struct stat st;
-      
-      if (check_link)
-        {
-          if (lstat (file_name, &st) < 0)
-            return -errno;
-        }
-      else if (stat (file_name, &st) < 0)
-        return -errno;
-      
-      if (0)
-        g_printerr ("file-check(\"%s\",\"%s\"): %s%s%s%s%s%s%s\n",
-                    file_name, mode,
-                    S_ISREG (st.st_mode) ? "f" : "",
-                    S_ISDIR (st.st_mode) ? "d" : "",
-                    S_ISLNK (st.st_mode) ? "l" : "",
-                    S_ISCHR (st.st_mode) ? "c" : "",
-                    S_ISBLK (st.st_mode) ? "b" : "",
-                    S_ISFIFO (st.st_mode) ? "p" : "",
-                    S_ISSOCK (st.st_mode) ? "s" : "");
-      
-      if (S_ISDIR (st.st_mode) && (check_file || check_link || check_char || check_block || check_pipe))
-        return -EISDIR;
-      if (check_file && !S_ISREG (st.st_mode))
-        return -EINVAL;
-      if (check_dir && !S_ISDIR (st.st_mode))
-        return -ENOTDIR;
-      if (check_link && !S_ISLNK (st.st_mode))
-        return -EINVAL;
-      if (check_char && !S_ISCHR (st.st_mode))
-        return -ENODEV;
-      if (check_block && !S_ISBLK (st.st_mode))
-        return -ENOTBLK;
-      if (check_pipe && !S_ISFIFO (st.st_mode))
-        return -ENXIO;
-      if (check_socket && !S_ISSOCK (st.st_mode))
-        return -ENOTSOCK;
-      if (check_exec && !(st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)))
-        return -EACCES; /* for root executable, any +x bit is good enough */
-    }
-  
-  return 0;
-}
-
-/**
- * @param file  possibly relative filename
- * @param mode  feature string
- * @return              TRUE if @a file adhears to @a mode
- *
- * Perform various checks on @a file and return whether all
- * checks passed. On failure, errno is set appropriately, and
- * FALSE is returned. Available features to be checked for are:
- * @itemize
- * @item e - @a file must exist
- * @item r - @a file must be readable
- * @item w - @a file must be writable
- * @item x - @a file must be executable
- * @item f - @a file must be a regular file
- * @item d - @a file must be a directory
- * @item l - @a file must be a symbolic link
- * @item c - @a file must be a character device
- * @item b - @a file must be a block device
- * @item p - @a file must be a named pipe
- * @item s - @a file must be a socket.
- * @done
- */
-bool
-birnet_file_check (const gchar *file,
-                   const gchar *mode)
-{
-  int err = file && mode ? errno_check_file (file, mode) : -EFAULT;
-  errno = err < 0 ? -err : 0;
-  return errno == 0;
-}
-
-/**
- * @param file1  possibly relative filename
- * @param file2  possibly relative filename
- * @return       TRUE if @a file1 and @a file2 are equal
- *
- * Check whether @a file1 and @a file2 are pointing to the same inode
- * in the same file system on the same device.
- */
-bool
-birnet_file_equals (const gchar *file1,
-                    const gchar *file2)
-{
-  if (!file1 || !file2)
-    return file1 == file2;
-  struct stat st1 = { 0, }, st2 = { 0, };
-  int err1 = 0, err2 = 0;
-  errno = 0;
-  if (stat (file1, &st1) < 0 && stat (file1, &st1) < 0)
-    err1 = errno;
-  errno = 0;
-  if (stat (file2, &st2) < 0 && stat (file2, &st2) < 0)
-    err2 = errno;
-  if (err1 || err2)
-    return err1 == err2;
-  return (st1.st_dev  == st2.st_dev &&
-          st1.st_ino  == st2.st_ino &&
-          st1.st_rdev == st2.st_rdev);
-}
-
-/* --- zintern support --- */
-#include <zlib.h>
-
-/**
- * @param decompressed_size exact size of the decompressed data to be returned
- * @param cdata             compressed data block
- * @param cdata_size        exact size of the compressed data block
- * @returns                 decompressed data block or NULL in low memory situations
- *
- * Decompress the data from @a cdata of length @a cdata_size into a newly
- * allocated block of size @a decompressed_size which is returned.
- * The returned block needs to be freed with g_free().
- * This function is intended to decompress data which has been compressed
- * with the birnet-zintern utility, so no errors should occour during
- * decompression.
- * Consequently, if any error occours during decompression or if the resulting
- * data block is of a size other than @a decompressed_size, the program will
- * abort with an appropriate error message.
- * If not enough memory could be allocated for decompression, NULL is returned.
- */
-guint8*
-birnet_zintern_decompress (unsigned int          decompressed_size,
-                           const unsigned char  *cdata,
-                           unsigned int          cdata_size)
-{
-  uLongf dlen = decompressed_size;
-  uint64 len = dlen + 1;
-  uint8 *text = g_try_malloc (len);
-  if (!text)
-    return NULL;        /* handle ENOMEM gracefully */
-
-  int64 result = uncompress (text, &dlen, cdata, cdata_size);
-  const char *err;
-  switch (result)
-    {
-    case Z_OK:
-      if (dlen == decompressed_size)
-        {
-          err = NULL;
-          break;
-        }
-      /* fall through */
-    case Z_DATA_ERROR:
-      err = "internal data corruption";
-      break;
-    case Z_MEM_ERROR:
-      err = "out of memory";
-      g_free (text);
-      return NULL;      /* handle ENOMEM gracefully */
-      break;
-    case Z_BUF_ERROR:
-      err = "insufficient buffer size";
-      break;
-    default:
-      err = "unknown error";
-      break;
-    }
-  if (err)
-    g_error ("failed to decompress (%p, %u): %s", cdata, cdata_size, err);
-
-  text[dlen] = 0;
-  return text;          /* success */
-}

Copied: trunk/birnet/birnetutils.cc (from rev 3931, trunk/birnet/birnetutils.c)
===================================================================
--- trunk/birnet/birnetutils.c	2006-10-03 17:04:26 UTC (rev 3931)
+++ trunk/birnet/birnetutils.cc	2006-10-06 16:54:11 UTC (rev 3936)
@@ -0,0 +1,507 @@
+/* Birnet
+ * Copyright (C) 2006 Tim Janik
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#include "birnetutils.hh"
+#include "birnetmsg.hh"
+#include "birnetthreadxx.hh"
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <wchar.h>
+
+#ifndef _
+#define _(string)       (string)        // FIXME
+#endif
+
+namespace Birnet {
+
+/* --- url handling --- */
+bool
+url_test_show (const char *url)
+{
+  static struct {
+    const char   *prg, *arg1, *prefix, *postfix;
+    volatile bool disabled;
+  } www_browsers[] = {
+    /* program */               /* arg1 */      /* prefix+URL+postfix */
+    /* system browser launchers */
+    { "sensible-browser",       NULL,           "", "" },
+    { "x-www-browser",          NULL,           "", "" },
+    { "htmlview",               NULL,           "", "" },
+    /* portable browser launchers */
+    { "xdg-open",               NULL,           "", "" },
+#if 1
+    /* desktop browser launchers */
+    { "gnome-open",             NULL,           "", "" },
+    { "kfmclient",              "openURL",      "", "" },
+    { "gnome-moz-remote",       "--newwin"      "", "" },
+    /* specific browser programs */
+    { "firefox",                NULL,           "", "" },
+    { "mozilla-firefox",        NULL,           "", "" },
+    { "mozilla",                NULL,           "", "" },
+    { "opera",                  "-newwindow",   "", "" },
+    { "konqueror",              NULL,           "", "" },
+#endif
+    /* above, we give system browser launchers precedence over xdg-open
+     * (especially the debian sensible-browser script), because xdg-open
+     * tends to exhibit bugs in desktop browser launchers still (e.g.
+     * gnome-open not honouring the users browser setting for file:///
+     * urls).
+     */
+  };
+  uint i;
+  for (i = 0; i < G_N_ELEMENTS (www_browsers); i++)
+    if (!www_browsers[i].disabled)
+      {
+        char *args[128] = { 0, };
+        uint n = 0;
+        args[n++] = (char*) www_browsers[i].prg;
+        if (www_browsers[i].arg1)
+          args[n++] = (char*) www_browsers[i].arg1;
+        char *string = g_strconcat (www_browsers[i].prefix, url, www_browsers[i].postfix, NULL);
+        args[n] = string;
+        GError *error = NULL;
+        bool success = g_spawn_async (NULL, /* cwd */
+                                      args,
+                                      NULL, /* envp */
+                                      G_SPAWN_SEARCH_PATH,
+                                      NULL, /* child_setup() */
+                                      NULL, /* user_data */
+                                      NULL, /* child_pid */
+                                      &error);
+        g_free (string);
+        // g_printerr ("show \"%s\": %s: %s\n", url, args[0], error ? error->message : "Ok");
+        g_clear_error (&error);
+        if (success)
+          return TRUE;
+        www_browsers[i].disabled = true;
+      }
+  /* reset disabled states if no browser could be found */
+  for (i = 0; i < G_N_ELEMENTS (www_browsers); i++)
+    www_browsers[i].disabled = false;
+  return false;
+}
+
+static void
+browser_launch_warning (const char *url)
+{
+  Msg::display (Msg::WARNING,
+                Msg::Title (_("Launch Web Browser")),
+                Msg::Text1 (_("Failed to launch a web browser executable")),
+                Msg::Text2 (_("No suitable web browser executable could be found to be executed and to display the URL: %s"), url),
+                Msg::Check (_("Show messages about web browser launch problems")));
+}
+
+void
+url_show (const char *url)
+{
+  bool success = url_test_show (url);
+  if (!success)
+    browser_launch_warning (url);
+}
+
+static void
+unlink_file_name (gpointer data)
+{
+  char *file_name = (char*) data;
+  while (unlink (file_name) < 0 && errno == EINTR);
+  g_free (file_name);
+}
+
+static const gchar*
+url_create_redirect (const char    *url,
+                     const char    *url_title,
+                     const char    *cookie)
+{
+  const char *ver = "0.5";
+  gchar *tname = NULL;
+  gint fd = -1;
+  while (fd < 0)
+    {
+      g_free (tname);
+      tname = g_strdup_printf ("/tmp/Url%08X%04X.html", (int) lrand48(), getpid());
+      fd = open (tname, O_WRONLY | O_CREAT | O_EXCL, 00600);
+      if (fd < 0 && errno != EEXIST)
+        {
+          g_free (tname);
+          return NULL;
+        }
+    }
+  char *text = g_strdup_printf ("<!DOCTYPE HTML SYSTEM>\n"
+                                "<html><head>\n"
+                                "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\n"
+                                "<meta http-equiv=\"refresh\" content=\"0; URL=%s\">\n"
+                                "<meta http-equiv=\"set-cookie\" content=\"%s\">\n"
+                                "<title>%s</title>\n"
+                                "</head><body>\n"
+                                "<h1>%s</h1>\n"
+                                "<b>Document Redirection</b><br>\n"
+                                "Your browser is being redirected.\n"
+                                "If it does not support automatic redirections, try <a href=\"%s\">%s</a>.\n"
+                                "<hr>\n"
+                                "<address>BirnetUrl/%s file redirect</address>\n"
+                                "</body></html>\n",
+                                url, cookie, url_title, url_title, url, url, ver);
+  int w, c, l = strlen (text);
+  do
+    w = write (fd, text, l);
+  while (w < 0 && errno == EINTR);
+  g_free (text);
+  do
+    c = close (fd);
+  while (c < 0 && errno == EINTR);
+  if (w != l || c < 0)
+    {
+      while (unlink (tname) < 0 && errno == EINTR)
+        {}
+      g_free (tname);
+      return NULL;
+    }
+  cleanup_add (60 * 1000, unlink_file_name, tname); /* free tname */
+  return tname;
+}
+
+bool
+url_test_show_with_cookie (const char *url,
+                           const char *url_title,
+                           const char *cookie)
+{
+  const char *redirect = url_create_redirect (url, url_title, cookie);
+  if (redirect)
+    return url_test_show (redirect);
+  else
+    return url_test_show (url);
+}
+
+void
+url_show_with_cookie (const char *url,
+                      const char *url_title,
+                      const char *cookie)
+{
+  bool success = url_test_show_with_cookie (url, url_title, cookie);
+  if (!success)
+    browser_launch_warning (url);
+}
+
+/* --- cleanups --- */
+typedef struct {
+  uint           id;
+  GDestroyNotify handler;
+  void          *data;
+} Cleanup;
+
+static Mutex cleanup_mutex;
+static GSList *cleanup_list = NULL;
+
+static void
+cleanup_exec_Lm (Cleanup *cleanup)
+{
+  cleanup_list = g_slist_remove (cleanup_list, cleanup);
+  g_source_remove (cleanup->id);
+  GDestroyNotify handler = cleanup->handler;
+  void *data = cleanup->data;
+  g_free (cleanup);
+  cleanup_mutex.unlock();
+  handler (data);
+  cleanup_mutex.lock();
+}
+
+/**
+ * Force all cleanup handlers (see birnet_cleanup_add()) to be immediately
+ * executed. This function should be called at program exit to execute
+ * cleanup handlers which have timeouts that have not yet expired.
+ */
+void
+cleanup_force_handlers (void)
+{
+  cleanup_mutex.lock();
+  while (cleanup_list)
+    cleanup_exec_Lm ((Cleanup*) cleanup_list->data);
+  cleanup_mutex.unlock();
+}
+
+static gboolean
+cleanup_exec (gpointer data)
+{
+  cleanup_mutex.lock();
+  cleanup_exec_Lm ((Cleanup*) data);
+  cleanup_mutex.unlock();
+  return FALSE;
+}
+
+/**
+ * @param timeout_ms    timeout in milliseconds
+ * @param handler       cleanup handler to run
+ * @param data          cleanup handler data
+ *
+ * Register a cleanup handler, the @a handler is guaranteed to be run
+ * asyncronously (i.e. not from within cleanup_add()). The cleanup
+ * handler will be called as soon as @a timeout_ms has elapsed or
+ * cleanup_force_handlers() is called.
+ */
+uint
+cleanup_add (guint          timeout_ms,
+             GDestroyNotify handler,
+             void          *data)
+{
+  Cleanup *cleanup = g_new0 (Cleanup, 1);
+  cleanup->handler = handler;
+  cleanup->data = data;
+  cleanup->id = g_timeout_add (timeout_ms, cleanup_exec, cleanup);
+  cleanup_mutex.lock();
+  cleanup_list = g_slist_prepend (cleanup_list, cleanup);
+  cleanup_mutex.unlock();
+  return cleanup->id;
+}
+
+/* --- string utils --- */
+void
+memset4 (guint32        *mem,
+         guint32         filler,
+         guint           length)
+{
+  BIRNET_STATIC_ASSERT (sizeof (*mem) == 4);
+  BIRNET_STATIC_ASSERT (sizeof (filler) == 4);
+  BIRNET_STATIC_ASSERT (sizeof (wchar_t) == 4);
+  wmemset ((wchar_t*) mem, filler, length);
+}
+
+/* --- memory utils --- */
+void*
+malloc_aligned (gsize	  total_size,
+                gsize	  alignment,
+                guint8	**free_pointer)
+{
+  uint8 *aligned_mem = (uint8*) g_malloc (total_size);
+  *free_pointer = aligned_mem;
+  if (!alignment || !(ptrdiff_t) aligned_mem % alignment)
+    return aligned_mem;
+  g_free (aligned_mem);
+  aligned_mem = (uint8*) g_malloc (total_size + alignment - 1);
+  *free_pointer = aligned_mem;
+  if ((ptrdiff_t) aligned_mem % alignment)
+    aligned_mem += alignment - (ptrdiff_t) aligned_mem % alignment;
+  return aligned_mem;
+}
+
+/* --- file testing --- */
+static int
+errno_check_file (const char *file_name,
+                  const char *mode)
+{
+  uint access_mask = 0, nac = 0;
+  
+  if (strchr (mode, 'e'))       /* exists */
+    nac++, access_mask |= F_OK;
+  if (strchr (mode, 'r'))       /* readable */
+    nac++, access_mask |= R_OK;
+  if (strchr (mode, 'w'))       /* writable */
+    nac++, access_mask |= W_OK;
+  bool check_exec = strchr (mode, 'x') != NULL;
+  if (check_exec)               /* executable */
+    nac++, access_mask |= X_OK;
+  
+  /* on some POSIX systems, X_OK may succeed for root without any
+   * executable bits set, so we also check via stat() below.
+   */
+  if (nac && access (file_name, access_mask) < 0)
+    return -errno;
+  
+  bool check_file = strchr (mode, 'f') != NULL;     /* open as file */
+  bool check_dir  = strchr (mode, 'd') != NULL;     /* open as directory */
+  bool check_link = strchr (mode, 'l') != NULL;     /* open as link */
+  bool check_char = strchr (mode, 'c') != NULL;     /* open as character device */
+  bool check_block = strchr (mode, 'b') != NULL;    /* open as block device */
+  bool check_pipe = strchr (mode, 'p') != NULL;     /* open as pipe */
+  bool check_socket = strchr (mode, 's') != NULL;   /* open as socket */
+  
+  if (check_exec || check_file || check_dir || check_link || check_char || check_block || check_pipe || check_socket)
+    {
+      struct stat st;
+      
+      if (check_link)
+        {
+          if (lstat (file_name, &st) < 0)
+            return -errno;
+        }
+      else if (stat (file_name, &st) < 0)
+        return -errno;
+      
+      if (0)
+        g_printerr ("file-check(\"%s\",\"%s\"): %s%s%s%s%s%s%s\n",
+                    file_name, mode,
+                    S_ISREG (st.st_mode) ? "f" : "",
+                    S_ISDIR (st.st_mode) ? "d" : "",
+                    S_ISLNK (st.st_mode) ? "l" : "",
+                    S_ISCHR (st.st_mode) ? "c" : "",
+                    S_ISBLK (st.st_mode) ? "b" : "",
+                    S_ISFIFO (st.st_mode) ? "p" : "",
+                    S_ISSOCK (st.st_mode) ? "s" : "");
+      
+      if (S_ISDIR (st.st_mode) && (check_file || check_link || check_char || check_block || check_pipe))
+        return -EISDIR;
+      if (check_file && !S_ISREG (st.st_mode))
+        return -EINVAL;
+      if (check_dir && !S_ISDIR (st.st_mode))
+        return -ENOTDIR;
+      if (check_link && !S_ISLNK (st.st_mode))
+        return -EINVAL;
+      if (check_char && !S_ISCHR (st.st_mode))
+        return -ENODEV;
+      if (check_block && !S_ISBLK (st.st_mode))
+        return -ENOTBLK;
+      if (check_pipe && !S_ISFIFO (st.st_mode))
+        return -ENXIO;
+      if (check_socket && !S_ISSOCK (st.st_mode))
+        return -ENOTSOCK;
+      if (check_exec && !(st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)))
+        return -EACCES; /* for root executable, any +x bit is good enough */
+    }
+  
+  return 0;
+}
+
+/**
+ * @param file  possibly relative filename
+ * @param mode  feature string
+ * @return              TRUE if @a file adhears to @a mode
+ *
+ * Perform various checks on @a file and return whether all
+ * checks passed. On failure, errno is set appropriately, and
+ * FALSE is returned. Available features to be checked for are:
+ * @itemize
+ * @item e - @a file must exist
+ * @item r - @a file must be readable
+ * @item w - @a file must be writable
+ * @item x - @a file must be executable
+ * @item f - @a file must be a regular file
+ * @item d - @a file must be a directory
+ * @item l - @a file must be a symbolic link
+ * @item c - @a file must be a character device
+ * @item b - @a file must be a block device
+ * @item p - @a file must be a named pipe
+ * @item s - @a file must be a socket.
+ * @done
+ */
+bool
+file_check (const gchar *file,
+            const gchar *mode)
+{
+  int err = file && mode ? errno_check_file (file, mode) : -EFAULT;
+  errno = err < 0 ? -err : 0;
+  return errno == 0;
+}
+
+/**
+ * @param file1  possibly relative filename
+ * @param file2  possibly relative filename
+ * @return       TRUE if @a file1 and @a file2 are equal
+ *
+ * Check whether @a file1 and @a file2 are pointing to the same inode
+ * in the same file system on the same device.
+ */
+bool
+file_equals (const gchar *file1,
+             const gchar *file2)
+{
+  if (!file1 || !file2)
+    return file1 == file2;
+  struct stat st1 = { 0, }, st2 = { 0, };
+  int err1 = 0, err2 = 0;
+  errno = 0;
+  if (stat (file1, &st1) < 0 && stat (file1, &st1) < 0)
+    err1 = errno;
+  errno = 0;
+  if (stat (file2, &st2) < 0 && stat (file2, &st2) < 0)
+    err2 = errno;
+  if (err1 || err2)
+    return err1 == err2;
+  return (st1.st_dev  == st2.st_dev &&
+          st1.st_ino  == st2.st_ino &&
+          st1.st_rdev == st2.st_rdev);
+}
+
+/* --- zintern support --- */
+#include <zlib.h>
+
+/**
+ * @param decompressed_size exact size of the decompressed data to be returned
+ * @param cdata             compressed data block
+ * @param cdata_size        exact size of the compressed data block
+ * @returns                 decompressed data block or NULL in low memory situations
+ *
+ * Decompress the data from @a cdata of length @a cdata_size into a newly
+ * allocated block of size @a decompressed_size which is returned.
+ * The returned block needs to be freed with g_free().
+ * This function is intended to decompress data which has been compressed
+ * with the birnet-zintern utility, so no errors should occour during
+ * decompression.
+ * Consequently, if any error occours during decompression or if the resulting
+ * data block is of a size other than @a decompressed_size, the program will
+ * abort with an appropriate error message.
+ * If not enough memory could be allocated for decompression, NULL is returned.
+ */
+uint8*
+zintern_decompress (unsigned int          decompressed_size,
+                    const unsigned char  *cdata,
+                    unsigned int          cdata_size)
+{
+  uLongf dlen = decompressed_size;
+  uint64 len = dlen + 1;
+  uint8 *text = (uint8*) g_try_malloc (len);
+  if (!text)
+    return NULL;        /* handle ENOMEM gracefully */
+  
+  int64 result = uncompress (text, &dlen, cdata, cdata_size);
+  const char *err;
+  switch (result)
+    {
+    case Z_OK:
+      if (dlen == decompressed_size)
+        {
+          err = NULL;
+          break;
+        }
+      /* fall through */
+    case Z_DATA_ERROR:
+      err = "internal data corruption";
+      break;
+    case Z_MEM_ERROR:
+      err = "out of memory";
+      g_free (text);
+      return NULL;      /* handle ENOMEM gracefully */
+      break;
+    case Z_BUF_ERROR:
+      err = "insufficient buffer size";
+      break;
+    default:
+      err = "unknown error";
+      break;
+    }
+  if (err)
+    g_error ("failed to decompress (%p, %u): %s", cdata, cdata_size, err);
+  
+  text[dlen] = 0;
+  return text;          /* success */
+}
+
+} // Birnet

Deleted: trunk/birnet/birnetutils.h
===================================================================
--- trunk/birnet/birnetutils.h	2006-10-05 15:52:43 UTC (rev 3935)
+++ trunk/birnet/birnetutils.h	2006-10-06 16:54:11 UTC (rev 3936)
@@ -1,66 +0,0 @@
-/* Birnet
- * Copyright (C) 2006 Tim Janik
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General
- * Public License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-#ifndef __BIRNET_UTILS_H__
-#define __BIRNET_UTILS_H__
-
-#include <birnet/birnetcore.h>
-
-BIRNET_EXTERN_C_BEGIN();
-
-/* --- url handling --- */
-void birnet_url_show                  (const char           *url);
-void birnet_url_show_with_cookie      (const char           *url,
-				       const char           *url_title,
-				       const char           *cookie);
-bool birnet_url_test_show             (const char           *url);
-bool birnet_url_test_show_with_cookie (const char	    *url,
-				       const char           *url_title,
-				       const char           *cookie);
-/* --- cleanup registration --- */
-uint birnet_cleanup_add               (uint                  timeout_ms,
-				       GDestroyNotify        handler,
-				       void                 *data);
-void birnet_cleanup_force_handlers    (void);
-
-/* --- string utils --- */
-void birnet_memset4		      (guint32              *mem,
-				       guint32               filler,
-				       guint                 length);
-/* --- memory utils --- */
-void* birnet_malloc_aligned           (gsize                 total_size,
-                                       gsize                 alignment,
-				       guint8             **free_pointer);
-/* --- file testing --- */
-bool birnet_file_check                (const gchar *file,	/* returns errno */
-				       const gchar *mode);
-bool birnet_file_equals		      (const gchar *file1,
-				       const gchar *file2);
-
-/* --- C++ demangling --- */
-gchar*  birnet_cxx_demangle	      (const char  *mangled_identifier); /* in birnetutilsxx.cc */
-
-/* --- zintern support --- */
-guint8* birnet_zintern_decompress     (unsigned int          decompressed_size,
-				       const unsigned char  *cdata,
-				       unsigned int          cdata_size);
-
-BIRNET_EXTERN_C_END();
-
-#endif /* __BIRNET_UTILS_H__ */
-/* vim:set ts=8 sts=2 sw=2: */

Copied: trunk/birnet/birnetutils.hh (from rev 3931, trunk/birnet/birnetutils.h)
===================================================================
--- trunk/birnet/birnetutils.h	2006-10-03 17:04:26 UTC (rev 3931)
+++ trunk/birnet/birnetutils.hh	2006-10-06 16:54:11 UTC (rev 3936)
@@ -0,0 +1,67 @@
+/* Birnet
+ * Copyright (C) 2006 Tim Janik
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef __BIRNET_UTILS_HH__
+#define __BIRNET_UTILS_HH__
+
+#include <birnet/birnetcore.h>
+
+namespace Birnet {
+
+/* --- url handling --- */
+void url_show                   (const char           *url);
+void url_show_with_cookie       (const char           *url,
+                                 const char           *url_title,
+                                 const char           *cookie);
+bool url_test_show              (const char           *url);
+bool url_test_show_with_cookie  (const char	      *url,
+                                 const char           *url_title,
+                                 const char           *cookie);
+
+/* --- cleanup registration --- */
+uint cleanup_add                (uint                  timeout_ms,
+                                 GDestroyNotify        handler,
+                                 void                 *data);
+void cleanup_force_handlers     (void);
+
+/* --- string utils --- */
+void memset4		        (uint32              *mem,
+                                 uint32               filler,
+                                 uint                 length);
+/* --- memory utils --- */
+void* malloc_aligned            (gsize                 total_size,
+                                 gsize                 alignment,
+                                 uint8               **free_pointer);
+/* --- file testing --- */
+bool file_check                 (const char *file,
+                                 const char *mode);
+bool file_equals	        (const char *file1,
+                                 const char *file2);
+
+/* --- C++ demangling --- */
+char*   cxx_demangle	        (const char  *mangled_identifier); /* in birnetutilsxx.cc */
+
+/* --- zintern support --- */
+uint8*  zintern_decompress      (unsigned int          decompressed_size,
+                                 const unsigned char  *cdata,
+                                 unsigned int          cdata_size);
+
+} // Birnet
+
+#endif /* __BIRNET_UTILS_HH__ */
+/* vim:set ts=8 sts=2 sw=2: */

Modified: trunk/birnet/birnetutilsxx.cc
===================================================================
--- trunk/birnet/birnetutilsxx.cc	2006-10-05 15:52:43 UTC (rev 3935)
+++ trunk/birnet/birnetutilsxx.cc	2006-10-06 16:54:11 UTC (rev 3936)
@@ -17,9 +17,8 @@
  * Boston, MA 02111-1307, USA.
  */
 #include "birnetutilsxx.hh"
-#include "birnetutils.h"
+#include "birnetutils.hh"
 #include "birnetthreadxx.hh"
-#include "birnetmsg.h"
 #include "birnetcpu.h"
 #include <sys/time.h>
 #include <vector>
@@ -102,7 +101,6 @@
   /* initialize sub systems */
   _birnet_init_cpuinfo();
   _birnet_init_threads();
-  _birnet_init_logging ();
   if (birnet_init_cplusplus_func)
     birnet_init_cplusplus_func();
 }
@@ -240,7 +238,7 @@
 check (const String &file,
        const String &mode)
 {
-  return birnet_file_check (file.c_str(), mode.c_str());
+  return file_check (file.c_str(), mode.c_str());
 }
 
 /**
@@ -255,7 +253,7 @@
 equals (const String &file1,
         const String &file2)
 {
-  return birnet_file_equals (file1.c_str(), file2.c_str());
+  return file_equals (file1.c_str(), file2.c_str());
 }
 
 } // Path
@@ -410,6 +408,12 @@
 
 /* --- ReferenceCountImpl --- */
 void
+ReferenceCountImpl::ref_diag (const char *msg) const
+{
+  fprintf (stderr, "%s: this=%p ref_count=%d floating=%d", msg ? msg : "ReferenceCountImpl", this, ref_count(), floating());
+}
+
+void
 ReferenceCountImpl::finalize ()
 {}
 

Modified: trunk/birnet/birnetutilsxx.hh
===================================================================
--- trunk/birnet/birnetutilsxx.hh	2006-10-05 15:52:43 UTC (rev 3935)
+++ trunk/birnet/birnetutilsxx.hh	2006-10-06 16:54:11 UTC (rev 3936)
@@ -20,7 +20,6 @@
 #define __BIRNET_UTILS_XX_HH__
 
 #include <birnet/birnetcore.h>
-#include <birnet/birnetmsg.h> // FIXME
 #include <string>
 #include <vector>
 #include <map>
@@ -228,11 +227,7 @@
         self->delete_this(); // effectively: delete this;
       }
   }
-  void
-  ref_diag (const char *msg = NULL) const
-  {
-    birnet_diag ("%s: this=%p ref_count=%d floating=%d", msg ? msg : "ReferenceCountImpl", this, ref_count(), floating()); // FIXME: use diag()
-  }
+  void                            ref_diag (const char *msg = NULL) const;
   template<class Obj> static Obj& ref      (Obj &obj) { obj.ref();       return obj; }
   template<class Obj> static Obj* ref      (Obj *obj) { obj->ref();      return obj; }
   template<class Obj> static Obj& ref_sink (Obj &obj) { obj.ref_sink();  return obj; }

Modified: trunk/birnet/tests/infotest.cc
===================================================================
--- trunk/birnet/tests/infotest.cc	2006-10-05 15:52:43 UTC (rev 3935)
+++ trunk/birnet/tests/infotest.cc	2006-10-06 16:54:11 UTC (rev 3936)
@@ -78,7 +78,7 @@
 {
   static const unsigned char TEST_DATA[] = "x\332K\312,\312K-\321\255\312\314+I-\312S(I-.QHI,I\4\0v\317\11V";
   TSTART ("ZIntern");
-  guint8 *data = birnet_zintern_decompress (24, TEST_DATA, sizeof (TEST_DATA) / sizeof (TEST_DATA[0]));
+  guint8 *data = zintern_decompress (24, TEST_DATA, sizeof (TEST_DATA) / sizeof (TEST_DATA[0]));
   TASSERT (String ((char*) data) == "birnet-zintern test data");
   g_free (data);
   TOK();




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]