/* GLIB - Library of useful routines for C programming
 * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
 */

/*
 * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
 * file for a list of people on the GLib Team.  See the ChangeLog
 * files for a list of changes.  These files are distributed with
 * GLib at ftp://ftp.gtk.org/pub/gtk/.
 */

/*
 * MT safe
 */

/**
 * SECTION:messages
 * @Title: Message Output and Debugging Functions
 * @Short_description: functions to output messages and help debug applications
 *
 * These functions provide support for outputting messages.
 *
 * The g_return family of macros (g_return_if_fail(),
 * g_return_val_if_fail(), g_return_if_reached(),
 * g_return_val_if_reached()) should only be used for programming
 * errors, a typical use case is checking for invalid parameters at
 * the beginning of a public function. They should not be used if
 * you just mean "if (error) return", they should only be used if
 * you mean "if (bug in program) return". The program behavior is
 * generally considered undefined after one of these checks fails.
 * They are not intended for normal control flow, only to give a
 * perhaps-helpful warning before giving up.
 *
 * Structured logging output is supported using g_log_structured(). This differs
 * from the traditional g_log() API in that log messages are handled as a
 * collection of key–value pairs representing individual pieces of information,
 * rather than as a single string containing all the information in an arbitrary
 * format.
 *
 * The convenience macros g_info(), g_message(), g_debug(), g_warning() and g_error()
 * will use the traditional g_log() API unless you define the symbol
 * %G_LOG_USE_STRUCTURED before including `glib.h`. But note that even messages
 * logged through the traditional g_log() API are ultimatively passed to
 * g_log_structured(), so that all log messages end up in same destination.
 * If %G_LOG_USE_STRUCTURED is defined, g_test_expect_message() will become
 * ineffective for the wrapper macros g_warning() and friends (see
 * [Testing for Messages][testing-for-messages]).
 *
 * The support for structured logging was motivated by the following needs (some
 * of which were supported previously; others weren’t):
 *  * Support for multiple logging levels.
 *  * Structured log support with the ability to add `MESSAGE_ID`s (see
 *    g_log_structured()).
 *  * Moving the responsibility for filtering log messages from the program to
 *    the log viewer — instead of libraries and programs installing log handlers
 *    (with g_log_set_handler()) which filter messages before output, all log
 *    messages are outputted, and the log viewer program (such as `journalctl`)
 *    must filter them. This is based on the idea that bugs are sometimes hard
 *    to reproduce, so it is better to log everything possible and then use
 *    tools to analyse the logs than it is to not be able to reproduce a bug to
 *    get additional log data. Code which uses logging in performance-critical
 *    sections should compile out the g_log_structured() calls in
 *    release builds, and compile them in in debugging builds.
 *  * A single writer function which handles all log messages in a process, from
 *    all libraries and program code; rather than multiple log handlers with
 *    poorly defined interactions between them. This allows a program to easily
 *    change its logging policy by changing the writer function, for example to
 *    log to an additional location or to change what logging output fallbacks
 *    are used. The log writer functions provided by GLib are exposed publicly
 *    so they can be used from programs’ log writers. This allows log writer
 *    policy and implementation to be kept separate.
 *  * If a library wants to add standard information to all of its log messages
 *    (such as library state) or to redact private data (such as passwords or
 *    network credentials), it should use a wrapper function around its
 *    g_log_structured() calls or implement that in the single log writer
 *    function.
 *  * If a program wants to pass context data from a g_log_structured() call to
 *    its log writer function so that, for example, it can use the correct
 *    server connection to submit logs to, that user data can be passed as a
 *    zero-length #GLogField to g_log_structured_array().
 *  * Color output needed to be supported on the terminal, to make reading
 *    through logs easier.
 *
 * ## Using Structured Logging ## {#using-structured-logging}
 *
 * To use structured logging (rather than the old-style logging), either use
 * the g_log_structured() and g_log_structured_array() functions; or define
 * `G_LOG_USE_STRUCTURED` before including any GLib header, and use the
 * g_message(), g_debug(), g_error() (etc.) macros.
 *
 * You do not need to define `G_LOG_USE_STRUCTURED` to use g_log_structured(),
 * but it is a good idea to avoid confusion.
 *
 * ## Log Domains ## {#log-domains}
 *
 * Log domains may be used to broadly split up the origins of log messages.
 * Typically, there are one or a few log domains per application or library.
 * %G_LOG_DOMAIN should be used to define the default log domain for the current
 * compilation unit — it is typically defined at the top of a source file, or in
 * the preprocessor flags for a group of source files.
 *
 * Log domains must be unique, and it is recommended that they are the
 * application or library name, optionally followed by a hyphen and a sub-domain
 * name. For example, `bloatpad` or `bloatpad-io`.
 *
 * ## Debug Message Output ## {#debug-message-output}
 *
 * The default log functions (g_log_default_handler() for the old-style API and
 * g_log_writer_default() for the structured API) both drop debug and
 * informational messages by default, unless the log domains of those messages
 * are listed in the `G_MESSAGES_DEBUG` environment variable (or it is set to
 * `all`).
 *
 * It is recommended that custom log writer functions re-use the
 * `G_MESSAGES_DEBUG` environment variable, rather than inventing a custom one,
 * so that developers can re-use the same debugging techniques and tools across
 * projects.
 *
 * ## Testing for Messages ## {#testing-for-messages}
 *
 * With the old g_log() API, g_test_expect_message() and
 * g_test_assert_expected_messages() could be used in simple cases to check
 * whether some code under test had emitted a given log message. These
 * functions have been deprecated with the structured logging API, for several
 * reasons:
 *  * They relied on an internal queue which was too inflexible for many use
 *    cases, where messages might be emitted in several orders, some
 *    messages might not be emitted deterministically, or messages might be
 *    emitted by unrelated log domains.
 *  * They do not support structured log fields.
 *  * Examining the log output of code is a bad approach to testing it, and
 *    while it might be necessary for legacy code which uses g_log(), it should
 *    be avoided for new code using g_log_structured().
 *
 * They will continue to work as before if g_log() is in use (and
 * %G_LOG_USE_STRUCTURED is not defined). They will do nothing if used with the
 * structured logging API.
 *
 * Examining the log output of code is discouraged: libraries should not emit to
 * `stderr` during defined behaviour, and hence this should not be tested. If
 * the log emissions of a library during undefined behaviour need to be tested,
 * they should be limited to asserting that the library aborts and prints a
 * suitable error message before aborting. This should be done with
 * g_test_trap_assert_stderr().
 *
 * If it is really necessary to test the structured log messages emitted by a
 * particular piece of code – and the code cannot be restructured to be more
 * suitable to more conventional unit testing – you should write a custom log
 * writer function (see g_log_set_writer_func()) which appends all log messages
 * to a queue. When you want to check the log messages, examine and clear the
 * queue, ignoring irrelevant log messages (for example, from log domains other
 * than the one under test).
 */

#include "config.h"

#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <locale.h>
#include <errno.h>

#if defined(__linux__) && !defined(__BIONIC__)
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <fcntl.h>
#include <sys/uio.h>
#endif

#include "glib-init.h"
#include "galloca.h"
#include "gbacktrace.h"
#include "gcharset.h"
#include "gconvert.h"
#include "genviron.h"
#include "gmain.h"
#include "gmem.h"
#include "gprintfint.h"
#include "gtestutils.h"
#include "gthread.h"
#include "gstrfuncs.h"
#include "gstring.h"
#include "gpattern.h"

#ifdef G_OS_UNIX
#include <unistd.h>
#endif

#ifdef G_OS_WIN32
#include <process.h>		/* For getpid() */
#include <io.h>
#  include <windows.h>

#ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING
#define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004
#endif

#if defined (_MSC_VER) && (_MSC_VER >=1400)
/* This is ugly, but we need it for isatty() in case we have bad fd's,
 * otherwise Windows will abort() the program on msvcrt80.dll and later
 */
#include <crtdbg.h>

_GLIB_EXTERN void
myInvalidParameterHandler(const wchar_t *expression,
                          const wchar_t *function,
                          const wchar_t *file,
                          unsigned int   line,
                          uintptr_t      pReserved)
{
}
#endif

#include "gwin32.h"
#endif

/**
 * G_LOG_DOMAIN:
 *
 * Defines the log domain. See [Log Domains](#log-domains).
 *
 * Libraries should define this so that any messages
 * which they log can be differentiated from messages from other
 * libraries and application code. But be careful not to define
 * it in any public header files.
 *
 * Log domains must be unique, and it is recommended that they are the
 * application or library name, optionally followed by a hyphen and a sub-domain
 * name. For example, `bloatpad` or `bloatpad-io`.
 *
 * If undefined, it defaults to the default %NULL (or `""`) log domain; this is
 * not advisable, as it cannot be filtered against using the `G_MESSAGES_DEBUG`
 * environment variable.
 *
 * For example, GTK+ uses this in its `Makefile.am`:
 * |[
 * AM_CPPFLAGS = -DG_LOG_DOMAIN=\"Gtk\"
 * ]|
 *
 * Applications can choose to leave it as the default %NULL (or `""`)
 * domain. However, defining the domain offers the same advantages as
 * above.
 *

 */

/**
 * G_LOG_FATAL_MASK:
 *
 * GLib log levels that are considered fatal by default.
 *
 * This is not used if structured logging is enabled; see
 * [Using Structured Logging][using-structured-logging].
 */

/**
 * GLogFunc:
 * @log_domain: the log domain of the message
 * @log_level: the log level of the message (including the
 *     fatal and recursion flags)
 * @message: the message to process
 * @user_data: user data, set in g_log_set_handler()
 *
 * Specifies the prototype of log handler functions.
 *
 * The default log handler, g_log_default_handler(), automatically appends a
 * new-line character to @message when printing it. It is advised that any
 * custom log handler functions behave similarly, so that logging calls in user
 * code do not need modifying to add a new-line character to the message if the
 * log handler is changed.
 *
 * This is not used if structured logging is enabled; see
 * [Using Structured Logging][using-structured-logging].
 */

/**
 * GLogLevelFlags:
 * @G_LOG_FLAG_RECURSION: internal flag
 * @G_LOG_FLAG_FATAL: internal flag
 * @G_LOG_LEVEL_ERROR: log level for errors, see g_error().
 *     This level is also used for messages produced by g_assert().
 * @G_LOG_LEVEL_CRITICAL: log level for critical warning messages, see
 *     g_critical().
 *     This level is also used for messages produced by g_return_if_fail()
 *     and g_return_val_if_fail().
 * @G_LOG_LEVEL_WARNING: log level for warnings, see g_warning()
 * @G_LOG_LEVEL_MESSAGE: log level for messages, see g_message()
 * @G_LOG_LEVEL_INFO: log level for informational messages, see g_info()
 * @G_LOG_LEVEL_DEBUG: log level for debug messages, see g_debug()
 * @G_LOG_LEVEL_MASK: a mask including all log levels
 *
 * Flags specifying the level of log messages.
 *
 * It is possible to change how GLib treats messages of the various
 * levels using g_log_set_handler() and g_log_set_fatal_mask().
 */

/**
 * G_LOG_LEVEL_USER_SHIFT:
 *
 * Log levels below 1<<G_LOG_LEVEL_USER_SHIFT are used by GLib.
 * Higher bits can be used for user-defined log levels.
 */

/**
 * g_message:
 * @...: format string, followed by parameters to insert
 *     into the format string (as with printf())
 *
 * A convenience function/macro to log a normal message.
 *
 * If g_log_default_handler() is used as the log handler function, a new-line
 * character will automatically be appended to @..., and need not be entered
 * manually.
 *
 * If structured logging is enabled, this will use g_log_structured();
 * otherwise it will use g_log(). See
 * [Using Structured Logging][using-structured-logging].
 */

/**
 * g_warning:
 * @...: format string, followed by parameters to insert
 *     into the format string (as with printf())
 *
 * A convenience function/macro to log a warning message. The message should
 * typically *not* be translated to the user's language.
 *
 * This is not intended for end user error reporting. Use of #GError is
 * preferred for that instead, as it allows calling functions to perform actions
 * conditional on the type of error.
 *
 * Warning messages are intended to be used in the event of unexpected
 * external conditions (system misconfiguration, missing files,
 * other trusted programs violating protocol, invalid contents in
 * trusted files, etc.)
 *
 * If attempting to deal with programmer errors (for example, incorrect function
 * parameters) then you should use %G_LOG_LEVEL_CRITICAL instead.
 *
 * g_warn_if_reached() and g_warn_if_fail() log at %G_LOG_LEVEL_WARNING.
 *
 * You can make warnings fatal at runtime by setting the `G_DEBUG`
 * environment variable (see
 * [Running GLib Applications](glib-running.html)):
 *
 * |[
 *   G_DEBUG=fatal-warnings gdb ./my-program
 * ]|
 *
 * Any unrelated failures can be skipped over in
 * [gdb](https://www.gnu.org/software/gdb/) using the `continue` command.
 *
 * If g_log_default_handler() is used as the log handler function,
 * a newline character will automatically be appended to @..., and
 * need not be entered manually.
 *
 * If structured logging is enabled, this will use g_log_structured();
 * otherwise it will use g_log(). See
 * [Using Structured Logging][using-structured-logging].
 */

