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 Lesser 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 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser 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-2000. 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/.
44 #include "gmessages.h"
46 #include "gbacktrace.h"
50 #include "gprintfint.h"
51 #include "gtestutils.h"
53 #include "gthreadprivate.h"
54 #include "gstrfuncs.h"
58 #include <process.h> /* For getpid() */
60 # define STRICT /* Strict typing, please */
61 # define _WIN32_WINDOWS 0x0401 /* to get IsDebuggerPresent */
67 /* --- structures --- */
68 typedef struct _GLogDomain GLogDomain
;
69 typedef struct _GLogHandler GLogHandler
;
73 GLogLevelFlags fatal_mask
;
74 GLogHandler
*handlers
;
80 GLogLevelFlags log_level
;
87 /* --- variables --- */
88 static GMutex
*g_messages_lock
= NULL
;
89 static GLogDomain
*g_log_domains
= NULL
;
90 static GLogLevelFlags g_log_always_fatal
= G_LOG_FATAL_MASK
;
91 static GPrintFunc glib_print_func
= NULL
;
92 static GPrintFunc glib_printerr_func
= NULL
;
93 static GPrivate
*g_log_depth
= NULL
;
94 static GLogLevelFlags g_log_msg_prefix
= G_LOG_LEVEL_ERROR
| G_LOG_LEVEL_WARNING
| G_LOG_LEVEL_CRITICAL
| G_LOG_LEVEL_DEBUG
;
95 static GLogFunc default_log_func
= g_log_default_handler
;
96 static gpointer default_log_data
= NULL
;
97 static GTestLogFatalFunc fatal_log_func
= NULL
;
98 static gpointer fatal_log_data
;
100 /* --- functions --- */
103 # include <windows.h>
105 static gboolean win32_keep_fatal_message
= FALSE
;
107 /* This default message will usually be overwritten. */
108 /* Yes, a fixed size buffer is bad. So sue me. But g_error() is never
109 * called with huge strings, is it?
111 static gchar fatal_msg_buf
[1000] = "Unspecified fatal error encountered, aborting.";
112 static gchar
*fatal_msg_ptr
= fatal_msg_buf
;
120 if (win32_keep_fatal_message
)
122 memcpy (fatal_msg_ptr
, buf
, len
);
123 fatal_msg_ptr
+= len
;
128 write (fd
, buf
, len
);
132 #define write(fd, buf, len) dowrite(fd, buf, len)
137 write_string (int fd
,
140 write (fd
, string
, strlen (string
));
144 g_messages_prefixed_init (void)
146 static gboolean initialized
= FALSE
;
153 val
= g_getenv ("G_MESSAGES_PREFIXED");
157 const GDebugKey keys
[] = {
158 { "error", G_LOG_LEVEL_ERROR
},
159 { "critical", G_LOG_LEVEL_CRITICAL
},
160 { "warning", G_LOG_LEVEL_WARNING
},
161 { "message", G_LOG_LEVEL_MESSAGE
},
162 { "info", G_LOG_LEVEL_INFO
},
163 { "debug", G_LOG_LEVEL_DEBUG
}
166 g_log_msg_prefix
= g_parse_debug_string (val
, keys
, G_N_ELEMENTS (keys
));
172 g_log_find_domain_L (const gchar
*log_domain
)
174 register GLogDomain
*domain
;
176 domain
= g_log_domains
;
179 if (strcmp (domain
->log_domain
, log_domain
) == 0)
181 domain
= domain
->next
;
187 g_log_domain_new_L (const gchar
*log_domain
)
189 register GLogDomain
*domain
;
191 domain
= g_new (GLogDomain
, 1);
192 domain
->log_domain
= g_strdup (log_domain
);
193 domain
->fatal_mask
= G_LOG_FATAL_MASK
;
194 domain
->handlers
= NULL
;
196 domain
->next
= g_log_domains
;
197 g_log_domains
= domain
;
203 g_log_domain_check_free_L (GLogDomain
*domain
)
205 if (domain
->fatal_mask
== G_LOG_FATAL_MASK
&&
206 domain
->handlers
== NULL
)
208 register GLogDomain
*last
, *work
;
212 work
= g_log_domains
;
218 last
->next
= domain
->next
;
220 g_log_domains
= domain
->next
;
221 g_free (domain
->log_domain
);
232 g_log_domain_get_handler_L (GLogDomain
*domain
,
233 GLogLevelFlags log_level
,
236 if (domain
&& log_level
)
238 register GLogHandler
*handler
;
240 handler
= domain
->handlers
;
243 if ((handler
->log_level
& log_level
) == log_level
)
245 *data
= handler
->data
;
246 return handler
->log_func
;
248 handler
= handler
->next
;
252 *data
= default_log_data
;
253 return default_log_func
;
257 g_log_set_always_fatal (GLogLevelFlags fatal_mask
)
259 GLogLevelFlags old_mask
;
261 /* restrict the global mask to levels that are known to glib
262 * since this setting applies to all domains
264 fatal_mask
&= (1 << G_LOG_LEVEL_USER_SHIFT
) - 1;
265 /* force errors to be fatal */
266 fatal_mask
|= G_LOG_LEVEL_ERROR
;
267 /* remove bogus flag */
268 fatal_mask
&= ~G_LOG_FLAG_FATAL
;
270 g_mutex_lock (g_messages_lock
);
271 old_mask
= g_log_always_fatal
;
272 g_log_always_fatal
= fatal_mask
;
273 g_mutex_unlock (g_messages_lock
);
279 g_log_set_fatal_mask (const gchar
*log_domain
,
280 GLogLevelFlags fatal_mask
)
282 GLogLevelFlags old_flags
;
283 register GLogDomain
*domain
;
288 /* force errors to be fatal */
289 fatal_mask
|= G_LOG_LEVEL_ERROR
;
290 /* remove bogus flag */
291 fatal_mask
&= ~G_LOG_FLAG_FATAL
;
293 g_mutex_lock (g_messages_lock
);
295 domain
= g_log_find_domain_L (log_domain
);
297 domain
= g_log_domain_new_L (log_domain
);
298 old_flags
= domain
->fatal_mask
;
300 domain
->fatal_mask
= fatal_mask
;
301 g_log_domain_check_free_L (domain
);
303 g_mutex_unlock (g_messages_lock
);
309 g_log_set_handler (const gchar
*log_domain
,
310 GLogLevelFlags log_levels
,
314 static guint handler_id
= 0;
316 GLogHandler
*handler
;
318 g_return_val_if_fail ((log_levels
& G_LOG_LEVEL_MASK
) != 0, 0);
319 g_return_val_if_fail (log_func
!= NULL
, 0);
324 handler
= g_new (GLogHandler
, 1);
326 g_mutex_lock (g_messages_lock
);
328 domain
= g_log_find_domain_L (log_domain
);
330 domain
= g_log_domain_new_L (log_domain
);
332 handler
->id
= ++handler_id
;
333 handler
->log_level
= log_levels
;
334 handler
->log_func
= log_func
;
335 handler
->data
= user_data
;
336 handler
->next
= domain
->handlers
;
337 domain
->handlers
= handler
;
339 g_mutex_unlock (g_messages_lock
);
345 g_log_set_default_handler (GLogFunc log_func
,
348 GLogFunc old_log_func
;
350 g_mutex_lock (g_messages_lock
);
351 old_log_func
= default_log_func
;
352 default_log_func
= log_func
;
353 default_log_data
= user_data
;
354 g_mutex_unlock (g_messages_lock
);
360 * g_test_log_set_fatal_handler:
361 * @log_func: the log handler function.
362 * @user_data: data passed to the log handler.
364 * Installs a non-error fatal log handler which can be
365 * used to decide whether log messages which are counted
366 * as fatal abort the program.
368 * The use case here is that you are running a test case
369 * that depends on particular libraries or circumstances
370 * and cannot prevent certain known critical or warning
371 * messages. So you install a handler that compares the
372 * domain and message to precisely not abort in such a case.
374 * Note that the handler is reset at the beginning of
375 * any test case, so you have to set it inside each test
376 * function which needs the special behavior.
378 * This handler has no effect on g_error messages.
383 g_test_log_set_fatal_handler (GTestLogFatalFunc log_func
,
386 g_mutex_lock (g_messages_lock
);
387 fatal_log_func
= log_func
;
388 fatal_log_data
= user_data
;
389 g_mutex_unlock (g_messages_lock
);
393 g_log_remove_handler (const gchar
*log_domain
,
396 register GLogDomain
*domain
;
398 g_return_if_fail (handler_id
> 0);
403 g_mutex_lock (g_messages_lock
);
404 domain
= g_log_find_domain_L (log_domain
);
407 GLogHandler
*work
, *last
;
410 work
= domain
->handlers
;
413 if (work
->id
== handler_id
)
416 last
->next
= work
->next
;
418 domain
->handlers
= work
->next
;
419 g_log_domain_check_free_L (domain
);
420 g_mutex_unlock (g_messages_lock
);
428 g_mutex_unlock (g_messages_lock
);
429 g_warning ("%s: could not find handler with id `%d' for domain \"%s\"",
430 G_STRLOC
, handler_id
, log_domain
);
434 g_logv (const gchar
*log_domain
,
435 GLogLevelFlags log_level
,
439 gboolean was_fatal
= (log_level
& G_LOG_FLAG_FATAL
) != 0;
440 gboolean was_recursion
= (log_level
& G_LOG_FLAG_RECURSION
) != 0;
443 log_level
&= G_LOG_LEVEL_MASK
;
447 for (i
= g_bit_nth_msf (log_level
, -1); i
>= 0; i
= g_bit_nth_msf (log_level
, i
))
449 register GLogLevelFlags test_level
;
452 if (log_level
& test_level
)
454 guint depth
= GPOINTER_TO_UINT (g_private_get (g_log_depth
));
457 GLogLevelFlags domain_fatal_mask
;
458 gpointer data
= NULL
;
459 gboolean masquerade_fatal
= FALSE
;
462 test_level
|= G_LOG_FLAG_FATAL
;
464 test_level
|= G_LOG_FLAG_RECURSION
;
466 /* check recursion and lookup handler */
467 g_mutex_lock (g_messages_lock
);
468 domain
= g_log_find_domain_L (log_domain
? log_domain
: "");
470 test_level
|= G_LOG_FLAG_RECURSION
;
472 domain_fatal_mask
= domain
? domain
->fatal_mask
: G_LOG_FATAL_MASK
;
473 if ((domain_fatal_mask
| g_log_always_fatal
) & test_level
)
474 test_level
|= G_LOG_FLAG_FATAL
;
475 if (test_level
& G_LOG_FLAG_RECURSION
)
476 log_func
= _g_log_fallback_handler
;
478 log_func
= g_log_domain_get_handler_L (domain
, test_level
, &data
);
480 g_mutex_unlock (g_messages_lock
);
482 g_private_set (g_log_depth
, GUINT_TO_POINTER (depth
));
484 /* had to defer debug initialization until we can keep track of recursion */
485 if (!(test_level
& G_LOG_FLAG_RECURSION
) && !_g_debug_initialized
)
487 GLogLevelFlags orig_test_level
= test_level
;
490 if ((domain_fatal_mask
| g_log_always_fatal
) & test_level
)
491 test_level
|= G_LOG_FLAG_FATAL
;
492 if (test_level
!= orig_test_level
)
494 /* need a relookup, not nice, but not too bad either */
495 g_mutex_lock (g_messages_lock
);
496 domain
= g_log_find_domain_L (log_domain
? log_domain
: "");
497 log_func
= g_log_domain_get_handler_L (domain
, test_level
, &data
);
499 g_mutex_unlock (g_messages_lock
);
503 if (test_level
& G_LOG_FLAG_RECURSION
)
505 /* we use a stack buffer of fixed size, since we're likely
506 * in an out-of-memory situation
509 gsize size G_GNUC_UNUSED
;
512 G_VA_COPY (args2
, args1
);
513 size
= _g_vsnprintf (buffer
, 1024, format
, args2
);
516 log_func (log_domain
, test_level
, buffer
, data
);
523 G_VA_COPY (args2
, args1
);
524 msg
= g_strdup_vprintf (format
, args2
);
527 log_func (log_domain
, test_level
, msg
, data
);
529 if ((test_level
& G_LOG_FLAG_FATAL
)
530 && !(test_level
& G_LOG_LEVEL_ERROR
))
532 masquerade_fatal
= fatal_log_func
533 && !fatal_log_func (log_domain
, test_level
, msg
, data
);
539 if ((test_level
& G_LOG_FLAG_FATAL
) && !masquerade_fatal
)
542 gchar
*locale_msg
= g_locale_from_utf8 (fatal_msg_buf
, -1, NULL
, NULL
, NULL
);
544 MessageBox (NULL
, locale_msg
, NULL
,
545 MB_ICONERROR
|MB_SETFOREGROUND
);
546 if (IsDebuggerPresent () && !(test_level
& G_LOG_FLAG_RECURSION
))
551 #if defined (G_ENABLE_DEBUG) && defined (SIGTRAP)
552 if (!(test_level
& G_LOG_FLAG_RECURSION
))
556 #else /* !G_ENABLE_DEBUG || !SIGTRAP */
558 #endif /* !G_ENABLE_DEBUG || !SIGTRAP */
559 #endif /* !G_OS_WIN32 */
563 g_private_set (g_log_depth
, GUINT_TO_POINTER (depth
));
569 g_log (const gchar
*log_domain
,
570 GLogLevelFlags log_level
,
576 va_start (args
, format
);
577 g_logv (log_domain
, log_level
, format
, args
);
582 g_return_if_fail_warning (const char *log_domain
,
583 const char *pretty_function
,
584 const char *expression
)
587 G_LOG_LEVEL_CRITICAL
,
588 "%s: assertion `%s' failed",
594 g_warn_message (const char *domain
,
598 const char *warnexpr
)
601 g_snprintf (lstr
, 32, "%d", line
);
603 s
= g_strconcat ("(", file
, ":", lstr
, "):",
604 func
, func
[0] ? ":" : "",
605 " runtime check failed: (", warnexpr
, ")", NULL
);
607 s
= g_strconcat ("(", file
, ":", lstr
, "):",
608 func
, func
[0] ? ":" : "",
609 " ", "code should not be reached", NULL
);
610 g_log (domain
, G_LOG_LEVEL_WARNING
, "%s", s
);
615 g_assert_warning (const char *log_domain
,
618 const char *pretty_function
,
619 const char *expression
)
624 ? "file %s: line %d (%s): assertion failed: (%s)"
625 : "file %s: line %d (%s): should not be reached",
633 #define CHAR_IS_SAFE(wc) (!((wc < 0x20 && wc != '\t' && wc != '\n' && wc != '\r') || \
635 (wc >= 0x80 && wc < 0xa0)))
638 strdup_convert (const gchar
*string
,
639 const gchar
*charset
)
641 if (!g_utf8_validate (string
, -1, NULL
))
643 GString
*gstring
= g_string_new ("[Invalid UTF-8] ");
646 for (p
= (guchar
*)string
; *p
; p
++)
648 if (CHAR_IS_SAFE(*p
) &&
649 !(*p
== '\r' && *(p
+ 1) != '\n') &&
651 g_string_append_c (gstring
, *p
);
653 g_string_append_printf (gstring
, "\\x%02x", (guint
)(guchar
)*p
);
656 return g_string_free (gstring
, FALSE
);
662 gchar
*result
= g_convert_with_fallback (string
, -1, charset
, "UTF-8", "?", NULL
, NULL
, &err
);
667 /* Not thread-safe, but doesn't matter if we print the warning twice
669 static gboolean warned
= FALSE
;
673 _g_fprintf (stderr
, "GLib: Cannot convert message: %s\n", err
->message
);
677 return g_strdup (string
);
682 /* For a radix of 8 we need at most 3 output bytes for 1 input
683 * byte. Additionally we might need up to 2 output bytes for the
684 * readix prefix and 1 byte for the trailing NULL.
686 #define FORMAT_UNSIGNED_BUFSIZE ((GLIB_SIZEOF_LONG * 3) + 3)
689 format_unsigned (gchar
*buf
,
697 /* we may not call _any_ GLib functions here (or macros like g_return_if_fail()) */
699 if (radix
!= 8 && radix
!= 10 && radix
!= 16)
732 /* Again we can't use g_assert; actually this check should _never_ fail. */
733 if (n
> FORMAT_UNSIGNED_BUFSIZE
- 3)
746 buf
[i
] = c
+ 'a' - 10;
753 /* string size big enough to hold level prefix */
754 #define STRING_BUFFER_SIZE (FORMAT_UNSIGNED_BUFSIZE + 32)
756 #define ALERT_LEVELS (G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING)
759 mklevel_prefix (gchar level_prefix
[STRING_BUFFER_SIZE
],
760 GLogLevelFlags log_level
)
762 gboolean to_stdout
= TRUE
;
764 /* we may not call _any_ GLib functions here */
766 switch (log_level
& G_LOG_LEVEL_MASK
)
768 case G_LOG_LEVEL_ERROR
:
769 strcpy (level_prefix
, "ERROR");
772 case G_LOG_LEVEL_CRITICAL
:
773 strcpy (level_prefix
, "CRITICAL");
776 case G_LOG_LEVEL_WARNING
:
777 strcpy (level_prefix
, "WARNING");
780 case G_LOG_LEVEL_MESSAGE
:
781 strcpy (level_prefix
, "Message");
784 case G_LOG_LEVEL_INFO
:
785 strcpy (level_prefix
, "INFO");
787 case G_LOG_LEVEL_DEBUG
:
788 strcpy (level_prefix
, "DEBUG");
793 strcpy (level_prefix
, "LOG-");
794 format_unsigned (level_prefix
+ 4, log_level
& G_LOG_LEVEL_MASK
, 16);
797 strcpy (level_prefix
, "LOG");
800 if (log_level
& G_LOG_FLAG_RECURSION
)
801 strcat (level_prefix
, " (recursed)");
802 if (log_level
& ALERT_LEVELS
)
803 strcat (level_prefix
, " **");
806 win32_keep_fatal_message
= (log_level
& G_LOG_FLAG_FATAL
) != 0;
808 return to_stdout
? 1 : 2;
812 _g_log_fallback_handler (const gchar
*log_domain
,
813 GLogLevelFlags log_level
,
814 const gchar
*message
,
815 gpointer unused_data
)
817 gchar level_prefix
[STRING_BUFFER_SIZE
];
819 gchar pid_string
[FORMAT_UNSIGNED_BUFSIZE
];
821 gboolean is_fatal
= (log_level
& G_LOG_FLAG_FATAL
) != 0;
824 /* we can not call _any_ GLib functions in this fallback handler,
825 * which is why we skip UTF-8 conversion, etc.
826 * since we either recursed or ran out of memory, we're in a pretty
827 * pathologic situation anyways, what we can do is giving the
828 * the process ID unconditionally however.
831 fd
= mklevel_prefix (level_prefix
, log_level
);
833 message
= "(NULL) message";
836 format_unsigned (pid_string
, getpid (), 10);
840 write_string (fd
, "\n");
842 write_string (fd
, "\n** ");
845 write_string (fd
, "(process:");
846 write_string (fd
, pid_string
);
847 write_string (fd
, "): ");
852 write_string (fd
, log_domain
);
853 write_string (fd
, "-");
855 write_string (fd
, level_prefix
);
856 write_string (fd
, ": ");
857 write_string (fd
, message
);
859 write_string (fd
, "\naborting...\n");
861 write_string (fd
, "\n");
865 escape_string (GString
*string
)
867 const char *p
= string
->str
;
870 while (p
< string
->str
+ string
->len
)
874 wc
= g_utf8_get_char_validated (p
, -1);
875 if (wc
== (gunichar
)-1 || wc
== (gunichar
)-2)
880 pos
= p
- string
->str
;
882 /* Emit invalid UTF-8 as hex escapes
884 tmp
= g_strdup_printf ("\\x%02x", (guint
)(guchar
)*p
);
885 g_string_erase (string
, pos
, 1);
886 g_string_insert (string
, pos
, tmp
);
888 p
= string
->str
+ (pos
+ 4); /* Skip over escape sequence */
895 safe
= *(p
+ 1) == '\n';
899 safe
= CHAR_IS_SAFE (wc
);
907 pos
= p
- string
->str
;
909 /* Largest char we escape is 0x0a, so we don't have to worry
910 * about 8-digit \Uxxxxyyyy
912 tmp
= g_strdup_printf ("\\u%04x", wc
);
913 g_string_erase (string
, pos
, g_utf8_next_char (p
) - p
);
914 g_string_insert (string
, pos
, tmp
);
917 p
= string
->str
+ (pos
+ 6); /* Skip over escape sequence */
920 p
= g_utf8_next_char (p
);
925 g_log_default_handler (const gchar
*log_domain
,
926 GLogLevelFlags log_level
,
927 const gchar
*message
,
928 gpointer unused_data
)
930 gboolean is_fatal
= (log_level
& G_LOG_FLAG_FATAL
) != 0;
931 gchar level_prefix
[STRING_BUFFER_SIZE
], *string
;
935 /* we can be called externally with recursion for whatever reason */
936 if (log_level
& G_LOG_FLAG_RECURSION
)
938 _g_log_fallback_handler (log_domain
, log_level
, message
, unused_data
);
942 g_messages_prefixed_init ();
944 fd
= mklevel_prefix (level_prefix
, log_level
);
946 gstring
= g_string_new (NULL
);
947 if (log_level
& ALERT_LEVELS
)
948 g_string_append (gstring
, "\n");
950 g_string_append (gstring
, "** ");
952 if ((g_log_msg_prefix
& log_level
) == log_level
)
954 const gchar
*prg_name
= g_get_prgname ();
957 g_string_append_printf (gstring
, "(process:%lu): ", (gulong
)getpid ());
959 g_string_append_printf (gstring
, "(%s:%lu): ", prg_name
, (gulong
)getpid ());
964 g_string_append (gstring
, log_domain
);
965 g_string_append_c (gstring
, '-');
967 g_string_append (gstring
, level_prefix
);
969 g_string_append (gstring
, ": ");
971 g_string_append (gstring
, "(NULL) message");
975 const gchar
*charset
;
977 msg
= g_string_new (message
);
980 if (g_get_charset (&charset
))
981 g_string_append (gstring
, msg
->str
); /* charset is UTF-8 already */
984 string
= strdup_convert (msg
->str
, charset
);
985 g_string_append (gstring
, string
);
989 g_string_free (msg
, TRUE
);
992 g_string_append (gstring
, "\naborting...\n");
994 g_string_append (gstring
, "\n");
996 string
= g_string_free (gstring
, FALSE
);
998 write_string (fd
, string
);
1003 g_set_print_handler (GPrintFunc func
)
1005 GPrintFunc old_print_func
;
1007 g_mutex_lock (g_messages_lock
);
1008 old_print_func
= glib_print_func
;
1009 glib_print_func
= func
;
1010 g_mutex_unlock (g_messages_lock
);
1012 return old_print_func
;
1016 g_print (const gchar
*format
,
1021 GPrintFunc local_glib_print_func
;
1023 g_return_if_fail (format
!= NULL
);
1025 va_start (args
, format
);
1026 string
= g_strdup_vprintf (format
, args
);
1029 g_mutex_lock (g_messages_lock
);
1030 local_glib_print_func
= glib_print_func
;
1031 g_mutex_unlock (g_messages_lock
);
1033 if (local_glib_print_func
)
1034 local_glib_print_func (string
);
1037 const gchar
*charset
;
1039 if (g_get_charset (&charset
))
1040 fputs (string
, stdout
); /* charset is UTF-8 already */
1043 gchar
*lstring
= strdup_convert (string
, charset
);
1045 fputs (lstring
, stdout
);
1054 g_set_printerr_handler (GPrintFunc func
)
1056 GPrintFunc old_printerr_func
;
1058 g_mutex_lock (g_messages_lock
);
1059 old_printerr_func
= glib_printerr_func
;
1060 glib_printerr_func
= func
;
1061 g_mutex_unlock (g_messages_lock
);
1063 return old_printerr_func
;
1067 g_printerr (const gchar
*format
,
1072 GPrintFunc local_glib_printerr_func
;
1074 g_return_if_fail (format
!= NULL
);
1076 va_start (args
, format
);
1077 string
= g_strdup_vprintf (format
, args
);
1080 g_mutex_lock (g_messages_lock
);
1081 local_glib_printerr_func
= glib_printerr_func
;
1082 g_mutex_unlock (g_messages_lock
);
1084 if (local_glib_printerr_func
)
1085 local_glib_printerr_func (string
);
1088 const gchar
*charset
;
1090 if (g_get_charset (&charset
))
1091 fputs (string
, stderr
); /* charset is UTF-8 already */
1094 gchar
*lstring
= strdup_convert (string
, charset
);
1096 fputs (lstring
, stderr
);
1105 g_printf_string_upper_bound (const gchar
*format
,
1109 return _g_vsnprintf (&c
, 1, format
, args
) + 1;
1113 _g_messages_thread_init_nomessage (void)
1115 g_messages_lock
= g_mutex_new ();
1116 g_log_depth
= g_private_new (NULL
);
1117 g_messages_prefixed_init ();
1121 gboolean _g_debug_initialized
= FALSE
;
1122 guint _g_debug_flags
= 0;
1125 _g_debug_init (void)
1129 _g_debug_initialized
= TRUE
;
1131 val
= g_getenv ("G_DEBUG");
1134 const GDebugKey keys
[] = {
1135 {"fatal_warnings", G_DEBUG_FATAL_WARNINGS
},
1136 {"fatal_criticals", G_DEBUG_FATAL_CRITICALS
}
1139 _g_debug_flags
= g_parse_debug_string (val
, keys
, G_N_ELEMENTS (keys
));
1142 if (_g_debug_flags
& G_DEBUG_FATAL_WARNINGS
)
1144 GLogLevelFlags fatal_mask
;
1146 fatal_mask
= g_log_set_always_fatal (G_LOG_FATAL_MASK
);
1147 fatal_mask
|= G_LOG_LEVEL_WARNING
| G_LOG_LEVEL_CRITICAL
;
1148 g_log_set_always_fatal (fatal_mask
);
1151 if (_g_debug_flags
& G_DEBUG_FATAL_CRITICALS
)
1153 GLogLevelFlags fatal_mask
;
1155 fatal_mask
= g_log_set_always_fatal (G_LOG_FATAL_MASK
);
1156 fatal_mask
|= G_LOG_LEVEL_CRITICAL
;
1157 g_log_set_always_fatal (fatal_mask
);