<SUBSECTION>
GMarkupCollectType
g_markup_collect_attributes
-g_markup_collect_known_attributes
<SUBSECTION Private>
g_markup_error_quark
</SECTION>
goto out;
}
- if (!g_markup_collect_known_attributes (element_name,
- attribute_names,
- attribute_values,
- error,
- G_MARKUP_COLLECT_STRING | G_MARKUP_COLLECT_OPTIONAL, "name", &name,
- G_MARKUP_COLLECT_INVALID))
+ if (!g_markup_collect_attributes (element_name,
+ attribute_names,
+ attribute_values,
+ error,
+ G_MARKUP_COLLECT_STRING | G_MARKUP_COLLECT_OPTIONAL, "name", &name,
+ /* some hand-written introspection XML documents use this */
+ G_MARKUP_COLLECT_STRING | G_MARKUP_COLLECT_OPTIONAL, "xmlns:doc", NULL,
+ G_MARKUP_COLLECT_INVALID))
goto out;
g_dbus_node_info_set (data,
goto out;
}
- if (!g_markup_collect_known_attributes (element_name,
- attribute_names,
- attribute_values,
- error,
- G_MARKUP_COLLECT_STRING, "name", &name,
- G_MARKUP_COLLECT_INVALID))
+ if (!g_markup_collect_attributes (element_name,
+ attribute_names,
+ attribute_values,
+ error,
+ G_MARKUP_COLLECT_STRING, "name", &name,
+ /* seen in the wild */
+ G_MARKUP_COLLECT_STRING | G_MARKUP_COLLECT_OPTIONAL, "version", NULL,
+ G_MARKUP_COLLECT_INVALID))
goto out;
g_dbus_interface_info_set (data,
goto out;
}
- if (!g_markup_collect_known_attributes (element_name,
- attribute_names,
- attribute_values,
- error,
- G_MARKUP_COLLECT_STRING, "name", &name,
- G_MARKUP_COLLECT_INVALID))
+ if (!g_markup_collect_attributes (element_name,
+ attribute_names,
+ attribute_values,
+ error,
+ G_MARKUP_COLLECT_STRING, "name", &name,
+ /* seen in the wild */
+ G_MARKUP_COLLECT_STRING | G_MARKUP_COLLECT_OPTIONAL, "version", NULL,
+ G_MARKUP_COLLECT_INVALID))
goto out;
g_dbus_method_info_set (data,
goto out;
}
- if (!g_markup_collect_known_attributes (element_name,
- attribute_names,
- attribute_values,
- error,
- G_MARKUP_COLLECT_STRING, "name", &name,
- G_MARKUP_COLLECT_INVALID))
+ if (!g_markup_collect_attributes (element_name,
+ attribute_names,
+ attribute_values,
+ error,
+ G_MARKUP_COLLECT_STRING, "name", &name,
+ G_MARKUP_COLLECT_INVALID))
goto out;
g_dbus_signal_info_set (data,
goto out;
}
- if (!g_markup_collect_known_attributes (element_name,
- attribute_names,
- attribute_values,
- error,
- G_MARKUP_COLLECT_STRING, "name", &name,
- G_MARKUP_COLLECT_STRING, "type", &type,
- G_MARKUP_COLLECT_STRING, "access", &access,
- G_MARKUP_COLLECT_INVALID))
+ if (!g_markup_collect_attributes (element_name,
+ attribute_names,
+ attribute_values,
+ error,
+ G_MARKUP_COLLECT_STRING, "name", &name,
+ G_MARKUP_COLLECT_STRING, "type", &type,
+ G_MARKUP_COLLECT_STRING, "access", &access,
+ G_MARKUP_COLLECT_INVALID))
goto out;
if (strcmp (access, "read") == 0)
goto out;
}
- if (!g_markup_collect_known_attributes (element_name,
- attribute_names,
- attribute_values,
- error,
- G_MARKUP_COLLECT_STRING | G_MARKUP_COLLECT_OPTIONAL, "name", &name,
- G_MARKUP_COLLECT_STRING | G_MARKUP_COLLECT_OPTIONAL, "direction", &direction,
- G_MARKUP_COLLECT_STRING, "type", &type,
- G_MARKUP_COLLECT_INVALID))
+ if (!g_markup_collect_attributes (element_name,
+ attribute_names,
+ attribute_values,
+ error,
+ G_MARKUP_COLLECT_STRING | G_MARKUP_COLLECT_OPTIONAL, "name", &name,
+ G_MARKUP_COLLECT_STRING | G_MARKUP_COLLECT_OPTIONAL, "direction", &direction,
+ G_MARKUP_COLLECT_STRING, "type", &type,
+ G_MARKUP_COLLECT_INVALID))
goto out;
if (strcmp (stack->next->data, "method") == 0)
goto out;
}
- if (!g_markup_collect_known_attributes (element_name,
- attribute_names,
- attribute_values,
- error,
- G_MARKUP_COLLECT_STRING, "name", &name,
- G_MARKUP_COLLECT_STRING, "value", &value,
- G_MARKUP_COLLECT_INVALID))
+ if (!g_markup_collect_attributes (element_name,
+ attribute_names,
+ attribute_values,
+ error,
+ G_MARKUP_COLLECT_STRING, "name", &name,
+ G_MARKUP_COLLECT_STRING, "value", &value,
+ G_MARKUP_COLLECT_INVALID))
goto out;
g_dbus_annotation_info_set (data,
g_markup_printf_escaped
g_markup_vprintf_escaped
g_markup_collect_attributes
-g_markup_collect_known_attributes
g_free
g_clear_pointer
g_malloc
* is set depending on what value type is used
*
* A mixed enumerated type and flags field. You must specify one type
- * (string, strdup, boolean, tristate). Additionally, you may optionally
+ * (string, strdup, boolean, tristate). Additionally, you may optionally
* bitwise OR the type with the flag %G_MARKUP_COLLECT_OPTIONAL.
*
* It is likely that this enum will be extended in the future to
* support other types.
*/
-static gboolean
-_g_markup_collect_attributesv (const gchar *element_name,
- const gchar **attribute_names,
- const gchar **attribute_values,
- gboolean reject_unknown_attributes,
- GError **error,
- GMarkupCollectType first_type,
- const gchar *first_attr,
- va_list ap)
+/**
+ * g_markup_collect_attributes:
+ * @element_name: the current tag name
+ * @attribute_names: the attribute names
+ * @attribute_values: the attribute values
+ * @error: a pointer to a #GError or %NULL
+ * @first_type: the #GMarkupCollectType of the first attribute
+ * @first_attr: the name of the first attribute
+ * @...: a pointer to the storage location of the first attribute
+ * (or %NULL), followed by more types names and pointers, ending
+ * with %G_MARKUP_COLLECT_INVALID
+ *
+ * Collects the attributes of the element from the data passed to the
+ * #GMarkupParser start_element function, dealing with common error
+ * conditions and supporting boolean values.
+ *
+ * This utility function is not required to write a parser but can save
+ * a lot of typing.
+ *
+ * The @element_name, @attribute_names, @attribute_values and @error
+ * parameters passed to the start_element callback should be passed
+ * unmodified to this function.
+ *
+ * Following these arguments is a list of "supported" attributes to collect.
+ * It is an error to specify multiple attributes with the same name. If any
+ * attribute not in the list appears in the @attribute_names array then an
+ * unknown attribute error will result.
+ *
+ * The #GMarkupCollectType field allows specifying the type of collection
+ * to perform and if a given attribute must appear or is optional.
+ *
+ * The attribute name is simply the name of the attribute to collect.
+ *
+ * The pointer should be of the appropriate type (see the descriptions
+ * under #GMarkupCollectType) and may be %NULL in case a particular
+ * attribute is to be allowed but ignored.
+ *
+ * This function deals with issuing errors for missing attributes
+ * (of type %G_MARKUP_ERROR_MISSING_ATTRIBUTE), unknown attributes
+ * (of type %G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE) and duplicate
+ * attributes (of type %G_MARKUP_ERROR_INVALID_CONTENT) as well
+ * as parse errors for boolean-valued attributes (again of type
+ * %G_MARKUP_ERROR_INVALID_CONTENT). In all of these cases %FALSE
+ * will be returned and @error will be set as appropriate.
+ *
+ * Return value: %TRUE if successful
+ *
+ * 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,
+ ...)
{
GMarkupCollectType type;
const gchar *attr;
guint64 collected;
int written;
+ va_list ap;
int i;
- va_list ap2;
type = first_type;
attr = first_attr;
collected = 0;
written = 0;
- /* Take a copy of the va_list so that we can iterate back over it in case of
- * errors. */
- G_VA_COPY (ap2, ap);
-
+ va_start (ap, first_attr);
while (type != G_MARKUP_COLLECT_INVALID)
{
gboolean mandatory;
"element '%s' requires attribute '%s'",
element_name, attr);
+ va_end (ap);
goto failure;
}
"cannot be parsed as a boolean value",
element_name, attr, value);
+ va_end (ap);
goto failure;
}
}
attr = va_arg (ap, const char *);
written++;
}
+ va_end (ap);
/* ensure we collected all the arguments */
for (i = 0; attribute_names[i]; i++)
break;
/* j is now the first occurrence of attribute_names[i] */
- if (i == j && reject_unknown_attributes)
+ if (i == j)
g_set_error (error, G_MARKUP_ERROR,
G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE,
"attribute '%s' invalid for element '%s'",
attribute_names[i], element_name);
- else if (i != j)
+ else
g_set_error (error, G_MARKUP_ERROR,
G_MARKUP_ERROR_INVALID_CONTENT,
"attribute '%s' given multiple times for element '%s'",
attribute_names[i], element_name);
- else
- continue; /* accepting unknown attributes */
goto failure;
}
- va_end (ap2);
return TRUE;
type = first_type;
attr = first_attr;
+ va_start (ap, first_attr);
while (type != G_MARKUP_COLLECT_INVALID)
{
gpointer ptr;
- ptr = va_arg (ap2, gpointer);
+ ptr = va_arg (ap, gpointer);
if (ptr != NULL)
{
}
}
- type = va_arg (ap2, GMarkupCollectType);
- attr = va_arg (ap2, const char *);
+ type = va_arg (ap, GMarkupCollectType);
+ attr = va_arg (ap, const char *);
}
- va_end (ap2);
-
- return FALSE;
-}
-
-/**
- * g_markup_collect_attributes:
- * @element_name: the current tag name
- * @attribute_names: the attribute names
- * @attribute_values: the attribute values
- * @error: a pointer to a #GError or %NULL
- * @first_type: the #GMarkupCollectType of the first attribute
- * @first_attr: the name of the first attribute
- * @...: a pointer to the storage location of the first attribute
- * (or %NULL), followed by more types names and pointers, ending
- * with %G_MARKUP_COLLECT_INVALID
- *
- * Collects the attributes of the element from the data passed to the
- * #GMarkupParser start_element function, dealing with common error
- * conditions and supporting boolean values.
- *
- * This utility function is not required to write a parser but can save
- * a lot of typing.
- *
- * The @element_name, @attribute_names, @attribute_values and @error
- * parameters passed to the start_element callback should be passed
- * unmodified to this function.
- *
- * Following these arguments is a list of "supported" attributes to collect.
- * It is an error to specify multiple attributes with the same name. If any
- * attribute not in the list appears in the @attribute_names array then an
- * unknown attribute error will result.
- *
- * The #GMarkupCollectType field allows specifying the type of collection
- * to perform and if a given attribute must appear or is optional.
- *
- * The attribute name is simply the name of the attribute to collect.
- *
- * The pointer should be of the appropriate type (see the descriptions
- * under #GMarkupCollectType) and may be %NULL in case a particular
- * attribute is to be allowed but ignored.
- *
- * This function deals with issuing errors for missing attributes
- * (of type %G_MARKUP_ERROR_MISSING_ATTRIBUTE), unknown attributes
- * (of type %G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE) and duplicate
- * attributes (of type %G_MARKUP_ERROR_INVALID_CONTENT) as well
- * as parse errors for boolean-valued attributes (again of type
- * %G_MARKUP_ERROR_INVALID_CONTENT). In all of these cases %FALSE
- * will be returned and @error will be set as appropriate.
- *
- * Return value: %TRUE if successful
- *
- * 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,
- ...)
-{
- gboolean retval;
- va_list ap;
-
- va_start (ap, first_attr);
- retval = _g_markup_collect_attributesv (element_name,
- attribute_names, attribute_values,
- TRUE, error,
- first_type, first_attr,
- ap);
va_end (ap);
- return retval;
-}
-
-/**
- * g_markup_collect_known_attributes:
- * @element_name: the current tag name
- * @attribute_names: (array zero-terminated=1): the attribute names
- * @attribute_values: (array zero-terminated=1): the attribute values
- * @error: (allow-none): a pointer to a #GError or %NULL
- * @first_type: the #GMarkupCollectType of the first attribute
- * @first_attr: the name of the first attribute
- * @...: a pointer to the storage location of the first attribute
- * (or %NULL), followed by more types names and pointers, ending
- * with %G_MARKUP_COLLECT_INVALID
- *
- * Collects the attributes of the element from the data passed to the
- * #GMarkupParser start_element function, dealing with common error
- * conditions and supporting boolean values.
- *
- * This is a more relaxed version of g_markup_collect_attributes(), which
- * ignores attributes found in @attribute_names but not listed in @first_attr
- * or @...; by comparison g_markup_collect_attributes() will return
- * %G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE instead. Otherwise, this function behaves
- * identically.
- *
- * This is intended for situations where the markup being parsed may use
- * extensions in other namespaces and thus contain extra, unknown, attributes.
- *
- * Return value: %TRUE if successful
- *
- * Since: 2.34
- */
-gboolean
-g_markup_collect_known_attributes (const gchar *element_name,
- const gchar **attribute_names,
- const gchar **attribute_values,
- GError **error,
- GMarkupCollectType first_type,
- const gchar *first_attr,
- ...)
-{
- gboolean retval;
- va_list ap;
-
- va_start (ap, first_attr);
- retval = _g_markup_collect_attributesv (element_name,
- attribute_names, attribute_values,
- FALSE, error,
- first_type, first_attr,
- ap);
- va_end (ap);
-
- return retval;
+ return FALSE;
}
const gchar *first_attr,
...);
-GLIB_AVAILABLE_IN_2_34
-gboolean g_markup_collect_known_attributes (const gchar *element_name,
- const gchar **attribute_names,
- const gchar **attribute_values,
- GError **error,
- GMarkupCollectType first_type,
- const gchar *first_attr,
- ...);
-
G_END_DECLS
#endif /* __G_MARKUP_H__ */
-/*
+/*
* Copyright © 2007 Ryan Lortie
- *
+ *
* This program 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
* License, or (at your option) any later version.
- *
+ *
* See the included COPYING file for more information.
*/
#include <string.h>
#include <glib.h>
-enum test_type
-{
- COLLECT_ATTRIBUTES = 0,
- COLLECT_KNOWN_ATTRIBUTES,
- MAX_TEST_TYPE
-};
-
-struct test_data
-{
- enum test_type test_type;
- GString *string;
-};
-
static void
start (GMarkupParseContext *context,
const char *element_name,
gpointer user_data,
GError **error)
{
- struct test_data *data = user_data;
+ GString *string = user_data;
gboolean result;
-#define collect(...) G_STMT_START { \
- if (data->test_type == COLLECT_ATTRIBUTES) \
- { \
- result = \
- g_markup_collect_attributes (element_name, attribute_names, \
- attribute_values, error, __VA_ARGS__, \
- G_MARKUP_COLLECT_INVALID); \
- } \
- else \
- { \
- result = \
- g_markup_collect_known_attributes (element_name, attribute_names, \
- attribute_values, error, \
- __VA_ARGS__, \
- G_MARKUP_COLLECT_INVALID); \
- } \
- } G_STMT_END
+#define collect(...) \
+ g_markup_collect_attributes (element_name, attribute_names, \
+ attribute_values, error, __VA_ARGS__, \
+ G_MARKUP_COLLECT_INVALID)
#define BOOL G_MARKUP_COLLECT_BOOLEAN
#define OPTBOOL G_MARKUP_COLLECT_BOOLEAN | G_MARKUP_COLLECT_OPTIONAL
#define TRI G_MARKUP_COLLECT_TRISTATE
{
gboolean mb = 2, ob = 2, tri = 2;
- collect (BOOL, "mb", &mb,
- OPTBOOL, "ob", &ob,
- TRI, "tri", &tri);
+ result = collect (BOOL, "mb", &mb,
+ OPTBOOL, "ob", &ob,
+ TRI, "tri", &tri);
g_assert (result ||
(mb == FALSE && ob == FALSE && tri != TRUE && tri != FALSE));
if (tri != FALSE && tri != TRUE)
tri = -1;
- g_string_append_printf (data->string, "<bool(%d) %d %d %d>",
+ g_string_append_printf (string, "<bool(%d) %d %d %d>",
result, mb, ob, tri);
}
const char *cm, *co;
char *am, *ao;
- collect (STR, "cm", &cm,
- STRDUP, "am", &am,
- OPTDUP, "ao", &ao,
- OPTSTR, "co", &co);
+ result = collect (STR, "cm", &cm,
+ STRDUP, "am", &am,
+ OPTDUP, "ao", &ao,
+ OPTSTR, "co", &co);
g_assert (result ||
(cm == NULL && am == NULL && ao == NULL && co == NULL));
- g_string_append_printf (data->string, "<str(%d) %s %s %s %s>",
+ g_string_append_printf (string, "<str(%d) %s %s %s %s>",
result, n (cm), n (am), n (ao), n (co));
g_free (am);
test_collect (gconstpointer d)
{
const struct test *test = d;
- enum test_type t;
- for (t = 0; t < MAX_TEST_TYPE; t++)
+ GMarkupParseContext *ctx;
+ GError *error = NULL;
+ GString *string;
+ gboolean result;
+
+ string = g_string_new ("");
+ ctx = g_markup_parse_context_new (&parser, 0, string, NULL);
+ result = g_markup_parse_context_parse (ctx,
+ test->document,
+ -1, &error);
+ if (result)
+ result = g_markup_parse_context_end_parse (ctx, &error);
+
+ if (result)
{
- GMarkupParseContext *ctx;
- GError *error = NULL;
- gboolean result;
- struct test_data data;
-
- data.test_type = t;
- data.string = g_string_new ("");
-
- ctx = g_markup_parse_context_new (&parser, 0, &data, NULL);
- result = g_markup_parse_context_parse (ctx,
- test->document,
- -1, &error);
- if (result)
- result = g_markup_parse_context_end_parse (ctx, &error);
-
- if (result &&
- !(t == COLLECT_KNOWN_ATTRIBUTES &&
- test->error_code == G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE))
- {
- /* Normal test */
- g_assert_no_error (error);
- g_assert_cmpint (test->error_code, ==, 0);
- g_assert_cmpstr (test->result, ==, data.string->str);
- }
- else if (result)
- {
- /* Test expecting UNKNOWN_ATTRIBUTE, and we're parsing with
- * collect_known_attributes(). */
- g_assert_no_error (error);
- }
- else
- {
- g_assert_error (error, G_MARKUP_ERROR, test->error_code);
- }
-
- g_markup_parse_context_free (ctx);
- g_string_free (data.string, TRUE);
- g_clear_error (&error);
+ g_assert_no_error (error);
+ g_assert_cmpint (test->error_code, ==, 0);
+ g_assert_cmpstr (test->result, ==, string->str);
}
+ else
+ {
+ g_assert_error (error, G_MARKUP_ERROR, test->error_code);
+ }
+
+ g_markup_parse_context_free (ctx);
+ g_string_free (string, TRUE);
+ g_clear_error (&error);
}
#define XML "<element a='1' b='2' c='3'/>"