/**
 * g_critical:
 * @...: format string, followed by parameters to insert
 *     into the format string (as with printf())
 *
 * Logs a "critical warning" (#G_LOG_LEVEL_CRITICAL).
 *
 * Critical warnings are intended to be used in the event of an error
 * that originated in the current process (a programmer error).
 * Logging of a critical error is by definition an indication of a bug
 * somewhere in the current program (or its libraries).
 *
 * g_return_if_fail(), g_return_val_if_fail(), g_return_if_reached() and
 * g_return_val_if_reached() log at %G_LOG_LEVEL_CRITICAL.
 *
 * You can make critical warnings fatal at runtime by
 * setting the `G_DEBUG` environment variable (see
 * [Running GLib Applications](glib-running.html)):
 *
 * |[
 *   G_DEBUG=fatal-warnings gdb ./my-program
 * ]|
 *
 * You can also use g_log_set_always_fatal().
 *
 * Any unrelated failures can be skipped over in
 * [gdb](https://www.gnu.org/software/gdb/) using the `continue` command.
 *
 * The message should typically *not* be translated to the
 * user's language.
 *
 * If g_log_default_handler() is used as the log handler function, a new-line
 * character will automatically be appended to @..., and need not be entered
 * manually.
 *
 * If structured logging is enabled, this will use g_log_structured();
 * otherwise it will use g_log(). See
 * [Using Structured Logging][using-structured-logging].
 */

/**
 * g_error:
 * @...: format string, followed by parameters to insert
 *     into the format string (as with printf())
 *
 * A convenience function/macro to log an error message. The message should
 * typically *not* be translated to the user's language.
 *
 * This is not intended for end user error reporting. Use of #GError is
 * preferred for that instead, as it allows calling functions to perform actions
 * conditional on the type of error.
 *
 * Error messages are always fatal, resulting in a call to G_BREAKPOINT()
 * to terminate the application. This function will
 * result in a core dump; don't use it for errors you expect.
 * Using this function indicates a bug in your program, i.e.
 * an assertion failure.
 *
 * If g_log_default_handler() is used as the log handler function, a new-line
 * character will automatically be appended to @..., and need not be entered
 * manually.
 *
 * If structured logging is enabled, this will use g_log_structured();
 * otherwise it will use g_log(). See
 * [Using Structured Logging][using-structured-logging].
 */

/**
 * g_info:
 * @...: format string, followed by parameters to insert
 *     into the format string (as with printf())
 *
 * A convenience function/macro to log an informational message. Seldom used.
 *
 * If g_log_default_handler() is used as the log handler function, a new-line
 * character will automatically be appended to @..., and need not be entered
 * manually.
 *
 * Such messages are suppressed by the g_log_default_handler() and
 * g_log_writer_default() unless the `G_MESSAGES_DEBUG` environment variable is
 * set appropriately.
 *
 * If structured logging is enabled, this will use g_log_structured();
 * otherwise it will use g_log(). See
 * [Using Structured Logging][using-structured-logging].
 *
 * Since: 2.40
 */

/**
 * g_debug:
 * @...: format string, followed by parameters to insert
 *     into the format string (as with printf())
 *
 * A convenience function/macro to log a debug message. The message should
 * typically *not* be translated to the user's language.
 *
 * If g_log_default_handler() is used as the log handler function, a new-line
 * character will automatically be appended to @..., and need not be entered
 * manually.
 *
 * Such messages are suppressed by the g_log_default_handler() and
 * g_log_writer_default() unless the `G_MESSAGES_DEBUG` environment variable is
 * set appropriately.
 *
 * If structured logging is enabled, this will use g_log_structured();
 * otherwise it will use g_log(). See
 * [Using Structured Logging][using-structured-logging].
 *
 * Since: 2.6
 */

/* --- structures --- */
typedef struct _GLogDomain	GLogDomain;
typedef struct _GLogHandler	GLogHandler;
struct _GLogDomain
{
  gchar		*log_domain;
  GLogLevelFlags fatal_mask;
  GLogHandler	*handlers;
  GLogDomain	*next;
};
struct _GLogHandler
{
  guint		 id;
  GLogLevelFlags log_level;
  GLogFunc	 log_func;
  gpointer	 data;
  GDestroyNotify destroy;
  GLogHandler	*next;
};


/* --- 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 GPrivate       g_log_depth;
static GPrivate       g_log_structured_depth;
static GLogFunc       default_log_func = g_log_default_handler;
static gpointer       default_log_data = NULL;
static GTestLogFatalFunc fatal_log_func = NULL;
static gpointer          fatal_log_data;
static GLogWriterFunc log_writer_func = g_log_writer_default;
static gpointer       log_writer_user_data = NULL;
static GDestroyNotify log_writer_user_data_free = NULL;

/* --- functions --- */

static void _g_log_abort (gboolean breakpoint);

static void
_g_log_abort (gboolean breakpoint)
{
  gboolean debugger_present;

  if (g_test_subprocess ())
    {
      /* If this is a test case subprocess then it probably caused
       * this error message on purpose, so just exit() rather than
       * abort()ing, to avoid triggering any system crash-reporting
       * daemon.
       */
      _exit (1);
    }

#ifdef G_OS_WIN32
  debugger_present = IsDebuggerPresent ();
#else
  /* Assume GDB is attached. */
  debugger_present = TRUE;
#endif /* !G_OS_WIN32 */

  if (debugger_present && breakpoint)
    G_BREAKPOINT ();
  else
    g_abort ();
}

#ifdef G_OS_WIN32
static gboolean win32_keep_fatal_message = FALSE;

/* This default message will usually be overwritten. */
/* Yes, a fixed size buffer is bad. So sue me. But g_error() is never
 * called with huge strings, is it?
 */
static gchar  fatal_msg_buf[1000] = "Unspecified fatal error encountered, aborting.";
static gchar *fatal_msg_ptr = fatal_msg_buf;

#undef write
static inline int
dowrite (int          fd,
	 const void  *buf,
	 unsigned int len)
{
  if (win32_keep_fatal_message)
    {
      memcpy (fatal_msg_ptr, buf, len);
      fatal_msg_ptr += len;
      *fatal_msg_ptr = 0;
      return len;
    }

  write (fd, buf, len);

  return len;
}
#define write(fd, buf, len) dowrite(fd, buf, len)

#endif

static void
write_string (FILE        *stream,
	      const gchar *string)
{
  fputs (string, stream);
}

static void
write_string_sized (FILE        *stream,
                    const gchar *string,
                    gssize       length)
{
  /* Is it nul-terminated? */
  if (length < 0)
    write_string (stream, string);
  else
    fwrite (string, 1, length, stream);
}

static GLogDomain*
g_log_find_domain_L (const gchar *log_domain)
{
  GLogDomain *domain;
  
  domain = g_log_domains;
  while (domain)
    {
      if (strcmp (domain->log_domain, log_domain) == 0)
	return domain;
      domain = domain->next;
    }
  return NULL;
}

static GLogDomain*
g_log_domain_new_L (const gchar *log_domain)
{
  GLogDomain *domain;

  domain = g_new (GLogDomain, 1);
  domain->log_domain = g_strdup (log_domain);
  domain->fatal_mask = G_LOG_FATAL_MASK;
  domain->handlers = NULL;
  
  domain->next = g_log_domains;
  g_log_domains = domain;
  
  return domain;
}

static void
g_log_domain_check_free_L (GLogDomain *domain)
{
  if (domain->fatal_mask == G_LOG_FATAL_MASK &&
      domain->handlers == NULL)
    {
      GLogDomain *last, *work;
      
      last = NULL;  

      work = g_log_domains;
      while (work)
	{
	  if (work == domain)
	    {
	      if (last)
		last->next = domain->next;
	      else
		g_log_domains = domain->next;
	      g_free (domain->log_domain);
	      g_free (domain);
	      break;
	    }
	  last = work;
	  work = last->next;
	}  
    }
}

static GLogFunc
g_log_domain_get_handler_L (GLogDomain	*domain,
			    GLogLevelFlags log_level,
			    gpointer	*data)
{
  if (domain && log_level)
    {
      GLogHandler *handler;
      
      handler = domain->handlers;
      while (handler)
	{
	  if ((handler->log_level & log_level) == log_level)
	    {
	      *data = handler->data;
	      return handler->log_func;
	    }
	  handler = handler->next;
	}
    }

  *data = default_log_data;
  return default_log_func;
}

/**
 * g_log_set_always_fatal:
 * @fatal_mask: the mask containing bits set for each level
 *     of error which is to be fatal
 *
 * Sets the message levels which are always fatal, in any log domain.
 * When a message with any of these levels is logged the program terminates.
 * You can only set the levels defined by GLib to be fatal.
 * %G_LOG_LEVEL_ERROR is always fatal.
 *
 * You can also make some message levels fatal at runtime by setting
 * the `G_DEBUG` environment variable (see
 * [Running GLib Applications](glib-running.html)).
 *
 * Libraries should not call this function, as it affects all messages logged
 * by a process, including those from other libraries.
 *
 * Structured log messages (using g_log_structured() and
 * g_log_structured_array()) are fatal only if the default log writer is used;
 * otherwise it is up to the writer function to determine which log messages
 * are fatal. See [Using Structured Logging][using-structured-logging].
 *
 * Returns: the old fatal mask
 */
GLogLevelFlags
g_log_set_always_fatal (GLogLevelFlags fatal_mask)
{
  GLogLevelFlags old_mask;

  /* restrict the global mask to levels that are known to glib
   * since this setting applies to all domains
   */
  fatal_mask &= (1 << G_LOG_LEVEL_USER_SHIFT) - 1;
  /* force errors to be fatal */
  fatal_mask |= G_LOG_LEVEL_ERROR;
  /* remove bogus flag */
  fatal_mask &= ~G_LOG_FLAG_FATAL;

  g_mutex_lock (&g_messages_lock);
  old_mask = g_log_always_fatal;
  g_log_always_fatal = fatal_mask;
  g_mutex_unlock (&g_messages_lock);

  return old_mask;
}

/**
 * g_log_set_fatal_mask:
 * @log_domain: the log domain
 * @fatal_mask: the new fatal mask
 *
 * Sets the log levels which are fatal in the given domain.
 * %G_LOG_LEVEL_ERROR is always fatal.
 *
 * This has no effect on structured log messages (using g_log_structured() or
 * g_log_structured_array()). To change the fatal behaviour for specific log
 * messages, programs must install a custom log writer function using
 * g_log_set_writer_func(). See
 * [Using Structured Logging][using-structured-logging].
 *
 * This function is mostly intended to be used with
 * %G_LOG_LEVEL_CRITICAL.  You should typically not set
 * %G_LOG_LEVEL_WARNING, %G_LOG_LEVEL_MESSAGE, %G_LOG_LEVEL_INFO or
 * %G_LOG_LEVEL_DEBUG as fatal except inside of test programs.
 *
 * Returns: the old fatal mask for the log domain
 */
GLogLevelFlags
g_log_set_fatal_mask (const gchar   *log_domain,
		      GLogLevelFlags fatal_mask)
{
  GLogLevelFlags old_flags;
  GLogDomain *domain;
  
  if (!log_domain)
    log_domain = "";

  /* force errors to be fatal */
  fatal_mask |= G_LOG_LEVEL_ERROR;
  /* remove bogus flag */
  fatal_mask &= ~G_LOG_FLAG_FATAL;
  
  g_mutex_lock (&g_messages_lock);

  domain = g_log_find_domain_L (log_domain);
  if (!domain)
    domain = g_log_domain_new_L (log_domain);
  old_flags = domain->fatal_mask;
  
  domain->fatal_mask = fatal_mask;
  g_log_domain_check_free_L (domain);

  g_mutex_unlock (&g_messages_lock);

  return old_flags;
}

/**
 * g_log_set_handler:
 * @log_domain: (nullable): the log domain, or %NULL for the default ""
 *     application domain
 * @log_levels: the log levels to apply the log handler for.
 *     To handle fatal and recursive messages as well, combine
 *     the log levels with the #G_LOG_FLAG_FATAL and
 *     #G_LOG_FLAG_RECURSION bit flags.
 * @log_func: the log handler function
 * @user_data: data passed to the log handler
 *
 * Sets the log handler for a domain and a set of log levels.
 * To handle fatal and recursive messages the @log_levels parameter
 * must be combined with the #G_LOG_FLAG_FATAL and #G_LOG_FLAG_RECURSION
 * bit flags.
 *
 * Note that since the #G_LOG_LEVEL_ERROR log level is always fatal, if
 * you want to set a handler for this log level you must combine it with
 * #G_LOG_FLAG_FATAL.
 *
 * This has no effect if structured logging is enabled; see
 * [Using Structured Logging][using-structured-logging].
 *
 * Here is an example for adding a log handler for all warning messages
 * in the default domain:
 * |[<!-- language="C" --> 
 * g_log_set_handler (NULL, G_LOG_LEVEL_WARNING | G_LOG_FLAG_FATAL
 *                    | G_LOG_FLAG_RECURSION, my_log_handler, NULL);
 * ]|
 *
 * This example adds a log handler for all critical messages from GTK+:
 * |[<!-- language="C" --> 
 * g_log_set_handler ("Gtk", G_LOG_LEVEL_CRITICAL | G_LOG_FLAG_FATAL
 *                    | G_LOG_FLAG_RECURSION, my_log_handler, NULL);
 * ]|
 *
 * This example adds a log handler for all messages from GLib:
 * |[<!-- language="C" --> 
 * g_log_set_handler ("GLib", G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL
 *                    | G_LOG_FLAG_RECURSION, my_log_handler, NULL);
 * ]|
 *
 * Returns: the id of the new handler
 */
