diff options
author | Ryan Lortie <desrt@desrt.ca> | 2014-07-28 11:11:49 +0200 |
---|---|---|
committer | Ryan Lortie <desrt@desrt.ca> | 2014-07-28 11:17:23 +0200 |
commit | e188f51f19155df2309c68c0c648f44032cdc197 (patch) | |
tree | 51e06288982ab69dc17d9a87238dcc5ebb740891 | |
parent | e15ba53cdab91587721a38efa4eeea9acf871860 (diff) | |
download | glib-e188f51f19155df2309c68c0c648f44032cdc197.tar.gz |
GMarkupParseContext: expose some API internally
Expose some of the guts of GMarkupParseContext for use via the
glib-private interface, from GIO.
There are some functionality changes in this commit that should probably
also be split out.....
-rw-r--r-- | glib/glib-private.c | 5 | ||||
-rw-r--r-- | glib/glib-private.h | 12 | ||||
-rw-r--r-- | glib/gmarkup-private.h | 117 | ||||
-rw-r--r-- | glib/gmarkup.c | 170 | ||||
-rw-r--r-- | glib/gmarkup.h | 6 |
5 files changed, 203 insertions, 107 deletions
diff --git a/glib/glib-private.c b/glib/glib-private.c index bbf879ff4..4ce6ac015 100644 --- a/glib/glib-private.c +++ b/glib/glib-private.c @@ -44,7 +44,10 @@ glib__private__ (void) g_main_context_new_with_next_id, g_dir_open_with_errno, - g_dir_new_from_dirp + g_dir_new_from_dirp, + + g_markup_parse_context_parse_slightly, + g_markup_collect_attributesv }; return &table; diff --git a/glib/glib-private.h b/glib/glib-private.h index 0a280087a..7a95519d4 100644 --- a/glib/glib-private.h +++ b/glib/glib-private.h @@ -20,6 +20,7 @@ #include <glib.h> #include "gwakeup.h" +#include "gmarkup-private.h" #if defined(__GNUC__) # define _g_alignof(type) (__alignof__ (type)) @@ -61,6 +62,17 @@ typedef struct { guint flags); GDir * (* g_dir_new_from_dirp) (gpointer dirp); + gboolean (* g_markup_parse_context_parse_slightly) (GMarkupParseContext *context, + GError **error); + + gboolean (* g_markup_collect_attributesv) (const gchar *element_name, + const gchar **attribute_names, + const gchar **attribute_values, + GError **error, + GMarkupCollectType first_type, + const gchar *first_attr, + va_list ap); + /* Add other private functions here, initialize them in glib-private.c */ } GLibPrivateVTable; diff --git a/glib/gmarkup-private.h b/glib/gmarkup-private.h new file mode 100644 index 000000000..c6d581b7b --- /dev/null +++ b/glib/gmarkup-private.h @@ -0,0 +1,117 @@ +/* + * Copyright 2000, 2003 Red Hat, Inc. + * Copyright 2007, 2008 Ryan Lortie <desrt@desrt.ca> + * + * 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 of the licence, 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/>. + */ + +#ifndef __G_MARKUP_PRIVATE_H__ +#define __G_MARKUP_PRIVATE_H__ + +#include "gstring.h" + +typedef enum +{ + STATE_START, + STATE_AFTER_OPEN_ANGLE, + STATE_AFTER_CLOSE_ANGLE, + STATE_AFTER_ELISION_SLASH, /* the slash that obviates need for end element */ + STATE_INSIDE_OPEN_TAG_NAME, + STATE_INSIDE_ATTRIBUTE_NAME, + STATE_AFTER_ATTRIBUTE_NAME, + STATE_BETWEEN_ATTRIBUTES, + STATE_AFTER_ATTRIBUTE_EQUALS_SIGN, + STATE_INSIDE_ATTRIBUTE_VALUE_SQ, + STATE_INSIDE_ATTRIBUTE_VALUE_DQ, + STATE_INSIDE_TEXT, + STATE_AFTER_CLOSE_TAG_SLASH, + STATE_INSIDE_CLOSE_TAG_NAME, + STATE_AFTER_CLOSE_TAG_NAME, + STATE_INSIDE_PASSTHROUGH, + STATE_ERROR +} GMarkupParseState; + +typedef struct +{ + const char *prev_element; + const GMarkupParser *prev_parser; + gpointer prev_user_data; +} GMarkupRecursionTracker; + +struct _GMarkupParseContext +{ + const GMarkupParser *parser; + + volatile gint ref_count; + + GMarkupParseFlags flags; + + gint line_number; + gint char_number; + + GMarkupParseState state; + + gpointer user_data; + GDestroyNotify dnotify; + + /* A piece of character data or an element that + * hasn't "ended" yet so we haven't yet called + * the callback for it. + */ + GString *partial_chunk; + GSList *spare_chunks; + + GSList *tag_stack; + GSList *tag_stack_gstr; + GSList *spare_list_nodes; + + GString **attr_names; + GString **attr_values; + gint cur_attr; + gint alloc_attrs; + + const gchar *current_text; + gsize current_text_len; + const gchar *current_text_end; + + /* used to save the start of the last interesting thingy */ + const gchar *start; + + const gchar *iter; + + guint document_empty : 1; + guint parsing : 1; + guint awaiting_pop : 1; + gint balance; + + /* subparser support */ + GSList *subparser_stack; /* (GMarkupRecursionTracker *) */ + const char *subparser_element; + gpointer held_user_data; +}; + +gboolean +g_markup_parse_context_parse_slightly (GMarkupParseContext *context, + GError **error); + +gboolean +g_markup_collect_attributesv (const gchar *element_name, + const gchar **attribute_names, + const gchar **attribute_values, + GError **error, + GMarkupCollectType first_type, + const gchar *first_attr, + va_list ap); + +#endif /* __G_MARKUP_PRIVATE_H__ */ diff --git a/glib/gmarkup.c b/glib/gmarkup.c index 9b60387cd..952fb5961 100644 --- a/glib/gmarkup.c +++ b/glib/gmarkup.c @@ -20,19 +20,19 @@ #include "config.h" +#include "gmarkup.h" +#include "gmarkup-private.h" + #include <stdarg.h> #include <string.h> #include <stdio.h> #include <stdlib.h> #include <errno.h> -#include "gmarkup.h" - #include "gatomic.h" #include "gslice.h" #include "galloca.h" #include "gstrfuncs.h" -#include "gstring.h" #include "gtestutils.h" #include "glibintl.h" #include "gthread.h" @@ -87,86 +87,6 @@ G_DEFINE_QUARK (g-markup-error-quark, g_markup_error) -typedef enum -{ - STATE_START, - STATE_AFTER_OPEN_ANGLE, - STATE_AFTER_CLOSE_ANGLE, - STATE_AFTER_ELISION_SLASH, /* the slash that obviates need for end element */ - STATE_INSIDE_OPEN_TAG_NAME, - STATE_INSIDE_ATTRIBUTE_NAME, - STATE_AFTER_ATTRIBUTE_NAME, - STATE_BETWEEN_ATTRIBUTES, - STATE_AFTER_ATTRIBUTE_EQUALS_SIGN, - STATE_INSIDE_ATTRIBUTE_VALUE_SQ, - STATE_INSIDE_ATTRIBUTE_VALUE_DQ, - STATE_INSIDE_TEXT, - STATE_AFTER_CLOSE_TAG_SLASH, - STATE_INSIDE_CLOSE_TAG_NAME, - STATE_AFTER_CLOSE_TAG_NAME, - STATE_INSIDE_PASSTHROUGH, - STATE_ERROR -} GMarkupParseState; - -typedef struct -{ - const char *prev_element; - const GMarkupParser *prev_parser; - gpointer prev_user_data; -} GMarkupRecursionTracker; - -struct _GMarkupParseContext -{ - const GMarkupParser *parser; - - volatile gint ref_count; - - GMarkupParseFlags flags; - - gint line_number; - gint char_number; - - GMarkupParseState state; - - gpointer user_data; - GDestroyNotify dnotify; - - /* A piece of character data or an element that - * hasn't "ended" yet so we haven't yet called - * the callback for it. - */ - GString *partial_chunk; - GSList *spare_chunks; - - GSList *tag_stack; - GSList *tag_stack_gstr; - GSList *spare_list_nodes; - - GString **attr_names; - GString **attr_values; - gint cur_attr; - gint alloc_attrs; - - const gchar *current_text; - gssize current_text_len; - const gchar *current_text_end; - - /* used to save the start of the last interesting thingy */ - const gchar *start; - - const gchar *iter; - - guint document_empty : 1; - guint parsing : 1; - guint awaiting_pop : 1; - gint balance; - - /* subparser support */ - GSList *subparser_stack; /* (GMarkupRecursionTracker *) */ - const char *subparser_element; - gpointer held_user_data; -}; - /* * Helpers to reduce our allocation overhead, we have * a well defined allocation lifecycle. @@ -1097,6 +1017,9 @@ emit_end_element (GMarkupParseContext *context, pop_tag (context); } +static void g_markup_parse_context_set_text (GMarkupParseContext *context, + const gchar *text, + gssize text_len); /** * g_markup_parse_context_parse: * @context: a #GMarkupParseContext @@ -1128,22 +1051,42 @@ g_markup_parse_context_parse (GMarkupParseContext *context, g_return_val_if_fail (context->state != STATE_ERROR, FALSE); g_return_val_if_fail (!context->parsing, FALSE); + g_markup_parse_context_set_text (context, text, text_len); + + while (context->iter != context->current_text_end) + if (!g_markup_parse_context_parse_slightly (context, error)) + break; + + context->parsing = FALSE; + + return context->state != STATE_ERROR; +} + +static void +g_markup_parse_context_set_text (GMarkupParseContext *context, + const gchar *text, + gssize text_len) +{ if (text_len < 0) text_len = strlen (text); if (text_len == 0) - return TRUE; + return; context->parsing = TRUE; - context->current_text = text; context->current_text_len = text_len; context->current_text_end = context->current_text + text_len; context->iter = context->current_text; context->start = context->iter; +} - while (context->iter != context->current_text_end) +gboolean +g_markup_parse_context_parse_slightly (GMarkupParseContext *context, + GError **error) +{ + if (context->iter != context->current_text_end) { switch (context->state) { @@ -1730,8 +1673,6 @@ g_markup_parse_context_parse (GMarkupParseContext *context, } finished: - context->parsing = FALSE; - return context->state != STATE_ERROR; } @@ -2669,27 +2610,28 @@ g_markup_parse_boolean (const char *string, * Since: 2.16 **/ gboolean -g_markup_collect_attributes (const gchar *element_name, - const gchar **attribute_names, - const gchar **attribute_values, - GError **error, - GMarkupCollectType first_type, - const gchar *first_attr, - ...) +g_markup_collect_attributesv (const gchar *element_name, + const gchar **attribute_names, + const gchar **attribute_values, + GError **error, + GMarkupCollectType first_type, + const gchar *first_attr, + va_list ap) { GMarkupCollectType type; const gchar *attr; guint64 collected; int written; - va_list ap; + va_list aq; int i; + G_VA_COPY (aq, ap); + type = first_type; attr = first_attr; collected = 0; written = 0; - va_start (ap, first_attr); while (type != G_MARKUP_COLLECT_INVALID) { gboolean mandatory; @@ -2734,7 +2676,6 @@ g_markup_collect_attributes (const gchar *element_name, "element '%s' requires attribute '%s'", element_name, attr); - va_end (ap); goto failure; } @@ -2792,7 +2733,6 @@ g_markup_collect_attributes (const gchar *element_name, "cannot be parsed as a boolean value", element_name, attr, value); - va_end (ap); goto failure; } } @@ -2807,7 +2747,6 @@ g_markup_collect_attributes (const gchar *element_name, attr = va_arg (ap, const char *); written++; } - va_end (ap); /* ensure we collected all the arguments */ for (i = 0; attribute_names[i]; i++) @@ -2842,6 +2781,8 @@ g_markup_collect_attributes (const gchar *element_name, goto failure; } + va_end (aq); + return TRUE; failure: @@ -2849,12 +2790,11 @@ failure: type = first_type; attr = first_attr; - va_start (ap, first_attr); while (type != G_MARKUP_COLLECT_INVALID) { gpointer ptr; - ptr = va_arg (ap, gpointer); + ptr = va_arg (aq, gpointer); if (ptr != NULL) { @@ -2878,10 +2818,30 @@ failure: } } - type = va_arg (ap, GMarkupCollectType); - attr = va_arg (ap, const char *); + type = va_arg (aq, GMarkupCollectType); + attr = va_arg (aq, const char *); } - va_end (ap); + va_end (aq); return FALSE; } + +gboolean +g_markup_collect_attributes (const gchar *element_name, + const gchar **attribute_names, + const gchar **attribute_values, + GError **error, + GMarkupCollectType first_type, + const gchar *first_attr, + ...) +{ + gboolean ok; + va_list ap; + + va_start (ap, first_attr); + ok = g_markup_collect_attributesv (element_name, attribute_names, attribute_values, + error, first_type, first_attr, ap); + va_end (ap); + + return ok; +} diff --git a/glib/gmarkup.h b/glib/gmarkup.h index 13b2343a7..e20c7eb61 100644 --- a/glib/gmarkup.h +++ b/glib/gmarkup.h @@ -90,6 +90,9 @@ GQuark g_markup_error_quark (void); * 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. + * @G_MARKUP_IGNORE_PASSTHROUGH: Ignore (don't report) passthrough + * data on a #GMarkupReader. Meaningless with #GMarkupParseContext; + * just give a %NULL callback in your parser. Since: 2.40. * * Flags that affect the behaviour of the parser. */ @@ -98,7 +101,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_IGNORE_QUALIFIED = 1 << 3 + G_MARKUP_IGNORE_QUALIFIED = 1 << 3, + G_MARKUP_IGNORE_PASSTHROUGH = 1 << 4 } GMarkupParseFlags; /** |