+Tue Oct 12 12:16:12 1999 Tim Janik <timj@gtk.org>
+
+ * gmessages.c (g_printf_string_upper_bound): completly new implementation
+ for printf string upper bounds calculation.
+ we handle all glibc 2.1 format specifiers now, except for positional
+ parameters (%nn$...) and wide char strings, plus some obscure upper
+ case variants of the standard conversions. this fixes a lot of
+ bugs in the old code, i.e.
+ - NULL format strings
+ - floats with exponents >+24
+ - %G
+ - precision specifications in general
+ - negative field widths
+ - %p for SIZEOF_VOID_P > 4 platforms
+ we now issue warnigns in places where the old code would have
+ caused buffer overruns anyways. warnings are suppressed when invoked
+ from glogv(), to avoid infinite recursions if someone passes a log
+ message that comes with really obscure format specifications.
+
+Tue Oct 12 11:49:00 1999 Tim Janik <timj@gtk.org>
+
+ * gstrfuncs.c: nuked old g_printf_string_upper_bound() version.
+
+Tue Oct 12 03:34:40 1999 Tim Janik <timj@gtk.org>
+
+ * glib.h: added GFloatIEEE754 and GDoubleIEEE754 unions to access sign,
+ mantissa and exponent of IEEE floats and doubles (required by the new
+ version of g_printf_string_upper_bound). the unions are endian specific,
+ we handle G_LITTLE_ENDIAN and G_BIG_ENDIAN as of currently. ieee floats
+ and doubles are supported (used for storage) by at least intel, ppc and
+ sparc, reference:
+ http://twister.ou.edu/workshop.docs/common-tools/numerical_comp_guide/ncg_math.doc.html
+
+Mon Oct 11 18:01:49 1999 Tim Janik <timj@gtk.org>
+
+ * configure.in: added additional checks to figure sizes of size_t,
+ ptrdiff_t and intmax_t (required by g_printf_string_upper_bound).
+
Wed Oct 6 12:44:23 PDT 1999 Manish Singh <yosh@gimp.org>
* configure.in: blah. use G_WITH_CYGWIN instead of G_HAVE_CYGWIN
+Tue Oct 12 12:16:12 1999 Tim Janik <timj@gtk.org>
+
+ * gmessages.c (g_printf_string_upper_bound): completly new implementation
+ for printf string upper bounds calculation.
+ we handle all glibc 2.1 format specifiers now, except for positional
+ parameters (%nn$...) and wide char strings, plus some obscure upper
+ case variants of the standard conversions. this fixes a lot of
+ bugs in the old code, i.e.
+ - NULL format strings
+ - floats with exponents >+24
+ - %G
+ - precision specifications in general
+ - negative field widths
+ - %p for SIZEOF_VOID_P > 4 platforms
+ we now issue warnigns in places where the old code would have
+ caused buffer overruns anyways. warnings are suppressed when invoked
+ from glogv(), to avoid infinite recursions if someone passes a log
+ message that comes with really obscure format specifications.
+
+Tue Oct 12 11:49:00 1999 Tim Janik <timj@gtk.org>
+
+ * gstrfuncs.c: nuked old g_printf_string_upper_bound() version.
+
+Tue Oct 12 03:34:40 1999 Tim Janik <timj@gtk.org>
+
+ * glib.h: added GFloatIEEE754 and GDoubleIEEE754 unions to access sign,
+ mantissa and exponent of IEEE floats and doubles (required by the new
+ version of g_printf_string_upper_bound). the unions are endian specific,
+ we handle G_LITTLE_ENDIAN and G_BIG_ENDIAN as of currently. ieee floats
+ and doubles are supported (used for storage) by at least intel, ppc and
+ sparc, reference:
+ http://twister.ou.edu/workshop.docs/common-tools/numerical_comp_guide/ncg_math.doc.html
+
+Mon Oct 11 18:01:49 1999 Tim Janik <timj@gtk.org>
+
+ * configure.in: added additional checks to figure sizes of size_t,
+ ptrdiff_t and intmax_t (required by g_printf_string_upper_bound).
+
Wed Oct 6 12:44:23 PDT 1999 Manish Singh <yosh@gimp.org>
* configure.in: blah. use G_WITH_CYGWIN instead of G_HAVE_CYGWIN
+Tue Oct 12 12:16:12 1999 Tim Janik <timj@gtk.org>
+
+ * gmessages.c (g_printf_string_upper_bound): completly new implementation
+ for printf string upper bounds calculation.
+ we handle all glibc 2.1 format specifiers now, except for positional
+ parameters (%nn$...) and wide char strings, plus some obscure upper
+ case variants of the standard conversions. this fixes a lot of
+ bugs in the old code, i.e.
+ - NULL format strings
+ - floats with exponents >+24
+ - %G
+ - precision specifications in general
+ - negative field widths
+ - %p for SIZEOF_VOID_P > 4 platforms
+ we now issue warnigns in places where the old code would have
+ caused buffer overruns anyways. warnings are suppressed when invoked
+ from glogv(), to avoid infinite recursions if someone passes a log
+ message that comes with really obscure format specifications.
+
+Tue Oct 12 11:49:00 1999 Tim Janik <timj@gtk.org>
+
+ * gstrfuncs.c: nuked old g_printf_string_upper_bound() version.
+
+Tue Oct 12 03:34:40 1999 Tim Janik <timj@gtk.org>
+
+ * glib.h: added GFloatIEEE754 and GDoubleIEEE754 unions to access sign,
+ mantissa and exponent of IEEE floats and doubles (required by the new
+ version of g_printf_string_upper_bound). the unions are endian specific,
+ we handle G_LITTLE_ENDIAN and G_BIG_ENDIAN as of currently. ieee floats
+ and doubles are supported (used for storage) by at least intel, ppc and
+ sparc, reference:
+ http://twister.ou.edu/workshop.docs/common-tools/numerical_comp_guide/ncg_math.doc.html
+
+Mon Oct 11 18:01:49 1999 Tim Janik <timj@gtk.org>
+
+ * configure.in: added additional checks to figure sizes of size_t,
+ ptrdiff_t and intmax_t (required by g_printf_string_upper_bound).
+
Wed Oct 6 12:44:23 PDT 1999 Manish Singh <yosh@gimp.org>
* configure.in: blah. use G_WITH_CYGWIN instead of G_HAVE_CYGWIN
+Tue Oct 12 12:16:12 1999 Tim Janik <timj@gtk.org>
+
+ * gmessages.c (g_printf_string_upper_bound): completly new implementation
+ for printf string upper bounds calculation.
+ we handle all glibc 2.1 format specifiers now, except for positional
+ parameters (%nn$...) and wide char strings, plus some obscure upper
+ case variants of the standard conversions. this fixes a lot of
+ bugs in the old code, i.e.
+ - NULL format strings
+ - floats with exponents >+24
+ - %G
+ - precision specifications in general
+ - negative field widths
+ - %p for SIZEOF_VOID_P > 4 platforms
+ we now issue warnigns in places where the old code would have
+ caused buffer overruns anyways. warnings are suppressed when invoked
+ from glogv(), to avoid infinite recursions if someone passes a log
+ message that comes with really obscure format specifications.
+
+Tue Oct 12 11:49:00 1999 Tim Janik <timj@gtk.org>
+
+ * gstrfuncs.c: nuked old g_printf_string_upper_bound() version.
+
+Tue Oct 12 03:34:40 1999 Tim Janik <timj@gtk.org>
+
+ * glib.h: added GFloatIEEE754 and GDoubleIEEE754 unions to access sign,
+ mantissa and exponent of IEEE floats and doubles (required by the new
+ version of g_printf_string_upper_bound). the unions are endian specific,
+ we handle G_LITTLE_ENDIAN and G_BIG_ENDIAN as of currently. ieee floats
+ and doubles are supported (used for storage) by at least intel, ppc and
+ sparc, reference:
+ http://twister.ou.edu/workshop.docs/common-tools/numerical_comp_guide/ncg_math.doc.html
+
+Mon Oct 11 18:01:49 1999 Tim Janik <timj@gtk.org>
+
+ * configure.in: added additional checks to figure sizes of size_t,
+ ptrdiff_t and intmax_t (required by g_printf_string_upper_bound).
+
Wed Oct 6 12:44:23 PDT 1999 Manish Singh <yosh@gimp.org>
* configure.in: blah. use G_WITH_CYGWIN instead of G_HAVE_CYGWIN
+Tue Oct 12 12:16:12 1999 Tim Janik <timj@gtk.org>
+
+ * gmessages.c (g_printf_string_upper_bound): completly new implementation
+ for printf string upper bounds calculation.
+ we handle all glibc 2.1 format specifiers now, except for positional
+ parameters (%nn$...) and wide char strings, plus some obscure upper
+ case variants of the standard conversions. this fixes a lot of
+ bugs in the old code, i.e.
+ - NULL format strings
+ - floats with exponents >+24
+ - %G
+ - precision specifications in general
+ - negative field widths
+ - %p for SIZEOF_VOID_P > 4 platforms
+ we now issue warnigns in places where the old code would have
+ caused buffer overruns anyways. warnings are suppressed when invoked
+ from glogv(), to avoid infinite recursions if someone passes a log
+ message that comes with really obscure format specifications.
+
+Tue Oct 12 11:49:00 1999 Tim Janik <timj@gtk.org>
+
+ * gstrfuncs.c: nuked old g_printf_string_upper_bound() version.
+
+Tue Oct 12 03:34:40 1999 Tim Janik <timj@gtk.org>
+
+ * glib.h: added GFloatIEEE754 and GDoubleIEEE754 unions to access sign,
+ mantissa and exponent of IEEE floats and doubles (required by the new
+ version of g_printf_string_upper_bound). the unions are endian specific,
+ we handle G_LITTLE_ENDIAN and G_BIG_ENDIAN as of currently. ieee floats
+ and doubles are supported (used for storage) by at least intel, ppc and
+ sparc, reference:
+ http://twister.ou.edu/workshop.docs/common-tools/numerical_comp_guide/ncg_math.doc.html
+
+Mon Oct 11 18:01:49 1999 Tim Janik <timj@gtk.org>
+
+ * configure.in: added additional checks to figure sizes of size_t,
+ ptrdiff_t and intmax_t (required by g_printf_string_upper_bound).
+
Wed Oct 6 12:44:23 PDT 1999 Manish Singh <yosh@gimp.org>
* configure.in: blah. use G_WITH_CYGWIN instead of G_HAVE_CYGWIN
+Tue Oct 12 12:16:12 1999 Tim Janik <timj@gtk.org>
+
+ * gmessages.c (g_printf_string_upper_bound): completly new implementation
+ for printf string upper bounds calculation.
+ we handle all glibc 2.1 format specifiers now, except for positional
+ parameters (%nn$...) and wide char strings, plus some obscure upper
+ case variants of the standard conversions. this fixes a lot of
+ bugs in the old code, i.e.
+ - NULL format strings
+ - floats with exponents >+24
+ - %G
+ - precision specifications in general
+ - negative field widths
+ - %p for SIZEOF_VOID_P > 4 platforms
+ we now issue warnigns in places where the old code would have
+ caused buffer overruns anyways. warnings are suppressed when invoked
+ from glogv(), to avoid infinite recursions if someone passes a log
+ message that comes with really obscure format specifications.
+
+Tue Oct 12 11:49:00 1999 Tim Janik <timj@gtk.org>
+
+ * gstrfuncs.c: nuked old g_printf_string_upper_bound() version.
+
+Tue Oct 12 03:34:40 1999 Tim Janik <timj@gtk.org>
+
+ * glib.h: added GFloatIEEE754 and GDoubleIEEE754 unions to access sign,
+ mantissa and exponent of IEEE floats and doubles (required by the new
+ version of g_printf_string_upper_bound). the unions are endian specific,
+ we handle G_LITTLE_ENDIAN and G_BIG_ENDIAN as of currently. ieee floats
+ and doubles are supported (used for storage) by at least intel, ppc and
+ sparc, reference:
+ http://twister.ou.edu/workshop.docs/common-tools/numerical_comp_guide/ncg_math.doc.html
+
+Mon Oct 11 18:01:49 1999 Tim Janik <timj@gtk.org>
+
+ * configure.in: added additional checks to figure sizes of size_t,
+ ptrdiff_t and intmax_t (required by g_printf_string_upper_bound).
+
Wed Oct 6 12:44:23 PDT 1999 Manish Singh <yosh@gimp.org>
* configure.in: blah. use G_WITH_CYGWIN instead of G_HAVE_CYGWIN
+Tue Oct 12 12:16:12 1999 Tim Janik <timj@gtk.org>
+
+ * gmessages.c (g_printf_string_upper_bound): completly new implementation
+ for printf string upper bounds calculation.
+ we handle all glibc 2.1 format specifiers now, except for positional
+ parameters (%nn$...) and wide char strings, plus some obscure upper
+ case variants of the standard conversions. this fixes a lot of
+ bugs in the old code, i.e.
+ - NULL format strings
+ - floats with exponents >+24
+ - %G
+ - precision specifications in general
+ - negative field widths
+ - %p for SIZEOF_VOID_P > 4 platforms
+ we now issue warnigns in places where the old code would have
+ caused buffer overruns anyways. warnings are suppressed when invoked
+ from glogv(), to avoid infinite recursions if someone passes a log
+ message that comes with really obscure format specifications.
+
+Tue Oct 12 11:49:00 1999 Tim Janik <timj@gtk.org>
+
+ * gstrfuncs.c: nuked old g_printf_string_upper_bound() version.
+
+Tue Oct 12 03:34:40 1999 Tim Janik <timj@gtk.org>
+
+ * glib.h: added GFloatIEEE754 and GDoubleIEEE754 unions to access sign,
+ mantissa and exponent of IEEE floats and doubles (required by the new
+ version of g_printf_string_upper_bound). the unions are endian specific,
+ we handle G_LITTLE_ENDIAN and G_BIG_ENDIAN as of currently. ieee floats
+ and doubles are supported (used for storage) by at least intel, ppc and
+ sparc, reference:
+ http://twister.ou.edu/workshop.docs/common-tools/numerical_comp_guide/ncg_math.doc.html
+
+Mon Oct 11 18:01:49 1999 Tim Janik <timj@gtk.org>
+
+ * configure.in: added additional checks to figure sizes of size_t,
+ ptrdiff_t and intmax_t (required by g_printf_string_upper_bound).
+
Wed Oct 6 12:44:23 PDT 1999 Manish Singh <yosh@gimp.org>
* configure.in: blah. use G_WITH_CYGWIN instead of G_HAVE_CYGWIN
+Tue Oct 12 12:16:12 1999 Tim Janik <timj@gtk.org>
+
+ * gmessages.c (g_printf_string_upper_bound): completly new implementation
+ for printf string upper bounds calculation.
+ we handle all glibc 2.1 format specifiers now, except for positional
+ parameters (%nn$...) and wide char strings, plus some obscure upper
+ case variants of the standard conversions. this fixes a lot of
+ bugs in the old code, i.e.
+ - NULL format strings
+ - floats with exponents >+24
+ - %G
+ - precision specifications in general
+ - negative field widths
+ - %p for SIZEOF_VOID_P > 4 platforms
+ we now issue warnigns in places where the old code would have
+ caused buffer overruns anyways. warnings are suppressed when invoked
+ from glogv(), to avoid infinite recursions if someone passes a log
+ message that comes with really obscure format specifications.
+
+Tue Oct 12 11:49:00 1999 Tim Janik <timj@gtk.org>
+
+ * gstrfuncs.c: nuked old g_printf_string_upper_bound() version.
+
+Tue Oct 12 03:34:40 1999 Tim Janik <timj@gtk.org>
+
+ * glib.h: added GFloatIEEE754 and GDoubleIEEE754 unions to access sign,
+ mantissa and exponent of IEEE floats and doubles (required by the new
+ version of g_printf_string_upper_bound). the unions are endian specific,
+ we handle G_LITTLE_ENDIAN and G_BIG_ENDIAN as of currently. ieee floats
+ and doubles are supported (used for storage) by at least intel, ppc and
+ sparc, reference:
+ http://twister.ou.edu/workshop.docs/common-tools/numerical_comp_guide/ncg_math.doc.html
+
+Mon Oct 11 18:01:49 1999 Tim Janik <timj@gtk.org>
+
+ * configure.in: added additional checks to figure sizes of size_t,
+ ptrdiff_t and intmax_t (required by g_printf_string_upper_bound).
+
Wed Oct 6 12:44:23 PDT 1999 Manish Singh <yosh@gimp.org>
* configure.in: blah. use G_WITH_CYGWIN instead of G_HAVE_CYGWIN
#undef G_THREADS_ENABLED
#undef GLIB_SIZEOF_GMUTEX
+#undef GLIB_SIZEOF_INTMAX_T
#undef GLIB_SIZEOF_PTHREAD_T
+#undef GLIB_SIZEOF_PTRDIFF_T
+#undef GLIB_SIZEOF_SIZE_T
+
#undef GLIB_BYTE_CONTENTS_GMUTEX
#undef GLIB_BYTE_CONTENTS_GRECMUTEX
xyes) AC_DEFINE(G_HAVE_INLINE)
esac
-dnl for bytesex stuff
+# check for bytesex stuff
AC_C_BIGENDIAN
-dnl header file checks
+# xhexk for header files
AC_CHECK_HEADERS(float.h, AC_DEFINE(HAVE_FLOAT_H))
AC_CHECK_HEADERS(limits.h, AC_DEFINE(HAVE_LIMITS_H))
AC_CHECK_HEADERS(pwd.h, AC_DEFINE(HAVE_PWD_H))
AC_CHECK_HEADERS(sys/times.h, AC_DEFINE(HAVE_SYS_TIMES_H))
AC_CHECK_HEADERS(unistd.h, AC_DEFINE(HAVE_UNISTD_H))
AC_CHECK_HEADERS(values.h, AC_DEFINE(HAVE_VALUES_H))
+AC_CHECK_HEADERS(stdint.h, AC_DEFINE(HAVE_VALUES_H))
+
+# check additional type sizes
+size_includes=["
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+"]
+if test "x$ac_cv_header_stdint_h" = "xyes"; then
+ size_includes=["$size_includes
+#include <stdint.h>
+"]
+fi
+if test "x$ac_cv_header_unistd_h" = "xyes"; then
+ size_includes=["$size_includes
+#include <unistd.h>
+"]
+fi
+GLIB_SIZEOF([$size_includes], size_t, size_t)
+GLIB_SIZEOF([$size_includes], ptrdiff_t, ptrdiff_t)
+GLIB_SIZEOF([$size_includes], intmax_t, intmax_t)
# Check for some functions
AC_CHECK_FUNCS(lstat strerror strsignal memmove vsnprintf strcasecmp strncasecmp poll)
typedef struct _GCompletion GCompletion;
typedef struct _GData GData;
typedef struct _GDebugKey GDebugKey;
+typedef union _GDoubleIEEE754 GDoubleIEEE754;
+typedef union _GFloatIEEE754 GFloatIEEE754;
typedef struct _GHashTable GHashTable;
typedef struct _GHook GHook;
typedef struct _GHookList GHookList;
};
+/* IEEE Standard 754 Single Precision Storage Format (gfloat):
+ *
+ * 31 30 23 22 0
+ * +--------+---------------+---------------+
+ * | s 1bit | e[30:23] 8bit | f[22:0] 23bit |
+ * +--------+---------------+---------------+
+ * B0------------------->B1------->B2-->B3-->
+ *
+ * IEEE Standard 754 Double Precision Storage Format (gdouble):
+ *
+ * 63 62 52 51 32 31 0
+ * +--------+----------------+----------------+ +---------------+
+ * | s 1bit | e[62:52] 11bit | f[51:32] 20bit | | f[31:0] 32bit |
+ * +--------+----------------+----------------+ +---------------+
+ * B0--------------->B1---------->B2--->B3----> B4->B5->B6->B7->
+ */
+/* subtract from biased_exponent to form base2 exponent (normal numbers) */
+#define G_IEEE754_FLOAT_BIAS (127)
+#define G_IEEE754_DOUBLE_BIAS (1023)
+/* multiply with base2 exponent to get base10 exponent (nomal numbers) */
+#define G_LOG_2_BASE_10 (0.30102999566398119521)
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
+union _GFloatIEEE754
+{
+ gfloat v_float;
+ struct {
+ guint mantissa : 23;
+ guint biased_exponent : 8;
+ guint sign : 1;
+ } mpn;
+};
+union _GDoubleIEEE754
+{
+ gdouble v_double;
+ struct {
+ guint mantissa_low : 32;
+ guint mantissa_high : 20;
+ guint biased_exponent : 11;
+ guint sign : 1;
+ } mpn;
+};
+#elif G_BYTE_ORDER == G_BIG_ENDIAN
+union _GFloatIEEE754
+{
+ gfloat v_float;
+ struct {
+ guint sign : 1;
+ guint biased_exponent : 8;
+ guint mantissa : 23;
+ } mpn;
+};
+union _GDoubleIEEE754
+{
+ gdouble v_double;
+ struct {
+ guint sign : 1;
+ guint biased_exponent : 11;
+ guint mantissa_high : 20;
+ guint mantissa_low : 32;
+ } mpn;
+};
+#else /* !G_LITTLE_ENDIAN && !G_BIG_ENDIAN */
+#error unknown ENDIAN type
+#endif /* !G_LITTLE_ENDIAN && !G_BIG_ENDIAN */
+
+
/* Doubly linked lists
*/
void g_list_push_allocator (GAllocator *allocator);
typedef struct _GCompletion GCompletion;
typedef struct _GData GData;
typedef struct _GDebugKey GDebugKey;
+typedef union _GDoubleIEEE754 GDoubleIEEE754;
+typedef union _GFloatIEEE754 GFloatIEEE754;
typedef struct _GHashTable GHashTable;
typedef struct _GHook GHook;
typedef struct _GHookList GHookList;
};
+/* IEEE Standard 754 Single Precision Storage Format (gfloat):
+ *
+ * 31 30 23 22 0
+ * +--------+---------------+---------------+
+ * | s 1bit | e[30:23] 8bit | f[22:0] 23bit |
+ * +--------+---------------+---------------+
+ * B0------------------->B1------->B2-->B3-->
+ *
+ * IEEE Standard 754 Double Precision Storage Format (gdouble):
+ *
+ * 63 62 52 51 32 31 0
+ * +--------+----------------+----------------+ +---------------+
+ * | s 1bit | e[62:52] 11bit | f[51:32] 20bit | | f[31:0] 32bit |
+ * +--------+----------------+----------------+ +---------------+
+ * B0--------------->B1---------->B2--->B3----> B4->B5->B6->B7->
+ */
+/* subtract from biased_exponent to form base2 exponent (normal numbers) */
+#define G_IEEE754_FLOAT_BIAS (127)
+#define G_IEEE754_DOUBLE_BIAS (1023)
+/* multiply with base2 exponent to get base10 exponent (nomal numbers) */
+#define G_LOG_2_BASE_10 (0.30102999566398119521)
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
+union _GFloatIEEE754
+{
+ gfloat v_float;
+ struct {
+ guint mantissa : 23;
+ guint biased_exponent : 8;
+ guint sign : 1;
+ } mpn;
+};
+union _GDoubleIEEE754
+{
+ gdouble v_double;
+ struct {
+ guint mantissa_low : 32;
+ guint mantissa_high : 20;
+ guint biased_exponent : 11;
+ guint sign : 1;
+ } mpn;
+};
+#elif G_BYTE_ORDER == G_BIG_ENDIAN
+union _GFloatIEEE754
+{
+ gfloat v_float;
+ struct {
+ guint sign : 1;
+ guint biased_exponent : 8;
+ guint mantissa : 23;
+ } mpn;
+};
+union _GDoubleIEEE754
+{
+ gdouble v_double;
+ struct {
+ guint sign : 1;
+ guint biased_exponent : 11;
+ guint mantissa_high : 20;
+ guint mantissa_low : 32;
+ } mpn;
+};
+#else /* !G_LITTLE_ENDIAN && !G_BIG_ENDIAN */
+#error unknown ENDIAN type
+#endif /* !G_LITTLE_ENDIAN && !G_BIG_ENDIAN */
+
+
/* Doubly linked lists
*/
void g_list_push_allocator (GAllocator *allocator);
#include <unistd.h>
#endif
#include <signal.h>
+#include <locale.h>
+#include <errno.h>
-#ifdef G_OS_WIN32
-# define STRICT
-# include <windows.h>
-# include <process.h> /* For _getpid() */
-
-/* Just use stdio. If we're out of memory, we're hosed anyway. */
-#undef write
-
-static inline int
-write (FILE *fd,
- const char *buf,
- int len)
-{
- fwrite (buf, len, 1, fd);
-
- return len;
-}
-
-static void
-ensure_stdout_valid (void)
-{
- HANDLE handle;
-
- handle = GetStdHandle (STD_OUTPUT_HANDLE);
-
- if (handle == INVALID_HANDLE_VALUE)
- {
- AllocConsole ();
- freopen ("CONOUT$", "w", stdout);
- }
-}
-#else
-#define ensure_stdout_valid() /* Define as empty */
-#endif
-
/* --- structures --- */
typedef struct _GLogDomain GLogDomain;
};
+/* --- prototypes --- */
+static inline guint printf_string_upper_bound (const gchar *format,
+ gboolean may_warn,
+ va_list args);
+
+
/* --- variables --- */
static GMutex* g_messages_lock = NULL;
/* --- functions --- */
+#ifdef G_OS_WIN32
+# define STRICT
+# include <windows.h>
+# include <process.h> /* For _getpid() */
+/* Just use stdio. If we're out of memory, we're hosed anyway. */
+#undef write
+static inline int
+write (FILE *fd,
+ const char *buf,
+ int len)
+{
+ fwrite (buf, len, 1, fd);
+
+ return len;
+}
+static void
+ensure_stdout_valid (void)
+{
+ HANDLE handle;
+
+ handle = GetStdHandle (STD_OUTPUT_HANDLE);
+
+ if (handle == INVALID_HANDLE_VALUE)
+ {
+ AllocConsole ();
+ freopen ("CONOUT$", "w", stdout);
+ }
+}
+#else
+#define ensure_stdout_valid() /* Define as empty */
+#endif
+
static inline GLogDomain*
-g_log_find_domain (const gchar *log_domain)
+g_log_find_domain (const gchar *log_domain)
{
register GLogDomain *domain;
}
void
-g_log_remove_handler (const gchar *log_domain,
- guint handler_id)
+g_log_remove_handler (const gchar *log_domain,
+ guint handler_id)
{
register GLogDomain *domain;
}
void
-g_logv (const gchar *log_domain,
- GLogLevelFlags log_level,
- const gchar *format,
- va_list args1)
+g_logv (const gchar *log_domain,
+ GLogLevelFlags log_level,
+ const gchar *format,
+ va_list args1)
{
va_list args2;
gchar buffer[1025];
* recursively.
*/
G_VA_COPY (args2, args1);
- if (g_printf_string_upper_bound (format, args1) < 1024)
+ if (printf_string_upper_bound (format, FALSE, args1) < 1024)
vsprintf (buffer, format, args2);
else
{
return old_message_func;
}
+#ifndef MB_LEN_MAX
+# define MB_LEN_MAX 8
+#endif
+
+typedef struct
+{
+ guint min_width;
+ guint precision;
+ gboolean alternate_format, zero_padding, adjust_left, locale_grouping;
+ gboolean add_space, add_sign, possible_sign, seen_precision;
+ gboolean mod_half, mod_long, mod_extra_long;
+} PrintfArgSpec;
+
+static inline guint
+printf_string_upper_bound (const gchar *format,
+ gboolean may_warn,
+ va_list args)
+{
+ static const gboolean honour_longs = SIZEOF_LONG > 4 || SIZEOF_VOID_P > 4;
+ guint len = 1;
+
+ if (!format)
+ return len;
+
+ while (*format)
+ {
+ register gchar c = *format++;
+
+ if (c != '%')
+ len += 1;
+ else /* (c == '%') */
+ {
+ PrintfArgSpec spec = { 0, };
+ gboolean seen_l = FALSE, conv_done = FALSE;
+ guint conv_len = 0;
+ const gchar *spec_start = format;
+
+ do
+ {
+ c = *format++;
+ switch (c)
+ {
+ GDoubleIEEE754 u_double;
+ guint v_uint;
+ gint v_int;
+ gchar *v_string;
+
+ /* beware of positional parameters
+ */
+ case '$':
+ if (may_warn)
+ g_warning (G_GNUC_PRETTY_FUNCTION
+ "(): unable to handle positional parameters (%%n$)");
+ len += 1024; /* try adding some safety padding */
+ break;
+
+ /* parse flags
+ */
+ case '#':
+ spec.alternate_format = TRUE;
+ break;
+ case '0':
+ spec.zero_padding = TRUE;
+ break;
+ case '-':
+ spec.adjust_left = TRUE;
+ break;
+ case ' ':
+ spec.add_space = TRUE;
+ break;
+ case '+':
+ spec.add_sign = TRUE;
+ break;
+ case '\'':
+ spec.locale_grouping = TRUE;
+ break;
+
+ /* parse output size specifications
+ */
+ case '.':
+ spec.seen_precision = TRUE;
+ break;
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ v_uint = c - '0';
+ c = *format;
+ while (c >= '0' && c <= '9')
+ {
+ format++;
+ v_uint = v_uint * 10 + c - '0';
+ c = *format;
+ }
+ if (spec.seen_precision)
+ spec.precision = MAX (spec.precision, v_uint);
+ else
+ spec.min_width = MAX (spec.min_width, v_uint);
+ break;
+ case '*':
+ v_int = va_arg (args, int);
+ if (spec.seen_precision)
+ {
+ /* forget about negative precision */
+ if (v_int >= 0)
+ spec.precision = MAX (spec.precision, v_int);
+ }
+ else
+ {
+ if (v_int < 0)
+ {
+ v_int = - v_int;
+ spec.adjust_left = TRUE;
+ }
+ spec.min_width = MAX (spec.min_width, v_int);
+ }
+ break;
+
+ /* parse type modifiers
+ */
+ case 'h':
+ spec.mod_half = TRUE;
+ break;
+ case 'l':
+ if (!seen_l)
+ {
+ spec.mod_long = TRUE;
+ seen_l = TRUE;
+ break;
+ }
+ /* else, fall through */
+ case 'L':
+ case 'q':
+ spec.mod_long = TRUE;
+ spec.mod_extra_long = TRUE;
+ break;
+ case 'z':
+ case 'Z':
+#if GLIB_SIZEOF_SIZE_T > 4
+ spec.mod_long = TRUE;
+ spec.mod_extra_long = TRUE;
+#endif /* GLIB_SIZEOF_SIZE_T > 4 */
+ break;
+ case 't':
+#if GLIB_SIZEOF_PTRDIFF_T > 4
+ spec.mod_long = TRUE;
+ spec.mod_extra_long = TRUE;
+#endif /* GLIB_SIZEOF_PTRDIFF_T > 4 */
+ break;
+ case 'j':
+#if GLIB_SIZEOF_INTMAX_T > 4
+ spec.mod_long = TRUE;
+ spec.mod_extra_long = TRUE;
+#endif /* GLIB_SIZEOF_INTMAX_T > 4 */
+ break;
+
+ /* parse output conversions
+ */
+ case '%':
+ conv_len += 1;
+ break;
+ case 'O':
+ case 'D':
+ case 'I':
+ case 'U':
+ /* some C libraries feature long variants for these as well? */
+ spec.mod_long = TRUE;
+ /* fall through */
+ case 'o':
+ conv_len += 2;
+ /* fall through */
+ case 'd':
+ case 'i':
+ conv_len += 1; /* sign */
+ /* fall through */
+ case 'u':
+ conv_len += 4;
+ /* fall through */
+ case 'x':
+ case 'X':
+ spec.possible_sign = TRUE;
+ conv_len += 10;
+ if (spec.mod_long && honour_longs)
+ conv_len *= 2;
+ if (spec.mod_extra_long)
+ conv_len *= 2;
+ if (spec.mod_extra_long)
+ {
+#ifdef G_HAVE_GINT64
+ (void) va_arg (args, gint64);
+#else /* !G_HAVE_GINT64 */
+ (void) va_arg (args, long);
+#endif /* !G_HAVE_GINT64 */
+ }
+ else if (spec.mod_long)
+ (void) va_arg (args, long);
+ else
+ (void) va_arg (args, int);
+ break;
+ case 'A':
+ case 'a':
+ /* 0x */
+ conv_len += 2;
+ /* fall through */
+ case 'g':
+ case 'G':
+ case 'e':
+ case 'E':
+ case 'f':
+ spec.possible_sign = TRUE;
+ /* n . dddddddddddddddddddddddd E +- eeee */
+ conv_len += 1 + 1 + MAX (24, spec.precision) + 1 + 1 + 4;
+ if (may_warn && spec.mod_extra_long)
+ g_warning (G_GNUC_PRETTY_FUNCTION
+ "(): unable to handle long double, collecting double only");
+#ifdef HAVE_LONG_DOUBLE
+#error need to implement special handling for long double
+#endif
+ u_double.v_double = va_arg (args, double);
+ /* %f can expand up to all significant digits before '.' (308) */
+ if (c == 'f' &&
+ u_double.mpn.biased_exponent > 0 && u_double.mpn.biased_exponent < 2047)
+ {
+ gint exp = u_double.mpn.biased_exponent;
+
+ exp -= G_IEEE754_DOUBLE_BIAS;
+ exp = exp * G_LOG_2_BASE_10 + 1;
+ conv_len += exp;
+ }
+ /* some printf() implementations require extra padding for rounding */
+ conv_len += 2;
+ /* we can't really handle locale specific grouping here */
+ if (spec.locale_grouping)
+ conv_len *= 2;
+ break;
+ case 'C':
+ spec.mod_long = TRUE;
+ /* fall through */
+ case 'c':
+ conv_len += spec.mod_long ? MB_LEN_MAX : 1;
+ (void) va_arg (args, int);
+ break;
+ case 'S':
+ spec.mod_long = TRUE;
+ /* fall through */
+ case 's':
+ v_string = va_arg (args, char*);
+ if (!v_string)
+ conv_len += 8; /* hold "(null)" */
+ else if (spec.seen_precision)
+ conv_len += spec.precision;
+ else
+ conv_len += strlen (v_string);
+ conv_done = TRUE;
+ if (spec.mod_long)
+ {
+ if (may_warn)
+ g_warning (G_GNUC_PRETTY_FUNCTION
+ "(): unable to handle wide char strings");
+ len += 1024; /* try adding some safety padding */
+ }
+ break;
+ case 'P': /* do we actually need this? */
+ /* fall through */
+ case 'p':
+ spec.alternate_format = TRUE;
+ conv_len += 10;
+ if (honour_longs)
+ conv_len *= 2;
+ /* fall through */
+ case 'n':
+ conv_done = TRUE;
+ (void) va_arg (args, void*);
+ break;
+ case 'm':
+ /* there's not much we can do to be clever */
+ v_string = g_strerror (errno);
+ v_uint = v_string ? strlen (v_string) : 0;
+ conv_len += MAX (256, v_uint);
+ break;
+
+ /* handle invalid cases
+ */
+ case '\000':
+ /* no conversion specification, bad bad */
+ conv_len += format - spec_start;
+ break;
+ default:
+ if (may_warn)
+ g_warning (G_GNUC_PRETTY_FUNCTION
+ "(): unable to handle `%c' while parsing format",
+ c);
+ break;
+ }
+ conv_done |= conv_len > 0;
+ }
+ while (!conv_done);
+ /* handle width specifications */
+ conv_len = MAX (conv_len, MAX (spec.precision, spec.min_width));
+ /* handle flags */
+ conv_len += spec.alternate_format ? 2 : 0;
+ conv_len += (spec.add_space || spec.add_sign || spec.possible_sign);
+ /* finally done */
+ len += conv_len;
+ } /* else (c == '%') */
+ } /* while (*format) */
+
+ return len;
+}
+
+guint
+g_printf_string_upper_bound (const gchar *format,
+ va_list args)
+{
+ return printf_string_upper_bound (format, TRUE, args);
+}
+
void
g_messages_init (void)
{
return msg;
}
-guint
-g_printf_string_upper_bound (const gchar* format,
- va_list args)
-{
- guint len = 1;
-
- while (*format)
- {
- gboolean long_int = FALSE;
- gboolean extra_long = FALSE;
- gchar c;
-
- c = *format++;
-
- if (c == '%')
- {
- gboolean done = FALSE;
-
- while (*format && !done)
- {
- switch (*format++)
- {
- gchar *string_arg;
-
- case '*':
- len += va_arg (args, int);
- break;
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- /* add specified format length, since it might exceed the
- * size we assume it to have.
- */
- format -= 1;
- len += strtol (format, (char**) &format, 10);
- break;
- case 'h':
- /* ignore short int flag, since all args have at least the
- * same size as an int
- */
- break;
- case 'l':
- if (long_int)
- extra_long = TRUE; /* linux specific */
- else
- long_int = TRUE;
- break;
- case 'q':
- case 'L':
- long_int = TRUE;
- extra_long = TRUE;
- break;
- case 's':
- string_arg = va_arg (args, char *);
- if (string_arg)
- len += strlen (string_arg);
- else
- {
- /* add enough padding to hold "(null)" identifier */
- len += 16;
- }
- done = TRUE;
- break;
- case 'd':
- case 'i':
- case 'o':
- case 'u':
- case 'x':
- case 'X':
-#ifdef G_HAVE_GINT64
- if (extra_long)
- (void) va_arg (args, gint64);
- else
-#endif /* G_HAVE_GINT64 */
- {
- if (long_int)
- (void) va_arg (args, long);
- else
- (void) va_arg (args, int);
- }
- len += extra_long ? 64 : 32;
- done = TRUE;
- break;
- case 'D':
- case 'O':
- case 'U':
- (void) va_arg (args, long);
- len += 32;
- done = TRUE;
- break;
- case 'e':
- case 'E':
- case 'f':
- case 'g':
-#ifdef HAVE_LONG_DOUBLE
- if (extra_long)
- (void) va_arg (args, long double);
- else
-#endif /* HAVE_LONG_DOUBLE */
- (void) va_arg (args, double);
- len += extra_long ? 64 : 32;
- done = TRUE;
- break;
- case 'c':
- (void) va_arg (args, int);
- len += 1;
- done = TRUE;
- break;
- case 'p':
- case 'n':
- (void) va_arg (args, void*);
- len += 32;
- done = TRUE;
- break;
- case '%':
- len += 1;
- done = TRUE;
- break;
- default:
- /* ignore unknow/invalid flags */
- break;
- }
- }
- }
- else
- len += 1;
- }
-
- return len;
-}
-
void
g_strdown (gchar *string)
{
#include <unistd.h>
#endif
#include <signal.h>
+#include <locale.h>
+#include <errno.h>
-#ifdef G_OS_WIN32
-# define STRICT
-# include <windows.h>
-# include <process.h> /* For _getpid() */
-
-/* Just use stdio. If we're out of memory, we're hosed anyway. */
-#undef write
-
-static inline int
-write (FILE *fd,
- const char *buf,
- int len)
-{
- fwrite (buf, len, 1, fd);
-
- return len;
-}
-
-static void
-ensure_stdout_valid (void)
-{
- HANDLE handle;
-
- handle = GetStdHandle (STD_OUTPUT_HANDLE);
-
- if (handle == INVALID_HANDLE_VALUE)
- {
- AllocConsole ();
- freopen ("CONOUT$", "w", stdout);
- }
-}
-#else
-#define ensure_stdout_valid() /* Define as empty */
-#endif
-
/* --- structures --- */
typedef struct _GLogDomain GLogDomain;
};
+/* --- prototypes --- */
+static inline guint printf_string_upper_bound (const gchar *format,
+ gboolean may_warn,
+ va_list args);
+
+
/* --- variables --- */
static GMutex* g_messages_lock = NULL;
/* --- functions --- */
+#ifdef G_OS_WIN32
+# define STRICT
+# include <windows.h>
+# include <process.h> /* For _getpid() */
+/* Just use stdio. If we're out of memory, we're hosed anyway. */
+#undef write
+static inline int
+write (FILE *fd,
+ const char *buf,
+ int len)
+{
+ fwrite (buf, len, 1, fd);
+
+ return len;
+}
+static void
+ensure_stdout_valid (void)
+{
+ HANDLE handle;
+
+ handle = GetStdHandle (STD_OUTPUT_HANDLE);
+
+ if (handle == INVALID_HANDLE_VALUE)
+ {
+ AllocConsole ();
+ freopen ("CONOUT$", "w", stdout);
+ }
+}
+#else
+#define ensure_stdout_valid() /* Define as empty */
+#endif
+
static inline GLogDomain*
-g_log_find_domain (const gchar *log_domain)
+g_log_find_domain (const gchar *log_domain)
{
register GLogDomain *domain;
}
void
-g_log_remove_handler (const gchar *log_domain,
- guint handler_id)
+g_log_remove_handler (const gchar *log_domain,
+ guint handler_id)
{
register GLogDomain *domain;
}
void
-g_logv (const gchar *log_domain,
- GLogLevelFlags log_level,
- const gchar *format,
- va_list args1)
+g_logv (const gchar *log_domain,
+ GLogLevelFlags log_level,
+ const gchar *format,
+ va_list args1)
{
va_list args2;
gchar buffer[1025];
* recursively.
*/
G_VA_COPY (args2, args1);
- if (g_printf_string_upper_bound (format, args1) < 1024)
+ if (printf_string_upper_bound (format, FALSE, args1) < 1024)
vsprintf (buffer, format, args2);
else
{
return old_message_func;
}
+#ifndef MB_LEN_MAX
+# define MB_LEN_MAX 8
+#endif
+
+typedef struct
+{
+ guint min_width;
+ guint precision;
+ gboolean alternate_format, zero_padding, adjust_left, locale_grouping;
+ gboolean add_space, add_sign, possible_sign, seen_precision;
+ gboolean mod_half, mod_long, mod_extra_long;
+} PrintfArgSpec;
+
+static inline guint
+printf_string_upper_bound (const gchar *format,
+ gboolean may_warn,
+ va_list args)
+{
+ static const gboolean honour_longs = SIZEOF_LONG > 4 || SIZEOF_VOID_P > 4;
+ guint len = 1;
+
+ if (!format)
+ return len;
+
+ while (*format)
+ {
+ register gchar c = *format++;
+
+ if (c != '%')
+ len += 1;
+ else /* (c == '%') */
+ {
+ PrintfArgSpec spec = { 0, };
+ gboolean seen_l = FALSE, conv_done = FALSE;
+ guint conv_len = 0;
+ const gchar *spec_start = format;
+
+ do
+ {
+ c = *format++;
+ switch (c)
+ {
+ GDoubleIEEE754 u_double;
+ guint v_uint;
+ gint v_int;
+ gchar *v_string;
+
+ /* beware of positional parameters
+ */
+ case '$':
+ if (may_warn)
+ g_warning (G_GNUC_PRETTY_FUNCTION
+ "(): unable to handle positional parameters (%%n$)");
+ len += 1024; /* try adding some safety padding */
+ break;
+
+ /* parse flags
+ */
+ case '#':
+ spec.alternate_format = TRUE;
+ break;
+ case '0':
+ spec.zero_padding = TRUE;
+ break;
+ case '-':
+ spec.adjust_left = TRUE;
+ break;
+ case ' ':
+ spec.add_space = TRUE;
+ break;
+ case '+':
+ spec.add_sign = TRUE;
+ break;
+ case '\'':
+ spec.locale_grouping = TRUE;
+ break;
+
+ /* parse output size specifications
+ */
+ case '.':
+ spec.seen_precision = TRUE;
+ break;
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ v_uint = c - '0';
+ c = *format;
+ while (c >= '0' && c <= '9')
+ {
+ format++;
+ v_uint = v_uint * 10 + c - '0';
+ c = *format;
+ }
+ if (spec.seen_precision)
+ spec.precision = MAX (spec.precision, v_uint);
+ else
+ spec.min_width = MAX (spec.min_width, v_uint);
+ break;
+ case '*':
+ v_int = va_arg (args, int);
+ if (spec.seen_precision)
+ {
+ /* forget about negative precision */
+ if (v_int >= 0)
+ spec.precision = MAX (spec.precision, v_int);
+ }
+ else
+ {
+ if (v_int < 0)
+ {
+ v_int = - v_int;
+ spec.adjust_left = TRUE;
+ }
+ spec.min_width = MAX (spec.min_width, v_int);
+ }
+ break;
+
+ /* parse type modifiers
+ */
+ case 'h':
+ spec.mod_half = TRUE;
+ break;
+ case 'l':
+ if (!seen_l)
+ {
+ spec.mod_long = TRUE;
+ seen_l = TRUE;
+ break;
+ }
+ /* else, fall through */
+ case 'L':
+ case 'q':
+ spec.mod_long = TRUE;
+ spec.mod_extra_long = TRUE;
+ break;
+ case 'z':
+ case 'Z':
+#if GLIB_SIZEOF_SIZE_T > 4
+ spec.mod_long = TRUE;
+ spec.mod_extra_long = TRUE;
+#endif /* GLIB_SIZEOF_SIZE_T > 4 */
+ break;
+ case 't':
+#if GLIB_SIZEOF_PTRDIFF_T > 4
+ spec.mod_long = TRUE;
+ spec.mod_extra_long = TRUE;
+#endif /* GLIB_SIZEOF_PTRDIFF_T > 4 */
+ break;
+ case 'j':
+#if GLIB_SIZEOF_INTMAX_T > 4
+ spec.mod_long = TRUE;
+ spec.mod_extra_long = TRUE;
+#endif /* GLIB_SIZEOF_INTMAX_T > 4 */
+ break;
+
+ /* parse output conversions
+ */
+ case '%':
+ conv_len += 1;
+ break;
+ case 'O':
+ case 'D':
+ case 'I':
+ case 'U':
+ /* some C libraries feature long variants for these as well? */
+ spec.mod_long = TRUE;
+ /* fall through */
+ case 'o':
+ conv_len += 2;
+ /* fall through */
+ case 'd':
+ case 'i':
+ conv_len += 1; /* sign */
+ /* fall through */
+ case 'u':
+ conv_len += 4;
+ /* fall through */
+ case 'x':
+ case 'X':
+ spec.possible_sign = TRUE;
+ conv_len += 10;
+ if (spec.mod_long && honour_longs)
+ conv_len *= 2;
+ if (spec.mod_extra_long)
+ conv_len *= 2;
+ if (spec.mod_extra_long)
+ {
+#ifdef G_HAVE_GINT64
+ (void) va_arg (args, gint64);
+#else /* !G_HAVE_GINT64 */
+ (void) va_arg (args, long);
+#endif /* !G_HAVE_GINT64 */
+ }
+ else if (spec.mod_long)
+ (void) va_arg (args, long);
+ else
+ (void) va_arg (args, int);
+ break;
+ case 'A':
+ case 'a':
+ /* 0x */
+ conv_len += 2;
+ /* fall through */
+ case 'g':
+ case 'G':
+ case 'e':
+ case 'E':
+ case 'f':
+ spec.possible_sign = TRUE;
+ /* n . dddddddddddddddddddddddd E +- eeee */
+ conv_len += 1 + 1 + MAX (24, spec.precision) + 1 + 1 + 4;
+ if (may_warn && spec.mod_extra_long)
+ g_warning (G_GNUC_PRETTY_FUNCTION
+ "(): unable to handle long double, collecting double only");
+#ifdef HAVE_LONG_DOUBLE
+#error need to implement special handling for long double
+#endif
+ u_double.v_double = va_arg (args, double);
+ /* %f can expand up to all significant digits before '.' (308) */
+ if (c == 'f' &&
+ u_double.mpn.biased_exponent > 0 && u_double.mpn.biased_exponent < 2047)
+ {
+ gint exp = u_double.mpn.biased_exponent;
+
+ exp -= G_IEEE754_DOUBLE_BIAS;
+ exp = exp * G_LOG_2_BASE_10 + 1;
+ conv_len += exp;
+ }
+ /* some printf() implementations require extra padding for rounding */
+ conv_len += 2;
+ /* we can't really handle locale specific grouping here */
+ if (spec.locale_grouping)
+ conv_len *= 2;
+ break;
+ case 'C':
+ spec.mod_long = TRUE;
+ /* fall through */
+ case 'c':
+ conv_len += spec.mod_long ? MB_LEN_MAX : 1;
+ (void) va_arg (args, int);
+ break;
+ case 'S':
+ spec.mod_long = TRUE;
+ /* fall through */
+ case 's':
+ v_string = va_arg (args, char*);
+ if (!v_string)
+ conv_len += 8; /* hold "(null)" */
+ else if (spec.seen_precision)
+ conv_len += spec.precision;
+ else
+ conv_len += strlen (v_string);
+ conv_done = TRUE;
+ if (spec.mod_long)
+ {
+ if (may_warn)
+ g_warning (G_GNUC_PRETTY_FUNCTION
+ "(): unable to handle wide char strings");
+ len += 1024; /* try adding some safety padding */
+ }
+ break;
+ case 'P': /* do we actually need this? */
+ /* fall through */
+ case 'p':
+ spec.alternate_format = TRUE;
+ conv_len += 10;
+ if (honour_longs)
+ conv_len *= 2;
+ /* fall through */
+ case 'n':
+ conv_done = TRUE;
+ (void) va_arg (args, void*);
+ break;
+ case 'm':
+ /* there's not much we can do to be clever */
+ v_string = g_strerror (errno);
+ v_uint = v_string ? strlen (v_string) : 0;
+ conv_len += MAX (256, v_uint);
+ break;
+
+ /* handle invalid cases
+ */
+ case '\000':
+ /* no conversion specification, bad bad */
+ conv_len += format - spec_start;
+ break;
+ default:
+ if (may_warn)
+ g_warning (G_GNUC_PRETTY_FUNCTION
+ "(): unable to handle `%c' while parsing format",
+ c);
+ break;
+ }
+ conv_done |= conv_len > 0;
+ }
+ while (!conv_done);
+ /* handle width specifications */
+ conv_len = MAX (conv_len, MAX (spec.precision, spec.min_width));
+ /* handle flags */
+ conv_len += spec.alternate_format ? 2 : 0;
+ conv_len += (spec.add_space || spec.add_sign || spec.possible_sign);
+ /* finally done */
+ len += conv_len;
+ } /* else (c == '%') */
+ } /* while (*format) */
+
+ return len;
+}
+
+guint
+g_printf_string_upper_bound (const gchar *format,
+ va_list args)
+{
+ return printf_string_upper_bound (format, TRUE, args);
+}
+
void
g_messages_init (void)
{
return msg;
}
-guint
-g_printf_string_upper_bound (const gchar* format,
- va_list args)
-{
- guint len = 1;
-
- while (*format)
- {
- gboolean long_int = FALSE;
- gboolean extra_long = FALSE;
- gchar c;
-
- c = *format++;
-
- if (c == '%')
- {
- gboolean done = FALSE;
-
- while (*format && !done)
- {
- switch (*format++)
- {
- gchar *string_arg;
-
- case '*':
- len += va_arg (args, int);
- break;
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- /* add specified format length, since it might exceed the
- * size we assume it to have.
- */
- format -= 1;
- len += strtol (format, (char**) &format, 10);
- break;
- case 'h':
- /* ignore short int flag, since all args have at least the
- * same size as an int
- */
- break;
- case 'l':
- if (long_int)
- extra_long = TRUE; /* linux specific */
- else
- long_int = TRUE;
- break;
- case 'q':
- case 'L':
- long_int = TRUE;
- extra_long = TRUE;
- break;
- case 's':
- string_arg = va_arg (args, char *);
- if (string_arg)
- len += strlen (string_arg);
- else
- {
- /* add enough padding to hold "(null)" identifier */
- len += 16;
- }
- done = TRUE;
- break;
- case 'd':
- case 'i':
- case 'o':
- case 'u':
- case 'x':
- case 'X':
-#ifdef G_HAVE_GINT64
- if (extra_long)
- (void) va_arg (args, gint64);
- else
-#endif /* G_HAVE_GINT64 */
- {
- if (long_int)
- (void) va_arg (args, long);
- else
- (void) va_arg (args, int);
- }
- len += extra_long ? 64 : 32;
- done = TRUE;
- break;
- case 'D':
- case 'O':
- case 'U':
- (void) va_arg (args, long);
- len += 32;
- done = TRUE;
- break;
- case 'e':
- case 'E':
- case 'f':
- case 'g':
-#ifdef HAVE_LONG_DOUBLE
- if (extra_long)
- (void) va_arg (args, long double);
- else
-#endif /* HAVE_LONG_DOUBLE */
- (void) va_arg (args, double);
- len += extra_long ? 64 : 32;
- done = TRUE;
- break;
- case 'c':
- (void) va_arg (args, int);
- len += 1;
- done = TRUE;
- break;
- case 'p':
- case 'n':
- (void) va_arg (args, void*);
- len += 32;
- done = TRUE;
- break;
- case '%':
- len += 1;
- done = TRUE;
- break;
- default:
- /* ignore unknow/invalid flags */
- break;
- }
- }
- }
- else
- len += 1;
- }
-
- return len;
-}
-
void
g_strdown (gchar *string)
{