removed this function which was not publically exported in glib.h. to

Mon Aug 24 02:08:56 1998  Tim Janik  <timj@gtk.org>

        * glib.h:
        * gstring.c:
        * gstrfuncs.c:
        (g_vsprintf): removed this function which was not publically
        exported in glib.h. to export it, it should have been named
        differently in the first place, since its semantics differ from
        vsprintf(). apart from that, it was a possible cause for
        problems since it worked on a previously allocated memory area and
        was used in a lot places of glib. exporting it would have been a
        guararant for problems with threaded programs.
        (g_printf_string_upper_bound): exported this function to return
        a string size, guarranteed to be big enough to hold the fully
        expanded format+args string. added 'q', 'L' and 'll' flag handling.
        in fact, the newly allocated area is in most cases much bigger than
        required.
        (g_strdup_vprintf()): new function returning a newly allocated string
        containing the contents of *format and associated args (size is
        calculated with g_printf_string_upper_bound()).
        (g_strdup_printf): new function which wraps g_strdup_vprintf().

        * configure.in: check for va_copy() or __va_copy() alternatively.
        check whether va_lists can be copyied by value.

        * glib.h: provide a definition for G_VA_COPY.

        * glib.h:
        * gmessages.c:
        (g_logv):
        (g_vsnprintf):
        pass va_lists by value, not by reference, since this causes problems
        on platforms that implement va_list as as arrays. internaly, use
        G_VA_COPY (new_arg, org_arg); va_end (new_arg); to produce a second
        va_list variable, if multiple passes are required. changed all
        callers.

        * glib.h:
        * gerror.h:
        renamed g_debug() to g_on_error_query(), cleaned up a bit.
        renamed g_stack_trace() to g_on_error_stack_trace() since both
        functions cluttered different namespaces.
        there is an appropriate comment in glib.h now that explains the
        unix and gdb specific dependencies of both functions.
        removed g_attach_process().
        g_on_error_stack_trace() should probably be handled with caution,
        i've seem several different linux versions (2.0.x) become unstable
        after invokation of this function.
This commit is contained in:
Tim Janik 1998-08-24 05:26:53 +00:00 committed by Tim Janik
parent 0b870ec357
commit b420fa8418
29 changed files with 1377 additions and 860 deletions

View File

@ -1,3 +1,52 @@
Mon Aug 24 02:08:56 1998 Tim Janik <timj@gtk.org>
* glib.h:
* gstring.c:
* gstrfuncs.c:
(g_vsprintf): removed this function which was not publically
exported in glib.h. to export it, it should have been named
differently in the first place, since its semantics differ from
vsprintf(). apart from that, it was a possible cause for
problems since it worked on a previously allocated memory area and
was used in a lot places of glib. exporting it would have been a
guararant for problems with threaded programs.
(g_printf_string_upper_bound): exported this function to return
a string size, guarranteed to be big enough to hold the fully
expanded format+args string. added 'q', 'L' and 'll' flag handling.
in fact, the newly allocated area is in most cases much bigger than
required.
(g_strdup_vprintf()): new function returning a newly allocated string
containing the contents of *format and associated args (size is
calculated with g_printf_string_upper_bound()).
(g_strdup_printf): new function which wraps g_strdup_vprintf().
* configure.in: check for va_copy() or __va_copy() alternatively.
check whether va_lists can be copyied by value.
* glib.h: provide a definition for G_VA_COPY.
* glib.h:
* gmessages.c:
(g_logv):
(g_vsnprintf):
pass va_lists by value, not by reference, since this causes problems
on platforms that implement va_list as as arrays. internaly, use
G_VA_COPY (new_arg, org_arg); va_end (new_arg); to produce a second
va_list variable, if multiple passes are required. changed all
callers.
* glib.h:
* gerror.h:
renamed g_debug() to g_on_error_query(), cleaned up a bit.
renamed g_stack_trace() to g_on_error_stack_trace() since both
functions cluttered different namespaces.
there is an appropriate comment in glib.h now that explains the
unix and gdb specific dependencies of both functions.
removed g_attach_process().
g_on_error_stack_trace() should probably be handled with caution,
i've seem several different linux versions (2.0.x) become unstable
after invokation of this function.
1998-08-18: Elliot Lee <sopwith@redhat.com>
. In gmem.c, add the ability to exclude memory chunks from the

View File

@ -1,3 +1,52 @@
Mon Aug 24 02:08:56 1998 Tim Janik <timj@gtk.org>
* glib.h:
* gstring.c:
* gstrfuncs.c:
(g_vsprintf): removed this function which was not publically
exported in glib.h. to export it, it should have been named
differently in the first place, since its semantics differ from
vsprintf(). apart from that, it was a possible cause for
problems since it worked on a previously allocated memory area and
was used in a lot places of glib. exporting it would have been a
guararant for problems with threaded programs.
(g_printf_string_upper_bound): exported this function to return
a string size, guarranteed to be big enough to hold the fully
expanded format+args string. added 'q', 'L' and 'll' flag handling.
in fact, the newly allocated area is in most cases much bigger than
required.
(g_strdup_vprintf()): new function returning a newly allocated string
containing the contents of *format and associated args (size is
calculated with g_printf_string_upper_bound()).
(g_strdup_printf): new function which wraps g_strdup_vprintf().
* configure.in: check for va_copy() or __va_copy() alternatively.
check whether va_lists can be copyied by value.
* glib.h: provide a definition for G_VA_COPY.
* glib.h:
* gmessages.c:
(g_logv):
(g_vsnprintf):
pass va_lists by value, not by reference, since this causes problems
on platforms that implement va_list as as arrays. internaly, use
G_VA_COPY (new_arg, org_arg); va_end (new_arg); to produce a second
va_list variable, if multiple passes are required. changed all
callers.
* glib.h:
* gerror.h:
renamed g_debug() to g_on_error_query(), cleaned up a bit.
renamed g_stack_trace() to g_on_error_stack_trace() since both
functions cluttered different namespaces.
there is an appropriate comment in glib.h now that explains the
unix and gdb specific dependencies of both functions.
removed g_attach_process().
g_on_error_stack_trace() should probably be handled with caution,
i've seem several different linux versions (2.0.x) become unstable
after invokation of this function.
1998-08-18: Elliot Lee <sopwith@redhat.com>
. In gmem.c, add the ability to exclude memory chunks from the

View File

@ -1,3 +1,52 @@
Mon Aug 24 02:08:56 1998 Tim Janik <timj@gtk.org>
* glib.h:
* gstring.c:
* gstrfuncs.c:
(g_vsprintf): removed this function which was not publically
exported in glib.h. to export it, it should have been named
differently in the first place, since its semantics differ from
vsprintf(). apart from that, it was a possible cause for
problems since it worked on a previously allocated memory area and
was used in a lot places of glib. exporting it would have been a
guararant for problems with threaded programs.
(g_printf_string_upper_bound): exported this function to return
a string size, guarranteed to be big enough to hold the fully
expanded format+args string. added 'q', 'L' and 'll' flag handling.
in fact, the newly allocated area is in most cases much bigger than
required.
(g_strdup_vprintf()): new function returning a newly allocated string
containing the contents of *format and associated args (size is
calculated with g_printf_string_upper_bound()).
(g_strdup_printf): new function which wraps g_strdup_vprintf().
* configure.in: check for va_copy() or __va_copy() alternatively.
check whether va_lists can be copyied by value.
* glib.h: provide a definition for G_VA_COPY.
* glib.h:
* gmessages.c:
(g_logv):
(g_vsnprintf):
pass va_lists by value, not by reference, since this causes problems
on platforms that implement va_list as as arrays. internaly, use
G_VA_COPY (new_arg, org_arg); va_end (new_arg); to produce a second
va_list variable, if multiple passes are required. changed all
callers.
* glib.h:
* gerror.h:
renamed g_debug() to g_on_error_query(), cleaned up a bit.
renamed g_stack_trace() to g_on_error_stack_trace() since both
functions cluttered different namespaces.
there is an appropriate comment in glib.h now that explains the
unix and gdb specific dependencies of both functions.
removed g_attach_process().
g_on_error_stack_trace() should probably be handled with caution,
i've seem several different linux versions (2.0.x) become unstable
after invokation of this function.
1998-08-18: Elliot Lee <sopwith@redhat.com>
. In gmem.c, add the ability to exclude memory chunks from the

View File

