[gtk+/wip/otte/tokenizer: 9/78] css: Add code to parse declarations



commit 840d347d59d2ad7ab23495feaa6711efcf11ac68
Author: Benjamin Otte <otte redhat com>
Date:   Mon Mar 14 18:56:00 2016 +0100

    css: Add code to parse declarations
    
    We don't parse the values yet.

 gtk/Makefile.am                     |    2 +
 gtk/gtkcssdeclaration.c             |  108 +++++++++++++++++++++++++++++++++++
 gtk/gtkcssdeclarationprivate.h      |   55 ++++++++++++++++++
 gtk/gtkcssstyledeclaration.c        |   43 +++++++++++++-
 gtk/gtkcssstyledeclarationprivate.h |    8 ++-
 gtk/gtkcssstylerule.c               |   22 +++++++-
 gtk/gtkcssstyleruleprivate.h        |   11 ++-
 gtk/gtkcsstokensource.c             |   19 ++++++
 gtk/gtkcsstokensourceprivate.h      |    1 +
 9 files changed, 259 insertions(+), 10 deletions(-)
---
diff --git a/gtk/Makefile.am b/gtk/Makefile.am
index c7aba5c..924d90b 100644
--- a/gtk/Makefile.am
+++ b/gtk/Makefile.am
@@ -397,6 +397,7 @@ gtk_private_h_sources =             \
        gtkcsscornervalueprivate.h      \
        gtkcsscustomgadgetprivate.h     \
        gtkcsscustompropertyprivate.h   \
+       gtkcssdeclarationprivate.h      \
        gtkcssdimensionvalueprivate.h   \
        gtkcsseasevalueprivate.h        \
        gtkcssenginevalueprivate.h      \
@@ -673,6 +674,7 @@ gtk_base_c_sources =                \
        gtkcsscornervalue.c     \
        gtkcsscustomgadget.c    \
        gtkcsscustomproperty.c  \
+       gtkcssdeclaration.c     \
        gtkcssdimensionvalue.c  \
        gtkcsseasevalue.c       \
        gtkcssenumvalue.c       \
