[gtk+/wip/otte/tokenizer: 41/42] css: Add token parser for @import



commit 7b359cd0dd69b549b62883ad09ecd0975f2c67f0
Author: Benjamin Otte <otte redhat com>
Date:   Sun Mar 20 01:48:30 2016 +0100

    css: Add token parser for @import

 gtk/Makefile.am               |    2 +
 gtk/gtkcssimportrule.c        |  120 +++++++++++++++++++++++++++++++++++++++++
 gtk/gtkcssimportruleprivate.h |   56 +++++++++++++++++++
 gtk/gtkcssrule.c              |   32 +++++++----
 4 files changed, 198 insertions(+), 12 deletions(-)
---
diff --git a/gtk/Makefile.am b/gtk/Makefile.am
index 924d90b..47fb2e0 100644
--- a/gtk/Makefile.am
+++ b/gtk/Makefile.am
@@ -418,6 +418,7 @@ gtk_private_h_sources =             \
        gtkcssimagescaledprivate.h      \
        gtkcssimagevalueprivate.h       \
        gtkcssimagewin32private.h       \
+       gtkcssimportruleprivate.h       \
        gtkcssinheritvalueprivate.h     \
        gtkcssinitialvalueprivate.h     \
        gtkcsskeyframesprivate.h        \
@@ -695,6 +696,7 @@ gtk_base_c_sources =                \
        gtkcssimagescaled.c     \
        gtkcssimagevalue.c      \
        gtkcssimagewin32.c      \
+       gtkcssimportrule.c      \
        gtkcssinheritvalue.c    \
        gtkcssinitialvalue.c    \
        gtkcsskeyframes.c       \
diff --git a/gtk/gtkcssimportrule.c b/gtk/gtkcssimportrule.c
new file mode 100644
index 0000000..dd94389
--- /dev/null
+++ b/gtk/gtkcssimportrule.c
@@ -0,0 +1,120 @@
+/*
+ * 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 "gtkcssimportruleprivate.h"
+
+#include "gtkcssstylesheetprivate.h"
+
+typedef struct _GtkCssImportRulePrivate GtkCssImportRulePrivate;
+struct _GtkCssImportRulePrivate {
+  GFile *file;
+  GtkCssStyleSheet *style_sheet;
+};
+
+G_DEFINE_TYPE_WITH_PRIVATE (GtkCssImportRule, gtk_css_import_rule, GTK_TYPE_CSS_RULE)
+
+static void
+gtk_css_import_rule_finalize (GObject *object)
+{
+  GtkCssImportRule *import_rule = GTK_CSS_IMPORT_RULE (object);
+  GtkCssImportRulePrivate *priv = gtk_css_import_rule_get_instance_private (import_rule);
+
+  g_object_unref (priv->file);
+  g_object_unref (priv->style_sheet);
+
+  G_OBJECT_CLASS (gtk_css_import_rule_parent_class)->finalize (object);
+}
+
+static void
+gtk_css_import_rule_class_init (GtkCssImportRuleClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->finalize = gtk_css_import_rule_finalize;
+}
+
+static void
+gtk_css_import_rule_init (GtkCssImportRule *import_rule)
+{
+  GtkCssImportRulePrivate *priv = gtk_css_import_rule_get_instance_private (import_rule);
+
+  priv->style_sheet = gtk_css_style_sheet_new ();
+}
+
+static GtkCssRule *
+gtk_css_import_rule_new (GtkCssRule       *parent_rule,
+                         GtkCssStyleSheet *parent_style_sheet,
+                         GFile            *file)
+{
+  return g_object_new (GTK_TYPE_CSS_IMPORT_RULE, NULL);
+}
+
+GtkCssRule *
+gtk_css_import_rule_new_parse (GtkCssTokenSource *source,
+                               GtkCssRule        *parent_rule,
+                               GtkCssStyleSheet  *parent_style_sheet)
+{
+  const GtkCssToken *token;
+  GtkCssRule *result;
+  GFile *file;
+
+  g_return_val_if_fail (source != NULL, NULL);
+  g_return_val_if_fail (parent_rule == NULL || GTK_IS_CSS_RULE (parent_rule), NULL);
+  g_return_val_if_fail (GTK_IS_CSS_STYLE_SHEET (parent_style_sheet), NULL);
+
+  token = gtk_css_token_source_get_token (source);
+  if (token->type != GTK_CSS_TOKEN_AT_KEYWORD ||
+      g_ascii_strcasecmp (token->string.string, "import") != 0)
+    {
+      gtk_css_token_source_error (source, "Expected '@import'");
+      gtk_css_token_source_consume_all (source);
+      return NULL;
+    }
+  gtk_css_token_source_consume_token (source);
+
+  token = gtk_css_token_source_get_token (source);
+  if (gtk_css_token_is (token, GTK_CSS_TOKEN_STRING))
+    {
+      file = gtk_css_token_source_resolve_url (source, token->string.string);
+      gtk_css_token_source_consume_token (source);
+    }
+  else
+    {
+      file = gtk_css_token_source_consume_url (source);
+    }
+
+  if (file == NULL)
+    return NULL;
+
+  token = gtk_css_token_source_get_token (source);
+  if (!gtk_css_token_is (token, GTK_CSS_TOKEN_SEMICOLON))
+    {
+      gtk_css_token_source_error (source, "Expected ';' at end of @import");
+      gtk_css_token_source_consume_all (source);
+      return NULL;
+    }
+  gtk_css_token_source_consume_token (source);
+
+  result = gtk_css_import_rule_new (parent_rule, parent_style_sheet, file);
+  g_object_unref (file);
+  return result;
+}
+
diff --git a/gtk/gtkcssimportruleprivate.h b/gtk/gtkcssimportruleprivate.h
new file mode 100644
index 0000000..135a71f
--- /dev/null
+++ b/gtk/gtkcssimportruleprivate.h
@@ -0,0 +1,56 @@
+/*
+ * 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_IMPORT_RULE_PRIVATE_H__
+#define __GTK_CSS_IMPORT_RULE_PRIVATE_H__
+
+#include "gtk/gtkcssruleprivate.h"
+
+G_BEGIN_DECLS
+
+#define GTK_TYPE_CSS_IMPORT_RULE           (gtk_css_import_rule_get_type ())
+#define GTK_CSS_IMPORT_RULE(obj)           (G_TYPE_CHECK_INSTANCE_CAST (obj, GTK_TYPE_CSS_IMPORT_RULE, 
GtkCssImportRule))
+#define GTK_CSS_IMPORT_RULE_CLASS(cls)     (G_TYPE_CHECK_CLASS_CAST (cls, GTK_TYPE_CSS_IMPORT_RULE, 
GtkCssImportRuleClass))
+#define GTK_IS_CSS_IMPORT_RULE(obj)        (G_TYPE_CHECK_INSTANCE_TYPE (obj, GTK_TYPE_CSS_IMPORT_RULE))
+#define GTK_IS_CSS_IMPORT_RULE_CLASS(obj)  (G_TYPE_CHECK_CLASS_TYPE (obj, GTK_TYPE_CSS_IMPORT_RULE))
+#define GTK_CSS_IMPORT_RULE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_CSS_IMPORT_RULE, 
GtkCssImportRuleClass))
+
+typedef struct _GtkCssImportRule           GtkCssImportRule;
+typedef struct _GtkCssImportRuleClass      GtkCssImportRuleClass;
+
+struct _GtkCssImportRule
+{
+  GtkCssRule parent;
+};
+
+struct _GtkCssImportRuleClass
+{
+  GtkCssRuleClass parent_class;
+};
+
+GType                   gtk_css_import_rule_get_type            (void) G_GNUC_CONST;
+
+GtkCssRule *            gtk_css_import_rule_new_parse           (GtkCssTokenSource      *source,
+                                                                 GtkCssRule             *parent_rule,
+                                                                 GtkCssStyleSheet       *parent_style_sheet);
+
+
+G_END_DECLS
+
+#endif /* __GTK_CSS_IMPORT_RULE_PRIVATE_H__ */
diff --git a/gtk/gtkcssrule.c b/gtk/gtkcssrule.c
index cffd975..c0211ce 100644
--- a/gtk/gtkcssrule.c
+++ b/gtk/gtkcssrule.c
@@ -21,6 +21,7 @@
 
 #include "gtkcssruleprivate.h"
 
