[gtk+/wip/otte/tokenizer: 14/42] css: Add gtk_style_property_token_parse()
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/wip/otte/tokenizer: 14/42] css: Add gtk_style_property_token_parse()
- Date: Sun, 20 Mar 2016 05:02:12 +0000 (UTC)
commit aa8d20471a5af399797aefb8878edb73bbbc0978
Author: Benjamin Otte <otte redhat com>
Date: Tue Mar 15 06:47:00 2016 +0100
css: Add gtk_style_property_token_parse()
Slowly move the token parser into CSS value parsing.
gtk/gtkcsscustomproperty.c | 9 +++
gtk/gtkcssdeclaration.c | 55 ++++++++---------
gtk/gtkcssparser.c | 2 +
gtk/gtkcssshorthandproperty.c | 109 ++++++++++++++++++++++++++++++++++
gtk/gtkcssshorthandpropertyprivate.h | 4 +
gtk/gtkcssstyleproperty.c | 76 +++++++++++++++++++++++
gtk/gtkcssstylepropertyprivate.h | 17 +++--
gtk/gtkstyleproperty.c | 50 +++++++++++++++
gtk/gtkstylepropertyprivate.h | 7 ++-
9 files changed, 292 insertions(+), 37 deletions(-)
---
diff --git a/gtk/gtkcsscustomproperty.c b/gtk/gtkcsscustomproperty.c
index f210ad3..3b65bac 100644
--- a/gtk/gtkcsscustomproperty.c
+++ b/gtk/gtkcsscustomproperty.c
@@ -43,6 +43,14 @@ gtk_css_custom_property_parse_value (GtkStyleProperty *property,
return NULL;
}
+static GtkCssValue *
+gtk_css_custom_property_token_parse (GtkStyleProperty *property,
+ GtkCssTokenSource *source)
+{
+ gtk_css_token_source_unknown (source, "Custom CSS properties are no longer supported.");
+ return NULL;
+}
+
static void
gtk_css_custom_property_query (GtkStyleProperty *property,
GValue *value,
@@ -81,6 +89,7 @@ _gtk_css_custom_property_class_init (GtkCssCustomPropertyClass *klass)
GtkStylePropertyClass *property_class = GTK_STYLE_PROPERTY_CLASS (klass);
property_class->parse_value = gtk_css_custom_property_parse_value;
+ property_class->token_parse = gtk_css_custom_property_token_parse;
property_class->query = gtk_css_custom_property_query;
property_class->assign = gtk_css_custom_property_assign;
}
diff --git a/gtk/gtkcssdeclaration.c b/gtk/gtkcssdeclaration.c
index 319c1fa..de40941 100644
--- a/gtk/gtkcssdeclaration.c
+++ b/gtk/gtkcssdeclaration.c
@@ -26,9 +26,8 @@
typedef struct _GtkCssDeclarationPrivate GtkCssDeclarationPrivate;
struct _GtkCssDeclarationPrivate {
GtkCssStyleDeclaration *style;
- char *name;
GtkStyleProperty *prop;
- char *value;
+ GtkCssValue *value;
};
G_DEFINE_TYPE_WITH_PRIVATE (GtkCssDeclaration, gtk_css_declaration, G_TYPE_OBJECT)
@@ -39,8 +38,8 @@ 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);
+ if (priv->value)
+ _gtk_css_value_unref (priv->value);
G_OBJECT_CLASS (gtk_css_declaration_parent_class)->finalize (object);
}
@@ -59,30 +58,13 @@ 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)
{
GtkCssDeclarationPrivate *priv;
const GtkCssToken *token;
GtkCssDeclaration *decl;
+ char *name;
decl = g_object_new (GTK_TYPE_CSS_DECLARATION, NULL);
priv = gtk_css_declaration_get_instance_private (decl);
@@ -99,25 +81,40 @@ gtk_css_declaration_new_parse (GtkCssStyleDeclaration *style,
g_object_unref (decl);
return NULL;
}
- priv->name = g_strdup (token->string.string);
- priv->prop = _gtk_style_property_lookup (priv->name);
+ name = g_utf8_strdown (token->string.string, -1);
+ priv->prop = _gtk_style_property_lookup (name);
if (priv->prop == NULL)
- gtk_css_token_source_unknown (source, "Unknown property name '%s'", priv->name);
- else if (!g_str_equal (priv->name, _gtk_style_property_get_name (priv->prop)))
+ {
+ gtk_css_token_source_unknown (source, "Unknown property name '%s'", token->string.string);
+ gtk_css_token_source_consume_all (source);
+ g_object_unref (decl);
+ g_free (name);
+ return NULL;
+ }
+ else if (!g_str_equal (name, _gtk_style_property_get_name (priv->prop)))
gtk_css_token_source_deprecated (source,
"The '%s' property has been renamed to '%s'",
- priv->name, _gtk_style_property_get_name (priv->prop));
+ name, _gtk_style_property_get_name (priv->prop));
gtk_css_token_source_consume_token (source);
gtk_css_token_source_consume_whitespace (source);
+ g_free (name);
+
token = gtk_css_token_source_get_token (source);
if (!gtk_css_token_is (token, GTK_CSS_TOKEN_COLON))
{
+ gtk_css_token_source_error (source, "No colon following property name");
gtk_css_token_source_consume_all (source);
g_object_unref (decl);
return NULL;
}
-
- priv->value = gtk_css_token_source_consume_to_string (source);
+ gtk_css_token_source_consume_token (source);
+
+ priv->value = gtk_style_property_token_parse (priv->prop, source);
+ if (priv->value == NULL)
+ {
+ g_object_unref (decl);
+ return NULL;
+ }
return decl;
}
diff --git a/gtk/gtkcssparser.c b/gtk/gtkcssparser.c
index 2a732e6..4cfd20a 100644
--- a/gtk/gtkcssparser.c
+++ b/gtk/gtkcssparser.c
@@ -75,6 +75,7 @@ do_the_tokenizer (const char *data)
gtk_css_tokenizer_unref (tokenizer);
#else
+#if 0
GtkCssStyleSheet *sheet;
GtkCssTokenSource *source;
GtkCssTokenizer *tokenizer;
@@ -91,6 +92,7 @@ do_the_tokenizer (const char *data)
gtk_css_tokenizer_unref (tokenizer);
g_bytes_unref (bytes);
#endif
+#endif
}
GtkCssParser *
diff --git a/gtk/gtkcssshorthandproperty.c b/gtk/gtkcssshorthandproperty.c
index 5e05761..34f83bc 100644
--- a/gtk/gtkcssshorthandproperty.c
+++ b/gtk/gtkcssshorthandproperty.c
@@ -156,6 +156,112 @@ gtk_css_shorthand_property_parse_value (GtkStyleProperty *property,
return result;
}
+static GtkCssValue *
+gtk_css_shorthand_property_token_parse (GtkStyleProperty *property,
+ GtkCssTokenSource *source)
+{
+ GtkCssShorthandProperty *shorthand = GTK_CSS_SHORTHAND_PROPERTY (property);
+ const GtkCssToken *token;
+ GtkCssValue **data;
+ GtkCssValue *result;
+ guint i;
+
+ data = g_new0 (GtkCssValue *, shorthand->subproperties->len);
+
+ token = gtk_css_token_source_get_token (source);
+ if (gtk_css_token_is_ident (token, "initial"))
+ {
+ /* the initial value can be explicitly specified with the
+ * ‘initial’ keyword which all properties accept.
+ */
+ for (i = 0; i < shorthand->subproperties->len; i++)
+ {
+ data[i] = _gtk_css_initial_value_new ();
+ }
+ gtk_css_token_source_consume_token (source);
+ }
+ else if (gtk_css_token_is_ident (token, "inherit"))
+ {
+ /* All properties accept the ‘inherit’ value which
+ * explicitly specifies that the value will be determined
+ * by inheritance. The ‘inherit’ value can be used to
+ * strengthen inherited values in the cascade, and it can
+ * also be used on properties that are not normally inherited.
+ */
+ for (i = 0; i < shorthand->subproperties->len; i++)
+ {
+ data[i] = _gtk_css_inherit_value_new ();
+ }
+ gtk_css_token_source_consume_token (source);
+ }
+ else if (gtk_css_token_is_ident (token, "unset"))
+ {
+ /* If the cascaded value of a property is the unset keyword,
+ * then if it is an inherited property, this is treated as
+ * inherit, and if it is not, this is treated as initial.
+ */
+ for (i = 0; i < shorthand->subproperties->len; i++)
+ {
+ data[i] = _gtk_css_unset_value_new ();
+ }
+ gtk_css_token_source_consume_token (source);
+ }
+ else if (!shorthand->token_parse (shorthand, data, source))
+ {
+ for (i = 0; i < shorthand->subproperties->len; i++)
+ {
+ if (data[i] != NULL)
+ _gtk_css_value_unref (data[i]);
+ }
+ g_free (data);
+ return NULL;
+ }
+
+ /* All values that aren't set by the parse func are set to their
+ * default values here.
+ * XXX: Is the default always initial or can it be inherit? */
+ for (i = 0; i < shorthand->subproperties->len; i++)
+ {
+ if (data[i] == NULL)
+ data[i] = _gtk_css_initial_value_new ();
+ }
+
+ result = _gtk_css_array_value_new_from_array (data, shorthand->subproperties->len);
+ g_free (data);
+
+ return result;
+}
+
+static void
+forward_error_to_source (GtkCssParser *parser,
+ const GError *error,
+ gpointer source)
+{
+ /* XXX: This is bad because it doesn't emit the error on the right token */
+ gtk_css_token_source_emit_error (source, error);
+}
+
+static gboolean
+gtk_css_shorthand_token_parse_default (GtkCssShorthandProperty *shorthand,
+ GtkCssValue **values,
+ GtkCssTokenSource *source)
+{
+ GtkCssParser *parser;
+ char *str;
+ gboolean result;
+
+ str = gtk_css_token_source_consume_to_string (source);
+ parser = _gtk_css_parser_new (str,
+ NULL,
+ forward_error_to_source,
+ source);
+ result = shorthand->parse (shorthand, values, parser);
+ _gtk_css_parser_free (parser);
+ g_free (str);
+
+ return result;
+}
+
static void
_gtk_css_shorthand_property_class_init (GtkCssShorthandPropertyClass *klass)
{
@@ -175,12 +281,15 @@ _gtk_css_shorthand_property_class_init (GtkCssShorthandPropertyClass *klass)
property_class->assign = _gtk_css_shorthand_property_assign;
property_class->query = _gtk_css_shorthand_property_query;
property_class->parse_value = gtk_css_shorthand_property_parse_value;
+ property_class->token_parse = gtk_css_shorthand_property_token_parse;
}
static void
_gtk_css_shorthand_property_init (GtkCssShorthandProperty *shorthand)
{
shorthand->subproperties = g_ptr_array_new_with_free_func (g_object_unref);
+
+ shorthand->token_parse = gtk_css_shorthand_token_parse_default;
}
GtkCssStyleProperty *
diff --git a/gtk/gtkcssshorthandpropertyprivate.h b/gtk/gtkcssshorthandpropertyprivate.h
index d548370..55d4af4 100644
--- a/gtk/gtkcssshorthandpropertyprivate.h
+++ b/gtk/gtkcssshorthandpropertyprivate.h
@@ -41,6 +41,9 @@ typedef struct _GtkCssShorthandPropertyClass GtkCssShorthandPropertyClass;
typedef gboolean (* GtkCssShorthandPropertyParseFunc) (GtkCssShorthandProperty *shorthand,
GtkCssValue **values,
GtkCssParser *parser);
+typedef gboolean (* GtkCssShorthandPropertyTokenParseFunc) (GtkCssShorthandProperty *shorthand,
+ GtkCssValue **values,
+ GtkCssTokenSource *source);
typedef void (* GtkCssShorthandPropertyAssignFunc) (GtkCssShorthandProperty *shorthand,
GtkStyleProperties *props,
GtkStateFlags state,
@@ -57,6 +60,7 @@ struct _GtkCssShorthandProperty
GPtrArray *subproperties;
GtkCssShorthandPropertyParseFunc parse;
+ GtkCssShorthandPropertyTokenParseFunc token_parse;
GtkCssShorthandPropertyAssignFunc assign;
GtkCssShorthandPropertyQueryFunc query;
};
diff --git a/gtk/gtkcssstyleproperty.c b/gtk/gtkcssstyleproperty.c
index e4d3f8f..6379151 100644
--- a/gtk/gtkcssstyleproperty.c
+++ b/gtk/gtkcssstyleproperty.c
@@ -193,6 +193,80 @@ gtk_css_style_property_parse_value (GtkStyleProperty *property,
}
static void
+forward_error_to_source (GtkCssParser *parser,
+ const GError *error,
+ gpointer source)
+{
+ /* XXX: This is bad because it doesn't emit the error on the right token */
+ gtk_css_token_source_emit_error (source, error);
+}
+
+static GtkCssValue *
+gtk_css_style_property_token_parse_default (GtkCssStyleProperty *property,
+ GtkCssTokenSource *source)
+{
+ GtkCssParser *parser;
+ GtkCssValue *value;
+ char *str;
+
+ str = gtk_css_token_source_consume_to_string (source);
+ parser = _gtk_css_parser_new (str,
+ NULL,
+ forward_error_to_source,
+ source);
+ value = property->parse_value (property, parser);
+ _gtk_css_parser_free (parser);
+ g_free (str);
+
+ return value;
+}
+
+static GtkCssValue *
+gtk_css_style_property_token_parse (GtkStyleProperty *property,
+ GtkCssTokenSource *source)
+{
+ GtkCssStyleProperty *style_property = GTK_CSS_STYLE_PROPERTY (property);
+ const GtkCssToken *token;
+ GtkCssValue *value;
+
+ token = gtk_css_token_source_get_token (source);
+ if (gtk_css_token_is_ident (token, "initial"))
+ {
+ /* the initial value can be explicitly specified with the
+ * ‘initial’ keyword which all properties accept.
+ */
+ value = _gtk_css_initial_value_new ();
+ gtk_css_token_source_consume_token (source);
+ }
+ else if (gtk_css_token_is_ident (token, "inherit"))
+ {
+ /* All properties accept the ‘inherit’ value which
+ * explicitly specifies that the value will be determined
+ * by inheritance. The ‘inherit’ value can be used to
+ * strengthen inherited values in the cascade, and it can
+ * also be used on properties that are not normally inherited.
+ */
+ value = _gtk_css_inherit_value_new ();
+ gtk_css_token_source_consume_token (source);
+ }
+ else if (gtk_css_token_is_ident (token, "unset"))
+ {
+ /* If the cascaded value of a property is the unset keyword,
+ * then if it is an inherited property, this is treated as
+ * inherit, and if it is not, this is treated as initial.
+ */
+ value = _gtk_css_unset_value_new ();
+ gtk_css_token_source_consume_token (source);
+ }
+ else
+ {
+ value = (* style_property->token_parse) (style_property, source);
+ }
+
+ return value;
+}
+
+static void
_gtk_css_style_property_class_init (GtkCssStylePropertyClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
@@ -242,6 +316,7 @@ _gtk_css_style_property_class_init (GtkCssStylePropertyClass *klass)
property_class->assign = _gtk_css_style_property_assign;
property_class->query = _gtk_css_style_property_query;
property_class->parse_value = gtk_css_style_property_parse_value;
+ property_class->token_parse = gtk_css_style_property_token_parse;
klass->style_properties = g_ptr_array_new ();
@@ -260,6 +335,7 @@ static void
_gtk_css_style_property_init (GtkCssStyleProperty *property)
{
property->parse_value = gtk_css_style_property_real_parse_value;
+ property->token_parse = gtk_css_style_property_token_parse_default;
}
/**
diff --git a/gtk/gtkcssstylepropertyprivate.h b/gtk/gtkcssstylepropertyprivate.h
index 2dbe6ed..c78f81f 100644
--- a/gtk/gtkcssstylepropertyprivate.h
+++ b/gtk/gtkcssstylepropertyprivate.h
@@ -34,13 +34,15 @@ G_BEGIN_DECLS
typedef struct _GtkCssStyleProperty GtkCssStyleProperty;
typedef struct _GtkCssStylePropertyClass GtkCssStylePropertyClass;
-typedef GtkCssValue * (* GtkCssStylePropertyParseFunc) (GtkCssStyleProperty *property,
- GtkCssParser *parser);
-typedef void (* GtkCssStylePropertyQueryFunc) (GtkCssStyleProperty *property,
- const GtkCssValue *cssvalue,
- GValue *value);
-typedef GtkCssValue * (* GtkCssStylePropertyAssignFunc) (GtkCssStyleProperty *property,
- const GValue *value);
+typedef GtkCssValue * (* GtkCssStylePropertyParseFunc) (GtkCssStyleProperty *property,
+ GtkCssParser *parser);
+typedef GtkCssValue * (* GtkCssStylePropertyTokenParseFunc) (GtkCssStyleProperty *property,
+ GtkCssTokenSource *source);
+typedef void (* GtkCssStylePropertyQueryFunc) (GtkCssStyleProperty *property,
+ const GtkCssValue *cssvalue,
+ GValue *value);
+typedef GtkCssValue * (* GtkCssStylePropertyAssignFunc) (GtkCssStyleProperty *property,
+ const GValue *value);
struct _GtkCssStyleProperty
{
GtkStyleProperty parent;
@@ -52,6 +54,7 @@ struct _GtkCssStyleProperty
guint animated :1;
GtkCssStylePropertyParseFunc parse_value;
+ GtkCssStylePropertyTokenParseFunc token_parse;
GtkCssStylePropertyQueryFunc query_value;
GtkCssStylePropertyAssignFunc assign_value;
};
diff --git a/gtk/gtkstyleproperty.c b/gtk/gtkstyleproperty.c
index 9639ae4..75279aa 100644
--- a/gtk/gtkstyleproperty.c
+++ b/gtk/gtkstyleproperty.c
@@ -159,6 +159,56 @@ _gtk_style_property_parse_value (GtkStyleProperty *property,
}
/**
+ * _gtk_style_property_parse_value:
+ * @property: the property
+ * @parser: the parser to parse from
+ *
+ * Tries to parse the given @property from the given @parser into
+ * @value. The type that @value will be assigned is dependant on
+ * the parser and no assumptions must be made about it. If the
+ * parsing fails, %FALSE will be returned and @value will be
+ * left uninitialized.
+ *
+ * Only if @property is a #GtkCssShorthandProperty, the @value will
+ * always be a #GtkCssValue whose values can be queried with
+ * _gtk_css_array_value_get_nth().
+ *
+ * Returns: %NULL on failure or the parsed #GtkCssValue
+ **/
+GtkCssValue *
+gtk_style_property_token_parse (GtkStyleProperty *property,
+ GtkCssTokenSource *source)
+{
+ GtkStylePropertyClass *klass;
+ GtkCssValue *value;
+
+ g_return_val_if_fail (GTK_IS_STYLE_PROPERTY (property), NULL);
+ g_return_val_if_fail (source != NULL, NULL);
+
+ klass = GTK_STYLE_PROPERTY_GET_CLASS (property);
+
+ gtk_css_token_source_consume_whitespace (source);
+
+ value = klass->token_parse (property, source);
+
+ if (value == NULL)
+ return NULL;
+
+ gtk_css_token_source_consume_whitespace (source);
+
+ if (!gtk_css_token_is (gtk_css_token_source_get_token (source),
+ GTK_CSS_TOKEN_EOF))
+ {
+ gtk_css_token_source_error (source, "Junk at end of value");
+ gtk_css_token_source_consume_all (source);
+ _gtk_css_value_unref (value);
+ return NULL;
+ }
+
+ return value;
+}
+
+/**
* _gtk_style_property_assign:
* @property: the property
* @props: The properties to assign to
diff --git a/gtk/gtkstylepropertyprivate.h b/gtk/gtkstylepropertyprivate.h
index 59b281f..d7ff8ab 100644
--- a/gtk/gtkstylepropertyprivate.h
+++ b/gtk/gtkstylepropertyprivate.h
@@ -19,6 +19,7 @@
#define __GTK_STYLEPROPERTY_PRIVATE_H__
#include "gtkcssparserprivate.h"
+#include "gtkcsstokensourceprivate.h"
#include "gtkstylecontextprivate.h"
#include "gtkcssvalueprivate.h"
@@ -57,8 +58,10 @@ struct _GtkStylePropertyClass
GValue *value,
GtkStyleQueryFunc query_func,
gpointer query_data);
- GtkCssValue * (* parse_value) (GtkStyleProperty * property,
+ GtkCssValue * (* parse_value) (GtkStyleProperty *property,
GtkCssParser *parser);
+ GtkCssValue * (* token_parse) (GtkStyleProperty *property,
+ GtkCssTokenSource *source);
GHashTable *properties;
};
@@ -76,6 +79,8 @@ const char * _gtk_style_property_get_name (GtkStyleProperty
GtkCssValue * _gtk_style_property_parse_value (GtkStyleProperty * property,
GtkCssParser *parser);
+GtkCssValue * gtk_style_property_token_parse (GtkStyleProperty *property,
+ GtkCssTokenSource *source);
GType _gtk_style_property_get_value_type(GtkStyleProperty * property);
void _gtk_style_property_query (GtkStyleProperty * property,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]