[monet/monet-xml] mn-config: simplify the markup parser
- From: Thomas Wood <thos src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [monet/monet-xml] mn-config: simplify the markup parser
- Date: Sat, 11 Sep 2010 17:28:07 +0000 (UTC)
commit 204f4a1f8bc35d7ac871fb15a564ebbf69169d4a
Author: Thomas Wood <thos gnome org>
Date: Sat Sep 4 22:17:30 2010 +0100
mn-config: simplify the markup parser
Move the state tracking into the private structure and remove the use of
a sub-parser for widgets elements.
monet/mn-config.c | 376 +++++++++++++++++++++++++++--------------------------
1 files changed, 194 insertions(+), 182 deletions(-)
---
diff --git a/monet/mn-config.c b/monet/mn-config.c
index 22a2660..549b3ed 100644
--- a/monet/mn-config.c
+++ b/monet/mn-config.c
@@ -33,6 +33,10 @@ G_DEFINE_TYPE (MnConfig, mn_config, G_TYPE_OBJECT)
struct _MnConfigPrivate
{
GHashTable *colors;
+
+ MnDrawingOps *current_ops;
+ MnDrawingOp *current_op;
+ cairo_pattern_t *current_pattern;
};
static void
@@ -139,210 +143,185 @@ perror (GMarkupParseContext *context,
g_warning ("An error occured during parsing: %s", error->message);
}
-typedef struct state
-{
- MnDrawingOp *op;
- cairo_pattern_t *gradient;
-} MnConfigState;
-
-static MnConfigState state;
-
static void
-widget_start_element (GMarkupParseContext *context,
- const gchar *element_name,
- const gchar **attribute_names,
- const gchar **attribute_values,
- gpointer user_data,
- GError **error)
+add_pattern (MnConfig *config,
+ const gchar **names,
+ const gchar **values,
+ gboolean stroke)
{
- GSList **ops = (GSList **) user_data;
- const gchar **attr_n;
- int i;
+ MnConfigPrivate *priv = config->priv;
+ cairo_pattern_t *gradient;
+ double x_1, y_1, x_2, y_2;
+ gint i;
- /* check for gradient defition */
- if (!strcmp (element_name, "gradient")
- || !strcmp (element_name, "stroke-gradient"))
+ if (!priv->current_op)
{
- MnDrawingOp *op = state.op;
- cairo_pattern_t *gradient;
- double x_1, y_1, x_2, y_2;
-
- if (!op)
- {
- g_warning ("Gradient found outside of drawing operation");
- return;
- }
-
- /* inspect the attributes */
- for (attr_n = attribute_names, i = 0; *attr_n; attr_n++, i++)
- {
- if (!strcmp (*attr_n, "x1"))
- x_1 = g_ascii_strtod (attribute_values[i], NULL);
- else if (!strcmp (*attr_n, "y1"))
- y_1 = g_ascii_strtod (attribute_values[i], NULL);
- else if (!strcmp (*attr_n, "x2"))
- x_2 = g_ascii_strtod (attribute_values[i], NULL);
- else if (!strcmp (*attr_n, "y2"))
- y_2 = g_ascii_strtod (attribute_values[i], NULL);
- }
-
- gradient = cairo_pattern_create_linear (x_1, y_1, x_2, y_2);
+ g_warning ("Gradient found outside of drawing operation");
+ return;
+ }
- if (!strcmp (element_name, "stroke-gradient"))
- {
- if (op->stroke)
- cairo_pattern_destroy (op->stroke);
+ /* inspect the attributes */
+ for (i = 0; names[i]; i++)
+ {
+ if (!strcmp (names[i], "x1"))
+ x_1 = g_ascii_strtod (values[i], NULL);
+ else if (!strcmp (names[i], "y1"))
+ y_1 = g_ascii_strtod (values[i], NULL);
+ else if (!strcmp (names[i], "x2"))
+ x_2 = g_ascii_strtod (values[i], NULL);
+ else if (!strcmp (names[i], "y2"))
+ y_2 = g_ascii_strtod (values[i], NULL);
+ }
- op->stroke = gradient;
- }
- else
- {
- if (op->fill)
- cairo_pattern_destroy (op->fill);
+ gradient = cairo_pattern_create_linear (x_1, y_1, x_2, y_2);
- op->fill = gradient;
- }
+ if (stroke)
+ {
+ if (priv->current_op->stroke)
+ cairo_pattern_destroy (priv->current_op->stroke);
- state.gradient = gradient;
+ priv->current_op->stroke = gradient;
}
- else if (!strcmp (element_name, "stop"))
+ else
{
- double position;
- MnColor color;
+ if (priv->current_op->fill)
+ cairo_pattern_destroy (priv->current_op->fill);
- /* add the stop to the current gradient */
- if (!state.gradient)
- {
- g_warning ("stop found outside gradient");
- return;
- }
+ priv->current_op->fill = gradient;
+ }
- /* inspect the attributes */
- for (attr_n = attribute_names, i = 0; *attr_n; attr_n++, i++)
- {
- if (!strcmp (*attr_n, "color"))
- mn_color_from_string (&color, attribute_values[i]);
- else if (!strcmp (*attr_n, "position"))
- position = g_ascii_strtod (attribute_values[i], NULL);
- }
+ config->priv->current_pattern = gradient;
+}
+
+static void
+pattern_add_stop (cairo_pattern_t *pattern,
+ const gchar **names,
+ const gchar **values)
+{
+ double position;
+ MnColor color;
+ gint i;
- cairo_pattern_add_color_stop_rgba (state.gradient,
- position,
- color.red / 255.0,
- color.green / 255.0,
- color.blue / 255.0,
- color.alpha / 255.0);
+ /* add the stop to the current gradient */
+ if (!pattern)
+ {
+ g_warning ("stop found outside gradient");
+ return;
}
- else if (!strcmp (element_name, "rect"))
+ /* inspect the attributes */
+ for (i = 0; names[i]; i++)
{
- MnRectangleOp *op = g_slice_new0 (MnRectangleOp);
- ((MnDrawingOp*)op)->type = MN_RECT;
+ if (!strcmp (names[i], "color"))
+ mn_color_from_string (&color, values[i]);
+ else if (!strcmp (names[i], "position"))
+ position = g_ascii_strtod (values[i], NULL);
+ }
- state.op = (MnDrawingOp*) op;
+ cairo_pattern_add_color_stop_rgba (pattern,
+ position,
+ color.red / 255.0,
+ color.green / 255.0,
+ color.blue / 255.0,
+ color.alpha / 255.0);
+}
- /* inspect the attributes */
- for (attr_n = attribute_names, i = 0; *attr_n; attr_n++, i++)
- {
- if (!strcmp (*attr_n, "x"))
- op->x = g_ascii_strtod (attribute_values[i], NULL);
- else if (!strcmp (*attr_n, "y"))
- op->y = g_ascii_strtod (attribute_values[i], NULL);
- else if (!strcmp (*attr_n, "width"))
- op->width = g_strdup (attribute_values[i]);
- else if (!strcmp (*attr_n, "height"))
- op->height = g_strdup (attribute_values[i]);
- else if (!strcmp (*attr_n, "stroke"))
- ((MnDrawingOp*) op)->stroke = cairo_pattern_from_paint (attribute_values[i]);
- else if (!strcmp (*attr_n, "stroke-width"))
- ((MnDrawingOp*) op)->stroke_width = g_ascii_strtod (attribute_values[i], NULL);
- else if (!strcmp (*attr_n, "fill"))
- ((MnDrawingOp*)op)->fill = cairo_pattern_from_paint (attribute_values[i]);
- else if (!strcmp (*attr_n, "corner-radius"))
- op->radius = g_ascii_strtod (attribute_values[i], NULL);
- }
+static void
+add_rect (MnConfig *config,
+ const gchar **names,
+ const gchar **values)
+{
+ MnRectangleOp *op = g_slice_new0 (MnRectangleOp);
+ gint i;
- *ops = g_slist_append (*ops, op);
- }
- else if (!strcmp (element_name, "line"))
- {
- MnLineOp *op = g_slice_new0 (MnLineOp);
- ((MnDrawingOp*)op)->type = MN_LINE;
+ ((MnDrawingOp*)op)->type = MN_RECT;
- state.op = (MnDrawingOp*) op;
+ /* inspect the attributes */
+ for (i = 0; names[i]; i++)
+ {
+ if (!strcmp (names[i], "x"))
+ op->x = g_ascii_strtod (values[i], NULL);
+ else if (!strcmp (names[i], "y"))
+ op->y = g_ascii_strtod (values[i], NULL);
+ else if (!strcmp (names[i], "width"))
+ op->width = g_strdup (values[i]);
+ else if (!strcmp (names[i], "height"))
+ op->height = g_strdup (values[i]);
+ else if (!strcmp (names[i], "stroke"))
+ ((MnDrawingOp*) op)->stroke = cairo_pattern_from_paint (values[i]);
+ else if (!strcmp (names[i], "stroke-width"))
+ ((MnDrawingOp*) op)->stroke_width = g_ascii_strtod (values[i], NULL);
+ else if (!strcmp (names[i], "fill"))
+ ((MnDrawingOp*)op)->fill = cairo_pattern_from_paint (values[i]);
+ else if (!strcmp (names[i], "corner-radius"))
+ op->radius = g_ascii_strtod (values[i], NULL);
+ }
- for (attr_n = attribute_names, i = 0; *attr_n; attr_n++, i++)
- {
- if (!strcmp (*attr_n, "x1"))
- op->x1 = g_ascii_strtod (attribute_values[i], NULL);
- else if (!strcmp (*attr_n, "y1"))
- op->y1 = g_ascii_strtod (attribute_values[i], NULL);
- else if (!strcmp (*attr_n, "x2"))
- op->x2 = g_ascii_strtod (attribute_values[i], NULL);
- else if (!strcmp (*attr_n, "y2"))
- op->y2 = g_ascii_strtod (attribute_values[i], NULL);
- else if (!strcmp (*attr_n, "stroke"))
- ((MnDrawingOp *) op)->stroke = cairo_pattern_from_paint (attribute_values[i]);
- else if (!strcmp (*attr_n, "stroke-width"))
- ((MnDrawingOp *) op)->stroke_width = g_ascii_strtod (attribute_values[i], NULL);
- }
+ config->priv->current_ops->ops = g_slist_append (config->priv->current_ops->ops,
+ op);
+ config->priv->current_op = (MnDrawingOp*) op;
+}
- *ops = g_slist_append (*ops, op);
- }
- else if (!strcmp (element_name, "circle"))
- {
- MnCircleOp *op = g_slice_new0 (MnCircleOp);
- ((MnDrawingOp*)op)->type = MN_CIRCLE;
+static void
+add_line (MnConfig *config,
+ const gchar **names,
+ const gchar **values)
+{
+ MnLineOp *op = g_slice_new0 (MnLineOp);
+ gint i;
- state.op = (MnDrawingOp *) op;
+ ((MnDrawingOp*)op)->type = MN_LINE;
- for (attr_n = attribute_names, i = 0; *attr_n; attr_n++, i++)
- {
- if (!strcmp (*attr_n, "cx"))
- op->x = g_ascii_strtod (attribute_values[i], NULL);
- else if (!strcmp (*attr_n, "cy"))
- op->y = g_ascii_strtod (attribute_values[i], NULL);
- else if (!strcmp (*attr_n, "r"))
- op->radius = g_ascii_strtod (attribute_values[i], NULL);
- else if (!strcmp (*attr_n, "stroke"))
- ((MnDrawingOp*) op)->stroke = cairo_pattern_from_paint (attribute_values[i]);
- else if (!strcmp (*attr_n, "stroke-width"))
- ((MnDrawingOp *) op)->stroke_width = g_ascii_strtod (attribute_values[i], NULL);
- else if (!strcmp (*attr_n, "fill"))
- ((MnDrawingOp *) op)->fill = cairo_pattern_from_paint (attribute_values[i]);
- }
- *ops = g_slist_append (*ops, op);
+ for (i = 0; names[i]; i++)
+ {
+ if (!strcmp (names[i], "x1"))
+ op->x1 = g_ascii_strtod (values[i], NULL);
+ else if (!strcmp (names[i], "y1"))
+ op->y1 = g_ascii_strtod (values[i], NULL);
+ else if (!strcmp (names[i], "x2"))
+ op->x2 = g_ascii_strtod (values[i], NULL);
+ else if (!strcmp (names[i], "y2"))
+ op->y2 = g_ascii_strtod (values[i], NULL);
+ else if (!strcmp (names[i], "stroke"))
+ ((MnDrawingOp *) op)->stroke = cairo_pattern_from_paint (values[i]);
+ else if (!strcmp (names[i], "stroke-width"))
+ ((MnDrawingOp *) op)->stroke_width = g_ascii_strtod (values[i], NULL);
}
+
+ config->priv->current_op = (MnDrawingOp*) op;
+ config->priv->current_ops->ops = g_slist_append (config->priv->current_ops->ops, op);
}
static void
-widget_end_element (GMarkupParseContext *context,
- const gchar *element_name,
- gpointer user_data,
- GError **error)
+add_circle (MnConfig *config,
+ const gchar **names,
+ const gchar **values)
{
- /* update state */
- if (!strcmp (element_name, "gradient"))
- {
- state.gradient = NULL;
- }
- else if (!strcmp (element_name, "rect"))
- {
- state.op = NULL;
- }
- else if (!strcmp (element_name, "line"))
- {
- state.op = NULL;
- }
- else if (!strcmp (element_name, "circle"))
+ MnCircleOp *op = g_slice_new0 (MnCircleOp);
+ gint i;
+
+ ((MnDrawingOp*)op)->type = MN_CIRCLE;
+
+ for (i = 0; names[i]; i++)
{
- state.op = NULL;
+ if (!strcmp (names[i], "cx"))
+ op->x = g_ascii_strtod (values[i], NULL);
+ else if (!strcmp (names[i], "cy"))
+ op->y = g_ascii_strtod (values[i], NULL);
+ else if (!strcmp (names[i], "r"))
+ op->radius = g_ascii_strtod (values[i], NULL);
+ else if (!strcmp (names[i], "stroke"))
+ ((MnDrawingOp*) op)->stroke = cairo_pattern_from_paint (values[i]);
+ else if (!strcmp (names[i], "stroke-width"))
+ ((MnDrawingOp *) op)->stroke_width = g_ascii_strtod (values[i], NULL);
+ else if (!strcmp (names[i], "fill"))
+ ((MnDrawingOp *) op)->fill = cairo_pattern_from_paint (values[i]);
}
-}
-static GMarkupParser widget_parser = { widget_start_element, widget_end_element, NULL,
- NULL, perror };
+ config->priv->current_op = (MnDrawingOp*) op;
+ config->priv->current_ops->ops = g_slist_append (config->priv->current_ops->ops, op);
+}
static MnState
monet_state_from_string (const gchar *string)
@@ -388,10 +367,10 @@ monet_start_element (GMarkupParseContext *context,
gpointer user_data,
GError **error)
{
+ MnConfig *config = (MnConfig *) user_data;
+ MnConfigPrivate *priv = config->priv;
GError *err = NULL;
- const gchar **attr_n;
gint i, widget;
- MnConfig *config = (MnConfig *) user_data;
if (!strcmp (element_name, "monet"))
{
@@ -402,7 +381,6 @@ monet_start_element (GMarkupParseContext *context,
if (!strcmp (element_name, "widget"))
{
const gchar *type = NULL;
- gpointer ops_list;
MnDrawingOps *ops;
MnState wstate;
MnFlags wflags;
@@ -411,15 +389,15 @@ monet_start_element (GMarkupParseContext *context,
wflags = 0;
/* inspect the attributes */
- for (attr_n = attribute_names, i = 0; *attr_n; attr_n++, i++)
+ for (i = 0; attribute_names[i]; i++)
{
- if (!strcmp (*attr_n, "type"))
+ if (!strcmp (attribute_names[i], "type"))
type = attribute_values[i];
- else if (!strcmp (*attr_n, "state"))
+ else if (!strcmp (attribute_names[i], "state"))
wstate = monet_state_from_string (attribute_values[i]);
- else if (!strcmp (*attr_n, "flags"))
+ else if (!strcmp (attribute_names[i], "flags"))
wflags = monet_flags_from_string (attribute_values[i]);
}
@@ -452,12 +430,24 @@ monet_start_element (GMarkupParseContext *context,
ops = g_new0 (MnDrawingOps, 1);
ops->flags = wflags;
- config->widget_ops[widget][wstate] = g_slist_prepend (config->widget_ops[widget][wstate], ops);
+ priv->current_ops = ops;
- ops_list = &ops->ops;
+ config->widget_ops[widget][wstate] =
+ g_slist_prepend (config->widget_ops[widget][wstate], ops);
- g_markup_parse_context_push (context, &widget_parser, ops_list);
}
+ else if (!strcmp (element_name, "gradient"))
+ add_pattern (config, attribute_names, attribute_values, FALSE);
+ else if (!strcmp (element_name, "stroke-gradient"))
+ add_pattern (config, attribute_names, attribute_values, TRUE);
+ else if (!strcmp (element_name, "stop"))
+ pattern_add_stop (priv->current_pattern, attribute_names, attribute_values);
+ else if (!strcmp (element_name, "rect"))
+ add_rect (config, attribute_names, attribute_values);
+ else if (!strcmp (element_name, "line"))
+ add_line (config, attribute_names, attribute_values);
+ else if (!strcmp (element_name, "circle"))
+ add_circle (config, attribute_names, attribute_names);
}
static void
@@ -466,9 +456,31 @@ monet_end_element (GMarkupParseContext *context,
gpointer user_data,
GError **error)
{
+ MnConfig *config = (MnConfig *) user_data;
+ MnConfigPrivate *priv = config->priv;
+
+ /* clear state */
if (!strcmp ("widget", element_name))
{
- g_markup_parse_context_pop (context);
+ priv->current_ops = NULL;
+ priv->current_op = NULL;
+ priv->current_pattern = NULL;
+ }
+ else if (!strcmp (element_name, "gradient"))
+ {
+ priv->current_pattern = NULL;
+ }
+ else if (!strcmp (element_name, "rect"))
+ {
+ priv->current_op = NULL;
+ }
+ else if (!strcmp (element_name, "line"))
+ {
+ priv->current_op = NULL;
+ }
+ else if (!strcmp (element_name, "circle"))
+ {
+ priv->current_op = NULL;
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]