Don't include ctype.h needlessly. (#156424, Morten Welinder)
[platform/upstream/glib.git] / glib / gkeyfile.c
1 /* gkeyfile.c - key file parser
2  *
3  *  Copyright 2004  Red Hat, Inc.  
4  *
5  * Written by Ray Strode <rstrode@redhat.com>
6  *
7  * GLib is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU Lesser General Public License as
9  * published by the Free Software Foundation; either version 2 of the
10  * License, or (at your option) any later version.
11  *
12  * GLib is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with GLib; see the file COPYING.LIB.  If not,
19  * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20  *   Boston, MA 02111-1307, USA.
21  */
22
23 #include "config.h"
24 #include "gkeyfile.h"
25
26 #include <errno.h>
27 #include <fcntl.h>
28 #include <locale.h>
29 #include <string.h>
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <sys/types.h>
33 #include <sys/stat.h>
34 #include <unistd.h>
35
36 #include "gconvert.h"
37 #include "gdataset.h"
38 #include "gerror.h"
39 #include "gfileutils.h"
40 #include "ghash.h"
41 #include "glibintl.h"
42 #include "glist.h"
43 #include "gslist.h"
44 #include "gmem.h"
45 #include "gmessages.h"
46 #include "gstring.h"
47 #include "gstrfuncs.h"
48 #include "gutils.h"
49
50 typedef struct _GKeyFileGroup GKeyFileGroup;
51
52 struct _GKeyFile
53 {
54   GList *groups;
55
56   gchar  *start_group_name;
57
58   GKeyFileGroup *current_group;
59
60   GString *parse_buffer; /* Holds up to one line of not-yet-parsed data */
61
62   /* Used for sizing the output buffer during serialization
63    */
64   gsize approximate_size;
65
66   gchar list_separator;
67
68   GKeyFileFlags flags;
69 };
70
71 struct _GKeyFileGroup
72 {
73   const gchar *name;  /* NULL for above first group (which will be comments) */
74
75   GList *key_value_pairs; 
76
77   /* Used in parallel with key_value_pairs for
78    * increased lookup performance
79    */
80   GHashTable *lookup_map;
81 };
82
83 typedef struct
84 {
85   gchar *key;  /* NULL for comments */
86   gchar *value;
87 } GKeyFileKeyValuePair;
88
89 static gint                  find_file_in_data_dirs            (const gchar            *file,
90                                                                 gchar                 **output_file,
91                                                                 gchar                ***data_dirs,
92                                                                 GError                **error);
93 static void                  g_key_file_load_from_fd           (GKeyFile               *key_file,
94                                                                 gint                    fd,
95                                                                 GKeyFileFlags           flags,
96                                                                 GError                **error);
97 static GKeyFileGroup        *g_key_file_lookup_group           (GKeyFile               *key_file,
98                                                                 const gchar            *group_name);
99 static GKeyFileKeyValuePair *g_key_file_lookup_key_value_pair  (GKeyFile               *key_file,
100                                                                 GKeyFileGroup          *group,
101                                                                 const gchar            *key);
102 static void                  g_key_file_remove_group_node      (GKeyFile               *entry,
103                                                                 GList                  *group_node);
104 static void                  g_key_file_add_key                (GKeyFile               *entry,
105                                                                 const gchar            *group_name,
106                                                                 const gchar            *key,
107                                                                 const gchar            *value);
108 static void                  g_key_file_add_group              (GKeyFile               *entry,
109                                                                 const gchar            *group_name);
110 static void                  g_key_file_key_value_pair_free    (GKeyFileKeyValuePair   *pair);
111 static gboolean              g_key_file_line_is_comment        (const gchar            *line);
112 static gboolean              g_key_file_line_is_group          (const gchar            *line);
113 static gboolean              g_key_file_line_is_key_value_pair (const gchar            *line);
114 static gchar                *g_key_file_parse_value_as_string  (GKeyFile               *entry,
115                                                                 const gchar            *value,
116                                                                 GSList                **separators,
117                                                                 GError                **error);
118 static gchar                *g_key_file_parse_string_as_value  (GKeyFile               *entry,
119                                                                 const gchar            *string,
120                                                                 gboolean                escape_separator);
121 static gint                  g_key_file_parse_value_as_integer (GKeyFile               *entry,
122                                                                 const gchar            *value,
123                                                                 GError                **error);
124 static gchar                *g_key_file_parse_integer_as_value (GKeyFile               *entry,
125                                                                 gint                    value);
126 static gboolean              g_key_file_parse_value_as_boolean (GKeyFile               *entry,
127                                                                 const gchar            *value,
128                                                                 GError                **error);
129 static gchar                *g_key_file_parse_boolean_as_value (GKeyFile               *entry,
130                                                                 gboolean                value);
131 static void                  g_key_file_parse_key_value_pair   (GKeyFile               *entry,
132                                                                 const gchar            *line,
133                                                                 gsize                   length,
134                                                                 GError                **error);
135 static void                  g_key_file_parse_comment          (GKeyFile               *entry,
136                                                                 const gchar            *line,
137                                                                 gsize                   length,
138                                                                 GError                **error);
139 static void                  g_key_file_parse_group            (GKeyFile               *entry,
140                                                                 const gchar            *line,
141                                                                 gsize                   length,
142                                                                 GError                **error);
143 static gchar                *key_get_locale                    (const gchar            *key);
144 static void                  g_key_file_parse_data             (GKeyFile               *entry,
145                                                                 const gchar            *data,
146                                                                 gsize                   length,
147                                                                 GError                **error);
148 static void                  g_key_file_flush_parse_buffer     (GKeyFile               *entry,
149                                                                 GError                **error);
150
151
152 GQuark
153 g_key_file_error_quark (void)
154 {
155   static GQuark error_quark = 0;
156
157   if (error_quark == 0)
158     error_quark = g_quark_from_static_string ("g-key-file-error-quark");
159
160   return error_quark;
161 }
162
163 static void
164 g_key_file_init (GKeyFile *key_file)
165 {  
166   key_file->current_group = g_new0 (GKeyFileGroup, 1);
167   key_file->groups = g_list_prepend (NULL, key_file->current_group);
168   key_file->start_group_name = NULL;
169   key_file->parse_buffer = g_string_sized_new (128);
170   key_file->approximate_size = 0;
171   key_file->list_separator = ';';
172   key_file->flags = 0;
173 }
174
175 static void
176 g_key_file_clear (GKeyFile *key_file)
177 {
178   GList *tmp, *group_node;
179
180   if (key_file->parse_buffer)
181     g_string_free (key_file->parse_buffer, TRUE);
182
183   g_free (key_file->start_group_name);
184
185   tmp = key_file->groups;
186   while (tmp != NULL)
187     {
188       group_node = tmp;
189       tmp = tmp->next;
190       g_key_file_remove_group_node (key_file, group_node);
191     }
192
193   g_assert (key_file->groups == NULL);
194 }
195
196
197 /**
198  * g_key_file_new:
199  * @flags: flags from #GKeyFileFlags
200  *
201  * Creates a new empty #GKeyFile object. Use g_key_file_load_from_file(),
202  * g_key_file_load_from_data() or g_key_file_load_from_data_dirs() to
203  * read an existing key file.
204  *
205  * Return value: an empty #GKeyFile.
206  *
207  * Since: 2.6
208  **/
209 GKeyFile *
210 g_key_file_new (void)
211 {
212   GKeyFile *key_file;
213
214   key_file = g_new0 (GKeyFile, 1);
215   g_key_file_init (key_file);
216
217   return key_file;
218 }
219
220 /**
221  * g_key_file_set_list_separator:
222  * @key_file: a #GKeyFile 
223  * @separator: the separator
224  *
225  * Sets the character which is used to separate
226  * values in lists. Typically ';' or ',' are used
227  * as separators. The default list separator is ';'.
228  *
229  * Since: 2.6
230  */
231 void
232 g_key_file_set_list_separator (GKeyFile *key_file,
233                                gchar     separator)
234 {
235   key_file->list_separator = separator;
236 }
237
238
239 /* Iterates through all the directories in *dirs trying to
240  * open file.  When it successfully locates and opens a file it
241  * returns the file descriptor to the open file.  It also
242  * outputs the absolute path of the file in output_file and
243  * leaves the unchecked directories in *dirs.
244  */
245 static gint
246 find_file_in_data_dirs (const gchar   *file,
247                         gchar        **output_file,
248                         gchar       ***dirs,
249                         GError       **error)
250 {
251   gchar **data_dirs, *data_dir, *path;
252   gint fd;
253   GError *file_error;
254
255   file_error = NULL;
256   path = NULL;
257   fd = -1;
258
259   if (dirs == NULL)
260     return fd;
261
262   data_dirs = *dirs;
263
264   while (data_dirs && (data_dir = *data_dirs) && fd < 0)
265     {
266       gchar *candidate_file, *sub_dir;
267
268       candidate_file = (gchar *) file;
269       sub_dir = g_strdup ("");
270       while (candidate_file != NULL && fd < 0)
271         {
272           gchar *p;
273
274           path = g_build_filename (data_dir, sub_dir,
275                                    candidate_file, NULL);
276
277           fd = open (path, O_RDONLY);
278
279           if (output_file != NULL)
280             *output_file = g_strdup (path);
281
282           g_free (path);
283
284           if (fd < 0 && file_error == NULL)
285             file_error = g_error_new (G_KEY_FILE_ERROR,
286                                       G_KEY_FILE_ERROR_NOT_FOUND,
287                                       _("Valid key file could not be "
288                                         "found in data dirs")); 
289
290           candidate_file = strchr (candidate_file, '-');
291
292           if (candidate_file == NULL)
293             break;
294
295           candidate_file++;
296
297           g_free (sub_dir);
298           sub_dir = g_strndup (file, candidate_file - file - 1);
299
300           for (p = sub_dir; *p != '\0'; p++)
301             {
302               if (*p == '-')
303                 *p = G_DIR_SEPARATOR;
304             }
305         }
306       g_free (sub_dir);
307       data_dirs++;
308     }
309
310   *dirs = data_dirs;
311
312   if (file_error)
313     {
314       if (fd >= 0)
315         g_error_free (file_error);
316       else
317         g_propagate_error (error, file_error);
318     }
319
320   if (output_file && fd < 0)
321     {
322       g_free (*output_file);
323       *output_file = NULL;
324     }
325
326   return fd;
327 }
328
329 static void
330 g_key_file_load_from_fd (GKeyFile       *key_file,
331                          gint            fd,
332                          GKeyFileFlags   flags,
333                          GError        **error)
334 {
335   GError *key_file_error = NULL;
336   gsize bytes_read;
337   struct stat stat_buf;
338   gchar read_buf[4096];
339
340   if (key_file->approximate_size > 0)
341     {
342       g_key_file_clear (key_file);
343       g_key_file_init (key_file);
344     }
345   key_file->flags = flags;
346
347   fstat (fd, &stat_buf);
348   if (stat_buf.st_size == 0)
349     {
350       g_set_error (error, G_KEY_FILE_ERROR,
351                    G_KEY_FILE_ERROR_PARSE,
352                    _("File is empty"));
353       return;
354     }
355
356   key_file->start_group_name = NULL;
357
358   bytes_read = 0;
359   do
360     {
361       bytes_read = read (fd, read_buf, 4096);
362
363       if (bytes_read == 0)  /* End of File */
364         break;
365
366       if (bytes_read < 0)
367         {
368           if (errno == EINTR)
369             continue;
370
371           g_set_error (error, G_FILE_ERROR,
372                        g_file_error_from_errno (errno),
373                        _("Failed to read from file: %s"),
374                        g_strerror (errno));
375           close (fd);
376           return;
377         }
378
379       g_key_file_parse_data (key_file, 
380                              read_buf, bytes_read,
381                              &key_file_error);
382     }
383   while (!key_file_error);
384
385   close (fd);
386
387   if (key_file_error)
388     {
389       g_propagate_error (error, key_file_error);
390       return;
391     }
392
393   g_key_file_flush_parse_buffer (key_file, &key_file_error);
394
395   if (key_file_error)
396     {
397       g_propagate_error (error, key_file_error);
398       return;
399     }
400 }
401
402 /**
403  * g_key_file_load_from_file:
404  * @key_file: an empty #GKeyFile struct
405  * @file: the path of a filename to load
406  * @flags: flags from #GKeyFileFlags
407  * @error: return location for a #GError, or %NULL
408  *
409  * Loads a key file into an empty #GKeyFile structure.
410  * If the file could not be loaded then %error is set to 
411  * either a #GFileError or #GKeyFileError.
412  *
413  * Since: 2.6
414  **/
415 void
416 g_key_file_load_from_file (GKeyFile       *key_file,
417                            const gchar    *file,
418                            GKeyFileFlags   flags,
419                            GError        **error)
420 {
421   GError *key_file_error = NULL;
422   gint fd;
423
424   fd = open (file, O_RDONLY);
425
426   if (fd < 0)
427     {
428       g_set_error (error, G_FILE_ERROR,
429                    g_file_error_from_errno (errno),
430                    _("Failed to open file '%s': %s"),
431                    file, g_strerror (errno));
432       return;
433     }
434
435   if (!g_file_test (file, G_FILE_TEST_IS_REGULAR))
436     {
437       g_set_error (error, G_FILE_ERROR,
438                    G_FILE_ERROR_ISDIR,
439                    _("Not a regular file: '%s'"),
440                    file);
441       return;
442     }
443
444   g_key_file_load_from_fd (key_file, fd, flags, &key_file_error);
445
446   if (key_file_error)
447     g_propagate_error (error, key_file_error);
448 }
449
450 /**
451  * g_key_file_load_from_data:
452  * @key_file: an empty #GKeyFile struct
453  * @data: key file loaded in memory.
454  * @length: the length of @data in bytes
455  * @flags: flags from #GKeyFileFlags
456  * @error: return location for a #GError, or %NULL
457  *
458  * Loads a key file from memory into an empty #GKeyFile structure.  
459  * If the object cannot be created then %error is set to a #GKeyFileError.
460  *
461  * Since: 2.6
462  **/
463 void
464 g_key_file_load_from_data (GKeyFile       *key_file,
465                            const gchar    *data,
466                            gsize           length,
467                            GKeyFileFlags   flags,
468                            GError        **error)
469 {
470   GError *key_file_error = NULL;
471
472   g_return_if_fail (data != NULL);
473   g_return_if_fail (length != 0);
474
475   if (key_file->approximate_size > 0)
476     {
477       g_key_file_clear (key_file);
478       g_key_file_init (key_file);
479     }
480   key_file->flags = flags;
481
482   g_key_file_parse_data (key_file, data, length, &key_file_error);
483   
484   if (key_file_error)
485     {
486       g_propagate_error (error, key_file_error);
487       return;
488     }
489
490   g_key_file_flush_parse_buffer (key_file, &key_file_error);
491   
492   if (key_file_error)
493     g_propagate_error (error, key_file_error);
494 }
495
496 /**
497  * g_key_file_load_from_data_dirs:
498  * @key_file: an empty #GKeyFile struct
499  * @file: a relative path to a filename to open and parse
500  * @full_path: return location for a string containing the full path
501  *   of the file, or %NULL
502  * @flags: flags from #GKeyFileFlags 
503  * @error: return location for a #GError, or %NULL
504  *
505  * This function looks for a key file named @file in the paths 
506  * returned from g_get_user_data_dir() and g_get_system_data_dirs(), 
507  * loads the file into @key_file and returns the file's full path in 
508  * @full_path.  If the file could not be loaded then an %error is
509  * set to either a #GFileError or #GKeyFileError.
510  *
511  * Since: 2.6
512  **/
513 void
514 g_key_file_load_from_data_dirs (GKeyFile       *key_file,
515                                 const gchar    *file,
516                                 gchar         **full_path,
517                                 GKeyFileFlags   flags,
518                                 GError        **error)
519 {
520   GError *key_file_error = NULL;
521   gchar **all_data_dirs, **data_dirs;
522   const gchar * user_data_dir;
523   const const gchar * const * system_data_dirs;
524   gsize i, j;
525   gchar *output_path;
526   gint fd;
527   
528   g_return_if_fail (!g_path_is_absolute (file));
529
530   user_data_dir = g_get_user_data_dir ();
531   system_data_dirs = g_get_system_data_dirs ();
532   all_data_dirs = g_new (gchar *, g_strv_length ((gchar **)system_data_dirs) + 1);
533
534   i = 0;
535   all_data_dirs[i++] = g_strdup (user_data_dir);
536
537   j = 0;
538   while (system_data_dirs[j] != NULL)
539     all_data_dirs[i++] = g_strdup (system_data_dirs[j++]);
540
541   data_dirs = all_data_dirs;
542   while (*data_dirs != NULL)
543     {
544       fd = find_file_in_data_dirs (file, &output_path, &data_dirs, 
545                                    &key_file_error);
546       
547       if (fd < 0)
548         {
549           if (key_file_error)
550             g_propagate_error (error, key_file_error);
551
552           break;
553         }
554
555       g_key_file_load_from_fd (key_file, fd, flags,
556                                &key_file_error);
557       
558       if (key_file_error)
559         {
560           g_propagate_error (error, key_file_error);
561           g_free (output_path);
562
563           break;
564         }
565       
566       if (full_path)
567         *full_path = output_path;
568     }
569
570   g_strfreev (all_data_dirs);
571 }
572
573 /**
574  * g_key_file_free:
575  * @key_file: a #GKeyFile
576  *
577  * Frees a #GKeyFile.
578  *
579  * Since: 2.6
580  **/
581 void
582 g_key_file_free (GKeyFile *key_file)
583 {
584   g_return_if_fail (key_file != NULL);
585   
586   g_key_file_clear (key_file);
587   g_free (key_file);
588 }
589
590 /* If G_KEY_FILE_KEEP_TRANSLATIONS is not set, only returns
591  * true for locales that match those in g_get_language_names().
592  */
593 static gboolean
594 g_key_file_locale_is_interesting (GKeyFile    *key_file,
595                                   const gchar *locale)
596 {
597   const const gchar * const * current_locales;
598   gsize i;
599
600   if (key_file->flags & G_KEY_FILE_KEEP_TRANSLATIONS)
601     return TRUE;
602
603   current_locales = g_get_language_names ();
604
605   for (i = 0; current_locales[i] != NULL; i++)
606     {
607       if (g_ascii_strcasecmp (current_locales[i], locale) == 0)
608         return TRUE;
609     }
610
611   return FALSE;
612 }
613
614 static void
615 g_key_file_parse_line (GKeyFile     *key_file,
616                        const gchar  *line,
617                        gsize         length,
618                        GError      **error)
619 {
620   GError *parse_error = NULL;
621   gchar *line_start;
622
623   g_return_if_fail (key_file != NULL);
624   g_return_if_fail (line != NULL);
625
626   line_start = (gchar *) line;
627   while (g_ascii_isspace (*line_start))
628     line_start++;
629
630   if (g_key_file_line_is_comment (line_start))
631     g_key_file_parse_comment (key_file, line, length, &parse_error);
632   else if (g_key_file_line_is_group (line_start))
633     g_key_file_parse_group (key_file, line_start,
634                             length - (line_start - line),
635                             &parse_error);
636   else if (g_key_file_line_is_key_value_pair (line_start))
637     g_key_file_parse_key_value_pair (key_file, line_start,
638                                      length - (line_start - line),
639                                      &parse_error);
640   else
641     {
642       g_set_error (error, G_KEY_FILE_ERROR,
643                    G_KEY_FILE_ERROR_PARSE,
644                    _("Key file contains line '%s' which is not "
645                      "a key-value pair, group, or comment"), line);
646       return;
647     }
648
649   if (parse_error)
650     g_propagate_error (error, parse_error);
651 }
652
653 static void
654 g_key_file_parse_comment (GKeyFile     *key_file,
655                           const gchar  *line,
656                           gsize         length,
657                           GError      **error)
658 {
659   GKeyFileKeyValuePair *pair;
660   
661   if (!key_file->flags & G_KEY_FILE_KEEP_COMMENTS)
662     return;
663   
664   g_assert (key_file->current_group != NULL);
665   
666   pair = g_new0 (GKeyFileKeyValuePair, 1);
667   
668   pair->key = NULL;
669   pair->value = g_strndup (line, length);
670   
671   key_file->current_group->key_value_pairs =
672     g_list_prepend (key_file->current_group->key_value_pairs, pair);
673 }
674
675 static void
676 g_key_file_parse_group (GKeyFile     *key_file,
677                         const gchar  *line,
678                         gsize         length,
679                         GError      **error)
680 {
681   gchar *group_name;
682   const gchar *group_name_start, *group_name_end;
683   
684   /* advance past opening '['
685    */
686   group_name_start = line + 1;
687   group_name_end = line + length - 1;
688   
689   while (*group_name_end != ']')
690     group_name_end--;
691
692   group_name = g_strndup (group_name_start, 
693                           group_name_end - group_name_start);
694   
695   if (key_file->start_group_name == NULL)
696     key_file->start_group_name = g_strdup (group_name);
697   
698   g_key_file_add_group (key_file, group_name);
699   g_free (group_name);
700 }
701
702 static void
703 g_key_file_parse_key_value_pair (GKeyFile     *key_file,
704                                  const gchar  *line,
705                                  gsize         length,
706                                  GError      **error)
707 {
708   gchar *key, *value, *key_end, *value_start, *locale;
709   gsize key_len, value_len;
710
711   if (key_file->current_group == NULL || key_file->current_group->name == NULL)
712     {
713       g_set_error (error, G_KEY_FILE_ERROR,
714                    G_KEY_FILE_ERROR_GROUP_NOT_FOUND,
715                    _("Key file does not start with a group"));
716       return;
717     }
718
719   key_end = value_start = strchr (line, '=');
720
721   g_assert (key_end != NULL);
722
723   key_end--;
724   value_start++;
725
726   /* Pull the key name from the line (chomping trailing whitespace)
727    */
728   while (g_ascii_isspace (*key_end))
729     key_end--;
730
731   key_len = key_end - line + 2;
732
733   g_assert (key_len <= length);
734
735   key = g_strndup (line, key_len - 1);
736
737   /* Pull the value from the line (chugging leading whitespace)
738    */
739   while (g_ascii_isspace (*value_start))
740     value_start++;
741
742   value_len = line + length - value_start + 1;
743
744   value = g_strndup (value_start, value_len);
745
746   if (!g_utf8_validate (value, -1, NULL))
747     {
748       g_set_error (error, G_KEY_FILE_ERROR,
749                    G_KEY_FILE_ERROR_UNKNOWN_ENCODING,
750                    _("Key file contains line '%s' "
751                      "which is not UTF-8"), line);
752
753       g_free (key);
754       g_free (value);
755       return;
756     }
757
758   if (key_file->current_group
759       && key_file->current_group->name
760       && strcmp (g_key_file_get_start_group (key_file),
761                  key_file->current_group->name) == 0
762       && strcmp (key, "Encoding") == 0)
763     {
764       if (g_ascii_strcasecmp (value, "UTF-8") != 0)
765         {
766           g_set_error (error, G_KEY_FILE_ERROR,
767                        G_KEY_FILE_ERROR_UNKNOWN_ENCODING,
768                        _("Key file contains unsupported encoding '%s'"), value);
769
770           g_free (key);
771           g_free (value);
772           return;
773         }
774     }
775
776   /* Is this key a translation? If so, is it one that we care about?
777    */
778   locale = key_get_locale (key);
779
780   if (locale == NULL || g_key_file_locale_is_interesting (key_file, locale))
781     g_key_file_add_key (key_file, key_file->current_group->name, key, value);
782
783   g_free (locale);
784   g_free (key);
785   g_free (value);
786 }
787
788 static gchar *
789 key_get_locale (const gchar *key)
790 {
791   gchar *locale;
792
793   locale = g_strrstr (key, "[");
794
795   if (locale && strlen (locale) <= 2)
796     locale = NULL;
797
798   if (locale)
799     locale = g_strndup (locale + 1, strlen (locale) - 2);
800
801   return locale;
802 }
803
804 static void
805 g_key_file_parse_data (GKeyFile     *key_file,
806                        const gchar  *data,
807                        gsize         length,
808                        GError      **error)
809 {
810   GError *parse_error;
811   gsize i;
812
813   g_return_if_fail (key_file != NULL);
814
815   parse_error = NULL;
816
817   for (i = 0; i < length; i++)
818     {
819       if (data[i] == '\n')
820         {
821           /* When a newline is encountered flush the parse buffer so that the
822            * line can be parsed.  Note that completely blank lines won't show
823            * up in the parse buffer, so they get parsed directly.
824            */
825           if (key_file->parse_buffer->len > 0)
826             g_key_file_flush_parse_buffer (key_file, &parse_error);
827           else
828             g_key_file_parse_comment (key_file, "", 1, &parse_error);
829
830           if (parse_error)
831             {
832               g_propagate_error (error, parse_error);
833               return;
834             }
835         }
836       else
837         g_string_append_c (key_file->parse_buffer, data[i]);
838     }
839
840   key_file->approximate_size += length;
841 }
842
843 static void
844 g_key_file_flush_parse_buffer (GKeyFile  *key_file,
845                                GError   **error)
846 {
847   GError *file_error = NULL;
848
849   g_return_if_fail (key_file != NULL);
850
851   file_error = NULL;
852
853   if (key_file->parse_buffer->len > 0)
854     {
855       g_key_file_parse_line (key_file, key_file->parse_buffer->str,
856                              key_file->parse_buffer->len,
857                              &file_error);
858       g_string_erase (key_file->parse_buffer, 0, -1);
859
860       if (file_error)
861         {
862           g_propagate_error (error, file_error);
863           return;
864         }
865     }
866 }
867
868 /**
869  * g_key_file_to_data:
870  * @key_file: a #GKeyFile
871  * @length: return location for the length of the 
872  *   returned string, or %NULL
873  * @error: return location for a #GError, or %NULL
874  *
875  * This function outputs @key_file as a string.  
876  *
877  * Return value: a newly allocated string holding
878  *   the contents of the #GKeyFile 
879  *
880  * Since: 2.6
881  **/
882 gchar *
883 g_key_file_to_data (GKeyFile  *key_file,
884                     gsize     *length,
885                     GError   **error)
886 {
887   GString *data_string;
888   gchar *data;
889   GList *group_node, *key_file_node;
890
891   g_return_val_if_fail (key_file != NULL, NULL);
892
893   data_string = g_string_sized_new (2 * key_file->approximate_size);
894   
895   for (group_node = g_list_last (key_file->groups);
896        group_node != NULL;
897        group_node = group_node->prev)
898     {
899       GKeyFileGroup *group;
900
901       group = (GKeyFileGroup *) group_node->data;
902
903       if (group->name != NULL)
904         g_string_append_printf (data_string, "[%s]\n", group->name);
905
906       for (key_file_node = g_list_last (group->key_value_pairs);
907            key_file_node != NULL;
908            key_file_node = key_file_node->prev)
909         {
910           GKeyFileKeyValuePair *pair;
911
912           pair = (GKeyFileKeyValuePair *) key_file_node->data;
913
914           if (pair->key != NULL)
915             g_string_append_printf (data_string, "%s=%s\n", pair->key, pair->value);
916           else
917             g_string_append_printf (data_string, "%s\n", pair->value);
918         }
919     }
920
921   if (length)
922     *length = data_string->len;
923
924   data = data_string->str;
925
926   g_string_free (data_string, FALSE);
927
928   return data;
929 }
930
931 /**
932  * g_key_file_get_keys:
933  * @key_file: a #GKeyFile
934  * @group_name: a group name, or %NULL
935  * @length: return location for the number of keys returned, or %NULL
936  * @error: return location for a #GError, or %NULL
937  *
938  * Returns all keys for the group name @group_name. If @group_name is
939  * %NULL, the start group is used. The array of returned keys will be 
940  * %NULL-terminated, so @length may optionally be %NULL.
941  *
942  * Return value: a newly-allocated %NULL-terminated array of
943  * strings. Use g_strfreev() to free it.
944  *
945  * Since: 2.6
946  **/
947 gchar **
948 g_key_file_get_keys (GKeyFile     *key_file,
949                      const gchar  *group_name,
950                      gsize        *length,
951                      GError      **error)
952 {
953   GKeyFileGroup *group;
954   GList *tmp;
955   gchar **keys;
956   gsize i, num_keys;
957   
958   g_return_val_if_fail (key_file != NULL, NULL);
959   
960   if (group_name == NULL)
961     group_name = (const gchar *) key_file->start_group_name;
962   
963   group = g_key_file_lookup_group (key_file, group_name);
964   
965   if (!group)
966     {
967       g_set_error (error, G_KEY_FILE_ERROR,
968                    G_KEY_FILE_ERROR_GROUP_NOT_FOUND,
969                    _("Key file does not have group '%s'"),
970                    group_name);
971       return NULL;
972     }
973
974   num_keys = g_list_length (group->key_value_pairs);
975   
976   keys = (gchar **) g_new (gchar **, num_keys + 1);
977
978   tmp = group->key_value_pairs;
979   for (i = 0; i < num_keys; i++)
980     {
981       GKeyFileKeyValuePair *pair;
982
983       pair = (GKeyFileKeyValuePair *) tmp->data;
984       keys[i] = g_strdup (pair->key);
985
986       tmp = tmp->next;
987     }
988   keys[i] = NULL;
989
990   if (length)
991     *length = num_keys;
992
993   return keys;
994 }
995
996 /**
997  * g_key_file_get_start_group:
998  * @key_file: a #GKeyFile
999  *
1000  * Returns the name of the start group of the file. 
1001  *
1002  * Return value: The start group of the key file.
1003  *
1004  * Since: 2.6
1005  **/
1006 gchar *
1007 g_key_file_get_start_group (GKeyFile *key_file)
1008 {
1009   g_return_val_if_fail (key_file != NULL, NULL);
1010
1011   if (key_file->start_group_name)
1012     return g_strdup (key_file->start_group_name);
1013   else
1014     return NULL;
1015 }
1016
1017 /**
1018  * g_key_file_get_groups:
1019  * @key_file: a #GKeyFile
1020  * @length: return location for the number of returned groups, or %NULL
1021  *
1022  * Returns all groups in the key file loaded with @key_file.  The
1023  * array of returned groups will be %NULL-terminated, so @length may
1024  * optionally be %NULL.
1025  *
1026  * Return value: a newly-allocated %NULL-terminated array of strings. 
1027  *   Use g_strfreev() to free it.
1028  * Since: 2.6
1029  **/
1030 gchar **
1031 g_key_file_get_groups (GKeyFile *key_file,
1032                        gsize    *length)
1033 {
1034   GList *tmp;
1035   gchar **groups;
1036   gsize i, num_groups;
1037
1038   g_return_val_if_fail (key_file != NULL, NULL);
1039
1040   num_groups = g_list_length (key_file->groups);
1041   groups = (gchar **) g_new (gchar **, num_groups + 1);
1042
1043   tmp = key_file->groups;
1044   for (i = 0; i < num_groups; i++)
1045     {
1046       GKeyFileGroup *group;
1047
1048       group = (GKeyFileGroup *) tmp->data;
1049       groups[i] = g_strdup (group->name);
1050
1051       tmp = tmp->next;
1052     }
1053   groups[i] = NULL;
1054
1055   if (length)
1056     *length = num_groups;
1057
1058   return groups;
1059 }
1060
1061 /**
1062  * g_key_file_get_value:
1063  * @key_file: a #GKeyFile
1064  * @group_name: a group name
1065  * @key: a key
1066  * @error: return location for a #GError, or #NULL
1067  *
1068  * Returns the value associated with @key under @group_name.  
1069  * In the event the key cannot be found, %NULL is returned and 
1070  * @error is set to #G_KEY_FILE_ERROR_KEY_NOT_FOUND.  In the 
1071  * event that the @group_name cannot be found, %NULL is returned 
1072  * and @error is set to #G_KEY_FILE_ERROR_GROUP_NOT_FOUND.
1073  *
1074  * Return value: a string or %NULL if the specified key cannot be
1075  * found.
1076  *
1077  * Since: 2.6
1078  **/
1079 gchar *
1080 g_key_file_get_value (GKeyFile     *key_file,
1081                       const gchar  *group_name,
1082                       const gchar  *key,
1083                       GError      **error)
1084 {
1085   GKeyFileGroup *group;
1086   GKeyFileKeyValuePair *pair;
1087   gchar *value = NULL;
1088
1089   if (group_name == NULL)
1090     group_name = (const gchar *) key_file->start_group_name;
1091   
1092   group = g_key_file_lookup_group (key_file, group_name);
1093
1094   if (!group)
1095     {
1096       g_set_error (error, G_KEY_FILE_ERROR,
1097                    G_KEY_FILE_ERROR_GROUP_NOT_FOUND,
1098                    _("Key file does not have group '%s'"),
1099                    group_name);
1100       return NULL;
1101     }
1102
1103   pair = g_key_file_lookup_key_value_pair (key_file, group, key);
1104
1105   if (pair)
1106     value = g_strdup (pair->value);
1107   else
1108     g_set_error (error, G_KEY_FILE_ERROR,
1109                  G_KEY_FILE_ERROR_KEY_NOT_FOUND,
1110                  _("Key file does not have key '%s'"), key);
1111
1112   return value;
1113 }
1114
1115 /**
1116  * g_key_file_set_value:
1117  * @key_file: a #GKeyFile
1118  * @group_name: a group name
1119  * @key: a key
1120  * @value: a string
1121  *
1122  * Associates a new value with @key under @group_name.
1123  * If @key cannot be found then it is created. If @group_name
1124  * cannot be found then it is created as well.
1125  *
1126  * Since: 2.6
1127  **/
1128 void
1129 g_key_file_set_value (GKeyFile    *key_file,
1130                       const gchar *group_name,
1131                       const gchar *key,
1132                       const gchar *value)
1133 {
1134   GKeyFileGroup *group;
1135   GKeyFileKeyValuePair *pair;
1136
1137   pair = NULL;
1138
1139   if (group_name == NULL)
1140     group_name = (const gchar *) key_file->start_group_name;
1141
1142   if (!g_key_file_has_key (key_file, group_name, key, NULL))
1143     g_key_file_add_key (key_file, group_name, key, value);
1144   else
1145     {
1146       group = g_key_file_lookup_group (key_file, group_name);
1147       pair = g_key_file_lookup_key_value_pair (key_file, group, key);
1148       g_free (pair->value);
1149       pair->value = g_strdup (value);
1150     }
1151 }
1152
1153 /**
1154  * g_key_file_get_string:
1155  * @key_file: a #GKeyFile
1156  * @group_name: a group name
1157  * @key: a key
1158  * @error: return location for a #GError, or #NULL
1159  *
1160  * Returns the value associated with @key under @group_name.  
1161  * In the event the key cannot be found, %NULL is returned and 
1162  * @error is set to #G_KEY_FILE_ERROR_KEY_NOT_FOUND.  In the 
1163  * event that the @group_name cannot be found, %NULL is returned 
1164  * and @error is set to #G_KEY_FILE_ERROR_GROUP_NOT_FOUND.
1165  *
1166  * Return value: a string or %NULL if the specified key cannot be
1167  * found.
1168  *
1169  * Since: 2.6
1170  **/
1171 gchar *
1172 g_key_file_get_string (GKeyFile     *key_file,
1173                        const gchar  *group_name,
1174                        const gchar  *key,
1175                        GError      **error)
1176 {
1177   gchar *value, *string_value;
1178   GError *key_file_error;
1179
1180   g_return_val_if_fail (key_file != NULL, NULL);
1181   g_return_val_if_fail (key != NULL, NULL);
1182
1183   key_file_error = NULL;
1184
1185   value = g_key_file_get_value (key_file, group_name, key, &key_file_error);
1186
1187   if (key_file_error)
1188     {
1189       g_propagate_error (error, key_file_error);
1190       return NULL;
1191     }
1192
1193   string_value = g_key_file_parse_value_as_string (key_file, value, NULL,
1194                                                    &key_file_error);
1195   g_free (value);
1196
1197   if (key_file_error)
1198     {
1199       if (g_error_matches (key_file_error,
1200                            G_KEY_FILE_ERROR,
1201                            G_KEY_FILE_ERROR_INVALID_VALUE))
1202         {
1203           g_set_error (error, G_KEY_FILE_ERROR,
1204                        G_KEY_FILE_ERROR_INVALID_VALUE,
1205                        _("Key file contains key '%s' "
1206                          "which has value that cannot be interpreted."),
1207                        key);
1208           g_error_free (key_file_error);
1209         }
1210       else
1211         g_propagate_error (error, key_file_error);
1212     }
1213
1214   return string_value;
1215 }
1216
1217 /**
1218  * g_key_file_set_string:
1219  * @key_file: a #GKeyFile
1220  * @group_name: a group name
1221  * @key: a key
1222  * @string: a string
1223  *
1224  * Associates a new string value with @key under @group_name.
1225  * If @key cannot be found then it is created. If @group_name
1226  * cannot be found then it is created as well.
1227  *
1228  * Since: 2.6
1229  **/
1230 void
1231 g_key_file_set_string (GKeyFile    *key_file,
1232                        const gchar *group_name,
1233                        const gchar *key,
1234                        const gchar *string)
1235 {
1236   gchar *value;
1237
1238   g_return_if_fail (key_file != NULL);
1239   g_return_if_fail (key != NULL);
1240   
1241   value = g_key_file_parse_string_as_value (key_file, string, FALSE);
1242   g_key_file_set_value (key_file, group_name, key, value);
1243   g_free (value);
1244 }
1245
1246 /**
1247  * g_key_file_get_string_list:
1248  * @key_file: a #GKeyFile
1249  * @group_name: a group name
1250  * @key: a key
1251  * @length: return location for the number of returned strings, or %NULL
1252  * @error: return location for a #GError, or %NULL
1253  *
1254  * Returns the values associated with @key under @group_name.
1255  * In the event the key cannot be found, %NULL is returned and
1256  * @error is set to #G_KEY_FILE_ERROR_KEY_NOT_FOUND.  In the
1257  * event that the @group_name cannot be found, %NULL is returned
1258  * and @error is set to #G_KEY_FILE_ERROR_GROUP_NOT_FOUND.
1259  *
1260  * Return value: a %NULL-terminated string array or %NULL if the specified 
1261  *   key cannot be found. The array should be freed with g_strfreev().
1262  *
1263  * Since: 2.6
1264  **/
1265 gchar **
1266 g_key_file_get_string_list (GKeyFile     *key_file,
1267                             const gchar  *group_name,
1268                             const gchar  *key,
1269                             gsize        *length,
1270                             GError      **error)
1271 {
1272   GError *key_file_error = NULL;
1273   gchar *value, *string_value, **values;
1274   gint i, len;
1275   GSList *p, *pieces = NULL;
1276
1277   value = g_key_file_get_value (key_file, group_name, key, &key_file_error);
1278
1279   if (key_file_error)
1280     {
1281       g_propagate_error (error, key_file_error);
1282       return NULL;
1283     }
1284
1285   string_value = g_key_file_parse_value_as_string (key_file, value, &pieces, &key_file_error);
1286   g_free (value);
1287   g_free (string_value);
1288
1289   if (key_file_error)
1290     {
1291       if (g_error_matches (key_file_error,
1292                            G_KEY_FILE_ERROR,
1293                            G_KEY_FILE_ERROR_INVALID_VALUE))
1294         {
1295           g_set_error (error, G_KEY_FILE_ERROR,
1296                        G_KEY_FILE_ERROR_INVALID_VALUE,
1297                        _("Key file contains key '%s' "
1298                          "which has value that cannot be interpreted."),
1299                        key);
1300           g_error_free (key_file_error);
1301         }
1302       else
1303         g_propagate_error (error, key_file_error);
1304     }
1305
1306   len = g_slist_length (pieces);
1307   values = g_new (gchar *, len + 1); 
1308   for (p = pieces, i = 0; p; p = p->next)
1309     values[i++] = p->data;
1310   values[len] = NULL;
1311
1312   g_slist_free (pieces);
1313
1314   if (length)
1315     *length = len;
1316
1317   return values;
1318 }
1319
1320 /**
1321  * g_key_file_set_string_list:
1322  * @key_file: a #GKeyFile
1323  * @group_name: a group name
1324  * @key: a key
1325  * @list: an array of locale string values
1326  * @length: number of locale string values in @list
1327  *
1328  * Associates a list of string values for @key under @group_name.
1329  * If the @key cannot be found then it is created.
1330  *
1331  * Since: 2.6
1332  **/
1333 void
1334 g_key_file_set_string_list (GKeyFile            *key_file,
1335                             const gchar         *group_name,
1336                             const gchar         *key,
1337                             const gchar * const  list[],
1338                             gsize                length)
1339 {
1340   GString *value_list;
1341   gsize i;
1342
1343   g_return_if_fail (key_file != NULL);
1344   g_return_if_fail (key != NULL);
1345
1346   value_list = g_string_sized_new (length * 128);
1347   for (i = 0; list[i] != NULL && i < length; i++)
1348     {
1349       gchar *value;
1350
1351       value = g_key_file_parse_string_as_value (key_file, list[i], TRUE);
1352       g_string_append (value_list, value);
1353       g_string_append_c (value_list, key_file->list_separator);
1354
1355       g_free (value);
1356     }
1357
1358   g_key_file_set_value (key_file, group_name, key, value_list->str);
1359   g_string_free (value_list, TRUE);
1360 }
1361
1362 /**
1363  * g_key_file_set_locale_string:
1364  * @key_file: a #GKeyFile
1365  * @group_name: a group name
1366  * @key: a key
1367  * @locale: a locale
1368  * @string: a string
1369  *
1370  * Associates a string value for @key and @locale under
1371  * @group_name.  If the translation for @key cannot be found 
1372  * then it is created.
1373  *
1374  * Since: 2.6
1375  **/
1376 void
1377 g_key_file_set_locale_string (GKeyFile     *key_file,
1378                               const gchar  *group_name,
1379                               const gchar  *key,
1380                               const gchar  *locale,
1381                               const gchar  *string)
1382 {
1383   gchar *full_key, *value;
1384
1385   g_return_if_fail (key_file != NULL);
1386   g_return_if_fail (key != NULL);
1387
1388   value = g_key_file_parse_string_as_value (key_file, string, FALSE);
1389   full_key = g_strdup_printf ("%s[%s]", key, locale);
1390   g_key_file_set_value (key_file, group_name, full_key, value);
1391   g_free (full_key);
1392   g_free (value);
1393 }
1394
1395 extern GSList *_g_compute_locale_variants (const gchar *locale);
1396
1397 /**
1398  * g_key_file_get_locale_string:
1399  * @key_file: a #GKeyFile
1400  * @group_name: a group name
1401  * @key: a key
1402  * @locale: a locale or %NULL
1403  * @error: return location for a #GError, or %NULL
1404  *
1405  * Returns the value associated with @key under @group_name
1406  * translated in the given @locale if available.  If @locale is
1407  * %NULL then the current locale is assumed. If @key cannot be
1408  * found then %NULL is returned and @error is set to
1409  * #G_KEY_FILE_ERROR_KEY_NOT_FOUND. If the value associated
1410  * with @key cannot be interpreted or no suitable translation can
1411  * be found then the untranslated value is returned and @error is
1412  * set to #G_KEY_FILE_ERROR_INVALID_VALUE and
1413  * #G_KEY_FILE_ERROR_KEY_NOT_FOUND, respectively. In the
1414  * event that the @group_name cannot be found, %NULL is returned
1415  * and @error is set to #G_KEY_FILE_ERROR_GROUP_NOT_FOUND.
1416  *
1417  * Return value: a string or %NULL if the specified key cannot be
1418  *               found.
1419  * Since: 2.6
1420  **/
1421 gchar *
1422 g_key_file_get_locale_string (GKeyFile     *key_file,
1423                               const gchar  *group_name,
1424                               const gchar  *key,
1425                               const gchar  *locale,
1426                               GError      **error)
1427 {
1428   gchar *candidate_key, *translated_value;
1429   GError *key_file_error;
1430   gchar **languages;
1431   gboolean free_languages = FALSE;
1432   gint i;
1433
1434   candidate_key = NULL;
1435   translated_value = NULL;
1436   key_file_error = NULL;
1437
1438   if (!g_key_file_has_group (key_file, group_name))
1439     {
1440       g_set_error (error, G_KEY_FILE_ERROR,
1441                    G_KEY_FILE_ERROR_GROUP_NOT_FOUND,
1442                    _("Key file does not have group '%s'"),
1443                    group_name);
1444       return NULL;
1445     }
1446
1447   if (locale)
1448     {
1449       GSList *l, *list;
1450
1451       list = _g_compute_locale_variants (locale);
1452
1453       languages = g_new0 (gchar *, g_slist_length (list) + 1);
1454       for (l = list, i = 0; l; l = l->next, i++)
1455         languages[i] = l->data;
1456       languages[i] = NULL;
1457
1458       g_slist_free (list);
1459       free_languages = TRUE;
1460     }
1461   else
1462     {
1463       languages = (gchar **) g_get_language_names ();
1464       free_languages = FALSE;
1465     }
1466   
1467   for (i = 0; languages[i]; i++)
1468     {
1469       candidate_key = g_strdup_printf ("%s[%s]", key, languages[i]);
1470       
1471       translated_value = g_key_file_get_string (key_file,
1472                                                 group_name,
1473                                                 candidate_key, NULL);
1474       g_free (candidate_key);
1475
1476       if (translated_value)
1477         break;
1478    }
1479
1480   if (translated_value && !g_utf8_validate (translated_value, -1, NULL))
1481     {
1482       g_set_error (error, G_KEY_FILE_ERROR,
1483                    G_KEY_FILE_ERROR_INVALID_VALUE,
1484                    _("Key file contains key '%s' "
1485                      "which has value that cannot be interpreted."),
1486                    candidate_key);
1487       g_free (translated_value);
1488       translated_value = NULL;
1489   }
1490
1491   /* Fallback to untranslated key
1492    */
1493   if (!translated_value)
1494     {
1495       translated_value = g_key_file_get_string (key_file, group_name, key,
1496                                                 &key_file_error);
1497       
1498       if (!translated_value)
1499         g_propagate_error (error, key_file_error);
1500       else
1501         g_set_error (error, G_KEY_FILE_ERROR,
1502                      G_KEY_FILE_ERROR_KEY_NOT_FOUND,
1503                      _("Key file contains no translated value "
1504                        "for key '%s' with locale '%s'."),
1505                      key, locale);
1506     }
1507
1508   if (free_languages)
1509     g_strfreev (languages);
1510
1511   return translated_value;
1512 }
1513
1514 /** 
1515  * g_key_file_get_locale_string_list: 
1516  * @key_file: a #GKeyFile
1517  * @group_name: a group name
1518  * @key: a key
1519  * @locale: a locale
1520  * @length: return location for the number of returned strings or %NULL
1521  * @error: return location for a #GError or %NULL
1522  *
1523  * Returns the values associated with @key under @group_name
1524  * translated in the given @locale if available.  If @locale is
1525  * %NULL then the current locale is assumed. If @key cannot be
1526  * found then %NULL is returned and @error is set to
1527  * #G_KEY_FILE_ERROR_KEY_NOT_FOUND. If the values associated
1528  * with @key cannot be interpreted or no suitable translations
1529  * can be found then the untranslated values are returned and
1530  * @error is set to #G_KEY_FILE_ERROR_INVALID_VALUE and
1531  * #G_KEY_FILE_ERROR_KEY_NOT_FOUND, respectively. In the
1532  * event that the @group_name cannot be found, %NULL is returned
1533  * and @error is set to #G_KEY_FILE_ERROR_GROUP_NOT_FOUND.
1534  * The returned array is %NULL-terminated, so @length may optionally be %NULL.
1535  *
1536  * Return value: a newly allocated %NULL-terminated string array
1537  *   or %NULL if the key isn't found. The string array should be freed
1538  *   with g_strfreev().
1539  *
1540  * Since: 2.6
1541  **/
1542 gchar **
1543 g_key_file_get_locale_string_list (GKeyFile     *key_file,
1544                                    const gchar  *group_name,
1545                                    const gchar  *key,
1546                                    const gchar  *locale,
1547                                    gsize        *length,
1548                                    GError      **error)
1549 {
1550   GError *key_file_error;
1551   gchar **values, *value;
1552
1553   key_file_error = NULL;
1554
1555   value = g_key_file_get_locale_string (key_file, group_name, 
1556                                         key, locale,
1557                                         &key_file_error);
1558   
1559   if (key_file_error)
1560     g_propagate_error (error, key_file_error);
1561   
1562   if (!value)
1563     return NULL;
1564
1565   if (value[strlen (value) - 1] == ';')
1566     value[strlen (value) - 1] = '\0';
1567
1568   values = g_strsplit (value, ";", 0);
1569
1570   g_free (value);
1571
1572   if (length)
1573     *length = g_strv_length (values);
1574
1575   return values;
1576 }
1577
1578 /**
1579  * g_key_file_set_locale_string_list:
1580  * @key_file: a #GKeyFile
1581  * @group_name: a group name
1582  * @key: a key
1583  * @locale: a locale
1584  * @list: a %NULL-terminated array of locale string values
1585  * @length: the length of @list
1586  *
1587  * Associates a list of string values for @key and @locale under
1588  * @group_name.  If the translation for @key cannot be found then
1589  * it is created.
1590  *
1591  * Since: 2.6
1592  **/
1593 void
1594 g_key_file_set_locale_string_list (GKeyFile            *key_file,
1595                                    const gchar         *group_name,
1596                                    const gchar         *key,
1597                                    const gchar         *locale,
1598                                    const gchar * const  list[],
1599                                    gsize                length)
1600 {
1601   GString *value_list;
1602   gchar *full_key;
1603   gsize i;
1604
1605   g_return_if_fail (key_file != NULL);
1606   g_return_if_fail (key != NULL);
1607
1608   value_list = g_string_sized_new (length * 128);
1609   for (i = 0; list[i] != NULL && i < length; i++)
1610     {
1611       gchar *value;
1612       
1613       value = g_key_file_parse_string_as_value (key_file, list[i], TRUE);
1614       
1615       g_string_append (value_list, value);
1616       g_string_append_c (value_list, ';');
1617
1618       g_free (value);
1619     }
1620
1621   full_key = g_strdup_printf ("%s[%s]", key, locale);
1622   g_key_file_set_value (key_file, group_name, full_key, value_list->str);
1623   g_free (full_key);
1624   g_string_free (value_list, TRUE);
1625 }
1626
1627 /**
1628  * g_key_file_get_boolean:
1629  * @key_file: a #GKeyFile
1630  * @group_name: a group name
1631  * @key: a key
1632  * @error: return location for a #GError
1633  *
1634  * Returns the value associated with @key under @group_name as a
1635  * boolean.  If @key cannot be found then the return value is
1636  * undefined and @error is set to
1637  * #G_KEY_FILE_ERROR_KEY_NOT_FOUND. Likewise, if the value
1638  * associated with @key cannot be interpreted as a boolean then
1639  * the return value is also undefined and @error is set to
1640  * #G_KEY_FILE_ERROR_INVALID_VALUE.
1641  *
1642  * Return value: the value associated with the key as a boolean
1643  * Since: 2.6
1644  **/
1645 gboolean
1646 g_key_file_get_boolean (GKeyFile     *key_file,
1647                         const gchar  *group_name,
1648                         const gchar  *key,
1649                         GError      **error)
1650 {
1651   GError *key_file_error = NULL;
1652   gchar *value;
1653   gboolean bool_value;
1654
1655   value = g_key_file_get_value (key_file, group_name, key, &key_file_error);
1656
1657   if (!value)
1658     {
1659       g_propagate_error (error, key_file_error);
1660       return FALSE;
1661     }
1662
1663   bool_value = g_key_file_parse_value_as_boolean (key_file, value,
1664                                                   &key_file_error);
1665   g_free (value);
1666
1667   if (key_file_error)
1668     {
1669       if (g_error_matches (key_file_error,
1670                            G_KEY_FILE_ERROR,
1671                            G_KEY_FILE_ERROR_INVALID_VALUE))
1672         {
1673           g_set_error (error, G_KEY_FILE_ERROR,
1674                        G_KEY_FILE_ERROR_INVALID_VALUE,
1675                        _("Key file contains key '%s' "
1676                          "which has value that cannot be interpreted."),
1677                        key);
1678           g_error_free (key_file_error);
1679         }
1680       else
1681         g_propagate_error (error, key_file_error);
1682     }
1683
1684   return bool_value;
1685 }
1686
1687 /**
1688  * g_key_file_set_boolean:
1689  * @key_file: a #GKeyFile
1690  * @group_name: a group name
1691  * @key: a key
1692  * @value: %TRUE or %FALSE
1693  *
1694  * Associates a new boolean value with @key under @group_name.
1695  * If @key cannot be found then it is created.
1696  *
1697  * Since: 2.6
1698  **/
1699 void
1700 g_key_file_set_boolean (GKeyFile    *key_file,
1701                         const gchar *group_name,
1702                         const gchar *key,
1703                         gboolean     value)
1704 {
1705   gchar *result;
1706
1707   g_return_if_fail (key_file != NULL);
1708   g_return_if_fail (key != NULL);
1709
1710   result = g_key_file_parse_boolean_as_value (key_file, value);
1711   g_key_file_set_value (key_file, group_name, key, result);
1712   g_free (result);
1713 }
1714
1715 /**
1716  * g_key_file_get_boolean_list:
1717  * @key_file: a #GKeyFile
1718  * @group_name: a group name
1719  * @key: a key
1720  * @length: the number of booleans returned
1721  * @error: return location for a #GError
1722  *
1723  * Returns the values associated with @key under @group_name as
1724  * booleans.  If @key cannot be found then the return value is
1725  * undefined and @error is set to
1726  * #G_KEY_FILE_ERROR_KEY_NOT_FOUND. Likewise, if the values
1727  * associated with @key cannot be interpreted as booleans then
1728  * the return value is also undefined and @error is set to
1729  * #G_KEY_FILE_ERROR_INVALID_VALUE.
1730  *
1731  * Return value: the values associated with the key as a boolean
1732  **/
1733 gboolean *
1734 g_key_file_get_boolean_list (GKeyFile     *key_file,
1735                              const gchar  *group_name,
1736                              const gchar  *key,
1737                              gsize        *length,
1738                              GError      **error)
1739 {
1740   GError *key_file_error;
1741   gchar **values;
1742   gboolean *bool_values;
1743   gsize i, num_bools;
1744
1745   key_file_error = NULL;
1746
1747   values = g_key_file_get_string_list (key_file, group_name, key,
1748                                        &num_bools, &key_file_error);
1749
1750   if (key_file_error)
1751     g_propagate_error (error, key_file_error);
1752
1753   if (!values)
1754     return NULL;
1755
1756   bool_values = g_new (gboolean, num_bools);
1757
1758   for (i = 0; i < num_bools; i++)
1759     {
1760       bool_values[i] = g_key_file_parse_value_as_boolean (key_file,
1761                                                           values[i],
1762                                                           &key_file_error);
1763
1764       if (key_file_error)
1765         {
1766           g_propagate_error (error, key_file_error);
1767           g_strfreev (values);
1768           g_free (bool_values);
1769
1770           return NULL;
1771         }
1772     }
1773   g_strfreev (values);
1774
1775   if (length)
1776     *length = num_bools;
1777
1778   return bool_values;
1779 }
1780
1781 /**
1782  * g_key_file_set_boolean_list:
1783  * @key_file: a #GKeyFile
1784  * @group_name: a group name
1785  * @key: a key
1786  * @list: an array of boolean values
1787  * @length: length of @list
1788  *
1789  * Associates a list of boolean values with @key under
1790  * @group_name.  If @key cannot be found then it is created.
1791  *
1792  * Since: 2.6
1793  **/
1794 void
1795 g_key_file_set_boolean_list (GKeyFile    *key_file,
1796                              const gchar *group_name,
1797                              const gchar *key,
1798                              gboolean     list[],
1799                              gsize        length)
1800 {
1801   GString *value_list;
1802   gsize i;
1803
1804   g_return_if_fail (key_file != NULL);
1805   g_return_if_fail (key != NULL);
1806
1807   value_list = g_string_sized_new (length * 8);
1808   for (i = 0; i < length; i++)
1809     {
1810       gchar *value;
1811
1812       value = g_key_file_parse_boolean_as_value (key_file, list[i]);
1813
1814       g_string_append (value_list, value);
1815       g_string_append_c (value_list, key_file->list_separator);
1816
1817       g_free (value);
1818     }
1819
1820   g_key_file_set_value (key_file, group_name, key, value_list->str);
1821   g_string_free (value_list, TRUE);
1822 }
1823
1824 /**
1825  * g_key_file_get_integer:
1826  * @key_file: a #GKeyFile
1827  * @group_name: a group name
1828  * @key: a key
1829  * @error: return location for a #GError
1830  *
1831  * Returns the value associated with @key under @group_name as an
1832  * integer. If @key cannot be found then the return value is
1833  * undefined and @error is set to
1834  * #G_KEY_FILE_ERROR_KEY_NOT_FOUND. Likewise, if the value
1835  * associated with @key cannot be interpreted as an integer then
1836  * the return value is also undefined and @error is set to
1837  * #G_KEY_FILE_ERROR_INVALID_VALUE.
1838  *
1839  * Return value: the value associated with the key as an integer.
1840  * Since: 2.6
1841  **/
1842 gint
1843 g_key_file_get_integer (GKeyFile     *key_file,
1844                         const gchar  *group_name,
1845                         const gchar  *key,
1846                         GError      **error)
1847 {
1848   GError *key_file_error;
1849   gchar *value;
1850   gint int_value;
1851
1852   key_file_error = NULL;
1853
1854   value = g_key_file_get_value (key_file, group_name, key, &key_file_error);
1855
1856   if (key_file_error)
1857     {
1858       g_propagate_error (error, key_file_error);
1859       return 0;
1860     }
1861
1862   int_value = g_key_file_parse_value_as_integer (key_file, value,
1863                                                  &key_file_error);
1864   g_free (value);
1865
1866   if (key_file_error)
1867     {
1868       if (g_error_matches (key_file_error,
1869                            G_KEY_FILE_ERROR,
1870                            G_KEY_FILE_ERROR_INVALID_VALUE))
1871         {
1872           g_set_error (error, G_KEY_FILE_ERROR,
1873                        G_KEY_FILE_ERROR_INVALID_VALUE,
1874                        _("Key file contains key '%s' in group '%s' "
1875                          "which has value that cannot be interpreted."), key, 
1876                        group_name);
1877           g_error_free (key_file_error);
1878         }
1879       else
1880         g_propagate_error (error, key_file_error);
1881     }
1882
1883   return int_value;
1884 }
1885
1886 /**
1887  * g_key_file_set_integer:
1888  * @key_file: a #GKeyFile
1889  * @group_name: a group name
1890  * @key: a key
1891  * @value: an integer value
1892  *
1893  * Associates a new integer value with @key under @group_name.
1894  * If @key cannot be found then it is created.
1895  *
1896  * Since: 2.6
1897  **/
1898 void
1899 g_key_file_set_integer (GKeyFile    *key_file,
1900                         const gchar *group_name,
1901                         const gchar *key,
1902                         gint         value)
1903 {
1904   gchar *result;
1905
1906   g_return_if_fail (key_file != NULL);
1907   g_return_if_fail (key != NULL);
1908
1909   result = g_key_file_parse_integer_as_value (key_file, value);
1910   g_key_file_set_value (key_file, group_name, key, result);
1911   g_free (result);
1912 }
1913
1914 /**
1915  * g_key_file_get_integer_list:
1916  * @key_file: a #GKeyFile
1917  * @group_name: a group name
1918  * @key: a key
1919  * @length: the number of integers returned
1920  * @error: return location for a #GError
1921  *
1922  * Returns the values associated with @key under @group_name as
1923  * integers.  If @key cannot be found then the return value is
1924  * undefined and @error is set to
1925  * #G_KEY_FILE_ERROR_KEY_NOT_FOUND. Likewise, if the values
1926  * associated with @key cannot be interpreted as integers then
1927  * the return value is also undefined and @error is set to
1928  * #G_KEY_FILE_ERROR_INVALID_VALUE.
1929  *
1930  * Return value: the values associated with the key as a integer
1931  * Since: 2.6
1932  **/
1933 gint *
1934 g_key_file_get_integer_list (GKeyFile     *key_file,
1935                              const gchar  *group_name,
1936                              const gchar  *key,
1937                              gsize        *length,
1938                              GError      **error)
1939 {
1940   GError *key_file_error = NULL;
1941   gchar **values;
1942   gint *int_values;
1943   gsize i, num_ints;
1944
1945   values = g_key_file_get_string_list (key_file, group_name, key,
1946                                        &num_ints, &key_file_error);
1947
1948   if (key_file_error)
1949     g_propagate_error (error, key_file_error);
1950
1951   if (!values)
1952     return NULL;
1953
1954   int_values = g_new (gint, num_ints);
1955
1956   for (i = 0; i < num_ints; i++)
1957     {
1958       int_values[i] = g_key_file_parse_value_as_integer (key_file,
1959                                                          values[i],
1960                                                          &key_file_error);
1961
1962       if (key_file_error)
1963         {
1964           g_propagate_error (error, key_file_error);
1965           g_strfreev (values);
1966           g_free (int_values);
1967
1968           return NULL;
1969         }
1970     }
1971   g_strfreev (values);
1972
1973   if (length)
1974     *length = num_ints;
1975
1976   return int_values;
1977 }
1978
1979 /**
1980  * g_key_file_set_integer_list:
1981  * @key_file: a #GKeyFile
1982  * @group_name: a group name
1983  * @key: a key
1984  * @list: an array of integer values
1985  * @length: number of integer values in @list
1986  *
1987  * Associates a list of integer values with @key under
1988  * @group_name.  If @key cannot be found then it is created.
1989  *
1990  * Since: 2.6
1991  **/
1992 void
1993 g_key_file_set_integer_list (GKeyFile     *key_file,
1994                              const gchar  *group_name,
1995                              const gchar  *key,
1996                              gint          list[],
1997                              gsize         length)
1998 {
1999   GString *values;
2000   gsize i;
2001
2002   g_return_if_fail (key_file != NULL);
2003   g_return_if_fail (key != NULL);
2004
2005   values = g_string_sized_new (length * 16);
2006   for (i = 0; i < length; i++)
2007     {
2008       gchar *value;
2009
2010       value = g_key_file_parse_integer_as_value (key_file, list[i]);
2011
2012       g_string_append (values, value);
2013       g_string_append_c (values, ';');
2014
2015       g_free (value);
2016     }
2017
2018   g_key_file_set_value (key_file, group_name, key, values->str);
2019   g_string_free (values, TRUE);
2020 }
2021
2022 /**
2023  * g_key_file_has_group:
2024  * @key_file: a #GKeyFile
2025  * @group_name: a group name
2026  *
2027  * Looks whether the key file has the group @group_name.
2028  *
2029  * Return value: %TRUE if @group_name is a part of @key_file, %FALSE
2030  * otherwise.
2031  * Since: 2.6
2032  **/
2033 gboolean
2034 g_key_file_has_group (GKeyFile    *key_file,
2035                       const gchar *group_name)
2036 {
2037   GList *tmp;
2038   GKeyFileGroup *group;
2039
2040   g_return_val_if_fail (key_file != NULL, FALSE);
2041   g_return_val_if_fail (group_name != NULL, FALSE);
2042
2043   for (tmp = key_file->groups; tmp != NULL; tmp = tmp->next)
2044     {
2045       group = (GKeyFileGroup *) tmp->data;
2046       if (group && group->name && (strcmp (group->name, group_name) == 0))
2047         return TRUE;
2048     }
2049
2050   return FALSE;
2051 }
2052
2053 /**
2054  * g_key_file_has_key:
2055  * @key_file: a #GKeyFile
2056  * @group_name: a group name
2057  * @key: a key name
2058  * @error: return location for a #GError
2059  *
2060  * Looks whether the key file has the key @key in the group
2061  * @group_name.
2062  *
2063  * Return value: %TRUE if @key is a part of @group_name, %FALSE
2064  * otherwise.
2065  * Since: 2.6
2066  **/
2067 gboolean
2068 g_key_file_has_key (GKeyFile     *key_file,
2069                     const gchar  *group_name,
2070                     const gchar  *key,
2071                     GError      **error)
2072 {
2073   GKeyFileKeyValuePair *pair;
2074   GKeyFileGroup *group;
2075
2076   g_return_val_if_fail (key_file != NULL, FALSE);
2077   g_return_val_if_fail (key != NULL, FALSE);
2078
2079   pair = NULL;
2080
2081   if (group_name == NULL)
2082     group_name = (const gchar *) key_file->start_group_name;
2083
2084   group = g_key_file_lookup_group (key_file, group_name);
2085
2086   if (!group)
2087     {
2088       g_set_error (error, G_KEY_FILE_ERROR,
2089                    G_KEY_FILE_ERROR_GROUP_NOT_FOUND,
2090                    _("Key file does not have group '%s'"),
2091                    group_name);
2092
2093       return FALSE;
2094     }
2095
2096   pair = g_key_file_lookup_key_value_pair (key_file, group, key);
2097
2098   return pair != NULL;
2099 }
2100
2101 static void
2102 g_key_file_add_group (GKeyFile    *key_file,
2103                       const gchar *group_name)
2104 {
2105   GKeyFileGroup *group;
2106
2107   g_return_if_fail (key_file != NULL);
2108   g_return_if_fail (group_name != NULL);
2109   g_return_if_fail (g_key_file_lookup_group (key_file, group_name) == NULL);
2110
2111   group = g_new0 (GKeyFileGroup, 1);
2112   group->name = g_strdup (group_name);
2113   group->lookup_map = g_hash_table_new (g_str_hash, g_str_equal);
2114   key_file->groups = g_list_prepend (key_file->groups, group);
2115   key_file->approximate_size += strlen (group_name) + 3;
2116   key_file->current_group = group;
2117
2118   if (key_file->start_group_name == NULL)
2119     key_file->start_group_name = g_strdup (group_name);
2120 }
2121
2122
2123 static void
2124 g_key_file_key_value_pair_free (GKeyFileKeyValuePair *pair)
2125 {
2126   if (pair != NULL)
2127     {
2128       g_free (pair->key);
2129       g_free (pair->value);
2130       g_free (pair);
2131     }
2132 }
2133
2134 static void
2135 g_key_file_remove_group_node (GKeyFile *key_file,
2136                               GList    *group_node)
2137 {
2138   GKeyFileGroup *group;
2139
2140   group = (GKeyFileGroup *) group_node->data;
2141
2142   /* If the current group gets deleted make the current group the first
2143    * group.
2144    */
2145   if (key_file->current_group == group)
2146     {
2147       GList *first_group;
2148
2149       first_group = key_file->groups;
2150
2151       if (first_group)
2152         key_file->current_group = (GKeyFileGroup *) first_group->data;
2153       else
2154         key_file->current_group = NULL;
2155     }
2156
2157   key_file->groups = g_list_remove_link (key_file->groups, group_node);
2158
2159   if (group->name != NULL)
2160     key_file->approximate_size -= strlen (group->name) + 3;
2161
2162   /* FIXME: approximate_size isn't getting updated for the
2163    * removed keys in group.  
2164    */
2165   g_list_foreach (group->key_value_pairs, 
2166                   (GFunc) g_key_file_key_value_pair_free, NULL);
2167   g_list_free (group->key_value_pairs);
2168   group->key_value_pairs = NULL;
2169
2170   if (group->lookup_map)
2171     {
2172       g_hash_table_destroy (group->lookup_map);
2173       group->lookup_map = NULL;
2174     }
2175
2176   g_free ((gchar *) group->name);
2177   g_free (group);
2178   g_list_free_1 (group_node);
2179 }
2180
2181 /**
2182  * g_key_file_remove_group:
2183  * @key_file: a #GKeyFile
2184  * @group_name: a group name
2185  * @error: return location for a #GError or %NULL
2186  *
2187  * Removes the specified group, @group_name, 
2188  * from the key file. 
2189  *
2190  * Since: 2.6
2191  **/
2192 void
2193 g_key_file_remove_group (GKeyFile     *key_file,
2194                          const gchar  *group_name,
2195                          GError      **error)
2196 {
2197   GKeyFileGroup *group;
2198   GList *group_node;
2199
2200   g_return_if_fail (key_file != NULL);
2201   g_return_if_fail (group_name != NULL);
2202
2203   group = g_key_file_lookup_group (key_file, group_name);
2204
2205   if (!group)
2206     g_set_error (error, G_KEY_FILE_ERROR,
2207                  G_KEY_FILE_ERROR_GROUP_NOT_FOUND,
2208                  _("Key file does not have group '%s'"),
2209                  group_name);
2210
2211   group_node = g_list_find (key_file->groups, group);
2212   g_key_file_remove_group_node (key_file, group_node);
2213 }
2214
2215 static void
2216 g_key_file_add_key (GKeyFile    *key_file,
2217                     const gchar *group_name,
2218                     const gchar *key,
2219                     const gchar *value)
2220 {
2221   GKeyFileGroup *group;
2222   GKeyFileKeyValuePair *pair;
2223
2224   group = g_key_file_lookup_group (key_file, group_name);
2225
2226   if (!group)
2227     {
2228       g_key_file_add_group (key_file, group_name);
2229       group = (GKeyFileGroup *) key_file->groups->data;
2230     }
2231
2232   pair = g_new0 (GKeyFileKeyValuePair, 1);
2233
2234   pair->key = g_strdup (key);
2235   pair->value =  g_strdup (value);
2236
2237   g_hash_table_replace (group->lookup_map, pair->key, pair);
2238   group->key_value_pairs = g_list_prepend (group->key_value_pairs, pair);
2239   key_file->approximate_size += strlen (key) + strlen (value) + 2;
2240 }
2241
2242 /**
2243  * g_key_file_remove_key:
2244  * @key_file: a #GKeyFile
2245  * @group_name: a group name
2246  * @key: a key name to remove
2247  * @error: return location for a #GError or %NULL
2248  *
2249  * Removes @key in @group_name from the key file. 
2250  *
2251  * Since: 2.6
2252  **/
2253 void
2254 g_key_file_remove_key (GKeyFile     *key_file,
2255                        const gchar  *group_name,
2256                        const gchar  *key,
2257                        GError      **error)
2258 {
2259   GKeyFileGroup *group;
2260   GKeyFileKeyValuePair *pair;
2261
2262   pair = NULL;
2263
2264   if (group_name == NULL)
2265     group = key_file->current_group;
2266   else
2267     group = g_key_file_lookup_group (key_file, group_name);
2268
2269   if (!group)
2270     {
2271       g_set_error (error, G_KEY_FILE_ERROR,
2272                    G_KEY_FILE_ERROR_GROUP_NOT_FOUND,
2273                    _("Key file does not have group '%s'"),
2274                    group_name);
2275       return;
2276     }
2277
2278   group->key_value_pairs = g_list_remove (group->key_value_pairs, key_file);
2279   pair = g_key_file_lookup_key_value_pair (key_file, group, key);
2280
2281   if (!pair)
2282     {
2283       g_set_error (error, G_KEY_FILE_ERROR,
2284                    G_KEY_FILE_ERROR_KEY_NOT_FOUND,
2285                    _("Key file does not have key '%s'"), key);
2286       return;
2287     }
2288
2289   g_hash_table_remove (group->lookup_map, pair->key);
2290
2291   key_file->approximate_size -= strlen (pair->key) + strlen (pair->value) + 2;
2292   g_key_file_key_value_pair_free (pair);
2293 }
2294
2295 static GKeyFileGroup *
2296 g_key_file_lookup_group (GKeyFile    *key_file,
2297                          const gchar *group_name)
2298 {
2299   GKeyFileGroup *group;
2300   GList *tmp;
2301
2302   group = NULL;
2303   for (tmp = key_file->groups; tmp != NULL; tmp = tmp->next)
2304     {
2305       group = (GKeyFileGroup *) tmp->data;
2306
2307       if (group && group->name && strcmp (group->name, group_name) == 0)
2308         break;
2309
2310       group = NULL;
2311     }
2312
2313   return group;
2314 }
2315
2316 static GKeyFileKeyValuePair *
2317 g_key_file_lookup_key_value_pair (GKeyFile      *key_file,
2318                                   GKeyFileGroup *group,
2319                                   const gchar   *key)
2320 {
2321   return (GKeyFileKeyValuePair *) g_hash_table_lookup (group->lookup_map, key);
2322 }
2323
2324 /* Lines starting with # or consisting entirely of whitespace are merely
2325  * recorded, not parsed. This function assumes all leading whitespace
2326  * has been stripped.
2327  */
2328 static gboolean
2329 g_key_file_line_is_comment (const gchar *line)
2330 {
2331   return (*line == '#' || *line == '\0' || *line == '\n');
2332 }
2333
2334 /* A group in a key file is made up of a starting '[' followed by one
2335  * or more letters making up the group name followed by ']'.
2336  */
2337 static gboolean
2338 g_key_file_line_is_group (const gchar *line)
2339 {
2340   gchar *p;
2341
2342   p = (gchar *) line;
2343   if (*p != '[')
2344     return FALSE;
2345
2346   p = g_utf8_next_char (p);
2347
2348   if (!*p)
2349     return FALSE;
2350
2351   p = g_utf8_next_char (p);
2352
2353   /* Group name must be non-empty
2354    */
2355   if (*p == ']')
2356     return FALSE;
2357
2358   while (*p && *p != ']')
2359     p = g_utf8_next_char (p);
2360
2361   if (!*p)
2362     return FALSE;
2363
2364   return TRUE;
2365 }
2366
2367 static gboolean
2368 g_key_file_line_is_key_value_pair (const gchar *line)
2369 {
2370   gchar *p;
2371
2372   p = (gchar *) g_utf8_strchr (line, -1, '=');
2373
2374   if (!p)
2375     return FALSE;
2376
2377   /* Key must be non-empty
2378    */
2379   if (*p == line[0])
2380     return FALSE;
2381
2382   return TRUE;
2383 }
2384
2385 static gchar *
2386 g_key_file_parse_value_as_string (GKeyFile     *key_file,
2387                                   const gchar  *value,
2388                                   GSList      **pieces,
2389                                   GError      **error)
2390 {
2391   GError *parse_error = NULL;
2392   gchar *string_value, *p, *q0, *q;
2393
2394   string_value = g_new (gchar, strlen (value) + 1);
2395
2396   p = (gchar *) value;
2397   q0 = q = string_value;
2398   while (*p)
2399     {
2400       if (*p == '\\')
2401         {
2402           p++;
2403
2404           switch (*p)
2405             {
2406             case 's':
2407               *q = ' ';
2408               break;
2409
2410             case 'n':
2411               *q = '\n';
2412               break;
2413
2414             case 't':
2415               *q = '\t';
2416               break;
2417
2418             case 'r':
2419               *q = '\r';
2420               break;
2421
2422             case '\\':
2423               *q = '\\';
2424               break;
2425
2426             default:
2427               if (pieces && *p == key_file->list_separator)
2428                 *q = key_file->list_separator;
2429               else
2430                 {
2431                   *q++ = '\\';
2432                   *q = *p;
2433                   
2434                   if (parse_error == NULL)
2435                     {
2436                       gchar sequence[3];
2437                       
2438                       sequence[0] = '\\';
2439                       sequence[1] = *p;
2440                       sequence[2] = '\0';
2441                       
2442                       g_set_error (error, G_KEY_FILE_ERROR,
2443                                    G_KEY_FILE_ERROR_INVALID_VALUE,
2444                                    _("Key file contains invalid escape "
2445                                      "sequence '%s'"), sequence);
2446                     }
2447                 }
2448               break;
2449             }
2450         }
2451       else
2452         {
2453           *q = *p;
2454           if (pieces && (*p == key_file->list_separator))
2455             {
2456               *pieces = g_slist_prepend (*pieces, g_strndup (q0, q - q0));
2457               q0 = q + 1; 
2458             }
2459         }
2460
2461       q++;
2462       p++;
2463     }
2464
2465   if (p[-1] == '\\' && error == NULL)
2466     g_set_error (error, G_KEY_FILE_ERROR,
2467                  G_KEY_FILE_ERROR_INVALID_VALUE,
2468                  _("Key file contains escape character at end of line"));
2469
2470   *q = '\0';
2471   if (pieces)
2472   {
2473     if (q0 < q)
2474       *pieces = g_slist_prepend (*pieces, g_strndup (q0, q - q0));
2475     *pieces = g_slist_reverse (*pieces);
2476   }
2477
2478   return string_value;
2479 }
2480
2481 static gchar *
2482 g_key_file_parse_string_as_value (GKeyFile    *key_file,
2483                                   const gchar *string,
2484                                   gboolean     escape_separator)
2485 {
2486   gchar *value, *p, *q;
2487   gsize length;
2488
2489   length = strlen (string) + 1;
2490
2491   /* Worst case would be that every character needs to be escaped.
2492    * In other words every character turns to two characters
2493    */
2494   value = g_new (gchar, 2 * length);
2495
2496   p = (gchar *) string;
2497   q = value;
2498   while (p < (string + length - 1))
2499     {
2500       gchar escaped_character[3] = { '\\', 0, 0 };
2501
2502       switch (*p)
2503         {
2504         case ' ':
2505           escaped_character[1] = 's';
2506           strcpy (q, escaped_character);
2507           q += 2;
2508           break;
2509         case '\n':
2510           escaped_character[1] = 'n';
2511           strcpy (q, escaped_character);
2512           q += 2;
2513           break;
2514         case '\t':
2515           escaped_character[1] = 't';
2516           strcpy (q, escaped_character);
2517           q += 2;
2518           break;
2519         case '\r':
2520           escaped_character[1] = 'r';
2521           strcpy (q, escaped_character);
2522           q += 2;
2523           break;
2524         case '\\':
2525           escaped_character[1] = '\\';
2526           strcpy (q, escaped_character);
2527           q += 2;
2528           break;
2529         default:
2530           if (escape_separator && *p == key_file->list_separator)
2531             {
2532               escaped_character[1] = key_file->list_separator;
2533               strcpy (q, escaped_character);
2534               q += 2;
2535             }
2536           else 
2537             {
2538               *q = *p;
2539               q++;
2540             }
2541           break;
2542         }
2543       p++;
2544     }
2545   *q = '\0';
2546
2547   return value;
2548 }
2549
2550 static gint
2551 g_key_file_parse_value_as_integer (GKeyFile     *key_file,
2552                                    const gchar  *value,
2553                                    GError      **error)
2554 {
2555   gchar *end_of_valid_int;
2556   gint int_value = 0;
2557
2558   int_value = strtol (value, &end_of_valid_int, 0);
2559
2560   if (*end_of_valid_int != '\0')
2561     g_set_error (error, G_KEY_FILE_ERROR,
2562                  G_KEY_FILE_ERROR_INVALID_VALUE,
2563                  _("Value '%s' cannot be interpreted as a number."), value);
2564
2565   return int_value;
2566 }
2567
2568 static gchar *
2569 g_key_file_parse_integer_as_value (GKeyFile *key_file,
2570                                    gint      value)
2571
2572 {
2573   return g_strdup_printf ("%d", value);
2574 }
2575
2576 static gboolean
2577 g_key_file_parse_value_as_boolean (GKeyFile     *key_file,
2578                                    const gchar  *value,
2579                                    GError      **error)
2580 {
2581   if (value)
2582     {
2583       if (strcmp (value, "true") == 0 || strcmp (value, "1") == 0)
2584         return TRUE;
2585       else if (strcmp (value, "false") == 0 || strcmp (value, "0") == 0)
2586         return FALSE;
2587     }
2588
2589   g_set_error (error, G_KEY_FILE_ERROR,
2590                G_KEY_FILE_ERROR_INVALID_VALUE,
2591                _("Value '%s' cannot be interpreted as a boolean."), value);
2592
2593   return FALSE;
2594 }
2595
2596 static gchar *
2597 g_key_file_parse_boolean_as_value (GKeyFile *key_file,
2598                                    gboolean  value)
2599 {
2600   if (value)
2601     return g_strdup ("true");
2602   else
2603     return g_strdup ("false");
2604 }