guint
g_log_set_handler (const gchar	 *log_domain,
                   GLogLevelFlags log_levels,
                   GLogFunc       log_func,
                   gpointer       user_data)
{
  return g_log_set_handler_full (log_domain, log_levels, log_func, user_data, NULL);
}

/**
 * g_log_set_handler_full: (rename-to g_log_set_handler)
 * @log_domain: (nullable): the log domain, or %NULL for the default ""
 *     application domain
 * @log_levels: the log levels to apply the log handler for.
 *     To handle fatal and recursive messages as well, combine
 *     the log levels with the #G_LOG_FLAG_FATAL and
 *     #G_LOG_FLAG_RECURSION bit flags.
 * @log_func: the log handler function
 * @user_data: data passed to the log handler
 * @destroy: destroy notify for @user_data, or %NULL
 *
 * Like g_log_set_handler(), but takes a destroy notify for the @user_data.
 *
 * This has no effect if structured logging is enabled; see
 * [Using Structured Logging][using-structured-logging].
 *
 * Returns: the id of the new handler
 *
 * Since: 2.46
 */
guint
g_log_set_handler_full (const gchar    *log_domain,
                        GLogLevelFlags  log_levels,
                        GLogFunc        log_func,
                        gpointer        user_data,
                        GDestroyNotify  destroy)
{
  static guint handler_id = 0;
  GLogDomain *domain;
  GLogHandler *handler;
  
  g_return_val_if_fail ((log_levels & G_LOG_LEVEL_MASK) != 0, 0);
  g_return_val_if_fail (log_func != NULL, 0);
  
  if (!log_domain)
    log_domain = "";

  handler = g_new (GLogHandler, 1);

  g_mutex_lock (&g_messages_lock);

  domain = g_log_find_domain_L (log_domain);
  if (!domain)
    domain = g_log_domain_new_L (log_domain);
  
  handler->id = ++handler_id;
  handler->log_level = log_levels;
  handler->log_func = log_func;
  handler->data = user_data;
  handler->destroy = destroy;
  handler->next = domain->handlers;
  domain->handlers = handler;

  g_mutex_unlock (&g_messages_lock);
  
  return handler_id;
}

/**
 * g_log_set_default_handler:
 * @log_func: the log handler function
 * @user_data: data passed to the log handler
 *
 * Installs a default log handler which is used if no
 * log handler has been set for the particular log domain
 * and log level combination. By default, GLib uses
 * g_log_default_handler() as default log handler.
 *
 * This has no effect if structured logging is enabled; see
 * [Using Structured Logging][using-structured-logging].
 *
 * Returns: the previous default log handler
 *
 * Since: 2.6
 */
GLogFunc
g_log_set_default_handler (GLogFunc log_func,
			   gpointer user_data)
{
  GLogFunc old_log_func;
  
  g_mutex_lock (&g_messages_lock);
  old_log_func = default_log_func;
  default_log_func = log_func;
  default_log_data = user_data;
  g_mutex_unlock (&g_messages_lock);
  
  return old_log_func;
}

/**
 * g_test_log_set_fatal_handler:
 * @log_func: the log handler function.
 * @user_data: data passed to the log handler.
 *
 * Installs a non-error fatal log handler which can be
 * used to decide whether log messages which are counted
 * as fatal abort the program.
 *
 * The use case here is that you are running a test case
 * that depends on particular libraries or circumstances
 * and cannot prevent certain known critical or warning
 * messages. So you install a handler that compares the
 * domain and message to precisely not abort in such a case.
 *
 * Note that the handler is reset at the beginning of
 * any test case, so you have to set it inside each test
 * function which needs the special behavior.
 *
 * This handler has no effect on g_error messages.
 *
 * This handler also has no effect on structured log messages (using
 * g_log_structured() or g_log_structured_array()). To change the fatal
 * behaviour for specific log messages, programs must install a custom log
 * writer function using g_log_set_writer_func().See
 * [Using Structured Logging][using-structured-logging].
 *
 * Since: 2.22
 **/
void
g_test_log_set_fatal_handler (GTestLogFatalFunc log_func,
                              gpointer          user_data)
{
  g_mutex_lock (&g_messages_lock);
  fatal_log_func = log_func;
  fatal_log_data = user_data;
  g_mutex_unlock (&g_messages_lock);
}

/**
 * g_log_remove_handler:
 * @log_domain: the log domain
 * @handler_id: the id of the handler, which was returned
 *     in g_log_set_handler()
 *
 * Removes the log handler.
 *
 * This has no effect if structured logging is enabled; see
 * [Using Structured Logging][using-structured-logging].
 */
void
g_log_remove_handler (const gchar *log_domain,
		      guint	   handler_id)
{
  GLogDomain *domain;
  
  g_return_if_fail (handler_id > 0);
  
  if (!log_domain)
    log_domain = "";
  
  g_mutex_lock (&g_messages_lock);
  domain = g_log_find_domain_L (log_domain);
  if (domain)
    {
      GLogHandler *work, *last;
      
      last = NULL;
      work = domain->handlers;
      while (work)
	{
	  if (work->id == handler_id)
	    {
	      if (last)
		last->next = work->next;
	      else
		domain->handlers = work->next;
	      g_log_domain_check_free_L (domain); 
	      g_mutex_unlock (&g_messages_lock);
              if (work->destroy)
                work->destroy (work->data);
	      g_free (work);
	      return;
	    }
	  last = work;
	  work = last->next;
	}
    } 
  g_mutex_unlock (&g_messages_lock);
  g_warning ("%s: could not find handler with id '%d' for domain \"%s\"",
	     G_STRLOC, handler_id, log_domain);
}

#define CHAR_IS_SAFE(wc) (!((wc < 0x20 && wc != '\t' && wc != '\n' && wc != '\r') || \
			    (wc == 0x7f) || \
			    (wc >= 0x80 && wc < 0xa0)))
     
static gchar*
strdup_convert (const gchar *string,
		const gchar *charset)
{
  if (!g_utf8_validate (string, -1, NULL))
    {
      GString *gstring = g_string_new ("[Invalid UTF-8] ");
      guchar *p;

      for (p = (guchar *)string; *p; p++)
	{
	  if (CHAR_IS_SAFE(*p) &&
	      !(*p == '\r' && *(p + 1) != '\n') &&
	      *p < 0x80)
	    g_string_append_c (gstring, *p);
	  else
	    g_string_append_printf (gstring, "\\x%02x", (guint)(guchar)*p);
	}
      
      return g_string_free (gstring, FALSE);
    }
  else
    {
      GError *err = NULL;
      
      gchar *result = g_convert_with_fallback (string, -1, charset, "UTF-8", "?", NULL, NULL, &err);
      if (result)
	return result;
      else
	{
	  /* Not thread-safe, but doesn't matter if we print the warning twice
	   */
	  static gboolean warned = FALSE; 
	  if (!warned)
	    {
	      warned = TRUE;
	      _g_fprintf (stderr, "GLib: Cannot convert message: %s\n", err->message);
	    }
	  g_error_free (err);
	  
	  return g_strdup (string);
	}
    }
}

/* For a radix of 8 we need at most 3 output bytes for 1 input
 * byte. Additionally we might need up to 2 output bytes for the
 * readix prefix and 1 byte for the trailing NULL.
 */
#define FORMAT_UNSIGNED_BUFSIZE ((GLIB_SIZEOF_LONG * 3) + 3)

static void
format_unsigned (gchar  *buf,
		 gulong  num,
		 guint   radix)
{
  gulong tmp;
  gchar c;
  gint i, n;

  /* we may not call _any_ GLib functions here (or macros like g_return_if_fail()) */

  if (radix != 8 && radix != 10 && radix != 16)
    {
      *buf = '\000';
      return;
    }
  
  if (!num)
    {
      *buf++ = '0';
      *buf = '\000';
      return;
    } 
  
  if (radix == 16)
    {
      *buf++ = '0';
      *buf++ = 'x';
    }
  else if (radix == 8)
    {
      *buf++ = '0';
    }
	
  n = 0;
  tmp = num;
  while (tmp)
    {
      tmp /= radix;
      n++;
    }

  i = n;

  /* Again we can't use g_assert; actually this check should _never_ fail. */
  if (n > FORMAT_UNSIGNED_BUFSIZE - 3)
    {
      *buf = '\000';
      return;
    }

  while (num)
    {
      i--;
      c = (num % radix);
      if (c < 10)
	buf[i] = c + '0';
      else
	buf[i] = c + 'a' - 10;
      num /= radix;
    }
  
  buf[n] = '\000';
}

/* string size big enough to hold level prefix */
#define	STRING_BUFFER_SIZE	(FORMAT_UNSIGNED_BUFSIZE + 32)

#define	ALERT_LEVELS		(G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING)

/* these are emitted by the default log handler */
#define DEFAULT_LEVELS (G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING | G_LOG_LEVEL_MESSAGE)
/* these are filtered by G_MESSAGES_DEBUG by the default log handler */
#define INFO_LEVELS (G_LOG_LEVEL_INFO | G_LOG_LEVEL_DEBUG)

static const gchar *log_level_to_color (GLogLevelFlags log_level,
                                        gboolean       use_color);
static const gchar *color_reset        (gboolean       use_color);

static FILE *
mklevel_prefix (gchar          level_prefix[STRING_BUFFER_SIZE],
                GLogLevelFlags log_level,
                gboolean       use_color)
{
  gboolean to_stdout = TRUE;

  /* we may not call _any_ GLib functions here */

  strcpy (level_prefix, log_level_to_color (log_level, use_color));

  switch (log_level & G_LOG_LEVEL_MASK)
    {
    case G_LOG_LEVEL_ERROR:
      strcat (level_prefix, "ERROR");
      to_stdout = FALSE;
      break;
    case G_LOG_LEVEL_CRITICAL:
      strcat (level_prefix, "CRITICAL");
      to_stdout = FALSE;
      break;
    case G_LOG_LEVEL_WARNING:
      strcat (level_prefix, "WARNING");
      to_stdout = FALSE;
      break;
    case G_LOG_LEVEL_MESSAGE:
      strcat (level_prefix, "Message");
      to_stdout = FALSE;
      break;
    case G_LOG_LEVEL_INFO:
      strcat (level_prefix, "INFO");
      break;
    case G_LOG_LEVEL_DEBUG:
      strcat (level_prefix, "DEBUG");
      break;
    default:
      if (log_level)
	{
	  strcat (level_prefix, "LOG-");
	  format_unsigned (level_prefix + 4, log_level & G_LOG_LEVEL_MASK, 16);
	}
      else
	strcat (level_prefix, "LOG");
      break;
    }

  strcat (level_prefix, color_reset (use_color));

  if (log_level & G_LOG_FLAG_RECURSION)
    strcat (level_prefix, " (recursed)");
  if (log_level & ALERT_LEVELS)
    strcat (level_prefix, " **");

#ifdef G_OS_WIN32
  if ((log_level & G_LOG_FLAG_FATAL) != 0 && !g_test_initialized ())
    win32_keep_fatal_message = TRUE;
#endif
  return to_stdout ? stdout : stderr;
}

typedef struct {
  gchar          *log_domain;
  GLogLevelFlags  log_level;
  gchar          *pattern;
} GTestExpectedMessage;

static GSList *expected_messages = NULL;

/**
 * g_logv:
 * @log_domain: (nullable): the log domain, or %NULL for the default ""
 * application domain
 * @log_level: the log level
 * @format: the message format. See the printf() documentation
 * @args: the parameters to insert into the format string
 *
 * Logs an error or debugging message.
 *
 * If the log level has been set as fatal, G_BREAKPOINT() is called
 * to terminate the program. See the documentation for G_BREAKPOINT() for
 * details of the debugging options this provides.
 *
 * If g_log_default_handler() is used as the log handler function, a new-line
 * character will automatically be appended to @..., and need not be entered
 * manually.
 *
 * If [structured logging is enabled][using-structured-logging] this will
 * output via the structured log writer function (see g_log_set_writer_func()).
 */