diff --git a/gtk/gtkcssdeclaration.c b/gtk/gtkcssdeclaration.c
new file mode 100644
index 0000000..f8c1c74
--- /dev/null
+++ b/gtk/gtkcssdeclaration.c
@@ -0,0 +1,108 @@
+/*
+ * Copyright © 2016 Red Hat Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Benjamin Otte <otte gnome org>
+ */
+
+#include "config.h"
+
+#include "gtkcssdeclarationprivate.h"
+
+typedef struct _GtkCssDeclarationPrivate GtkCssDeclarationPrivate;
+struct _GtkCssDeclarationPrivate {
+  GtkCssStyleDeclaration *style;
+  char *name;
+  char *value;
+};
+
+G_DEFINE_TYPE_WITH_PRIVATE (GtkCssDeclaration, gtk_css_declaration, G_TYPE_OBJECT)
+
+static void
+gtk_css_declaration_finalize (GObject *object)
+{
+  GtkCssDeclaration *declaration = GTK_CSS_DECLARATION (object);
+  GtkCssDeclarationPrivate *priv = gtk_css_declaration_get_instance_private (declaration);
+
+  g_free (priv->name);
+  g_free (priv->value);
+
+  G_OBJECT_CLASS (gtk_css_declaration_parent_class)->finalize (object);
+}
+
+static void
+gtk_css_declaration_class_init (GtkCssDeclarationClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->finalize = gtk_css_declaration_finalize;
+}
+
+static void
+gtk_css_declaration_init (GtkCssDeclaration *declaration)
+{
+}
+
+GtkCssDeclaration *
+gtk_css_declaration_new (GtkCssStyleDeclaration *style,
+                         const char             *name,
+                         const char             *value)
+{
+  GtkCssDeclarationPrivate *priv;
+  GtkCssDeclaration *result;
+
+  result = g_object_new (GTK_TYPE_CSS_DECLARATION, NULL);
+  priv = gtk_css_declaration_get_instance_private (result);
+
+  priv->style = style;
+  priv->name = g_strdup (name);
+  priv->value = g_strdup (value);
+
+  return result;
+}
+
+GtkCssDeclaration *
+gtk_css_declaration_new_parse (GtkCssStyleDeclaration *style,
+                               GtkCssTokenSource      *source)
+{
+  const GtkCssToken *token;
+  GtkCssDeclaration *decl;
+  char *name, *value;
+
+  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);
+      return NULL;
+    }
+  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);
+      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);
+
+  return decl;
+}
diff --git a/gtk/gtkcssdeclarationprivate.h b/gtk/gtkcssdeclarationprivate.h
new file mode 100644
index 0000000..ad7ef78
--- /dev/null
+++ b/gtk/gtkcssdeclarationprivate.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright © 2016 Red Hat Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Benjamin Otte <otte gnome org>
+ */
+
+#ifndef __GTK_CSS_DECLARATION_PRIVATE_H__
+#define __GTK_CSS_DECLARATION_PRIVATE_H__
+
+#include "gtk/gtkcssstyledeclarationprivate.h"
+
+G_BEGIN_DECLS
+
+#define GTK_TYPE_CSS_DECLARATION           (gtk_css_declaration_get_type ())
+#define GTK_CSS_DECLARATION(obj)           (G_TYPE_CHECK_INSTANCE_CAST (obj, GTK_TYPE_CSS_DECLARATION, 
GtkCssDeclaration))
+#define GTK_CSS_DECLARATION_CLASS(cls)     (G_TYPE_CHECK_CLASS_CAST (cls, GTK_TYPE_CSS_DECLARATION, 
GtkCssDeclarationClass))
+#define GTK_IS_CSS_DECLARATION(obj)        (G_TYPE_CHECK_INSTANCE_TYPE (obj, GTK_TYPE_CSS_DECLARATION))
+#define GTK_IS_CSS_DECLARATION_CLASS(obj)  (G_TYPE_CHECK_CLASS_TYPE (obj, GTK_TYPE_CSS_DECLARATION))
+#define GTK_CSS_DECLARATION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_CSS_DECLARATION, 
GtkCssDeclarationClass))
+
+typedef struct _GtkCssDeclaration           GtkCssDeclaration;
+typedef struct _GtkCssDeclarationClass      GtkCssDeclarationClass;
+
+struct _GtkCssDeclaration
+{
+  GObject parent;
+};
+
+struct _GtkCssDeclarationClass
+{
+  GObjectClass parent_class;
+};
+
+GType                   gtk_css_declaration_get_type            (void) G_GNUC_CONST;
+  
+GtkCssDeclaration *     gtk_css_declaration_new_parse           (GtkCssStyleDeclaration *style,
+                                                                 GtkCssTokenSource      *source);
+
+
+G_END_DECLS
+
+#endif /* __GTK_CSS_DECLARATION_PRIVATE_H__ */
diff --git a/gtk/gtkcssstyledeclaration.c b/gtk/gtkcssstyledeclaration.c
index a543a2c..8b19a5f 100644
--- a/gtk/gtkcssstyledeclaration.c
+++ b/gtk/gtkcssstyledeclaration.c
@@ -21,8 +21,7 @@
 
 #include "gtkcssstyledeclarationprivate.h"
 
-#include "gtkcssselectorprivate.h"
-#include "gtkcssstylesheetprivate.h"
+#include "gtkcssdeclarationprivate.h"
 
 typedef struct _GtkCssStyleDeclarationPrivate GtkCssStyleDeclarationPrivate;
 struct _GtkCssStyleDeclarationPrivate {
@@ -64,3 +63,43 @@ gtk_css_style_declaration_new (GtkCssRule *parent_rule)
   return g_object_new (GTK_TYPE_CSS_STYLE_DECLARATION, NULL);
 }
 
