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