void
g_logv (const gchar   *log_domain,
	GLogLevelFlags log_level,
	const gchar   *format,
	va_list	       args)
{
  gboolean was_fatal = (log_level & G_LOG_FLAG_FATAL) != 0;
  gboolean was_recursion = (log_level & G_LOG_FLAG_RECURSION) != 0;
  gchar buffer[1025], *msg, *msg_alloc = NULL;
  gint i;

  log_level &= G_LOG_LEVEL_MASK;
  if (!log_level)
    return;

  if (log_level & G_LOG_FLAG_RECURSION)
    {
      /* we use a stack buffer of fixed size, since we're likely
       * in an out-of-memory situation
       */
      gsize size G_GNUC_UNUSED;

      size = _g_vsnprintf (buffer, 1024, format, args);
      msg = buffer;
    }
  else
    msg = msg_alloc = g_strdup_vprintf (format, args);

  if (expected_messages)
    {
      GTestExpectedMessage *expected = expected_messages->data;

      if (g_strcmp0 (expected->log_domain, log_domain) == 0 &&
          ((log_level & expected->log_level) == expected->log_level) &&
          g_pattern_match_simple (expected->pattern, msg))
        {
          expected_messages = g_slist_delete_link (expected_messages,
                                                   expected_messages);
          g_free (expected->log_domain);
          g_free (expected->pattern);
          g_free (expected);
          g_free (msg_alloc);
          return;
        }
      else if ((log_level & G_LOG_LEVEL_DEBUG) != G_LOG_LEVEL_DEBUG)
        {
          gchar level_prefix[STRING_BUFFER_SIZE];
          gchar *expected_message;

          mklevel_prefix (level_prefix, expected->log_level, FALSE);
          expected_message = g_strdup_printf ("Did not see expected message %s-%s: %s",
                                              expected->log_domain ? expected->log_domain : "**",
                                              level_prefix, expected->pattern);
          g_log_default_handler (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, expected_message, NULL);
          g_free (expected_message);

          log_level |= G_LOG_FLAG_FATAL;
        }
    }

  for (i = g_bit_nth_msf (log_level, -1); i >= 0; i = g_bit_nth_msf (log_level, i))
    {
      GLogLevelFlags test_level;

      test_level = 1L << i;
      if (log_level & test_level)
	{
	  GLogDomain *domain;
	  GLogFunc log_func;
	  GLogLevelFlags domain_fatal_mask;
	  gpointer data = NULL;
          gboolean masquerade_fatal = FALSE;
          guint depth;

	  if (was_fatal)
	    test_level |= G_LOG_FLAG_FATAL;
	  if (was_recursion)
	    test_level |= G_LOG_FLAG_RECURSION;

	  /* check recursion and lookup handler */
	  g_mutex_lock (&g_messages_lock);
          depth = GPOINTER_TO_UINT (g_private_get (&g_log_depth));
	  domain = g_log_find_domain_L (log_domain ? log_domain : "");
	  if (depth)
	    test_level |= G_LOG_FLAG_RECURSION;
	  depth++;
	  domain_fatal_mask = domain ? domain->fatal_mask : G_LOG_FATAL_MASK;
	  if ((domain_fatal_mask | g_log_always_fatal) & test_level)
	    test_level |= G_LOG_FLAG_FATAL;
	  if (test_level & G_LOG_FLAG_RECURSION)
	    log_func = _g_log_fallback_handler;
	  else
	    log_func = g_log_domain_get_handler_L (domain, test_level, &data);
	  domain = NULL;
	  g_mutex_unlock (&g_messages_lock);

	  g_private_set (&g_log_depth, GUINT_TO_POINTER (depth));

          log_func (log_domain, test_level, msg, data);

          if ((test_level & G_LOG_FLAG_FATAL)
              && !(test_level & G_LOG_LEVEL_ERROR))
            {
              masquerade_fatal = fatal_log_func
                && !fatal_log_func (log_domain, test_level, msg, fatal_log_data);
            }

          if ((test_level & G_LOG_FLAG_FATAL) && !masquerade_fatal)
            {
              /* MessageBox is allowed on UWP apps only when building against
               * the debug CRT, which will set -D_DEBUG */
#if defined(G_OS_WIN32) && (defined(_DEBUG) || !defined(G_WINAPI_ONLY_APP))
              if (win32_keep_fatal_message)
                {
                  gchar *locale_msg = g_locale_from_utf8 (fatal_msg_buf, -1, NULL, NULL, NULL);

                  MessageBox (NULL, locale_msg, NULL,
                              MB_ICONERROR|MB_SETFOREGROUND);
                }
#endif

              _g_log_abort (!(test_level & G_LOG_FLAG_RECURSION));
	    }
	  
	  depth--;
	  g_private_set (&g_log_depth, GUINT_TO_POINTER (depth));
	}
    }

  g_free (msg_alloc);
}

/**
 * g_log:
 * @log_domain: (nullable): the log domain, usually #G_LOG_DOMAIN, or %NULL
 * for the default
 * @log_level: the log level, either from #GLogLevelFlags
 *     or a user-defined level
 * @format: the message format. See the printf() documentation
 * @...: the parameters to insert into the format string
 *
 * Logs an error or debugging message.
 *
 * If the log level has been set as fatal, G_BREAKPOINT() is called
 * to terminate the program. See the documentation for G_BREAKPOINT() for
 * details of the debugging options this provides.
 *
 * If g_log_default_handler() is used as the log handler function, a new-line
 * character will automatically be appended to @..., and need not be entered
 * manually.
 *
 * If [structured logging is enabled][using-structured-logging] this will
 * output via the structured log writer function (see g_log_set_writer_func()).
 */
void
g_log (const gchar   *log_domain,
       GLogLevelFlags log_level,
       const gchar   *format,
       ...)
{
  va_list args;
  
  va_start (args, format);
  g_logv (log_domain, log_level, format, args);
  va_end (args);
}

/* Return value must be 1 byte long (plus nul byte).
 * Reference: http://man7.org/linux/man-pages/man3/syslog.3.html#DESCRIPTION
 */
static const gchar *
log_level_to_priority (GLogLevelFlags log_level)
{
  if (log_level & G_LOG_LEVEL_ERROR)
    return "3";
  else if (log_level & G_LOG_LEVEL_CRITICAL)
    return "4";
  else if (log_level & G_LOG_LEVEL_WARNING)
    return "4";
  else if (log_level & G_LOG_LEVEL_MESSAGE)
    return "5";
  else if (log_level & G_LOG_LEVEL_INFO)
    return "6";
  else if (log_level & G_LOG_LEVEL_DEBUG)
    return "7";

  /* Default to LOG_NOTICE for custom log levels. */
  return "5";
}

static FILE *
log_level_to_file (GLogLevelFlags log_level)
{
  if (log_level & (G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL |
                   G_LOG_LEVEL_WARNING | G_LOG_LEVEL_MESSAGE))
    return stderr;
  else
    return stdout;
}

static const gchar *
log_level_to_color (GLogLevelFlags log_level,
                    gboolean       use_color)
{
  /* we may not call _any_ GLib functions here */

  if (!use_color)
    return "";

  if (log_level & G_LOG_LEVEL_ERROR)
    return "\033[1;31m"; /* red */
  else if (log_level & G_LOG_LEVEL_CRITICAL)
    return "\033[1;35m"; /* magenta */
  else if (log_level & G_LOG_LEVEL_WARNING)
    return "\033[1;33m"; /* yellow */
  else if (log_level & G_LOG_LEVEL_MESSAGE)
    return "\033[1;32m"; /* green */
  else if (log_level & G_LOG_LEVEL_INFO)
    return "\033[1;32m"; /* green */
  else if (log_level & G_LOG_LEVEL_DEBUG)
    return "\033[1;32m"; /* green */

  /* No color for custom log levels. */
  return "";
}

static const gchar *
color_reset (gboolean use_color)
{
  /* we may not call _any_ GLib functions here */

  if (!use_color)
    return "";

  return "\033[0m";
}

#ifdef G_OS_WIN32

/* We might be using tty emulators such as mintty, so try to detect it, if we passed in a valid FD
 * so we need to check the name of the pipe if _isatty (fd) == 0
 */

static gboolean
win32_is_pipe_tty (int fd)
{
  gboolean result = FALSE;
  HANDLE h_fd;
  FILE_NAME_INFO *info = NULL;
  gint info_size = sizeof (FILE_NAME_INFO) + sizeof (WCHAR) * MAX_PATH;
  wchar_t *name = NULL;
  gint length;

  h_fd = (HANDLE) _get_osfhandle (fd);

  if (h_fd == INVALID_HANDLE_VALUE || GetFileType (h_fd) != FILE_TYPE_PIPE)
    goto done_query;

  /* mintty uses a pipe, in the form of \{cygwin|msys}-xxxxxxxxxxxxxxxx-ptyN-{from|to}-master */

  info = g_try_malloc (info_size);

  if (info == NULL ||
      !GetFileInformationByHandleEx (h_fd, FileNameInfo, info, info_size))
    goto done_query;

  info->FileName[info->FileNameLength / sizeof (WCHAR)] = L'\0';
  name = info->FileName;

  length = wcslen (L"\\cygwin-");
  if (wcsncmp (name, L"\\cygwin-", length))
    {
      length = wcslen (L"\\msys-");
      if (wcsncmp (name, L"\\msys-", length))
        goto done_query;
    }

  name += length;
  length = wcsspn (name, L"0123456789abcdefABCDEF");
  if (length != 16)
    goto done_query;

  name += length;
  length = wcslen (L"-pty");
  if (wcsncmp (name, L"-pty", length))
    goto done_query;

  name += length;
  length = wcsspn (name, L"0123456789");
  if (length != 1)
    goto done_query;

  name += length;
  length = wcslen (L"-to-master");
  if (wcsncmp (name, L"-to-master", length))
    {
      length = wcslen (L"-from-master");
      if (wcsncmp (name, L"-from-master", length))
        goto done_query;
    }

  result = TRUE;

done_query:
  if (info != NULL)
    g_free (info);

  return result;
}
#endif

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wformat-nonliteral"

/**
 * g_log_structured:
 * @log_domain: log domain, usually %G_LOG_DOMAIN
 * @log_level: log level, either from #GLogLevelFlags, or a user-defined
 *    level
 * @...: key-value pairs of structured data to add to the log entry, followed
 *    by the key "MESSAGE", followed by a printf()-style message format,
 *    followed by parameters to insert in the format string
 *
 * Log a message with structured data. The message will be passed through to
 * the log writer set by the application using g_log_set_writer_func(). If the
 * message is fatal (i.e. its log level is %G_LOG_LEVEL_ERROR), the program will
 * be aborted by calling G_BREAKPOINT() at the end of this function. If the log writer returns
 * %G_LOG_WRITER_UNHANDLED (failure), no other fallback writers will be tried.
 * See the documentation for #GLogWriterFunc for information on chaining
 * writers.
 *
 * The structured data is provided as key–value pairs, where keys are UTF-8
 * strings, and values are arbitrary pointers — typically pointing to UTF-8
 * strings, but that is not a requirement. To pass binary (non-nul-terminated)
 * structured data, use g_log_structured_array(). The keys for structured data
 * should follow the [systemd journal
 * fields](https://www.freedesktop.org/software/systemd/man/systemd.journal-fields.html)
 * specification. It is suggested that custom keys are namespaced according to
 * the code which sets them. For example, custom keys from GLib all have a
 * `GLIB_` prefix.
 *
 * The @log_domain will be converted into a `GLIB_DOMAIN` field. @log_level will
 * be converted into a
 * [`PRIORITY`](https://www.freedesktop.org/software/systemd/man/systemd.journal-fields.html#PRIORITY=)
 * field. The format string will have its placeholders substituted for the provided
 * values and be converted into a
 * [`MESSAGE`](https://www.freedesktop.org/software/systemd/man/systemd.journal-fields.html#MESSAGE=)
 * field.
 *
 * Other fields you may commonly want to pass into this function:
 *
 *  * [`MESSAGE_ID`](https://www.freedesktop.org/software/systemd/man/systemd.journal-fields.html#MESSAGE_ID=)
 *  * [`CODE_FILE`](https://www.freedesktop.org/software/systemd/man/systemd.journal-fields.html#CODE_FILE=)
 *  * [`CODE_LINE`](https://www.freedesktop.org/software/systemd/man/systemd.journal-fields.html#CODE_LINE=)
 *  * [`CODE_FUNC`](https://www.freedesktop.org/software/systemd/man/systemd.journal-fields.html#CODE_FUNC=)
 *  * [`ERRNO`](https://www.freedesktop.org/software/systemd/man/systemd.journal-fields.html#ERRNO=)
 *
 * Note that `CODE_FILE`, `CODE_LINE` and `CODE_FUNC` are automatically set by
 * the logging macros, G_DEBUG_HERE(), g_message(), g_warning(), g_critical(),
 * g_error(), etc, if the symbols `G_LOG_USE_STRUCTURED` is defined before including
 * glib.h.
 *
 * For example:
 * |[<!-- language="C" -->
 * g_log_structured (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG,
 *                   "MESSAGE_ID", "06d4df59e6c24647bfe69d2c27ef0b4e",
 *                   "MY_APPLICATION_CUSTOM_FIELD", "some debug string",
 *                   "MESSAGE", "This is a debug message about pointer %p and integer %u.",
 *                   some_pointer, some_integer);
 * ]|
 *
 * Note that each `MESSAGE_ID` must be [uniquely and randomly
 * generated](https://www.freedesktop.org/software/systemd/man/systemd.journal-fields.html#MESSAGE_ID=).
 * If adding a `MESSAGE_ID`, consider shipping a [message
 * catalog](https://www.freedesktop.org/wiki/Software/systemd/catalog/) with
 * your software.
 *
 * To pass a user data pointer to the log writer function which is specific to
 * this logging call, you must use g_log_structured_array() and pass the pointer
 * as a field with #GLogField.length set to zero, otherwise it will be
 * interpreted as a string.
 *
 * For example:
 * |[<!-- language="C" -->
 * const GLogField fields[] = {
 *   { "MESSAGE", "This is a debug message.", -1 },
 *   { "MESSAGE_ID", "fcfb2e1e65c3494386b74878f1abf893", -1 },
 *   { "MY_APPLICATION_CUSTOM_FIELD", "some debug string", -1 },
 *   { "MY_APPLICATION_STATE", state_object, 0 },
 * };
 * g_log_structured_array (G_LOG_LEVEL_DEBUG, fields, G_N_ELEMENTS (fields));
 * ]|
 *
 * Note also that, even if no other structured fields are specified, there
 * must always be a `MESSAGE` key before the format string. The `MESSAGE`-format
 * pair has to be the last of the key-value pairs, and `MESSAGE` is the only
 * field for which printf()-style formatting is supported.
 *
 * The default writer function for `stdout` and `stderr` will automatically
 * append a new-line character after the message, so you should not add one
 * manually to the format string.
 *
 * Since: 2.50
 */