@ -1,3 +1,52 @@
Mon Aug 24 02:08:56 1998 Tim Janik <timj@gtk.org>
* glib.h:
* gstring.c:
* gstrfuncs.c:
(g_vsprintf): removed this function which was not publically
exported in glib.h. to export it, it should have been named
differently in the first place, since its semantics differ from
vsprintf(). apart from that, it was a possible cause for
problems since it worked on a previously allocated memory area and
was used in a lot places of glib. exporting it would have been a
guararant for problems with threaded programs.
(g_printf_string_upper_bound): exported this function to return
a string size, guarranteed to be big enough to hold the fully
expanded format+args string. added 'q', 'L' and 'll' flag handling.
in fact, the newly allocated area is in most cases much bigger than
required.
(g_strdup_vprintf()): new function returning a newly allocated string
containing the contents of *format and associated args (size is
calculated with g_printf_string_upper_bound()).
(g_strdup_printf): new function which wraps g_strdup_vprintf().
* configure.in: check for va_copy() or __va_copy() alternatively.
check whether va_lists can be copyied by value.
* glib.h: provide a definition for G_VA_COPY.
* glib.h:
* gmessages.c:
(g_logv):
(g_vsnprintf):
pass va_lists by value, not by reference, since this causes problems
on platforms that implement va_list as as arrays. internaly, use
G_VA_COPY (new_arg, org_arg); va_end (new_arg); to produce a second
va_list variable, if multiple passes are required. changed all
callers.
* glib.h:
* gerror.h:
renamed g_debug() to g_on_error_query(), cleaned up a bit.
renamed g_stack_trace() to g_on_error_stack_trace() since both
functions cluttered different namespaces.
there is an appropriate comment in glib.h now that explains the
unix and gdb specific dependencies of both functions.
removed g_attach_process().
g_on_error_stack_trace() should probably be handled with caution,
i've seem several different linux versions (2.0.x) become unstable
after invokation of this function.
1998-08-18: Elliot Lee <sopwith@redhat.com>
. In gmem.c, add the ability to exclude memory chunks from the

View File

@ -1,3 +1,52 @@
Mon Aug 24 02:08:56 1998 Tim Janik <timj@gtk.org>
* glib.h:
* gstring.c:
* gstrfuncs.c:
(g_vsprintf): removed this function which was not publically
exported in glib.h. to export it, it should have been named
differently in the first place, since its semantics differ from
vsprintf(). apart from that, it was a possible cause for
problems since it worked on a previously allocated memory area and
was used in a lot places of glib. exporting it would have been a
guararant for problems with threaded programs.
(g_printf_string_upper_bound): exported this function to return
a string size, guarranteed to be big enough to hold the fully
expanded format+args string. added 'q', 'L' and 'll' flag handling.
in fact, the newly allocated area is in most cases much bigger than
required.
(g_strdup_vprintf()): new function returning a newly allocated string
containing the contents of *format and associated args (size is
calculated with g_printf_string_upper_bound()).
(g_strdup_printf): new function which wraps g_strdup_vprintf().
* configure.in: check for va_copy() or __va_copy() alternatively.
check whether va_lists can be copyied by value.
* glib.h: provide a definition for G_VA_COPY.
* glib.h:
* gmessages.c:
(g_logv):
(g_vsnprintf):
pass va_lists by value, not by reference, since this causes problems
on platforms that implement va_list as as arrays. internaly, use
G_VA_COPY (new_arg, org_arg); va_end (new_arg); to produce a second
va_list variable, if multiple passes are required. changed all
callers.
* glib.h:
* gerror.h:
renamed g_debug() to g_on_error_query(), cleaned up a bit.
renamed g_stack_trace() to g_on_error_stack_trace() since both
functions cluttered different namespaces.
there is an appropriate comment in glib.h now that explains the
unix and gdb specific dependencies of both functions.
removed g_attach_process().
g_on_error_stack_trace() should probably be handled with caution,
i've seem several different linux versions (2.0.x) become unstable
after invokation of this function.
1998-08-18: Elliot Lee <sopwith@redhat.com>
. In gmem.c, add the ability to exclude memory chunks from the

View File

@ -1,3 +1,52 @@
Mon Aug 24 02:08:56 1998 Tim Janik <timj@gtk.org>
* glib.h:
* gstring.c:
* gstrfuncs.c:
(g_vsprintf): removed this function which was not publically
exported in glib.h. to export it, it should have been named
differently in the first place, since its semantics differ from
vsprintf(). apart from that, it was a possible cause for
problems since it worked on a previously allocated memory area and
was used in a lot places of glib. exporting it would have been a
guararant for problems with threaded programs.
(g_printf_string_upper_bound): exported this function to return
a string size, guarranteed to be big enough to hold the fully
expanded format+args string. added 'q', 'L' and 'll' flag handling.
in fact, the newly allocated area is in most cases much bigger than
required.
(g_strdup_vprintf()): new function returning a newly allocated string
containing the contents of *format and associated args (size is
calculated with g_printf_string_upper_bound()).
(g_strdup_printf): new function which wraps g_strdup_vprintf().
* configure.in: check for va_copy() or __va_copy() alternatively.
check whether va_lists can be copyied by value.
* glib.h: provide a definition for G_VA_COPY.
* glib.h:
* gmessages.c:
(g_logv):
(g_vsnprintf):
pass va_lists by value, not by reference, since this causes problems
on platforms that implement va_list as as arrays. internaly, use
G_VA_COPY (new_arg, org_arg); va_end (new_arg); to produce a second
va_list variable, if multiple passes are required. changed all
callers.
* glib.h:
* gerror.h:
renamed g_debug() to g_on_error_query(), cleaned up a bit.
renamed g_stack_trace() to g_on_error_stack_trace() since both
functions cluttered different namespaces.
there is an appropriate comment in glib.h now that explains the
unix and gdb specific dependencies of both functions.
removed g_attach_process().
g_on_error_stack_trace() should probably be handled with caution,
i've seem several different linux versions (2.0.x) become unstable
after invokation of this function.
1998-08-18: Elliot Lee <sopwith@redhat.com>
. In gmem.c, add the ability to exclude memory chunks from the

View File

@ -1,3 +1,52 @@
Mon Aug 24 02:08:56 1998 Tim Janik <timj@gtk.org>
* glib.h:
* gstring.c:
* gstrfuncs.c:
(g_vsprintf): removed this function which was not publically
exported in glib.h. to export it, it should have been named
differently in the first place, since its semantics differ from
vsprintf(). apart from that, it was a possible cause for
problems since it worked on a previously allocated memory area and
was used in a lot places of glib. exporting it would have been a
guararant for problems with threaded programs.
(g_printf_string_upper_bound): exported this function to return
a string size, guarranteed to be big enough to hold the fully
expanded format+args string. added 'q', 'L' and 'll' flag handling.
in fact, the newly allocated area is in most cases much bigger than
required.
(g_strdup_vprintf()): new function returning a newly allocated string
containing the contents of *format and associated args (size is
calculated with g_printf_string_upper_bound()).
(g_strdup_printf): new function which wraps g_strdup_vprintf().
* configure.in: check for va_copy() or __va_copy() alternatively.
check whether va_lists can be copyied by value.
* glib.h: provide a definition for G_VA_COPY.
* glib.h:
* gmessages.c:
(g_logv):
(g_vsnprintf):
pass va_lists by value, not by reference, since this causes problems
on platforms that implement va_list as as arrays. internaly, use
G_VA_COPY (new_arg, org_arg); va_end (new_arg); to produce a second
va_list variable, if multiple passes are required. changed all
callers.
* glib.h:
* gerror.h:
renamed g_debug() to g_on_error_query(), cleaned up a bit.
renamed g_stack_trace() to g_on_error_stack_trace() since both
functions cluttered different namespaces.
there is an appropriate comment in glib.h now that explains the
unix and gdb specific dependencies of both functions.
removed g_attach_process().
g_on_error_stack_trace() should probably be handled with caution,
i've seem several different linux versions (2.0.x) become unstable
after invokation of this function.
1998-08-18: Elliot Lee <sopwith@redhat.com>
. In gmem.c, add the ability to exclude memory chunks from the

View File

@ -1,3 +1,52 @@
Mon Aug 24 02:08:56 1998 Tim Janik <timj@gtk.org>
* glib.h:
* gstring.c:
* gstrfuncs.c:
(g_vsprintf): removed this function which was not publically
exported in glib.h. to export it, it should have been named
differently in the first place, since its semantics differ from
vsprintf(). apart from that, it was a possible cause for
problems since it worked on a previously allocated memory area and
was used in a lot places of glib. exporting it would have been a
guararant for problems with threaded programs.
(g_printf_string_upper_bound): exported this function to return
a string size, guarranteed to be big enough to hold the fully
expanded format+args string. added 'q', 'L' and 'll' flag handling.
in fact, the newly allocated area is in most cases much bigger than
required.
(g_strdup_vprintf()): new function returning a newly allocated string
containing the contents of *format and associated args (size is
calculated with g_printf_string_upper_bound()).
(g_strdup_printf): new function which wraps g_strdup_vprintf().
* configure.in: check for va_copy() or __va_copy() alternatively.
check whether va_lists can be copyied by value.
* glib.h: provide a definition for G_VA_COPY.
* glib.h:
* gmessages.c:
(g_logv):
(g_vsnprintf):
pass va_lists by value, not by reference, since this causes problems
on platforms that implement va_list as as arrays. internaly, use
G_VA_COPY (new_arg, org_arg); va_end (new_arg); to produce a second
va_list variable, if multiple passes are required. changed all
callers.
* glib.h:
* gerror.h:
renamed g_debug() to g_on_error_query(), cleaned up a bit.
renamed g_stack_trace() to g_on_error_stack_trace() since both
functions cluttered different namespaces.
there is an appropriate comment in glib.h now that explains the
unix and gdb specific dependencies of both functions.
removed g_attach_process().
g_on_error_stack_trace() should probably be handled with caution,
i've seem several different linux versions (2.0.x) become unstable
after invokation of this function.
1998-08-18: Elliot Lee <sopwith@redhat.com>
. In gmem.c, add the ability to exclude memory chunks from the

