mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-01-09 22:16:15 +01:00
59394b3e1e
We need to have some more discussion on this topic. This reverts commits86329ba44f
and8d40389d15
. https://bugzilla.gnome.org/show_bug.cgi?id=665634
235 lines
7.7 KiB
C
235 lines
7.7 KiB
C
/*
|
|
* 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 <stdlib.h>
|
|
#include <string.h>
|
|
#include <glib.h>
|
|
|
|
static void
|
|
start (GMarkupParseContext *context,
|
|
const char *element_name,
|
|
const char **attribute_names,
|
|
const char **attribute_values,
|
|
gpointer user_data,
|
|
GError **error)
|
|
{
|
|
GString *string = user_data;
|
|
gboolean result;
|
|
|
|
#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
|
|
#define STR G_MARKUP_COLLECT_STRING
|
|
#define STRDUP G_MARKUP_COLLECT_STRDUP
|
|
#define OPTSTR G_MARKUP_COLLECT_STRING | G_MARKUP_COLLECT_OPTIONAL
|
|
#define OPTDUP G_MARKUP_COLLECT_STRDUP | G_MARKUP_COLLECT_OPTIONAL
|
|
#define n(x) ((x)?(x):"(null)")
|
|
|
|
if (strcmp (element_name, "bool") == 0)
|
|
{
|
|
gboolean mb = 2, ob = 2, tri = 2;
|
|
|
|
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 (string, "<bool(%d) %d %d %d>",
|
|
result, mb, ob, tri);
|
|
}
|
|
|
|
else if (strcmp (element_name, "str") == 0)
|
|
{
|
|
const char *cm, *co;
|
|
char *am, *ao;
|
|
|
|
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 (string, "<str(%d) %s %s %s %s>",
|
|
result, n (cm), n (am), n (ao), n (co));
|
|
|
|
g_free (am);
|
|
g_free (ao);
|
|
}
|
|
}
|
|
|
|
static GMarkupParser parser = { start };
|
|
|
|
struct test
|
|
{
|
|
const char *document;
|
|
const char *result;
|
|
GMarkupError error_code;
|
|
const char *error_info;
|
|
};
|
|
|
|
static struct test tests[] =
|
|
{
|
|
{ "<bool mb='y'>", "<bool(1) 1 0 -1>",
|
|
G_MARKUP_ERROR_PARSE, "'bool'" },
|
|
|
|
{ "<bool mb='false'/>", "<bool(1) 0 0 -1>" },
|
|
{ "<bool mb='true'/>", "<bool(1) 1 0 -1>" },
|
|
{ "<bool mb='t' ob='f' tri='1'/>", "<bool(1) 1 0 1>" },
|
|
{ "<bool mb='y' ob='n' tri='0'/>", "<bool(1) 1 0 0>" },
|
|
|
|
{ "<bool ob='y'/>", "<bool(0) 0 0 -1>",
|
|
G_MARKUP_ERROR_MISSING_ATTRIBUTE, "'mb'" },
|
|
|
|
{ "<bool mb='y' mb='y'/>", "<bool(0) 0 0 -1>",
|
|
G_MARKUP_ERROR_INVALID_CONTENT, "'mb'" },
|
|
|
|
{ "<bool mb='y' tri='y' tri='n'/>", "<bool(0) 0 0 -1>",
|
|
G_MARKUP_ERROR_INVALID_CONTENT, "'tri'" },
|
|
|
|
{ "<str cm='x' am='y'/>", "<str(1) x y (null) (null)>" },
|
|
|
|
{ "<str am='x' co='y'/>", "<str(0) (null) (null) (null) (null)>",
|
|
G_MARKUP_ERROR_MISSING_ATTRIBUTE, "'cm'" },
|
|
|
|
{ "<str am='x'/>", "<str(0) (null) (null) (null) (null)>",
|
|
G_MARKUP_ERROR_MISSING_ATTRIBUTE, "'cm'" },
|
|
|
|
{ "<str am='x' cm='x' am='y'/>", "<str(0) (null) (null) (null) (null)>",
|
|
G_MARKUP_ERROR_INVALID_CONTENT, "'am'" },
|
|
|
|
{ "<str am='x' qm='y' cm='x'/>", "<str(0) (null) (null) (null) (null)>",
|
|
G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE, "'qm'" },
|
|
|
|
{ "<str am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' cm='x'/>", "<str(0) (null) (null) (null) (null)>",
|
|
G_MARKUP_ERROR_INVALID_CONTENT, "'am'" },
|
|
|
|
{ "<str cm='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x'/>", "<str(0) (null) (null) (null) (null)>",
|
|
G_MARKUP_ERROR_INVALID_CONTENT, "'am'" },
|
|
|
|
{ "<str a='x' b='x' c='x' d='x' e='x' f='x' g='x' h='x' i='x' j='x' k='x' l='x' m='x' n='x' o='x' p='x' q='x' r='x' s='x' t='x' u='x' v='x' w='x' x='x' y='x' z='x' aa='x' bb='x' cc='x' dd='x' ee='x' ff='x' gg='x' hh='x' ii='x' jj='x' kk='x' ll='x' mm='x' nn='x' oo='x' pp='x' qq='x' rr='x' ss='x' tt='x' uu='x' vv='x' ww='x' xx='x' yy='x' zz='x' am='x' cm='x'/>",
|
|
"<str(0) (null) (null) (null) (null)>",
|
|
G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE, "'a'" },
|
|
|
|
{ "<bool mb='ja'/>", "<bool(0) 0 0 -1>",
|
|
G_MARKUP_ERROR_INVALID_CONTENT, "'mb'" },
|
|
|
|
{ "<bool mb='nein'/>", "<bool(0) 0 0 -1>",
|
|
G_MARKUP_ERROR_INVALID_CONTENT, "'mb'" }
|
|
};
|
|
|
|
static void
|
|
test_collect (gconstpointer d)
|
|
{
|
|
const struct test *test = d;
|
|
|
|
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)
|
|
{
|
|
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'/>"
|
|
|
|
static void
|
|
start_element (GMarkupParseContext *context,
|
|
const gchar *element_name,
|
|
const gchar **attribute_names,
|
|
const gchar **attribute_values,
|
|
gpointer user_data,
|
|
GError **error)
|
|
{
|
|
/* Omitting "c" attribute intentionally to trigger crash. */
|
|
g_markup_collect_attributes (element_name,
|
|
attribute_names,
|
|
attribute_values,
|
|
error,
|
|
G_MARKUP_COLLECT_STRING, "a", NULL,
|
|
G_MARKUP_COLLECT_STRING, "b", NULL,
|
|
G_MARKUP_COLLECT_INVALID);
|
|
}
|
|
|
|
static GMarkupParser cleanup_parser = {
|
|
start_element
|
|
};
|
|
|
|
static void
|
|
test_cleanup (void)
|
|
{
|
|
GMarkupParseContext *context;
|
|
|
|
if (!g_test_undefined ())
|
|
return;
|
|
|
|
context = g_markup_parse_context_new (&cleanup_parser, 0, NULL, NULL);
|
|
g_markup_parse_context_parse (context, XML, -1, NULL);
|
|
|
|
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
|
|
"g_markup_parse_context_end_parse: assertion `context->state != STATE_ERROR' failed");
|
|
g_markup_parse_context_end_parse (context, NULL);
|
|
g_test_assert_expected_messages ();
|
|
|
|
g_markup_parse_context_free (context);
|
|
}
|
|
|
|
int
|
|
main (int argc, char **argv)
|
|
{
|
|
int i;
|
|
gchar *path;
|
|
|
|
g_test_init (&argc, &argv, NULL);
|
|
|
|
for (i = 0; i < G_N_ELEMENTS (tests); i++)
|
|
{
|
|
path = g_strdup_printf ("/markup/collect/%d", i);
|
|
g_test_add_data_func (path, &tests[i], test_collect);
|
|
g_free (path);
|
|
}
|
|
|
|
g_test_add_func ("/markup/collect/cleanup", test_cleanup);
|
|
|
|
return g_test_run ();
|
|
}
|