void
g_log_structured (const gchar    *log_domain,
                  GLogLevelFlags  log_level,
                  ...)
{
  va_list args;
  gchar buffer[1025], *message_allocated = NULL;
  const char *format;
  const gchar *message;
  gpointer p;
  gsize n_fields, i;
  GLogField stack_fields[16];
  GLogField *fields = stack_fields;
  GLogField *fields_allocated = NULL;
  GArray *array = NULL;

  va_start (args, log_level);

  /* MESSAGE and PRIORITY are a given */
  n_fields = 2;

  if (log_domain)
    n_fields++;

  for (p = va_arg (args, gchar *), i = n_fields;
       strcmp (p, "MESSAGE") != 0;
       p = va_arg (args, gchar *), i++)
    {
      GLogField field;
      const gchar *key = p;
      gconstpointer value = va_arg (args, gpointer);

      field.key = key;
      field.value = value;
      field.length = -1;

      if (i < 16)
        stack_fields[i] = field;
      else
        {
          /* Don't allow dynamic allocation, since we're likely
           * in an out-of-memory situation. For lack of a better solution,
           * just ignore further key-value pairs.
           */
          if (log_level & G_LOG_FLAG_RECURSION)
            continue;

          if (i == 16)
            {
              array = g_array_sized_new (FALSE, FALSE, sizeof (GLogField), 32);
              g_array_append_vals (array, stack_fields, 16);
            }

          g_array_append_val (array, field);
        }
    }

  n_fields = i;

  if (array)
    fields = fields_allocated = (GLogField *) g_array_free (array, FALSE);

  format = va_arg (args, gchar *);

  if (log_level & G_LOG_FLAG_RECURSION)
    {
      /* we use a stack buffer of fixed size, since we're likely
       * in an out-of-memory situation
       */
      gsize size G_GNUC_UNUSED;

      size = _g_vsnprintf (buffer, sizeof (buffer), format, args);
      message = buffer;
    }
  else
    {
      message = message_allocated = g_strdup_vprintf (format, args);
    }

  /* Add MESSAGE, PRIORITY and GLIB_DOMAIN. */
  fields[0].key = "MESSAGE";
  fields[0].value = message;
  fields[0].length = -1;

  fields[1].key = "PRIORITY";
  fields[1].value = log_level_to_priority (log_level);
  fields[1].length = -1;

  if (log_domain)
    {
      fields[2].key = "GLIB_DOMAIN";
      fields[2].value = log_domain;
      fields[2].length = -1;
    }

  /* Log it. */
  g_log_structured_array (log_level, fields, n_fields);

  g_free (fields_allocated);
  g_free (message_allocated);

  va_end (args);
}

/**
 * g_log_variant:
 * @log_domain: (nullable): log domain, usually %G_LOG_DOMAIN
 * @log_level: log level, either from #GLogLevelFlags, or a user-defined
 *    level
 * @fields: a dictionary (#GVariant of the type %G_VARIANT_TYPE_VARDICT)
 * containing the key-value pairs of message data.
 *
 * Log a message with structured data, accepting the data within a #GVariant. This
 * version is especially useful for use in other languages, via introspection.
 *
 * The only mandatory item in the @fields dictionary is the "MESSAGE" which must
 * contain the text shown to the user.
 *
 * The values in the @fields dictionary are likely to be of type String
 * (#G_VARIANT_TYPE_STRING). Array of bytes (#G_VARIANT_TYPE_BYTESTRING) is also
 * supported. In this case the message is handled as binary and will be forwarded
 * to the log writer as such. The size of the array should not be higher than
 * %G_MAXSSIZE. Otherwise it will be truncated to this size. For other types
 * g_variant_print() will be used to convert the value into a string.
 *
 * For more details on its usage and about the parameters, see g_log_structured().
 *
 * Since: 2.50
 */

void
g_log_variant (const gchar    *log_domain,
               GLogLevelFlags  log_level,
               GVariant       *fields)
{
  GVariantIter iter;
  GVariant *value;
  gchar *key;
  GArray *fields_array;
  GLogField field;
  GSList *values_list, *print_list;

  g_return_if_fail (g_variant_is_of_type (fields, G_VARIANT_TYPE_VARDICT));

  values_list = print_list = NULL;
  fields_array = g_array_new (FALSE, FALSE, sizeof (GLogField));

  field.key = "PRIORITY";
  field.value = log_level_to_priority (log_level);
  field.length = -1;
  g_array_append_val (fields_array, field);

  if (log_domain)
    {
      field.key = "GLIB_DOMAIN";
      field.value = log_domain;
      field.length = -1;
      g_array_append_val (fields_array, field);
    }

  g_variant_iter_init (&iter, fields);
  while (g_variant_iter_next (&iter, "{&sv}", &key, &value))
    {
      gboolean defer_unref = TRUE;

      field.key = key;
      field.length = -1;

      if (g_variant_is_of_type (value, G_VARIANT_TYPE_STRING))
        {
          field.value = g_variant_get_string (value, NULL);
        }
      else if (g_variant_is_of_type (value, G_VARIANT_TYPE_BYTESTRING))
        {
          gsize s;
          field.value = g_variant_get_fixed_array (value, &s, sizeof (guchar));
          if (G_LIKELY (s <= G_MAXSSIZE))
            {
              field.length = s;
            }
          else
            {
               _g_fprintf (stderr,
                           "Byte array too large (%" G_GSIZE_FORMAT " bytes)"
                           " passed to g_log_variant(). Truncating to " G_STRINGIFY (G_MAXSSIZE)
                           " bytes.", s);
              field.length = G_MAXSSIZE;
            }
        }
      else
        {
          char *s = g_variant_print (value, FALSE);
          field.value = s;
          print_list = g_slist_prepend (print_list, s);
          defer_unref = FALSE;
        }

      g_array_append_val (fields_array, field);

      if (G_LIKELY (defer_unref))
        values_list = g_slist_prepend (values_list, value);
      else
        g_variant_unref (value);
    }

  /* Log it. */
  g_log_structured_array (log_level, (GLogField *) fields_array->data, fields_array->len);

  g_array_free (fields_array, TRUE);
  g_slist_free_full (values_list, (GDestroyNotify) g_variant_unref);
  g_slist_free_full (print_list, g_free);
}


#pragma GCC diagnostic pop

static GLogWriterOutput _g_log_writer_fallback (GLogLevelFlags   log_level,
                                                const GLogField *fields,
                                                gsize            n_fields,
                                                gpointer         user_data);

/**
 * g_log_structured_array:
 * @log_level: log level, either from #GLogLevelFlags, or a user-defined
 *    level
 * @fields: (array length=n_fields): key–value pairs of structured data to add
 *    to the log message
 * @n_fields: number of elements in the @fields array
 *
 * Log a message with structured data. The message will be passed through to the
 * log writer set by the application using g_log_set_writer_func(). If the
 * message is fatal (i.e. its log level is %G_LOG_LEVEL_ERROR), the program will
 * be aborted at the end of this function.
 *
 * See g_log_structured() for more documentation.
 *
 * This assumes that @log_level is already present in @fields (typically as the
 * `PRIORITY` field).
 *
 * Since: 2.50
 */
void
g_log_structured_array (GLogLevelFlags   log_level,
                        const GLogField *fields,
                        gsize            n_fields)
{
  GLogWriterFunc writer_func;
  gpointer writer_user_data;
  gboolean recursion;
  guint depth;

  if (n_fields == 0)
    return;

  /* Check for recursion and look up the writer function. */
  depth = GPOINTER_TO_UINT (g_private_get (&g_log_structured_depth));
  recursion = (depth > 0);

  g_mutex_lock (&g_messages_lock);

  writer_func = recursion ? _g_log_writer_fallback : log_writer_func;
  writer_user_data = log_writer_user_data;

  g_mutex_unlock (&g_messages_lock);

  /* Write the log entry. */
  g_private_set (&g_log_structured_depth, GUINT_TO_POINTER (++depth));

  g_assert (writer_func != NULL);
  writer_func (log_level, fields, n_fields, writer_user_data);

  g_private_set (&g_log_structured_depth, GUINT_TO_POINTER (--depth));

  /* Abort if the message was fatal. */
  if (log_level & G_LOG_FATAL_MASK)
    _g_log_abort (!(log_level & G_LOG_FLAG_RECURSION));
}

/* Semi-private helper function to implement the g_message() (etc.) macros
 * with support for G_GNUC_PRINTF so that @message_format can be checked
 * with -Wformat. */
void
g_log_structured_standard (const gchar    *log_domain,
                           GLogLevelFlags  log_level,
                           const gchar    *file,
                           const gchar    *line,
                           const gchar    *func,
                           const gchar    *message_format,
                           ...)
{
  GLogField fields[] =
    {
      { "PRIORITY", log_level_to_priority (log_level), -1 },
      { "CODE_FILE", file, -1 },
      { "CODE_LINE", line, -1 },
      { "CODE_FUNC", func, -1 },
      /* Filled in later: */
      { "MESSAGE", NULL, -1 },
      /* If @log_domain is %NULL, we will not pass this field: */
      { "GLIB_DOMAIN", log_domain, -1 },
    };
  gsize n_fields;
  gchar *message_allocated = NULL;
  gchar buffer[1025];
  va_list args;

  va_start (args, message_format);

  if (log_level & G_LOG_FLAG_RECURSION)
    {
      /* we use a stack buffer of fixed size, since we're likely
       * in an out-of-memory situation
       */
      gsize size G_GNUC_UNUSED;

      size = _g_vsnprintf (buffer, sizeof (buffer), message_format, args);
      fields[4].value = buffer;
    }
  else
    {
      fields[4].value = message_allocated = g_strdup_vprintf (message_format, args);
    }

  va_end (args);

  n_fields = G_N_ELEMENTS (fields) - ((log_domain == NULL) ? 1 : 0);
  g_log_structured_array (log_level, fields, n_fields);

  g_free (message_allocated);
}

/**
 * g_log_set_writer_func:
 * @func: log writer function, which must not be %NULL
 * @user_data: (closure func): user data to pass to @func
 * @user_data_free: (destroy func): function to free @user_data once it’s
 *    finished with, if non-%NULL
 *
 * Set a writer function which will be called to format and write out each log
 * message. Each program should set a writer function, or the default writer
 * (g_log_writer_default()) will be used.
 *
 * Libraries **must not** call this function — only programs are allowed to
 * install a writer function, as there must be a single, central point where
 * log messages are formatted and outputted.
 *
 * There can only be one writer function. It is an error to set more than one.
 *
 * Since: 2.50
 */
void
g_log_set_writer_func (GLogWriterFunc func,
                       gpointer       user_data,
                       GDestroyNotify user_data_free)
{
  g_return_if_fail (func != NULL);

  g_mutex_lock (&g_messages_lock);
  log_writer_func = func;
  log_writer_user_data = user_data;
  log_writer_user_data_free = user_data_free;
  g_mutex_unlock (&g_messages_lock);
}

/**
 * g_log_writer_supports_color:
 * @output_fd: output file descriptor to check
 *
 * Check whether the given @output_fd file descriptor supports ANSI color
 * escape sequences. If so, they can safely be used when formatting log
 * messages.
 *
 * Returns: %TRUE if ANSI color escapes are supported, %FALSE otherwise
 * Since: 2.50
 */