9
NEWS
View File

@ -2,7 +2,14 @@ Overview of Changes in GLib 1.1.3:
* New library gmodule included which basically wraps dlopen() facilities.
* New g_log() mechanism for logging of messages at different log levels,
associated with certain log domains.
associated with certain log domains (define -DG_LOG_DOMAIN for your module).
* New inline functions for bit masks tests.
* GNode functions now return the newly allocated node.
* New macro G_VA_COPY() to work around va_list copying oddities on some
platforms. the non-static g_vsprintf() function vanished in favour of
a publically exported g_strdup_vprintf().
* New utility functions for string and printf-like format handling .
* Lotsa bug fixes and cleanups as always ;)
Overview of Changes in GLib 1.1.2:

View File

@ -62,6 +62,9 @@
#undef SIZEOF_INT
#undef SIZEOF_VOID_P
#undef G_VA_COPY
#undef G_VA_COPY_AS_ARRAY
#undef GLIB_MAJOR_VERSION
#undef GLIB_MINOR_VERSION
#undef GLIB_MICRO_VERSION

View File

@ -222,6 +222,87 @@ if test $gtk_ok = no; then
fi
AC_MSG_RESULT($gtk_ok)
dnl **********************
dnl *** va_copy checks ***
dnl **********************
dnl we currently check for all three cases, so we get all results in config.log
AC_MSG_CHECKING(for an implementation of va_copy())
AC_CACHE_VAL(glib_cv_va_copy,[
AC_TRY_RUN([
#include <stdarg.h>
void f (int i, ...) {
va_list args1, args2;
va_start (args1, i);
va_copy (args2, args1);
if (va_arg (args2, int) != 42 || va_arg (args1, int) != 42)
exit (1);
va_end (args1); va_end (args2);
}
int main() {
f (0, 42);
return 0;
}],
glib_cv_va_copy=yes
,
glib_cv_va_copy=no
,)
])
AC_MSG_RESULT($glib_cv_va_copy)
AC_MSG_CHECKING(for an implementation of __va_copy())
AC_CACHE_VAL(glib_cv___va_copy,[
AC_TRY_RUN([
#include <stdarg.h>
void f (int i, ...) {
va_list args1, args2;
va_start (args1, i);
__va_copy (args2, args1);
if (va_arg (args2, int) != 42 || va_arg (args1, int) != 42)
exit (1);
va_end (args1); va_end (args2);
}
int main() {
f (0, 42);
return 0;
}],
glib_cv___va_copy=yes
,
glib_cv___va_copy=no
,)
])
AC_MSG_RESULT($glib_cv___va_copy)
AC_MSG_CHECKING(whether va_lists can be copied by value)
AC_CACHE_VAL(glib_cv_va_val_copy,[
AC_TRY_RUN([
#include <stdarg.h>
void f (int i, ...) {
va_list args1, args2;
va_start (args1, i);
args2 = args1;
if (va_arg (args2, int) != 42 || va_arg (args1, int) != 42)
exit (1);
va_end (args1); va_end (args2);
}
int main() {
f (0, 42);
return 0;
}],
glib_cv_va_val_copy=yes
,
glib_cv_va_val_copy=no
,)
])
if test "x$glib_cv_va_copy" = "xyes"; then
AC_DEFINE(G_VA_COPY, va_copy)
else if test "x$glib_cv___va_copy" = "xyes"; then
AC_DEFINE(G_VA_COPY, __va_copy)
fi
fi
if test "x$glib_cv_va_val_copy" = "xno"; then
AC_DEFINE(G_VA_COPY_AS_ARRAY)
fi
AC_MSG_RESULT($glib_cv_va_val_copy)
dnl ***********************
dnl *** g_module checks ***
dnl ***********************

View File

@ -36,9 +36,6 @@
#include <string.h> /* for bzero on BSD systems */
#endif
#define INTERACTIVE 0
#define STACK_TRACE 1
#ifndef NO_FD_SET
# define SELECT_MASK fd_set
@ -54,104 +51,105 @@
#endif
static int do_query (char *prompt);
static void debug (const gchar *progname, int method);
static void stack_trace (char **);
static void stack_trace_sigchld (int);
static void stack_trace (char **args);
static int stack_trace_done;
extern volatile gboolean glib_on_error_halt;
volatile gboolean glib_on_error_halt = TRUE;
void
g_debug (const gchar *progname)
g_on_error_query (const gchar *prg_name)
{
char buf[32];
static const gchar *query1 = "[E]xit, [H]alt";
static const gchar *query2 = ", show [S]tack trace";
static const gchar *query3 = " or [P]roceed";
gchar buf[16];
fprintf (stdout, "[n]othing, [e]xit, [s]tack trace, [a]ttach to process: ");
fflush (stdout);
fgets (buf, 32, stdin);
if (strcmp (buf, "n\n") == 0)
return;
else if (strcmp (buf, "s\n") == 0)
debug (progname, STACK_TRACE);
else if (strcmp (buf, "a\n") == 0)
debug (progname, INTERACTIVE);
if (!prg_name)
prg_name = g_get_prgname ();
retry:
if (prg_name)
fprintf (stdout,
"%s (pid:%u): %s%s%s: ",
prg_name,
(guint) getpid (),
query1,
query2,
query3);
else
exit (0);
}
void
g_attach_process (const gchar *progname,
gboolean query)
{
if (!query || do_query ("attach to process"))
debug (progname, INTERACTIVE);
}
void
g_stack_trace (const gchar *progname,
gboolean query)
{
if (!query || do_query ("print stack trace"))
debug (progname, STACK_TRACE);
}
static int
do_query (char *prompt)
{
char buf[32];
fprintf (stdout, "%s (y/n) ", prompt);
fprintf (stdout,
"(process:%u): %s%s: ",
(guint) getpid (),
query1,
query3);
fflush (stdout);
fgets (buf, 8, stdin);
fgets (buf, 32, stdin);
if ((strcmp (buf, "yes\n") == 0) ||
(strcmp (buf, "y\n") == 0) ||
(strcmp (buf, "YES\n") == 0) ||
(strcmp (buf, "Y\n") == 0))
return TRUE;
return FALSE;
if ((buf[0] == 'E' || buf[0] == 'e')
&& buf[1] == '\n')
_exit (0);
else if ((buf[0] == 'P' || buf[0] == 'p')
&& buf[1] == '\n')
return;
else if (prg_name
&& (buf[0] == 'S' || buf[0] == 's')
&& buf[1] == '\n')
{
g_on_error_stack_trace (prg_name);
goto retry;
}
else if ((buf[0] == 'H' || buf[0] == 'h')
&& buf[1] == '\n')
{
while (glib_on_error_halt)
;
glib_on_error_halt = TRUE;
return;
}
else
goto retry;
}
static void
debug (const char *progname,
int method)
void
g_on_error_stack_trace (const gchar *prg_name)
{
pid_t pid;
char buf[16];
char *args[4] = { "gdb", NULL, NULL, NULL };
volatile int x;
gchar buf[16];
gchar *args[4] = { "gdb", NULL, NULL, NULL };
sprintf (buf, "%d", (int) getpid ());
if (!prg_name)
return;
args[1] = (gchar*) progname;
sprintf (buf, "%u", (guint) getpid ());
args[1] = (gchar*) prg_name;
args[2] = buf;
switch (method)
pid = fork ();
if (pid == 0)
{
case INTERACTIVE:
fprintf (stdout, "pid: %s\n", buf);
break;
case STACK_TRACE:
pid = fork ();
if (pid == 0)
{
stack_trace (args);
_exit (0);
}
else if (pid == (pid_t) -1)
{
perror ("could not fork");
return;
}
break;
stack_trace (args);
_exit (0);
}
x = 1;
while (x)
else if (pid == (pid_t) -1)
{
perror ("unable to fork gdb");
return;
}
while (glib_on_error_halt)
;
glib_on_error_halt = TRUE;
}
static gboolean stack_trace_done = FALSE;
static void
stack_trace_sigchld (int signum)
{
stack_trace_done = TRUE;
}
static void
@ -167,12 +165,12 @@ stack_trace (char **args)
char buffer[256];
char c;
stack_trace_done = 0;
stack_trace_done = FALSE;
signal (SIGCHLD, stack_trace_sigchld);
if ((pipe (in_fd) == -1) || (pipe (out_fd) == -1))
{
perror ("could open pipe");
perror ("unable to open pipe");
_exit (0);
}
@ -189,7 +187,7 @@ stack_trace (char **args)
}
else if (pid == (pid_t) -1)
{
perror ("could not fork");
perror ("unable to fork");
_exit (0);
}
@ -252,9 +250,3 @@ stack_trace (char **args)
close (out_fd[1]);
_exit (0);
}
static void
stack_trace_sigchld (int signum)
{
stack_trace_done = 1;
}

