[glib/wip/gmarkupreader: 1/4] GMarkupParseContext: expose some API internally



commit e188f51f19155df2309c68c0c648f44032cdc197
Author: Ryan Lortie <desrt desrt ca>
Date:   Mon Jul 28 11:11:49 2014 +0200

    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.....

 glib/glib-private.c    |    5 +-
 glib/glib-private.h    |   12 ++++
 glib/gmarkup-private.h |  117 +++++++++++++++++++++++++++++++++
 glib/gmarkup.c         |  170 ++++++++++++++++++-----------------------------
 glib/gmarkup.h         |    6 ++-
 5 files changed, 203 insertions(+), 107 deletions(-)
---
diff --git a/glib/glib-private.c b/glib/glib-private.c
index bbf879f..4ce6ac0 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 0a28008..7a95519 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 0000000..c6d581b
--- /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 9b60387..952fb59 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 13b2343..e20c7eb 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;
 
 /**


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]