2 * Copyright © 2007 Ryan Lortie
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or (at your option) any later version.
9 * See the included COPYING file for more information.
17 start (GMarkupParseContext
*context
,
18 const char *element_name
,
19 const char **attribute_names
,
20 const char **attribute_values
,
24 GString
*string
= user_data
;
27 #define collect(...) \
28 g_markup_collect_attributes (element_name, attribute_names, \
29 attribute_values, error, __VA_ARGS__, \
30 G_MARKUP_COLLECT_INVALID)
31 #define BOOL G_MARKUP_COLLECT_BOOLEAN
32 #define OPTBOOL G_MARKUP_COLLECT_BOOLEAN | G_MARKUP_COLLECT_OPTIONAL
33 #define TRI G_MARKUP_COLLECT_TRISTATE
34 #define STR G_MARKUP_COLLECT_STRING
35 #define STRDUP G_MARKUP_COLLECT_STRDUP
36 #define OPTSTR G_MARKUP_COLLECT_STRING | G_MARKUP_COLLECT_OPTIONAL
37 #define OPTDUP G_MARKUP_COLLECT_STRDUP | G_MARKUP_COLLECT_OPTIONAL
38 #define n(x) ((x)?(x):"(null)")
40 if (strcmp (element_name
, "bool") == 0)
42 gboolean mb
= 2, ob
= 2, tri
= 2;
44 result
= collect (BOOL
, "mb", &mb
,
49 (mb
== FALSE
&& ob
== FALSE
&& tri
!= TRUE
&& tri
!= FALSE
));
51 if (tri
!= FALSE
&& tri
!= TRUE
)
54 g_string_append_printf (string
, "<bool(%d) %d %d %d>",
58 else if (strcmp (element_name
, "str") == 0)
63 result
= collect (STR
, "cm", &cm
,
69 (cm
== NULL
&& am
== NULL
&& ao
== NULL
&& co
== NULL
));
71 g_string_append_printf (string
, "<str(%d) %s %s %s %s>",
72 result
, n (cm
), n (am
), n (ao
), n (co
));
79 static GMarkupParser parser
= { start
};
85 GMarkupError error_code
;
86 const char *error_info
;
89 static struct test tests
[] =
91 { "<bool mb='y'>", "<bool(1) 1 0 -1>",
92 G_MARKUP_ERROR_PARSE
, "'bool'" },
94 { "<bool mb='false'/>", "<bool(1) 0 0 -1>" },
95 { "<bool mb='true'/>", "<bool(1) 1 0 -1>" },
96 { "<bool mb='t' ob='f' tri='1'/>", "<bool(1) 1 0 1>" },
97 { "<bool mb='y' ob='n' tri='0'/>", "<bool(1) 1 0 0>" },
99 { "<bool mb='y' my:attr='q'><my:tag/></bool>", "<bool(1) 1 0 -1>" },
100 { "<bool mb='y' my:attr='q'><my:tag>some <b>text</b> is in here</my:tag></bool>", "<bool(1) 1 0 -1>" },
102 { "<bool ob='y'/>", "<bool(0) 0 0 -1>",
103 G_MARKUP_ERROR_MISSING_ATTRIBUTE
, "'mb'" },
105 { "<bool mb='y' mb='y'/>", "<bool(0) 0 0 -1>",
106 G_MARKUP_ERROR_INVALID_CONTENT
, "'mb'" },
108 { "<bool mb='y' tri='y' tri='n'/>", "<bool(0) 0 0 -1>",
109 G_MARKUP_ERROR_INVALID_CONTENT
, "'tri'" },
111 { "<str cm='x' am='y'/>", "<str(1) x y (null) (null)>" },
113 { "<str am='x' co='y'/>", "<str(0) (null) (null) (null) (null)>",
114 G_MARKUP_ERROR_MISSING_ATTRIBUTE
, "'cm'" },
116 { "<str am='x'/>", "<str(0) (null) (null) (null) (null)>",
117 G_MARKUP_ERROR_MISSING_ATTRIBUTE
, "'cm'" },
119 { "<str am='x' cm='x' am='y'/>", "<str(0) (null) (null) (null) (null)>",
120 G_MARKUP_ERROR_INVALID_CONTENT
, "'am'" },
122 { "<str am='x' qm='y' cm='x'/>", "<str(0) (null) (null) (null) (null)>",
123 G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE
, "'qm'" },
125 { "<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)>",
126 G_MARKUP_ERROR_INVALID_CONTENT
, "'am'" },
128 { "<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)>",
129 G_MARKUP_ERROR_INVALID_CONTENT
, "'am'" },
131 { "<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'/>",
132 "<str(0) (null) (null) (null) (null)>",
133 G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE
, "'a'" },
135 { "<bool mb='ja'/>", "<bool(0) 0 0 -1>",
136 G_MARKUP_ERROR_INVALID_CONTENT
, "'mb'" },
138 { "<bool mb='nein'/>", "<bool(0) 0 0 -1>",
139 G_MARKUP_ERROR_INVALID_CONTENT
, "'mb'" }
143 test_collect (gconstpointer d
)
145 const struct test
*test
= d
;
147 GMarkupParseContext
*ctx
;
148 GError
*error
= NULL
;
152 string
= g_string_new ("");
153 ctx
= g_markup_parse_context_new (&parser
, G_MARKUP_IGNORE_QUALIFIED
, string
, NULL
);
154 result
= g_markup_parse_context_parse (ctx
,
158 result
= g_markup_parse_context_end_parse (ctx
, &error
);
162 g_assert_no_error (error
);
163 g_assert_cmpint (test
->error_code
, ==, 0);
164 g_assert_cmpstr (test
->result
, ==, string
->str
);
168 g_assert_error (error
, G_MARKUP_ERROR
, test
->error_code
);
171 g_markup_parse_context_free (ctx
);
172 g_string_free (string
, TRUE
);
173 g_clear_error (&error
);
176 #define XML "<element a='1' b='2' c='3'/>"
179 start_element (GMarkupParseContext
*context
,
180 const gchar
*element_name
,
181 const gchar
**attribute_names
,
182 const gchar
**attribute_values
,
186 /* Omitting "c" attribute intentionally to trigger crash. */
187 g_markup_collect_attributes (element_name
,
191 G_MARKUP_COLLECT_STRING
, "a", NULL
,
192 G_MARKUP_COLLECT_STRING
, "b", NULL
,
193 G_MARKUP_COLLECT_INVALID
);
196 static GMarkupParser cleanup_parser
= {
203 GMarkupParseContext
*context
;
205 if (!g_test_undefined ())
208 context
= g_markup_parse_context_new (&cleanup_parser
, 0, NULL
, NULL
);
209 g_markup_parse_context_parse (context
, XML
, -1, NULL
);
211 g_test_expect_message (G_LOG_DOMAIN
, G_LOG_LEVEL_CRITICAL
,
212 "g_markup_parse_context_end_parse: assertion 'context->state != STATE_ERROR' failed");
213 g_markup_parse_context_end_parse (context
, NULL
);
214 g_test_assert_expected_messages ();
216 g_markup_parse_context_free (context
);
220 main (int argc
, char **argv
)
225 g_test_init (&argc
, &argv
, NULL
);
227 for (i
= 0; i
< G_N_ELEMENTS (tests
); i
++)
229 path
= g_strdup_printf ("/markup/collect/%d", i
);
230 g_test_add_data_func (path
, &tests
[i
], test_collect
);
234 g_test_add_func ("/markup/collect/cleanup", test_cleanup
);
236 return g_test_run ();