[libdazzle] util: add more complete GAction name parser



commit 8556db7381e0b4611de1685c383047e828318bb3
Author: Christian Hergert <chergert redhat com>
Date:   Sun Aug 27 18:35:54 2017 -0700

    util: add more complete GAction name parser
    
    This is easier and more convenient for how we need to use it compared to
    what is in GAction API.

 src/shortcuts/dzl-shortcut-closure-chain.c |   32 +++----------
 src/util/dzl-util-private.h                |    4 ++
 src/util/dzl-util.c                        |   41 ++++++++++++++++
 tests/meson.build                          |    7 +++
 tests/test-util.c                          |   72 ++++++++++++++++++++++++++++
 5 files changed, 131 insertions(+), 25 deletions(-)
---
diff --git a/src/shortcuts/dzl-shortcut-closure-chain.c b/src/shortcuts/dzl-shortcut-closure-chain.c
index 4e8233d..f5cf665 100644
--- a/src/shortcuts/dzl-shortcut-closure-chain.c
+++ b/src/shortcuts/dzl-shortcut-closure-chain.c
@@ -27,6 +27,7 @@
 #include "shortcuts/dzl-shortcut-controller.h"
 #include "shortcuts/dzl-shortcut-private.h"
 #include "util/dzl-gtk.h"
+#include "util/dzl-util-private.h"
 
 static DzlShortcutClosureChain *
 dzl_shortcut_closure_chain_new (DzlShortcutClosureType type)
