+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
+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
+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
+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
+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
+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
+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
+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
* 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:
#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
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 ***********************
#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
#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];
-
- fprintf (stdout, "[n]othing, [e]xit, [s]tack trace, [a]ttach to process: ");
+ 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];
+
+ 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
+ fprintf (stdout,
+ "(process:%u): %s%s: ",
+ (guint) getpid (),
+ query1,
+ query3);
fflush (stdout);
-
- fgets (buf, 32, stdin);
- if (strcmp (buf, "n\n") == 0)
+
+ fgets (buf, 8, stdin);
+
+ 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 (strcmp (buf, "s\n") == 0)
- debug (progname, STACK_TRACE);
- else if (strcmp (buf, "a\n") == 0)
- debug (progname, INTERACTIVE);
+ 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
- exit (0);
-}
-
-void
-g_attach_process (const gchar *progname,
- gboolean query)
-{
- if (!query || do_query ("attach to process"))
- debug (progname, INTERACTIVE);
+ goto retry;
}
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);
- fflush (stdout);
-
- 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;
-}
-
-static void
-debug (const char *progname,
- int method)
+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 };
+
+ if (!prg_name)
+ return;
- sprintf (buf, "%d", (int) getpid ());
+ sprintf (buf, "%u", (guint) getpid ());
- args[1] = (gchar*) progname;
+ 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
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);
}
}
else if (pid == (pid_t) -1)
{
- perror ("could not fork");
+ perror ("unable to fork");
_exit (0);
}
close (out_fd[1]);
_exit (0);
}
-
-static void
-stack_trace_sigchld (int signum)
-{
- stack_trace_done = 1;
-}
#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
#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];
-
- fprintf (stdout, "[n]othing, [e]xit, [s]tack trace, [a]ttach to process: ");
+ 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];
+
+ 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
+ fprintf (stdout,
+ "(process:%u): %s%s: ",
+ (guint) getpid (),
+ query1,
+ query3);
fflush (stdout);
-
- fgets (buf, 32, stdin);
- if (strcmp (buf, "n\n") == 0)
+
+ fgets (buf, 8, stdin);
+
+ 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 (strcmp (buf, "s\n") == 0)
- debug (progname, STACK_TRACE);
- else if (strcmp (buf, "a\n") == 0)
- debug (progname, INTERACTIVE);
+ 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
- exit (0);
-}
-
-void
-g_attach_process (const gchar *progname,
- gboolean query)
-{
- if (!query || do_query ("attach to process"))
- debug (progname, INTERACTIVE);
+ goto retry;
}
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);
- fflush (stdout);
-
- 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;
-}
-
-static void
-debug (const char *progname,
- int method)
+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 };
+
+ if (!prg_name)
+ return;
- sprintf (buf, "%d", (int) getpid ());
+ sprintf (buf, "%u", (guint) getpid ());
- args[1] = (gchar*) progname;
+ 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
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);
}
}
else if (pid == (pid_t) -1)
{
- perror ("could not fork");
+ perror ("unable to fork");
_exit (0);
}
close (out_fd[1]);
_exit (0);
}
-
-static void
-stack_trace_sigchld (int signum)
-{
- stack_trace_done = 1;
-}
#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]
*/
((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
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);
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__ */
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,
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
*/
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() */
#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
#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];
-
- fprintf (stdout, "[n]othing, [e]xit, [s]tack trace, [a]ttach to process: ");
+ 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];
+
+ 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
+ fprintf (stdout,
+ "(process:%u): %s%s: ",
+ (guint) getpid (),
+ query1,
+ query3);
fflush (stdout);
-
- fgets (buf, 32, stdin);
- if (strcmp (buf, "n\n") == 0)
+
+ fgets (buf, 8, stdin);
+
+ 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 (strcmp (buf, "s\n") == 0)
- debug (progname, STACK_TRACE);
- else if (strcmp (buf, "a\n") == 0)
- debug (progname, INTERACTIVE);
+ 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
- exit (0);
-}
-
-void
-g_attach_process (const gchar *progname,
- gboolean query)
-{
- if (!query || do_query ("attach to process"))
- debug (progname, INTERACTIVE);
+ goto retry;
}
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);
- fflush (stdout);
-
- 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;
-}
-
-static void
-debug (const char *progname,
- int method)
+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 };
+
+ if (!prg_name)
+ return;
- sprintf (buf, "%d", (int) getpid ());
+ sprintf (buf, "%u", (guint) getpid ());
- args[1] = (gchar*) progname;
+ 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
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);
}
}
else if (pid == (pid_t) -1)
{
- perror ("could not fork");
+ perror ("unable to fork");
_exit (0);
}
close (out_fd[1]);
_exit (0);
}
-
-static void
-stack_trace_sigchld (int signum)
-{
- stack_trace_done = 1;
-}
#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
#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];
-
- fprintf (stdout, "[n]othing, [e]xit, [s]tack trace, [a]ttach to process: ");
+ 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];
+
+ 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
+ fprintf (stdout,
+ "(process:%u): %s%s: ",
+ (guint) getpid (),
+ query1,
+ query3);
fflush (stdout);
-
- fgets (buf, 32, stdin);
- if (strcmp (buf, "n\n") == 0)
+
+ fgets (buf, 8, stdin);
+
+ 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 (strcmp (buf, "s\n") == 0)
- debug (progname, STACK_TRACE);
- else if (strcmp (buf, "a\n") == 0)
- debug (progname, INTERACTIVE);
+ 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
- exit (0);
-}
-
-void
-g_attach_process (const gchar *progname,
- gboolean query)
-{
- if (!query || do_query ("attach to process"))
- debug (progname, INTERACTIVE);
+ goto retry;
}
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);
- fflush (stdout);
-
- 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;
-}
-
-static void
-debug (const char *progname,
- int method)
+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 };
+
+ if (!prg_name)
+ return;
- sprintf (buf, "%d", (int) getpid ());
+ sprintf (buf, "%u", (guint) getpid ());
- args[1] = (gchar*) progname;
+ 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
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);
}
}
else if (pid == (pid_t) -1)
{
- perror ("could not fork");
+ perror ("unable to fork");
_exit (0);
}
close (out_fd[1]);
_exit (0);
}
-
-static void
-stack_trace_sigchld (int signum)
-{
- stack_trace_done = 1;
-}
#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]
*/
((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
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);
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__ */
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,
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
*/
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() */
};
-/* --- 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;
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;
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))
{
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
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
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 */
/* --- 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);
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);
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);
}
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, ...)
{
guint l;
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)
{
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
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
const gchar *fmt,
...)
{
- va_list args, args2;
-
- va_start(args, fmt);
- va_start(args2, fmt);
-
- g_string_sprintfa_int (string, fmt, &args, &args2);
+ va_list args;
- va_end(args);
- va_end(args2);
+ va_start (args, fmt);
+ g_string_sprintfa_int (string, fmt, args);
+ va_end (args);
}
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,
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 */
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 */
#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
};
-/* --- 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;
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;
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))
{
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
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
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 */
#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;
/* --- 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);
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);
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);
}
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, ...)
{
guint l;
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)
{
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
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
const gchar *fmt,
...)
{
- va_list args, args2;
-
- va_start(args, fmt);
- va_start(args2, fmt);
-
- g_string_sprintfa_int (string, fmt, &args, &args2);
+ va_list args;
- va_end(args);
- va_end(args2);
+ va_start (args, fmt);
+ g_string_sprintfa_int (string, fmt, args);
+ va_end (args);
}
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,
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 */
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 */