PROPOSAL: revise GLib message system
- From: Tim Janik <timj gtk org>
- To: Gtk+ Developers <gtk-devel-list redhat com>
- cc: Hacking Gnomes <Gnome-Hackers athena nuclecu unam mx>
- Subject: PROPOSAL: revise GLib message system
- Date: Fri, 7 Aug 1998 10:40:14 +0200 (CEST)
hi all,
i'll start out with an overview of the current API:
typedef void (*GErrorFunc) (gchar *str);
typedef void (*GWarningFunc) (gchar *str);
typedef void (*GPrintFunc) (gchar *str);
#define g_assert(expr) /* invoke g_error on failures */
#define g_assert_not_reached() /* invoke g_error */
#define g_return_if_fail(expr) /* invoke g_warning on failures */
#define g_return_val_if_fail(expr,val) /* invoke g_warning on failures */
void g_error (const gchar *format, ...) /* print error and abort */
void g_warning (const gchar *format, ...) /* print warning */
void g_message (const gchar *format, ...) /* print message */
void g_print (const gchar *format, ...) /* print something */
/* override default handlers for the above functions */
GErrorFunc g_set_error_handler (GErrorFunc func);
GWarningFunc g_set_warning_handler (GWarningFunc func);
GPrintFunc g_set_message_handler (GPrintFunc func);
GPrintFunc g_set_print_handler (GPrintFunc func);
and a few message samples:
g_print ("Test Print\n");
> Test Print
g_message ("Test Message");
> message: Test Message
g_warning ("Test Warning");
>
> ** WARNING **: Test Warning
g_error ("Test Error");
>
> ** ERROR **: Test Error
now a few sample warnings that actually appear in gtk/gdk/glib:
/* gtkmain.c: */ g_warning ("unable to register exit function");
/* gdkimage.c: */ g_warning ("shmget failed!");
/* gmem.c: */ g_warning ("trying to realloc freed memory\n");
gives:
>
> ** WARNING **: unable to register exit function
>
> ** WARNING **: shmget failed!
>
> ** WARNING **: trying to realloc freed memory
i think it would be much nicer to get something like:
>
> ** Gtk+-WARNING: unable to register exit function
>
> ** Gdk-WARNING: shmget failed!
>
> ** GLib-WARNING: trying to realloc freed memory
while g_warning ("Test Warning"); on the application level still produces:
>
> ** WARNING **: Test Warning
the same applies to g_message and g_error statements.
for things like the gimp, it doesn't actually make much sense to popup
a warning window if something below te gimp level is screwed.
imagine this warning window contains a GtkPixmap widget with a NULL
pixmap, this will cause a new warning window to popup and so on, until
the xserver crashes because of window overflow (i had that happening
some time ago, actually).
but unfortunately, with the current warning/error handlers, gimp can't
distinct between gtk, gdk, glib and gimp warnings.
further problems occour if gimp tries to handle messages/warnings that
come from e.g. gle. currently, parsing errors of ~/.glerc or the normal
g_return_if_fail () statements will be caught by the gimp's warning
handler, since i can't install custom handler functions for this without
reinventing the whole stuff for gle again.
to have warning, error and message handlers be implemented on a
per-library basis, i'd like to propose to rename
g_error to _g_error
g_warning to _g_warning
g_message to _g_message
and additionally have
void g_glib_error (const gchar *format, ...);
void g_glib_warning (const gchar *format, ...);
void g_glib_message (const gchar *format, ...);
GErrorFunc g_set_glib_error_handler (GErrorFunc func);
GWarningFunc g_set_glib_warning_handler (GWarningFunc func);
GPrintFunc g_set_glib_message_handler (GPrintFunc func);
and then have this in glib.h:
#ifdef GLIB_INTERNAL
#define g_error g_glib_error
#define g_warning g_glib_warning
#define g_message g_glib_message
#endif /* GLIB_INTERNAL */
#ifndef g_error
#define g_error _g_error
#endif /* g_error */
#ifndef g_warning
#define g_warning _g_warning
#endif /* g_warning */
#ifndef g_message
#define g_message _g_message
#endif /* g_message */
if we then compile the glib *.c files with -DGLIB_INTERNAL, all the warnings
and errors from within glib will be routed through the g_glib_* functions,
while the current behaviour is still provided on the application level.
to get specialized warning, error and message handlers for gtk, we just need
to trade the
#include <gdk/gdk.h>
in the header files with something like
#include <gtk/gtkbase.h>
and have this in gtkbase.h:
#ifdef GTK_INTERNAL
#define g_error _gtk_error
#define g_warning _gtk_warning
#define g_message _gtk_message
#endif /* GTK_INTERNAL */
#include <gdk/gdk.h>
/* the following functions should most probably go into gtkmain.h */
void _gtk_error (const gchar *format, ...);
void _gtk_warning (const gchar *format, ...);
void _gtk_message (const gchar *format, ...);
GErrorFunc gtk_set_error_handler (GErrorFunc func);
GWarningFunc gtk_set_warning_handler (GWarningFunc func);
GPrintFunc gtk_set_message_handler (GPrintFunc func);
of course all gtk*.c files need to be compiled with -DGTK_INTERNAL.
the same scheme can be applied to gdk and -especially- gnome, which
introduces a bunch of different libraries. keep in mind, that nothing
will change on the application level with the new scheme, programmers
have just to explicitely overload the message handlers of underlying
libraries if they really intend to catch those as well.
on a related note, i think the current g_return_val_if_fail (1 == 2, 0);
>
> ** WARNING **: file gwarn.c: line 6 (main): assertion "1 == 2" failed.
should better produce
>
> ** WARNING **: file gwarn.c: line 6 (main): assertion failed: "1 == 2"
also, people should refrain from using g_print() inside of libraries and
better go for g_message() for informational purposes, since g_print()
is of actuall use on the application side to print into a special
purpose messaging window or something the like, which is not supposed
to contain debugging information of the underlying libraries.
since g_print() is usually used for debugging statements, it might be a
good idea to implement an additional g_debug() call, similar to the
current g_message() function.
g_debug() could even be combined with existing debug keys, such as
gdk_debug_flags, so code portions like
#ifdef G_ENABLE_DEBUG
if (gdk_debug_flags & (GDK_DEBUG_EVENTS | GDK_DEBUG_DND))
g_print ("GDK_DROP_LEAVE\n");
#endif
could be written as (inside gdk):
g_debug (GDK_DEBUG_EVENTS | GDK_DEBUG_DND, "GDK_DROP_LEAVE");
and would produce:
> Gdk-Message: GDK_DROP_LEAVE
i'm curious to hear peoples comments on this isuue, and will most probably
go for the implementation of this in gtk, gdk and glib after a few days if
no one stands up and objects ;)
---
ciaoTJ
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]