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