nexmon – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | /* |
2 | * Copyright © 2007 Ryan Lortie |
||
3 | * |
||
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. |
||
8 | * |
||
9 | * See the included COPYING file for more information. |
||
10 | */ |
||
11 | |||
12 | #include <stdlib.h> |
||
13 | #include <string.h> |
||
14 | #include <glib.h> |
||
15 | |||
16 | static void |
||
17 | start (GMarkupParseContext *context, |
||
18 | const char *element_name, |
||
19 | const char **attribute_names, |
||
20 | const char **attribute_values, |
||
21 | gpointer user_data, |
||
22 | GError **error) |
||
23 | { |
||
24 | GString *string = user_data; |
||
25 | gboolean result; |
||
26 | |||
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)") |
||
39 | |||
40 | if (strcmp (element_name, "bool") == 0) |
||
41 | { |
||
42 | gboolean mb = 2, ob = 2, tri = 2; |
||
43 | |||
44 | result = collect (BOOL, "mb", &mb, |
||
45 | OPTBOOL, "ob", &ob, |
||
46 | TRI, "tri", &tri); |
||
47 | |||
48 | g_assert (result || |
||
49 | (mb == FALSE && ob == FALSE && tri != TRUE && tri != FALSE)); |
||
50 | |||
51 | if (tri != FALSE && tri != TRUE) |
||
52 | tri = -1; |
||
53 | |||
54 | g_string_append_printf (string, "<bool(%d) %d %d %d>", |
||
55 | result, mb, ob, tri); |
||
56 | } |
||
57 | |||
58 | else if (strcmp (element_name, "str") == 0) |
||
59 | { |
||
60 | const char *cm, *co; |
||
61 | char *am, *ao; |
||
62 | |||
63 | result = collect (STR, "cm", &cm, |
||
64 | STRDUP, "am", &am, |
||
65 | OPTDUP, "ao", &ao, |
||
66 | OPTSTR, "co", &co); |
||
67 | |||
68 | g_assert (result || |
||
69 | (cm == NULL && am == NULL && ao == NULL && co == NULL)); |
||
70 | |||
71 | g_string_append_printf (string, "<str(%d) %s %s %s %s>", |
||
72 | result, n (cm), n (am), n (ao), n (co)); |
||
73 | |||
74 | g_free (am); |
||
75 | g_free (ao); |
||
76 | } |
||
77 | } |
||
78 | |||
79 | static GMarkupParser parser = { start }; |
||
80 | |||
81 | struct test |
||
82 | { |
||
83 | const char *document; |
||
84 | const char *result; |
||
85 | GMarkupError error_code; |
||
86 | const char *error_info; |
||
87 | }; |
||
88 | |||
89 | static struct test tests[] = |
||
90 | { |
||
91 | { "<bool mb='y'>", "<bool(1) 1 0 -1>", |
||
92 | G_MARKUP_ERROR_PARSE, "'bool'" }, |
||
93 | |||
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>" }, |
||
98 | |||
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>" }, |
||
101 | |||
102 | { "<bool ob='y'/>", "<bool(0) 0 0 -1>", |
||
103 | G_MARKUP_ERROR_MISSING_ATTRIBUTE, "'mb'" }, |
||
104 | |||
105 | { "<bool mb='y' mb='y'/>", "<bool(0) 0 0 -1>", |
||
106 | G_MARKUP_ERROR_INVALID_CONTENT, "'mb'" }, |
||
107 | |||
108 | { "<bool mb='y' tri='y' tri='n'/>", "<bool(0) 0 0 -1>", |
||
109 | G_MARKUP_ERROR_INVALID_CONTENT, "'tri'" }, |
||
110 | |||
111 | { "<str cm='x' am='y'/>", "<str(1) x y (null) (null)>" }, |
||
112 | |||
113 | { "<str am='x' co='y'/>", "<str(0) (null) (null) (null) (null)>", |
||
114 | G_MARKUP_ERROR_MISSING_ATTRIBUTE, "'cm'" }, |
||
115 | |||
116 | { "<str am='x'/>", "<str(0) (null) (null) (null) (null)>", |
||
117 | G_MARKUP_ERROR_MISSING_ATTRIBUTE, "'cm'" }, |
||
118 | |||
119 | { "<str am='x' cm='x' am='y'/>", "<str(0) (null) (null) (null) (null)>", |
||
120 | G_MARKUP_ERROR_INVALID_CONTENT, "'am'" }, |
||
121 | |||
122 | { "<str am='x' qm='y' cm='x'/>", "<str(0) (null) (null) (null) (null)>", |
||
123 | G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE, "'qm'" }, |
||
124 | |||
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'" }, |
||
127 | |||
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'" }, |
||
130 | |||
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'" }, |
||
134 | |||
135 | { "<bool mb='ja'/>", "<bool(0) 0 0 -1>", |
||
136 | G_MARKUP_ERROR_INVALID_CONTENT, "'mb'" }, |
||
137 | |||
138 | { "<bool mb='nein'/>", "<bool(0) 0 0 -1>", |
||
139 | G_MARKUP_ERROR_INVALID_CONTENT, "'mb'" } |
||
140 | }; |
||
141 | |||
142 | static void |
||
143 | test_collect (gconstpointer d) |
||
144 | { |
||
145 | const struct test *test = d; |
||
146 | |||
147 | GMarkupParseContext *ctx; |
||
148 | GError *error = NULL; |
||
149 | GString *string; |
||
150 | gboolean result; |
||
151 | |||
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, |
||
155 | test->document, |
||
156 | -1, &error); |
||
157 | if (result) |
||
158 | result = g_markup_parse_context_end_parse (ctx, &error); |
||
159 | |||
160 | if (result) |
||
161 | { |
||
162 | g_assert_no_error (error); |
||
163 | g_assert_cmpint (test->error_code, ==, 0); |
||
164 | g_assert_cmpstr (test->result, ==, string->str); |
||
165 | } |
||
166 | else |
||
167 | { |
||
168 | g_assert_error (error, G_MARKUP_ERROR, test->error_code); |
||
169 | } |
||
170 | |||
171 | g_markup_parse_context_free (ctx); |
||
172 | g_string_free (string, TRUE); |
||
173 | g_clear_error (&error); |
||
174 | } |
||
175 | |||
176 | #define XML "<element a='1' b='2' c='3'/>" |
||
177 | |||
178 | static void |
||
179 | start_element (GMarkupParseContext *context, |
||
180 | const gchar *element_name, |
||
181 | const gchar **attribute_names, |
||
182 | const gchar **attribute_values, |
||
183 | gpointer user_data, |
||
184 | GError **error) |
||
185 | { |
||
186 | /* Omitting "c" attribute intentionally to trigger crash. */ |
||
187 | g_markup_collect_attributes (element_name, |
||
188 | attribute_names, |
||
189 | attribute_values, |
||
190 | error, |
||
191 | G_MARKUP_COLLECT_STRING, "a", NULL, |
||
192 | G_MARKUP_COLLECT_STRING, "b", NULL, |
||
193 | G_MARKUP_COLLECT_INVALID); |
||
194 | } |
||
195 | |||
196 | static GMarkupParser cleanup_parser = { |
||
197 | start_element |
||
198 | }; |
||
199 | |||
200 | static void |
||
201 | test_cleanup (void) |
||
202 | { |
||
203 | GMarkupParseContext *context; |
||
204 | |||
205 | if (!g_test_undefined ()) |
||
206 | return; |
||
207 | |||
208 | context = g_markup_parse_context_new (&cleanup_parser, 0, NULL, NULL); |
||
209 | g_markup_parse_context_parse (context, XML, -1, NULL); |
||
210 | |||
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 (); |
||
215 | |||
216 | g_markup_parse_context_free (context); |
||
217 | } |
||
218 | |||
219 | int |
||
220 | main (int argc, char **argv) |
||
221 | { |
||
222 | int i; |
||
223 | gchar *path; |
||
224 | |||
225 | g_test_init (&argc, &argv, NULL); |
||
226 | |||
227 | for (i = 0; i < G_N_ELEMENTS (tests); i++) |
||
228 | { |
||
229 | path = g_strdup_printf ("/markup/collect/%d", i); |
||
230 | g_test_add_data_func (path, &tests[i], test_collect); |
||
231 | g_free (path); |
||
232 | } |
||
233 | |||
234 | g_test_add_func ("/markup/collect/cleanup", test_cleanup); |
||
235 | |||
236 | return g_test_run (); |
||
237 | } |