r3936 - in trunk/birnet: . tests
- From: timj svn gnome org
- To: svn-commits-list gnome org
- Subject: r3936 - in trunk/birnet: . tests
- Date: Fri, 6 Oct 2006 12:54:25 -0400 (EDT)
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]