g_parse_debug_string: invert flags given besides "all"
authorWill Thompson <will.thompson@collabora.co.uk>
Thu, 20 Oct 2011 15:07:03 +0000 (16:07 +0100)
committerMatthias Clasen <mclasen@redhat.com>
Tue, 25 Oct 2011 00:35:30 +0000 (20:35 -0400)
Any flags specified as well as "all" are subtracted from the result,
allowing the user to specify FOO_DEBUG="all,bar,baz" to mean "give me
debugging information for everything except bar and baz".

https://bugzilla.gnome.org/show_bug.cgi?id=642452

glib/glib-init.c
tests/testglib.c

index 4879e0b..09a9ef7 100644 (file)
@@ -76,9 +76,13 @@ debug_key_matches (const gchar *key,
  * 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 <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.
  */
@@ -101,12 +105,7 @@ 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: ");
@@ -118,6 +117,7 @@ g_parse_debug_string  (const gchar     *string,
     {
       const gchar *p = string;
       const gchar *q;
+      gboolean invert = FALSE;
 
       while (*p)
        {
@@ -125,14 +125,31 @@ g_parse_debug_string  (const gchar     *string,
          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;
+         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;
index 35c9573..1a06d10 100644 (file)
@@ -509,10 +509,11 @@ find_first_that(gpointer key,
 static void
 test_g_parse_debug_string (void)
 {
-  GDebugKey keys[3] = { 
+  GDebugKey keys[] = { 
     { "foo", 1 },
     { "bar", 2 },
-    { "baz", 4 }
+    { "baz", 4 },
+    { "weird", 8 },
   };
   guint n_keys = G_N_ELEMENTS (keys);
   guint result;
@@ -531,6 +532,19 @@ test_g_parse_debug_string (void)
 
   result = g_parse_debug_string ("all", keys, n_keys);
   g_assert_cmpuint (result, ==, (1 << n_keys) - 1);
+
+  /* Test subtracting debug flags from "all" */
+  result = g_parse_debug_string ("all:foo", keys, n_keys);
+  g_assert_cmpuint (result, ==, 2 | 4 | 8);
+
+  result = g_parse_debug_string ("foo baz,all", keys, n_keys);
+  g_assert_cmpuint (result, ==, 2 | 8);
+
+  result = g_parse_debug_string ("all,fooo,baz", keys, n_keys);
+  g_assert_cmpuint (result, ==, 1 | 2 | 8);
+
+  result = g_parse_debug_string ("all:weird", keys, n_keys);
+  g_assert_cmpuint (result, ==, 1 | 2 | 4);
 }
 
 static void