1 #undef G_DISABLE_ASSERT
2 #undef G_LOG_DOMAIN
3
4 #include <stdio.h>
5 #include <glib.h>
6
7 static int depth = 0;
8
9 static void
indent(int extra)10 indent (int extra)
11 {
12 int i = 0;
13 while (i < depth)
14 {
15 fputs (" ", stdout);
16 ++i;
17 }
18 }
19
20 static void
start_element_handler(GMarkupParseContext * context,const gchar * element_name,const gchar ** attribute_names,const gchar ** attribute_values,gpointer user_data,GError ** error)21 start_element_handler (GMarkupParseContext *context,
22 const gchar *element_name,
23 const gchar **attribute_names,
24 const gchar **attribute_values,
25 gpointer user_data,
26 GError **error)
27 {
28 int i;
29
30 indent (0);
31 printf ("ELEMENT '%s'\n", element_name);
32
33 i = 0;
34 while (attribute_names[i] != NULL)
35 {
36 indent (1);
37
38 printf ("%s=\"%s\"\n",
39 attribute_names[i],
40 attribute_values[i]);
41
42 ++i;
43 }
44
45 ++depth;
46 }
47
48 static void
end_element_handler(GMarkupParseContext * context,const gchar * element_name,gpointer user_data,GError ** error)49 end_element_handler (GMarkupParseContext *context,
50 const gchar *element_name,
51 gpointer user_data,
52 GError **error)
53 {
54 --depth;
55 indent (0);
56 printf ("END '%s'\n", element_name);
57 }
58
59 static void
text_handler(GMarkupParseContext * context,const gchar * text,gsize text_len,gpointer user_data,GError ** error)60 text_handler (GMarkupParseContext *context,
61 const gchar *text,
62 gsize text_len,
63 gpointer user_data,
64 GError **error)
65 {
66 indent (0);
67 printf ("TEXT '%.*s'\n", (int)text_len, text);
68 }
69
70
71 static void
passthrough_handler(GMarkupParseContext * context,const gchar * passthrough_text,gsize text_len,gpointer user_data,GError ** error)72 passthrough_handler (GMarkupParseContext *context,
73 const gchar *passthrough_text,
74 gsize text_len,
75 gpointer user_data,
76 GError **error)
77 {
78 indent (0);
79
80 printf ("PASS '%.*s'\n", (int)text_len, passthrough_text);
81 }
82
83 static void
error_handler(GMarkupParseContext * context,GError * error,gpointer user_data)84 error_handler (GMarkupParseContext *context,
85 GError *error,
86 gpointer user_data)
87 {
88 fprintf (stderr, " %s\n", error->message);
89 }
90
91 static const GMarkupParser parser = {
92 start_element_handler,
93 end_element_handler,
94 text_handler,
95 passthrough_handler,
96 error_handler
97 };
98
99 static const GMarkupParser silent_parser = {
100 NULL,
101 NULL,
102 NULL,
103 NULL,
104 error_handler
105 };
106
107 static int
test_in_chunks(const gchar * contents,gint length,gint chunk_size)108 test_in_chunks (const gchar *contents,
109 gint length,
110 gint chunk_size)
111 {
112 GMarkupParseContext *context;
113 int i = 0;
114
115 context = g_markup_parse_context_new (&silent_parser, 0, NULL, NULL);
116
117 while (i < length)
118 {
119 int this_chunk = MIN (length - i, chunk_size);
120
121 if (!g_markup_parse_context_parse (context,
122 contents + i,
123 this_chunk,
124 NULL))
125 {
126 g_markup_parse_context_free (context);
127 return 1;
128 }
129
130 i += this_chunk;
131 }
132
133 if (!g_markup_parse_context_end_parse (context, NULL))
134 {
135 g_markup_parse_context_free (context);
136 return 1;
137 }
138
139 g_markup_parse_context_free (context);
140
141 return 0;
142 }
143
144 static int
test_file(const gchar * filename)145 test_file (const gchar *filename)
146 {
147 gchar *contents;
148 gsize length;
149 GError *error;
150 GMarkupParseContext *context;
151
152 error = NULL;
153 if (!g_file_get_contents (filename,
154 &contents,
155 &length,
156 &error))
157 {
158 fprintf (stderr, "%s\n", error->message);
159 g_error_free (error);
160 return 1;
161 }
162
163 context = g_markup_parse_context_new (&parser, 0, NULL, NULL);
164
165 if (!g_markup_parse_context_parse (context, contents, length, NULL))
166 {
167 g_markup_parse_context_free (context);
168 return 1;
169 }
170
171 if (!g_markup_parse_context_end_parse (context, NULL))
172 {
173 g_markup_parse_context_free (context);
174 return 1;
175 }
176
177 g_markup_parse_context_free (context);
178
179 /* A byte at a time */
180 if (test_in_chunks (contents, length, 1) != 0)
181 return 1;
182
183 /* 2 bytes */
184 if (test_in_chunks (contents, length, 2) != 0)
185 return 1;
186
187 /*5 bytes */
188 if (test_in_chunks (contents, length, 5) != 0)
189 return 1;
190
191 /* 12 bytes */
192 if (test_in_chunks (contents, length, 12) != 0)
193 return 1;
194
195 /* 1024 bytes */
196 if (test_in_chunks (contents, length, 1024) != 0)
197 return 1;
198
199 return 0;
200 }
201
202 int
main(int argc,char * argv[])203 main (int argc,
204 char *argv[])
205 {
206 if (argc > 1)
207 return test_file (argv[1]);
208 else
209 {
210 fprintf (stderr, "Give a markup file on the command line\n");
211 return 1;
212 }
213 }
214
215