Simplify subprocesses in tests
[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_locale_string_list_value (GKeyFile    *keyfile,
102                                 const gchar *group,
103                                 const gchar *key,
104                                 const gchar *locale,
105                                 ...)
106 {
107   gint i;
108   gchar *v, **value;
109   va_list args;
110   gsize len;
111   GError *error = NULL;
112
113   value = g_key_file_get_locale_string_list (keyfile, group, key, locale, &len, &error);
114   check_no_error (&error);
115   g_assert (value != NULL);
116
117   va_start (args, locale);
118   i = 0;
119   v = va_arg (args, gchar*);
120   while (v)
121     {
122       g_assert (value[i] != NULL);
123       g_assert_cmpstr (v, ==, value[i]);
124       i++;
125       v = va_arg (args, gchar*);
126     }
127
128   va_end (args);
129
130   g_strfreev (value);
131 }
132
133 static void
134 check_integer_list_value (GKeyFile    *keyfile,
135                           const gchar *group,
136                           const gchar *key,
137                           ...)
138 {
139   gint i;
140   gint v, *value;
141   va_list args;
142   gsize len;
143   GError *error = NULL;
144
145   value = g_key_file_get_integer_list (keyfile, group, key, &len, &error);
146   check_no_error (&error);
147   g_assert (value != NULL);
148
149   va_start (args, key);
150   i = 0;
151   v = va_arg (args, gint);
152   while (v != -100)
153     {
154       g_assert_cmpint (i, <, len);
155       g_assert_cmpint (value[i], ==, v);
156       i++;
157       v = va_arg (args, gint);
158     }
159
160   va_end (args);
161
162   g_free (value);
163 }
164
165 static void
166 check_double_list_value (GKeyFile    *keyfile,
167                           const gchar *group,
168                           const gchar *key,
169                           ...)
170 {
171   gint i;
172   gdouble v, *value;
173   va_list args;
174   gsize len;
175   GError *error = NULL;
176
177   value = g_key_file_get_double_list (keyfile, group, key, &len, &error);
178   check_no_error (&error);
179   g_assert (value != NULL);
180
181   va_start (args, key);
182   i = 0;
183   v = va_arg (args, gdouble);
184   while (v != -100)
185     {
186       g_assert_cmpint (i, <, len);
187       g_assert_cmpfloat (value[i], ==, v);
188       i++;
189       v = va_arg (args, gdouble);
190     }
191
192   va_end (args);
193
194   g_free (value);
195 }
196
197 static void
198 check_boolean_list_value (GKeyFile    *keyfile,
199                           const gchar *group,
200                           const gchar *key,
201                           ...)
202 {
203   gint i;
204   gboolean v, *value;
205   va_list args;
206   gsize len;
207   GError *error = NULL;
208
209   value = g_key_file_get_boolean_list (keyfile, group, key, &len, &error);
210   check_no_error (&error);
211   g_assert (value != NULL);
212
213   va_start (args, key);
214   i = 0;
215   v = va_arg (args, gboolean);
216   while (v != -100)
217     {
218       g_assert_cmpint (i, <, len);
219       g_assert_cmpint (value[i], ==, v);
220       i++;
221       v = va_arg (args, gboolean);
222     }
223
224   va_end (args);
225
226   g_free (value);
227 }
228
229 static void
230 check_boolean_value (GKeyFile    *keyfile,
231                      const gchar *group,
232                      const gchar *key,
233                      gboolean     expected)
234 {
235   GError *error = NULL;
236   gboolean value;
237
238   value = g_key_file_get_boolean (keyfile, group, key, &error);
239   check_no_error (&error);
240   g_assert_cmpint (value, ==, expected);
241 }
242
243 static void
244 check_integer_value (GKeyFile    *keyfile,
245                      const gchar *group,
246                      const gchar *key,
247                      gint         expected)
248 {
249   GError *error = NULL;
250   gint value;
251
252   value = g_key_file_get_integer (keyfile, group, key, &error);
253   check_no_error (&error);
254   g_assert_cmpint (value, ==, expected);
255 }
256
257 static void
258 check_double_value (GKeyFile    *keyfile,
259                      const gchar *group,
260                      const gchar *key,
261                      gdouble      expected)
262 {
263   GError *error = NULL;
264   gdouble value;
265
266   value = g_key_file_get_double (keyfile, group, key, &error);
267   check_no_error (&error);
268   g_assert_cmpfloat (value, ==, expected);
269 }
270
271 static void
272 check_name (const gchar *what,
273             const gchar *value,
274             const gchar *expected,
275             gint         position)
276 {
277   g_assert_cmpstr (value, ==, expected);
278 }
279
280 static void
281 check_length (const gchar *what,
282               gint         n_items,
283               gint         length,
284               gint         expected)
285 {
286   g_assert_cmpint (n_items, ==, length);
287   g_assert_cmpint (n_items, ==, expected);
288 }
289
290
291 /* check that both \n and \r\n are accepted as line ends,
292  * and that stray \r are passed through
293  */
294 static void
295 test_line_ends (void)
296 {
297   GKeyFile *keyfile;
298
299   const gchar *data =
300     "[group1]\n"
301     "key1=value1\n"
302     "key2=value2\r\n"
303     "[group2]\r\n"
304     "key3=value3\r\r\n"
305     "key4=value4\n";
306
307   keyfile = load_data (data, 0);
308
309   check_string_value (keyfile, "group1", "key1", "value1");
310   check_string_value (keyfile, "group1", "key2", "value2");
311   check_string_value (keyfile, "group2", "key3", "value3\r");
312   check_string_value (keyfile, "group2", "key4", "value4");
313
314   g_key_file_free (keyfile);
315 }
316
317 /* check handling of whitespace
318  */
319 static void
320 test_whitespace (void)
321 {
322   GKeyFile *keyfile;
323
324   const gchar *data =
325     "[group1]\n"
326     "key1 = value1\n"
327     "key2\t=\tvalue2\n"
328     " [ group2 ] \n"
329     "key3  =  value3  \n"
330     "key4  =  value \t4\n"
331     "  key5  =  value5\n";
332
333   keyfile = load_data (data, 0);
334
335   check_string_value (keyfile, "group1", "key1", "value1");
336   check_string_value (keyfile, "group1", "key2", "value2");
337   check_string_value (keyfile, " group2 ", "key3", "value3  ");
338   check_string_value (keyfile, " group2 ", "key4", "value \t4");
339   check_string_value (keyfile, " group2 ", "key5", "value5");
340
341   g_key_file_free (keyfile);
342 }
343
344 /* check handling of comments
345  */
346 static void
347 test_comments (void)
348 {
349   GKeyFile *keyfile;
350   gchar **names;
351   gsize len;
352   GError *error = NULL;
353   gchar *comment;
354
355   const gchar *data =
356     "# top comment\n"
357     "# top comment, continued\n"
358     "[group1]\n"
359     "key1 = value1\n"
360     "# key comment\n"
361     "# key comment, continued\n"
362     "key2 = value2\n"
363     "# line end check\r\n"
364     "key3 = value3\n"
365     "key4 = value4\n"
366     "# group comment\n"
367     "# group comment, continued\n"
368     "[group2]\n";
369
370   const gchar *top_comment= " top comment\n top comment, continued\n";
371   const gchar *group_comment= " group comment\n group comment, continued\n";
372   const gchar *key_comment= " key comment\n key comment, continued\n";
373
374   keyfile = load_data (data, 0);
375
376   check_string_value (keyfile, "group1", "key1", "value1");
377   check_string_value (keyfile, "group1", "key2", "value2");
378   check_string_value (keyfile, "group1", "key3", "value3");
379   check_string_value (keyfile, "group1", "key4", "value4");
380
381   names = g_key_file_get_keys (keyfile, "group1", &len, &error);
382   check_no_error (&error);
383
384   check_length ("keys", g_strv_length (names), len, 4);
385   check_name ("key", names[0], "key1", 0);
386   check_name ("key", names[1], "key2", 1);
387   check_name ("key", names[2], "key3", 2);
388   check_name ("key", names[3], "key4", 3);
389
390   g_strfreev (names);
391
392   g_key_file_free (keyfile);
393
394   keyfile = load_data (data, G_KEY_FILE_KEEP_COMMENTS);
395
396   names = g_key_file_get_keys (keyfile, "group1", &len, &error);
397   check_no_error (&error);
398
399   check_length ("keys", g_strv_length (names), len, 4);
400   check_name ("key", names[0], "key1", 0);
401   check_name ("key", names[1], "key2", 1);
402   check_name ("key", names[2], "key3", 2);
403   check_name ("key", names[3], "key4", 3);
404
405   g_strfreev (names);
406
407   comment = g_key_file_get_comment (keyfile, NULL, NULL, &error);
408   check_no_error (&error);
409   check_name ("top comment", comment, top_comment, 0);
410   g_free (comment);
411
412   comment = g_key_file_get_comment (keyfile, "group1", "key2", &error);
413   check_no_error (&error);
414   check_name ("key comment", comment, key_comment, 0);
415   g_free (comment);
416
417   g_key_file_remove_comment (keyfile, "group1", "key2", &error);
418   check_no_error (&error);
419   comment = g_key_file_get_comment (keyfile, "group1", "key2", &error);
420   check_no_error (&error);
421   g_assert (comment == NULL);
422
423   comment = g_key_file_get_comment (keyfile, "group2", NULL, &error);
424   check_no_error (&error);
425   check_name ("group comment", comment, group_comment, 0);
426   g_free (comment);
427
428   comment = g_key_file_get_comment (keyfile, "group3", NULL, &error);
429   check_error (&error,
430                G_KEY_FILE_ERROR,
431                G_KEY_FILE_ERROR_GROUP_NOT_FOUND);
432   g_assert (comment == NULL);
433
434   g_key_file_free (keyfile);
435 }
436
437
438 /* check key and group listing */
439 static void
440 test_listing (void)
441 {
442   GKeyFile *keyfile;
443   gchar **names;
444   gsize len;
445   gchar *start;
446   GError *error = NULL;
447
448   const gchar *data =
449     "[group1]\n"
450     "key1=value1\n"
451     "key2=value2\n"
452     "[group2]\n"
453     "key3=value3\n"
454     "key4=value4\n";
455
456   keyfile = load_data (data, 0);
457
458   names = g_key_file_get_groups (keyfile, &len);
459   g_assert (names != NULL);
460
461   check_length ("groups", g_strv_length (names), len, 2);
462   check_name ("group name", names[0], "group1", 0);
463   check_name ("group name", names[1], "group2", 1);
464
465   g_strfreev (names);
466
467   names = g_key_file_get_keys (keyfile, "group1", &len, &error);
468   check_no_error (&error);
469
470   check_length ("keys", g_strv_length (names), len, 2);
471   check_name ("key", names[0], "key1", 0);
472   check_name ("key", names[1], "key2", 1);
473
474   g_strfreev (names);
475
476   names = g_key_file_get_keys (keyfile, "no-such-group", &len, &error);
477   check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_GROUP_NOT_FOUND);
478
479   g_strfreev (names);
480
481   g_assert (g_key_file_has_group (keyfile, "group1"));
482   g_assert (g_key_file_has_group (keyfile, "group2"));
483   g_assert (!g_key_file_has_group (keyfile, "group10"));
484   g_assert (!g_key_file_has_group (keyfile, "group20"));
485
486   start = g_key_file_get_start_group (keyfile);
487   g_assert_cmpstr (start, ==, "group1");
488   g_free (start);
489
490   g_assert (g_key_file_has_key (keyfile, "group1", "key1", &error));
491   check_no_error (&error);
492   g_assert (g_key_file_has_key (keyfile, "group2", "key3", &error));
493   check_no_error (&error);
494   g_assert (!g_key_file_has_key (keyfile, "group2", "no-such-key", NULL));
495
496   g_key_file_has_key (keyfile, "no-such-group", "key", &error);
497   check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_GROUP_NOT_FOUND);
498
499   g_key_file_free (keyfile);
500 }
501
502 /* check parsing of string values */
503 static void
504 test_string (void)
505 {
506   GKeyFile *keyfile;
507   GError *error = NULL;
508   gchar *value;
509   const gchar const *list[3];
510   const gchar *data =
511     "[valid]\n"
512     "key1=\\s\\n\\t\\r\\\\\n"
513     "key2=\"quoted\"\n"
514     "key3='quoted'\n"
515     "key4=\xe2\x89\xa0\xe2\x89\xa0\n"
516     "key5=  leading space\n"
517     "key6=trailing space  \n"
518     "[invalid]\n"
519     "key1=\\a\\b\\0800xff\n"
520     "key2=blabla\\\n";
521
522   keyfile = load_data (data, 0);
523
524   check_string_value (keyfile, "valid", "key1", " \n\t\r\\");
525   check_string_value (keyfile, "valid", "key2", "\"quoted\"");
526   check_string_value (keyfile, "valid", "key3", "'quoted'");
527   check_string_value (keyfile, "valid", "key4", "\xe2\x89\xa0\xe2\x89\xa0");
528   check_string_value (keyfile, "valid", "key5", "leading space");
529   check_string_value (keyfile, "valid", "key6", "trailing space  ");
530
531   value = g_key_file_get_string (keyfile, "invalid", "key1", &error);
532   check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE);
533   g_free (value);
534
535   value = g_key_file_get_string (keyfile, "invalid", "key2", &error);
536   check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE);
537   g_free (value);
538
539   g_key_file_set_string (keyfile, "inserted", "key1", "simple");
540   g_key_file_set_string (keyfile, "inserted", "key2", " leading space");
541   g_key_file_set_string (keyfile, "inserted", "key3", "\tleading tab");
542   g_key_file_set_string (keyfile, "inserted", "key4", "new\nline");
543   g_key_file_set_string (keyfile, "inserted", "key5", "carriage\rreturn");
544   g_key_file_set_string (keyfile, "inserted", "key6", "slash\\yay!");
545   list[0] = "one";
546   list[1] = "two;andahalf";
547   list[2] = "3";
548   g_key_file_set_string_list (keyfile, "inserted", "key7", list, 3);
549
550   check_string_value (keyfile, "inserted", "key1", "simple");
551   check_string_value (keyfile, "inserted", "key2", " leading space");
552   check_string_value (keyfile, "inserted", "key3", "\tleading tab");
553   check_string_value (keyfile, "inserted", "key4", "new\nline");
554   check_string_value (keyfile, "inserted", "key5", "carriage\rreturn");
555   check_string_value (keyfile, "inserted", "key6", "slash\\yay!");
556   check_string_list_value (keyfile, "inserted", "key7", "one", "two;andahalf", "3", NULL);
557
558   g_key_file_free (keyfile);
559 }
560
561 /* check parsing of boolean values */
562 static void
563 test_boolean (void)
564 {
565   GKeyFile *keyfile;
566   GError *error = NULL;
567
568   const gchar *data =
569     "[valid]\n"
570     "key1=true\n"
571     "key2=false\n"
572     "key3=1\n"
573     "key4=0\n"
574     "[invalid]\n"
575     "key1=t\n"
576     "key2=f\n"
577     "key3=yes\n"
578     "key4=no\n";
579
580   keyfile = load_data (data, 0);
581
582   check_boolean_value (keyfile, "valid", "key1", TRUE);
583   check_boolean_value (keyfile, "valid", "key2", FALSE);
584   check_boolean_value (keyfile, "valid", "key3", TRUE);
585   check_boolean_value (keyfile, "valid", "key4", FALSE);
586
587   g_key_file_get_boolean (keyfile, "invalid", "key1", &error);
588   check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE);
589
590   g_key_file_get_boolean (keyfile, "invalid", "key2", &error);
591   check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE);
592
593   g_key_file_get_boolean (keyfile, "invalid", "key3", &error);
594   check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE);
595
596   g_key_file_get_boolean (keyfile, "invalid", "key4", &error);
597   check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE);
598
599   g_key_file_set_boolean (keyfile, "valid", "key1", FALSE);
600   check_boolean_value (keyfile, "valid", "key1", FALSE);
601
602   g_key_file_free (keyfile);
603 }
604
605 /* check parsing of integer and double values */
606 static void
607 test_number (void)
608 {
609   GKeyFile *keyfile;
610   GError *error = NULL;
611
612   const gchar *data =
613     "[valid]\n"
614     "key1=0\n"
615     "key2=1\n"
616     "key3=-1\n"
617     "key4=2324431\n"
618     "key5=-2324431\n"
619     "key6=000111\n"
620     "dkey1=000111\n"
621     "dkey2=145.45\n"
622     "dkey3=-3453.7\n"
623     "[invalid]\n"
624     "key1=0xffff\n"
625     "key2=0.5\n"
626     "key3=1e37\n"
627     "key4=ten\n"
628     "key5=\n"
629     "key6=1.0.0\n"
630     "key7=2x2\n"
631     "key8=abc\n";
632
633   keyfile = load_data (data, 0);
634
635   check_integer_value (keyfile, "valid", "key1", 0);
636   check_integer_value (keyfile, "valid", "key2", 1);
637   check_integer_value (keyfile, "valid", "key3", -1);
638   check_integer_value (keyfile, "valid", "key4", 2324431);
639   check_integer_value (keyfile, "valid", "key5", -2324431);
640   check_integer_value (keyfile, "valid", "key6", 111);
641   check_double_value (keyfile, "valid", "dkey1", 111.0);
642   check_double_value (keyfile, "valid", "dkey2", 145.45);
643   check_double_value (keyfile, "valid", "dkey3", -3453.7);
644
645   g_key_file_get_integer (keyfile, "invalid", "key1", &error);
646   check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE);
647
648   g_key_file_get_integer (keyfile, "invalid", "key2", &error);
649   check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE);
650
651   g_key_file_get_integer (keyfile, "invalid", "key3", &error);
652   check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE);
653
654   g_key_file_get_integer (keyfile, "invalid", "key4", &error);
655   check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE);
656
657   g_key_file_get_double (keyfile, "invalid", "key5", &error);
658   check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE);
659
660   g_key_file_get_double (keyfile, "invalid", "key6", &error);
661   check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE);
662
663   g_key_file_get_double (keyfile, "invalid", "key7", &error);
664   check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE);
665
666   g_key_file_get_double (keyfile, "invalid", "key8", &error);
667   check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE);
668
669   g_key_file_free (keyfile);
670 }
671
672 /* check handling of translated strings */
673 static void
674 test_locale_string (void)
675 {
676   GKeyFile *keyfile;
677   gchar *old_locale;
678
679   const gchar *data =
680     "[valid]\n"
681     "key1=v1\n"
682     "key1[de]=v1-de\n"
683     "key1[de_DE]=v1-de_DE\n"
684     "key1[de_DE.UTF8]=v1-de_DE.UTF8\n"
685     "key1[fr]=v1-fr\n"
686     "key1[en] =v1-en\n"
687     "key1[sr@Latn]=v1-sr\n";
688
689   keyfile = load_data (data, G_KEY_FILE_KEEP_TRANSLATIONS);
690
691   check_locale_string_value (keyfile, "valid", "key1", "it", "v1");
692   check_locale_string_value (keyfile, "valid", "key1", "de", "v1-de");
693   check_locale_string_value (keyfile, "valid", "key1", "de_DE", "v1-de_DE");
694   check_locale_string_value (keyfile, "valid", "key1", "de_DE.UTF8", "v1-de_DE.UTF8");
695   check_locale_string_value (keyfile, "valid", "key1", "fr", "v1-fr");
696   check_locale_string_value (keyfile, "valid", "key1", "fr_FR", "v1-fr");
697   check_locale_string_value (keyfile, "valid", "key1", "en", "v1-en");
698   check_locale_string_value (keyfile, "valid", "key1", "sr@Latn", "v1-sr");
699
700   g_key_file_free (keyfile);
701
702   /* now test that translations are thrown away */
703
704   old_locale = g_strdup (setlocale (LC_ALL, NULL));
705   g_setenv ("LANGUAGE", "de", TRUE);
706   setlocale (LC_ALL, "");
707
708   keyfile = load_data (data, 0);
709
710   check_locale_string_value (keyfile, "valid", "key1", "it", "v1");
711   check_locale_string_value (keyfile, "valid", "key1", "de", "v1-de");
712   check_locale_string_value (keyfile, "valid", "key1", "de_DE", "v1-de");
713   check_locale_string_value (keyfile, "valid", "key1", "de_DE.UTF8", "v1-de");
714   check_locale_string_value (keyfile, "valid", "key1", "fr", "v1");
715   check_locale_string_value (keyfile, "valid", "key1", "fr_FR", "v1");
716   check_locale_string_value (keyfile, "valid", "key1", "en", "v1");
717
718   g_key_file_free (keyfile);
719
720   setlocale (LC_ALL, old_locale);
721   g_free (old_locale);
722 }
723
724 static void
725 test_lists (void)
726 {
727   GKeyFile *keyfile;
728
729   const gchar *data =
730     "[valid]\n"
731     "key1=v1;v2\n"
732     "key2=v1;v2;\n"
733     "key3=v1,v2\n"
734     "key4=v1\\;v2\n"
735     "key5=true;false\n"
736     "key6=1;0;-1\n"
737     "key7= 1 ; 0 ; -1 \n"
738     "key8=v1\\,v2\n"
739     "key9=0;1.3456;-76532.456\n";
740
741   keyfile = load_data (data, 0);
742
743   check_string_list_value (keyfile, "valid", "key1", "v1", "v2", NULL);
744   check_string_list_value (keyfile, "valid", "key2", "v1", "v2", NULL);
745   check_string_list_value (keyfile, "valid", "key3", "v1,v2", NULL);
746   check_string_list_value (keyfile, "valid", "key4", "v1;v2", NULL);
747   check_boolean_list_value (keyfile, "valid", "key5", TRUE, FALSE, -100);
748   check_integer_list_value (keyfile, "valid", "key6", 1, 0, -1, -100);
749   check_double_list_value (keyfile, "valid", "key9", 0.0, 1.3456, -76532.456, -100.0);
750   /* maybe these should be valid */
751   /* check_integer_list_value (keyfile, "valid", "key7", 1, 0, -1, -100);*/
752   /* check_string_list_value (keyfile, "valid", "key8", "v1\\,v2", NULL);*/
753
754   g_key_file_free (keyfile);
755
756   /* Now check an alternate separator */
757
758   keyfile = load_data (data, 0);
759   g_key_file_set_list_separator (keyfile, ',');
760
761   check_string_list_value (keyfile, "valid", "key1", "v1;v2", NULL);
762   check_string_list_value (keyfile, "valid", "key2", "v1;v2;", NULL);
763   check_string_list_value (keyfile, "valid", "key3", "v1", "v2", NULL);
764
765   g_key_file_free (keyfile);
766 }
767
768 static void
769 test_lists_set_get (void)
770 {
771   GKeyFile *keyfile;
772   static const char * const strings[] = { "v1", "v2" };
773   static const char * const locale_strings[] = { "v1-l", "v2-l" };
774   static int integers[] = { 1, -1, 2 };
775   static gdouble doubles[] = { 3.14, 2.71 };
776
777   keyfile = g_key_file_new ();
778   g_key_file_set_string_list (keyfile, "group0", "key1", strings, G_N_ELEMENTS (strings));
779   g_key_file_set_locale_string_list (keyfile, "group0", "key1", "de", locale_strings, G_N_ELEMENTS (locale_strings));
780   g_key_file_set_integer_list (keyfile, "group0", "key2", integers, G_N_ELEMENTS (integers));
781   g_key_file_set_double_list (keyfile, "group0", "key3", doubles, G_N_ELEMENTS (doubles));
782
783   check_string_list_value (keyfile, "group0", "key1", strings[0], strings[1], NULL);
784   check_locale_string_list_value (keyfile, "group0", "key1", "de", locale_strings[0], locale_strings[1], NULL);
785   check_integer_list_value (keyfile, "group0", "key2", integers[0], integers[1], -100);
786   check_double_list_value (keyfile, "group0", "key3", doubles[0], doubles[1], -100.0);
787   g_key_file_free (keyfile);
788
789   /* and again with a different list separator */
790   keyfile = g_key_file_new ();
791   g_key_file_set_list_separator (keyfile, ',');
792   g_key_file_set_string_list (keyfile, "group0", "key1", strings, G_N_ELEMENTS (strings));
793   g_key_file_set_locale_string_list (keyfile, "group0", "key1", "de", locale_strings, G_N_ELEMENTS (locale_strings));
794   g_key_file_set_integer_list (keyfile, "group0", "key2", integers, G_N_ELEMENTS (integers));
795   g_key_file_set_double_list (keyfile, "group0", "key3", doubles, G_N_ELEMENTS (doubles));
796
797   check_string_list_value (keyfile, "group0", "key1", strings[0], strings[1], NULL);
798   check_locale_string_list_value (keyfile, "group0", "key1", "de", locale_strings[0], locale_strings[1], NULL);
799   check_integer_list_value (keyfile, "group0", "key2", integers[0], integers[1], -100);
800   check_double_list_value (keyfile, "group0", "key3", doubles[0], doubles[1], -100.0);
801   g_key_file_free (keyfile);
802 }
803
804 static void
805 test_group_remove (void)
806 {
807   GKeyFile *keyfile;
808   gchar **names;
809   gsize len;
810   GError *error = NULL;
811
812   const gchar *data =
813     "[group1]\n"
814     "[group2]\n"
815     "key1=bla\n"
816     "key2=bla\n"
817     "[group3]\n"
818     "key1=bla\n"
819     "key2=bla\n";
820
821   g_test_bug ("165887");
822
823   keyfile = load_data (data, 0);
824
825   names = g_key_file_get_groups (keyfile, &len);
826   g_assert (names != NULL);
827
828   check_length ("groups", g_strv_length (names), len, 3);
829   check_name ("group name", names[0], "group1", 0);
830   check_name ("group name", names[1], "group2", 1);
831   check_name ("group name", names[2], "group3", 2);
832
833   g_key_file_remove_group (keyfile, "group1", &error);
834   check_no_error (&error);
835
836   g_strfreev (names);
837
838   names = g_key_file_get_groups (keyfile, &len);
839   g_assert (names != NULL);
840
841   check_length ("groups", g_strv_length (names), len, 2);
842   check_name ("group name", names[0], "group2", 0);
843   check_name ("group name", names[1], "group3", 1);
844
845   g_key_file_remove_group (keyfile, "group2", &error);
846   check_no_error (&error);
847
848   g_strfreev (names);
849
850   names = g_key_file_get_groups (keyfile, &len);
851   g_assert (names != NULL);
852
853   check_length ("groups", g_strv_length (names), len, 1);
854   check_name ("group name", names[0], "group3", 0);
855
856   g_key_file_remove_group (keyfile, "no such group", &error);
857   check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_GROUP_NOT_FOUND);
858
859   g_strfreev (names);
860
861   g_key_file_free (keyfile);
862 }
863
864 static void
865 test_key_remove (void)
866 {
867   GKeyFile *keyfile;
868   gchar *value;
869   GError *error = NULL;
870
871   const gchar *data =
872     "[group1]\n"
873     "key1=bla\n"
874     "key2=bla\n";
875
876   g_test_bug ("165980");
877
878   keyfile = load_data (data, 0);
879
880   check_string_value (keyfile, "group1", "key1", "bla");
881
882   g_key_file_remove_key (keyfile, "group1", "key1", &error);
883   check_no_error (&error);
884
885   value = g_key_file_get_string (keyfile, "group1", "key1", &error);
886   check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_KEY_NOT_FOUND);
887   g_free (value);
888
889   g_key_file_remove_key (keyfile, "group1", "key1", &error);
890   check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_KEY_NOT_FOUND);
891
892   g_key_file_remove_key (keyfile, "no such group", "key1", &error);
893   check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_GROUP_NOT_FOUND);
894
895   g_key_file_free (keyfile);
896 }
897
898
899 static void
900 test_groups (void)
901 {
902   GKeyFile *keyfile;
903
904   const gchar *data =
905     "[1]\n"
906     "key1=123\n"
907     "[2]\n"
908     "key2=123\n";
909
910   g_test_bug ("316309");
911
912   keyfile = load_data (data, 0);
913
914   check_string_value (keyfile, "1", "key1", "123");
915   check_string_value (keyfile, "2", "key2", "123");
916
917   g_key_file_free (keyfile);
918 }
919
920 static void
921 test_group_names (void)
922 {
923   GKeyFile *keyfile;
924   GError *error = NULL;
925   const gchar *data;
926   gchar *value;
927
928   /* [ in group name */
929   data = "[a[b]\n"
930          "key1=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   /* ] in group name */
939   data = "[a]b]\n"
940          "key1=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   /* control char in group name */
949   data = "[a\tb]\n"
950          "key1=123\n";
951   keyfile = g_key_file_new ();
952   g_key_file_load_from_data (keyfile, data, -1, 0, &error);
953   g_key_file_free (keyfile);
954   check_error (&error,
955                G_KEY_FILE_ERROR,
956                G_KEY_FILE_ERROR_PARSE);
957
958   /* empty group name */
959   data = "[]\n"
960          "key1=123\n";
961   keyfile = g_key_file_new ();
962   g_key_file_load_from_data (keyfile, data, -1, 0, &error);
963   g_key_file_free (keyfile);
964   check_error (&error,
965                G_KEY_FILE_ERROR,
966                G_KEY_FILE_ERROR_PARSE);
967
968   /* Unicode in group name */
969   data = "[\xc2\xbd]\n"
970          "key1=123\n";
971   keyfile = g_key_file_new ();
972   g_key_file_load_from_data (keyfile, data, -1, 0, &error);
973   g_key_file_free (keyfile);
974   check_no_error (&error);
975
976   keyfile = g_key_file_new ();
977   /*g_key_file_set_string (keyfile, "a[b", "key1", "123");*/
978   value = g_key_file_get_string (keyfile, "a[b", "key1", &error);
979   check_error (&error,
980                G_KEY_FILE_ERROR,
981                G_KEY_FILE_ERROR_GROUP_NOT_FOUND);
982   g_assert (value == NULL);
983   g_key_file_free (keyfile);
984
985   keyfile = g_key_file_new ();
986   /*g_key_file_set_string (keyfile, "a]b", "key1", "123");*/
987   value = g_key_file_get_string (keyfile, "a]b", "key1", &error);
988   check_error (&error,
989                G_KEY_FILE_ERROR,
990                G_KEY_FILE_ERROR_GROUP_NOT_FOUND);
991   g_assert (value == NULL);
992   g_key_file_free (keyfile);
993
994   keyfile = g_key_file_new ();
995   /*g_key_file_set_string (keyfile, "a\tb", "key1", "123");*/
996   value = g_key_file_get_string (keyfile, "a\tb", "key1", &error);
997   check_error (&error,
998                G_KEY_FILE_ERROR,
999                G_KEY_FILE_ERROR_GROUP_NOT_FOUND);
1000   g_assert (value == NULL);
1001   g_key_file_free (keyfile);
1002
1003   keyfile = g_key_file_new ();
1004   g_key_file_set_string (keyfile, "\xc2\xbd", "key1", "123");
1005   check_string_value (keyfile, "\xc2\xbd", "key1", "123");
1006   g_key_file_free (keyfile);
1007 }
1008
1009 static void
1010 test_key_names (void)
1011 {
1012   GKeyFile *keyfile;
1013   GError *error = NULL;
1014   const gchar *data;
1015   gchar *value;
1016
1017   /* [ in key name */
1018   data = "[a]\n"
1019          "key[=123\n";
1020   keyfile = g_key_file_new ();
1021   g_key_file_load_from_data (keyfile, data, -1, 0, &error);
1022   g_key_file_free (keyfile);
1023   check_error (&error,
1024                G_KEY_FILE_ERROR,
1025                G_KEY_FILE_ERROR_PARSE);
1026
1027   /* empty key name */
1028   data = "[a]\n"
1029          " =123\n";
1030   keyfile = g_key_file_new ();
1031   g_key_file_load_from_data (keyfile, data, -1, 0, &error);
1032   g_key_file_free (keyfile);
1033   check_error (&error,
1034                G_KEY_FILE_ERROR,
1035                G_KEY_FILE_ERROR_PARSE);
1036
1037   /* empty key name */
1038   data = "[a]\n"
1039          " [de] =123\n";
1040   keyfile = g_key_file_new ();
1041   g_key_file_load_from_data (keyfile, data, -1, 0, &error);
1042   g_key_file_free (keyfile);
1043   check_error (&error,
1044                G_KEY_FILE_ERROR,
1045                G_KEY_FILE_ERROR_PARSE);
1046
1047   /* bad locale suffix */
1048   data = "[a]\n"
1049          "foo[@#!&%]=123\n";
1050   keyfile = g_key_file_new ();
1051   g_key_file_load_from_data (keyfile, data, -1, 0, &error);
1052   g_key_file_free (keyfile);
1053   check_error (&error,
1054                G_KEY_FILE_ERROR,
1055                G_KEY_FILE_ERROR_PARSE);
1056
1057   /* initial space */
1058   data = "[a]\n"
1059          " foo=123\n";
1060   keyfile = g_key_file_new ();
1061   g_key_file_load_from_data (keyfile, data, -1, 0, &error);
1062   check_no_error (&error);
1063   check_string_value (keyfile, "a", "foo", "123");
1064   g_key_file_free (keyfile);
1065
1066   /* final space */
1067   data = "[a]\n"
1068          "foo =123\n";
1069   keyfile = g_key_file_new ();
1070   g_key_file_load_from_data (keyfile, data, -1, 0, &error);
1071   check_no_error (&error);
1072   check_string_value (keyfile, "a", "foo", "123");
1073   g_key_file_free (keyfile);
1074
1075   /* inner space */
1076   data = "[a]\n"
1077          "foo bar=123\n";
1078   keyfile = g_key_file_new ();
1079   g_key_file_load_from_data (keyfile, data, -1, 0, &error);
1080   check_no_error (&error);
1081   check_string_value (keyfile, "a", "foo bar", "123");
1082   g_key_file_free (keyfile);
1083
1084   /* inner space */
1085   data = "[a]\n"
1086          "foo [de] =123\n";
1087   keyfile = g_key_file_new ();
1088   g_key_file_load_from_data (keyfile, data, -1, 0, &error);
1089   check_error (&error,
1090                G_KEY_FILE_ERROR,
1091                G_KEY_FILE_ERROR_PARSE);
1092   g_key_file_free (keyfile);
1093
1094   /* control char in key name */
1095   data = "[a]\n"
1096          "key\tfoo=123\n";
1097   keyfile = g_key_file_new ();
1098   g_key_file_load_from_data (keyfile, data, -1, 0, &error);
1099   g_key_file_free (keyfile);
1100   check_no_error (&error);
1101
1102   /* Unicode in key name */
1103   data = "[a]\n"
1104          "\xc2\xbd=123\n";
1105   keyfile = g_key_file_new ();
1106   g_key_file_load_from_data (keyfile, data, -1, 0, &error);
1107   g_key_file_free (keyfile);
1108   check_no_error (&error);
1109
1110   keyfile = g_key_file_new ();
1111   g_key_file_set_string (keyfile, "a", "x", "123");
1112   /*g_key_file_set_string (keyfile, "a", "key=", "123");*/
1113   value = g_key_file_get_string (keyfile, "a", "key=", &error);
1114   check_error (&error,
1115                G_KEY_FILE_ERROR,
1116                G_KEY_FILE_ERROR_KEY_NOT_FOUND);
1117   g_key_file_free (keyfile);
1118
1119   keyfile = g_key_file_new ();
1120   g_key_file_set_string (keyfile, "a", "x", "123");
1121   /*g_key_file_set_string (keyfile, "a", "key[", "123");*/
1122   value = g_key_file_get_string (keyfile, "a", "key[", &error);
1123   check_error (&error,
1124                G_KEY_FILE_ERROR,
1125                G_KEY_FILE_ERROR_KEY_NOT_FOUND);
1126   g_key_file_free (keyfile);
1127
1128   keyfile = g_key_file_new ();
1129   g_key_file_set_string (keyfile, "a", "x", "123");
1130   g_key_file_set_string (keyfile, "a", "key\tfoo", "123");
1131   value = g_key_file_get_string (keyfile, "a", "key\tfoo", &error);
1132   check_no_error (&error);
1133   g_free (value);
1134   g_key_file_free (keyfile);
1135
1136   keyfile = g_key_file_new ();
1137   g_key_file_set_string (keyfile, "a", "x", "123");
1138   /*g_key_file_set_string (keyfile, "a", " key", "123");*/
1139   value = g_key_file_get_string (keyfile, "a", " key", &error);
1140   check_error (&error,
1141                G_KEY_FILE_ERROR,
1142                G_KEY_FILE_ERROR_KEY_NOT_FOUND);
1143   g_key_file_free (keyfile);
1144
1145   keyfile = g_key_file_new ();
1146   g_key_file_set_string (keyfile, "a", "x", "123");
1147
1148   /* Unicode key */
1149   g_key_file_set_string (keyfile, "a", "\xc2\xbd", "123");
1150   check_string_value (keyfile, "a", "\xc2\xbd", "123");
1151
1152   /* Keys with / + . (as used by the gnome-vfs mime cache) */
1153   g_key_file_set_string (keyfile, "a", "foo/bar", "/");
1154   check_string_value (keyfile, "a", "foo/bar", "/");
1155   g_key_file_set_string (keyfile, "a", "foo+bar", "+");
1156   check_string_value (keyfile, "a", "foo+bar", "+");
1157   g_key_file_set_string (keyfile, "a", "foo.bar", ".");
1158   check_string_value (keyfile, "a", "foo.bar", ".");
1159
1160   g_key_file_free (keyfile);
1161 }
1162
1163 static void
1164 test_duplicate_keys (void)
1165 {
1166   GKeyFile *keyfile;
1167   const gchar *data =
1168     "[1]\n"
1169     "key1=123\n"
1170     "key1=345\n";
1171
1172   keyfile = load_data (data, 0);
1173   check_string_value (keyfile, "1", "key1", "345");
1174
1175   g_key_file_free (keyfile);
1176 }
1177
1178 static void
1179 test_duplicate_groups (void)
1180 {
1181   GKeyFile *keyfile;
1182   const gchar *data =
1183     "[Desktop Entry]\n"
1184     "key1=123\n"
1185     "[Desktop Entry]\n"
1186     "key2=123\n";
1187
1188   g_test_bug ("157877");
1189
1190   keyfile = load_data (data, 0);
1191   check_string_value (keyfile, "Desktop Entry", "key1", "123");
1192   check_string_value (keyfile, "Desktop Entry", "key2", "123");
1193
1194   g_key_file_free (keyfile);
1195 }
1196
1197 static void
1198 test_duplicate_groups2 (void)
1199 {
1200   GKeyFile *keyfile;
1201   const gchar *data =
1202     "[A]\n"
1203     "foo=bar\n"
1204     "[B]\n"
1205     "foo=baz\n"
1206     "[A]\n"
1207     "foo=bang\n";
1208
1209   g_test_bug ("385910");
1210
1211   keyfile = load_data (data, 0);
1212   check_string_value (keyfile, "A", "foo", "bang");
1213   check_string_value (keyfile, "B", "foo", "baz");
1214
1215   g_key_file_free (keyfile);
1216 }
1217
1218 static void
1219 test_reload_idempotency (void)
1220 {
1221   static const gchar *original_data=""
1222     "# Top comment\n"
1223     "\n"
1224     "# First comment\n"
1225     "[first]\n"
1226     "key=value\n"
1227     "# A random comment in the first group\n"
1228     "anotherkey=anothervalue\n"
1229     "# Second comment - one line\n"
1230     "[second]\n"
1231     "# Third comment - two lines\n"
1232     "# Third comment - two lines\n"
1233     "[third]\n"
1234     "blank_line=1\n"
1235     "\n"
1236     "blank_lines=2\n"
1237     "\n\n"
1238     "[fourth]\n"
1239     "[fifth]\n";
1240   GKeyFile *keyfile;
1241   GError *error = NULL;
1242   gchar *data1, *data2;
1243   gsize len1, len2;
1244
1245   g_test_bug ("420686");
1246
1247   /* check that we only insert a single new line between groups */
1248   keyfile = g_key_file_new ();
1249   g_key_file_load_from_data (keyfile,
1250                              original_data, strlen(original_data),
1251                              G_KEY_FILE_KEEP_COMMENTS,
1252                              &error);
1253   check_no_error (&error);
1254
1255   data1 = g_key_file_to_data (keyfile, &len1, &error);
1256   g_assert (data1 != NULL);
1257   g_key_file_free (keyfile);
1258
1259   keyfile = g_key_file_new ();
1260   g_key_file_load_from_data (keyfile,
1261                              data1, len1,
1262                              G_KEY_FILE_KEEP_COMMENTS,
1263                              &error);
1264   check_no_error (&error);
1265
1266   data2 = g_key_file_to_data (keyfile, &len2, &error);
1267   g_assert (data2 != NULL);
1268   g_key_file_free (keyfile);
1269
1270   g_assert_cmpstr (data1, ==, data2);
1271
1272   g_free (data2);
1273   g_free (data1);
1274 }
1275
1276 static const char int64_data[] =
1277 "[bees]\n"
1278 "a=1\n"
1279 "b=2\n"
1280 "c=123456789123456789\n"
1281 "d=-123456789123456789\n";
1282
1283 static void
1284 test_int64 (void)
1285 {
1286   GKeyFile *file;
1287   gboolean ok;
1288   guint64 c;
1289   gint64 d;
1290   gchar *value;
1291
1292   g_test_bug ("614864");
1293
1294   file = g_key_file_new ();
1295
1296   ok = g_key_file_load_from_data (file, int64_data, strlen (int64_data),
1297       0, NULL);
1298   g_assert (ok);
1299
1300   c = g_key_file_get_uint64 (file, "bees", "c", NULL);
1301   g_assert (c == G_GUINT64_CONSTANT (123456789123456789));
1302
1303   d = g_key_file_get_int64 (file, "bees", "d", NULL);
1304   g_assert (d == G_GINT64_CONSTANT (-123456789123456789));
1305
1306   g_key_file_set_uint64 (file, "bees", "c",
1307       G_GUINT64_CONSTANT (987654321987654321));
1308   value = g_key_file_get_value (file, "bees", "c", NULL);
1309   g_assert_cmpstr (value, ==, "987654321987654321");
1310   g_free (value);
1311
1312   g_key_file_set_int64 (file, "bees", "d",
1313       G_GINT64_CONSTANT (-987654321987654321));
1314   value = g_key_file_get_value (file, "bees", "d", NULL);
1315   g_assert_cmpstr (value, ==, "-987654321987654321");
1316   g_free (value);
1317
1318   g_key_file_free (file);
1319 }
1320
1321 static void
1322 test_load (void)
1323 {
1324   GKeyFile *file;
1325   GError *error;
1326   gboolean bools[2] = { TRUE, FALSE };
1327   gboolean loaded;
1328
1329   file = g_key_file_new ();
1330   error = NULL;
1331 #ifdef G_OS_UNIX
1332   /* Uses the value of $XDG_DATA_HOME we set in main() */
1333   loaded = g_key_file_load_from_data_dirs (file, "keyfiletest.ini", NULL, 0, &error);
1334 #else
1335   loaded = g_key_file_load_from_file (file, g_test_get_filename (G_TEST_DIST, "keyfiletest.ini", NULL), 0, &error);
1336 #endif
1337   g_assert_no_error (error);
1338   g_assert (loaded);
1339
1340   g_key_file_set_locale_string (file, "test", "key4", "de", "Vierter Schlüssel");
1341   g_key_file_set_boolean_list (file, "test", "key5", bools, 2);
1342   g_key_file_set_integer (file, "test", "key6", 22);
1343   g_key_file_set_double (file, "test", "key7", 2.5);
1344   g_key_file_set_comment (file, "test", "key7", "some float", NULL);
1345   g_key_file_set_comment (file, "test", NULL, "the test group", NULL);
1346   g_key_file_set_comment (file, NULL, NULL, "top comment", NULL);
1347
1348   g_key_file_free (file);
1349
1350   file = g_key_file_new ();
1351   error = NULL;
1352   g_assert (!g_key_file_load_from_data_dirs (file, "keyfile-test.ini", NULL, 0, &error));
1353   g_assert_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_NOT_FOUND);
1354   g_error_free (error);
1355   g_key_file_free (file);
1356 }
1357
1358 static void
1359 test_save (void)
1360 {
1361   GKeyFile *kf;
1362   GKeyFile *kf2;
1363   static const char data[] =
1364     "[bees]\n"
1365     "a=1\n"
1366     "b=2\n"
1367     "c=123456789123456789\n"
1368     "d=-123456789123456789\n";
1369   gboolean ok;
1370   gchar *file;
1371   guint64 c;
1372   GError *error = NULL;
1373
1374   kf = g_key_file_new ();
1375   ok = g_key_file_load_from_data (kf, data, strlen (data), 0, NULL);
1376   g_assert (ok);
1377
1378   file = g_strdup ("key_file_XXXXXX");
1379   g_mkstemp (file);
1380   ok = g_key_file_save_to_file (kf, file, &error);
1381   g_assert (ok);
1382   g_assert_no_error (error);
1383
1384   kf2 = g_key_file_new ();
1385   ok = g_key_file_load_from_file (kf2, file, 0, &error);
1386   g_assert (ok);
1387   g_assert_no_error (error);
1388
1389   c = g_key_file_get_uint64 (kf2, "bees", "c", NULL);
1390   g_assert (c == G_GUINT64_CONSTANT (123456789123456789));
1391
1392   g_free (file);
1393   g_key_file_free (kf);
1394   g_key_file_free (kf2);
1395 }
1396
1397 static void
1398 test_load_fail (void)
1399 {
1400   GKeyFile *file;
1401   GError *error;
1402
1403   file = g_key_file_new ();
1404   error = NULL;
1405   g_assert (!g_key_file_load_from_file (file, g_test_get_filename (G_TEST_DIST, "keyfile.c", NULL), 0, &error));
1406   g_assert_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_PARSE);
1407   g_clear_error (&error);
1408   g_assert (!g_key_file_load_from_file (file, "/nosuchfile", 0, &error));
1409   g_assert_error (error, G_FILE_ERROR, G_FILE_ERROR_NOENT);
1410   g_clear_error (&error);
1411
1412   g_key_file_free (file);
1413 }
1414
1415 static void
1416 test_non_utf8 (void)
1417 {
1418   GKeyFile *file;
1419   static const char data[] =
1420 "[group]\n"
1421 "a=\230\230\230\n"
1422 "b=a;b;\230\230\230;\n"
1423 "c=a\\\n";
1424   gboolean ok;
1425   GError *error;
1426   gchar *s;
1427   gchar **l;
1428
1429   file = g_key_file_new ();
1430
1431   ok = g_key_file_load_from_data (file, data, strlen (data), 0, NULL);
1432   g_assert (ok);
1433
1434   error = NULL;
1435   s = g_key_file_get_string (file, "group", "a", &error);
1436   g_assert_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_UNKNOWN_ENCODING);
1437   g_assert (s == NULL);
1438
1439   g_clear_error (&error);
1440   l = g_key_file_get_string_list (file, "group", "b", NULL, &error);
1441   g_assert_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_UNKNOWN_ENCODING);
1442   g_assert (l == NULL);
1443
1444   g_clear_error (&error);
1445   l = g_key_file_get_string_list (file, "group", "c", NULL, &error);
1446   g_assert_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE);
1447   g_assert (l == NULL);
1448
1449   g_clear_error (&error);
1450
1451   g_key_file_free (file);
1452 }
1453
1454 static void
1455 test_page_boundary (void)
1456 {
1457   GKeyFile *file;
1458   GError *error;
1459   gint i;
1460
1461 #define GROUP "main_section"
1462 #define KEY_PREFIX "fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_"
1463 #define FIRST_KEY 10
1464 #define LAST_KEY 99
1465 #define VALUE 92
1466
1467   g_test_bug ("640695");
1468
1469   file = g_key_file_new ();
1470
1471   error = NULL;
1472   g_key_file_load_from_file (file, g_test_get_filename (G_TEST_DIST, "pages.ini", NULL), G_KEY_FILE_NONE, &error);
1473   g_assert_no_error (error);
1474
1475   for (i = FIRST_KEY; i <= LAST_KEY; i++)
1476     {
1477       gchar *key;
1478       gint val;
1479
1480       key = g_strdup_printf (KEY_PREFIX "%d", i);
1481       val = g_key_file_get_integer (file, GROUP, key, &error);
1482       g_free (key);
1483       g_assert_no_error (error);
1484       g_assert_cmpint (val, ==, VALUE);
1485     }
1486
1487   g_key_file_free (file);
1488 }
1489
1490 static void
1491 test_ref (void)
1492 {
1493   GKeyFile *file;
1494   static const char data[] =
1495 "[group]\n"
1496 "a=1\n";
1497   gboolean ok;
1498
1499   file = g_key_file_new ();
1500
1501   ok = g_key_file_load_from_data (file, data, strlen (data), 0, NULL);
1502   g_assert (ok);
1503   g_assert (g_key_file_has_key (file, "group", "a", NULL));
1504   g_key_file_ref (file);
1505   g_key_file_free (file);
1506   g_key_file_unref (file);
1507 }
1508
1509 /* https://bugzilla.gnome.org/show_bug.cgi?id=634232 */
1510 static void
1511 test_replace_value (void)
1512 {
1513   GKeyFile *keyfile;
1514
1515   keyfile = g_key_file_new();
1516   g_key_file_set_value(keyfile, "grupo1", "chave1", "1234567890");
1517   g_key_file_set_value(keyfile, "grupo1", "chave1", "123123423423423432432423423");
1518   g_key_file_remove_group(keyfile, "grupo1", NULL);
1519   g_free (g_key_file_to_data (keyfile, NULL, NULL));
1520   g_key_file_unref (keyfile);
1521 }
1522
1523 static void
1524 test_list_separator (void)
1525 {
1526   GKeyFile *keyfile;
1527   GError *error = NULL;
1528
1529   const gchar *data =
1530     "[test]\n"
1531     "key1=v1,v2\n";
1532
1533   keyfile = g_key_file_new ();
1534   g_key_file_set_list_separator (keyfile, ',');
1535   g_key_file_load_from_data (keyfile, data, -1, 0, &error);
1536
1537   check_string_list_value (keyfile, "test", "key1", "v1", "v2", NULL);
1538   g_key_file_unref (keyfile);
1539 }
1540
1541 static void
1542 test_empty_string (void)
1543 {
1544   GError *error = NULL;
1545   GKeyFile *kf;
1546
1547   kf = g_key_file_new ();
1548
1549   g_key_file_load_from_data (kf, "", 0, 0, &error);
1550   g_assert_no_error (error);
1551
1552   g_key_file_load_from_data (kf, "", -1, 0, &error);
1553   g_assert_no_error (error);
1554
1555   /* NULL is a fine pointer to use if length is zero */
1556   g_key_file_load_from_data (kf, NULL, 0, 0, &error);
1557   g_assert_no_error (error);
1558
1559   /* should not attempt to access non-NULL pointer if length is zero */
1560   g_key_file_load_from_data (kf, GINT_TO_POINTER (1), 0, 0, &error);
1561   g_assert_no_error (error);
1562
1563   g_key_file_unref (kf);
1564 }
1565
1566 static void
1567 test_limbo (void)
1568 {
1569   GKeyFile *file;
1570   static const char data[] =
1571 "a=b\n"
1572 "[group]\n"
1573 "b=c\n";
1574   gboolean ok;
1575   GError *error;
1576
1577   file = g_key_file_new ();
1578
1579   error = NULL;
1580   ok = g_key_file_load_from_data (file, data, strlen (data), 0, &error);
1581   g_assert (!ok);
1582   g_assert_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_GROUP_NOT_FOUND);
1583   g_clear_error (&error);
1584   g_key_file_free (file);
1585 }
1586
1587 static void
1588 test_utf8 (void)
1589 {
1590   GKeyFile *file;
1591   static const char data[] =
1592 "[group]\n"
1593 "Encoding=non-UTF-8\n";
1594   gboolean ok;
1595   GError *error;
1596
1597   file = g_key_file_new ();
1598
1599   error = NULL;
1600   ok = g_key_file_load_from_data (file, data, strlen (data), 0, &error);
1601   g_assert (!ok);
1602   g_assert_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_UNKNOWN_ENCODING);
1603   g_clear_error (&error);
1604   g_key_file_free (file);
1605 }
1606
1607 static void
1608 test_roundtrip (void)
1609 {
1610   GKeyFile *kf;
1611   const gchar orig[] =
1612     "[Group1]\n"
1613     "key1=value1\n"
1614     "\n"
1615     "[Group2]\n"
1616     "key1=value1\n";
1617   gsize len;
1618   gchar *data;
1619
1620   kf = load_data (orig, G_KEY_FILE_KEEP_COMMENTS);
1621   g_key_file_set_integer (kf, "Group1", "key2", 0);
1622   g_key_file_remove_key (kf, "Group1", "key2", NULL);
1623
1624   data = g_key_file_to_data (kf, &len, NULL);
1625   g_assert_cmpstr (data, ==, orig);
1626
1627   g_free (data);
1628   g_key_file_free (kf);
1629 }
1630
1631 int
1632 main (int argc, char *argv[])
1633 {
1634   g_test_init (&argc, &argv, NULL);
1635
1636 #ifdef G_OS_UNIX
1637   g_setenv ("XDG_DATA_HOME", g_test_get_dir (G_TEST_DIST), TRUE);
1638 #endif
1639
1640   g_test_bug_base ("http://bugzilla.gnome.org/");
1641
1642   g_test_add_func ("/keyfile/line-ends", test_line_ends);
1643   g_test_add_func ("/keyfile/whitespace", test_whitespace);
1644   g_test_add_func ("/keyfile/comments", test_comments);
1645   g_test_add_func ("/keyfile/listing", test_listing);
1646   g_test_add_func ("/keyfile/string", test_string);
1647   g_test_add_func ("/keyfile/boolean", test_boolean);
1648   g_test_add_func ("/keyfile/number", test_number);
1649   g_test_add_func ("/keyfile/locale-string", test_locale_string);
1650   g_test_add_func ("/keyfile/lists", test_lists);
1651   g_test_add_func ("/keyfile/lists-set-get", test_lists_set_get);
1652   g_test_add_func ("/keyfile/group-remove", test_group_remove);
1653   g_test_add_func ("/keyfile/key-remove", test_key_remove);
1654   g_test_add_func ("/keyfile/groups", test_groups);
1655   g_test_add_func ("/keyfile/duplicate-keys", test_duplicate_keys);
1656   g_test_add_func ("/keyfile/duplicate-groups", test_duplicate_groups);
1657   g_test_add_func ("/keyfile/duplicate-groups2", test_duplicate_groups2);
1658   g_test_add_func ("/keyfile/group-names", test_group_names);
1659   g_test_add_func ("/keyfile/key-names", test_key_names);
1660   g_test_add_func ("/keyfile/reload", test_reload_idempotency);
1661   g_test_add_func ("/keyfile/int64", test_int64);
1662   g_test_add_func ("/keyfile/load", test_load);
1663   g_test_add_func ("/keyfile/save", test_save);
1664   g_test_add_func ("/keyfile/load-fail", test_load_fail);
1665   g_test_add_func ("/keyfile/non-utf8", test_non_utf8);
1666   g_test_add_func ("/keyfile/page-boundary", test_page_boundary);
1667   g_test_add_func ("/keyfile/ref", test_ref);
1668   g_test_add_func ("/keyfile/replace-value", test_replace_value);
1669   g_test_add_func ("/keyfile/list-separator", test_list_separator);
1670   g_test_add_func ("/keyfile/empty-string", test_empty_string);
1671   g_test_add_func ("/keyfile/limbo", test_limbo);
1672   g_test_add_func ("/keyfile/utf8", test_utf8);
1673   g_test_add_func ("/keyfile/roundtrip", test_roundtrip);
1674
1675   return g_test_run ();
1676 }