[kdbus] KDBUS_ITEM_PAYLOAD_OFF items are (once again) relative to msg header
[platform/upstream/glib.git] / glib / glib-init.c
index ffc3a2f..24efe9d 100644 (file)
@@ -12,9 +12,7 @@
  * 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.
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  *
  * Author: Ryan Lortie <desrt@desrt.ca>
  */
 
 #include "glib-init.h"
 
+#include "glib-private.h"
+#include "gtypes.h"
 #include "gutils.h"     /* for GDebugKey */
+#include "gconstructor.h"
+#include "gmem.h"       /* for g_mem_gc_friendly */
 
 #include <string.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <ctype.h>
 
+/* This seems as good a place as any to make static assertions about platform
+ * assumptions we make throughout GLib. */
+
+/* We do not support 36-bit bytes or other historical curiosities. */
+G_STATIC_ASSERT (CHAR_BIT == 8);
+
+/* We assume that data pointers are the same size as function pointers... */
+G_STATIC_ASSERT (sizeof (gpointer) == sizeof (GFunc));
+G_STATIC_ASSERT (_g_alignof (gpointer) == _g_alignof (GFunc));
+/* ... and that all function pointers are the same size. */
+G_STATIC_ASSERT (sizeof (GFunc) == sizeof (GCompareDataFunc));
+G_STATIC_ASSERT (_g_alignof (GFunc) == _g_alignof (GCompareDataFunc));
+
 /**
  * g_mem_gc_friendly:
  *
- * This variable is %TRUE if the <envar>G_DEBUG</envar> environment variable
- * includes the key <link linkend="G_DEBUG">gc-friendly</link>.
+ * This variable is %TRUE if the `G_DEBUG` environment variable
+ * includes the key `gc-friendly`.
  */
 #ifdef ENABLE_GC_FRIENDLY_DEFAULT
 gboolean g_mem_gc_friendly = TRUE;
@@ -69,16 +84,20 @@ debug_key_matches (const gchar *key,
  * 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.
+ * @nkeys: the number of #GDebugKeys 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 "all", all flags are set.  If @string
- * is equal to "help", all the available keys in @keys are printed
- * out to standard error.
+ * If @string is equal to "all", all flags are set. Any flags
+ * specified along with "all" in @string are inverted; thus,
+ * "all,foo,bar" or "foo,bar,all" sets all flags except those
+ * corresponding to "foo" and "bar".
+ *
+ * If @string is equal to "help", all the available keys in @keys
+ * are printed out to standard error.
  *
  * Returns: the combined set of bit flags.
  */
@@ -101,38 +120,51 @@ g_parse_debug_string  (const gchar     *string,
    * inside GLib.
    */
 
-  if (!strcasecmp (string, "all"))
-    {
-      for (i = 0; i < nkeys; i++)
-       result |= keys[i].value;
-    }
-  else if (!strcasecmp (string, "help"))
+  if (!strcasecmp (string, "help"))
     {
       /* using stdio directly for the reason stated above */
-      fprintf (stderr, "Supported debug values: ");
+      fprintf (stderr, "Supported debug values:");
       for (i = 0; i < nkeys; i++)
        fprintf (stderr, " %s", keys[i].key);
-      fprintf (stderr, "\n");
+      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);
-
-         for (i = 0; i < nkeys; i++)
-           if (debug_key_matches (keys[i].key, p, q - p))
-             result |= keys[i].value;
+           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;
@@ -141,13 +173,14 @@ g_parse_debug_string  (const gchar     *string,
 static guint
 g_parse_debug_envvar (const gchar     *envvar,
                       const GDebugKey *keys,
-                      gint             n_keys)
+                      gint             n_keys,
+                      guint            default_value)
 {
   const gchar *value;
 
 #ifdef OS_WIN32
   /* "fatal-warnings,fatal-criticals,all,help" is pretty short */
-  gchar buffer[80];
+  gchar buffer[100];
 
   if (GetEnvironmentVariable (envvar, buffer, 100) < 100)
     value = buffer;
@@ -157,6 +190,9 @@ g_parse_debug_envvar (const gchar     *envvar,
   value = getenv (envvar);
 #endif
 
+  if (value == NULL)
+    return default_value;
+
   return g_parse_debug_string (value, keys, n_keys);
 }
 
@@ -172,32 +208,24 @@ g_messages_prefixed_init (void)
     { "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 = 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));
-
-  g_log_always_fatal |= flags;
-}
+  flags = g_parse_debug_envvar ("G_DEBUG", keys, G_N_ELEMENTS (keys), 0);
 
-static void
-g_mem_init (void)
-{
-  const GDebugKey keys[] = {
-    { "gc-friendly", 1 },
-  };
+  g_log_always_fatal |= flags & G_LOG_LEVEL_MASK;
 
-  if (g_parse_debug_envvar ("G_DEBUG", keys, G_N_ELEMENTS (keys)))
-    g_mem_gc_friendly = TRUE;
+  g_mem_gc_friendly = flags & 1;
 }
 
 static void
@@ -205,11 +233,14 @@ glib_init (void)
 {
   g_messages_prefixed_init ();
   g_debug_init ();
-  g_mem_init ();
 }
 
 #if defined (G_OS_WIN32)
 
+BOOL WINAPI DllMain (HINSTANCE hinstDLL,
+                     DWORD     fdwReason,
+                     LPVOID    lpvReserved);
+
 HMODULE glib_dll;
 
 BOOL WINAPI
@@ -221,10 +252,19 @@ DllMain (HINSTANCE hinstDLL,
     {
     case DLL_PROCESS_ATTACH:
       glib_dll = hinstDLL;
+      g_clock_win32_init ();
+#ifdef THREADS_WIN32
       g_thread_win32_init ();
+#endif
       glib_init ();
       break;
 
+    case DLL_THREAD_DETACH:
+#ifdef THREADS_WIN32
+      g_thread_win32_thread_detach ();
+#endif
+      break;
+
     default:
       /* do nothing */
       ;
@@ -233,9 +273,14 @@ DllMain (HINSTANCE hinstDLL,
   return TRUE;
 }
 
-#elif defined (__GNUC__)
+#elif defined (G_HAS_CONSTRUCTORS)
 
-__attribute__ ((constructor)) static void
+#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 ();