Bug 556186 – gpoll.h breaks gmain.h inclusion
[platform/upstream/glib.git] / glib / tests / keyfile.c
1 #include <glib.h>
2 #include <locale.h>
3 #include <string.h>
4 #include <stdlib.h>
5
6 static GKeyFile *
7 load_data (const gchar   *data, 
8            GKeyFileFlags  flags)
9 {
10   GKeyFile *keyfile;
11   GError *error = NULL;
12
13   keyfile = g_key_file_new ();
14   g_key_file_load_from_data (keyfile, data, -1, flags, &error);
15   g_assert_no_error (error);
16   return keyfile;
17 }
18
19 static void
20 check_error (GError **error,
21              GQuark   domain,
22              gint     code)
23 {
24   g_assert_error (*error, domain, code);
25   g_error_free (*error);
26   *error = NULL;
27 }
28
29 static void 
30 check_no_error (GError **error)
31 {
32   g_assert_no_error (*error);
33 }
34
35 static void
36 check_string_value (GKeyFile    *keyfile,
37                     const gchar *group,
38                     const gchar *key,
39                     const gchar *expected) 
40 {
41   GError *error = NULL;
42   gchar *value;
43
44   value = g_key_file_get_string (keyfile, group, key, &error);
45   check_no_error (&error);
46   g_assert (value != NULL);
47   g_assert_cmpstr (value, ==, expected);
48   g_free (value);
49 }
50
51 static void
52 check_locale_string_value (GKeyFile    *keyfile,
53                            const gchar *group,
54                            const gchar *key,
55                            const gchar *locale,
56                            const gchar *expected) 
57 {
58   GError *error = NULL;
59   gchar *value;
60
61   value = g_key_file_get_locale_string (keyfile, group, key, locale, &error);
62   check_no_error (&error);
63   g_assert (value != NULL);
64   g_assert_cmpstr (value, ==, expected);
65   g_free (value);
66 }
67
68 static void
69 check_string_list_value (GKeyFile    *keyfile,
70                          const gchar *group,
71                          const gchar *key,
72                          ...)
73 {
74   gint i;
75   gchar *v, **value;
76   va_list args;
77   gsize len;
78   GError *error = NULL;
79
80   value = g_key_file_get_string_list (keyfile, group, key, &len, &error);
81   check_no_error (&error);
82   g_assert (value != NULL);
83   
84   va_start (args, key);
85   i = 0;
86   v = va_arg (args, gchar*);
87   while (v)
88     {
89       g_assert (value[i] != NULL);
90       g_assert_cmpstr (v, ==, value[i]);
91       i++;
92       v = va_arg (args, gchar*);
93     }
94
95   va_end (args);
96   
97   g_strfreev (value);
98 }
99
100 static void
101 check_integer_list_value (GKeyFile    *keyfile,
102                           const gchar *group,
103                           const gchar *key,
104                           ...)
105 {
106   gint i;
107   gint v, *value;
108   va_list args;
109   gsize len;
110   GError *error = NULL;
111
112   value = g_key_file_get_integer_list (keyfile, group, key, &len, &error);
113   check_no_error (&error);
114   g_assert (value != NULL);
115   
116   va_start (args, key);
117   i = 0;
118   v = va_arg (args, gint);
119   while (v != -100)
120     {
121       g_assert_cmpint (i, <, len);
122       g_assert_cmpint (value[i], ==, v);
123       i++;
124       v = va_arg (args, gint);
125     }
126
127   va_end (args);
128   
129   g_free (value);
130 }
131
132 static void
133 check_double_list_value (GKeyFile    *keyfile,
134                           const gchar *group,
135                           const gchar *key,
136                           ...)
137 {
138   gint i;
139   gdouble v, *value;
140   va_list args;
141   gsize len;
142   GError *error = NULL;
143
144   value = g_key_file_get_double_list (keyfile, group, key, &len, &error);
145   check_no_error (&error);
146   g_assert (value != NULL);
147   
148   va_start (args, key);
149   i = 0;
150   v = va_arg (args, gdouble);
151   while (v != -100)
152     {
153       g_assert_cmpint (i, <, len);
154       g_assert_cmpfloat (value[i], ==, v);
155       i++;
156       v = va_arg (args, gdouble);
157     }
158
159   va_end (args);
160   
161   g_free (value);
162 }
163
164 static void
165 check_boolean_list_value (GKeyFile    *keyfile,
166                           const gchar *group,
167                           const gchar *key,
168                           ...)
169 {
170   gint i;
171   gboolean v, *value;
172   va_list args;
173   gsize len;
174   GError *error = NULL;
175
176   value = g_key_file_get_boolean_list (keyfile, group, key, &len, &error);
177   check_no_error (&error);
178   g_assert (value != NULL);
179   
180   va_start (args, key);
181   i = 0;
182   v = va_arg (args, gboolean);
183   while (v != -100)
184     {
185       g_assert_cmpint (i, <, len);
186       g_assert_cmpint (value[i], ==, v);
187       i++;
188       v = va_arg (args, gboolean);
189     }
190
191   va_end (args);
192   
193   g_free (value);
194 }
195
196 static void
197 check_boolean_value (GKeyFile    *keyfile,
198                      const gchar *group,
199                      const gchar *key,
200                      gboolean     expected) 
201 {
202   GError *error = NULL;
203   gboolean value;
204
205   value = g_key_file_get_boolean (keyfile, group, key, &error);
206   check_no_error (&error);
207   g_assert_cmpint (value, ==, expected);
208 }
209
210 static void
211 check_integer_value (GKeyFile    *keyfile,
212                      const gchar *group,
213                      const gchar *key,
214                      gint         expected) 
215 {
216   GError *error = NULL;
217   gint value;
218
219   value = g_key_file_get_integer (keyfile, group, key, &error);
220   check_no_error (&error);
221   g_assert_cmpint (value, ==, expected);
222 }
223
224 static void
225 check_double_value (GKeyFile    *keyfile,
226                      const gchar *group,
227                      const gchar *key,
228                      gdouble      expected) 
229 {
230   GError *error = NULL;
231   gdouble value;
232
233   value = g_key_file_get_double (keyfile, group, key, &error);
234   check_no_error (&error);
235   g_assert_cmpfloat (value, ==, expected);
236 }
237
238 static void
239 check_name (const gchar *what,
240             const gchar *value,
241             const gchar *expected,
242             gint         position)
243 {
244   g_assert_cmpstr (value, ==, expected);
245 }
246
247 static void
248 check_length (const gchar *what,
249               gint         n_items,
250               gint         length,
251               gint         expected)
252 {
253   g_assert_cmpint (n_items, ==, length);
254   g_assert_cmpint (n_items, ==, expected);
255 }
256
257
258 /* check that both \n and \r\n are accepted as line ends,
259  * and that stray \r are passed through
260  */
261 static void
262 test_line_ends (void)
263 {
264   GKeyFile *keyfile;
265
266   const gchar *data = 
267     "[group1]\n"
268     "key1=value1\n"
269     "key2=value2\r\n"
270     "[group2]\r\n"
271     "key3=value3\r\r\n"
272     "key4=value4\n";
273
274   keyfile = load_data (data, 0);
275
276   check_string_value (keyfile, "group1", "key1", "value1");
277   check_string_value (keyfile, "group1", "key2", "value2");
278   check_string_value (keyfile, "group2", "key3", "value3\r");
279   check_string_value (keyfile, "group2", "key4", "value4");
280
281   g_key_file_free (keyfile);
282 }
283
284 /* check handling of whitespace 
285  */
286 static void
287 test_whitespace (void)
288 {
289   GKeyFile *keyfile;
290
291   const gchar *data = 
292     "[group1]\n"
293     "key1 = value1\n"
294     "key2\t=\tvalue2\n"
295     " [ group2 ] \n"
296     "key3  =  value3  \n"
297     "key4  =  value \t4\n"
298     "  key5  =  value5\n";
299   
300   keyfile = load_data (data, 0);
301
302   check_string_value (keyfile, "group1", "key1", "value1");
303   check_string_value (keyfile, "group1", "key2", "value2");
304   check_string_value (keyfile, " group2 ", "key3", "value3  ");
305   check_string_value (keyfile, " group2 ", "key4", "value \t4");
306   check_string_value (keyfile, " group2 ", "key5", "value5");
307
308   g_key_file_free (keyfile);
309 }
310
311 /* check handling of comments
312  */
313 static void
314 test_comments (void)
315 {
316   GKeyFile *keyfile;
317   gchar **names;
318   gsize len;
319   GError *error = NULL;
320   gchar *comment;
321
322   const gchar *data = 
323     "# top comment\n"
324     "# top comment, continued\n"
325     "[group1]\n"
326     "key1 = value1\n"
327     "# key comment\n"
328     "# key comment, continued\n"
329     "key2 = value2\n"
330     "# line end check\r\n"
331     "key3 = value3\n"
332     "key4 = value4\n"
333     "# group comment\n"
334     "# group comment, continued\n"
335     "[group2]\n";
336
337   const gchar *top_comment= " top comment\n top comment, continued\n";
338   const gchar *group_comment= " group comment\n group comment, continued\n";
339   const gchar *key_comment= " key comment\n key comment, continued\n";
340   
341   keyfile = load_data (data, 0);
342
343   check_string_value (keyfile, "group1", "key1", "value1");
344   check_string_value (keyfile, "group1", "key2", "value2");
345   check_string_value (keyfile, "group1", "key3", "value3");
346   check_string_value (keyfile, "group1", "key4", "value4");
347
348   names = g_key_file_get_keys (keyfile, "group1", &len, &error);
349   check_no_error (&error);
350
351   check_length ("keys", g_strv_length (names), len, 4);
352   check_name ("key", names[0], "key1", 0);
353   check_name ("key", names[1], "key2", 1);
354   check_name ("key", names[2], "key3", 2);
355   check_name ("key", names[3], "key4", 3);
356
357   g_strfreev (names);
358
359   g_key_file_free (keyfile);
360
361   keyfile = load_data (data, G_KEY_FILE_KEEP_COMMENTS);
362
363   names = g_key_file_get_keys (keyfile, "group1", &len, &error);
364   check_no_error (&error);
365
366   check_length ("keys", g_strv_length (names), len, 4);
367   check_name ("key", names[0], "key1", 0);
368   check_name ("key", names[1], "key2", 1);
369   check_name ("key", names[2], "key3", 2);
370   check_name ("key", names[3], "key4", 3);
371
372   g_strfreev (names);
373
374   comment = g_key_file_get_comment (keyfile, NULL, NULL, &error);
375   check_no_error (&error);
376   check_name ("top comment", comment, top_comment, 0);
377   g_free (comment);
378
379   comment = g_key_file_get_comment (keyfile, "group1", "key2", &error);
380   check_no_error (&error);
381   check_name ("key comment", comment, key_comment, 0);
382   g_free (comment);
383
384   comment = g_key_file_get_comment (keyfile, "group2", NULL, &error);
385   check_no_error (&error);
386   check_name ("group comment", comment, group_comment, 0);
387   g_free (comment);
388
389   comment = g_key_file_get_comment (keyfile, "group3", NULL, &error);
390   check_error (&error, 
391                G_KEY_FILE_ERROR,
392                G_KEY_FILE_ERROR_GROUP_NOT_FOUND);
393   g_assert (comment == NULL);
394
395   g_key_file_free (keyfile);
396 }
397
398
399 /* check key and group listing */
400 static void
401 test_listing (void)
402 {
403   GKeyFile *keyfile;
404   gchar **names;
405   gsize len;
406   gchar *start;
407   GError *error = NULL;
408
409   const gchar *data = 
410     "[group1]\n"
411     "key1=value1\n"
412     "key2=value2\n"
413     "[group2]\n"
414     "key3=value3\n"
415     "key4=value4\n";
416   
417   keyfile = load_data (data, 0);
418
419   names = g_key_file_get_groups (keyfile, &len);
420   g_assert (names != NULL);
421
422   check_length ("groups", g_strv_length (names), len, 2);
423   check_name ("group name", names[0], "group1", 0);
424   check_name ("group name", names[1], "group2", 1);
425   
426   g_strfreev (names);
427   
428   names = g_key_file_get_keys (keyfile, "group1", &len, &error);
429   check_no_error (&error);
430
431   check_length ("keys", g_strv_length (names), len, 2);
432   check_name ("key", names[0], "key1", 0);
433   check_name ("key", names[1], "key2", 1);
434
435   g_strfreev (names);
436
437   names = g_key_file_get_keys (keyfile, "no-such-group", &len, &error);
438   check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_GROUP_NOT_FOUND);
439
440   g_strfreev (names);
441
442   g_assert (g_key_file_has_group (keyfile, "group1"));
443   g_assert (g_key_file_has_group (keyfile, "group2"));
444   g_assert (!g_key_file_has_group (keyfile, "group10"));
445   g_assert (!g_key_file_has_group (keyfile, "group20"));
446
447   start = g_key_file_get_start_group (keyfile);
448   g_assert_cmpstr (start, ==, "group1");
449   g_free (start);
450
451   g_assert (g_key_file_has_key (keyfile, "group1", "key1", &error));
452   check_no_error (&error);
453   g_assert (g_key_file_has_key (keyfile, "group2", "key3", &error)); 
454   check_no_error (&error);
455   g_assert (!g_key_file_has_key (keyfile, "group2", "no-such-key", NULL)); 
456   
457   g_key_file_has_key (keyfile, "no-such-group", "key", &error);
458   check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_GROUP_NOT_FOUND);
459
460   g_key_file_free (keyfile);
461 }
462
463 /* check parsing of string values */
464 static void
465 test_string (void)
466 {
467   GKeyFile *keyfile;
468   GError *error = NULL;
469   gchar *value;
470
471   const gchar *data = 
472     "[valid]\n"
473     "key1=\\s\\n\\t\\r\\\\\n"
474     "key2=\"quoted\"\n"
475     "key3='quoted'\n"
476     "key4=\xe2\x89\xa0\xe2\x89\xa0\n"
477     "[invalid]\n"
478     "key1=\\a\\b\\0800xff\n"
479     "key2=blabla\\\n";
480   
481   keyfile = load_data (data, 0);
482
483   check_string_value (keyfile, "valid", "key1", " \n\t\r\\");
484   check_string_value (keyfile, "valid", "key2", "\"quoted\"");
485   check_string_value (keyfile, "valid", "key3", "'quoted'");  
486   check_string_value (keyfile, "valid", "key4", "\xe2\x89\xa0\xe2\x89\xa0");  
487   
488   value = g_key_file_get_string (keyfile, "invalid", "key1", &error);
489   check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE);
490   g_free (value);
491
492   value = g_key_file_get_string (keyfile, "invalid", "key2", &error);
493   check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE);
494   g_free (value);
495   
496   g_key_file_free (keyfile);
497 }
498
499 /* check parsing of boolean values */
500 static void
501 test_boolean (void)
502 {
503   GKeyFile *keyfile;
504   GError *error = NULL;
505
506   const gchar *data = 
507     "[valid]\n"
508     "key1=true\n"
509     "key2=false\n"
510     "key3=1\n"
511     "key4=0\n"
512     "[invalid]\n"
513     "key1=t\n"
514     "key2=f\n"
515     "key3=yes\n"
516     "key4=no\n";
517   
518   keyfile = load_data (data, 0);
519
520   check_boolean_value (keyfile, "valid", "key1", TRUE);
521   check_boolean_value (keyfile, "valid", "key2", FALSE);
522   check_boolean_value (keyfile, "valid", "key3", TRUE);
523   check_boolean_value (keyfile, "valid", "key4", FALSE);
524
525   g_key_file_get_boolean (keyfile, "invalid", "key1", &error);
526   check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE);
527
528   g_key_file_get_boolean (keyfile, "invalid", "key2", &error);
529   check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE);
530
531   g_key_file_get_boolean (keyfile, "invalid", "key3", &error);
532   check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE);
533
534   g_key_file_get_boolean (keyfile, "invalid", "key4", &error);
535   check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE);
536
537   g_key_file_free (keyfile);
538 }
539
540 /* check parsing of integer and double values */
541 static void
542 test_number (void)
543 {
544   GKeyFile *keyfile;
545   GError *error = NULL;
546
547   const gchar *data = 
548     "[valid]\n"
549     "key1=0\n"
550     "key2=1\n"
551     "key3=-1\n"
552     "key4=2324431\n"
553     "key5=-2324431\n"
554     "key6=000111\n"
555     "dkey1=000111\n"
556     "dkey2=145.45\n"
557     "dkey3=-3453.7\n"
558     "[invalid]\n"
559     "key1=0xffff\n"
560     "key2=0.5\n"
561     "key3=1e37\n"
562     "key4=ten\n"
563     "key5=\n"
564     "key6=1.0.0\n"
565     "key7=2x2\n"
566     "key8=abc\n";
567   
568   keyfile = load_data (data, 0);
569
570   check_integer_value (keyfile, "valid", "key1", 0);
571   check_integer_value (keyfile, "valid", "key2", 1);
572   check_integer_value (keyfile, "valid", "key3", -1);
573   check_integer_value (keyfile, "valid", "key4", 2324431);
574   check_integer_value (keyfile, "valid", "key5", -2324431);
575   check_integer_value (keyfile, "valid", "key6", 111);
576   check_double_value (keyfile, "valid", "dkey1", 111.0);
577   check_double_value (keyfile, "valid", "dkey2", 145.45);
578   check_double_value (keyfile, "valid", "dkey3", -3453.7);
579
580   g_key_file_get_integer (keyfile, "invalid", "key1", &error);
581   check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE);
582
583   g_key_file_get_integer (keyfile, "invalid", "key2", &error);
584   check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE);
585
586   g_key_file_get_integer (keyfile, "invalid", "key3", &error);
587   check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE);
588
589   g_key_file_get_integer (keyfile, "invalid", "key4", &error);
590   check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE);
591
592   g_key_file_get_double (keyfile, "invalid", "key5", &error);
593   check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE);
594
595   g_key_file_get_double (keyfile, "invalid", "key6", &error);
596   check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE);
597
598   g_key_file_get_double (keyfile, "invalid", "key7", &error);
599   check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE);
600
601   g_key_file_get_double (keyfile, "invalid", "key8", &error);
602   check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE);
603
604   g_key_file_free (keyfile);
605 }
606
607 /* check handling of translated strings */
608 static void
609 test_locale_string (void)
610 {
611   GKeyFile *keyfile;
612
613   const gchar *data = 
614     "[valid]\n"
615     "key1=v1\n"
616     "key1[de]=v1-de\n"
617     "key1[de_DE]=v1-de_DE\n"
618     "key1[de_DE.UTF8]=v1-de_DE.UTF8\n"
619     "key1[fr]=v1-fr\n"
620     "key1[en] =v1-en\n"
621     "key1[sr@Latn]=v1-sr\n";
622   
623   keyfile = load_data (data, G_KEY_FILE_KEEP_TRANSLATIONS);
624
625   check_locale_string_value (keyfile, "valid", "key1", "it", "v1");
626   check_locale_string_value (keyfile, "valid", "key1", "de", "v1-de");
627   check_locale_string_value (keyfile, "valid", "key1", "de_DE", "v1-de_DE");
628   check_locale_string_value (keyfile, "valid", "key1", "de_DE.UTF8", "v1-de_DE.UTF8");
629   check_locale_string_value (keyfile, "valid", "key1", "fr", "v1-fr");
630   check_locale_string_value (keyfile, "valid", "key1", "fr_FR", "v1-fr");
631   check_locale_string_value (keyfile, "valid", "key1", "en", "v1-en");
632   check_locale_string_value (keyfile, "valid", "key1", "sr@Latn", "v1-sr");
633   
634   g_key_file_free (keyfile);
635
636   /* now test that translations are thrown away */
637
638   g_setenv ("LANGUAGE", "de", TRUE);
639   setlocale (LC_ALL, "");
640
641   keyfile = load_data (data, 0);
642
643   check_locale_string_value (keyfile, "valid", "key1", "it", "v1");
644   check_locale_string_value (keyfile, "valid", "key1", "de", "v1-de");
645   check_locale_string_value (keyfile, "valid", "key1", "de_DE", "v1-de");
646   check_locale_string_value (keyfile, "valid", "key1", "de_DE.UTF8", "v1-de");
647   check_locale_string_value (keyfile, "valid", "key1", "fr", "v1");
648   check_locale_string_value (keyfile, "valid", "key1", "fr_FR", "v1");
649   check_locale_string_value (keyfile, "valid", "key1", "en", "v1");
650
651   g_key_file_free (keyfile);  
652 }
653
654 static void
655 test_lists (void)
656 {
657   GKeyFile *keyfile;
658
659   const gchar *data = 
660     "[valid]\n"
661     "key1=v1;v2\n"
662     "key2=v1;v2;\n"
663     "key3=v1,v2\n"
664     "key4=v1\\;v2\n"
665     "key5=true;false\n"
666     "key6=1;0;-1\n"
667     "key7= 1 ; 0 ; -1 \n"
668     "key8=v1\\,v2\n"
669     "key9=0;1.3456;-76532.456\n";
670   
671   keyfile = load_data (data, 0);
672
673   check_string_list_value (keyfile, "valid", "key1", "v1", "v2", NULL);
674   check_string_list_value (keyfile, "valid", "key2", "v1", "v2", NULL);
675   check_string_list_value (keyfile, "valid", "key3", "v1,v2", NULL);
676   check_string_list_value (keyfile, "valid", "key4", "v1;v2", NULL);
677   check_boolean_list_value (keyfile, "valid", "key5", TRUE, FALSE, -100);
678   check_integer_list_value (keyfile, "valid", "key6", 1, 0, -1, -100);
679   check_double_list_value (keyfile, "valid", "key9", 0.0, 1.3456, -76532.456, -100.0);
680   /* maybe these should be valid */
681   /* check_integer_list_value (keyfile, "valid", "key7", 1, 0, -1, -100);*/
682   /* check_string_list_value (keyfile, "valid", "key8", "v1\\,v2", NULL);*/
683
684   g_key_file_free (keyfile);  
685
686   /* Now check an alternate separator */
687
688   keyfile = load_data (data, 0);
689   g_key_file_set_list_separator (keyfile, ',');
690
691   check_string_list_value (keyfile, "valid", "key1", "v1;v2", NULL);
692   check_string_list_value (keyfile, "valid", "key2", "v1;v2;", NULL);
693   check_string_list_value (keyfile, "valid", "key3", "v1", "v2", NULL);
694
695   g_key_file_free (keyfile);  
696 }
697
698 static void 
699 test_group_remove (void)
700 {
701   GKeyFile *keyfile;
702   gchar **names;
703   gsize len;
704   GError *error = NULL;
705
706   const gchar *data = 
707     "[group1]\n"
708     "[group2]\n"
709     "key1=bla\n"
710     "key2=bla\n"
711     "[group3]\n"
712     "key1=bla\n"
713     "key2=bla\n";
714   
715   g_test_bug ("165887");
716
717   keyfile = load_data (data, 0);
718   
719   names = g_key_file_get_groups (keyfile, &len);
720   g_assert (names != NULL);
721
722   check_length ("groups", g_strv_length (names), len, 3);
723   check_name ("group name", names[0], "group1", 0);
724   check_name ("group name", names[1], "group2", 1);
725   check_name ("group name", names[2], "group3", 2);
726
727   g_key_file_remove_group (keyfile, "group1", &error);
728   check_no_error (&error);
729   
730   g_strfreev (names);
731
732   names = g_key_file_get_groups (keyfile, &len);
733   g_assert (names != NULL);
734
735   check_length ("groups", g_strv_length (names), len, 2);
736   check_name ("group name", names[0], "group2", 0);
737   check_name ("group name", names[1], "group3", 1);
738
739   g_key_file_remove_group (keyfile, "group2", &error);
740   check_no_error (&error);
741   
742   g_strfreev (names);
743
744   names = g_key_file_get_groups (keyfile, &len);
745   g_assert (names != NULL);
746
747   check_length ("groups", g_strv_length (names), len, 1);
748   check_name ("group name", names[0], "group3", 0);
749
750   g_key_file_remove_group (keyfile, "no such group", &error);
751   check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_GROUP_NOT_FOUND);
752
753   g_strfreev (names);
754
755   g_key_file_free (keyfile);
756 }
757
758 static void 
759 test_key_remove (void)
760 {
761   GKeyFile *keyfile;
762   gchar *value;
763   GError *error = NULL;
764
765   const gchar *data = 
766     "[group1]\n"
767     "key1=bla\n"
768     "key2=bla\n";
769   
770   g_test_bug ("165980");
771   
772   keyfile = load_data (data, 0);
773   
774   check_string_value (keyfile, "group1", "key1", "bla");
775
776   g_key_file_remove_key (keyfile, "group1", "key1", &error);
777   check_no_error (&error);
778
779   value = g_key_file_get_string (keyfile, "group1", "key1", &error);
780   check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_KEY_NOT_FOUND);
781   g_free (value);
782   
783   g_key_file_remove_key (keyfile, "group1", "key1", &error);
784   check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_KEY_NOT_FOUND);
785
786   g_key_file_remove_key (keyfile, "no such group", "key1", &error);
787   check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_GROUP_NOT_FOUND);
788
789   g_key_file_free (keyfile);
790 }
791
792
793 static void
794 test_groups (void)
795 {
796   GKeyFile *keyfile;
797
798   const gchar *data = 
799     "[1]\n"
800     "key1=123\n"
801     "[2]\n"
802     "key2=123\n";
803   
804   g_test_bug ("316309");
805
806   keyfile = load_data (data, 0);
807
808   check_string_value (keyfile, "1", "key1", "123");
809   check_string_value (keyfile, "2", "key2", "123");
810
811   g_key_file_free (keyfile);  
812 }
813
814 static void
815 test_group_names (void)
816 {
817   GKeyFile *keyfile;
818   GError *error = NULL;
819   const gchar *data;
820   gchar *value;
821
822   /* [ in group name */
823   data = "[a[b]\n"
824          "key1=123\n";
825   keyfile = g_key_file_new ();
826   g_key_file_load_from_data (keyfile, data, -1, 0, &error);
827   g_key_file_free (keyfile);  
828   check_error (&error, 
829                G_KEY_FILE_ERROR,
830                G_KEY_FILE_ERROR_PARSE);
831
832   /* ] in group name */
833   data = "[a]b]\n"
834          "key1=123\n";
835   keyfile = g_key_file_new ();
836   g_key_file_load_from_data (keyfile, data, -1, 0, &error);
837   g_key_file_free (keyfile);  
838   check_error (&error, 
839                G_KEY_FILE_ERROR,
840                G_KEY_FILE_ERROR_PARSE);
841
842   /* control char in group name */
843   data = "[a\tb]\n"
844          "key1=123\n";
845   keyfile = g_key_file_new ();
846   g_key_file_load_from_data (keyfile, data, -1, 0, &error);
847   g_key_file_free (keyfile);  
848   check_error (&error, 
849                G_KEY_FILE_ERROR,
850                G_KEY_FILE_ERROR_PARSE);
851
852   /* empty group name */
853   data = "[]\n"
854          "key1=123\n";
855   keyfile = g_key_file_new ();
856   g_key_file_load_from_data (keyfile, data, -1, 0, &error);
857   g_key_file_free (keyfile);  
858   check_error (&error, 
859                G_KEY_FILE_ERROR,
860                G_KEY_FILE_ERROR_PARSE);
861
862   /* Unicode in group name */
863   data = "[\xc2\xbd]\n"
864          "key1=123\n";
865   keyfile = g_key_file_new ();
866   g_key_file_load_from_data (keyfile, data, -1, 0, &error);
867   g_key_file_free (keyfile);  
868   check_no_error (&error);
869
870   keyfile = g_key_file_new ();
871   /*g_key_file_set_string (keyfile, "a[b", "key1", "123");*/
872   value = g_key_file_get_string (keyfile, "a[b", "key1", &error);
873   check_error (&error, 
874                G_KEY_FILE_ERROR,
875                G_KEY_FILE_ERROR_GROUP_NOT_FOUND);  
876   g_key_file_free (keyfile);  
877
878   keyfile = g_key_file_new ();
879   /*g_key_file_set_string (keyfile, "a]b", "key1", "123");*/
880   value = g_key_file_get_string (keyfile, "a]b", "key1", &error);
881   check_error (&error, 
882                G_KEY_FILE_ERROR,
883                G_KEY_FILE_ERROR_GROUP_NOT_FOUND);  
884   g_key_file_free (keyfile);  
885
886   keyfile = g_key_file_new ();
887   /*g_key_file_set_string (keyfile, "a\tb", "key1", "123");*/
888   value = g_key_file_get_string (keyfile, "a\tb", "key1", &error);
889   check_error (&error, 
890                G_KEY_FILE_ERROR,
891                G_KEY_FILE_ERROR_GROUP_NOT_FOUND);  
892   g_key_file_free (keyfile);  
893
894   keyfile = g_key_file_new ();
895   g_key_file_set_string (keyfile, "\xc2\xbd", "key1", "123");
896   check_string_value (keyfile, "\xc2\xbd", "key1", "123");
897   g_key_file_free (keyfile);  
898 }
899
900 static void
901 test_key_names (void)
902 {
903   GKeyFile *keyfile;
904   GError *error = NULL;
905   const gchar *data;
906   gchar *value;
907
908   /* [ in key name */
909   data = "[a]\n"
910          "key[=123\n";
911   keyfile = g_key_file_new ();
912   g_key_file_load_from_data (keyfile, data, -1, 0, &error);
913   g_key_file_free (keyfile);  
914   check_error (&error, 
915                G_KEY_FILE_ERROR,
916                G_KEY_FILE_ERROR_PARSE);
917
918   /* empty key name */
919   data = "[a]\n"
920          " =123\n";
921   keyfile = g_key_file_new ();
922   g_key_file_load_from_data (keyfile, data, -1, 0, &error);
923   g_key_file_free (keyfile);  
924   check_error (&error, 
925                G_KEY_FILE_ERROR,
926                G_KEY_FILE_ERROR_PARSE);
927
928   /* empty key name */
929   data = "[a]\n"
930          " [de] =123\n";
931   keyfile = g_key_file_new ();
932   g_key_file_load_from_data (keyfile, data, -1, 0, &error);
933   g_key_file_free (keyfile);  
934   check_error (&error, 
935                G_KEY_FILE_ERROR,
936                G_KEY_FILE_ERROR_PARSE);
937
938   /* bad locale suffix */
939   data = "[a]\n"
940          "foo[@#!&%]=123\n";
941   keyfile = g_key_file_new ();
942   g_key_file_load_from_data (keyfile, data, -1, 0, &error);
943   g_key_file_free (keyfile);  
944   check_error (&error, 
945                G_KEY_FILE_ERROR,
946                G_KEY_FILE_ERROR_PARSE);
947
948   /* initial space */
949   data = "[a]\n"
950          " foo=123\n";
951   keyfile = g_key_file_new ();
952   g_key_file_load_from_data (keyfile, data, -1, 0, &error);
953   check_no_error (&error);
954   check_string_value (keyfile, "a", "foo", "123");
955   g_key_file_free (keyfile);  
956
957   /* final space */
958   data = "[a]\n"
959          "foo =123\n";
960   keyfile = g_key_file_new ();
961   g_key_file_load_from_data (keyfile, data, -1, 0, &error);
962   check_no_error (&error);
963   check_string_value (keyfile, "a", "foo", "123");
964   g_key_file_free (keyfile);  
965
966   /* inner space */
967   data = "[a]\n"
968          "foo bar=123\n";
969   keyfile = g_key_file_new ();
970   g_key_file_load_from_data (keyfile, data, -1, 0, &error);
971   check_no_error (&error);
972   check_string_value (keyfile, "a", "foo bar", "123");
973   g_key_file_free (keyfile);  
974
975   /* inner space */
976   data = "[a]\n"
977          "foo [de] =123\n";
978   keyfile = g_key_file_new ();
979   g_key_file_load_from_data (keyfile, data, -1, 0, &error);
980   check_error (&error, 
981                G_KEY_FILE_ERROR,
982                G_KEY_FILE_ERROR_PARSE);
983   g_key_file_free (keyfile);  
984
985   /* control char in key name */
986   data = "[a]\n"
987          "key\tfoo=123\n";
988   keyfile = g_key_file_new ();
989   g_key_file_load_from_data (keyfile, data, -1, 0, &error);
990   g_key_file_free (keyfile);  
991   check_no_error (&error);
992
993   /* Unicode in key name */
994   data = "[a]\n"
995          "\xc2\xbd=123\n";
996   keyfile = g_key_file_new ();
997   g_key_file_load_from_data (keyfile, data, -1, 0, &error);
998   g_key_file_free (keyfile);  
999   check_no_error (&error); 
1000
1001   keyfile = g_key_file_new ();
1002   g_key_file_set_string (keyfile, "a", "x", "123");
1003   /*g_key_file_set_string (keyfile, "a", "key=", "123");*/
1004   value = g_key_file_get_string (keyfile, "a", "key=", &error);
1005   check_error (&error, 
1006                G_KEY_FILE_ERROR,
1007                G_KEY_FILE_ERROR_KEY_NOT_FOUND);  
1008   g_key_file_free (keyfile);  
1009
1010   keyfile = g_key_file_new ();
1011   g_key_file_set_string (keyfile, "a", "x", "123");
1012   /*g_key_file_set_string (keyfile, "a", "key[", "123");*/
1013   value = g_key_file_get_string (keyfile, "a", "key[", &error);
1014   check_error (&error, 
1015                G_KEY_FILE_ERROR,
1016                G_KEY_FILE_ERROR_KEY_NOT_FOUND);  
1017   g_key_file_free (keyfile);  
1018
1019   keyfile = g_key_file_new ();
1020   g_key_file_set_string (keyfile, "a", "x", "123");
1021   g_key_file_set_string (keyfile, "a", "key\tfoo", "123");
1022   value = g_key_file_get_string (keyfile, "a", "key\tfoo", &error);
1023   check_no_error (&error);
1024   g_key_file_free (keyfile);  
1025
1026   keyfile = g_key_file_new ();
1027   g_key_file_set_string (keyfile, "a", "x", "123");
1028   /*g_key_file_set_string (keyfile, "a", " key", "123");*/
1029   value = g_key_file_get_string (keyfile, "a", " key", &error);
1030   check_error (&error, 
1031                G_KEY_FILE_ERROR,
1032                G_KEY_FILE_ERROR_KEY_NOT_FOUND);  
1033   g_key_file_free (keyfile);  
1034
1035   keyfile = g_key_file_new ();
1036   g_key_file_set_string (keyfile, "a", "x", "123");
1037
1038   /* Unicode key */
1039   g_key_file_set_string (keyfile, "a", "\xc2\xbd", "123");
1040   check_string_value (keyfile, "a", "\xc2\xbd", "123");
1041
1042   /* Keys with / + . (as used by the gnome-vfs mime cache) */
1043   g_key_file_set_string (keyfile, "a", "foo/bar", "/");
1044   check_string_value (keyfile, "a", "foo/bar", "/");
1045   g_key_file_set_string (keyfile, "a", "foo+bar", "+");
1046   check_string_value (keyfile, "a", "foo+bar", "+");
1047   g_key_file_set_string (keyfile, "a", "foo.bar", ".");
1048   check_string_value (keyfile, "a", "foo.bar", ".");
1049
1050   g_key_file_free (keyfile);  
1051 }
1052
1053 static void
1054 test_duplicate_keys (void)
1055 {
1056   GKeyFile *keyfile;
1057   const gchar *data = 
1058     "[1]\n"
1059     "key1=123\n"
1060     "key1=345\n";
1061
1062   keyfile = load_data (data, 0);
1063   check_string_value (keyfile, "1", "key1", "345");
1064
1065   g_key_file_free (keyfile);  
1066 }
1067
1068 static void
1069 test_duplicate_groups (void)
1070 {
1071   GKeyFile *keyfile;
1072   const gchar *data = 
1073     "[Desktop Entry]\n"
1074     "key1=123\n"
1075     "[Desktop Entry]\n"
1076     "key2=123\n";
1077   
1078   g_test_bug ("157877");
1079
1080   keyfile = load_data (data, 0);
1081   check_string_value (keyfile, "Desktop Entry", "key1", "123");
1082   check_string_value (keyfile, "Desktop Entry", "key2", "123");
1083
1084   g_key_file_free (keyfile);  
1085 }
1086
1087 static void
1088 test_duplicate_groups2 (void)
1089 {
1090   GKeyFile *keyfile;
1091   const gchar *data = 
1092     "[A]\n"
1093     "foo=bar\n"
1094     "[B]\n"
1095     "foo=baz\n"
1096     "[A]\n"
1097     "foo=bang\n";
1098   
1099   g_test_bug ("385910");
1100
1101   keyfile = load_data (data, 0);
1102   check_string_value (keyfile, "A", "foo", "bang");
1103   check_string_value (keyfile, "B", "foo", "baz");
1104
1105   g_key_file_free (keyfile);  
1106 }
1107
1108 static void
1109 test_reload_idempotency (void)
1110 {
1111   static const gchar *original_data=""
1112     "# Top comment\n"
1113     "\n"
1114     "# First comment\n"
1115     "[first]\n"
1116     "key=value\n"
1117     "# A random comment in the first group\n"
1118     "anotherkey=anothervalue\n"
1119     "# Second comment - one line\n"
1120     "[second]\n"
1121     "# Third comment - two lines\n"
1122     "# Third comment - two lines\n"
1123     "[third]\n"
1124     "blank_line=1\n"
1125     "\n"
1126     "blank_lines=2\n"
1127     "\n\n"
1128     "[fourth]\n"
1129     "[fifth]\n";
1130   GKeyFile *keyfile;
1131   GError *error = NULL;
1132   gchar *data1, *data2;
1133   gsize len1, len2;
1134
1135   g_test_bug ("420686");
1136
1137   /* check that we only insert a single new line between groups */
1138   keyfile = g_key_file_new ();
1139   g_key_file_load_from_data (keyfile,
1140                              original_data, strlen(original_data),
1141                              G_KEY_FILE_KEEP_COMMENTS,
1142                              &error);
1143   check_no_error (&error);
1144
1145   data1 = g_key_file_to_data (keyfile, &len1, &error);
1146   g_assert (data1 != NULL);
1147   g_key_file_free (keyfile);
1148
1149   keyfile = g_key_file_new ();
1150   g_key_file_load_from_data (keyfile,
1151                              data1, len1,
1152                              G_KEY_FILE_KEEP_COMMENTS,
1153                              &error);
1154   check_no_error (&error);
1155
1156   data2 = g_key_file_to_data (keyfile, &len2, &error);
1157   g_assert (data2 != NULL);
1158   g_key_file_free (keyfile);
1159
1160   g_assert_cmpstr (data1, ==, data2);
1161
1162   g_free (data2);
1163   g_free (data1);
1164 }
1165
1166 int
1167 main (int argc, char *argv[])
1168 {
1169   g_test_init (&argc, &argv, NULL);
1170   g_test_bug_base ("http://bugzilla.gnome.org/");
1171
1172   g_test_add_func ("/keyfile/line-ends", test_line_ends);
1173   g_test_add_func ("/keyfile/whitespace", test_whitespace);
1174   g_test_add_func ("/keyfile/comments", test_comments);
1175   g_test_add_func ("/keyfile/listing", test_listing);
1176   g_test_add_func ("/keyfile/string", test_string);
1177   g_test_add_func ("/keyfile/boolean", test_boolean);
1178   g_test_add_func ("/keyfile/number", test_number);
1179   g_test_add_func ("/keyfile/locale-string", test_locale_string);
1180   g_test_add_func ("/keyfile/lists", test_lists);
1181   g_test_add_func ("/keyfile/group-remove", test_group_remove);
1182   g_test_add_func ("/keyfile/key-remove", test_key_remove);
1183   g_test_add_func ("/keyfile/groups", test_groups);
1184   g_test_add_func ("/keyfile/duplicate-keys", test_duplicate_keys);
1185   g_test_add_func ("/keyfile/duplicate-groups", test_duplicate_groups);
1186   g_test_add_func ("/keyfile/duplicate-groups2", test_duplicate_groups2);
1187   g_test_add_func ("/keyfile/group-names", test_group_names);
1188   g_test_add_func ("/keyfile/key-names", test_key_names);
1189   g_test_add_func ("/keyfile/reload", test_reload_idempotency);
1190   
1191   return g_test_run ();
1192 }