glib/tests: fix leaks
[platform/upstream/glib.git] / glib / tests / markup-parse.c
1 #undef G_DISABLE_ASSERT
2 #undef G_LOG_DOMAIN
3
4 #include <locale.h>
5 #include <string.h>
6 #include <stdio.h>
7 #include <glib.h>
8
9 #ifndef SRCDIR
10 #define SRCDIR "."
11 #endif
12
13 static int depth = 0;
14 static GString *string;
15
16 static void
17 indent (int extra)
18 {
19   int i = 0;
20   while (i < depth)
21     {
22       g_string_append (string, "  ");
23       ++i;
24     }
25 }
26
27 static void
28 start_element_handler  (GMarkupParseContext *context,
29                         const gchar         *element_name,
30                         const gchar        **attribute_names,
31                         const gchar        **attribute_values,
32                         gpointer             user_data,
33                         GError             **error)
34 {
35   int i;
36   
37   indent (0);
38   g_string_append_printf (string, "ELEMENT '%s'\n", element_name);
39
40   i = 0;
41   while (attribute_names[i] != NULL)
42     {
43       indent (1);
44
45       g_string_append_printf (string, "%s=\"%s\"\n",
46                               attribute_names[i],
47                               attribute_values[i]);
48       
49       ++i;
50     }
51   
52   ++depth;
53 }
54
55 static void
56 end_element_handler (GMarkupParseContext *context,
57                      const gchar         *element_name,
58                      gpointer             user_data,
59                      GError             **error)
60 {
61   --depth;
62   indent (0);
63   g_string_append_printf (string, "END '%s'\n", element_name);
64   }
65
66 static void
67 text_handler (GMarkupParseContext *context,
68               const gchar         *text,
69               gsize                text_len,
70               gpointer             user_data,
71               GError             **error)
72 {
73   indent (0);
74   g_string_append_printf (string, "TEXT '%.*s'\n", (int)text_len, text);
75 }
76
77
78 static void
79 passthrough_handler (GMarkupParseContext *context,
80                      const gchar         *passthrough_text,
81                      gsize                text_len,
82                      gpointer             user_data,
83                      GError             **error)
84 {
85   indent (0);
86
87   g_string_append_printf (string, "PASS '%.*s'\n", (int)text_len, passthrough_text);
88 }
89
90 static void
91 error_handler (GMarkupParseContext *context,
92                GError              *error,
93                gpointer             user_data)
94 {
95   g_string_append_printf (string, "ERROR %s\n", error->message);
96 }
97
98 static const GMarkupParser parser = {
99   start_element_handler,
100   end_element_handler,
101   text_handler,
102   passthrough_handler,
103   error_handler
104 };
105
106 static const GMarkupParser silent_parser = {
107   NULL,
108   NULL,
109   NULL,
110   NULL,
111   error_handler
112 };
113
114 static int
115 test_in_chunks (const gchar *contents,
116                 gint         length,
117                 gint         chunk_size)
118 {
119   GMarkupParseContext *context;
120   int i = 0;
121   
122   context = g_markup_parse_context_new (&silent_parser, 0, NULL, NULL);
123
124   while (i < length)
125     {
126       int this_chunk = MIN (length - i, chunk_size);
127
128       if (!g_markup_parse_context_parse (context,
129                                          contents + i,
130                                          this_chunk,
131                                          NULL))
132         {
133           g_markup_parse_context_free (context);
134           return 1;
135         }
136
137       i += this_chunk;
138     }
139       
140   if (!g_markup_parse_context_end_parse (context, NULL))
141     {
142       g_markup_parse_context_free (context);
143       return 1;
144     }
145
146   g_markup_parse_context_free (context);
147
148   return 0;
149 }
150
151 static int
152 test_file (const gchar *filename)
153 {
154   gchar *contents;
155   gsize  length;
156   GError *error;
157   GMarkupParseContext *context;
158   gint line, col;
159
160   error = NULL;
161   if (!g_file_get_contents (filename,
162                             &contents,
163                             &length,
164                             &error))
165     {
166       fprintf (stderr, "%s\n", error->message);
167       g_error_free (error);
168       return 1;
169     }
170
171   context = g_markup_parse_context_new (&parser, 0, NULL, NULL);
172   g_assert (g_markup_parse_context_get_user_data (context) == NULL);
173   g_markup_parse_context_get_position (context, &line, &col);
174   g_assert (line == 1 && col == 1);
175
176   if (!g_markup_parse_context_parse (context, contents, length, NULL))
177     {
178       g_markup_parse_context_free (context);
179       g_free (contents);
180       return 1;
181     }
182
183   if (!g_markup_parse_context_end_parse (context, NULL))
184     {
185       g_markup_parse_context_free (context);
186       g_free (contents);
187       return 1;
188     }
189
190   g_markup_parse_context_free (context);
191
192   /* A byte at a time */
193   if (test_in_chunks (contents, length, 1) != 0)
194     {
195       g_free (contents);
196       return 1;
197     }
198
199   /* 2 bytes */
200   if (test_in_chunks (contents, length, 2) != 0)
201     {
202       g_free (contents);
203       return 1;
204     }
205
206   /*5 bytes */
207   if (test_in_chunks (contents, length, 5) != 0)
208     {
209       g_free (contents);
210       return 1;
211     }
212
213   /* 12 bytes */
214   if (test_in_chunks (contents, length, 12) != 0)
215     {
216       g_free (contents);
217       return 1;
218     }
219
220   /* 1024 bytes */
221   if (test_in_chunks (contents, length, 1024) != 0)
222     {
223       g_free (contents);
224       return 1;
225     }
226
227   g_free (contents);
228
229   return 0;
230 }
231
232 static gchar *
233 get_expected_filename (const gchar *filename)
234 {
235   gchar *f, *p, *expected;
236
237   f = g_strdup (filename);
238   p = strstr (f, ".gmarkup");
239   if (p)
240     *p = 0;
241   expected = g_strconcat (f, ".expected", NULL);
242   g_free (f);
243
244   return expected;
245 }
246
247 static void
248 test_parse (gconstpointer d)
249 {
250   const gchar *filename = d;
251   gchar *expected_file;
252   gchar *expected;
253   gint res;
254
255   depth = 0;
256   string = g_string_sized_new (0);
257
258   res = test_file (filename);
259
260   if (strstr (filename, "valid"))
261     g_assert_cmpint (res, ==, 0);
262   else
263     g_assert_cmpint (res, ==, 1);
264
265   expected_file = get_expected_filename (filename);
266   if (g_file_get_contents (expected_file, &expected, NULL, NULL))
267     {
268       g_assert_cmpstr (string->str, ==, expected);
269       g_free (expected);
270     }
271   g_free (expected_file);
272
273   g_string_free (string, TRUE);
274 }
275
276 int
277 main (int argc, char *argv[])
278 {
279   GDir *dir;
280   GError *error;
281   const gchar *name;
282   gchar *path;
283
284   g_setenv ("LANG", "en_US.utf-8", TRUE);
285   setlocale (LC_ALL, "");
286
287   g_test_init (&argc, &argv, NULL);
288
289   /* allow to easily generate expected output for new test cases */
290   if (argc > 1)
291     {
292       string = g_string_sized_new (0);
293       test_file (argv[1]);
294       g_print ("%s", string->str);
295       return 0;
296     }
297
298   error = NULL;
299   dir = g_dir_open (SRCDIR "/markups", 0, &error);
300   g_assert_no_error (error);
301   while ((name = g_dir_read_name (dir)) != NULL)
302     {
303       if (strstr (name, "expected"))
304         continue;
305
306       path = g_strdup_printf ("/markup/parse/%s", name);
307       g_test_add_data_func_full (path, g_build_filename (SRCDIR, "markups", name, NULL),
308                                  test_parse, g_free);
309       g_free (path);
310     }
311   g_dir_close (dir);
312
313   return g_test_run ();
314 }
315