+void
+gtk_css_style_declaration_parse (GtkCssStyleDeclaration *style,
+                                 GtkCssTokenSource      *source)
+{
+  GtkCssStyleDeclarationPrivate *priv;
+  GtkCssTokenSource *decl_source;
+  GtkCssDeclaration *declaration;
+  const GtkCssToken *token;
+
+  priv = gtk_css_style_declaration_get_instance_private (style);
+
+  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))
+    {
+      if (gtk_css_token_is (token, GTK_CSS_TOKEN_SEMICOLON) ||
+          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))
+        {
+          decl_source = gtk_css_token_source_new_for_part (source, GTK_CSS_TOKEN_SEMICOLON);
+          declaration = gtk_css_declaration_new_parse (style, decl_source);
+          if (declaration)
+            g_ptr_array_add (priv->declarations, declaration);
+          gtk_css_token_source_unref (decl_source);
+          gtk_css_token_source_consume_token (source);
+        }
+      else
+        {
+          gtk_css_token_source_error (source, "Expected property declaration");
+          decl_source = gtk_css_token_source_new_for_part (source, GTK_CSS_TOKEN_SEMICOLON);
+          gtk_css_token_source_consume_all (decl_source);
+          gtk_css_token_source_unref (decl_source);
+          gtk_css_token_source_consume_token (source);
+        }
+    }
+}
diff --git a/gtk/gtkcssstyledeclarationprivate.h b/gtk/gtkcssstyledeclarationprivate.h
index 14ca8e0..a6303e7 100644
--- a/gtk/gtkcssstyledeclarationprivate.h
+++ b/gtk/gtkcssstyledeclarationprivate.h
@@ -48,12 +48,16 @@ GType                   gtk_css_style_declaration_get_type              (void) G
 
 GtkCssStyleDeclaration *gtk_css_style_declaration_new                   (GtkCssRule             
*parent_rule);
 
+void                    gtk_css_style_declaration_parse                 (GtkCssStyleDeclaration *style,
+                                                                         GtkCssTokenSource      *source);
+
+/* GtkCssStyleDeclaration DOM */
 void                    gtk_css_style_declaration_print_css_text        (GtkCssStyleDeclaration *declaration,
                                                                          GString                *string);
 char *                  gtk_css_style_declaration_get_css_text          (GtkCssStyleDeclaration 
*declaration);
-
-/* GtkCssStyleDeclaration DOM */
 gsize                   gtk_css_style_declaration_get_length            (GtkCssStyleDeclaration 
*declaration);
+char *                  gtk_css_style_declaration_get_item              (GtkCssStyleDeclaration *declaration,
+                                                                         gssize                  size);
 
 
 G_END_DECLS
diff --git a/gtk/gtkcssstylerule.c b/gtk/gtkcssstylerule.c
index 74df7fa..c9864ca 100644
--- a/gtk/gtkcssstylerule.c
+++ b/gtk/gtkcssstylerule.c
@@ -27,7 +27,7 @@
 typedef struct _GtkCssStyleRulePrivate GtkCssStyleRulePrivate;
 struct _GtkCssStyleRulePrivate {
   GPtrArray *selectors;
-  //GtkCssStyleDeclaration *declaration;
+  GtkCssStyleDeclaration *style;
 };
 
 G_DEFINE_TYPE_WITH_PRIVATE (GtkCssStyleRule, gtk_css_style_rule, GTK_TYPE_CSS_RULE)
@@ -39,6 +39,7 @@ gtk_css_style_rule_finalize (GObject *object)
   GtkCssStyleRulePrivate *priv = gtk_css_style_rule_get_instance_private (style_rule);
 
   g_ptr_array_unref (priv->selectors);
+  g_object_unref (priv->style);
 
   G_OBJECT_CLASS (gtk_css_style_rule_parent_class)->finalize (object);
 }
@@ -57,6 +58,7 @@ gtk_css_style_rule_init (GtkCssStyleRule *style_rule)
   GtkCssStyleRulePrivate *priv = gtk_css_style_rule_get_instance_private (style_rule);
 
   priv->selectors = g_ptr_array_new_with_free_func ((GDestroyNotify) _gtk_css_selector_free);
+  priv->style = gtk_css_style_declaration_new (GTK_CSS_RULE (style_rule));
 }
 
 static GtkCssRule *