174
gerror.c
View File

@ -36,9 +36,6 @@
#include <string.h> /* for bzero on BSD systems */
#endif
#define INTERACTIVE 0
#define STACK_TRACE 1
#ifndef NO_FD_SET
# define SELECT_MASK fd_set
@ -54,104 +51,105 @@
#endif
static int do_query (char *prompt);
static void debug (const gchar *progname, int method);
static void stack_trace (char **);
static void stack_trace_sigchld (int);
static void stack_trace (char **args);
static int stack_trace_done;
extern volatile gboolean glib_on_error_halt;
volatile gboolean glib_on_error_halt = TRUE;
void
g_debug (const gchar *progname)
g_on_error_query (const gchar *prg_name)
{
char buf[32];
static const gchar *query1 = "[E]xit, [H]alt";
static const gchar *query2 = ", show [S]tack trace";
static const gchar *query3 = " or [P]roceed";
gchar buf[16];
fprintf (stdout, "[n]othing, [e]xit, [s]tack trace, [a]ttach to process: ");
fflush (stdout);
fgets (buf, 32, stdin);
if (strcmp (buf, "n\n") == 0)
return;
else if (strcmp (buf, "s\n") == 0)
debug (progname, STACK_TRACE);
else if (strcmp (buf, "a\n") == 0)
debug (progname, INTERACTIVE);
if (!prg_name)
prg_name = g_get_prgname ();
retry:
if (prg_name)
fprintf (stdout,
"%s (pid:%u): %s%s%s: ",
prg_name,
(guint) getpid (),
query1,
query2,
query3);
else
exit (0);
}
void
g_attach_process (const gchar *progname,
gboolean query)
{
if (!query || do_query ("attach to process"))
debug (progname, INTERACTIVE);
}
void
g_stack_trace (const gchar *progname,
gboolean query)
{
if (!query || do_query ("print stack trace"))
debug (progname, STACK_TRACE);
}
static int
do_query (char *prompt)
{
char buf[32];
fprintf (stdout, "%s (y/n) ", prompt);
fprintf (stdout,
"(process:%u): %s%s: ",
(guint) getpid (),
query1,
query3);
fflush (stdout);
fgets (buf, 8, stdin);
fgets (buf, 32, stdin);
if ((strcmp (buf, "yes\n") == 0) ||
(strcmp (buf, "y\n") == 0) ||
(strcmp (buf, "YES\n") == 0) ||
(strcmp (buf, "Y\n") == 0))
return TRUE;
return FALSE;
if ((buf[0] == 'E' || buf[0] == 'e')
&& buf[1] == '\n')
_exit (0);
else if ((buf[0] == 'P' || buf[0] == 'p')
&& buf[1] == '\n')
return;
else if (prg_name
&& (buf[0] == 'S' || buf[0] == 's')
&& buf[1] == '\n')
{
g_on_error_stack_trace (prg_name);
goto retry;
}
else if ((buf[0] == 'H' || buf[0] == 'h')
&& buf[1] == '\n')
{
while (glib_on_error_halt)
;
glib_on_error_halt = TRUE;
return;
}
else
goto retry;
}
static void
debug (const char *progname,
int method)
void
g_on_error_stack_trace (const gchar *prg_name)
{
pid_t pid;
char buf[16];
char *args[4] = { "gdb", NULL, NULL, NULL };
volatile int x;
gchar buf[16];
gchar *args[4] = { "gdb", NULL, NULL, NULL };
sprintf (buf, "%d", (int) getpid ());
if (!prg_name)
return;
args[1] = (gchar*) progname;
sprintf (buf, "%u", (guint) getpid ());
args[1] = (gchar*) prg_name;
args[2] = buf;
switch (method)
pid = fork ();
if (pid == 0)
{
case INTERACTIVE:
fprintf (stdout, "pid: %s\n", buf);
break;
case STACK_TRACE:
pid = fork ();
if (pid == 0)
{
stack_trace (args);
_exit (0);
}
else if (pid == (pid_t) -1)
{
perror ("could not fork");
return;
}
break;
stack_trace (args);
_exit (0);
}
x = 1;
while (x)
else if (pid == (pid_t) -1)
{
perror ("unable to fork gdb");
return;
}
while (glib_on_error_halt)
;
glib_on_error_halt = TRUE;
}
static gboolean stack_trace_done = FALSE;
static void
stack_trace_sigchld (int signum)
{
stack_trace_done = TRUE;
}
static void
@ -167,12 +165,12 @@ stack_trace (char **args)
char buffer[256];
char c;
stack_trace_done = 0;
stack_trace_done = FALSE;
signal (SIGCHLD, stack_trace_sigchld);
if ((pipe (in_fd) == -1) || (pipe (out_fd) == -1))
{
perror ("could open pipe");
perror ("unable to open pipe");
_exit (0);
}
@ -189,7 +187,7 @@ stack_trace (char **args)
}
else if (pid == (pid_t) -1)
{
perror ("could not fork");
perror ("unable to fork");
_exit (0);
}
@ -252,9 +250,3 @@ stack_trace (char **args)
close (out_fd[1]);
_exit (0);
}
static void
stack_trace_sigchld (int signum)
{
stack_trace_done = 1;
}

69
glib.h
View File

