completly new implementation for printf string upper bounds calculation.

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).
This commit is contained in:
Tim Janik
1999-10-12 12:08:13 +00:00
committed by Tim Janik
parent acbe34e51a
commit 30a1e1addb
16 changed files with 1209 additions and 362 deletions

View File

@@ -794,143 +794,6 @@ extern const char * strsignal(int);
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)
{