[gtk+/wip/otte/tokenizer: 11/78] css: Add a consumer object to consume_token()



commit 14e7c422005320fc70fefb2723d029db73a16454
Author: Benjamin Otte <otte redhat com>
Date:   Mon Mar 14 20:27:55 2016 +0100

    css: Add a consumer object to consume_token()
    
    This is to allow backreferences from code analysis frameworks.

 gtk/gtkcssdeclaration.c        |   19 ++++++++++-------
 gtk/gtkcssrule.c               |    9 +++++--
 gtk/gtkcssrulelist.c           |    2 +
 gtk/gtkcssselector.c           |    2 +-
 gtk/gtkcssstyledeclaration.c   |    2 +-
 gtk/gtkcssstylerule.c          |   30 ++++++++++++++++++---------
 gtk/gtkcsstokensource.c        |   43 ++++++++++++++++++++++++++++++++-------
 gtk/gtkcsstokensourceprivate.h |   11 +++++++++-
 8 files changed, 86 insertions(+), 32 deletions(-)
---
diff --git a/gtk/gtkcssdeclaration.c b/gtk/gtkcssdeclaration.c
index f8c1c74..50245d9 100644
--- a/gtk/gtkcssdeclaration.c
+++ b/gtk/gtkcssdeclaration.c
@@ -77,32 +77,35 @@ GtkCssDeclaration *
 gtk_css_declaration_new_parse (GtkCssStyleDeclaration *style,
                                GtkCssTokenSource      *source)
 {
+  GtkCssDeclarationPrivate *priv;
   const GtkCssToken *token;
   GtkCssDeclaration *decl;
-  char *name, *value;
 
+  decl = g_object_new (GTK_TYPE_CSS_DECLARATION, NULL);
+  priv = gtk_css_declaration_get_instance_private (decl);
+
+  gtk_css_token_source_set_consumer (source, G_OBJECT (decl));
+
+  priv->style = style;
   token = gtk_css_token_source_get_token (source);
   if (!gtk_css_token_is (token, GTK_CSS_TOKEN_IDENT))
     {
       gtk_css_token_source_consume_all (source);
+      g_object_unref (decl);
       return NULL;
     }
-  name = g_strdup (token->string.string);
+  priv->name = g_strdup (token->string.string);
   gtk_css_token_source_consume_token (source);
   gtk_css_token_source_consume_whitespace (source);
   token = gtk_css_token_source_get_token (source);
   if (!gtk_css_token_is (token, GTK_CSS_TOKEN_COLON))
     {
-      g_free (name);
       gtk_css_token_source_consume_all (source);
+      g_object_unref (decl);
       return NULL;
     }
 
-  value = gtk_css_token_source_consume_to_string (source);
-
-  decl = gtk_css_declaration_new (style, name, value);
-  g_free (name);
-  g_free (value);
+  priv->value = gtk_css_token_source_consume_to_string (source);
 
   return decl;
 }
diff --git a/gtk/gtkcssrule.c b/gtk/gtkcssrule.c
index d074a4a..7693b7f 100644
--- a/gtk/gtkcssrule.c
+++ b/gtk/gtkcssrule.c
@@ -46,7 +46,8 @@ gtk_css_token_source_at_finalize (GtkCssTokenSource *source)
 }
 
 static void
-gtk_css_token_source_at_consume_token (GtkCssTokenSource *source)
+gtk_css_token_source_at_consume_token (GtkCssTokenSource *source,
+                                       GObject           *consumer)
 {
   GtkCssTokenSourceAt *at = (GtkCssTokenSourceAt *) source;
   const GtkCssToken *token;
@@ -56,7 +57,7 @@ gtk_css_token_source_at_consume_token (GtkCssTokenSource *source)
 
   if (gtk_css_token_get_pending_block (source))
     {
-      gtk_css_token_source_consume_token (at->source);
+      gtk_css_token_source_consume_token_as (at->source, consumer);
       return;
     }
 
@@ -68,7 +69,7 @@ gtk_css_token_source_at_consume_token (GtkCssTokenSource *source)
   else if (gtk_css_token_is (token, GTK_CSS_TOKEN_OPEN_CURLY))
     at->inside_curly_block = TRUE;
 
-  gtk_css_token_source_consume_token (at->source);
+  gtk_css_token_source_consume_token_as (at->source, consumer);
 }
 
 const GtkCssToken *
