1 /* GLIB - Library of useful routines for C programming
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
21 * Modified by the GLib Team and others 1997-1999. See the AUTHORS
22 * file for a list of people on the GLib Team. See the ChangeLog
23 * files for a list of changes. These files are distributed with
24 * GLib at ftp://ftp.gtk.org/pub/gtk/.
47 # include <process.h> /* For _getpid() */
49 /* Just use stdio. If we're out of memory, we're hosed anyway. */
57 fwrite (buf, len, 1, fd);
63 ensure_stdout_valid (void)
67 handle = GetStdHandle (STD_OUTPUT_HANDLE);
69 if (handle == INVALID_HANDLE_VALUE)
72 freopen ("CONOUT$", "w", stdout);
76 #define ensure_stdout_valid() /* Define as empty */
80 /* --- structures --- */
81 typedef struct _GLogDomain GLogDomain;
82 typedef struct _GLogHandler GLogHandler;
86 GLogLevelFlags fatal_mask;
87 GLogHandler *handlers;
93 GLogLevelFlags log_level;
100 /* --- variables --- */
102 static GMutex* g_messages_lock = NULL;
104 const gchar *g_log_domain_glib = "GLib";
105 static GLogDomain *g_log_domains = NULL;
106 static GLogLevelFlags g_log_always_fatal = G_LOG_FATAL_MASK;
107 static GPrintFunc glib_print_func = NULL;
108 static GPrintFunc glib_printerr_func = NULL;
109 static GErrorFunc glib_error_func = NULL;
110 static GWarningFunc glib_warning_func = NULL;
111 static GPrintFunc glib_message_func = NULL;
113 static GPrivate* g_log_depth = NULL;
116 /* --- functions --- */
117 static inline GLogDomain*
118 g_log_find_domain (const gchar *log_domain)
120 register GLogDomain *domain;
122 g_mutex_lock (g_messages_lock);
123 domain = g_log_domains;
126 if (strcmp (domain->log_domain, log_domain) == 0)
128 g_mutex_unlock (g_messages_lock);
131 domain = domain->next;
133 g_mutex_unlock (g_messages_lock);
137 static inline GLogDomain*
138 g_log_domain_new (const gchar *log_domain)
140 register GLogDomain *domain;
142 domain = g_new (GLogDomain, 1);
143 domain->log_domain = g_strdup (log_domain);
144 domain->fatal_mask = G_LOG_FATAL_MASK;
145 domain->handlers = NULL;
147 g_mutex_lock (g_messages_lock);
148 domain->next = g_log_domains;
149 g_log_domains = domain;
150 g_mutex_unlock (g_messages_lock);
156 g_log_domain_check_free (GLogDomain *domain)
158 if (domain->fatal_mask == G_LOG_FATAL_MASK &&
159 domain->handlers == NULL)
161 register GLogDomain *last, *work;
165 g_mutex_lock (g_messages_lock);
166 work = g_log_domains;
172 last->next = domain->next;
174 g_log_domains = domain->next;
175 g_free (domain->log_domain);
181 g_mutex_unlock (g_messages_lock);
185 static inline GLogFunc
186 g_log_domain_get_handler (GLogDomain *domain,
187 GLogLevelFlags log_level,
190 if (domain && log_level)
192 register GLogHandler *handler;
194 handler = domain->handlers;
197 if ((handler->log_level & log_level) == log_level)
199 *data = handler->data;
200 return handler->log_func;
202 handler = handler->next;
205 return g_log_default_handler;
209 g_log_set_always_fatal (GLogLevelFlags fatal_mask)
211 GLogLevelFlags old_mask;
213 /* restrict the global mask to levels that are known to glib */
214 fatal_mask &= (1 << G_LOG_LEVEL_USER_SHIFT) - 1;
215 /* force errors to be fatal */
216 fatal_mask |= G_LOG_LEVEL_ERROR;
217 /* remove bogus flag */
218 fatal_mask &= ~G_LOG_FLAG_FATAL;
220 g_mutex_lock (g_messages_lock);
221 old_mask = g_log_always_fatal;
222 g_log_always_fatal = fatal_mask;
223 g_mutex_unlock (g_messages_lock);
229 g_log_set_fatal_mask (const gchar *log_domain,
230 GLogLevelFlags fatal_mask)
232 GLogLevelFlags old_flags;
233 register GLogDomain *domain;
238 /* force errors to be fatal */
239 fatal_mask |= G_LOG_LEVEL_ERROR;
240 /* remove bogus flag */
241 fatal_mask &= ~G_LOG_FLAG_FATAL;
243 domain = g_log_find_domain (log_domain);
245 domain = g_log_domain_new (log_domain);
246 old_flags = domain->fatal_mask;
248 domain->fatal_mask = fatal_mask;
249 g_log_domain_check_free (domain);
255 g_log_set_handler (const gchar *log_domain,
256 GLogLevelFlags log_levels,
260 register GLogDomain *domain;
261 register GLogHandler *handler;
262 static guint handler_id = 0;
264 g_return_val_if_fail ((log_levels & G_LOG_LEVEL_MASK) != 0, 0);
265 g_return_val_if_fail (log_func != NULL, 0);
270 domain = g_log_find_domain (log_domain);
272 domain = g_log_domain_new (log_domain);
274 handler = g_new (GLogHandler, 1);
275 g_mutex_lock (g_messages_lock);
276 handler->id = ++handler_id;
277 g_mutex_unlock (g_messages_lock);
278 handler->log_level = log_levels;
279 handler->log_func = log_func;
280 handler->data = user_data;
281 handler->next = domain->handlers;
282 domain->handlers = handler;
288 g_log_remove_handler (const gchar *log_domain,
291 register GLogDomain *domain;
293 g_return_if_fail (handler_id > 0);
298 domain = g_log_find_domain (log_domain);
301 register GLogHandler *work, *last;
304 work = domain->handlers;
307 if (work->id == handler_id)
310 last->next = work->next;
312 domain->handlers = work->next;
314 g_log_domain_check_free (domain);
320 g_warning ("g_log_remove_handler(): could not find handler with id `%d' for domain \"%s\"",
326 g_logv (const gchar *log_domain,
327 GLogLevelFlags log_level,
335 log_level &= G_LOG_LEVEL_MASK;
339 /* we use a stack buffer of fixed size, because we might get called
342 G_VA_COPY (args2, args1);
343 if (g_printf_string_upper_bound (format, args1) < 1024)
344 vsprintf (buffer, format, args2);
347 /* since we might be out of memory, we can't use g_vsnprintf(). */
348 #ifdef HAVE_VSNPRINTF
349 vsnprintf (buffer, 1024, format, args2);
350 #else /* !HAVE_VSNPRINTF */
351 /* we are out of luck here */
352 strncpy (buffer, format, 1024);
353 #endif /* !HAVE_VSNPRINTF */
358 for (i = g_bit_nth_msf (log_level, -1); i >= 0; i = g_bit_nth_msf (log_level, i))
360 register GLogLevelFlags test_level;
363 if (log_level & test_level)
365 guint depth = GPOINTER_TO_UINT (g_private_get (g_log_depth));
368 gpointer data = NULL;
370 domain = g_log_find_domain (log_domain ? log_domain : "");
373 test_level |= G_LOG_FLAG_RECURSION;
376 g_private_set (g_log_depth, GUINT_TO_POINTER (depth));
378 g_mutex_lock (g_messages_lock);
379 if ((((domain ? domain->fatal_mask : G_LOG_FATAL_MASK) |
380 g_log_always_fatal) & test_level) != 0)
381 test_level |= G_LOG_FLAG_FATAL;
382 g_mutex_unlock (g_messages_lock);
384 log_func = g_log_domain_get_handler (domain, test_level, &data);
385 log_func (log_domain, test_level, buffer, data);
387 /* *domain can be cluttered now */
389 if (test_level & G_LOG_FLAG_FATAL)
393 g_private_set (g_log_depth, GUINT_TO_POINTER (depth));
399 g_log (const gchar *log_domain,
400 GLogLevelFlags log_level,
406 va_start (args, format);
407 g_logv (log_domain, log_level, format, args);
412 g_log_default_handler (const gchar *log_domain,
413 GLogLevelFlags log_level,
414 const gchar *message,
415 gpointer unused_data)
422 gboolean in_recursion;
424 GErrorFunc local_glib_error_func;
425 GWarningFunc local_glib_warning_func;
426 GPrintFunc local_glib_message_func;
427 gchar prg_pid[64], *prg_name = g_get_prgname ();
429 in_recursion = (log_level & G_LOG_FLAG_RECURSION) != 0;
430 is_fatal = (log_level & G_LOG_FLAG_FATAL) != 0;
431 log_level &= G_LOG_LEVEL_MASK;
434 message = "g_log_default_handler(): (NULL) message";
437 prg_name = "(process";
438 sprintf (prg_pid, ":%u): ", getpid ());
441 sprintf (prg_pid, " (pid:%u): ", getpid ());
444 /* Use just stdout as stderr is hard to get redirected from the
449 fd = (log_level >= G_LOG_LEVEL_MESSAGE) ? 1 : 2;
452 g_mutex_lock (g_messages_lock);
453 local_glib_error_func = glib_error_func;
454 local_glib_warning_func = glib_warning_func;
455 local_glib_message_func = glib_message_func;
456 g_mutex_unlock (g_messages_lock);
460 case G_LOG_LEVEL_ERROR:
461 if (!log_domain && local_glib_error_func)
463 /* compatibility code */
464 local_glib_error_func (message);
467 /* use write(2) for output, in case we are out of memeory */
468 ensure_stdout_valid ();
470 #ifdef G_ENABLE_MSG_PREFIX
471 write (fd, prg_name, strlen (prg_name));
472 write (fd, prg_pid, strlen (prg_pid));
473 #endif /* G_ENABLE_MSG_PREFIX */
476 write (fd, log_domain, strlen (log_domain));
480 write (fd, "** ", 3);
482 write (fd, "ERROR (recursed) **: ", 21);
484 write (fd, "ERROR **: ", 10);
485 write (fd, message, strlen (message));
487 write (fd, "\naborting...\n", 13);
491 case G_LOG_LEVEL_CRITICAL:
492 ensure_stdout_valid ();
494 #ifdef G_ENABLE_MSG_PREFIX
495 write (fd, prg_name, strlen (prg_name));
496 write (fd, prg_pid, strlen (prg_pid));
497 #endif /* G_ENABLE_MSG_PREFIX */
500 write (fd, log_domain, strlen (log_domain));
504 write (fd, "** ", 3);
506 write (fd, "CRITICAL (recursed) **: ", 24);
508 write (fd, "CRITICAL **: ", 13);
509 write (fd, message, strlen (message));
511 write (fd, "\naborting...\n", 13);
515 case G_LOG_LEVEL_WARNING:
516 if (!log_domain && local_glib_warning_func)
518 /* compatibility code */
519 local_glib_warning_func (message);
522 ensure_stdout_valid ();
524 #ifdef G_ENABLE_MSG_PREFIX
525 write (fd, prg_name, strlen (prg_name));
526 write (fd, prg_pid, strlen (prg_pid));
527 #endif /* G_ENABLE_MSG_PREFIX */
530 write (fd, log_domain, strlen (log_domain));
534 write (fd, "** ", 3);
536 write (fd, "WARNING (recursed) **: ", 23);
538 write (fd, "WARNING **: ", 12);
539 write (fd, message, strlen (message));
541 write (fd, "\naborting...\n", 13);
545 case G_LOG_LEVEL_MESSAGE:
546 if (!log_domain && local_glib_message_func)
548 /* compatibility code */
549 local_glib_message_func (message);
552 ensure_stdout_valid ();
553 #ifdef G_ENABLE_MSG_PREFIX
554 write (fd, prg_name, strlen (prg_name));
555 write (fd, prg_pid, strlen (prg_pid));
556 #endif /* G_ENABLE_MSG_PREFIX */
559 write (fd, log_domain, strlen (log_domain));
563 write (fd, "Message (recursed): ", 20);
565 write (fd, "Message: ", 9);
566 write (fd, message, strlen (message));
568 write (fd, "\naborting...\n", 13);
572 case G_LOG_LEVEL_INFO:
573 ensure_stdout_valid ();
574 #ifdef G_ENABLE_MSG_PREFIX
575 write (fd, prg_name, strlen (prg_name));
576 write (fd, prg_pid, strlen (prg_pid));
577 #endif /* G_ENABLE_MSG_PREFIX */
580 write (fd, log_domain, strlen (log_domain));
584 write (fd, "INFO (recursed): ", 17);
586 write (fd, "INFO: ", 6);
587 write (fd, message, strlen (message));
589 write (fd, "\naborting...\n", 13);
593 case G_LOG_LEVEL_DEBUG:
594 ensure_stdout_valid ();
595 #ifdef G_ENABLE_MSG_PREFIX
596 write (fd, prg_name, strlen (prg_name));
597 write (fd, prg_pid, strlen (prg_pid));
598 #endif /* G_ENABLE_MSG_PREFIX */
601 write (fd, log_domain, strlen (log_domain));
605 write (fd, "DEBUG (recursed): ", 18);
607 write (fd, "DEBUG: ", 7);
608 write (fd, message, strlen (message));
610 write (fd, "\naborting...\n", 13);
615 /* we are used for a log level that is not defined by GLib itself,
616 * try to make the best out of it.
618 ensure_stdout_valid ();
619 #ifdef G_ENABLE_MSG_PREFIX
620 write (fd, prg_name, strlen (prg_name));
621 write (fd, prg_pid, strlen (prg_pid));
622 #endif /* G_ENABLE_MSG_PREFIX */
625 write (fd, log_domain, strlen (log_domain));
627 write (fd, "-LOG (recursed:", 15);
629 write (fd, "-LOG (", 6);
631 else if (in_recursion)
632 write (fd, "LOG (recursed:", 14);
634 write (fd, "LOG (", 5);
637 gchar string[] = "0x00): ";
638 gchar *p = string + 2;
641 i = g_bit_nth_msf (log_level, -1);
644 *p = '0' + (i & 0xf);
648 write (fd, string, 7);
651 write (fd, "): ", 3);
652 write (fd, message, strlen (message));
654 write (fd, "\naborting...\n", 13);
662 g_set_print_handler (GPrintFunc func)
664 GPrintFunc old_print_func;
666 g_mutex_lock (g_messages_lock);
667 old_print_func = glib_print_func;
668 glib_print_func = func;
669 g_mutex_unlock (g_messages_lock);
671 return old_print_func;
675 g_print (const gchar *format,
680 GPrintFunc local_glib_print_func;
682 g_return_if_fail (format != NULL);
684 va_start (args, format);
685 string = g_strdup_vprintf (format, args);
688 g_mutex_lock (g_messages_lock);
689 local_glib_print_func = glib_print_func;
690 g_mutex_unlock (g_messages_lock);
692 if (local_glib_print_func)
693 local_glib_print_func (string);
696 ensure_stdout_valid ();
697 fputs (string, stdout);
704 g_set_printerr_handler (GPrintFunc func)
706 GPrintFunc old_printerr_func;
708 g_mutex_lock (g_messages_lock);
709 old_printerr_func = glib_printerr_func;
710 glib_printerr_func = func;
711 g_mutex_unlock (g_messages_lock);
713 return old_printerr_func;
717 g_printerr (const gchar *format,
722 GPrintFunc local_glib_printerr_func;
724 g_return_if_fail (format != NULL);
726 va_start (args, format);
727 string = g_strdup_vprintf (format, args);
730 g_mutex_lock (g_messages_lock);
731 local_glib_printerr_func = glib_printerr_func;
732 g_mutex_unlock (g_messages_lock);
734 if (local_glib_printerr_func)
735 local_glib_printerr_func (string);
738 fputs (string, stderr);
744 /* compatibility code */
746 g_set_error_handler (GErrorFunc func)
748 GErrorFunc old_error_func;
750 g_mutex_lock (g_messages_lock);
751 old_error_func = glib_error_func;
752 glib_error_func = func;
753 g_mutex_unlock (g_messages_lock);
755 return old_error_func;
758 /* compatibility code */
760 g_set_warning_handler (GWarningFunc func)
762 GWarningFunc old_warning_func;
764 g_mutex_lock (g_messages_lock);
765 old_warning_func = glib_warning_func;
766 glib_warning_func = func;
767 g_mutex_unlock (g_messages_lock);
769 return old_warning_func;
772 /* compatibility code */
774 g_set_message_handler (GPrintFunc func)
776 GPrintFunc old_message_func;
778 g_mutex_lock (g_messages_lock);
779 old_message_func = glib_message_func;
780 glib_message_func = func;
781 g_mutex_unlock (g_messages_lock);
783 return old_message_func;
787 g_messages_init (void)
789 g_messages_lock = g_mutex_new();
790 g_log_depth = g_private_new(NULL);