@ -125,6 +125,20 @@
#define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x)))
/* Define G_VA_COPY() to do the right thing for copying va_list variables.
* glibconfig.h may have already defined G_VA_COPY as va_copy or __va_copy.
*/
#if !defined (G_VA_COPY)
# if defined (__GNUC__) && defined (__PPC__) && (defined (_CALL_SYSV) || defined (_WIN32))
# define G_VA_COPY(ap1, ap2) (*(ap1) = *(ap2))
# elif defined (G_VA_COPY_AS_ARRAY)
# define G_VA_COPY(ap1, ap2) g_memmove ((ap1), (ap2), sizeof (va_list))
# else /* va_list is a pointer */
# define G_VA_COPY(ap1, ap2) ((ap1) = (ap2))
# endif /* va_list is a pointer */
#endif /* !G_VA_COPY */
/* Provide simple enum value macro wrappers that ease automated
* enum value stringification code. [abandoned]
*/
@ -926,13 +940,17 @@ GNode* g_node_last_sibling (GNode *node);
((GNode*) (node))->children : NULL)
/* Fatal error handlers
/* Fatal error handlers.
* g_on_error_query() will prompt the user to either
* [E]xit, [H]alt, [P]roceed or show [S]tack trace.
* g_on_error_stack_trace() invokes gdb, which attaches to the current
* process and shows a stack trace.
* These function may cause different actions on non-unix platforms.
* The prg_name arg is required by gdb to find the executable, if it is
* passed as NULL, g_on_error_query() will try g_get_prgname().
*/
void g_attach_process (const gchar *progname,
gboolean query);
void g_debug (const gchar *progname);
void g_stack_trace (const gchar *progname,
gboolean query);
void g_on_error_query (const gchar *prg_name);
void g_on_error_stack_trace (const gchar *prg_name);
/* Logging mechanism
@ -955,8 +973,7 @@ void g_log (const gchar *log_domain,
void g_logv (const gchar *log_domain,
GLogLevelFlags log_level,
const gchar *format,
va_list *args1,
va_list *args2);
va_list args);
GLogLevelFlags g_log_set_fatal_mask (const gchar *log_domain,
GLogLevelFlags fatal_mask);
GLogLevelFlags g_log_set_always_fatal (GLogLevelFlags fatal_mask);
@ -978,28 +995,28 @@ static inline void
g_error (const gchar *format,
...)
{
va_list arg_list1, arg_list2;
va_start (arg_list1, format); va_start (arg_list2, format);
g_logv (G_LOG_DOMAIN, G_LOG_LEVEL_ERROR, format, &arg_list1, &arg_list2);
va_end (arg_list2); va_end (arg_list1);
va_list args;
va_start (args, format);
g_logv (G_LOG_DOMAIN, G_LOG_LEVEL_ERROR, format, args);
va_end (args);
}
static inline void
g_message (const gchar *format,
...)
{
va_list arg_list1, arg_list2;
va_start (arg_list1, format); va_start (arg_list2, format);
g_logv (G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, format, &arg_list1, &arg_list2);
va_end (arg_list2); va_end (arg_list1);
va_list args;
va_start (args, format);
g_logv (G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, format, args);
va_end (args);
}
static inline void
g_warning (const gchar *format,
...)
{
va_list arg_list1, arg_list2;
va_start (arg_list1, format); va_start (arg_list2, format);
g_logv (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, format, &arg_list1, &arg_list2);
va_end (arg_list2); va_end (arg_list1);
va_list args;
va_start (args, format);
g_logv (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, format, args);
va_end (args);
}
#endif /* !__GNUC__ */
@ -1106,6 +1123,10 @@ void g_strdelimit (gchar *string,
const gchar *delimiters,
gchar new_delimiter);
gchar* g_strdup (const gchar *str);
gchar* g_strdup_printf (const gchar *format,
...) G_GNUC_PRINTF (1, 2);
gchar* g_strdup_vprintf (const gchar *format,
va_list args);
gchar* g_strndup (const gchar *str,
gulong n);
gchar* g_strconcat (const gchar *string1,
@ -1120,6 +1141,11 @@ void g_strdown (gchar *string);
void g_strup (gchar *string);
void g_strreverse (gchar *string);
/* calculate a string size, guarranteed to fit format + args.
*/
guint g_printf_string_upper_bound (const gchar* format,
va_list args);
/* Retrive static string info
*/
@ -1143,8 +1169,7 @@ gint g_snprintf (gchar *string,
gint g_vsnprintf (gchar *string,
gulong n,
gchar const *format,
va_list *args1,
va_list *args2);
va_list args);
gchar* g_basename (const gchar *file_name);
/* strings are newly allocated with g_malloc() */

View File

@ -36,9 +36,6 @@
#include <string.h> /* for bzero on BSD systems */
#endif
#define INTERACTIVE 0
#define STACK_TRACE 1
#ifndef NO_FD_SET
# define SELECT_MASK fd_set
@ -54,104 +51,105 @@
#endif
static int do_query (char *prompt);
static void debug (const gchar *progname, int method);
static void stack_trace (char **);
static void stack_trace_sigchld (int);
static void stack_trace (char **args);
static int stack_trace_done;
extern volatile gboolean glib_on_error_halt;
volatile gboolean glib_on_error_halt = TRUE;
void
g_debug (const gchar *progname)
g_on_error_query (const gchar *prg_name)
{
char buf[32];
static const gchar *query1 = "[E]xit, [H]alt";
static const gchar *query2 = ", show [S]tack trace";
static const gchar *query3 = " or [P]roceed";
gchar buf[16];
fprintf (stdout, "[n]othing, [e]xit, [s]tack trace, [a]ttach to process: ");
fflush (stdout);
fgets (buf, 32, stdin);
if (strcmp (buf, "n\n") == 0)
return;
else if (strcmp (buf, "s\n") == 0)
debug (progname, STACK_TRACE);
else if (strcmp (buf, "a\n") == 0)
debug (progname, INTERACTIVE);
if (!prg_name)
prg_name = g_get_prgname ();
retry:
if (prg_name)
fprintf (stdout,
"%s (pid:%u): %s%s%s: ",
prg_name,
(guint) getpid (),
query1,
query2,
query3);
else
exit (0);
}
void
g_attach_process (const gchar *progname,
gboolean query)
{
if (!query || do_query ("attach to process"))
debug (progname, INTERACTIVE);
}
void
g_stack_trace (const gchar *progname,
gboolean query)
{
if (!query || do_query ("print stack trace"))
debug (progname, STACK_TRACE);
}
static int
do_query (char *prompt)
{
char buf[32];
fprintf (stdout, "%s (y/n) ", prompt);
fprintf (stdout,
"(process:%u): %s%s: ",
(guint) getpid (),
query1,
query3);
fflush (stdout);
fgets (buf, 8, stdin);
fgets (buf, 32, stdin);
if ((strcmp (buf, "yes\n") == 0) ||
(strcmp (buf, "y\n") == 0) ||
(strcmp (buf, "YES\n") == 0) ||
(strcmp (buf, "Y\n") == 0))
return TRUE;
return FALSE;
if ((buf[0] == 'E' || buf[0] == 'e')
&& buf[1] == '\n')
_exit (0);
else if ((buf[0] == 'P' || buf[0] == 'p')
&& buf[1] == '\n')
return;
else if (prg_name
&& (buf[0] == 'S' || buf[0] == 's')
&& buf[1] == '\n')
{
g_on_error_stack_trace (prg_name);
goto retry;
}
else if ((buf[0] == 'H' || buf[0] == 'h')
&& buf[1] == '\n')
{
while (glib_on_error_halt)
;
glib_on_error_halt = TRUE;
return;
}
else
goto retry;
}
static void
debug (const char *progname,
int method)
void
g_on_error_stack_trace (const gchar *prg_name)
{
pid_t pid;
char buf[16];
char *args[4] = { "gdb", NULL, NULL, NULL };
volatile int x;
gchar buf[16];
gchar *args[4] = { "gdb", NULL, NULL, NULL };
sprintf (buf, "%d", (int) getpid ());
if (!prg_name)
return;
args[1] = (gchar*) progname;
sprintf (buf, "%u", (guint) getpid ());
args[1] = (gchar*) prg_name;
args[2] = buf;
switch (method)
pid = fork ();
if (pid == 0)
{
case INTERACTIVE:
fprintf (stdout, "pid: %s\n", buf);
break;
case STACK_TRACE:
pid = fork ();
if (pid == 0)
{
stack_trace (args);
_exit (0);
}
else if (pid == (pid_t) -1)
{
perror ("could not fork");
return;
}
break;
stack_trace (args);
_exit (0);
}
x = 1;
while (x)
else if (pid == (pid_t) -1)
{
perror ("unable to fork gdb");
return;
}
while (glib_on_error_halt)
;
glib_on_error_halt = TRUE;
}
static gboolean stack_trace_done = FALSE;
static void
stack_trace_sigchld (int signum)
{
stack_trace_done = TRUE;
}
static void
@ -167,12 +165,12 @@ stack_trace (char **args)
char buffer[256];
char c;
stack_trace_done = 0;
stack_trace_done = FALSE;
signal (SIGCHLD, stack_trace_sigchld);
if ((pipe (in_fd) == -1) || (pipe (out_fd) == -1))
{
perror ("could open pipe");
perror ("unable to open pipe");
_exit (0);
}
@ -189,7 +187,7 @@ stack_trace (char **args)
}
else if (pid == (pid_t) -1)
{
perror ("could not fork");
perror ("unable to fork");
_exit (0);
}
@ -252,9 +250,3 @@ stack_trace (char **args)
close (out_fd[1]);
_exit (0);
}
static void
stack_trace_sigchld (int signum)
{
stack_trace_done = 1;
}

View File

@ -36,9 +36,6 @@
#include <string.h> /* for bzero on BSD systems */
#endif
#define INTERACTIVE 0
#define STACK_TRACE 1
#ifndef NO_FD_SET
# define SELECT_MASK fd_set
@ -54,104 +51,105 @@
#endif
static int do_query (char *prompt);
static void debug (const gchar *progname, int method);
static void stack_trace (char **);
static void stack_trace_sigchld (int);
static void stack_trace (char **args);
static int stack_trace_done;
extern volatile gboolean glib_on_error_halt;
volatile gboolean glib_on_error_halt = TRUE;
void
g_debug (const gchar *progname)
g_on_error_query (const gchar *prg_name)
{
char buf[32];
static const gchar *query1 = "[E]xit, [H]alt";
static const gchar *query2 = ", show [S]tack trace";
static const gchar *query3 = " or [P]roceed";
gchar buf[16];
fprintf (stdout, "[n]othing, [e]xit, [s]tack trace, [a]ttach to process: ");
fflush (stdout);
fgets (buf, 32, stdin);
if (strcmp (buf, "n\n") == 0)
return;
else if (strcmp (buf, "s\n") == 0)
debug (progname, STACK_TRACE);
else if (strcmp (buf, "a\n") == 0)
debug (progname, INTERACTIVE);
if (!prg_name)
prg_name = g_get_prgname ();
retry:
if (prg_name)
fprintf (stdout,
"%s (pid:%u): %s%s%s: ",
prg_name,
(guint) getpid (),
query1,
query2,
query3);
else
exit (0);
}
void
g_attach_process (const gchar *progname,
gboolean query)
{
if (!query || do_query ("attach to process"))
debug (progname, INTERACTIVE);
}
void
g_stack_trace (const gchar *progname,
gboolean query)
{
if (!query || do_query ("print stack trace"))
debug (progname, STACK_TRACE);
}
static int
do_query (char *prompt)
{
char buf[32];
fprintf (stdout, "%s (y/n) ", prompt);
fprintf (stdout,
"(process:%u): %s%s: ",
(guint) getpid (),
query1,
query3);
fflush (stdout);
fgets (buf, 8, stdin);
fgets (buf, 32, stdin);
if ((strcmp (buf, "yes\n") == 0) ||
(strcmp (buf, "y\n") == 0) ||
(strcmp (buf, "YES\n") == 0) ||
(strcmp (buf, "Y\n") == 0))
return TRUE;
return FALSE;
if ((buf[0] == 'E' || buf[0] == 'e')
&& buf[1] == '\n')
_exit (0);
else if ((buf[0] == 'P' || buf[0] == 'p')
&& buf[1] == '\n')
return;
else if (prg_name
&& (buf[0] == 'S' || buf[0] == 's')
&& buf[1] == '\n')
{
g_on_error_stack_trace (prg_name);
goto retry;
}
else if ((buf[0] == 'H' || buf[0] == 'h')
&& buf[1] == '\n')
{
while (glib_on_error_halt)
;
glib_on_error_halt = TRUE;
return;
}
else
goto retry;
}
static void
debug (const char *progname,
int method)
void
g_on_error_stack_trace (const gchar *prg_name)
{
pid_t pid;
char buf[16];
char *args[4] = { "gdb", NULL, NULL, NULL };
volatile int x;
gchar buf[16];
gchar *args[4] = { "gdb", NULL, NULL, NULL };
sprintf (buf, "%d", (int) getpid ());
if (!prg_name)
return;
args[1] = (gchar*) progname;
sprintf (buf, "%u", (guint) getpid ());
args[1] = (gchar*) prg_name;
args[2] = buf;
switch (method)
pid = fork ();
if (pid == 0)
{
case INTERACTIVE:
fprintf (stdout, "pid: %s\n", buf);
break;
case STACK_TRACE:
pid = fork ();
if (pid == 0)
{
stack_trace (args);
_exit (0);
}
else if (pid == (pid_t) -1)
{
perror ("could not fork");
return;
}
break;
stack_trace (args);
_exit (0);
}
x = 1;
while (x)
else if (pid == (pid_t) -1)
{
perror ("unable to fork gdb");
return;
}
while (glib_on_error_halt)
;
glib_on_error_halt = TRUE;
}
static gboolean stack_trace_done = FALSE;
static void
stack_trace_sigchld (int signum)
{
stack_trace_done = TRUE;
}
static void
@ -167,12 +165,12 @@ stack_trace (char **args)
char buffer[256];
char c;
stack_trace_done = 0;
stack_trace_done = FALSE;
signal (SIGCHLD, stack_trace_sigchld);
if ((pipe (in_fd) == -1) || (pipe (out_fd) == -1))
{
perror ("could open pipe");
perror ("unable to open pipe");
_exit (0);
}
@ -189,7 +187,7 @@ stack_trace (char **args)
}
else if (pid == (pid_t) -1)
{
perror ("could not fork");
perror ("unable to fork");
_exit (0);
}
@ -252,9 +250,3 @@ stack_trace (char **args)
close (out_fd[1]);
_exit (0);
}
static void
stack_trace_sigchld (int signum)
{
stack_trace_done = 1;
}

