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.
29 /* Just use stdio. If we're out of memroy, we're hosed anyway. */
37 fwrite (buf, len, 1, fd);
41 #endif /* NATIVE_WIN32 */
44 /* --- structures --- */
45 typedef struct _GLogDomain GLogDomain;
46 typedef struct _GLogHandler GLogHandler;
50 GLogLevelFlags fatal_mask;
51 GLogHandler *handlers;
57 GLogLevelFlags log_level;
64 /* --- variables --- */
65 const gchar *g_log_domain_glib = "GLib";
66 static GLogDomain *g_log_domains = NULL;
67 static GLogLevelFlags g_log_always_fatal = G_LOG_FATAL_MASK;
68 static GPrintFunc glib_print_func = NULL;
69 static GPrintFunc glib_printerr_func = NULL;
70 static GErrorFunc glib_error_func = NULL;
71 static GWarningFunc glib_warning_func = NULL;
72 static GPrintFunc glib_message_func = NULL;
75 /* --- functions --- */
76 static inline GLogDomain*
77 g_log_find_domain (const gchar *log_domain)
79 register GLogDomain *domain;
81 domain = g_log_domains;
84 if (strcmp (domain->log_domain, log_domain) == 0)
86 domain = domain->next;
91 static inline GLogDomain*
92 g_log_domain_new (const gchar *log_domain)
94 register GLogDomain *domain;
96 domain = g_new (GLogDomain, 1);
97 domain->log_domain = g_strdup (log_domain);
98 domain->fatal_mask = G_LOG_FATAL_MASK;
99 domain->handlers = NULL;
100 domain->next = g_log_domains;
101 g_log_domains = domain;
107 g_log_domain_check_free (GLogDomain *domain)
109 if (domain->fatal_mask == G_LOG_FATAL_MASK &&
110 domain->handlers == NULL)
112 register GLogDomain *last, *work;
115 work = g_log_domains;
121 last->next = domain->next;
123 g_log_domains = domain->next;
124 g_free (domain->log_domain);
133 static inline GLogFunc
134 g_log_domain_get_handler (GLogDomain *domain,
135 GLogLevelFlags log_level,
138 if (domain && log_level)
140 register GLogHandler *handler;
142 handler = domain->handlers;
145 if ((handler->log_level & log_level) == log_level)
147 *data = handler->data;
148 return handler->log_func;
150 handler = handler->next;
153 return g_log_default_handler;
157 g_log_set_always_fatal (GLogLevelFlags fatal_mask)
159 GLogLevelFlags old_mask;
161 /* restrict the global mask to levels that are known to glib */
162 fatal_mask &= (1 << G_LOG_LEVEL_USER_SHIFT) - 1;
163 /* force errors to be fatal */
164 fatal_mask |= G_LOG_LEVEL_ERROR;
165 /* remove bogus flag */
166 fatal_mask &= ~G_LOG_FLAG_FATAL;
168 old_mask = g_log_always_fatal;
169 g_log_always_fatal = fatal_mask;
175 g_log_set_fatal_mask (const gchar *log_domain,
176 GLogLevelFlags fatal_mask)
178 GLogLevelFlags old_flags;
179 register GLogDomain *domain;
184 /* force errors to be fatal */
185 fatal_mask |= G_LOG_LEVEL_ERROR;
186 /* remove bogus flag */
187 fatal_mask &= ~G_LOG_FLAG_FATAL;
189 domain = g_log_find_domain (log_domain);
191 domain = g_log_domain_new (log_domain);
192 old_flags = domain->fatal_mask;
194 domain->fatal_mask = fatal_mask;
195 g_log_domain_check_free (domain);
201 g_log_set_handler (const gchar *log_domain,
202 GLogLevelFlags log_levels,
206 register GLogDomain *domain;
207 register GLogHandler *handler;
208 static guint handler_id = 0;
210 g_return_val_if_fail ((log_levels & G_LOG_LEVEL_MASK) != 0, 0);
211 g_return_val_if_fail (log_func != NULL, 0);
216 domain = g_log_find_domain (log_domain);
218 domain = g_log_domain_new (log_domain);
220 handler = g_new (GLogHandler, 1);
221 handler->id = ++handler_id;
222 handler->log_level = log_levels;
223 handler->log_func = log_func;
224 handler->data = user_data;
225 handler->next = domain->handlers;
226 domain->handlers = handler;
232 g_log_remove_handler (const gchar *log_domain,
235 register GLogDomain *domain;
237 g_return_if_fail (handler_id > 0);
242 domain = g_log_find_domain (log_domain);
245 register GLogHandler *work, *last;
248 work = domain->handlers;
251 if (work->id == handler_id)
254 last->next = work->next;
256 domain->handlers = work->next;
258 g_log_domain_check_free (domain);
264 g_warning ("g_log_remove_handler(): could not find handler with id `%d' for domain \"%s\"",
270 g_logv (const gchar *log_domain,
271 GLogLevelFlags log_level,
279 log_level &= G_LOG_LEVEL_MASK;
283 /* we use a stack buffer of fixed size, because we might get called
286 G_VA_COPY (args2, args1);
287 if (g_printf_string_upper_bound (format, args1) < 1024)
288 vsprintf (buffer, format, args2);
291 /* since we might be out of memory, we can't use g_vsnprintf(). */
292 #ifdef HAVE_VSNPRINTF
293 vsnprintf (buffer, 1024, format, args2);
294 #else /* !HAVE_VSNPRINTF */
295 /* we are out of luck here */
296 strncpy (buffer, format, 1024);
297 #endif /* !HAVE_VSNPRINTF */
302 for (i = g_bit_nth_msf (log_level, -1); i >= 0; i = g_bit_nth_msf (log_level, i))
304 register GLogLevelFlags test_level;
307 if (log_level & test_level)
309 static guint g_log_depth = 0;
312 gpointer data = NULL;
314 domain = g_log_find_domain (log_domain ? log_domain : "");
317 test_level |= G_LOG_FLAG_RECURSION;
319 if ((((domain ? domain->fatal_mask : G_LOG_FATAL_MASK) | g_log_always_fatal) &
321 test_level |= G_LOG_FLAG_FATAL;
322 log_func = g_log_domain_get_handler (domain, test_level, &data);
323 log_func (log_domain, test_level, buffer, data);
325 /* *domain can be cluttered now */
327 if (test_level & G_LOG_FLAG_FATAL)
336 g_log (const gchar *log_domain,
337 GLogLevelFlags log_level,
343 va_start (args, format);
344 g_logv (log_domain, log_level, format, args);
349 g_log_default_handler (const gchar *log_domain,
350 GLogLevelFlags log_level,
351 const gchar *message,
352 gpointer unused_data)
359 gboolean in_recursion;
362 in_recursion = (log_level & G_LOG_FLAG_RECURSION) != 0;
363 is_fatal = (log_level & G_LOG_FLAG_FATAL) != 0;
364 log_level &= G_LOG_LEVEL_MASK;
367 message = "g_log_default_handler(): (NULL) message";
370 /* Use just stdout as stderr is hard to get redirected from the
375 fd = (log_level >= G_LOG_LEVEL_MESSAGE) ? 1 : 2;
380 case G_LOG_LEVEL_ERROR:
381 if (!log_domain && glib_error_func)
383 /* compatibility code */
384 glib_error_func (message);
387 /* use write(2) for output, in case we are out of memeory */
391 write (fd, log_domain, strlen (log_domain));
395 write (fd, "\n** ", 4);
397 write (fd, "ERROR (recursed) **: ", 21);
399 write (fd, "ERROR **: ", 10);
400 write (fd, message, strlen(message));
402 write (fd, "\naborting...\n", 13);
406 case G_LOG_LEVEL_CRITICAL:
410 write (fd, log_domain, strlen (log_domain));
414 write (fd, "\n** ", 4);
416 write (fd, "CRITICAL (recursed) **: ", 24);
418 write (fd, "CRITICAL **: ", 13);
419 write (fd, message, strlen(message));
421 write (fd, "\naborting...\n", 13);
425 case G_LOG_LEVEL_WARNING:
426 if (!log_domain && glib_warning_func)
428 /* compatibility code */
429 glib_warning_func (message);
435 write (fd, log_domain, strlen (log_domain));
439 write (fd, "\n** ", 4);
441 write (fd, "WARNING (recursed) **: ", 23);
443 write (fd, "WARNING **: ", 12);
444 write (fd, message, strlen(message));
446 write (fd, "\naborting...\n", 13);
450 case G_LOG_LEVEL_MESSAGE:
451 if (!log_domain && glib_message_func)
453 /* compatibility code */
454 glib_message_func (message);
459 write (fd, log_domain, strlen (log_domain));
463 write (fd, "Message (recursed): ", 20);
465 write (fd, "Message: ", 9);
466 write (fd, message, strlen(message));
468 write (fd, "\naborting...\n", 13);
472 case G_LOG_LEVEL_INFO:
475 write (fd, log_domain, strlen (log_domain));
479 write (fd, "INFO (recursed): ", 17);
481 write (fd, "INFO: ", 6);
482 write (fd, message, strlen(message));
484 write (fd, "\naborting...\n", 13);
488 case G_LOG_LEVEL_DEBUG:
491 write (fd, log_domain, strlen (log_domain));
495 write (fd, "DEBUG (recursed): ", 18);
497 write (fd, "DEBUG: ", 7);
498 write (fd, message, strlen(message));
500 write (fd, "\naborting...\n", 13);
505 /* we are used for a log level that is not defined by GLib itself,
506 * try to make the best out of it.
510 write (fd, log_domain, strlen (log_domain));
512 write (fd, "-LOG (recursed:", 15);
514 write (fd, "-LOG (", 6);
516 else if (in_recursion)
517 write (fd, "LOG (recursed:", 14);
519 write (fd, "LOG (", 5);
522 gchar string[] = "0x00): ";
523 gchar *p = string + 2;
526 i = g_bit_nth_msf (log_level, -1);
529 *p = '0' + (i & 0xf);
533 write (fd, string, 7);
536 write (fd, "): ", 3);
537 write (fd, message, strlen(message));
539 write (fd, "\naborting...\n", 13);
547 g_set_print_handler (GPrintFunc func)
549 GPrintFunc old_print_func;
551 old_print_func = glib_print_func;
552 glib_print_func = func;
554 return old_print_func;
558 g_print (const gchar *format,
564 g_return_if_fail (format != NULL);
566 va_start (args, format);
567 string = g_strdup_vprintf (format, args);
571 glib_print_func (string);
574 fputs (string, stdout);
581 g_set_printerr_handler (GPrintFunc func)
583 GPrintFunc old_printerr_func;
585 old_printerr_func = glib_printerr_func;
586 glib_printerr_func = func;
588 return old_printerr_func;
592 g_printerr (const gchar *format,
598 g_return_if_fail (format != NULL);
600 va_start (args, format);
601 string = g_strdup_vprintf (format, args);
604 if (glib_printerr_func)
605 glib_printerr_func (string);
608 fputs (string, stderr);
614 /* compatibility code */
616 g_set_error_handler (GErrorFunc func)
618 GErrorFunc old_error_func;
620 old_error_func = glib_error_func;
621 glib_error_func = func;
623 return old_error_func;
626 /* compatibility code */
628 g_set_warning_handler (GWarningFunc func)
630 GWarningFunc old_warning_func;
632 old_warning_func = glib_warning_func;
633 glib_warning_func = func;
635 return old_warning_func;
638 /* compatibility code */
640 g_set_message_handler (GPrintFunc func)
642 GPrintFunc old_message_func;
644 old_message_func = glib_message_func;
645 glib_message_func = func;
647 return old_message_func;