@@ -105,6 +106,8 @@ gtk_css_token_source_new_at (GtkCssTokenSource *source)
   GtkCssTokenSourceAt *at = gtk_css_token_source_new (GtkCssTokenSourceAt, &GTK_CSS_TOKEN_SOURCE_AT);
 
   at->source = gtk_css_token_source_ref (source);
+  gtk_css_token_source_set_consumer (&at->parent,
+                                     gtk_css_token_source_get_consumer (source));
 
   return &at->parent;
 }
diff --git a/gtk/gtkcssrulelist.c b/gtk/gtkcssrulelist.c
index fa72a63..69b1de9 100644
--- a/gtk/gtkcssrulelist.c
+++ b/gtk/gtkcssrulelist.c
@@ -77,6 +77,8 @@ gtk_css_rule_list_parse (GtkCssRuleList    *rule_list,
   g_return_if_fail (parent_rule == NULL || GTK_IS_CSS_RULE (parent_rule));
   g_return_if_fail (GTK_IS_CSS_STYLE_SHEET (parent_style_sheet));
 
+  gtk_css_token_source_set_consumer (source, G_OBJECT (rule_list));
+
   for (token = gtk_css_token_source_get_token (source);
        token->type != GTK_CSS_TOKEN_EOF;
        token = gtk_css_token_source_get_token (source))
diff --git a/gtk/gtkcssselector.c b/gtk/gtkcssselector.c
index c0f9ef0..fd537d3 100644
--- a/gtk/gtkcssselector.c
+++ b/gtk/gtkcssselector.c
@@ -1590,7 +1590,7 @@ token_parse_selector_pseudo_class (GtkCssTokenSource *source,
 
               if (gtk_css_token_is_delim (token, '*'))
                 {
-                  selector = gtk_css_selector_new (&GTK_CSS_SELECTOR_ANY, selector);
+                  selector = gtk_css_selector_new (&GTK_CSS_SELECTOR_NOT_ANY, selector);
                   gtk_css_token_source_consume_token (source);
                 }
               else if (gtk_css_token_is (token, GTK_CSS_TOKEN_IDENT))
diff --git a/gtk/gtkcssstyledeclaration.c b/gtk/gtkcssstyledeclaration.c
index 8b19a5f..9560d33 100644
--- a/gtk/gtkcssstyledeclaration.c
+++ b/gtk/gtkcssstyledeclaration.c
@@ -73,6 +73,7 @@ gtk_css_style_declaration_parse (GtkCssStyleDeclaration *style,
   const GtkCssToken *token;
 
   priv = gtk_css_style_declaration_get_instance_private (style);
+  gtk_css_token_source_set_consumer (source, G_OBJECT (style));
 
   for (token = gtk_css_token_source_get_token (source);
        !gtk_css_token_is (token, GTK_CSS_TOKEN_EOF);
@@ -82,7 +83,6 @@ gtk_css_style_declaration_parse (GtkCssStyleDeclaration *style,
           gtk_css_token_is (token, GTK_CSS_TOKEN_WHITESPACE))
         {
           gtk_css_token_source_consume_token (source);
-          continue;
         }
       else if (gtk_css_token_is (token, GTK_CSS_TOKEN_IDENT))
         {
diff --git a/gtk/gtkcssstylerule.c b/gtk/gtkcssstylerule.c
index c9864ca..c40c9b6 100644
--- a/gtk/gtkcssstylerule.c
+++ b/gtk/gtkcssstylerule.c
@@ -68,7 +68,7 @@ gtk_css_style_rule_new (GtkCssRule       *parent_rule,
   return g_object_new (GTK_TYPE_CSS_STYLE_RULE, NULL);
 }
 
-static GtkCssStyleRule *
+static gboolean
 gtk_css_style_rule_parse_selectors (GtkCssStyleRule   *rule,
                                     GtkCssTokenSource *source)
 {
@@ -77,6 +77,8 @@ gtk_css_style_rule_parse_selectors (GtkCssStyleRule   *rule,
   GtkCssSelector *selector;
   const GtkCssToken *token;
 
+  gtk_css_token_source_set_consumer (source, G_OBJECT (rule));
+
   for (token = gtk_css_token_source_get_token (source);
        !gtk_css_token_is (token, GTK_CSS_TOKEN_EOF);
        token = gtk_css_token_source_get_token (source))
@@ -86,15 +88,13 @@ gtk_css_style_rule_parse_selectors (GtkCssStyleRule   *rule,
       selector = gtk_css_selector_token_parse (child_source);
       gtk_css_token_source_unref (child_source);
       if (selector == NULL)
-        {
-          g_object_unref (rule);
-          return NULL;
-        }
+        return FALSE;
+
       g_ptr_array_add (priv->selectors, selector);
       gtk_css_token_source_consume_token (source);
     }
 
-  return rule;
+  return TRUE;
 }
 
 GtkCssRule *
@@ -105,6 +105,7 @@ gtk_css_style_rule_new_parse (GtkCssTokenSource *source,
   GtkCssStyleRulePrivate *priv;
   GtkCssTokenSource *child_source;
   GtkCssStyleRule *rule;
+  gboolean success;
 
   g_return_val_if_fail (source != NULL, NULL);
   g_return_val_if_fail (parent_rule == NULL || GTK_IS_CSS_RULE (parent_rule), NULL);
@@ -113,19 +114,28 @@ gtk_css_style_rule_new_parse (GtkCssTokenSource *source,
   rule = GTK_CSS_STYLE_RULE (gtk_css_style_rule_new (parent_rule, parent_style_sheet));
   priv = gtk_css_style_rule_get_instance_private (rule);
 
+  gtk_css_token_source_set_consumer (source, G_OBJECT (rule));
   child_source = gtk_css_token_source_new_for_part (source, GTK_CSS_TOKEN_OPEN_CURLY);
-  rule = gtk_css_style_rule_parse_selectors (rule, child_source);
+  success = gtk_css_style_rule_parse_selectors (rule, child_source);
   gtk_css_token_source_unref (child_source);
 
   gtk_css_token_source_consume_token (source);
   child_source = gtk_css_token_source_new_for_part (source, GTK_CSS_TOKEN_CLOSE_CURLY);
-  if (rule == NULL)
-    gtk_css_token_source_consume_all (child_source);
-  else
+  if (success)
     gtk_css_style_declaration_parse (priv->style, child_source);
+  else
+    {
+      gtk_css_token_source_consume_all (child_source);
+    }
   gtk_css_token_source_unref (child_source);
   gtk_css_token_source_consume_token (source);
 
+  if (!success)
+    {
+      g_object_unref (rule);
+      return NULL;
+    }
+
   return GTK_CSS_RULE (rule);
 }
 
diff --git a/gtk/gtkcsstokensource.c b/gtk/gtkcsstokensource.c
index 09f8816..962d676 100644
--- a/gtk/gtkcsstokensource.c
+++ b/gtk/gtkcsstokensource.c
@@ -40,7 +40,8 @@ gtk_css_token_source_tokenizer_finalize (GtkCssTokenSource *source)
 }
 
 static void
-gtk_css_token_source_tokenizer_consume_token (GtkCssTokenSource *source)
+gtk_css_token_source_tokenizer_consume_token (GtkCssTokenSource *source,
+                                              GObject           *consumer)
 {
   GtkCssTokenSourceTokenizer *tok = (GtkCssTokenSourceTokenizer *) source;
 
@@ -54,9 +55,7 @@ gtk_css_token_source_tokenizer_get_token (GtkCssTokenSource   *source)
 
   if (gtk_css_token_is (&tok->current_token, GTK_CSS_TOKEN_EOF))
     {
-      do {
-       gtk_css_tokenizer_read_token (tok->tokenizer, &tok->current_token);
-      } while (gtk_css_token_is (&tok->current_token, GTK_CSS_TOKEN_COMMENT));
+      gtk_css_tokenizer_read_token (tok->tokenizer, &tok->current_token);
 
 #if 0
       if (!gtk_css_token_is (&tok->current_token, GTK_CSS_TOKEN_EOF)) {
@@ -121,7 +120,8 @@ gtk_css_token_source_part_finalize (GtkCssTokenSource *source)
 }
 
 static void
-gtk_css_token_source_part_consume_token (GtkCssTokenSource *source)
+gtk_css_token_source_part_consume_token (GtkCssTokenSource *source,
+                                         GObject           *consumer)
 {
   GtkCssTokenSourcePart *part = (GtkCssTokenSourcePart *) source;
   const GtkCssToken *token;
@@ -133,7 +133,7 @@ gtk_css_token_source_part_consume_token (GtkCssTokenSource *source)
         return;
     }
 
-  gtk_css_token_source_consume_token (part->source);
+  gtk_css_token_source_consume_token_as (part->source, consumer);
 }
 
 static const GtkCssToken *
@@ -179,6 +179,8 @@ gtk_css_token_source_new_for_part (GtkCssTokenSource *source,
   part = gtk_css_token_source_new (GtkCssTokenSourcePart, &GTK_CSS_TOKEN_SOURCE_PART);
   part->source = gtk_css_token_source_ref (source);
   part->end_type = end_type;
+  gtk_css_token_source_set_consumer (&part->parent,
+                                     gtk_css_token_source_get_consumer (source));
 
   return &part->parent;
 }
@@ -213,6 +215,8 @@ gtk_css_token_source_unref (GtkCssTokenSource *source)
 
   source->klass->finalize (source);
 
+  g_clear_object (&source->consumer);
+
   g_free (source);
 }
 
@@ -236,7 +240,7 @@ gtk_css_token_source_consume_token_as (GtkCssTokenSource *source,
         source->blocks = g_slist_remove (source->blocks, source->blocks->data);
     }
 
-  source->klass->consume_token (source);
+  source->klass->consume_token (source, consumer);
 
   token = gtk_css_token_source_get_token (source);
   switch (token->type)
@@ -267,7 +271,17 @@ gtk_css_token_source_consume_token_as (GtkCssTokenSource *source,
 const GtkCssToken *
 gtk_css_token_source_get_token (GtkCssTokenSource *source)
 {
-  return source->klass->get_token (source);
+  const GtkCssToken *token;
+
+  for (token = source->klass->get_token (source);
+       gtk_css_token_is (token, GTK_CSS_TOKEN_COMMENT);
+       token = source->klass->get_token (source))
+    {
+      /* use vfunc here to avoid infloop */
+      source->klass->consume_token (source, source->consumer);
+    }
+
+  return token;
 }
 
 void
@@ -386,3 +400,16 @@ gtk_css_token_source_deprecated (GtkCssTokenSource *source,
   va_end (args);
 }
 
+GObject *
+gtk_css_token_source_get_consumer (GtkCssTokenSource *source)
+{
+  return source->consumer;
+}
+
+void
+gtk_css_token_source_set_consumer (GtkCssTokenSource *source,
+                                   GObject           *consumer)
+{
+  g_set_object (&source->consumer, consumer);
+}
+
diff --git a/gtk/gtkcsstokensourceprivate.h b/gtk/gtkcsstokensourceprivate.h
index 5700251..6ddcbfa 100644
--- a/gtk/gtkcsstokensourceprivate.h
+++ b/gtk/gtkcsstokensourceprivate.h
@@ -32,13 +32,15 @@ struct _GtkCssTokenSource
 {
   const GtkCssTokenSourceClass *klass;
   gint ref_count;
+  GObject *consumer;
   GSList *blocks; /* of GPOINTER_TO_UINT(GtkCssTokenType) */
 };
 
 struct _GtkCssTokenSourceClass
 {
   void                  (* finalize)                            (GtkCssTokenSource      *source);
-  void                  (* consume_token)                       (GtkCssTokenSource      *source);
+  void                  (* consume_token)                       (GtkCssTokenSource      *source,
+                                                                 GObject                *consumer);
   const GtkCssToken *   (* get_token)                           (GtkCssTokenSource      *source);
   void                  (* error)                               (GtkCssTokenSource      *source,
                                                                  const GError           *error);
@@ -56,6 +58,8 @@ GtkCssTokenSource *     gtk_css_token_source_alloc              (gsize
                                                                  const GtkCssTokenSourceClass *klass);
 
 void                    gtk_css_token_source_consume_token      (GtkCssTokenSource      *source);
+void                    gtk_css_token_source_consume_token_as   (GtkCssTokenSource      *source,
+                                                                 GObject                *consumer);
 const GtkCssToken *     gtk_css_token_source_get_token          (GtkCssTokenSource      *source);
 
 GtkCssTokenType         gtk_css_token_get_pending_block         (GtkCssTokenSource      *source);
@@ -76,6 +80,11 @@ void                    gtk_css_token_source_deprecated         (GtkCssTokenSour
                                                                  const char             *format,
                                                                  ...) G_GNUC_PRINTF(2, 3);
 
+GObject *               gtk_css_token_source_get_consumer       (GtkCssTokenSource      *source);
+void                    gtk_css_token_source_set_consumer       (GtkCssTokenSource      *source,
+                                                                 GObject                *consumer);
+                                                                 
+
 
 G_END_DECLS
 


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