@@ -100,6 +102,7 @@ gtk_css_style_rule_new_parse (GtkCssTokenSource *source,
                               GtkCssRule        *parent_rule,
                               GtkCssStyleSheet  *parent_style_sheet)
 {
+  GtkCssStyleRulePrivate *priv;
   GtkCssTokenSource *child_source;
   GtkCssStyleRule *rule;
 
@@ -108,6 +111,7 @@ gtk_css_style_rule_new_parse (GtkCssTokenSource *source,
   g_return_val_if_fail (GTK_IS_CSS_STYLE_SHEET (parent_style_sheet), NULL);
 
   rule = GTK_CSS_STYLE_RULE (gtk_css_style_rule_new (parent_rule, parent_style_sheet));
+  priv = gtk_css_style_rule_get_instance_private (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);
@@ -115,10 +119,24 @@ gtk_css_style_rule_new_parse (GtkCssTokenSource *source,
 
   gtk_css_token_source_consume_token (source);
   child_source = gtk_css_token_source_new_for_part (source, GTK_CSS_TOKEN_CLOSE_CURLY);
-  gtk_css_token_source_consume_all (child_source);
+  if (rule == NULL)
+    gtk_css_token_source_consume_all (child_source);
+  else
+    gtk_css_style_declaration_parse (priv->style, child_source);
   gtk_css_token_source_unref (child_source);
   gtk_css_token_source_consume_token (source);
 
   return GTK_CSS_RULE (rule);
 }
 
+GtkCssStyleDeclaration *
+gtk_css_style_rule_get_style (GtkCssStyleRule *rule)
+{
+  GtkCssStyleRulePrivate *priv;
+
+  g_return_val_if_fail (GTK_IS_CSS_STYLE_RULE (rule), NULL);
+
+  priv = gtk_css_style_rule_get_instance_private (rule);
+
+  return priv->style;
+}
diff --git a/gtk/gtkcssstyleruleprivate.h b/gtk/gtkcssstyleruleprivate.h
index ef5b936..1b60ec0 100644
--- a/gtk/gtkcssstyleruleprivate.h
+++ b/gtk/gtkcssstyleruleprivate.h
@@ -21,6 +21,7 @@
 #define __GTK_CSS_STYLE_RULE_PRIVATE_H__
 
 #include "gtk/gtkcssruleprivate.h"
+#include "gtk/gtkcssstyledeclarationprivate.h"
 
 G_BEGIN_DECLS
 
@@ -44,11 +45,13 @@ struct _GtkCssStyleRuleClass
   GtkCssRuleClass parent_class;
 };
 
-GType                  gtk_css_style_rule_get_type         (void) G_GNUC_CONST;
+GType                   gtk_css_style_rule_get_type             (void) G_GNUC_CONST;
 
-GtkCssRule *           gtk_css_style_rule_new_parse        (GtkCssTokenSource           *source,
-                                                            GtkCssRule                  *parent_rule,
-                                                            GtkCssStyleSheet            *parent_style_sheet);
+GtkCssRule *            gtk_css_style_rule_new_parse            (GtkCssTokenSource      *source,
+                                                                 GtkCssRule             *parent_rule,
+                                                                 GtkCssStyleSheet       *parent_style_sheet);
+
+GtkCssStyleDeclaration *gtk_css_style_rule_get_style            (GtkCssStyleRule        *rule);
 
 
 G_END_DECLS
diff --git a/gtk/gtkcsstokensource.c b/gtk/gtkcsstokensource.c
index 069cf9b..09f8816 100644
--- a/gtk/gtkcsstokensource.c
+++ b/gtk/gtkcsstokensource.c
@@ -283,6 +283,25 @@ gtk_css_token_source_consume_all (GtkCssTokenSource *source)
     }
 }
 
+char *
+gtk_css_token_source_consume_to_string (GtkCssTokenSource *source)
+{
+  GString *string;
+  const GtkCssToken *token;
+
+  string = g_string_new (NULL);
+
+  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))
+    {
+      gtk_css_token_print (token, string);
+      gtk_css_token_source_consume_token (source);
+    }
+
+  return g_string_free (string, FALSE);
+}
+
 gboolean
 gtk_css_token_source_consume_whitespace (GtkCssTokenSource *source)
 {
diff --git a/gtk/gtkcsstokensourceprivate.h b/gtk/gtkcsstokensourceprivate.h
index 7316c19..5700251 100644
--- a/gtk/gtkcsstokensourceprivate.h
+++ b/gtk/gtkcsstokensourceprivate.h
@@ -61,6 +61,7 @@ const GtkCssToken *     gtk_css_token_source_get_token          (GtkCssTokenSour
 GtkCssTokenType         gtk_css_token_get_pending_block         (GtkCssTokenSource      *source);
 
 void                    gtk_css_token_source_consume_all        (GtkCssTokenSource      *source);
+char *                  gtk_css_token_source_consume_to_string  (GtkCssTokenSource      *source);
 gboolean                gtk_css_token_source_consume_whitespace (GtkCssTokenSource      *source);
 
 void                    gtk_css_token_source_emit_error         (GtkCssTokenSource      *source,


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