From 474d91566a7db52ee1776933ea5c4b6276b1280a Mon Sep 17 00:00:00 2001 From: Ryan Lortie Date: Mon, 28 Oct 2013 14:05:51 -0700 Subject: [PATCH] GMarkup: add G_MARKUP_IGNORE_QUALIFIED Add a flag to GMarkupParserFlags to ignore qualified tags (along with their contents) and attributes. This will provide a nice way for some of our parsers (GDBus introspection, GSettings schema, etc) to ignore additional tags that users have added to their files, under a different namespace. https://bugzilla.gnome.org/show_bug.cgi?id=665634 --- glib/gmarkup.c | 36 +++++++++++++++++++++++++++++++----- glib/gmarkup.h | 7 ++++++- 2 files changed, 37 insertions(+), 6 deletions(-) diff --git a/glib/gmarkup.c b/glib/gmarkup.c index 0b1278b16..f27bb3b54 100644 --- a/glib/gmarkup.c +++ b/glib/gmarkup.c @@ -1004,21 +1004,39 @@ static inline void emit_start_element (GMarkupParseContext *context, GError **error) { - int i; + int i, j = 0; const gchar *start_name; const gchar **attr_names; const gchar **attr_values; GError *tmp_error; + /* In case we want to ignore qualified tags and we see that we have + * one here, we push a subparser. This will ignore all tags inside of + * the qualified tag. + * + * We deal with the end of the subparser from emit_end_element. + */ + if (context->flags & G_MARKUP_IGNORE_QUALIFIED && strchr (current_element (context), ':')) + { + static const GMarkupParser ignore_parser; + g_markup_parse_context_push (context, &ignore_parser, NULL); + return; + } + attr_names = g_newa (const gchar *, context->cur_attr + 2); attr_values = g_newa (const gchar *, context->cur_attr + 2); for (i = 0; i < context->cur_attr + 1; i++) { - attr_names[i] = context->attr_names[i]->str; - attr_values[i] = context->attr_values[i]->str; + /* Possibly omit qualified attribute names from the list */ + if ((context->flags & G_MARKUP_IGNORE_QUALIFIED) && strchr (context->attr_names[i]->str, ':')) + continue; + + attr_names[j] = context->attr_names[i]->str; + attr_values[j] = context->attr_values[i]->str; + j++; } - attr_names[i] = NULL; - attr_values[i] = NULL; + attr_names[j] = NULL; + attr_values[j] = NULL; /* Call user callback for element start */ tmp_error = NULL; @@ -1051,6 +1069,14 @@ emit_end_element (GMarkupParseContext *context, possibly_finish_subparser (context); + /* We might have just returned from our ignore subparser */ + if (context->flags & G_MARKUP_IGNORE_QUALIFIED && strchr (current_element (context), ':')) + { + g_markup_parse_context_pop (context); + pop_tag (context); + return; + } + tmp_error = NULL; if (context->parser->end_element) (* context->parser->end_element) (context, diff --git a/glib/gmarkup.h b/glib/gmarkup.h index eb7214d26..96425db5d 100644 --- a/glib/gmarkup.h +++ b/glib/gmarkup.h @@ -87,6 +87,10 @@ GQuark g_markup_error_quark (void); * caller know the location of the error. When this flag is set the * location information is also prefixed to errors generated by the * #GMarkupParser implementation functions + * @G_MARKUP_IGNORE_QUALIFIED: Ignore (don't report) qualified + * attributes and tags, along with their contents. A qualified + * attribute or tag is one that contains ':' in its name (ie: is in + * another namespace). Since: 2.40. * * Flags that affect the behaviour of the parser. */ @@ -94,7 +98,8 @@ typedef enum { G_MARKUP_DO_NOT_USE_THIS_UNSUPPORTED_FLAG = 1 << 0, G_MARKUP_TREAT_CDATA_AS_TEXT = 1 << 1, - G_MARKUP_PREFIX_ERROR_POSITION = 1 << 2 + G_MARKUP_PREFIX_ERROR_POSITION = 1 << 2, + G_MARKUP_IGNORE_QUALIFIED = 1 << 3 } GMarkupParseFlags; /**