@@ -145,39 +146,20 @@ dzl_shortcut_closure_chain_append_action_string (DzlShortcutClosureChain *chain,
                                                  const gchar             *detailed_action_name)
 {
   DzlShortcutClosureChain *tail;
-  g_autoptr(GError) error = NULL;
   g_autoptr(GVariant) target_value = NULL;
-  g_autofree gchar *full_name = NULL;
-  g_autofree gchar *group = NULL;
-  const gchar *name = NULL;
-  const gchar *dot;
+  g_autofree gchar *prefix = NULL;
+  g_autofree gchar *name = NULL;
 
   g_return_val_if_fail (detailed_action_name != NULL, NULL);
 
-  if (!g_action_parse_detailed_name (detailed_action_name, &full_name, &target_value, &error))
+  if (!dzl_g_action_name_parse_full (detailed_action_name, &prefix, &name, &target_value))
     {
-      g_warning ("%s", error->message);
-      return chain;
-    }
-
-  if (target_value != NULL)
-    g_variant_take_ref (target_value);
-
-  dot = strchr (full_name, '.');
-
-  if (dot != NULL)
-    {
-      group = g_strndup (full_name, dot - full_name);
-      name = dot + 1;
-    }
-  else
-    {
-      group = NULL;
-      name = full_name;
+      g_warning ("Failed to parse action: %s", detailed_action_name);
+      return NULL;
     }
 
   tail = dzl_shortcut_closure_chain_new (DZL_SHORTCUT_CLOSURE_ACTION);
-  tail->action.group = g_intern_string (group);
+  tail->action.group = g_intern_string (prefix);
   tail->action.name = g_intern_string (name);
   tail->action.params = g_steal_pointer (&target_value);
 
diff --git a/src/util/dzl-util-private.h b/src/util/dzl-util-private.h
index 09f3879..c08d8ed 100644
--- a/src/util/dzl-util-private.h
+++ b/src/util/dzl-util-private.h
@@ -65,6 +65,10 @@ GActionGroup *dzl_gtk_widget_find_group_for_action  (GtkWidget        *widget,
 void          dzl_g_action_name_parse               (const gchar      *action_name,
                                                      gchar           **prefix,
                                                      gchar           **name);
+gboolean      dzl_g_action_name_parse_full          (const gchar      *detailed_action_name,
+                                                     gchar           **prefix,
+                                                     gchar           **name,
+                                                     GVariant        **target);
 void          dzl_gtk_style_context_get_borders     (GtkStyleContext  *style_context,
                                                      GtkBorder        *borders);
 void          dzl_gtk_allocation_subtract_border    (GtkAllocation    *alloc,
diff --git a/src/util/dzl-util.c b/src/util/dzl-util.c
index 4920106..2903060 100644
--- a/src/util/dzl-util.c
+++ b/src/util/dzl-util.c
@@ -265,6 +265,47 @@ dzl_g_action_name_parse (const gchar  *action_name,
   split_action_name (action_name, prefix, name);
 }
 
+gboolean
+dzl_g_action_name_parse_full (const gchar  *detailed_action_name,
+                              gchar       **prefix,
+                              gchar       **name,
+                              GVariant    **target)
+{
+  g_autofree gchar *full_name = NULL;
+  g_autoptr(GVariant) target_value = NULL;
+  const gchar *dot;
+
+  if (detailed_action_name == NULL)
+    return FALSE;
+
+  if (!g_action_parse_detailed_name (detailed_action_name, &full_name, &target_value, NULL))
+    return FALSE;
+
+  if (target_value != NULL)
+    g_variant_take_ref (target_value);
+
+  dot = strchr (full_name, '.');
+
+  if (dot != NULL)
+    {
+      if (prefix != NULL)
+        *prefix = g_strndup (full_name, dot - full_name);
+
+      if (name != NULL)
+        *name = g_strdup (dot + 1);
+    }
+  else
+    {
+      *prefix = NULL;
+      *name = g_steal_pointer (&full_name);
+    }
+
+  if (target != NULL)
+    *target = g_steal_pointer (&target_value);
+
+  return TRUE;
+}
+
 void
 dzl_gtk_allocation_subtract_border (GtkAllocation *alloc,
                                     GtkBorder     *border)
diff --git a/tests/meson.build b/tests/meson.build
index 0098b2d..fd370a0 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -326,4 +326,11 @@ test_list_store_adapter = executable('test-list-store-adapter', 'test-list-store
 )
 test('test-list-store-adapter', test_list_store_adapter, env: test_env)
 
+test_util = executable('test-util', 'test-util.c',
+        c_args: test_cflags,
+     link_args: test_link_args,
+  dependencies: libdazzle_deps + [libdazzle_dep],
+)
+test('test-util', test_util, env: test_env)
+
 endif
diff --git a/tests/test-util.c b/tests/test-util.c
new file mode 100644
index 0000000..724102f
--- /dev/null
+++ b/tests/test-util.c
@@ -0,0 +1,72 @@
+/* test-util.c
+ *
+ * Copyright (C) 2017 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <dazzle.h>
+
+#include "util/dzl-util-private.h"
+
+static void
+test_action_parsing (void)
+{
+  struct {
+    const gchar *input;
+    const gchar *expected_prefix;
+    const gchar *expected_name;
+    const gchar *expected_target;
+  } simple_tests[] = {
+    { "app.foobar", "app", "foobar", NULL },
+    { "win.foo", "win", "foo", NULL },
+    { "win.foo::1", "win", "foo", "'1'" },
+    { "win.foo(1)", "win", "foo", "1" },
+  };
+
+  for (guint i = 0; i < G_N_ELEMENTS (simple_tests); i++)
+    {
+      g_autofree gchar *prefix = NULL;
+      g_autofree gchar *name = NULL;
+      g_autoptr(GVariant) target = NULL;
+
+      if (!dzl_g_action_name_parse_full (simple_tests[i].input, &prefix, &name, &target))
+        g_error ("Failed to parse %s", simple_tests[i].input);
+
+      g_assert_cmpstr (prefix, ==, simple_tests[i].expected_prefix);
+      g_assert_cmpstr (name, ==, simple_tests[i].expected_name);
+
+      if (simple_tests[i].expected_target)
+        {
+          g_autoptr(GVariant) expected_target = g_variant_parse (NULL,
+                                                                 simple_tests[i].expected_target,
+                                                                 NULL, NULL, NULL);
+          if (!g_variant_equal (expected_target, target))
+            {
+              g_printerr ("Expected: %s\n", g_variant_print (expected_target, TRUE));
+              g_printerr ("Actual: %s\n", g_variant_print (target, TRUE));
+              g_assert_not_reached ();
+            }
+        }
+    }
+}
+
+gint
+main (gint   argc,
+      gchar *argv[])
+{
+  g_test_init (&argc, &argv, NULL);
+  g_test_add_func ("/Util/Action/parse", test_action_parsing);
+  return g_test_run ();
+}


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]