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/.
48 typedef FILE* GFileDescriptor
;
50 typedef gint GFileDescriptor
;
53 /* --- structures --- */
54 typedef struct _GLogDomain GLogDomain
;
55 typedef struct _GLogHandler GLogHandler
;
59 GLogLevelFlags fatal_mask
;
60 GLogHandler
*handlers
;
66 GLogLevelFlags log_level
;
73 /* --- prototypes --- */
74 static inline guint
printf_string_upper_bound (const gchar
*format
,
79 /* --- variables --- */
81 static GMutex
* g_messages_lock
= NULL
;
83 const gchar
*g_log_domain_glib
= "GLib";
84 static GLogDomain
*g_log_domains
= NULL
;
85 static GLogLevelFlags g_log_always_fatal
= G_LOG_FATAL_MASK
;
86 static GPrintFunc glib_print_func
= NULL
;
87 static GPrintFunc glib_printerr_func
= NULL
;
88 static GErrorFunc glib_error_func
= NULL
;
89 static GWarningFunc glib_warning_func
= NULL
;
90 static GPrintFunc glib_message_func
= NULL
;
92 static GPrivate
* g_log_depth
= NULL
;
94 /* --- functions --- */
99 # include <process.h> /* For _getpid() */
101 static gboolean alloc_console_called
= FALSE
;
103 static gboolean gonna_abort
= FALSE
;
105 /* This default message will usually be overwritten. */
106 /* Yes, a fixed size buffer is bad. So sue me. But g_error is never
107 * with huge strings, is it? */
108 static char fatal_msg_buf
[1000] = "Unspecified fatal error encountered, aborting.";
109 static char *fatal_msg_ptr
= fatal_msg_buf
;
111 /* Just use stdio. If we're out of memory, we're hosed anyway. */
114 dowrite (GFileDescriptor fd
,
120 memcpy (fatal_msg_ptr
, buf
, len
);
121 fatal_msg_ptr
+= len
;
126 fwrite (buf
, len
, 1, fd
);
132 #define write(fd, buf, len) dowrite(fd, buf, len)
135 ensure_stdout_valid (void)
142 if (!alloc_console_called
)
144 handle
= GetStdHandle (STD_OUTPUT_HANDLE
);
146 if (handle
== INVALID_HANDLE_VALUE
)
149 alloc_console_called
= TRUE
;
150 freopen ("CONOUT$", "w", stdout
);
155 #define ensure_stdout_valid() /* Define as empty */
159 write_unsigned (GFileDescriptor fd
,
168 g_return_if_fail (radix
>= 2 && radix
<= 36);
197 buffer
[i
] = c
+ 'a' - 10;
201 write (fd
, buffer
, n
);
205 write_string (GFileDescriptor fd
,
208 write (fd
, string
, strlen (string
));
212 g_log_write_prefix (GFileDescriptor fd
,
215 static GLogLevelFlags g_log_msg_prefix
= G_LOG_LEVEL_ERROR
| G_LOG_LEVEL_WARNING
| G_LOG_LEVEL_CRITICAL
| G_LOG_LEVEL_DEBUG
;
216 static gboolean initialized
= FALSE
;
218 g_mutex_lock (g_messages_lock
);
225 val
= g_getenv ("G_MESSAGES_PREFIXED");
229 static const GDebugKey keys
[] = {
230 { "error", G_LOG_LEVEL_ERROR
},
231 { "critical", G_LOG_LEVEL_CRITICAL
},
232 { "warning", G_LOG_LEVEL_WARNING
},
233 { "message", G_LOG_LEVEL_MESSAGE
},
234 { "info", G_LOG_LEVEL_INFO
},
235 { "debug", G_LOG_LEVEL_DEBUG
}
238 g_log_msg_prefix
= g_parse_debug_string (val
, keys
, G_N_ELEMENTS (keys
));
242 g_mutex_unlock (g_messages_lock
);
244 if ((g_log_msg_prefix
& mask
) == mask
)
248 prg_name
= g_get_prgname ();
251 write_string (fd
, "(process:");
254 write_string (fd
, prg_name
);
255 write_string (fd
, " (pid:");
258 write_unsigned (fd
, getpid (), 10);
259 write_string (fd
, "): ");
263 static inline GLogDomain
*
264 g_log_find_domain (const gchar
*log_domain
)
266 register GLogDomain
*domain
;
268 g_mutex_lock (g_messages_lock
);
269 domain
= g_log_domains
;
272 if (strcmp (domain
->log_domain
, log_domain
) == 0)
274 g_mutex_unlock (g_messages_lock
);
277 domain
= domain
->next
;
279 g_mutex_unlock (g_messages_lock
);
283 static inline GLogDomain
*
284 g_log_domain_new (const gchar
*log_domain
)
286 register GLogDomain
*domain
;
288 domain
= g_new (GLogDomain
, 1);
289 domain
->log_domain
= g_strdup (log_domain
);
290 domain
->fatal_mask
= G_LOG_FATAL_MASK
;
291 domain
->handlers
= NULL
;
293 g_mutex_lock (g_messages_lock
);
294 domain
->next
= g_log_domains
;
295 g_log_domains
= domain
;
296 g_mutex_unlock (g_messages_lock
);
302 g_log_domain_check_free (GLogDomain
*domain
)
304 if (domain
->fatal_mask
== G_LOG_FATAL_MASK
&&
305 domain
->handlers
== NULL
)
307 register GLogDomain
*last
, *work
;
311 g_mutex_lock (g_messages_lock
);
312 work
= g_log_domains
;
318 last
->next
= domain
->next
;
320 g_log_domains
= domain
->next
;
321 g_free (domain
->log_domain
);
328 g_mutex_unlock (g_messages_lock
);
332 static inline GLogFunc
333 g_log_domain_get_handler (GLogDomain
*domain
,
334 GLogLevelFlags log_level
,
337 if (domain
&& log_level
)
339 register GLogHandler
*handler
;
341 handler
= domain
->handlers
;
344 if ((handler
->log_level
& log_level
) == log_level
)
346 *data
= handler
->data
;
347 return handler
->log_func
;
349 handler
= handler
->next
;
352 return g_log_default_handler
;
356 g_log_set_always_fatal (GLogLevelFlags fatal_mask
)
358 GLogLevelFlags old_mask
;
360 /* restrict the global mask to levels that are known to glib */
361 fatal_mask
&= (1 << G_LOG_LEVEL_USER_SHIFT
) - 1;
362 /* force errors to be fatal */
363 fatal_mask
|= G_LOG_LEVEL_ERROR
;
364 /* remove bogus flag */
365 fatal_mask
&= ~G_LOG_FLAG_FATAL
;
367 g_mutex_lock (g_messages_lock
);
368 old_mask
= g_log_always_fatal
;
369 g_log_always_fatal
= fatal_mask
;
370 g_mutex_unlock (g_messages_lock
);
376 g_log_set_fatal_mask (const gchar
*log_domain
,
377 GLogLevelFlags fatal_mask
)
379 GLogLevelFlags old_flags
;
380 register GLogDomain
*domain
;
385 /* force errors to be fatal */
386 fatal_mask
|= G_LOG_LEVEL_ERROR
;
387 /* remove bogus flag */
388 fatal_mask
&= ~G_LOG_FLAG_FATAL
;
390 domain
= g_log_find_domain (log_domain
);
392 domain
= g_log_domain_new (log_domain
);
393 old_flags
= domain
->fatal_mask
;
395 domain
->fatal_mask
= fatal_mask
;
396 g_log_domain_check_free (domain
);
402 g_log_set_handler (const gchar
*log_domain
,
403 GLogLevelFlags log_levels
,
407 register GLogDomain
*domain
;
408 register GLogHandler
*handler
;
409 static guint handler_id
= 0;
411 g_return_val_if_fail ((log_levels
& G_LOG_LEVEL_MASK
) != 0, 0);
412 g_return_val_if_fail (log_func
!= NULL
, 0);
417 domain
= g_log_find_domain (log_domain
);
419 domain
= g_log_domain_new (log_domain
);
421 handler
= g_new (GLogHandler
, 1);
422 g_mutex_lock (g_messages_lock
);
423 handler
->id
= ++handler_id
;
424 g_mutex_unlock (g_messages_lock
);
425 handler
->log_level
= log_levels
;
426 handler
->log_func
= log_func
;
427 handler
->data
= user_data
;
428 handler
->next
= domain
->handlers
;
429 domain
->handlers
= handler
;
435 g_log_remove_handler (const gchar
*log_domain
,
438 register GLogDomain
*domain
;
440 g_return_if_fail (handler_id
> 0);
445 domain
= g_log_find_domain (log_domain
);
448 register GLogHandler
*work
, *last
;
451 work
= domain
->handlers
;
454 if (work
->id
== handler_id
)
457 last
->next
= work
->next
;
459 domain
->handlers
= work
->next
;
461 g_log_domain_check_free (domain
);
468 g_warning ("g_log_remove_handler(): could not find handler with id `%d' for domain \"%s\"",
474 g_logv (const gchar
*log_domain
,
475 GLogLevelFlags log_level
,
483 log_level
&= G_LOG_LEVEL_MASK
;
487 /* we use a stack buffer of fixed size, because we might get called
490 G_VA_COPY (args2
, args1
);
491 if (printf_string_upper_bound (format
, FALSE
, args1
) < 1024)
492 vsprintf (buffer
, format
, args2
);
495 /* since we might be out of memory, we can't use g_vsnprintf(). */
496 #ifdef HAVE_VSNPRINTF
497 vsnprintf (buffer
, 1024, format
, args2
);
498 #else /* !HAVE_VSNPRINTF */
499 /* we are out of luck here */
500 strncpy (buffer
, format
, 1024);
501 #endif /* !HAVE_VSNPRINTF */
506 for (i
= g_bit_nth_msf (log_level
, -1); i
>= 0; i
= g_bit_nth_msf (log_level
, i
))
508 register GLogLevelFlags test_level
;
511 if (log_level
& test_level
)
513 guint depth
= GPOINTER_TO_UINT (g_private_get (g_log_depth
));
516 gpointer data
= NULL
;
518 domain
= g_log_find_domain (log_domain
? log_domain
: "");
521 test_level
|= G_LOG_FLAG_RECURSION
;
524 g_private_set (g_log_depth
, GUINT_TO_POINTER (depth
));
526 g_mutex_lock (g_messages_lock
);
527 if ((((domain
? domain
->fatal_mask
: G_LOG_FATAL_MASK
) |
528 g_log_always_fatal
) & test_level
) != 0)
529 test_level
|= G_LOG_FLAG_FATAL
;
530 g_mutex_unlock (g_messages_lock
);
532 log_func
= g_log_domain_get_handler (domain
, test_level
, &data
);
533 log_func (log_domain
, test_level
, buffer
, data
);
535 /* *domain can be cluttered now */
537 if (test_level
& G_LOG_FLAG_FATAL
)
539 #if defined (G_ENABLE_DEBUG) && defined (SIGTRAP)
540 if (!(test_level
& G_LOG_FLAG_RECURSION
))
544 #else /* !G_ENABLE_DEBUG || !SIGTRAP */
546 MessageBox (NULL
, fatal_msg_buf
, NULL
, MB_OK
);
548 # if defined (_MSC_VER) && defined (_DEBUG)
549 /* let's see the call stack ... */
553 #endif /* !G_ENABLE_DEBUG || !SIGTRAP */
557 g_private_set (g_log_depth
, GUINT_TO_POINTER (depth
));
563 g_log (const gchar
*log_domain
,
564 GLogLevelFlags log_level
,
570 va_start (args
, format
);
571 g_logv (log_domain
, log_level
, format
, args
);
576 g_log_default_handler (const gchar
*log_domain
,
577 GLogLevelFlags log_level
,
578 const gchar
*message
,
579 gpointer unused_data
)
582 gboolean in_recursion
;
584 GErrorFunc local_glib_error_func
;
585 GWarningFunc local_glib_warning_func
;
586 GPrintFunc local_glib_message_func
;
588 in_recursion
= (log_level
& G_LOG_FLAG_RECURSION
) != 0;
589 is_fatal
= (log_level
& G_LOG_FLAG_FATAL
) != 0;
590 log_level
&= G_LOG_LEVEL_MASK
;
593 message
= "g_log_default_handler(): (NULL) message";
596 /* Use just stdout as stderr is hard to get redirected from the
600 gonna_abort
= is_fatal
;
602 fd
= (log_level
> G_LOG_LEVEL_MESSAGE
) ? 1 : 2;
605 g_mutex_lock (g_messages_lock
);
606 local_glib_error_func
= glib_error_func
;
607 local_glib_warning_func
= glib_warning_func
;
608 local_glib_message_func
= glib_message_func
;
609 g_mutex_unlock (g_messages_lock
);
613 case G_LOG_LEVEL_ERROR
:
614 if (!log_domain
&& local_glib_error_func
)
616 /* compatibility code */
617 local_glib_error_func (message
);
620 /* use write(2) for output, in case we are out of memeory */
621 ensure_stdout_valid ();
623 g_log_write_prefix (fd
, log_level
);
627 write (fd
, log_domain
, strlen (log_domain
));
631 write (fd
, "** ", 3);
633 write (fd
, "ERROR (recursed) **: ", 21);
635 write (fd
, "ERROR **: ", 10);
636 write (fd
, message
, strlen (message
));
638 write (fd
, "\naborting...\n", 13);
642 case G_LOG_LEVEL_CRITICAL
:
643 ensure_stdout_valid ();
645 g_log_write_prefix (fd
, log_level
);
649 write (fd
, log_domain
, strlen (log_domain
));
653 write (fd
, "** ", 3);
655 write (fd
, "CRITICAL (recursed) **: ", 24);
657 write (fd
, "CRITICAL **: ", 13);
658 write (fd
, message
, strlen (message
));
660 write (fd
, "\naborting...\n", 13);
664 case G_LOG_LEVEL_WARNING
:
665 if (!log_domain
&& local_glib_warning_func
)
667 /* compatibility code */
668 local_glib_warning_func (message
);
671 ensure_stdout_valid ();
673 g_log_write_prefix (fd
, log_level
);
677 write (fd
, log_domain
, strlen (log_domain
));
681 write (fd
, "** ", 3);
683 write (fd
, "WARNING (recursed) **: ", 23);
685 write (fd
, "WARNING **: ", 12);
686 write (fd
, message
, strlen (message
));
688 write (fd
, "\naborting...\n", 13);
692 case G_LOG_LEVEL_MESSAGE
:
693 if (!log_domain
&& local_glib_message_func
)
695 /* compatibility code */
696 local_glib_message_func (message
);
699 ensure_stdout_valid ();
701 g_log_write_prefix (fd
, log_level
);
705 write (fd
, log_domain
, strlen (log_domain
));
709 write (fd
, "Message (recursed): ", 20);
711 write (fd
, "Message: ", 9);
712 write (fd
, message
, strlen (message
));
714 write (fd
, "\naborting...\n", 13);
718 case G_LOG_LEVEL_INFO
:
719 ensure_stdout_valid ();
721 g_log_write_prefix (fd
, log_level
);
725 write (fd
, log_domain
, strlen (log_domain
));
729 write (fd
, "INFO (recursed): ", 17);
731 write (fd
, "INFO: ", 6);
732 write (fd
, message
, strlen (message
));
734 write (fd
, "\naborting...\n", 13);
738 case G_LOG_LEVEL_DEBUG
:
739 ensure_stdout_valid ();
741 g_log_write_prefix (fd
, log_level
);
745 write (fd
, log_domain
, strlen (log_domain
));
749 write (fd
, "DEBUG (recursed): ", 18);
751 write (fd
, "DEBUG: ", 7);
752 write (fd
, message
, strlen (message
));
754 write (fd
, "\naborting...\n", 13);
759 /* we are used for a log level that is not defined by GLib itself,
760 * try to make the best out of it.
762 ensure_stdout_valid ();
764 g_log_write_prefix (fd
, log_level
);
768 write (fd
, log_domain
, strlen (log_domain
));
770 write (fd
, "-LOG (recursed:", 15);
772 write (fd
, "-LOG (", 6);
774 else if (in_recursion
)
775 write (fd
, "LOG (recursed:", 14);
777 write (fd
, "LOG (", 5);
780 gchar string
[] = "0x00): ";
781 gchar
*p
= string
+ 2;
784 i
= g_bit_nth_msf (log_level
, -1);
787 *p
= '0' + (i
& 0xf);
791 write (fd
, string
, 7);
794 write (fd
, "): ", 3);
795 write (fd
, message
, strlen (message
));
797 write (fd
, "\naborting...\n", 13);
805 g_set_print_handler (GPrintFunc func
)
807 GPrintFunc old_print_func
;
809 g_mutex_lock (g_messages_lock
);
810 old_print_func
= glib_print_func
;
811 glib_print_func
= func
;
812 g_mutex_unlock (g_messages_lock
);
814 return old_print_func
;
818 g_print (const gchar
*format
,
823 GPrintFunc local_glib_print_func
;
825 g_return_if_fail (format
!= NULL
);
827 va_start (args
, format
);
828 string
= g_strdup_vprintf (format
, args
);
831 g_mutex_lock (g_messages_lock
);
832 local_glib_print_func
= glib_print_func
;
833 g_mutex_unlock (g_messages_lock
);
835 if (local_glib_print_func
)
836 local_glib_print_func (string
);
839 ensure_stdout_valid ();
840 fputs (string
, stdout
);
847 g_set_printerr_handler (GPrintFunc func
)
849 GPrintFunc old_printerr_func
;
851 g_mutex_lock (g_messages_lock
);
852 old_printerr_func
= glib_printerr_func
;
853 glib_printerr_func
= func
;
854 g_mutex_unlock (g_messages_lock
);
856 return old_printerr_func
;
860 g_printerr (const gchar
*format
,
865 GPrintFunc local_glib_printerr_func
;
867 g_return_if_fail (format
!= NULL
);
869 va_start (args
, format
);
870 string
= g_strdup_vprintf (format
, args
);
873 g_mutex_lock (g_messages_lock
);
874 local_glib_printerr_func
= glib_printerr_func
;
875 g_mutex_unlock (g_messages_lock
);
877 if (local_glib_printerr_func
)
878 local_glib_printerr_func (string
);
881 fputs (string
, stderr
);
887 /* compatibility code */
889 g_set_error_handler (GErrorFunc func
)
891 GErrorFunc old_error_func
;
893 g_mutex_lock (g_messages_lock
);
894 old_error_func
= glib_error_func
;
895 glib_error_func
= func
;
896 g_mutex_unlock (g_messages_lock
);
898 return old_error_func
;
901 /* compatibility code */
903 g_set_warning_handler (GWarningFunc func
)
905 GWarningFunc old_warning_func
;
907 g_mutex_lock (g_messages_lock
);
908 old_warning_func
= glib_warning_func
;
909 glib_warning_func
= func
;
910 g_mutex_unlock (g_messages_lock
);
912 return old_warning_func
;
915 /* compatibility code */
917 g_set_message_handler (GPrintFunc func
)
919 GPrintFunc old_message_func
;
921 g_mutex_lock (g_messages_lock
);
922 old_message_func
= glib_message_func
;
923 glib_message_func
= func
;
924 g_mutex_unlock (g_messages_lock
);
926 return old_message_func
;
930 # define MB_LEN_MAX 8
937 gboolean alternate_format
, zero_padding
, adjust_left
, locale_grouping
;
938 gboolean add_space
, add_sign
, possible_sign
, seen_precision
;
939 gboolean mod_half
, mod_long
, mod_extra_long
;
943 printf_string_upper_bound (const gchar
*format
,
947 static const gboolean honour_longs
= SIZEOF_LONG
> 4 || SIZEOF_VOID_P
> 4;
955 register gchar c
= *format
++;
959 else /* (c == '%') */
961 PrintfArgSpec spec
= { 0, };
962 gboolean seen_l
= FALSE
, conv_done
= FALSE
;
964 const gchar
*spec_start
= format
;
971 GDoubleIEEE754 u_double
;
974 const gchar
*v_string
;
976 /* beware of positional parameters
980 g_warning (G_GNUC_PRETTY_FUNCTION
981 "(): unable to handle positional parameters (%%n$)");
982 len
+= 1024; /* try adding some safety padding */
988 spec
.alternate_format
= TRUE
;
991 spec
.zero_padding
= TRUE
;
994 spec
.adjust_left
= TRUE
;
997 spec
.add_space
= TRUE
;
1000 spec
.add_sign
= TRUE
;
1003 spec
.locale_grouping
= TRUE
;
1006 /* parse output size specifications
1009 spec
.seen_precision
= TRUE
;
1022 while (c
>= '0' && c
<= '9')
1025 v_uint
= v_uint
* 10 + c
- '0';
1028 if (spec
.seen_precision
)
1029 spec
.precision
= MAX (spec
.precision
, v_uint
);
1031 spec
.min_width
= MAX (spec
.min_width
, v_uint
);
1034 v_int
= va_arg (args
, int);
1035 if (spec
.seen_precision
)
1037 /* forget about negative precision */
1039 spec
.precision
= MAX (spec
.precision
, v_int
);
1046 spec
.adjust_left
= TRUE
;
1048 spec
.min_width
= MAX (spec
.min_width
, v_int
);
1052 /* parse type modifiers
1055 spec
.mod_half
= TRUE
;
1060 spec
.mod_long
= TRUE
;
1064 /* else, fall through */
1067 spec
.mod_long
= TRUE
;
1068 spec
.mod_extra_long
= TRUE
;
1072 #if GLIB_SIZEOF_SIZE_T > 4
1073 spec
.mod_long
= TRUE
;
1074 spec
.mod_extra_long
= TRUE
;
1075 #endif /* GLIB_SIZEOF_SIZE_T > 4 */
1078 #if GLIB_SIZEOF_PTRDIFF_T > 4
1079 spec
.mod_long
= TRUE
;
1080 spec
.mod_extra_long
= TRUE
;
1081 #endif /* GLIB_SIZEOF_PTRDIFF_T > 4 */
1084 #if GLIB_SIZEOF_INTMAX_T > 4
1085 spec
.mod_long
= TRUE
;
1086 spec
.mod_extra_long
= TRUE
;
1087 #endif /* GLIB_SIZEOF_INTMAX_T > 4 */
1090 /* parse output conversions
1099 /* some C libraries feature long variants for these as well? */
1100 spec
.mod_long
= TRUE
;
1107 conv_len
+= 1; /* sign */
1114 spec
.possible_sign
= TRUE
;
1116 if (spec
.mod_long
&& honour_longs
)
1118 if (spec
.mod_extra_long
)
1120 if (spec
.mod_extra_long
)
1122 #ifdef G_HAVE_GINT64
1123 (void) va_arg (args
, gint64
);
1124 #else /* !G_HAVE_GINT64 */
1125 (void) va_arg (args
, long);
1126 #endif /* !G_HAVE_GINT64 */
1128 else if (spec
.mod_long
)
1129 (void) va_arg (args
, long);
1131 (void) va_arg (args
, int);
1143 spec
.possible_sign
= TRUE
;
1144 /* n . dddddddddddddddddddddddd E +- eeee */
1145 conv_len
+= 1 + 1 + MAX (24, spec
.precision
) + 1 + 1 + 4;
1146 if (may_warn
&& spec
.mod_extra_long
)
1147 g_warning (G_GNUC_PRETTY_FUNCTION
1148 "(): unable to handle long double, collecting double only");
1149 #ifdef HAVE_LONG_DOUBLE
1150 #error need to implement special handling for long double
1152 u_double
.v_double
= va_arg (args
, double);
1153 /* %f can expand up to all significant digits before '.' (308) */
1155 u_double
.mpn
.biased_exponent
> 0 && u_double
.mpn
.biased_exponent
< 2047)
1157 gint exp
= u_double
.mpn
.biased_exponent
;
1159 exp
-= G_IEEE754_DOUBLE_BIAS
;
1160 exp
= exp
* G_LOG_2_BASE_10
+ 1;
1163 /* some printf() implementations require extra padding for rounding */
1165 /* we can't really handle locale specific grouping here */
1166 if (spec
.locale_grouping
)
1170 spec
.mod_long
= TRUE
;
1173 conv_len
+= spec
.mod_long
? MB_LEN_MAX
: 1;
1174 (void) va_arg (args
, int);
1177 spec
.mod_long
= TRUE
;
1180 v_string
= va_arg (args
, char*);
1182 conv_len
+= 8; /* hold "(null)" */
1183 else if (spec
.seen_precision
)
1184 conv_len
+= spec
.precision
;
1186 conv_len
+= strlen (v_string
);
1191 g_warning (G_GNUC_PRETTY_FUNCTION
1192 "(): unable to handle wide char strings");
1193 len
+= 1024; /* try adding some safety padding */
1196 case 'P': /* do we actually need this? */
1199 spec
.alternate_format
= TRUE
;
1206 (void) va_arg (args
, void*);
1209 /* there's not much we can do to be clever */
1210 v_string
= g_strerror (errno
);
1211 v_uint
= v_string
? strlen (v_string
) : 0;
1212 conv_len
+= MAX (256, v_uint
);
1215 /* handle invalid cases
1218 /* no conversion specification, bad bad */
1219 conv_len
+= format
- spec_start
;
1223 g_warning (G_GNUC_PRETTY_FUNCTION
1224 "(): unable to handle `%c' while parsing format",
1228 conv_done
|= conv_len
> 0;
1231 /* handle width specifications */
1232 conv_len
= MAX (conv_len
, MAX (spec
.precision
, spec
.min_width
));
1234 conv_len
+= spec
.alternate_format
? 2 : 0;
1235 conv_len
+= (spec
.add_space
|| spec
.add_sign
|| spec
.possible_sign
);
1238 } /* else (c == '%') */
1239 } /* while (*format) */
1245 g_printf_string_upper_bound (const gchar
*format
,
1248 return printf_string_upper_bound (format
, TRUE
, args
);
1252 g_messages_init (void)
1254 g_messages_lock
= g_mutex_new();
1255 g_log_depth
= g_private_new(NULL
);