/* * 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.1 of the License, or (at your option) any later version. * * See the included COPYING file for more information. */ #include #include #include 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, "", 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, "", 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[] = { { "", "", G_MARKUP_ERROR_PARSE, "'bool'" }, { "", "" }, { "", "" }, { "", "" }, { "", "" }, { "", "" }, { "some text is in here", "" }, { "", "", G_MARKUP_ERROR_MISSING_ATTRIBUTE, "'mb'" }, { "", "", G_MARKUP_ERROR_INVALID_CONTENT, "'mb'" }, { "", "", G_MARKUP_ERROR_INVALID_CONTENT, "'tri'" }, { "", "" }, { "", "", G_MARKUP_ERROR_MISSING_ATTRIBUTE, "'cm'" }, { "", "", G_MARKUP_ERROR_MISSING_ATTRIBUTE, "'cm'" }, { "", "", G_MARKUP_ERROR_INVALID_CONTENT, "'am'" }, { "", "", G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE, "'qm'" }, { "", "", G_MARKUP_ERROR_INVALID_CONTENT, "'am'" }, { "", "", G_MARKUP_ERROR_INVALID_CONTENT, "'am'" }, { "", "", G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE, "'a'" }, { "", "", G_MARKUP_ERROR_INVALID_CONTENT, "'mb'" }, { "", "", 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, G_MARKUP_IGNORE_QUALIFIED, 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 "" 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 (); }