gboolean
g_log_writer_supports_color (gint output_fd)
{
#ifdef G_OS_WIN32
  gboolean result = FALSE;

#if (defined (_MSC_VER) && _MSC_VER >= 1400)
  _invalid_parameter_handler oldHandler, newHandler;
  int prev_report_mode = 0;
#endif

#endif

  g_return_val_if_fail (output_fd >= 0, FALSE);

  /* FIXME: This check could easily be expanded in future to be more robust
   * against different types of terminal, which still vary in their color
   * support. cmd.exe on Windows, for example, supports ANSI colors only
   * from Windows 10 onwards; bash on Windows has always supported ANSI colors.
   * The Windows 10 color support is supported on:
   * -Output in the cmd.exe, MSYS/Cygwin standard consoles.
   * -Output in the cmd.exe, MSYS/Cygwin piped to the less program.
   * but not:
   * -Output in Cygwin via mintty (https://github.com/mintty/mintty/issues/482)
   * -Color code output when output redirected to file (i.e. program 2> some.txt)
   *
   * On UNIX systems, we probably want to use the functions from terminfo to
   * work out whether colors are supported.
   *
   * Some examples:
   *  - https://github.com/chalk/supports-color/blob/9434c93918301a6b47faa01999482adfbf1b715c/index.js#L61
   *  - http://stackoverflow.com/questions/16755142/how-to-make-win32-console-recognize-ansi-vt100-escape-sequences
   *  - http://blog.mmediasys.com/2010/11/24/we-all-love-colors/
   *  - http://unix.stackexchange.com/questions/198794/where-does-the-term-environment-variable-default-get-set
   */
#ifdef G_OS_WIN32

#if (defined (_MSC_VER) && _MSC_VER >= 1400)
  /* Set up our empty invalid parameter handler, for isatty(),
   * in case of bad fd's passed in for isatty(), so that
   * msvcrt80.dll+ won't abort the program
   */
  newHandler = myInvalidParameterHandler;
  oldHandler = _set_invalid_parameter_handler (newHandler);

  /* Disable the message box for assertions. */
  prev_report_mode = _CrtSetReportMode(_CRT_ASSERT, 0);
#endif

  if (g_win32_check_windows_version (10, 0, 0, G_WIN32_OS_ANY))
    {
      HANDLE h_output;
      DWORD dw_mode;

      if (_isatty (output_fd))
        {
          h_output = (HANDLE) _get_osfhandle (output_fd);

          if (!GetConsoleMode (h_output, &dw_mode))
            goto reset_invalid_param_handler;

          if (dw_mode & ENABLE_VIRTUAL_TERMINAL_PROCESSING)
            result = TRUE;

          if (!SetConsoleMode (h_output, dw_mode | ENABLE_VIRTUAL_TERMINAL_PROCESSING))
            goto reset_invalid_param_handler;

          result = TRUE;
        }
    }

  /* FIXME: Support colored outputs for structured logs for pre-Windows 10,
   *        perhaps using WriteConsoleOutput or SetConsoleTextAttribute
   *        (bug 775468), on standard Windows consoles, such as cmd.exe
   */
  if (!result)
    result = win32_is_pipe_tty (output_fd);

reset_invalid_param_handler:
#if defined (_MSC_VER) && (_MSC_VER >= 1400)
      _CrtSetReportMode(_CRT_ASSERT, prev_report_mode);
      _set_invalid_parameter_handler (oldHandler);
#endif

  return result;
#else
  return isatty (output_fd);
#endif
}

#if defined(__linux__) && !defined(__BIONIC__)
static int journal_fd = -1;

#ifndef SOCK_CLOEXEC
#define SOCK_CLOEXEC 0
#else
#define HAVE_SOCK_CLOEXEC 1
#endif

static void
open_journal (void)
{
  if ((journal_fd = socket (AF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC, 0)) < 0)
    return;

#ifndef HAVE_SOCK_CLOEXEC
  if (fcntl (journal_fd, F_SETFD, FD_CLOEXEC) < 0)
    {
      close (journal_fd);
      journal_fd = -1;
    }
#endif
}
#endif

/**
 * g_log_writer_is_journald:
 * @output_fd: output file descriptor to check
 *
 * Check whether the given @output_fd file descriptor is a connection to the
 * systemd journal, or something else (like a log file or `stdout` or
 * `stderr`).
 *
 * Invalid file descriptors are accepted and return %FALSE, which allows for
 * the following construct without needing any additional error handling:
 * |[<!-- language="C" -->
 *   is_journald = g_log_writer_is_journald (fileno (stderr));
 * ]|
 *
 * Returns: %TRUE if @output_fd points to the journal, %FALSE otherwise
 * Since: 2.50
 */
gboolean
g_log_writer_is_journald (gint output_fd)
{
#if defined(__linux__) && !defined(__BIONIC__)
  /* FIXME: Use the new journal API for detecting whether we’re writing to the
   * journal. See: https://github.com/systemd/systemd/issues/2473
   */
  union {
    struct sockaddr_storage storage;
    struct sockaddr sa;
    struct sockaddr_un un;
  } addr;
  socklen_t addr_len;
  int err;

  if (output_fd < 0)
    return FALSE;

  addr_len = sizeof(addr);
  err = getpeername (output_fd, &addr.sa, &addr_len);
  if (err == 0 && addr.storage.ss_family == AF_UNIX)
    return g_str_has_prefix (addr.un.sun_path, "/run/systemd/journal/");
#endif

  return FALSE;
}

static void escape_string (GString *string);

/**
 * g_log_writer_format_fields:
 * @log_level: log level, either from #GLogLevelFlags, or a user-defined
 *    level
 * @fields: (array length=n_fields): key–value pairs of structured data forming
 *    the log message
 * @n_fields: number of elements in the @fields array
 * @use_color: %TRUE to use ANSI color escape sequences when formatting the
 *    message, %FALSE to not
 *
 * Format a structured log message as a string suitable for outputting to the
 * terminal (or elsewhere). This will include the values of all fields it knows
 * how to interpret, which includes `MESSAGE` and `GLIB_DOMAIN` (see the
 * documentation for g_log_structured()). It does not include values from
 * unknown fields.
 *
 * The returned string does **not** have a trailing new-line character. It is
 * encoded in the character set of the current locale, which is not necessarily
 * UTF-8.
 *
 * Returns: (transfer full): string containing the formatted log message, in
 *    the character set of the current locale
 * Since: 2.50
 */
gchar *
g_log_writer_format_fields (GLogLevelFlags   log_level,
                            const GLogField *fields,
                            gsize            n_fields,
                            gboolean         use_color)
{
  gsize i;
  const gchar *message = NULL;
  const gchar *log_domain = NULL;
  gchar level_prefix[STRING_BUFFER_SIZE];
  GString *gstring;
  gint64 now;
  time_t now_secs;
  struct tm *now_tm;
  gchar time_buf[128];

  /* Extract some common fields. */
  for (i = 0; (message == NULL || log_domain == NULL) && i < n_fields; i++)
    {
      const GLogField *field = &fields[i];

      if (g_strcmp0 (field->key, "MESSAGE") == 0)
        message = field->value;
      else if (g_strcmp0 (field->key, "GLIB_DOMAIN") == 0)
        log_domain = field->value;
    }

  /* Format things. */
  mklevel_prefix (level_prefix, log_level, use_color);

  gstring = g_string_new (NULL);
  if (log_level & ALERT_LEVELS)
    g_string_append (gstring, "\n");
  if (!log_domain)
    g_string_append (gstring, "** ");

  if ((g_log_msg_prefix & (log_level & G_LOG_LEVEL_MASK)) ==
      (log_level & G_LOG_LEVEL_MASK))
    {
      const gchar *prg_name = g_get_prgname ();
      gulong pid = getpid ();

      if (prg_name == NULL)
        g_string_append_printf (gstring, "(process:%lu): ", pid);
      else
        g_string_append_printf (gstring, "(%s:%lu): ", prg_name, pid);
    }

  if (log_domain != NULL)
    {
      g_string_append (gstring, log_domain);
      g_string_append_c (gstring, '-');
    }
  g_string_append (gstring, level_prefix);

  g_string_append (gstring, ": ");

  /* Timestamp */
  now = g_get_real_time ();
  now_secs = (time_t) (now / 1000000);
  now_tm = localtime (&now_secs);
  strftime (time_buf, sizeof (time_buf), "%H:%M:%S", now_tm);

  g_string_append_printf (gstring, "%s%s.%03d%s: ",
                          use_color ? "\033[34m" : "",
                          time_buf, (gint) ((now / 1000) % 1000),
                          color_reset (use_color));

  if (message == NULL)
    {
      g_string_append (gstring, "(NULL) message");
    }
  else
    {
      GString *msg;
      const gchar *charset;

      msg = g_string_new (message);
      escape_string (msg);

      if (g_get_console_charset (&charset))
        {
          /* charset is UTF-8 already */
          g_string_append (gstring, msg->str);
        }
      else
        {
          gchar *lstring = strdup_convert (msg->str, charset);
          g_string_append (gstring, lstring);
          g_free (lstring);
        }

      g_string_free (msg, TRUE);
    }

  return g_string_free (gstring, FALSE);
}

/* Enable support for the journal if we're on a recent enough Linux */
#if defined(__linux__) && !defined(__BIONIC__) && defined(HAVE_MKOSTEMP) && defined(O_CLOEXEC)
#define ENABLE_JOURNAL_SENDV
#endif

#ifdef ENABLE_JOURNAL_SENDV
static int
journal_sendv (struct iovec *iov,
               gsize         iovlen)
{
  int buf_fd = -1;
  struct msghdr mh;
  struct sockaddr_un sa;
  union {
    struct cmsghdr cmsghdr;
    guint8 buf[CMSG_SPACE(sizeof(int))];
  } control;
  struct cmsghdr *cmsg;
  char path[] = "/dev/shm/journal.XXXXXX";

  if (journal_fd < 0)
    open_journal ();

  if (journal_fd < 0)
    return -1;

  memset (&sa, 0, sizeof (sa));
  sa.sun_family = AF_UNIX;
  if (g_strlcpy (sa.sun_path, "/run/systemd/journal/socket", sizeof (sa.sun_path)) >= sizeof (sa.sun_path))
    return -1;

  memset (&mh, 0, sizeof (mh));
  mh.msg_name = &sa;
  mh.msg_namelen = offsetof (struct sockaddr_un, sun_path) + strlen (sa.sun_path);
  mh.msg_iov = iov;
  mh.msg_iovlen = iovlen;

retry:
  if (sendmsg (journal_fd, &mh, MSG_NOSIGNAL) >= 0)
    return 0;

  if (errno == EINTR)
    goto retry;

  if (errno != EMSGSIZE && errno != ENOBUFS)
    return -1;

  /* Message was too large, so dump to temporary file
   * and pass an FD to the journal
   */
  if ((buf_fd = mkostemp (path, O_CLOEXEC|O_RDWR)) < 0)
    return -1;

  if (unlink (path) < 0)
    {
      close (buf_fd);
      return -1;
    }

  if (writev (buf_fd, iov, iovlen) < 0)
    {
      close (buf_fd);
      return -1;
    }

  mh.msg_iov = NULL;
  mh.msg_iovlen = 0;

  memset (&control, 0, sizeof (control));
  mh.msg_control = &control;
  mh.msg_controllen = sizeof (control);

  cmsg = CMSG_FIRSTHDR (&mh);
  cmsg->cmsg_level = SOL_SOCKET;
  cmsg->cmsg_type = SCM_RIGHTS;
  cmsg->cmsg_len = CMSG_LEN (sizeof (int));
  memcpy (CMSG_DATA (cmsg), &buf_fd, sizeof (int));

  mh.msg_controllen = cmsg->cmsg_len;

retry2:
  if (sendmsg (journal_fd, &mh, MSG_NOSIGNAL) >= 0)
    return 0;

  if (errno == EINTR)
    goto retry2;

  return -1;
}
#endif /* ENABLE_JOURNAL_SENDV */

/**
 * g_log_writer_journald:
 * @log_level: log level, either from #GLogLevelFlags, or a user-defined
 *    level
 * @fields: (array length=n_fields): key–value pairs of structured data forming
 *    the log message
 * @n_fields: number of elements in the @fields array
 * @user_data: user data passed to g_log_set_writer_func()
 *
 * Format a structured log message and send it to the systemd journal as a set
 * of key–value pairs. All fields are sent to the journal, but if a field has
 * length zero (indicating program-specific data) then only its key will be
 * sent.
 *
 * This is suitable for use as a #GLogWriterFunc.
 *
 * If GLib has been compiled without systemd support, this function is still
 * defined, but will always return %G_LOG_WRITER_UNHANDLED.
 *
 * Returns: %G_LOG_WRITER_HANDLED on success, %G_LOG_WRITER_UNHANDLED otherwise
 * Since: 2.50
 */
