⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gmessages.c

📁 嵌入式下基于MiniGUI的Web Browser
💻 C
📖 第 1 页 / 共 2 页
字号:
/* GLIB - Library of useful routines for C programming * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald * * 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. *//* * 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/.  *//*  * MT safe */#ifdef HAVE_CONFIG_H#include "glibconfig.h"#endif#include <stdlib.h>#include <stdarg.h>#include <stdio.h>#include <string.h>#include "glib.h"#ifdef HAVE_UNISTD_H#include <unistd.h>#endif#include <signal.h>#include <locale.h>#include <errno.h>#include "gdebug.h"#ifdef G_OS_WIN32typedef FILE* GFileDescriptor;#elsetypedef gint GFileDescriptor;#endif/* --- structures --- */typedef struct _GLogDomain	GLogDomain;typedef struct _GLogHandler	GLogHandler;struct _GLogDomain{  gchar		*log_domain;  GLogLevelFlags fatal_mask;  GLogHandler	*handlers;  GLogDomain	*next;};struct _GLogHandler{  guint		 id;  GLogLevelFlags log_level;  GLogFunc	 log_func;  gpointer	 data;  GLogHandler	*next;};/* --- prototypes --- */#ifndef HAVE_C99_VSNPRINTFstatic gsize printf_string_upper_bound (const gchar *format,					gboolean     may_warn,					va_list      args);#endif /* !HAVE_C99_VSNPRINTF *//* --- variables --- */static GMutex        *g_messages_lock = NULL;static GLogDomain    *g_log_domains = NULL;static GLogLevelFlags g_log_always_fatal = G_LOG_FATAL_MASK;static GPrintFunc     glib_print_func = NULL;static GPrintFunc     glib_printerr_func = NULL;static GPrivate	     *g_log_depth = NULL;static GLogLevelFlags g_log_msg_prefix = G_LOG_LEVEL_ERROR | G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_DEBUG;/* --- functions --- */#ifdef G_OS_WIN32#  define STRICT#  include <windows.h>#  undef STRICT#  include <process.h>          /* For _getpid() */static gboolean alloc_console_called = FALSE;static gboolean win32_keep_fatal_message = FALSE;/* This default message will usually be overwritten. *//* Yes, a fixed size buffer is bad. So sue me. But g_error is never * with huge strings, is it? */static gchar  fatal_msg_buf[1000] = "Unspecified fatal error encountered, aborting.";static gchar *fatal_msg_ptr = fatal_msg_buf;/* Just use stdio. If we're out of memory, we're hosed anyway. */#undef writestatic inline intdowrite (GFileDescriptor fd,	 const void  *buf,	 unsigned int len){  if (win32_keep_fatal_message)    {      memcpy (fatal_msg_ptr, buf, len);      fatal_msg_ptr += len;      *fatal_msg_ptr = 0;      return len;    }  fwrite (buf, len, 1, fd);  fflush (fd);  return len;}#define write(fd, buf, len) dowrite(fd, buf, len)static voidensure_stdout_valid (void){  HANDLE handle;  if (win32_keep_fatal_message)    return;  if (!alloc_console_called)    {      handle = GetStdHandle (STD_OUTPUT_HANDLE);        if (handle == INVALID_HANDLE_VALUE)	{	  AllocConsole ();	  alloc_console_called = TRUE;	  freopen ("CONOUT$", "w", stdout);	}    }}#else#define ensure_stdout_valid()	/* Define as empty */#endifstatic voidwrite_string (GFileDescriptor fd,	      const gchar    *string){  write (fd, string, strlen (string));}static voidg_messages_prefixed_init (void){  static gboolean initialized = FALSE;  if (!initialized)    {      const gchar *val;      initialized = TRUE;      val = g_getenv ("G_MESSAGES_PREFIXED");            if (val)	{	  static const GDebugKey keys[] = {	    { "error", G_LOG_LEVEL_ERROR },	    { "critical", G_LOG_LEVEL_CRITICAL },	    { "warning", G_LOG_LEVEL_WARNING },	    { "message", G_LOG_LEVEL_MESSAGE },	    { "info", G_LOG_LEVEL_INFO },	    { "debug", G_LOG_LEVEL_DEBUG }	  };	  	  g_log_msg_prefix = g_parse_debug_string (val, keys, G_N_ELEMENTS (keys));	}    }}static GLogDomain*g_log_find_domain_L (const gchar *log_domain){  register GLogDomain *domain;    domain = g_log_domains;  while (domain)    {      if (strcmp (domain->log_domain, log_domain) == 0)	return domain;      domain = domain->next;    }  return NULL;}static GLogDomain*g_log_domain_new_L (const gchar *log_domain){  register GLogDomain *domain;  domain = g_new (GLogDomain, 1);  domain->log_domain = g_strdup (log_domain);  domain->fatal_mask = G_LOG_FATAL_MASK;  domain->handlers = NULL;    domain->next = g_log_domains;  g_log_domains = domain;    return domain;}static voidg_log_domain_check_free_L (GLogDomain *domain){  if (domain->fatal_mask == G_LOG_FATAL_MASK &&      domain->handlers == NULL)    {      register GLogDomain *last, *work;            last = NULL;        work = g_log_domains;      while (work)	{	  if (work == domain)	    {	      if (last)		last->next = domain->next;	      else		g_log_domains = domain->next;	      g_free (domain->log_domain);	      g_free (domain);	      break;	    }	  last = work;	  work = last->next;	}      }}static GLogFuncg_log_domain_get_handler_L (GLogDomain	*domain,			    GLogLevelFlags log_level,			    gpointer	*data){  if (domain && log_level)    {      register GLogHandler *handler;            handler = domain->handlers;      while (handler)	{	  if ((handler->log_level & log_level) == log_level)	    {	      *data = handler->data;	      return handler->log_func;	    }	  handler = handler->next;	}    }  return g_log_default_handler;}GLogLevelFlagsg_log_set_always_fatal (GLogLevelFlags fatal_mask){  GLogLevelFlags old_mask;  /* restrict the global mask to levels that are known to glib   * since this setting applies to all domains   */  fatal_mask &= (1 << G_LOG_LEVEL_USER_SHIFT) - 1;  /* force errors to be fatal */  fatal_mask |= G_LOG_LEVEL_ERROR;  /* remove bogus flag */  fatal_mask &= ~G_LOG_FLAG_FATAL;  g_mutex_lock (g_messages_lock);  old_mask = g_log_always_fatal;  g_log_always_fatal = fatal_mask;  g_mutex_unlock (g_messages_lock);  return old_mask;}GLogLevelFlagsg_log_set_fatal_mask (const gchar   *log_domain,		      GLogLevelFlags fatal_mask){  GLogLevelFlags old_flags;  register GLogDomain *domain;    if (!log_domain)    log_domain = "";    /* force errors to be fatal */  fatal_mask |= G_LOG_LEVEL_ERROR;  /* remove bogus flag */  fatal_mask &= ~G_LOG_FLAG_FATAL;    g_mutex_lock (g_messages_lock);  domain = g_log_find_domain_L (log_domain);  if (!domain)    domain = g_log_domain_new_L (log_domain);  old_flags = domain->fatal_mask;    domain->fatal_mask = fatal_mask;  g_log_domain_check_free_L (domain);  g_mutex_unlock (g_messages_lock);  return old_flags;}guintg_log_set_handler (const gchar	 *log_domain,		   GLogLevelFlags log_levels,		   GLogFunc	  log_func,		   gpointer	  user_data){  static guint handler_id = 0;  GLogDomain *domain;  GLogHandler *handler;    g_return_val_if_fail ((log_levels & G_LOG_LEVEL_MASK) != 0, 0);  g_return_val_if_fail (log_func != NULL, 0);    if (!log_domain)    log_domain = "";  handler = g_new (GLogHandler, 1);  g_mutex_lock (g_messages_lock);  domain = g_log_find_domain_L (log_domain);  if (!domain)    domain = g_log_domain_new_L (log_domain);    handler->id = ++handler_id;  handler->log_level = log_levels;  handler->log_func = log_func;  handler->data = user_data;  handler->next = domain->handlers;  domain->handlers = handler;  g_mutex_unlock (g_messages_lock);    return handler_id;}voidg_log_remove_handler (const gchar *log_domain,		      guint	   handler_id){  register GLogDomain *domain;    g_return_if_fail (handler_id > 0);    if (!log_domain)    log_domain = "";    g_mutex_lock (g_messages_lock);  domain = g_log_find_domain_L (log_domain);  if (domain)    {      GLogHandler *work, *last;            last = NULL;      work = domain->handlers;      while (work)	{	  if (work->id == handler_id)	    {	      if (last)		last->next = work->next;	      else		domain->handlers = work->next;	      g_log_domain_check_free_L (domain); 	      g_mutex_unlock (g_messages_lock);	      g_free (work);	      return;	    }	  last = work;	  work = last->next;	}    }   g_mutex_unlock (g_messages_lock);  g_warning ("%s: could not find handler with id `%d' for domain \"%s\"",	     G_STRLOC, handler_id, log_domain);}voidg_logv (const gchar   *log_domain,	GLogLevelFlags log_level,	const gchar   *format,	va_list	       args1){  gchar buffer[1025];  gboolean was_fatal = (log_level & G_LOG_FLAG_FATAL) != 0;  gboolean was_recursion = (log_level & G_LOG_FLAG_RECURSION) != 0;  gint i;#ifndef  HAVE_VSNPRINTF  va_list args2;#endif	/* HAVE_VSNPRINTF */    log_level &= G_LOG_LEVEL_MASK;  if (!log_level)    return;    /* we use a stack buffer of fixed size, because we might get called   * recursively.   */#ifdef  HAVE_VSNPRINTF  vsnprintf (buffer, 1024, format, args1);#else	/* !HAVE_VSNPRINTF */  G_VA_COPY (args2, args1);  if (printf_string_upper_bound (format, FALSE, args1) < 1024)    vsprintf (buffer, format, args2);  else    {      /* since we might be out of memory, we can't use g_vsnprintf(). */      /* we are out of luck here */      strncpy (buffer, format, 1024);      buffer[1024] = 0;    }  va_end (args2);#endif	/* !HAVE_VSNPRINTF */    for (i = g_bit_nth_msf (log_level, -1); i >= 0; i = g_bit_nth_msf (log_level, i))    {      register GLogLevelFlags test_level;            test_level = 1 << i;      if (log_level & test_level)	{	  guint depth = GPOINTER_TO_UINT (g_private_get (g_log_depth));	  GLogDomain *domain;	  GLogFunc log_func;	  guint domain_fatal_mask;	  gpointer data = NULL;	  if (was_fatal)	    test_level |= G_LOG_FLAG_FATAL;	  if (was_recursion)	    test_level |= G_LOG_FLAG_RECURSION;	  /* check recursion and lookup handler */	  g_mutex_lock (g_messages_lock);	  domain = g_log_find_domain_L (log_domain ? log_domain : "");	  if (depth)	    test_level |= G_LOG_FLAG_RECURSION;	  depth++;	  domain_fatal_mask = domain ? domain->fatal_mask : G_LOG_FATAL_MASK;	  if ((domain_fatal_mask | g_log_always_fatal) & test_level)	    test_level |= G_LOG_FLAG_FATAL;	  if (test_level & G_LOG_FLAG_RECURSION)	    log_func = _g_log_fallback_handler;	  else	    log_func = g_log_domain_get_handler_L (domain, test_level, &data);	  domain = NULL;	  g_mutex_unlock (g_messages_lock);	  g_private_set (g_log_depth, GUINT_TO_POINTER (depth));	  /* had to defer debug initialization until we can keep track of recursion */	  if (!(test_level & G_LOG_FLAG_RECURSION) && !_g_debug_initialized)	    {	      guint orig_test_level = test_level;	      _g_debug_init ();	      if ((domain_fatal_mask | g_log_always_fatal) & test_level)		test_level |= G_LOG_FLAG_FATAL;	      if (test_level != orig_test_level)		{		  /* need a relookup, not nice, but not too bad either */		  g_mutex_lock (g_messages_lock);		  domain = g_log_find_domain_L (log_domain ? log_domain : "");		  log_func = g_log_domain_get_handler_L (domain, test_level, &data);		  domain = NULL;		  g_mutex_unlock (g_messages_lock);		}	    }	  log_func (log_domain, test_level, buffer, data);	  if (test_level & G_LOG_FLAG_FATAL)	    {#ifdef G_OS_WIN32	      MessageBox (NULL, fatal_msg_buf, NULL, MB_OK);#endif#if defined (G_ENABLE_DEBUG) && (defined (SIGTRAP) || defined (G_OS_WIN32))	      if (!(test_level & G_LOG_FLAG_RECURSION))		G_BREAKPOINT ();	      else		abort ();#else /* !G_ENABLE_DEBUG || !(SIGTRAP || G_OS_WIN32) */	      abort ();#endif /* !G_ENABLE_DEBUG || !(SIGTRAP || G_OS_WIN32) */	    }	  	  depth--;	  g_private_set (g_log_depth, GUINT_TO_POINTER (depth));	}    }}voidg_log (const gchar   *log_domain,       GLogLevelFlags log_level,       const gchar   *format,       ...){  va_list args;    va_start (args, format);  g_logv (log_domain, log_level, format, args);  va_end (args);}#if 0static gchar*strdup_convert (const gchar *string,		const gchar *charset){  if (!g_utf8_validate (string, -1, NULL))    return g_strconcat ("[Invalid UTF-8] ", string, NULL);  else    {      GError *err = NULL;            gchar *result = g_convert_with_fallback (string, -1, charset, "UTF-8", "?", NULL, NULL, &err);      if (result)	return result;      else	{	  /* Not thread-safe, but doesn't matter if we print the warning twice	   */	  static gboolean warned = FALSE; 	  if (!warned)	    {	      warned = TRUE;	      fprintf (stderr, "GLib: Cannot convert message: %s\n", err->message);	    }	  g_error_free (err);	  	  return g_strdup (string);	}    }}#endif/* For a radix of 8 we need at most 3 output bytes for 1 input * byte. Additionally we might need up to 2 output bytes for the * readix prefix and 1 byte for the trailing NULL. */#define FORMAT_UNSIGNED_BUFSIZE ((GLIB_SIZEOF_LONG * 3) + 3)static voidformat_unsigned (gchar  *buf,		 gulong  num,		 guint   radix){  gulong tmp;  gchar c;  gint i, n;  /* we may not call _any_ GLib functions here (or macros like g_return_if_fail()) */  if (radix != 8 && radix != 10 && radix != 16)    {      *buf = '\000';      return;    }    if (!num)    {      *buf++ = '0';      *buf = '\000';      return;    }     if (radix == 16)    {      *buf++ = '0';      *buf++ = 'x';    }  else if (radix == 8)    {      *buf++ = '0';    }	  n = 0;  tmp = num;  while (tmp)    {      tmp /= radix;      n++;    }  i = n;  /* Again we can't use g_assert; actually this check should _never_ fail. */  if (n > FORMAT_UNSIGNED_BUFSIZE - 3)    {      *buf = '\000';      return;    }  while (num)    {      i--;      c = (num % radix);      if (c < 10)	buf[i] = c + '0';      else	buf[i] = c + 'a' - 10;      num /= radix;    }    buf[n] = '\000';}/* string size big enough to hold level prefix */#define	STRING_BUFFER_SIZE	(FORMAT_UNSIGNED_BUFSIZE + 32)#define	ALERT_LEVELS		(G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING)static GFileDescriptormklevel_prefix (gchar level_prefix[STRING_BUFFER_SIZE],		guint log_level){  gboolean to_stdout = TRUE;  /* we may not call _any_ GLib functions here */  switch (log_level & G_LOG_LEVEL_MASK)    {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -