summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRyan Lortie <desrt@desrt.ca>2014-07-28 11:11:49 +0200
committerRyan Lortie <desrt@desrt.ca>2014-07-28 11:17:23 +0200
commite188f51f19155df2309c68c0c648f44032cdc197 (patch)
tree51e06288982ab69dc17d9a87238dcc5ebb740891
parente15ba53cdab91587721a38efa4eeea9acf871860 (diff)
downloadglib-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.c5
-rw-r--r--glib/glib-private.h12
-rw-r--r--glib/gmarkup-private.h117
-rw-r--r--glib/gmarkup.c170
-rw-r--r--glib/gmarkup.h6
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;
/**