GLogWriterOutput
g_log_writer_journald (GLogLevelFlags   log_level,
                       const GLogField *fields,
                       gsize            n_fields,
                       gpointer         user_data)
{
#ifdef ENABLE_JOURNAL_SENDV
  const char equals = '=';
  const char newline = '\n';
  gsize i, k;
  struct iovec *iov, *v;
  char *buf;
  gint retval;

  g_return_val_if_fail (fields != NULL, G_LOG_WRITER_UNHANDLED);
  g_return_val_if_fail (n_fields > 0, G_LOG_WRITER_UNHANDLED);

  /* According to systemd.journal-fields(7), the journal allows fields in any
   * format (including arbitrary binary), but expects text fields to be UTF-8.
   * This is great, because we require input strings to be in UTF-8, so no
   * conversion is necessary and we don’t need to care about the current
   * locale’s character set.
   */

  iov = g_alloca (sizeof (struct iovec) * 5 * n_fields);
  buf = g_alloca (32 * n_fields);

  k = 0;
  v = iov;
  for (i = 0; i < n_fields; i++)
    {
      guint64 length;
      gboolean binary;

      if (fields[i].length < 0)
        {
          length = strlen (fields[i].value);
          binary = strchr (fields[i].value, '\n') != NULL;
        }
      else
        {
          length = fields[i].length;
          binary = TRUE;
        }

      if (binary)
        {
          guint64 nstr;

          v[0].iov_base = (gpointer)fields[i].key;
          v[0].iov_len = strlen (fields[i].key);

          v[1].iov_base = (gpointer)&newline;
          v[1].iov_len = 1;

          nstr = GUINT64_TO_LE(length);
          memcpy (&buf[k], &nstr, sizeof (nstr));

          v[2].iov_base = &buf[k];
          v[2].iov_len = sizeof (nstr);
          v += 3;
          k += sizeof (nstr);
        }
      else
        {
          v[0].iov_base = (gpointer)fields[i].key;
          v[0].iov_len = strlen (fields[i].key);

          v[1].iov_base = (gpointer)&equals;
          v[1].iov_len = 1;
          v += 2;
        }

      v[0].iov_base = (gpointer)fields[i].value;
      v[0].iov_len = length;

      v[1].iov_base = (gpointer)&newline;
      v[1].iov_len = 1;
      v += 2;
    }

  retval = journal_sendv (iov, v - iov);

  return retval == 0 ? G_LOG_WRITER_HANDLED : G_LOG_WRITER_UNHANDLED;
#else
  return G_LOG_WRITER_UNHANDLED;
#endif /* ENABLE_JOURNAL_SENDV */
}

/**
 * g_log_writer_standard_streams:
 * @log_level: log level, either from #GLogLevelFlags, or a user-defined
 *    level
 * @fields: (array length=n_fields): key–value pairs of structured data forming
 *    the log message
 * @n_fields: number of elements in the @fields array
 * @user_data: user data passed to g_log_set_writer_func()
 *
 * Format a structured log message and print it to either `stdout` or `stderr`,
 * depending on its log level. %G_LOG_LEVEL_INFO and %G_LOG_LEVEL_DEBUG messages
 * are sent to `stdout`; all other log levels are sent to `stderr`. Only fields
 * which are understood by this function are included in the formatted string
 * which is printed.
 *
 * If the output stream supports ANSI color escape sequences, they will be used
 * in the output.
 *
 * A trailing new-line character is added to the log message when it is printed.
 *
 * This is suitable for use as a #GLogWriterFunc.
 *
 * Returns: %G_LOG_WRITER_HANDLED on success, %G_LOG_WRITER_UNHANDLED otherwise
 * Since: 2.50
 */
GLogWriterOutput
g_log_writer_standard_streams (GLogLevelFlags   log_level,
                               const GLogField *fields,
                               gsize            n_fields,
                               gpointer         user_data)
{
  FILE *stream;
  gchar *out = NULL;  /* in the current locale’s character set */

  g_return_val_if_fail (fields != NULL, G_LOG_WRITER_UNHANDLED);
  g_return_val_if_fail (n_fields > 0, G_LOG_WRITER_UNHANDLED);

  stream = log_level_to_file (log_level);
  if (!stream || fileno (stream) < 0)
    return G_LOG_WRITER_UNHANDLED;

  out = g_log_writer_format_fields (log_level, fields, n_fields,
                                    g_log_writer_supports_color (fileno (stream)));
  _g_fprintf (stream, "%s\n", out);
  fflush (stream);
  g_free (out);

  return G_LOG_WRITER_HANDLED;
}

/* The old g_log() API is implemented in terms of the new structured log API.
 * However, some of the checks do not line up between the two APIs: the
 * structured API only handles fatalness of messages for log levels; the old API
 * handles it per-domain as well. Consequently, we need to disable fatalness
 * handling in the structured log API when called from the old g_log() API.
 *
 * We can guarantee that g_log_default_handler() will pass GLIB_OLD_LOG_API as
 * the first field to g_log_structured_array(), if that is the case.
 */
static gboolean
log_is_old_api (const GLogField *fields,
                gsize            n_fields)
{
  return (n_fields >= 1 &&
          g_strcmp0 (fields[0].key, "GLIB_OLD_LOG_API") == 0 &&
          g_strcmp0 (fields[0].value, "1") == 0);
}

/**
 * g_log_writer_default:
 * @log_level: log level, either from #GLogLevelFlags, or a user-defined
 *    level
 * @fields: (array length=n_fields): key–value pairs of structured data forming
 *    the log message
 * @n_fields: number of elements in the @fields array
 * @user_data: user data passed to g_log_set_writer_func()
 *
 * Format a structured log message and output it to the default log destination
 * for the platform. On Linux, this is typically the systemd journal, falling
 * back to `stdout` or `stderr` if running from the terminal or if output is
 * being redirected to a file.
 *
 * Support for other platform-specific logging mechanisms may be added in
 * future. Distributors of GLib may modify this function to impose their own
 * (documented) platform-specific log writing policies.
 *
 * This is suitable for use as a #GLogWriterFunc, and is the default writer used
 * if no other is set using g_log_set_writer_func().
 *
 * As with g_log_default_handler(), this function drops debug and informational
 * messages unless their log domain (or `all`) is listed in the space-separated
 * `G_MESSAGES_DEBUG` environment variable.
 *
 * Returns: %G_LOG_WRITER_HANDLED on success, %G_LOG_WRITER_UNHANDLED otherwise
 * Since: 2.50
 */
GLogWriterOutput
g_log_writer_default (GLogLevelFlags   log_level,
                      const GLogField *fields,
                      gsize            n_fields,
                      gpointer         user_data)
{
  static gsize initialized = 0;
  static gboolean stderr_is_journal = FALSE;

  g_return_val_if_fail (fields != NULL, G_LOG_WRITER_UNHANDLED);
  g_return_val_if_fail (n_fields > 0, G_LOG_WRITER_UNHANDLED);

  /* Disable debug message output unless specified in G_MESSAGES_DEBUG. */
  if (!(log_level & DEFAULT_LEVELS) && !(log_level >> G_LOG_LEVEL_USER_SHIFT))
    {
      const gchar *domains, *log_domain = NULL;
      gsize i;

      domains = g_getenv ("G_MESSAGES_DEBUG");

      if ((log_level & INFO_LEVELS) == 0 ||
          domains == NULL)
        return G_LOG_WRITER_HANDLED;

      for (i = 0; i < n_fields; i++)
        {
          if (g_strcmp0 (fields[i].key, "GLIB_DOMAIN") == 0)
            {
              log_domain = fields[i].value;
              break;
            }
        }

      if (strcmp (domains, "all") != 0 &&
          (log_domain == NULL || !strstr (domains, log_domain)))
        return G_LOG_WRITER_HANDLED;
    }

  /* Mark messages as fatal if they have a level set in
   * g_log_set_always_fatal().
   */
  if ((log_level & g_log_always_fatal) && !log_is_old_api (fields, n_fields))
    log_level |= G_LOG_FLAG_FATAL;

  /* Try logging to the systemd journal as first choice. */
  if (g_once_init_enter (&initialized))
    {
      stderr_is_journal = g_log_writer_is_journald (fileno (stderr));
      g_once_init_leave (&initialized, TRUE);
    }

  if (stderr_is_journal &&
      g_log_writer_journald (log_level, fields, n_fields, user_data) ==
      G_LOG_WRITER_HANDLED)
    goto handled;

  /* FIXME: Add support for the Windows log. */

  if (g_log_writer_standard_streams (log_level, fields, n_fields, user_data) ==
      G_LOG_WRITER_HANDLED)
    goto handled;

  return G_LOG_WRITER_UNHANDLED;

handled:
  /* Abort if the message was fatal. */
  if (log_level & G_LOG_FLAG_FATAL)
    {
      /* MessageBox is allowed on UWP apps only when building against
       * the debug CRT, which will set -D_DEBUG */
#if defined(G_OS_WIN32) && (defined(_DEBUG) || !defined(G_WINAPI_ONLY_APP))
      if (!g_test_initialized ())
        {
          gchar *locale_msg = NULL;

          locale_msg = g_locale_from_utf8 (fatal_msg_buf, -1, NULL, NULL, NULL);
          MessageBox (NULL, locale_msg, NULL,
                      MB_ICONERROR | MB_SETFOREGROUND);
          g_free (locale_msg);
        }
#endif /* !G_OS_WIN32 */

      _g_log_abort (!(log_level & G_LOG_FLAG_RECURSION));
    }

  return G_LOG_WRITER_HANDLED;
}

static GLogWriterOutput
_g_log_writer_fallback (GLogLevelFlags   log_level,
                        const GLogField *fields,
                        gsize            n_fields,
                        gpointer         user_data)
{
  FILE *stream;
  gsize i;

  /* we cannot call _any_ GLib functions in this fallback handler,
   * which is why we skip UTF-8 conversion, etc.
   * since we either recursed or ran out of memory, we're in a pretty
   * pathologic situation anyways, what we can do is giving the
   * the process ID unconditionally however.
   */

  stream = log_level_to_file (log_level);

  for (i = 0; i < n_fields; i++)
    {
      const GLogField *field = &fields[i];

      /* Only print fields we definitely recognise, otherwise we could end up
       * printing a random non-string pointer provided by the user to be
       * interpreted by their writer function.
       */
      if (strcmp (field->key, "MESSAGE") != 0 &&
          strcmp (field->key, "MESSAGE_ID") != 0 &&
          strcmp (field->key, "PRIORITY") != 0 &&
          strcmp (field->key, "CODE_FILE") != 0 &&
          strcmp (field->key, "CODE_LINE") != 0 &&
          strcmp (field->key, "CODE_FUNC") != 0 &&
          strcmp (field->key, "ERRNO") != 0 &&
          strcmp (field->key, "SYSLOG_FACILITY") != 0 &&
          strcmp (field->key, "SYSLOG_IDENTIFIER") != 0 &&
          strcmp (field->key, "SYSLOG_PID") != 0 &&
          strcmp (field->key, "GLIB_DOMAIN") != 0)
        continue;

      write_string (stream, field->key);
      write_string (stream, "=");
      write_string_sized (stream, field->value, field->length);
    }

#ifndef G_OS_WIN32
  {
    gchar pid_string[FORMAT_UNSIGNED_BUFSIZE];

    format_unsigned (pid_string, getpid (), 10);
    write_string (stream, "_PID=");
    write_string (stream, pid_string);
  }
#endif

  return G_LOG_WRITER_HANDLED;
}

/**
 * g_return_if_fail_warning: (skip)
 * @log_domain: (nullable): log domain
 * @pretty_function: function containing the assertion
 * @expression: (nullable): expression which failed
 *
 * Internal function used to print messages from the public g_return_if_fail()
 * and g_return_val_if_fail() macros.
 */
void
g_return_if_fail_warning (const char *log_domain,
			  const char *pretty_function,
			  const char *expression)
{
  g_log (log_domain,
	 G_LOG_LEVEL_CRITICAL,
	 "%s: assertion '%s' failed",
	 pretty_function,
	 expression);
}

/**
 * g_warn_message: (skip)
 * @domain: (nullable): log domain
 * @file: file containing the warning
 * @line: line number of the warning
 * @func: function containing the warning
 * @warnexpr: (nullable): expression which failed
 *
 * Internal function used to print messages from the public g_warn_if_reached()
 * and g_warn_if_fail() macros.
 */
void
g_warn_message (const char     *domain,
                const char     *file,
                int             line,
                const char     *func,
                const char     *warnexpr)
{
  char *s, lstr[32];
  g_snprintf (lstr, 32, "%d", line);
  if (warnexpr)
    s = g_strconcat ("(", file, ":", lstr, "):",
                     func, func[0] ? ":" : "",
                     " runtime check failed: (", warnexpr, ")", NULL);
  else
    s = g_strconcat ("(", file, ":", lstr, "):",
                     func, func[0] ? ":" : "",
                     " ", "code should not be reached", NULL);
  g_log (domain, G_LOG_LEVEL_WARNING, "%s", s);
  g_free (s);
}

void
g_assert_warning (const char *log_domain,
		  const char *file,
		  const int   line,
		  const char *pretty_function,
		  const char *expression)
{
  if (expression)
    g_log (log_domain,
	   G_LOG_LEVEL_ERROR,
	   "file %s: line %d (%s): assertion failed: (%s)",
	   file,
	   line,
	   pretty_function,
	   expression);
  else
    g_log (log_domain,
	   G_LOG_LEVEL_ERROR,
	   "file %s: line %d (%s): should not be reached",
	   file,
	   line,
	   pretty_function);
  _g_log_abort (FALSE);
  g_abort ();
}

