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