+#include "gtkcssimportruleprivate.h"
 #include "gtkcssstylesheetprivate.h"
 
 typedef struct _GtkCssRulePrivate GtkCssRulePrivate;
@@ -159,6 +160,7 @@ gtk_css_rule_new_from_at_rule (GtkCssTokenSource *source,
 {
   GtkCssTokenSource *at_source;
   const GtkCssToken *token;
+  GtkCssRule *rule;
 
   g_return_val_if_fail (source != NULL, NULL);
   g_return_val_if_fail (parent_rule == NULL || GTK_IS_CSS_RULE (parent_rule), NULL);
@@ -170,27 +172,33 @@ gtk_css_rule_new_from_at_rule (GtkCssTokenSource *source,
   if (token->type != GTK_CSS_TOKEN_AT_KEYWORD)
     {
       gtk_css_token_source_error (at_source, "Expected an '@'");
+      gtk_css_token_source_consume_all (at_source);
       gtk_css_token_source_unref (at_source);
       return NULL;
     }
+
+  if (g_ascii_strcasecmp (token->string.string, "import") == 0)
+    {
+      rule = gtk_css_import_rule_new_parse (at_source, parent_rule, parent_style_sheet);
+    }
   else
     {
-      const char *name = token->string.string;
-
-      if (g_ascii_strcasecmp (name, "import") == 0)
-        {
-          gtk_css_token_source_error (source, "Add code to parse @import here");
-        }
-      else
-        {
-          gtk_css_token_source_unknown (source, "Unknown rule @%s", name);
-        }
+      gtk_css_token_source_unknown (at_source, "Unknown rule @%s", token->string.string);
+      gtk_css_token_source_consume_all (at_source);
+      rule = NULL;
     }
 
-  gtk_css_token_source_consume_all (at_source);
+  token = gtk_css_token_source_get_token (at_source);
+  if (rule != NULL && !gtk_css_token_is (token, GTK_CSS_TOKEN_EOF))
+    {
+      gtk_css_token_source_unknown (at_source, "Junk at end of @-rule");
+      gtk_css_token_source_consume_all (at_source);
+      g_object_unref (rule);
+      rule = NULL;
+    }
   gtk_css_token_source_unref (at_source);
 
-  return NULL;
+  return rule;
 }
 
 void


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