diff options
author | Dan Nicholson <dbn.lists@gmail.com> | 2010-06-05 12:32:36 -0700 |
---|---|---|
committer | Dan Nicholson <dbn.lists@gmail.com> | 2012-04-21 12:46:31 -0700 |
commit | c23f6a6ef365ad472e2c397558dc8bbe10fd709c (patch) | |
tree | c2b55278a46e1d844d9d6aef8e4f8f7d02110a9f /glib/glib/glib-init.c | |
parent | 9961b85d2a4880376d0fd01278433162a3a5602d (diff) | |
download | pkg-config-c23f6a6ef365ad472e2c397558dc8bbe10fd709c.tar.gz |
glib: Bundle snapshot of glib-2.0
Add a snapshot of the current stable version of glib, glib-2.32.0. Since
we only need the glib library, a lot of files are removed. See the
README and update-glib.sh files in glib-patches for details.
Diffstat (limited to 'glib/glib/glib-init.c')
-rw-r--r-- | glib/glib/glib-init.c | 269 |
1 files changed, 269 insertions, 0 deletions
diff --git a/glib/glib/glib-init.c b/glib/glib/glib-init.c new file mode 100644 index 0000000..f4edd5c --- /dev/null +++ b/glib/glib/glib-init.c @@ -0,0 +1,269 @@ +/* + * Copyright © 2011 Canonical Limited + * + * 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 of the + * licence, 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, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + * + * Author: Ryan Lortie <desrt@desrt.ca> + */ + +#include "config.h" + +#include "glib-init.h" + +#include "gutils.h" /* for GDebugKey */ +#include "gconstructor.h" + +#include <string.h> +#include <stdlib.h> +#include <stdio.h> +#include <ctype.h> + +/** + * g_mem_gc_friendly: + * + * This variable is %TRUE if the <envar>G_DEBUG</envar> environment variable + * includes the key <literal>gc-friendly</literal>. + */ +#ifdef ENABLE_GC_FRIENDLY_DEFAULT +gboolean g_mem_gc_friendly = TRUE; +#else +gboolean g_mem_gc_friendly = FALSE; +#endif +GLogLevelFlags g_log_msg_prefix = G_LOG_LEVEL_ERROR | G_LOG_LEVEL_WARNING | + G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_DEBUG; +GLogLevelFlags g_log_always_fatal = G_LOG_FATAL_MASK; + +static gboolean +debug_key_matches (const gchar *key, + const gchar *token, + guint length) +{ + /* may not call GLib functions: see note in g_parse_debug_string() */ + for (; length; length--, key++, token++) + { + char k = (*key == '_') ? '-' : tolower (*key ); + char t = (*token == '_') ? '-' : tolower (*token); + + if (k != t) + return FALSE; + } + + return *key == '\0'; +} + +/** + * g_parse_debug_string: + * @string: (allow-none): a list of debug options separated by colons, spaces, or + * commas, or %NULL. + * @keys: (array length=nkeys): pointer to an array of #GDebugKey which associate + * strings with bit flags. + * @nkeys: the number of #GDebugKey<!-- -->s in the array. + * + * Parses a string containing debugging options + * into a %guint containing bit flags. This is used + * within GDK and GTK+ to parse the debug options passed on the + * command line or through environment variables. + * + * If @string is equal to <code>"all"</code>, all flags are set. Any flags + * specified along with <code>"all"</code> in @string are inverted; thus, + * <code>"all,foo,bar"</code> or <code>"foo,bar,all"</code> sets all flags + * except those corresponding to <code>"foo"</code> and <code>"bar"</code>. + * + * If @string is equal to <code>"help"</code>, all the available keys in @keys + * are printed out to standard error. + * + * Returns: the combined set of bit flags. + */ +guint +g_parse_debug_string (const gchar *string, + const GDebugKey *keys, + guint nkeys) +{ + guint i; + guint result = 0; + + if (string == NULL) + return 0; + + /* this function is used during the initialisation of gmessages, gmem + * and gslice, so it may not do anything that causes memory to be + * allocated or risks messages being emitted. + * + * this means, more or less, that this code may not call anything + * inside GLib. + */ + + if (!strcasecmp (string, "help")) + { + /* using stdio directly for the reason stated above */ + fprintf (stderr, "Supported debug values:"); + for (i = 0; i < nkeys; i++) + fprintf (stderr, " %s", keys[i].key); + fprintf (stderr, " all help\n"); + } + else + { + const gchar *p = string; + const gchar *q; + gboolean invert = FALSE; + + while (*p) + { + q = strpbrk (p, ":;, \t"); + if (!q) + q = p + strlen (p); + + if (debug_key_matches ("all", p, q - p)) + { + invert = TRUE; + } + else + { + for (i = 0; i < nkeys; i++) + if (debug_key_matches (keys[i].key, p, q - p)) + result |= keys[i].value; + } + + p = q; + if (*p) + p++; + } + + if (invert) + { + guint all_flags = 0; + + for (i = 0; i < nkeys; i++) + all_flags |= keys[i].value; + + result = all_flags & (~result); + } + } + + return result; +} + +static guint +g_parse_debug_envvar (const gchar *envvar, + const GDebugKey *keys, + gint n_keys, + guint default_value) +{ + const gchar *value; + +#ifdef OS_WIN32 + /* "fatal-warnings,fatal-criticals,all,help" is pretty short */ + gchar buffer[100]; + + if (GetEnvironmentVariable (envvar, buffer, 100) < 100) + value = buffer; + else + return 0; +#else + value = getenv (envvar); +#endif + + if (value == NULL) + return default_value; + + return g_parse_debug_string (value, keys, n_keys); +} + +static void +g_messages_prefixed_init (void) +{ + const GDebugKey keys[] = { + { "error", G_LOG_LEVEL_ERROR }, + { "critical", G_LOG_LEVEL_CRITICAL }, + { "warning", G_LOG_LEVEL_WARNING }, + { "message", G_LOG_LEVEL_MESSAGE }, + { "info", G_LOG_LEVEL_INFO }, + { "debug", G_LOG_LEVEL_DEBUG } + }; + + g_log_msg_prefix = g_parse_debug_envvar ("G_MESSAGES_PREFIXED", keys, G_N_ELEMENTS (keys), g_log_msg_prefix); +} + +static void +g_debug_init (void) +{ + const GDebugKey keys[] = { + { "gc-friendly", 1 }, + {"fatal-warnings", G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL }, + {"fatal-criticals", G_LOG_LEVEL_CRITICAL } + }; + GLogLevelFlags flags; + + flags = g_parse_debug_envvar ("G_DEBUG", keys, G_N_ELEMENTS (keys), 0); + + g_log_always_fatal |= flags & G_LOG_LEVEL_MASK; + + g_mem_gc_friendly = flags & 1; +} + +static void +glib_init (void) +{ + g_messages_prefixed_init (); + g_debug_init (); +} + +#if defined (G_OS_WIN32) + +HMODULE glib_dll; + +BOOL WINAPI +DllMain (HINSTANCE hinstDLL, + DWORD fdwReason, + LPVOID lpvReserved) +{ + switch (fdwReason) + { + case DLL_PROCESS_ATTACH: + glib_dll = hinstDLL; + g_clock_win32_init (); + g_thread_win32_init (); + glib_init (); + break; + + case DLL_THREAD_DETACH: + g_thread_win32_thread_detach (); + break; + + default: + /* do nothing */ + ; + } + + return TRUE; +} + +#elif defined (G_HAS_CONSTRUCTORS) + +#ifdef G_DEFINE_CONSTRUCTOR_NEEDS_PRAGMA +#pragma G_DEFINE_CONSTRUCTOR_PRAGMA_ARGS(glib_init_ctor) +#endif +G_DEFINE_CONSTRUCTOR(glib_init_ctor) + +static void +glib_init_ctor (void) +{ + glib_init (); +} + +#else +# error Your platform/compiler is missing constructor support +#endif |