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.
26 /* --- structures --- */
27 typedef struct _GLogDomain GLogDomain;
28 typedef struct _GLogHandler GLogHandler;
32 GLogLevelFlags fatal_mask;
33 GLogHandler *handlers;
39 GLogLevelFlags log_level;
46 /* --- prototypes --- */
47 extern gchar* g_vsprintf (const gchar *fmt,
52 /* --- variables --- */
53 const gchar *g_log_domain_glib = "GLib";
54 static GLogDomain *g_log_domains = NULL;
55 static GPrintFunc glib_print_func = NULL;
56 static GPrintFunc glib_printerr_func = NULL;
57 static GErrorFunc glib_error_func = NULL;
58 static GWarningFunc glib_warning_func = NULL;
59 static GPrintFunc glib_message_func = NULL;
62 /* --- functions --- */
63 static inline GLogDomain*
64 g_log_find_domain (const gchar *log_domain)
66 register GLogDomain *domain;
68 domain = g_log_domains;
71 if (strcmp (domain->log_domain, log_domain) == 0)
73 domain = domain->next;
78 static inline GLogDomain*
79 g_log_domain_new (const gchar *log_domain)
81 register GLogDomain *domain;
83 domain = g_new (GLogDomain, 1);
84 domain->log_domain = g_strdup (log_domain);
85 domain->fatal_mask = G_LOG_FATAL_MASK;
86 domain->handlers = NULL;
87 domain->next = g_log_domains;
88 g_log_domains = domain;
94 g_log_domain_check_free (GLogDomain *domain)
96 if (domain->fatal_mask == G_LOG_FATAL_MASK &&
97 domain->handlers == NULL)
99 register GLogDomain *last, *work;
102 work = g_log_domains;
108 last->next = domain->next;
110 g_log_domains = domain->next;
111 g_free (domain->log_domain);
120 static inline GLogFunc
121 g_log_domain_get_handler (GLogDomain *domain,
122 GLogLevelFlags log_level,
125 if (domain && log_level)
127 register GLogHandler *handler;
129 handler = domain->handlers;
132 if ((handler->log_level & log_level) == log_level)
134 *data = handler->data;
135 return handler->log_func;
137 handler = handler->next;
140 return g_log_default_handler;
144 g_log_set_fatal_mask (const gchar *log_domain,
145 GLogLevelFlags fatal_mask)
147 GLogLevelFlags old_flags;
148 register GLogDomain *domain;
153 /* force errors to be fatal */
154 fatal_mask |= G_LOG_LEVEL_ERROR;
155 /* remove bogus flag */
156 fatal_mask &= ~G_LOG_FLAG_FATAL;
158 domain = g_log_find_domain (log_domain);
160 domain = g_log_domain_new (log_domain);
161 old_flags = domain->fatal_mask;
163 domain->fatal_mask = fatal_mask;
164 g_log_domain_check_free (domain);
170 g_log_set_handler (const gchar *log_domain,
171 GLogLevelFlags log_levels,
175 register GLogDomain *domain;
176 register GLogHandler *handler;
177 static guint handler_id = 0;
179 g_return_val_if_fail ((log_levels & G_LOG_LEVEL_MASK) != 0, 0);
180 g_return_val_if_fail (log_func != NULL, 0);
185 domain = g_log_find_domain (log_domain);
187 domain = g_log_domain_new (log_domain);
189 handler = g_new (GLogHandler, 1);
190 handler->id = ++handler_id;
191 handler->log_level = log_levels;
192 handler->log_func = log_func;
193 handler->data = user_data;
194 handler->next = domain->handlers;
195 domain->handlers = handler;
201 g_log_remove_handler (const gchar *log_domain,
204 register GLogDomain *domain;
206 g_return_if_fail (handler_id > 0);
211 domain = g_log_find_domain (log_domain);
214 register GLogHandler *work, *last;
217 work = domain->handlers;
220 if (work->id == handler_id)
223 last->next = work->next;
225 domain->handlers = work->next;
227 g_log_domain_check_free (domain);
233 g_warning ("g_log_remove_handler(): could not find handler with id `%d' for domain \"%s\"",
239 g_logv (const gchar *log_domain,
240 GLogLevelFlags log_level,
248 log_level &= G_LOG_LEVEL_MASK;
252 /* we use a stack buffer of fixed size, because we might get called
253 * recursively, and we can also be out of memory.
255 g_vsnprintf (buffer, 1025, format, args1, args2);
257 for (i = g_bit_nth_msf (log_level, -1); i >= 0; i = g_bit_nth_msf (log_level, i))
259 register GLogLevelFlags test_level;
262 if (log_level & test_level)
264 static guint g_log_depth = 0;
267 gpointer data = NULL;
269 domain = g_log_find_domain (log_domain);
272 test_level |= G_LOG_FLAG_RECURSION;
274 if (((domain ? domain->fatal_mask : G_LOG_FATAL_MASK) & test_level) != 0)
275 test_level |= G_LOG_FLAG_FATAL;
276 log_func = g_log_domain_get_handler (domain, test_level, &data);
277 log_func (log_domain, test_level, buffer, data);
279 /* *domain can be cluttered now */
281 if (test_level & G_LOG_FLAG_FATAL)
290 g_log (const gchar *log_domain,
291 GLogLevelFlags log_level,
295 va_list arg_list1, arg_list2;
297 va_start (arg_list1, format);
298 va_start (arg_list2, format);
299 g_logv (log_domain, log_level, format, &arg_list1, &arg_list2);
305 g_log_default_handler (const gchar *log_domain,
306 GLogLevelFlags log_level,
307 const gchar *message,
308 gpointer unused_data)
311 gboolean in_recursion;
314 in_recursion = (log_level & G_LOG_FLAG_RECURSION) != 0;
315 is_fatal = (log_level & G_LOG_FLAG_FATAL) != 0;
316 log_level &= G_LOG_LEVEL_MASK;
319 message = "g_log_default_handler(): (NULL) message";
321 fd = (log_level >= G_LOG_LEVEL_MESSAGE) ? 1 : 2;
325 case G_LOG_LEVEL_ERROR:
326 if (!log_domain && glib_error_func)
328 /* compatibility code */
329 glib_error_func (message);
332 /* use write(2) for output, in case we are out of memeory */
336 write (fd, log_domain, strlen (log_domain));
340 write (fd, "\n** ", 4);
342 write (fd, "ERROR (recursed) **: ", 21);
344 write (fd, "ERROR **: ", 10);
345 write (fd, message, strlen(message));
347 write (fd, "\naborting...\n", 13);
351 case G_LOG_LEVEL_CRITICAL:
355 write (fd, log_domain, strlen (log_domain));
359 write (fd, "\n** ", 4);
361 write (fd, "CRITICAL (recursed) **: ", 24);
363 write (fd, "CRITICAL **: ", 13);
364 write (fd, message, strlen(message));
366 write (fd, "\naborting...\n", 13);
370 case G_LOG_LEVEL_WARNING:
371 if (!log_domain && glib_warning_func)
373 /* compatibility code */
374 glib_warning_func (message);
380 write (fd, log_domain, strlen (log_domain));
384 write (fd, "\n** ", 4);
386 write (fd, "WARNING (recursed) **: ", 23);
388 write (fd, "WARNING **: ", 12);
389 write (fd, message, strlen(message));
391 write (fd, "\naborting...\n", 13);
395 case G_LOG_LEVEL_MESSAGE:
396 if (!log_domain && glib_message_func)
398 /* compatibility code */
399 glib_message_func (message);
404 write (fd, log_domain, strlen (log_domain));
408 write (fd, "Message (recursed): ", 20);
410 write (fd, "Message: ", 9);
411 write (fd, message, strlen(message));
413 write (fd, "\naborting...\n", 13);
417 case G_LOG_LEVEL_INFO:
420 write (fd, log_domain, strlen (log_domain));
424 write (fd, "INFO (recursed): ", 17);
426 write (fd, "INFO: ", 6);
427 write (fd, message, strlen(message));
429 write (fd, "\naborting...\n", 13);
433 case G_LOG_LEVEL_DEBUG:
436 write (fd, log_domain, strlen (log_domain));
440 write (fd, "DEBUG (recursed): ", 18);
442 write (fd, "DEBUG: ", 7);
443 write (fd, message, strlen(message));
445 write (fd, "\naborting...\n", 13);
450 /* we are used for a log level that is not defined by GLib itself,
451 * try to make the best out of it.
455 write (fd, log_domain, strlen (log_domain));
457 write (fd, "-LOG (recursed:", 15);
459 write (fd, "-LOG (", 6);
461 else if (in_recursion)
462 write (fd, "LOG (recursed:", 14);
464 write (fd, "LOG (", 5);
467 gchar string[] = "0x00): ";
468 gchar *p = string + 2;
471 i = g_bit_nth_msf (log_level, -1);
474 *p = '0' + (i & 0xf);
478 write (fd, string, 7);
481 write (fd, "): ", 3);
482 write (fd, message, strlen(message));
484 write (fd, "\naborting...\n", 13);
492 g_set_print_handler (GPrintFunc func)
494 GPrintFunc old_print_func;
496 old_print_func = glib_print_func;
497 glib_print_func = func;
499 return old_print_func;
503 g_print (const gchar *format,
509 g_return_if_fail (format != NULL);
511 va_start (args, format);
512 va_start (args2, format);
513 buf = g_vsprintf (format, &args, &args2);
521 string = g_strdup (buf);
522 glib_print_func (string);
533 g_set_printerr_handler (GPrintFunc func)
535 GPrintFunc old_printerr_func;
537 old_printerr_func = glib_printerr_func;
538 glib_printerr_func = func;
540 return old_printerr_func;
544 g_printerr (const gchar *format,
550 g_return_if_fail (format != NULL);
552 va_start (args, format);
553 va_start (args2, format);
554 buf = g_vsprintf (format, &args, &args2);
558 if (glib_printerr_func)
562 string = g_strdup (buf);
563 glib_printerr_func (string);
573 /* compatibility code */
575 g_set_error_handler (GErrorFunc func)
577 GErrorFunc old_error_func;
579 old_error_func = glib_error_func;
580 glib_error_func = func;
582 return old_error_func;
585 /* compatibility code */
587 g_set_warning_handler (GWarningFunc func)
589 GWarningFunc old_warning_func;
591 old_warning_func = glib_warning_func;
592 glib_warning_func = func;
594 return old_warning_func;
597 /* compatibility code */
599 g_set_message_handler (GPrintFunc func)
601 GPrintFunc old_message_func;
603 old_message_func = glib_message_func;
604 glib_message_func = func;
606 return old_message_func;