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.
34 /* Just use stdio. If we're out of memroy, we're hosed anyway. */
42 fwrite (buf, len, 1, fd);
46 #endif /* NATIVE_WIN32 */
49 /* --- structures --- */
50 typedef struct _GLogDomain GLogDomain;
51 typedef struct _GLogHandler GLogHandler;
55 GLogLevelFlags fatal_mask;
56 GLogHandler *handlers;
62 GLogLevelFlags log_level;
69 /* --- variables --- */
70 const gchar *g_log_domain_glib = "GLib";
71 static GLogDomain *g_log_domains = NULL;
72 static GLogLevelFlags g_log_always_fatal = G_LOG_FATAL_MASK;
73 static GPrintFunc glib_print_func = NULL;
74 static GPrintFunc glib_printerr_func = NULL;
75 static GErrorFunc glib_error_func = NULL;
76 static GWarningFunc glib_warning_func = NULL;
77 static GPrintFunc glib_message_func = NULL;
80 /* --- functions --- */
81 static inline GLogDomain*
82 g_log_find_domain (const gchar *log_domain)
84 register GLogDomain *domain;
86 domain = g_log_domains;
89 if (strcmp (domain->log_domain, log_domain) == 0)
91 domain = domain->next;
96 static inline GLogDomain*
97 g_log_domain_new (const gchar *log_domain)
99 register GLogDomain *domain;
101 domain = g_new (GLogDomain, 1);
102 domain->log_domain = g_strdup (log_domain);
103 domain->fatal_mask = G_LOG_FATAL_MASK;
104 domain->handlers = NULL;
105 domain->next = g_log_domains;
106 g_log_domains = domain;
112 g_log_domain_check_free (GLogDomain *domain)
114 if (domain->fatal_mask == G_LOG_FATAL_MASK &&
115 domain->handlers == NULL)
117 register GLogDomain *last, *work;
120 work = g_log_domains;
126 last->next = domain->next;
128 g_log_domains = domain->next;
129 g_free (domain->log_domain);
138 static inline GLogFunc
139 g_log_domain_get_handler (GLogDomain *domain,
140 GLogLevelFlags log_level,
143 if (domain && log_level)
145 register GLogHandler *handler;
147 handler = domain->handlers;
150 if ((handler->log_level & log_level) == log_level)
152 *data = handler->data;
153 return handler->log_func;
155 handler = handler->next;
158 return g_log_default_handler;
162 g_log_set_always_fatal (GLogLevelFlags fatal_mask)
164 GLogLevelFlags old_mask;
166 /* restrict the global mask to levels that are known to glib */
167 fatal_mask &= (1 << G_LOG_LEVEL_USER_SHIFT) - 1;
168 /* force errors to be fatal */
169 fatal_mask |= G_LOG_LEVEL_ERROR;
170 /* remove bogus flag */
171 fatal_mask &= ~G_LOG_FLAG_FATAL;
173 old_mask = g_log_always_fatal;
174 g_log_always_fatal = fatal_mask;
180 g_log_set_fatal_mask (const gchar *log_domain,
181 GLogLevelFlags fatal_mask)
183 GLogLevelFlags old_flags;
184 register GLogDomain *domain;
189 /* force errors to be fatal */
190 fatal_mask |= G_LOG_LEVEL_ERROR;
191 /* remove bogus flag */
192 fatal_mask &= ~G_LOG_FLAG_FATAL;
194 domain = g_log_find_domain (log_domain);
196 domain = g_log_domain_new (log_domain);
197 old_flags = domain->fatal_mask;
199 domain->fatal_mask = fatal_mask;
200 g_log_domain_check_free (domain);
206 g_log_set_handler (const gchar *log_domain,
207 GLogLevelFlags log_levels,
211 register GLogDomain *domain;
212 register GLogHandler *handler;
213 static guint handler_id = 0;
215 g_return_val_if_fail ((log_levels & G_LOG_LEVEL_MASK) != 0, 0);
216 g_return_val_if_fail (log_func != NULL, 0);
221 domain = g_log_find_domain (log_domain);
223 domain = g_log_domain_new (log_domain);
225 handler = g_new (GLogHandler, 1);
226 handler->id = ++handler_id;
227 handler->log_level = log_levels;
228 handler->log_func = log_func;
229 handler->data = user_data;
230 handler->next = domain->handlers;
231 domain->handlers = handler;
237 g_log_remove_handler (const gchar *log_domain,
240 register GLogDomain *domain;
242 g_return_if_fail (handler_id > 0);
247 domain = g_log_find_domain (log_domain);
250 register GLogHandler *work, *last;
253 work = domain->handlers;
256 if (work->id == handler_id)
259 last->next = work->next;
261 domain->handlers = work->next;
263 g_log_domain_check_free (domain);
269 g_warning ("g_log_remove_handler(): could not find handler with id `%d' for domain \"%s\"",
275 g_logv (const gchar *log_domain,
276 GLogLevelFlags log_level,
284 log_level &= G_LOG_LEVEL_MASK;
288 /* we use a stack buffer of fixed size, because we might get called
291 G_VA_COPY (args2, args1);
292 if (g_printf_string_upper_bound (format, args1) < 1024)
293 vsprintf (buffer, format, args2);
296 /* since we might be out of memory, we can't use g_vsnprintf(). */
297 #ifdef HAVE_VSNPRINTF
298 vsnprintf (buffer, 1024, format, args2);
299 #else /* !HAVE_VSNPRINTF */
300 /* we are out of luck here */
301 strncpy (buffer, format, 1024);
302 #endif /* !HAVE_VSNPRINTF */
307 for (i = g_bit_nth_msf (log_level, -1); i >= 0; i = g_bit_nth_msf (log_level, i))
309 register GLogLevelFlags test_level;
312 if (log_level & test_level)
314 static guint g_log_depth = 0;
317 gpointer data = NULL;
319 domain = g_log_find_domain (log_domain ? log_domain : "");
322 test_level |= G_LOG_FLAG_RECURSION;
324 if ((((domain ? domain->fatal_mask : G_LOG_FATAL_MASK) | g_log_always_fatal) &
326 test_level |= G_LOG_FLAG_FATAL;
327 log_func = g_log_domain_get_handler (domain, test_level, &data);
328 log_func (log_domain, test_level, buffer, data);
330 /* *domain can be cluttered now */
332 if (test_level & G_LOG_FLAG_FATAL)
341 g_log (const gchar *log_domain,
342 GLogLevelFlags log_level,
348 va_start (args, format);
349 g_logv (log_domain, log_level, format, args);
354 g_log_default_handler (const gchar *log_domain,
355 GLogLevelFlags log_level,
356 const gchar *message,
357 gpointer unused_data)
364 gboolean in_recursion;
367 in_recursion = (log_level & G_LOG_FLAG_RECURSION) != 0;
368 is_fatal = (log_level & G_LOG_FLAG_FATAL) != 0;
369 log_level &= G_LOG_LEVEL_MASK;
372 message = "g_log_default_handler(): (NULL) message";
375 /* Use just stdout as stderr is hard to get redirected from the
380 fd = (log_level >= G_LOG_LEVEL_MESSAGE) ? 1 : 2;
385 case G_LOG_LEVEL_ERROR:
386 if (!log_domain && glib_error_func)
388 /* compatibility code */
389 glib_error_func (message);
392 /* use write(2) for output, in case we are out of memeory */
396 write (fd, log_domain, strlen (log_domain));
400 write (fd, "\n** ", 4);
402 write (fd, "ERROR (recursed) **: ", 21);
404 write (fd, "ERROR **: ", 10);
405 write (fd, message, strlen(message));
407 write (fd, "\naborting...\n", 13);
411 case G_LOG_LEVEL_CRITICAL:
415 write (fd, log_domain, strlen (log_domain));
419 write (fd, "\n** ", 4);
421 write (fd, "CRITICAL (recursed) **: ", 24);
423 write (fd, "CRITICAL **: ", 13);
424 write (fd, message, strlen(message));
426 write (fd, "\naborting...\n", 13);
430 case G_LOG_LEVEL_WARNING:
431 if (!log_domain && glib_warning_func)
433 /* compatibility code */
434 glib_warning_func (message);
440 write (fd, log_domain, strlen (log_domain));
444 write (fd, "\n** ", 4);
446 write (fd, "WARNING (recursed) **: ", 23);
448 write (fd, "WARNING **: ", 12);
449 write (fd, message, strlen(message));
451 write (fd, "\naborting...\n", 13);
455 case G_LOG_LEVEL_MESSAGE:
456 if (!log_domain && glib_message_func)
458 /* compatibility code */
459 glib_message_func (message);
464 write (fd, log_domain, strlen (log_domain));
468 write (fd, "Message (recursed): ", 20);
470 write (fd, "Message: ", 9);
471 write (fd, message, strlen(message));
473 write (fd, "\naborting...\n", 13);
477 case G_LOG_LEVEL_INFO:
480 write (fd, log_domain, strlen (log_domain));
484 write (fd, "INFO (recursed): ", 17);
486 write (fd, "INFO: ", 6);
487 write (fd, message, strlen(message));
489 write (fd, "\naborting...\n", 13);
493 case G_LOG_LEVEL_DEBUG:
496 write (fd, log_domain, strlen (log_domain));
500 write (fd, "DEBUG (recursed): ", 18);
502 write (fd, "DEBUG: ", 7);
503 write (fd, message, strlen(message));
505 write (fd, "\naborting...\n", 13);
510 /* we are used for a log level that is not defined by GLib itself,
511 * try to make the best out of it.
515 write (fd, log_domain, strlen (log_domain));
517 write (fd, "-LOG (recursed:", 15);
519 write (fd, "-LOG (", 6);
521 else if (in_recursion)
522 write (fd, "LOG (recursed:", 14);
524 write (fd, "LOG (", 5);
527 gchar string[] = "0x00): ";
528 gchar *p = string + 2;
531 i = g_bit_nth_msf (log_level, -1);
534 *p = '0' + (i & 0xf);
538 write (fd, string, 7);
541 write (fd, "): ", 3);
542 write (fd, message, strlen(message));
544 write (fd, "\naborting...\n", 13);
552 g_set_print_handler (GPrintFunc func)
554 GPrintFunc old_print_func;
556 old_print_func = glib_print_func;
557 glib_print_func = func;
559 return old_print_func;
563 g_print (const gchar *format,
569 g_return_if_fail (format != NULL);
571 va_start (args, format);
572 string = g_strdup_vprintf (format, args);
576 glib_print_func (string);
579 fputs (string, stdout);
586 g_set_printerr_handler (GPrintFunc func)
588 GPrintFunc old_printerr_func;
590 old_printerr_func = glib_printerr_func;
591 glib_printerr_func = func;
593 return old_printerr_func;
597 g_printerr (const gchar *format,
603 g_return_if_fail (format != NULL);
605 va_start (args, format);
606 string = g_strdup_vprintf (format, args);
609 if (glib_printerr_func)
610 glib_printerr_func (string);
613 fputs (string, stderr);
619 /* compatibility code */
621 g_set_error_handler (GErrorFunc func)
623 GErrorFunc old_error_func;
625 old_error_func = glib_error_func;
626 glib_error_func = func;
628 return old_error_func;
631 /* compatibility code */
633 g_set_warning_handler (GWarningFunc func)
635 GWarningFunc old_warning_func;
637 old_warning_func = glib_warning_func;
638 glib_warning_func = func;
640 return old_warning_func;
643 /* compatibility code */
645 g_set_message_handler (GPrintFunc func)
647 GPrintFunc old_message_func;
649 old_message_func = glib_message_func;
650 glib_message_func = func;
652 return old_message_func;