gmessages: Make print handler functions to return default handlers

g_set_print_handler() and g_set_printerr_handler() are supposed to return
the old printer handlers, but in case the default is used NULL is returned
instead.

This makes hard to override the default handler to e.g. decorate the output
with some minor content, without having to rewrite the low-level
implementation.

So, make the default printers to be functions and set them as the default
ones. Also this avoids having to check each time what function to use at
print time.
This commit is contained in:
Marco Trevisan (Treviño) 2023-01-13 21:39:14 +01:00
parent 5d91834d9b
commit 3d1736c828
2 changed files with 76 additions and 22 deletions

View File

@ -501,12 +501,14 @@ struct _GLogHandler
GLogHandler *next;
};
static void g_default_print_func (const gchar *string);
static void g_default_printerr_func (const gchar *string);
/* --- variables --- */
static GMutex g_messages_lock;
static GLogDomain *g_log_domains = NULL;
static GPrintFunc glib_print_func = NULL;
static GPrintFunc glib_printerr_func = NULL;
static GPrintFunc glib_print_func = g_default_print_func;
static GPrintFunc glib_printerr_func = g_default_printerr_func;
static GPrivate g_log_depth;
static GPrivate g_log_structured_depth;
static GLogFunc default_log_func = g_log_default_handler;
@ -3284,9 +3286,11 @@ g_log_default_handler (const gchar *log_domain,
/**
* g_set_print_handler:
* @func: the new print handler
* @func: (nullable): the new print handler or %NULL to
* reset to the default
*
* Sets the print handler.
* Sets the print handler to @func, or resets it to the
* default GLib handler if %NULL.
*
* Any messages passed to g_print() will be output via
* the new handler. The default handler simply outputs
@ -3294,7 +3298,14 @@ g_log_default_handler (const gchar *log_domain,
* you can redirect the output, to a GTK+ widget or a
* log file for example.
*
* Returns: the old print handler
* Since 2.76 this functions always returns a valid
* #GPrintFunc, and never returns %NULL. If no custom
* print handler was set, it will return the GLib
* default print handler and that can be re-used to
* decorate its output and/or to write to stderr
* in all platforms. Before GLib 2.76, this was %NULL.
*
* Returns: (not nullable): the old print handler
*/
GPrintFunc
g_set_print_handler (GPrintFunc func)
@ -3303,7 +3314,7 @@ g_set_print_handler (GPrintFunc func)
g_mutex_lock (&g_messages_lock);
old_print_func = glib_print_func;
glib_print_func = func;
glib_print_func = func ? func : g_default_print_func;
g_mutex_unlock (&g_messages_lock);
return old_print_func;
@ -3360,6 +3371,18 @@ format_string (const char *format,
}
}
static void
g_default_print_func (const gchar *string)
{
print_string (stdout, string);
}
static void
g_default_printerr_func (const gchar *string)
{
print_string (stderr, string);
}
/**
* g_print:
* @format: the message format. See the printf() documentation
@ -3395,19 +3418,17 @@ g_print (const gchar *format,
local_glib_print_func = glib_print_func;
g_mutex_unlock (&g_messages_lock);
if (local_glib_print_func)
local_glib_print_func (string);
else
print_string (stdout, string);
local_glib_print_func (string);
g_free (free_me);
}
/**
* g_set_printerr_handler:
* @func: the new error message handler
* @func: (nullable): he new error message handler or %NULL
* to reset to the default
*
* Sets the handler for printing error messages.
* Sets the handler for printing error messages to @func,
* or resets it to the default GLib handler if %NULL.
*
* Any messages passed to g_printerr() will be output via
* the new handler. The default handler simply outputs the
@ -3415,7 +3436,14 @@ g_print (const gchar *format,
* redirect the output, to a GTK+ widget or a log file for
* example.
*
* Returns: the old error message handler
* Since 2.76 this functions always returns a valid
* #GPrintFunc, and never returns %NULL. If no custom error
* print handler was set, it will return the GLib default
* error print handler and that can be re-used to decorate
* its output and/or to write to stderr in all platforms.
* Before GLib 2.76, this was %NULL.
*
* Returns: (not nullable): the old error message handler
*/
GPrintFunc
g_set_printerr_handler (GPrintFunc func)
@ -3424,7 +3452,7 @@ g_set_printerr_handler (GPrintFunc func)
g_mutex_lock (&g_messages_lock);
old_printerr_func = glib_printerr_func;
glib_printerr_func = func;
glib_printerr_func = func ? func : g_default_printerr_func;
g_mutex_unlock (&g_messages_lock);
return old_printerr_func;
@ -3463,11 +3491,7 @@ g_printerr (const gchar *format,
local_glib_printerr_func = glib_printerr_func;
g_mutex_unlock (&g_messages_lock);
if (local_glib_printerr_func)
local_glib_printerr_func (string);
else
print_string (stderr, string);
local_glib_printerr_func (string);
g_free (free_me);
}

View File

@ -3,6 +3,12 @@
#define G_LOG_USE_STRUCTURED 1
#include <glib.h>
#ifdef G_OS_WIN32
#define LINE_END "\r\n"
#else
#define LINE_END "\n"
#endif
/* Test g_warn macros */
static void
test_warnings (void)
@ -362,13 +368,25 @@ test_print_handler (void)
GPrintFunc old_print_handler;
old_print_handler = g_set_print_handler (my_print_handler);
g_assert (old_print_handler == NULL);
g_assert_nonnull (old_print_handler);
my_print_count = 0;
g_print ("bu ba");
g_assert_cmpint (my_print_count, ==, 1);
g_set_print_handler (NULL);
if (g_test_subprocess ())
{
old_print_handler ("default handler\n");
g_print ("bu ba\n");
return;
}
g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT);
g_test_trap_assert_stdout ("*default handler" LINE_END "*");
g_test_trap_assert_stdout ("*bu ba" LINE_END "*");
g_test_trap_has_passed ();
}
static void
@ -377,13 +395,25 @@ test_printerr_handler (void)
GPrintFunc old_printerr_handler;
old_printerr_handler = g_set_printerr_handler (my_print_handler);
g_assert (old_printerr_handler == NULL);
g_assert_nonnull (old_printerr_handler);
my_print_count = 0;
g_printerr ("bu ba");
g_assert_cmpint (my_print_count, ==, 1);
g_set_printerr_handler (NULL);
if (g_test_subprocess ())
{
old_printerr_handler ("default handler\n");
g_printerr ("bu ba\n");
return;
}
g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT);
g_test_trap_assert_stderr ("*default handler" LINE_END "*");
g_test_trap_assert_stderr ("*bu ba" LINE_END "*");
g_test_trap_has_passed ();
}
static char *fail_str = "foo";