View File

@ -125,6 +125,20 @@
#define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x)))
/* Define G_VA_COPY() to do the right thing for copying va_list variables.
* glibconfig.h may have already defined G_VA_COPY as va_copy or __va_copy.
*/
#if !defined (G_VA_COPY)
# if defined (__GNUC__) && defined (__PPC__) && (defined (_CALL_SYSV) || defined (_WIN32))
# define G_VA_COPY(ap1, ap2) (*(ap1) = *(ap2))
# elif defined (G_VA_COPY_AS_ARRAY)
# define G_VA_COPY(ap1, ap2) g_memmove ((ap1), (ap2), sizeof (va_list))
# else /* va_list is a pointer */
# define G_VA_COPY(ap1, ap2) ((ap1) = (ap2))
# endif /* va_list is a pointer */
#endif /* !G_VA_COPY */
/* Provide simple enum value macro wrappers that ease automated
* enum value stringification code. [abandoned]
*/
@ -926,13 +940,17 @@ GNode* g_node_last_sibling (GNode *node);
((GNode*) (node))->children : NULL)
/* Fatal error handlers
/* Fatal error handlers.
* g_on_error_query() will prompt the user to either
* [E]xit, [H]alt, [P]roceed or show [S]tack trace.
* g_on_error_stack_trace() invokes gdb, which attaches to the current
* process and shows a stack trace.
* These function may cause different actions on non-unix platforms.
* The prg_name arg is required by gdb to find the executable, if it is
* passed as NULL, g_on_error_query() will try g_get_prgname().
*/
void g_attach_process (const gchar *progname,
gboolean query);
void g_debug (const gchar *progname);
void g_stack_trace (const gchar *progname,
gboolean query);
void g_on_error_query (const gchar *prg_name);
void g_on_error_stack_trace (const gchar *prg_name);
/* Logging mechanism
@ -955,8 +973,7 @@ void g_log (const gchar *log_domain,
void g_logv (const gchar *log_domain,
GLogLevelFlags log_level,
const gchar *format,
va_list *args1,
va_list *args2);
va_list args);
GLogLevelFlags g_log_set_fatal_mask (const gchar *log_domain,
GLogLevelFlags fatal_mask);
GLogLevelFlags g_log_set_always_fatal (GLogLevelFlags fatal_mask);
@ -978,28 +995,28 @@ static inline void
g_error (const gchar *format,
...)
{
va_list arg_list1, arg_list2;
va_start (arg_list1, format); va_start (arg_list2, format);
g_logv (G_LOG_DOMAIN, G_LOG_LEVEL_ERROR, format, &arg_list1, &arg_list2);
va_end (arg_list2); va_end (arg_list1);
va_list args;
va_start (args, format);
g_logv (G_LOG_DOMAIN, G_LOG_LEVEL_ERROR, format, args);
va_end (args);
}
static inline void
g_message (const gchar *format,
...)
{
va_list arg_list1, arg_list2;
va_start (arg_list1, format); va_start (arg_list2, format);
g_logv (G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, format, &arg_list1, &arg_list2);
va_end (arg_list2); va_end (arg_list1);
va_list args;
va_start (args, format);
g_logv (G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, format, args);
va_end (args);
}
static inline void
g_warning (const gchar *format,
...)
{
va_list arg_list1, arg_list2;
va_start (arg_list1, format); va_start (arg_list2, format);
g_logv (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, format, &arg_list1, &arg_list2);
va_end (arg_list2); va_end (arg_list1);
va_list args;
va_start (args, format);
g_logv (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, format, args);
va_end (args);
}
#endif /* !__GNUC__ */
@ -1106,6 +1123,10 @@ void g_strdelimit (gchar *string,
const gchar *delimiters,
gchar new_delimiter);
gchar* g_strdup (const gchar *str);
gchar* g_strdup_printf (const gchar *format,
...) G_GNUC_PRINTF (1, 2);
gchar* g_strdup_vprintf (const gchar *format,
va_list args);
gchar* g_strndup (const gchar *str,
gulong n);
gchar* g_strconcat (const gchar *string1,
@ -1120,6 +1141,11 @@ void g_strdown (gchar *string);
void g_strup (gchar *string);
void g_strreverse (gchar *string);
/* calculate a string size, guarranteed to fit format + args.
*/
guint g_printf_string_upper_bound (const gchar* format,
va_list args);
/* Retrive static string info
*/
@ -1143,8 +1169,7 @@ gint g_snprintf (gchar *string,
gint g_vsnprintf (gchar *string,
gulong n,
gchar const *format,
va_list *args1,
va_list *args2);
va_list args);
gchar* g_basename (const gchar *file_name);
/* strings are newly allocated with g_malloc() */

View File

@ -43,12 +43,6 @@ struct _GLogHandler
};
/* --- prototypes --- */
extern gchar* g_vsprintf (const gchar *fmt,
va_list *args,
va_list *args2);
/* --- variables --- */
const gchar *g_log_domain_glib = "GLib";
static GLogDomain *g_log_domains = NULL;
@ -258,9 +252,9 @@ void
g_logv (const gchar *log_domain,
GLogLevelFlags log_level,
const gchar *format,
va_list *args1,
va_list *args2)
va_list args1)
{
va_list args2;
gchar buffer[1025];
register gint i;
@ -269,9 +263,23 @@ g_logv (const gchar *log_domain,
return;
/* we use a stack buffer of fixed size, because we might get called
* recursively, and we can also be out of memory.
* recursively.
*/
g_vsnprintf (buffer, 1025, format, args1, args2);
G_VA_COPY (args2, args1);
if (g_printf_string_upper_bound (format, args1) < 1024)
vsprintf (buffer, format, args2);
else
{
/* since we might be out of memory, we can't use g_vsnprintf(). */
#ifdef HAVE_VSNPRINTF
vsnprintf (buffer, 1024, format, args2);
#else /* !HAVE_VSNPRINTF */
/* we are out of luck here */
strncpy (buffer, format, 1024);
#endif /* !HAVE_VSNPRINTF */
buffer[1024] = 0;
}
va_end (args2);
for (i = g_bit_nth_msf (log_level, -1); i >= 0; i = g_bit_nth_msf (log_level, i))
{
@ -312,13 +320,11 @@ g_log (const gchar *log_domain,
const gchar *format,
...)
{
va_list arg_list1, arg_list2;
va_list args;
va_start (arg_list1, format);
va_start (arg_list2, format);
g_logv (log_domain, log_level, format, &arg_list1, &arg_list2);
va_end (arg_list2);
va_end (arg_list1);
va_start (args, format);
g_logv (log_domain, log_level, format, args);
va_end (args);
}
void
@ -523,30 +529,23 @@ void
g_print (const gchar *format,
...)
{
va_list args, args2;
char *buf;
va_list args;
gchar *string;
g_return_if_fail (format != NULL);
va_start (args, format);
va_start (args2, format);
buf = g_vsprintf (format, &args, &args2);
string = g_strdup_vprintf (format, args);
va_end (args);
va_end (args2);
if (glib_print_func)
{
gchar *string;
string = g_strdup (buf);
glib_print_func (string);
g_free (string);
}
glib_print_func (string);
else
{
fputs (buf, stdout);
fputs (string, stdout);
fflush (stdout);
}
g_free (string);
}
GPrintFunc
@ -564,30 +563,23 @@ void
g_printerr (const gchar *format,
...)
{
va_list args, args2;
char *buf;
va_list args;
gchar *string;
g_return_if_fail (format != NULL);
va_start (args, format);
va_start (args2, format);
buf = g_vsprintf (format, &args, &args2);
string = g_strdup_vprintf (format, args);
va_end (args);
va_end (args2);
if (glib_printerr_func)
{
gchar *string;
string = g_strdup (buf);
glib_printerr_func (string);
g_free (string);
}
glib_printerr_func (string);
else
{
fputs (buf, stderr);
fputs (string, stderr);
fflush (stderr);
}
g_free (string);
}
/* compatibility code */

View File

@ -102,7 +102,6 @@ static GScannerConfig g_scanner_config_template =
/* --- prototypes --- */
extern char* g_vsprintf (gchar *fmt, va_list *args, va_list *args2);
static inline
gint g_scanner_char_2_num (guchar c,
guchar base);
@ -271,16 +270,12 @@ g_scanner_error (GScanner *scanner,
if (scanner->msg_handler)
{
va_list args, args2;
va_list args;
gchar *string;
va_start (args, format);
va_start (args2, format);
string = g_vsprintf ((gchar*) format, &args, &args2);
string = g_strdup_vprintf (format, args);
va_end (args);
va_end (args2);
string = g_strdup (string);
scanner->msg_handler (scanner, string, TRUE);
@ -298,16 +293,12 @@ g_scanner_warn (GScanner *scanner,
if (scanner->msg_handler)
{
va_list args, args2;
va_list args;
gchar *string;
va_start (args, format);
va_start (args2, format);
string = g_vsprintf ((gchar*) format, &args, &args2);
string = g_strdup_vprintf (format, args);
va_end (args);
va_end (args2);
string = g_strdup (string);
scanner->msg_handler (scanner, string, FALSE);

View File

@ -58,6 +58,37 @@ g_strndup (const gchar *str, gulong n)
return new_str;
}
gchar*
g_strdup_vprintf (const gchar *format,
va_list args1)
{
gchar *buffer;
va_list args2;
G_VA_COPY (args2, args1);
buffer = g_new (gchar, g_printf_string_upper_bound (format, args1));
vsprintf (buffer, format, args2);
va_end (args2);
return buffer;
}
gchar*
g_strdup_printf (const gchar *format,
...)
{
gchar *buffer;
va_list args;
va_start (args, format);
buffer = g_strdup_vprintf (format, args);
va_end (args);
return buffer;
}
gchar*
g_strconcat (const gchar *string1, ...)
{
@ -681,6 +712,143 @@ g_strsignal (gint signum)
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 HAVE_GINT64
if (extra_long)
(void) va_arg (args, gint64);
else
#endif /* 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)
{

View File

@ -466,152 +466,16 @@ g_string_up (GString *fstring)
return fstring;
}
static int
get_length_upper_bound (const gchar* fmt, va_list *args)
{
int len = 0;
int short_int;
int long_int;
int done;
char *tmp;
while (*fmt)
{
char c = *fmt++;
short_int = FALSE;
long_int = FALSE;
if (c == '%')
{
done = FALSE;
while (*fmt && !done)
{
switch (*fmt++)
{
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':
fmt -= 1;
len += strtol (fmt, (char **)&fmt, 10);
break;
case 'h':
short_int = TRUE;
break;
case 'l':
long_int = TRUE;
break;
/* I ignore 'q' and 'L', they're not portable anyway. */
case 's':
tmp = va_arg(*args, char *);
if(tmp)
len += strlen (tmp);
else
len += strlen ("(null)");
done = TRUE;
break;
case 'd':
case 'i':
case 'o':
case 'u':
case 'x':
case 'X':
if (long_int)
(void)va_arg (*args, long);
else if (short_int)
(void)va_arg (*args, int);
else
(void)va_arg (*args, int);
len += 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':
(void)va_arg (*args, double);
len += 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:
break;
}
}
}
else
len += 1;
}
return len;
}
extern gchar* g_vsprintf (const gchar *fmt, va_list *args, va_list *args2);
gchar*
g_vsprintf (const gchar *fmt,
va_list *args,
va_list *args2)
{
static gchar *buf = NULL;
static guint alloc = 0;
guint len;
len = get_length_upper_bound (fmt, args);
if (len >= alloc)
{
if (buf)
g_free (buf);
alloc = nearest_pow (MAX (len + 1, 1024 + 1));
buf = g_new (gchar, alloc);
}
vsprintf (buf, fmt, *args2);
return buf;
}
static void
g_string_sprintfa_int (GString *string,
g_string_sprintfa_int (GString *string,
const gchar *fmt,
va_list *args,
va_list *args2)
va_list args)
{
g_string_append (string, g_vsprintf (fmt, args, args2));
gchar *buffer;
buffer = g_strdup_vprintf (fmt, args);
g_string_append (string, buffer);
g_free (buffer);
}
void
@ -619,17 +483,13 @@ g_string_sprintf (GString *string,
const gchar *fmt,
...)
{
va_list args, args2;
va_start(args, fmt);
va_start(args2, fmt);
va_list args;
g_string_truncate (string, 0);
g_string_sprintfa_int (string, fmt, &args, &args2);
va_end(args);
va_end(args2);
va_start (args, fmt);
g_string_sprintfa_int (string, fmt, args);
va_end (args);
}
void
@ -637,13 +497,9 @@ g_string_sprintfa (GString *string,
const gchar *fmt,
...)
{
va_list args, args2;
va_list args;
va_start(args, fmt);
va_start(args2, fmt);
g_string_sprintfa_int (string, fmt, &args, &args2);
va_end(args);
va_end(args2);
va_start (args, fmt);
g_string_sprintfa_int (string, fmt, args);
va_end (args);
}

View File

@ -32,7 +32,6 @@ const guint glib_micro_version = GLIB_MICRO_VERSION;
const guint glib_interface_age = GLIB_INTERFACE_AGE;
const guint glib_binary_age = GLIB_BINARY_AGE;
extern char* g_vsprintf (const gchar *fmt, va_list *args, va_list *args2);
gint
g_snprintf (gchar *str,
@ -51,17 +50,16 @@ g_snprintf (gchar *str,
return retval;
#else /* !HAVE_VSNPRINTF */
gchar *printed;
va_list args, args2;
va_list args;
va_start (args, fmt);
va_start (args2, fmt);
printed = g_strdup_vprintf (fmt, args);
va_end (args);
printed = g_vsprintf (fmt, &args, &args2);
strncpy (str, printed, n);
str[n-1] = '\0';
va_end (args2);
va_end (args);
g_free (printed);
return strlen (str);
#endif /* !HAVE_VSNPRINTF */
@ -71,21 +69,22 @@ gint
g_vsnprintf (gchar *str,
gulong n,
gchar const *fmt,
va_list *args1,
va_list *args2)
va_list args)
{
#ifdef HAVE_VSNPRINTF
gint retval;
retval = vsnprintf (str, n, fmt, *args1);
retval = vsnprintf (str, n, fmt, args);
return retval;
#else /* !HAVE_VSNPRINTF */
gchar *printed;
printed = g_vsprintf (fmt, args1, args2);
printed = g_strdup_vprintf (fmt, args);
strncpy (str, printed, n);
str[n-1] = '\0';
g_free (printed);
return strlen (str);
#endif /* !HAVE_VSNPRINTF */

View File

@ -37,6 +37,9 @@
#undef NO_SYS_ERRLIST
#undef NO_SYS_SIGLIST
#undef G_VA_COPY
#undef G_VA_COPY_AS_ARRAY
#undef GLIB_MAJOR_VERSION
#undef GLIB_MINOR_VERSION
#undef GLIB_MICRO_VERSION

View File

@ -43,12 +43,6 @@ struct _GLogHandler
};
/* --- prototypes --- */
extern gchar* g_vsprintf (const gchar *fmt,
va_list *args,
va_list *args2);
/* --- variables --- */
const gchar *g_log_domain_glib = "GLib";
static GLogDomain *g_log_domains = NULL;
@ -258,9 +252,9 @@ void
g_logv (const gchar *log_domain,
GLogLevelFlags log_level,
const gchar *format,
va_list *args1,
va_list *args2)
va_list args1)
{
va_list args2;
gchar buffer[1025];
register gint i;
@ -269,9 +263,23 @@ g_logv (const gchar *log_domain,
return;
/* we use a stack buffer of fixed size, because we might get called
* recursively, and we can also be out of memory.
* recursively.
*/
g_vsnprintf (buffer, 1025, format, args1, args2);
G_VA_COPY (args2, args1);
if (g_printf_string_upper_bound (format, args1) < 1024)
vsprintf (buffer, format, args2);
else
{
/* since we might be out of memory, we can't use g_vsnprintf(). */
#ifdef HAVE_VSNPRINTF
vsnprintf (buffer, 1024, format, args2);
#else /* !HAVE_VSNPRINTF */
/* we are out of luck here */
strncpy (buffer, format, 1024);
#endif /* !HAVE_VSNPRINTF */
buffer[1024] = 0;
}
va_end (args2);
for (i = g_bit_nth_msf (log_level, -1); i >= 0; i = g_bit_nth_msf (log_level, i))
{
@ -312,13 +320,11 @@ g_log (const gchar *log_domain,
const gchar *format,
...)
{
va_list arg_list1, arg_list2;
va_list args;
va_start (arg_list1, format);
va_start (arg_list2, format);
g_logv (log_domain, log_level, format, &arg_list1, &arg_list2);
va_end (arg_list2);
va_end (arg_list1);
va_start (args, format);
g_logv (log_domain, log_level, format, args);
va_end (args);
}
void
@ -523,30 +529,23 @@ void
g_print (const gchar *format,
...)
{
va_list args, args2;
char *buf;
va_list args;
gchar *string;
g_return_if_fail (format != NULL);
va_start (args, format);
va_start (args2, format);
buf = g_vsprintf (format, &args, &args2);
string = g_strdup_vprintf (format, args);
va_end (args);
va_end (args2);
if (glib_print_func)
{
gchar *string;
string = g_strdup (buf);
glib_print_func (string);
g_free (string);
}
glib_print_func (string);
else
{
fputs (buf, stdout);
fputs (string, stdout);
fflush (stdout);
}
g_free (string);
}
GPrintFunc
@ -564,30 +563,23 @@ void
g_printerr (const gchar *format,
...)
{
va_list args, args2;
char *buf;
va_list args;
gchar *string;
g_return_if_fail (format != NULL);
va_start (args, format);
va_start (args2, format);
buf = g_vsprintf (format, &args, &args2);
string = g_strdup_vprintf (format, args);
va_end (args);
va_end (args2);
if (glib_printerr_func)
{
gchar *string;
string = g_strdup (buf);
glib_printerr_func (string);
g_free (string);
}
glib_printerr_func (string);
else
{
fputs (buf, stderr);
fputs (string, stderr);
fflush (stderr);
}
g_free (string);
}
/* compatibility code */

View File

@ -169,7 +169,8 @@ main (int arg,
#if 0
g_log_set_fatal_mask ("GModule", G_LOG_FATAL_MASK|G_LOG_LEVEL_WARNING);
g_module_symbol (0, 0, 0);
g_warning("jahoooo");
g_warning("jahooo");
g_on_error_query (".libs/testgmodule");
#endif
return 0;

View File

@ -102,7 +102,6 @@ static GScannerConfig g_scanner_config_template =
/* --- prototypes --- */
extern char* g_vsprintf (gchar *fmt, va_list *args, va_list *args2);
static inline
gint g_scanner_char_2_num (guchar c,
guchar base);
@ -271,16 +270,12 @@ g_scanner_error (GScanner *scanner,
if (scanner->msg_handler)
{
va_list args, args2;
va_list args;
gchar *string;
va_start (args, format);
va_start (args2, format);
string = g_vsprintf ((gchar*) format, &args, &args2);
string = g_strdup_vprintf (format, args);
va_end (args);
va_end (args2);
string = g_strdup (string);
scanner->msg_handler (scanner, string, TRUE);
@ -298,16 +293,12 @@ g_scanner_warn (GScanner *scanner,
if (scanner->msg_handler)
{
va_list args, args2;
va_list args;
gchar *string;
va_start (args, format);
va_start (args2, format);
string = g_vsprintf ((gchar*) format, &args, &args2);
string = g_strdup_vprintf (format, args);
va_end (args);
va_end (args2);
string = g_strdup (string);
scanner->msg_handler (scanner, string, FALSE);

View File

@ -58,6 +58,37 @@ g_strndup (const gchar *str, gulong n)
return new_str;
}
gchar*
g_strdup_vprintf (const gchar *format,
va_list args1)
{
gchar *buffer;
va_list args2;
G_VA_COPY (args2, args1);
buffer = g_new (gchar, g_printf_string_upper_bound (format, args1));
vsprintf (buffer, format, args2);
va_end (args2);
return buffer;
}
gchar*
g_strdup_printf (const gchar *format,
...)
{
gchar *buffer;
va_list args;
va_start (args, format);
buffer = g_strdup_vprintf (format, args);
va_end (args);
return buffer;
}
gchar*
g_strconcat (const gchar *string1, ...)
{
@ -681,6 +712,143 @@ g_strsignal (gint signum)
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 HAVE_GINT64
if (extra_long)
(void) va_arg (args, gint64);
else
#endif /* 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)
{

174
gstring.c
View File

@ -466,152 +466,16 @@ g_string_up (GString *fstring)
return fstring;
}
static int
get_length_upper_bound (const gchar* fmt, va_list *args)
{
int len = 0;
int short_int;
int long_int;
int done;
char *tmp;
while (*fmt)
{
char c = *fmt++;
short_int = FALSE;
long_int = FALSE;
if (c == '%')
{
done = FALSE;
while (*fmt && !done)
{
switch (*fmt++)
{
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':
fmt -= 1;
len += strtol (fmt, (char **)&fmt, 10);
break;
case 'h':
short_int = TRUE;
break;
case 'l':
long_int = TRUE;
break;
/* I ignore 'q' and 'L', they're not portable anyway. */
case 's':
tmp = va_arg(*args, char *);
if(tmp)
len += strlen (tmp);
else
len += strlen ("(null)");
done = TRUE;
break;
case 'd':
case 'i':
case 'o':
case 'u':
case 'x':
case 'X':
if (long_int)
(void)va_arg (*args, long);
else if (short_int)
(void)va_arg (*args, int);
else
(void)va_arg (*args, int);
len += 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':
(void)va_arg (*args, double);
len += 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:
break;
}
}
}
else
len += 1;
}
return len;
}
extern gchar* g_vsprintf (const gchar *fmt, va_list *args, va_list *args2);
gchar*
g_vsprintf (const gchar *fmt,
va_list *args,
va_list *args2)
{
static gchar *buf = NULL;
static guint alloc = 0;
guint len;
len = get_length_upper_bound (fmt, args);
if (len >= alloc)
{
if (buf)
g_free (buf);
alloc = nearest_pow (MAX (len + 1, 1024 + 1));
buf = g_new (gchar, alloc);
}
vsprintf (buf, fmt, *args2);
return buf;
}
static void
g_string_sprintfa_int (GString *string,
g_string_sprintfa_int (GString *string,
const gchar *fmt,
va_list *args,
va_list *args2)
va_list args)
{
g_string_append (string, g_vsprintf (fmt, args, args2));
gchar *buffer;
buffer = g_strdup_vprintf (fmt, args);
g_string_append (string, buffer);
g_free (buffer);
}
void
@ -619,17 +483,13 @@ g_string_sprintf (GString *string,
const gchar *fmt,
...)
{
va_list args, args2;
va_start(args, fmt);
va_start(args2, fmt);
va_list args;
g_string_truncate (string, 0);
g_string_sprintfa_int (string, fmt, &args, &args2);
va_end(args);
va_end(args2);
va_start (args, fmt);
g_string_sprintfa_int (string, fmt, args);
va_end (args);
}
void
@ -637,13 +497,9 @@ g_string_sprintfa (GString *string,
const gchar *fmt,
...)
{
va_list args, args2;
va_list args;
va_start(args, fmt);
va_start(args2, fmt);
g_string_sprintfa_int (string, fmt, &args, &args2);
va_end(args);
va_end(args2);
va_start (args, fmt);
g_string_sprintfa_int (string, fmt, args);
va_end (args);
}

View File

@ -32,7 +32,6 @@ const guint glib_micro_version = GLIB_MICRO_VERSION;
const guint glib_interface_age = GLIB_INTERFACE_AGE;
const guint glib_binary_age = GLIB_BINARY_AGE;
extern char* g_vsprintf (const gchar *fmt, va_list *args, va_list *args2);
gint
g_snprintf (gchar *str,
@ -51,17 +50,16 @@ g_snprintf (gchar *str,
return retval;
#else /* !HAVE_VSNPRINTF */
gchar *printed;
va_list args, args2;
va_list args;
va_start (args, fmt);
va_start (args2, fmt);
printed = g_strdup_vprintf (fmt, args);
va_end (args);
printed = g_vsprintf (fmt, &args, &args2);
strncpy (str, printed, n);
str[n-1] = '\0';
va_end (args2);
va_end (args);
g_free (printed);
return strlen (str);
#endif /* !HAVE_VSNPRINTF */
@ -71,21 +69,22 @@ gint
g_vsnprintf (gchar *str,
gulong n,
gchar const *fmt,
va_list *args1,
va_list *args2)
va_list args)
{
#ifdef HAVE_VSNPRINTF
gint retval;
retval = vsnprintf (str, n, fmt, *args1);
retval = vsnprintf (str, n, fmt, args);
return retval;
#else /* !HAVE_VSNPRINTF */
gchar *printed;
printed = g_vsprintf (fmt, args1, args2);
printed = g_strdup_vprintf (fmt, args);
strncpy (str, printed, n);
str[n-1] = '\0';
g_free (printed);
return strlen (str);
#endif /* !HAVE_VSNPRINTF */