/**
 * g_test_expect_message:
 * @log_domain: (nullable): the log domain of the message
 * @log_level: the log level of the message
 * @pattern: a glob-style [pattern][glib-Glob-style-pattern-matching]
 *
 * Indicates that a message with the given @log_domain and @log_level,
 * with text matching @pattern, is expected to be logged. When this
 * message is logged, it will not be printed, and the test case will
 * not abort.
 *
 * This API may only be used with the old logging API (g_log() without
 * %G_LOG_USE_STRUCTURED defined). It will not work with the structured logging
 * API. See [Testing for Messages][testing-for-messages].
 *
 * Use g_test_assert_expected_messages() to assert that all
 * previously-expected messages have been seen and suppressed.
 *
 * You can call this multiple times in a row, if multiple messages are
 * expected as a result of a single call. (The messages must appear in
 * the same order as the calls to g_test_expect_message().)
 *
 * For example:
 *
 * |[<!-- language="C" --> 
 *   // g_main_context_push_thread_default() should fail if the
 *   // context is already owned by another thread.
 *   g_test_expect_message (G_LOG_DOMAIN,
 *                          G_LOG_LEVEL_CRITICAL,
 *                          "assertion*acquired_context*failed");
 *   g_main_context_push_thread_default (bad_context);
 *   g_test_assert_expected_messages ();
 * ]|
 *
 * Note that you cannot use this to test g_error() messages, since
 * g_error() intentionally never returns even if the program doesn't
 * abort; use g_test_trap_subprocess() in this case.
 *
 * If messages at %G_LOG_LEVEL_DEBUG are emitted, but not explicitly
 * expected via g_test_expect_message() then they will be ignored.
 *
 * Since: 2.34
 */
void
g_test_expect_message (const gchar    *log_domain,
                       GLogLevelFlags  log_level,
                       const gchar    *pattern)
{
  GTestExpectedMessage *expected;

  g_return_if_fail (log_level != 0);
  g_return_if_fail (pattern != NULL);
  g_return_if_fail (~log_level & G_LOG_LEVEL_ERROR);

  expected = g_new (GTestExpectedMessage, 1);
  expected->log_domain = g_strdup (log_domain);
  expected->log_level = log_level;
  expected->pattern = g_strdup (pattern);

  expected_messages = g_slist_append (expected_messages, expected);
}

void
g_test_assert_expected_messages_internal (const char     *domain,
                                          const char     *file,
                                          int             line,
                                          const char     *func)
{
  if (expected_messages)
    {
      GTestExpectedMessage *expected;
      gchar level_prefix[STRING_BUFFER_SIZE];
      gchar *message;

      expected = expected_messages->data;

      mklevel_prefix (level_prefix, expected->log_level, FALSE);
      message = g_strdup_printf ("Did not see expected message %s-%s: %s",
                                 expected->log_domain ? expected->log_domain : "**",
                                 level_prefix, expected->pattern);
      g_assertion_message (G_LOG_DOMAIN, file, line, func, message);
      g_free (message);
    }
}

/**
 * g_test_assert_expected_messages:
 *
 * Asserts that all messages previously indicated via
 * g_test_expect_message() have been seen and suppressed.
 *
 * This API may only be used with the old logging API (g_log() without
 * %G_LOG_USE_STRUCTURED defined). It will not work with the structured logging
 * API. See [Testing for Messages][testing-for-messages].
 *
 * If messages at %G_LOG_LEVEL_DEBUG are emitted, but not explicitly
 * expected via g_test_expect_message() then they will be ignored.
 *
 * Since: 2.34
 */

void
_g_log_fallback_handler (const gchar   *log_domain,
			 GLogLevelFlags log_level,
			 const gchar   *message,
			 gpointer       unused_data)
{
  gchar level_prefix[STRING_BUFFER_SIZE];
#ifndef G_OS_WIN32
  gchar pid_string[FORMAT_UNSIGNED_BUFSIZE];
#endif
  FILE *stream;

  /* we cannot call _any_ GLib functions in this fallback handler,
   * which is why we skip UTF-8 conversion, etc.
   * since we either recursed or ran out of memory, we're in a pretty
   * pathologic situation anyways, what we can do is giving the
   * the process ID unconditionally however.
   */

  stream = mklevel_prefix (level_prefix, log_level, FALSE);
  if (!message)
    message = "(NULL) message";

#ifndef G_OS_WIN32
  format_unsigned (pid_string, getpid (), 10);
#endif

  if (log_domain)
    write_string (stream, "\n");
  else
    write_string (stream, "\n** ");

#ifndef G_OS_WIN32
  write_string (stream, "(process:");
  write_string (stream, pid_string);
  write_string (stream, "): ");
#endif

  if (log_domain)
    {
      write_string (stream, log_domain);
      write_string (stream, "-");
    }
  write_string (stream, level_prefix);
  write_string (stream, ": ");
  write_string (stream, message);
}

static void
escape_string (GString *string)
{
  const char *p = string->str;
  gunichar wc;

  while (p < string->str + string->len)
    {
      gboolean safe;
	    
      wc = g_utf8_get_char_validated (p, -1);
      if (wc == (gunichar)-1 || wc == (gunichar)-2)  
	{
	  gchar *tmp;
	  guint pos;

	  pos = p - string->str;

	  /* Emit invalid UTF-8 as hex escapes 
           */
	  tmp = g_strdup_printf ("\\x%02x", (guint)(guchar)*p);
	  g_string_erase (string, pos, 1);
	  g_string_insert (string, pos, tmp);

	  p = string->str + (pos + 4); /* Skip over escape sequence */

	  g_free (tmp);
	  continue;
	}
      if (wc == '\r')
	{
	  safe = *(p + 1) == '\n';
	}
      else
	{
	  safe = CHAR_IS_SAFE (wc);
	}
      
      if (!safe)
	{
	  gchar *tmp;
	  guint pos;

	  pos = p - string->str;
	  
	  /* Largest char we escape is 0x0a, so we don't have to worry
	   * about 8-digit \Uxxxxyyyy
	   */
	  tmp = g_strdup_printf ("\\u%04x", wc); 
	  g_string_erase (string, pos, g_utf8_next_char (p) - p);
	  g_string_insert (string, pos, tmp);
	  g_free (tmp);

	  p = string->str + (pos + 6); /* Skip over escape sequence */
	}
      else
	p = g_utf8_next_char (p);
    }
}

/**
 * g_log_default_handler:
 * @log_domain: (nullable): the log domain of the message, or %NULL for the
 * default "" application domain
 * @log_level: the level of the message
 * @message: (nullable): the message
 * @unused_data: (nullable): data passed from g_log() which is unused
 *
 * The default log handler set up by GLib; g_log_set_default_handler()
 * allows to install an alternate default log handler.
 * This is used if no log handler has been set for the particular log
 * domain and log level combination. It outputs the message to stderr
 * or stdout and if the log level is fatal it calls G_BREAKPOINT(). It automatically
 * prints a new-line character after the message, so one does not need to be
 * manually included in @message.
 *
 * The behavior of this log handler can be influenced by a number of
 * environment variables:
 *
 * - `G_MESSAGES_PREFIXED`: A :-separated list of log levels for which
 *   messages should be prefixed by the program name and PID of the
 *   application.
 *
 * - `G_MESSAGES_DEBUG`: A space-separated list of log domains for
 *   which debug and informational messages are printed. By default
 *   these messages are not printed.
 *
 * stderr is used for levels %G_LOG_LEVEL_ERROR, %G_LOG_LEVEL_CRITICAL,
 * %G_LOG_LEVEL_WARNING and %G_LOG_LEVEL_MESSAGE. stdout is used for
 * the rest.
 *
 * This has no effect if structured logging is enabled; see
 * [Using Structured Logging][using-structured-logging].
 */
void
g_log_default_handler (const gchar   *log_domain,
		       GLogLevelFlags log_level,
		       const gchar   *message,
		       gpointer	      unused_data)
{
  GLogField fields[4];
  int n_fields = 0;

  /* we can be called externally with recursion for whatever reason */
  if (log_level & G_LOG_FLAG_RECURSION)
    {
      _g_log_fallback_handler (log_domain, log_level, message, unused_data);
      return;
    }

  fields[0].key = "GLIB_OLD_LOG_API";
  fields[0].value = "1";
  fields[0].length = -1;
  n_fields++;

  fields[1].key = "MESSAGE";
  fields[1].value = message;
  fields[1].length = -1;
  n_fields++;

  fields[2].key = "PRIORITY";
  fields[2].value = log_level_to_priority (log_level);
  fields[2].length = -1;
  n_fields++;

  if (log_domain)
    {
      fields[3].key = "GLIB_DOMAIN";
      fields[3].value = log_domain;
      fields[3].length = -1;
      n_fields++;
    }

  /* Print out via the structured log API, but drop any fatal flags since we
   * have already handled them. The fatal handling in the structured logging
   * API is more coarse-grained than in the old g_log() API, so we don't want
   * to use it here.
   */
  g_log_structured_array (log_level & ~G_LOG_FLAG_FATAL, fields, n_fields);
}

/**
 * g_set_print_handler:
 * @func: the new print handler
 *
 * Sets the print handler.
 *
 * Any messages passed to g_print() will be output via
 * the new handler. The default handler simply outputs
 * the message to stdout. By providing your own handler
 * you can redirect the output, to a GTK+ widget or a
 * log file for example.
 *
 * Returns: the old print handler
 */
GPrintFunc
g_set_print_handler (GPrintFunc func)
{
  GPrintFunc old_print_func;

  g_mutex_lock (&g_messages_lock);
  old_print_func = glib_print_func;
  glib_print_func = func;
  g_mutex_unlock (&g_messages_lock);

  return old_print_func;
}

/**
 * g_print:
 * @format: the message format. See the printf() documentation
 * @...: the parameters to insert into the format string
 *
 * Outputs a formatted message via the print handler.
 * The default print handler simply outputs the message to stdout, without
 * appending a trailing new-line character. Typically, @format should end with
 * its own new-line character.
 *
 * g_print() should not be used from within libraries for debugging
 * messages, since it may be redirected by applications to special
 * purpose message windows or even files. Instead, libraries should
 * use g_log(), g_log_structured(), or the convenience macros g_message(),
 * g_warning() and g_error().
 */
void
g_print (const gchar *format,
         ...)
{
  va_list args;
  gchar *string;
  GPrintFunc local_glib_print_func;

  g_return_if_fail (format != NULL);

  va_start (args, format);
  string = g_strdup_vprintf (format, args);
  va_end (args);

  g_mutex_lock (&g_messages_lock);
  local_glib_print_func = glib_print_func;
  g_mutex_unlock (&g_messages_lock);

  if (local_glib_print_func)
    local_glib_print_func (string);
  else
    {
      const gchar *charset;

      if (g_get_console_charset (&charset))
        fputs (string, stdout); /* charset is UTF-8 already */
      else
        {
          gchar *lstring = strdup_convert (string, charset);

          fputs (lstring, stdout);
          g_free (lstring);
        }
      fflush (stdout);
    }
  g_free (string);
}

/**
 * g_set_printerr_handler:
 * @func: the new error message handler
 *
 * Sets the handler for printing error messages.
 *
 * Any messages passed to g_printerr() will be output via
 * the new handler. The default handler simply outputs the
 * message to stderr. By providing your own handler you can
 * redirect the output, to a GTK+ widget or a log file for
 * example.
 *
 * Returns: the old error message handler
 */
GPrintFunc
g_set_printerr_handler (GPrintFunc func)
{
  GPrintFunc old_printerr_func;

  g_mutex_lock (&g_messages_lock);
  old_printerr_func = glib_printerr_func;
  glib_printerr_func = func;
  g_mutex_unlock (&g_messages_lock);

  return old_printerr_func;
}

/**
 * g_printerr:
 * @format: the message format. See the printf() documentation
 * @...: the parameters to insert into the format string
 *
 * Outputs a formatted message via the error message handler.
 * The default handler simply outputs the message to stderr, without appending
 * a trailing new-line character. Typically, @format should end with its own
 * new-line character.
 *
 * g_printerr() should not be used from within libraries.
 * Instead g_log() or g_log_structured() should be used, or the convenience
 * macros g_message(), g_warning() and g_error().
 */
void
g_printerr (const gchar *format,
            ...)
{
  va_list args;
  gchar *string;
  GPrintFunc local_glib_printerr_func;

  g_return_if_fail (format != NULL);

  va_start (args, format);
  string = g_strdup_vprintf (format, args);
  va_end (args);

  g_mutex_lock (&g_messages_lock);
  local_glib_printerr_func = glib_printerr_func;
  g_mutex_unlock (&g_messages_lock);

  if (local_glib_printerr_func)
    local_glib_printerr_func (string);
  else
    {
      const gchar *charset;

      if (g_get_console_charset (&charset))
        fputs (string, stderr); /* charset is UTF-8 already */
      else
        {
          gchar *lstring = strdup_convert (string, charset);

          fputs (lstring, stderr);
          g_free (lstring);
        }
      fflush (stderr);
    }
  g_free (string);
}

/**
 * g_printf_string_upper_bound:
 * @format: the format string. See the printf() documentation
 * @args: the parameters to be inserted into the format string
 *
 * Calculates the maximum space needed to store the output
 * of the sprintf() function.
 *
 * Returns: the maximum space needed to store the formatted string
 */
gsize
g_printf_string_upper_bound (const gchar *format,
                             va_list      args)
{
  gchar c;
  return _g_vsnprintf (&c, 1, format, args) + 1;
}
