[gtk+/key-themes] Improve binding-set parser



commit e3e021d757bde46b149ae795fd7e9ac51ee44a65
Author: Matthias Clasen <mclasen redhat com>
Date:   Fri Jan 28 19:36:24 2011 -0500

    Improve binding-set parser
    
    Make gtk_binding_entry_add_signal_from_string() return the expected
    token in case of parsing error, so that we can return a GError
    instead of spewing. Also, add a separate scope for binding-set,
    since allowing {} in identifiers in SCOPE_VALUE breaks the fact
    that the ; after the last assignment in a rule is optional.

 gtk/gtkbindings.c    |   19 ++++++++++---------
 gtk/gtkbindings.h    |    4 ++--
 gtk/gtkcssprovider.c |   23 +++++++++++++++++++----
 3 files changed, 31 insertions(+), 15 deletions(-)
---
diff --git a/gtk/gtkbindings.c b/gtk/gtkbindings.c
index 2b9d512..ef31fb9 100644
--- a/gtk/gtkbindings.c
+++ b/gtk/gtkbindings.c
@@ -1271,17 +1271,20 @@ create_signal_scanner (void)
  * Key combinations must be in a format that can be parsed by
  * gtk_accelerator_parse().
  *
+ * Returns: %G_TOKEN_NONE if the signal was successfully parsed and added,
+ *     the expected token otherwise
+ *
  * Since: 3.0
- **/
-void
+ */
+GTokenType
 gtk_binding_entry_add_signal_from_string (GtkBindingSet *binding_set,
-					  const gchar   *signal_desc)
+                                          const gchar   *signal_desc)
 {
   static GScanner *scanner = NULL;
   GTokenType ret;
 
-  g_return_if_fail (binding_set != NULL);
-  g_return_if_fail (signal_desc != NULL);
+  g_return_val_if_fail (binding_set != NULL, G_TOKEN_NONE);
+  g_return_val_if_fail (signal_desc != NULL, G_TOKEN_NONE);
 
   if (G_UNLIKELY (!scanner))
     scanner = create_signal_scanner ();
@@ -1291,12 +1294,10 @@ gtk_binding_entry_add_signal_from_string (GtkBindingSet *binding_set,
 
   ret = gtk_binding_parse_bind (scanner, binding_set);
 
-  if (ret != G_TOKEN_NONE)
-    g_scanner_unexp_token (scanner, ret, NULL, NULL, NULL,
-                           "Could not parse binding", FALSE);
-
   /* Reset for next use */
   g_scanner_set_scope (scanner, 0);
+
+  return ret;
 }
 
 /**
diff --git a/gtk/gtkbindings.h b/gtk/gtkbindings.h
index 4529567..cf7f6bf 100644
--- a/gtk/gtkbindings.h
+++ b/gtk/gtkbindings.h
@@ -125,8 +125,8 @@ void	 gtk_binding_entry_add_signall	(GtkBindingSet	*binding_set,
 					 const gchar	*signal_name,
 					 GSList		*binding_args);
 
-void     gtk_binding_entry_add_signal_from_string (GtkBindingSet *binding_set,
-						   const gchar   *signal_desc);
+GTokenType gtk_binding_entry_add_signal_from_string (GtkBindingSet *binding_set,
+                                                     const gchar   *signal_desc);
 
 void	 gtk_binding_entry_remove	(GtkBindingSet	*binding_set,
 					 guint		 keyval,
diff --git a/gtk/gtkcssprovider.c b/gtk/gtkcssprovider.c
index 1c5441f..7313bba 100644
--- a/gtk/gtkcssprovider.c
+++ b/gtk/gtkcssprovider.c
@@ -801,7 +801,8 @@ enum ParserScope {
   SCOPE_PSEUDO_CLASS,
   SCOPE_NTH_CHILD,
   SCOPE_DECLARATION,
-  SCOPE_VALUE
+  SCOPE_VALUE,
+  SCOPE_BINDING_SET
 };
 
 /* Extend GtkStateType, since these
@@ -1507,6 +1508,12 @@ scanner_apply_scope (GScanner    *scanner,
   if (scope == SCOPE_VALUE)
     {
       scanner->config->cset_identifier_first = G_CSET_a_2_z G_CSET_A_2_Z G_CSET_DIGITS "@#-_";
+      scanner->config->cset_identifier_nth = G_CSET_a_2_z G_CSET_A_2_Z G_CSET_DIGITS "@#-_ +(),.%\t\n'/\"";
+      scanner->config->scan_identifier_1char = TRUE;
+    }
+  else if (scope == SCOPE_BINDING_SET)
+    {
+      scanner->config->cset_identifier_first = G_CSET_a_2_z G_CSET_A_2_Z G_CSET_DIGITS "@#-_";
       scanner->config->cset_identifier_nth = G_CSET_a_2_z G_CSET_A_2_Z G_CSET_DIGITS "@#-_ +(){}<>,.%\t\n'/\"";
       scanner->config->scan_identifier_1char = TRUE;
     }
@@ -3318,19 +3325,27 @@ parse_rule (GtkCssProvider  *css_provider,
           if (scanner->token != G_TOKEN_LEFT_CURLY)
             return G_TOKEN_LEFT_CURLY;
 
-          css_provider_push_scope (css_provider, SCOPE_VALUE);
+          css_provider_push_scope (css_provider, SCOPE_BINDING_SET);
           g_scanner_get_next_token (scanner);
 
           do
             {
+              GTokenType ret;
+
               if (scanner->token != G_TOKEN_IDENTIFIER)
                 {
                   scanner->user_data = "Binding definition";
                   return G_TOKEN_IDENTIFIER;
                 }
 
-              gtk_binding_entry_add_signal_from_string (binding_set,
-                                                        scanner->value.v_identifier);
+              ret = gtk_binding_entry_add_signal_from_string (binding_set,
+                                                              scanner->value.v_identifier);
+              if (ret != G_TOKEN_NONE)
+                {
+                  scanner->user_data = "Binding definition";
+                  return ret;
+                }
+
               g_scanner_get_next_token (scanner);
 
               if (scanner->token != ';')



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