summaryrefslogtreecommitdiffstats
path: root/mcop/debug.cc
diff options
context:
space:
mode:
Diffstat (limited to 'mcop/debug.cc')
-rw-r--r--mcop/debug.cc822
1 files changed, 0 insertions, 822 deletions
diff --git a/mcop/debug.cc b/mcop/debug.cc
deleted file mode 100644
index d2d00f8..0000000
--- a/mcop/debug.cc
+++ /dev/null
@@ -1,822 +0,0 @@
- /*
-
- Copyright (C) 2000-2002 Stefan Westerfeld
- stefan@space.twc.de
-
- (see also below for details on the copyright of arts_strdup_printf,
- which is taken from GLib)
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public License
- along with this library; see the file COPYING.LIB. If not, write to
- the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA.
-
- */
-
-#include "debug.h"
-#include <config.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <string.h>
-#include "thread.h"
-
-static int arts_debug_level = Arts::Debug::lInfo;
-static bool arts_debug_abort = false;
-static const char *arts_debug_prefix = "";
-static char *messageAppName = 0;
-static Arts::Mutex *arts_debug_mutex = 0;
-
-/* routines for variable length sprintf without buffer overflow (from GLib) */
-static char* arts_strdup_vprintf(const char *format, va_list args1);
-
-namespace Arts {
-
-static char * shell_quote(const char *s)
-{
- char *result;
- char *p;
- p = result = static_cast<char*>( malloc(strlen(s)*5+1) );
- while(*s)
- {
- if (*s == '\'')
- {
- *p++ = '\'';
- *p++ = '"';
- *p++ = *s++;
- *p++ = '"';
- *p++ = '\'';
- }
- else
- {
- *p++ = *s++;
- }
- }
- *p = '\0';
- return result;
-}
-
-/*
- * Call the graphical application to display a message, if
- * defined. Otherwise, send to standard error. Debug messages are
- * always sent to standard error because they tend to be very verbose.
- * Note that the external application is run in the background to
- * avoid blocking the sound server.
- */
-static void output_message(Debug::Level level, const char *msg) {
- char *quoted_msg;
- char *buff = 0;
-
- /* default to text output if no message app is defined or if it is a debug message. */
- if (messageAppName == 0 || !strcmp(messageAppName, "") || (level == Debug::lDebug))
- {
- fprintf(stderr, "%s\n", msg);
- return;
- }
-
- quoted_msg = shell_quote(msg);
- switch (level) {
- case Debug::lFatal:
- buff = arts_strdup_printf("%s -e 'Sound server fatal error:\n\n%s' &", messageAppName, quoted_msg);
- break;
- case Debug::lWarning:
- buff = arts_strdup_printf("%s -w 'Sound server warning message:\n\n%s' &", messageAppName, quoted_msg);
- break;
- case Debug::lInfo:
- buff = arts_strdup_printf("%s -i 'Sound server informational message:\n\n%s' &", messageAppName, quoted_msg);
- break;
- default:
- break; // avoid compile warning
- }
- free(quoted_msg);
-
- if(buff != 0)
- {
- system(buff);
- free(buff);
- }
-}
-
-/*
- * Display a message using output_message. If the message is the same
- * as the previous one, just increment a count but don't display
- * it. This prevents flooding the user with duplicate warnings. If the
- * message is not the same as the previous one, then we report the
- * previously repeated message (if any) and reset the last message and
- * count.
- */
-static void display_message(Debug::Level level, const char *msg) {
- static char lastMsg[1024];
- static Debug::Level lastLevel;
- static int msgCount = 0;
-
- if(arts_debug_mutex)
- arts_debug_mutex->lock();
-
- if (!strncmp(msg, lastMsg, 1024))
- {
- msgCount++;
- } else {
- if (msgCount > 0)
- {
- char *buff;
- buff = arts_strdup_printf("%s\n(The previous message was repeated %d times.)", lastMsg, msgCount);
- output_message(lastLevel, buff);
- free(buff);
- }
- strncpy(lastMsg, msg, 1024);
- lastMsg[ 1023 ] = '\0';
- lastLevel = level;
- msgCount = 0;
- output_message(level, msg);
- }
-
- if(arts_debug_mutex)
- arts_debug_mutex->unlock();
-}
-
-static class DebugInitFromEnv {
-public:
- DebugInitFromEnv() {
- const char *env = getenv("ARTS_DEBUG");
- if(env)
- {
- if(strcmp(env,"debug") == 0)
- arts_debug_level = Debug::lDebug;
- else if(strcmp(env,"info") == 0)
- arts_debug_level = Debug::lInfo;
- else if(strcmp(env,"warning") == 0)
- arts_debug_level = Debug::lWarning;
- else if(strcmp(env,"quiet") == 0)
- arts_debug_level = Debug::lFatal;
- else
- {
- fprintf(stderr,
- "ARTS_DEBUG must be one of debug,info,warning,quiet\n");
- }
- }
- env = getenv("ARTS_DEBUG_ABORT");
- if(env)
- arts_debug_abort = true;
- }
-} debugInitFromEnv;
-
-}
-
-void Arts::Debug::init(const char *prefix, Level level)
-{
- arts_debug_level = level;
- arts_debug_prefix = prefix;
-}
-
-void Arts::Debug::fatal(const char *fmt, ...)
-{
- char *buff;
- va_list ap;
-
- va_start(ap, fmt);
- buff = arts_strdup_vprintf(fmt, ap);
- va_end(ap);
-
- display_message(Debug::lFatal, buff);
- free(buff);
-
- if(arts_debug_abort) abort();
- exit(1);
-}
-
-void Arts::Debug::warning(const char *fmt, ...)
-{
- if(lWarning >= arts_debug_level)
- {
- char *buff;
- va_list ap;
-
- va_start(ap, fmt);
- buff = arts_strdup_vprintf(fmt, ap);
- va_end(ap);
-
- display_message(Debug::lWarning, buff);
- free(buff);
- }
-}
-
-void Arts::Debug::info(const char *fmt, ...)
-{
- if(lInfo >= arts_debug_level)
- {
- char *buff;
- va_list ap;
-
- va_start(ap, fmt);
- buff = arts_strdup_vprintf(fmt, ap);
- va_end(ap);
-
- display_message(Debug::lInfo, buff);
- free(buff);
- }
-}
-
-void Arts::Debug::debug(const char *fmt, ...)
-{
- if(lDebug >= arts_debug_level)
- {
- char *buff;
- va_list ap;
-
- va_start(ap, fmt);
- buff = arts_strdup_vprintf(fmt, ap);
- va_end(ap);
-
- display_message(Debug::lDebug, buff);
- free(buff);
- }
-}
-
-void Arts::Debug::messageApp(const char *appName)
-{
- messageAppName = (char*) realloc(messageAppName, strlen(appName)+1);
- strcpy(messageAppName, appName);
-}
-
-void Arts::Debug::initMutex()
-{
- arts_return_if_fail(arts_debug_mutex == 0);
-
- arts_debug_mutex = new Arts::Mutex();
-}
-
-void Arts::Debug::freeMutex()
-{
- arts_return_if_fail(arts_debug_mutex != 0);
-
- delete arts_debug_mutex;
- arts_debug_mutex = 0;
-}
-
-/*
- * For the sake of portability (snprintf is non-portable), what follows is an
- * implementation of a variant g_strdup_printf, to format debug messages of
- * an arbitary length appropriately. This is reduntant with flow/gsl/gslglib.c,
- * however, as libmcop doesn't necessarily link against gslglib.c, this is a
- * more-or-less complete copy.
- */
-
-/* GLIB - Library of useful routines for C programming
- * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
- *
- * GScanner: Flexible lexical scanner for general purpose.
- * Copyright (C) 1997, 1998 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., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-/*
- * Modified by the GLib Team and others 1997-2000. See the AUTHORS
- * file for a list of people on the GLib Team. See the ChangeLog
- * files for a list of changes. These files are distributed with
- * GLib at ftp://ftp.gtk.org/pub/gtk/.
- */
-
-
-#include <sys/types.h>
-#include <stdarg.h>
-#include <string.h>
-
-#define g_warning printf
-#define g_strerror strerror
-
-/*--- gslglib.h ---*/
-
-#include <limits.h>
-#include <float.h>
-#include <stddef.h>
-#include <stdarg.h>
-
-/* --- GLib typedefs --- */
-typedef void* gpointer;
-typedef const void* gconstpointer;
-typedef char gchar;
-typedef unsigned char guchar;
-typedef signed short gshort;
-typedef unsigned short gushort;
-typedef signed int gint;
-typedef unsigned int guint;
-typedef signed long glong;
-typedef unsigned long gulong;
-typedef float gfloat;
-typedef double gdouble;
-typedef size_t gsize;
-typedef gchar gint8;
-typedef guchar guint8;
-typedef gshort gint16;
-typedef gushort guint16;
-typedef gint gint32;
-typedef guint guint32;
-typedef gint gboolean;
-typedef gint32 GTime;
-#ifdef __alpha
-typedef long int gint64;
-typedef unsigned long int guint64;
-#else
-typedef long long int gint64;
-typedef unsigned long long int guint64;
-#endif
-typedef struct _GString GString;
-
-/* --- standard macros --- */
-#ifndef ABS
-#define ABS(a) ((a) > 0 ? (a) : -(a))
-#endif
-#ifndef MAX
-#define MAX(a,b) ((a) > (b) ? (a) : (b))
-#endif
-#ifndef MIN
-#define MIN(a,b) ((a) < (b) ? (a) : (b))
-#endif
-#ifndef CLAMP
-#define CLAMP(v,l,h) ((v) < (l) ? (l) : (v) > (h) ? (h) : (v))
-#endif
-#ifndef FALSE
-#define FALSE 0
-#endif
-#ifndef TRUE
-#define TRUE (!FALSE)
-#endif
-#ifndef NULL
-#define NULL ((void*) 0)
-#endif
-
-/* --- configure stuff!!! --- */
-#ifdef WORDS_BIGENDIAN
-#define G_BYTE_ORDER G_BIG_ENDIAN
-#else
-#define G_BYTE_ORDER G_LITTLE_ENDIAN
-#endif
-
-/* #define GLIB_HAVE_STPCPY 1 */
-/* Define G_VA_COPY() to do the right thing for copying va_list variables.
- * glibconfig.h may have already defined G_VA_COPY as va_copy or __va_copy.
- */
-#if !defined (G_VA_COPY)
-# if defined (__GNUC__) && defined (__PPC__) && (defined (_CALL_SYSV) || defined (_WIN32) || defined(WIN32)) || defined(__s390__) || defined(__x86_64__)
-# define G_VA_COPY(ap1, ap2) (*(ap1) = *(ap2))
-# elif defined (G_VA_COPY_AS_ARRAY)
-# define G_VA_COPY(ap1, ap2) g_memmove ((ap1), (ap2), sizeof (va_list))
-# else /* va_list is a pointer */
-# define G_VA_COPY(ap1, ap2) ((ap1) = (ap2))
-# endif /* va_list is a pointer */
-#endif /* !G_VA_COPY */
-
-/* --- glib macros --- */
-#define G_MINFLOAT FLT_MIN
-#define G_MAXFLOAT FLT_MAX
-#define G_MINDOUBLE DBL_MIN
-#define G_MAXDOUBLE DBL_MAX
-#define G_MINSHORT SHRT_MIN
-#define G_MAXSHORT SHRT_MAX
-#define G_MAXUSHORT USHRT_MAX
-#define G_MININT INT_MIN
-#define G_MAXINT INT_MAX
-#define G_MAXUINT UINT_MAX
-#define G_MINLONG LONG_MIN
-#define G_MAXLONG LONG_MAX
-#define G_MAXULONG ULONG_MAX
-#define G_USEC_PER_SEC 1000000
-#define G_LITTLE_ENDIAN 1234
-#define G_BIG_ENDIAN 4321
-
-#define G_STRINGIFY(macro_or_string) G_STRINGIFY_ARG (macro_or_string)
-#define G_STRINGIFY_ARG(contents) #contents
-#if defined __GNUC__ && !defined __cplusplus
-# define G_STRLOC __FILE__ ":" G_STRINGIFY (__LINE__) ":" __PRETTY_FUNCTION__ "()"
-#else
-# define G_STRLOC __FILE__ ":" G_STRINGIFY (__LINE__)
-#endif
-
-/* subtract from biased_exponent to form base2 exponent (normal numbers) */
-typedef union _GDoubleIEEE754 GDoubleIEEE754;
-typedef union _GFloatIEEE754 GFloatIEEE754;
-#define G_IEEE754_FLOAT_BIAS (127)
-#define G_IEEE754_DOUBLE_BIAS (1023)
-/* multiply with base2 exponent to get base10 exponent (nomal numbers) */
-#define G_LOG_2_BASE_10 (0.30102999566398119521)
-#if G_BYTE_ORDER == G_LITTLE_ENDIAN
-union _GFloatIEEE754
-{
- gfloat v_float;
- struct {
- guint mantissa : 23;
- guint biased_exponent : 8;
- guint sign : 1;
- } mpn;
-};
-union _GDoubleIEEE754
-{
- gdouble v_double;
- struct {
- guint mantissa_low : 32;
- guint mantissa_high : 20;
- guint biased_exponent : 11;
- guint sign : 1;
- } mpn;
-};
-#elif G_BYTE_ORDER == G_BIG_ENDIAN
-union _GFloatIEEE754
-{
- gfloat v_float;
- struct {
- guint sign : 1;
- guint biased_exponent : 8;
- guint mantissa : 23;
- } mpn;
-};
-union _GDoubleIEEE754
-{
- gdouble v_double;
- struct {
- guint sign : 1;
- guint biased_exponent : 11;
- guint mantissa_high : 20;
- guint mantissa_low : 32;
- } mpn;
-};
-#else /* !G_LITTLE_ENDIAN && !G_BIG_ENDIAN */
-#error unknown ENDIAN type
-#endif /* !G_LITTLE_ENDIAN && !G_BIG_ENDIAN */
-
-#include <errno.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <stdio.h>
-
-#define GLIB_SIZEOF_INTMAX (8 /* educated guess */)
-
-typedef struct
-{
- guint min_width;
- guint precision;
- gboolean alternate_format, zero_padding, adjust_left, locale_grouping;
- gboolean add_space, add_sign, possible_sign, seen_precision;
- gboolean mod_half, mod_long, mod_extra_long;
-} PrintfArgSpec;
-
-
-static gsize
-printf_string_upper_bound (const gchar *format,
- gboolean may_warn,
- va_list args)
-{
- static gboolean honour_longs = sizeof(long) > 4 || sizeof(void*) > 4;
- gsize len = 1;
-
- if (!format)
- return len;
-
- while (*format)
- {
- gchar c = *format++;
-
- if (c != '%')
- len += 1;
- else /* (c == '%') */
- {
- PrintfArgSpec spec = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
- gboolean seen_l = FALSE, conv_done = FALSE;
- gsize conv_len = 0;
- const gchar *spec_start = format;
-
- do
- {
- c = *format++;
- switch (c)
- {
- GDoubleIEEE754 u_double;
- guint v_uint;
- gint v_int;
- const gchar *v_string;
-
- /* beware of positional parameters
- */
- case '$':
- if (may_warn)
- g_warning (G_STRLOC ": unable to handle positional parameters (%%n$)");
- len += 1024; /* try adding some safety padding */
- break;
-
- /* parse flags
- */
- case '#':
- spec.alternate_format = TRUE;
- break;
- case '0':
- spec.zero_padding = TRUE;
- break;
- case '-':
- spec.adjust_left = TRUE;
- break;
- case ' ':
- spec.add_space = TRUE;
- break;
- case '+':
- spec.add_sign = TRUE;
- break;
- case '\'':
- spec.locale_grouping = TRUE;
- break;
-
- /* parse output size specifications
- */
- case '.':
- spec.seen_precision = TRUE;
- break;
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- v_uint = c - '0';
- c = *format;
- while (c >= '0' && c <= '9')
- {
- format++;
- v_uint = v_uint * 10 + c - '0';
- c = *format;
- }
- if (spec.seen_precision)
- spec.precision = MAX (spec.precision, v_uint);
- else
- spec.min_width = MAX (spec.min_width, v_uint);
- break;
- case '*':
- v_int = va_arg (args, int);
- if (spec.seen_precision)
- {
- /* forget about negative precision */
- if (v_int >= 0)
- spec.precision = MAX (spec.precision, (unsigned)v_int);
- }
- else
- {
- if (v_int < 0)
- {
- v_int = - v_int;
- spec.adjust_left = TRUE;
- }
- spec.min_width = MAX (spec.min_width, (unsigned)v_int);
- }
- break;
-
- /* parse type modifiers
- */
- case 'h':
- spec.mod_half = TRUE;
- break;
- case 'l':
- if (!seen_l)
- {
- spec.mod_long = TRUE;
- seen_l = TRUE;
- break;
- }
- /* else, fall through */
- case 'L':
- case 'q':
- spec.mod_long = TRUE;
- spec.mod_extra_long = TRUE;
- break;
- case 'z':
- case 'Z':
- if (sizeof(size_t))
- {
- spec.mod_long = TRUE;
- spec.mod_extra_long = TRUE;
- }
- break;
- case 't':
- if (sizeof(ptrdiff_t) > 4)
- {
- spec.mod_long = TRUE;
- spec.mod_extra_long = TRUE;
- }
- break;
- case 'j':
- if (GLIB_SIZEOF_INTMAX > 4)
- {
- spec.mod_long = TRUE;
- spec.mod_extra_long = TRUE;
- }
- break;
-
- /* parse output conversions
- */
- case '%':
- conv_len += 1;
- break;
- case 'O':
- case 'D':
- case 'I':
- case 'U':
- /* some C libraries feature long variants for these as well? */
- spec.mod_long = TRUE;
- /* fall through */
- case 'o':
- conv_len += 2;
- /* fall through */
- case 'd':
- case 'i':
- conv_len += 1; /* sign */
- /* fall through */
- case 'u':
- conv_len += 4;
- /* fall through */
- case 'x':
- case 'X':
- spec.possible_sign = TRUE;
- conv_len += 10;
- if (spec.mod_long && honour_longs)
- conv_len *= 2;
- if (spec.mod_extra_long)
- conv_len *= 2;
- if (spec.mod_extra_long)
- {
- (void) va_arg (args, gint64);
- }
- else if (spec.mod_long)
- (void) va_arg (args, long);
- else
- (void) va_arg (args, int);
- break;
- case 'A':
- case 'a':
- /* 0x */
- conv_len += 2;
- /* fall through */
- case 'g':
- case 'G':
- case 'e':
- case 'E':
- case 'f':
- spec.possible_sign = TRUE;
- /* n . dddddddddddddddddddddddd E +- eeee */
- conv_len += 1 + 1 + MAX (24, spec.precision) + 1 + 1 + 4;
- if (may_warn && spec.mod_extra_long)
- g_warning (G_STRLOC ": unable to handle long double, collecting double only");
-#ifdef HAVE_LONG_DOUBLE
-#error need to implement special handling for long double
-#endif
- u_double.v_double = va_arg (args, double);
- /* %f can expand up to all significant digits before '.' (308) */
- if (c == 'f' &&
- u_double.mpn.biased_exponent > 0 && u_double.mpn.biased_exponent < 2047)
- {
- gint exp = u_double.mpn.biased_exponent;
-
- exp -= G_IEEE754_DOUBLE_BIAS;
- exp = (gint)(exp * G_LOG_2_BASE_10 + 1);
- conv_len += ABS (exp); /* exp can be <0 */
- }
- /* some printf() implementations require extra padding for rounding */
- conv_len += 2;
- /* we can't really handle locale specific grouping here */
- if (spec.locale_grouping)
- conv_len *= 2;
- break;
- case 'C':
- spec.mod_long = TRUE;
- /* fall through */
- case 'c':
- conv_len += spec.mod_long ? MB_LEN_MAX : 1;
- (void) va_arg (args, int);
- break;
- case 'S':
- spec.mod_long = TRUE;
- /* fall through */
- case 's':
- v_string = va_arg (args, char*);
- if (!v_string)
- conv_len += 8; /* hold "(null)" */
- else if (spec.seen_precision)
- conv_len += spec.precision;
- else
- conv_len += strlen (v_string);
- conv_done = TRUE;
- if (spec.mod_long)
- {
- if (may_warn)
- g_warning (G_STRLOC": unable to handle wide char strings");
- len += 1024; /* try adding some safety padding */
- }
- break;
- case 'P': /* do we actually need this? */
- /* fall through */
- case 'p':
- spec.alternate_format = TRUE;
- conv_len += 10;
- if (honour_longs)
- conv_len *= 2;
- /* fall through */
- case 'n':
- conv_done = TRUE;
- (void) va_arg (args, void*);
- break;
- case 'm':
- /* there's not much we can do to be clever */
- v_string = g_strerror (errno);
- v_uint = v_string ? strlen (v_string) : 0;
- conv_len += MAX (256, v_uint);
- break;
-
- /* handle invalid cases
- */
- case '\000':
- /* no conversion specification, bad bad */
- conv_len += format - spec_start;
- break;
- default:
- if (may_warn)
- g_warning (G_STRLOC": unable to handle `%c' while parsing format",
- c);
- break;
- }
- conv_done |= conv_len > 0;
- }
- while (!conv_done);
- /* handle width specifications */
- conv_len = MAX (conv_len, MAX (spec.precision, spec.min_width));
- /* handle flags */
- conv_len += spec.alternate_format ? 2 : 0;
- conv_len += (spec.add_space || spec.add_sign || spec.possible_sign);
- /* finally done */
- len += conv_len;
- } /* else (c == '%') */
- } /* while (*format) */
-
- return len;
-}
-
-static char*
-#ifdef __GNUC__
-__attribute__ ( (format (printf, 1, 0) ) )
-#endif
-arts_strdup_vprintf (const char *format, va_list args1)
-{
- gchar *buffer;
-#ifdef HAVE_VASPRINTF
- if (vasprintf (&buffer, format, args1) < 0)
- buffer = NULL;
-#else
- va_list args2;
-
- G_VA_COPY (args2, args1);
-
- buffer = (gchar *)malloc (printf_string_upper_bound (format, TRUE, args1));
-
- vsprintf (buffer, format, args2);
- va_end (args2);
-#endif
- return buffer;
-}
-
-char*
-#ifdef __GNUC__
-__attribute__ ( (format (printf, 1, 0) ) )
-#endif
-arts_strdup_printf (const char *format, ...)
-{
- gchar *buffer;
- va_list args;
-
- va_start (args, format);
- buffer = arts_strdup_vprintf (format, args);
- va_end (args);
-
- return buffer;
-}