653ac98322ba273e4db2b6db7b2f9dec06203241
[platform/upstream/glib.git] / glib / gkeyfile.c
1 /* gkeyfile.c - key file parser
2  *
3  *  Copyright 2004  Red Hat, Inc.  
4  *  Copyright 2009-2010  Collabora Ltd.
5  *  Copyright 2009  Nokia Corporation
6  *
7  * Written by Ray Strode <rstrode@redhat.com>
8  *            Matthias Clasen <mclasen@redhat.com>
9  *
10  * GLib is free software; you can redistribute it and/or modify it
11  * under the terms of the GNU Lesser General Public License as
12  * published by the Free Software Foundation; either version 2 of the
13  * License, or (at your option) any later version.
14  *
15  * GLib is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  * Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public
21  * License along with GLib; see the file COPYING.LIB.  If not,
22  * see <http://www.gnu.org/licenses/>.
23  */
24
25 #include "config.h"
26
27 #include "gkeyfile.h"
28 #include "gutils.h"
29
30 #include <errno.h>
31 #include <fcntl.h>
32 #include <locale.h>
33 #include <string.h>
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <sys/types.h>
37 #include <sys/stat.h>
38 #ifdef G_OS_UNIX
39 #include <unistd.h>
40 #endif
41 #ifdef G_OS_WIN32
42 #include <io.h>
43
44 #undef fstat
45 #define fstat(a,b) _fstati64(a,b)
46 #undef stat
47 #define stat _stati64
48
49 #ifndef S_ISREG
50 #define S_ISREG(mode) ((mode)&_S_IFREG)
51 #endif
52
53 #endif  /* G_OS_WIN23 */
54
55 #include "gconvert.h"
56 #include "gdataset.h"
57 #include "gerror.h"
58 #include "gfileutils.h"
59 #include "ghash.h"
60 #include "glibintl.h"
61 #include "glist.h"
62 #include "gslist.h"
63 #include "gmem.h"
64 #include "gmessages.h"
65 #include "gstdio.h"
66 #include "gstring.h"
67 #include "gstrfuncs.h"
68 #include "gutils.h"
69
70
71 /**
72  * SECTION:keyfile
73  * @title: Key-value file parser
74  * @short_description: parses .ini-like config files
75  *
76  * #GKeyFile lets you parse, edit or create files containing groups of
77  * key-value pairs, which we call <firstterm>key files</firstterm> for
78  * lack of a better name. Several freedesktop.org specifications use
79  * key files now, e.g the
80  * [Desktop Entry Specification](http://freedesktop.org/Standards/desktop-entry-spec)
81  * and the
82  * [Icon Theme Specification](http://freedesktop.org/Standards/icon-theme-spec).
83  *
84  * The syntax of key files is described in detail in the
85  * [Desktop Entry Specification](http://freedesktop.org/Standards/desktop-entry-spec),
86  * here is a quick summary: Key files
87  * consists of groups of key-value pairs, interspersed with comments.
88  *
89  * |[
90  * # this is just an example
91  * # there can be comments before the first group
92  *
93  * [First Group]
94  *
95  * Name=Key File Example\tthis value shows\nescaping
96  *
97  * # localized strings are stored in multiple key-value pairs
98  * Welcome=Hello
99  * Welcome[de]=Hallo
100  * Welcome[fr_FR]=Bonjour
101  * Welcome[it]=Ciao
102  * Welcome[be@latin]=Hello
103  *
104  * [Another Group]
105  *
106  * Numbers=2;20;-200;0
107  *
108  * Booleans=true;false;true;true
109  * ]|
110  *
111  * Lines beginning with a '#' and blank lines are considered comments.
112  *
113  * Groups are started by a header line containing the group name enclosed
114  * in '[' and ']', and ended implicitly by the start of the next group or
115  * the end of the file. Each key-value pair must be contained in a group.
116  *
117  * Key-value pairs generally have the form <literal>key=value</literal>,
118  * with the exception of localized strings, which have the form
119  * <literal>key[locale]=value</literal>, with a locale identifier of the
120  * form <literal>lang_COUNTRY\@MODIFIER</literal>
121  * where <literal>COUNTRY</literal> and <literal>MODIFIER</literal>
122  * are optional.
123  * Space before and after the '=' character are ignored. Newline, tab,
124  * carriage return and backslash characters in value are escaped as \n,
125  * \t, \r, and \\, respectively. To preserve leading spaces in values,
126  * these can also be escaped as \s.
127  *
128  * Key files can store strings (possibly with localized variants), integers,
129  * booleans and lists of these. Lists are separated by a separator character,
130  * typically ';' or ','. To use the list separator character in a value in
131  * a list, it has to be escaped by prefixing it with a backslash.
132  *
133  * This syntax is obviously inspired by the .ini files commonly met
134  * on Windows, but there are some important differences:
135  *
136  * - .ini files use the ';' character to begin comments,
137  *   key files use the '#' character.
138  *
139  * - Key files do not allow for ungrouped keys meaning only
140  *   comments can precede the first group.
141  *
142  * - Key files are always encoded in UTF-8.
143  *
144  * - Key and Group names are case-sensitive. For example, a group called
145  *   [GROUP] is a different from [group].
146  *
147  * - .ini files don't have a strongly typed boolean entry type,
148  *    they only have GetProfileInt(). In key files, only
149  *    true and false (in lower case) are allowed.
150  *
151  * Note that in contrast to the
152  * [Desktop Entry Specification](http://freedesktop.org/Standards/desktop-entry-spec),
153  * groups in key files may contain the same
154  * key multiple times; the last entry wins. Key files may also contain
155  * multiple groups with the same name; they are merged together.
156  * Another difference is that keys and group names in key files are not
157  * restricted to ASCII characters.
158  */
159
160 /**
161  * G_KEY_FILE_ERROR:
162  *
163  * Error domain for key file parsing. Errors in this domain will
164  * be from the #GKeyFileError enumeration.
165  *
166  * See #GError for information on error domains.
167  */
168
169 /**
170  * GKeyFileError:
171  * @G_KEY_FILE_ERROR_UNKNOWN_ENCODING: the text being parsed was in
172  *     an unknown encoding
173  * @G_KEY_FILE_ERROR_PARSE: document was ill-formed
174  * @G_KEY_FILE_ERROR_NOT_FOUND: the file was not found
175  * @G_KEY_FILE_ERROR_KEY_NOT_FOUND: a requested key was not found
176  * @G_KEY_FILE_ERROR_GROUP_NOT_FOUND: a requested group was not found
177  * @G_KEY_FILE_ERROR_INVALID_VALUE: a value could not be parsed
178  *
179  * Error codes returned by key file parsing.
180  */
181
182 /**
183  * GKeyFileFlags:
184  * @G_KEY_FILE_NONE: No flags, default behaviour
185  * @G_KEY_FILE_KEEP_COMMENTS: Use this flag if you plan to write the
186  *     (possibly modified) contents of the key file back to a file;
187  *     otherwise all comments will be lost when the key file is
188  *     written back.
189  * @G_KEY_FILE_KEEP_TRANSLATIONS: Use this flag if you plan to write the
190  *     (possibly modified) contents of the key file back to a file;
191  *     otherwise only the translations for the current language will be
192  *     written back.
193  *
194  * Flags which influence the parsing.
195  */
196
197 /**
198  * G_KEY_FILE_DESKTOP_GROUP:
199  *
200  * The name of the main group of a desktop entry file, as defined in the
201  * [Desktop Entry Specification](http://freedesktop.org/Standards/desktop-entry-spec).
202  * Consult the specification for more
203  * details about the meanings of the keys below.
204  *
205  * Since: 2.14
206  */
207
208 /**
209  * G_KEY_FILE_DESKTOP_KEY_TYPE:
210  *
211  * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a string
212  * giving the type of the desktop entry. Usually
213  * #G_KEY_FILE_DESKTOP_TYPE_APPLICATION,
214  * #G_KEY_FILE_DESKTOP_TYPE_LINK, or
215  * #G_KEY_FILE_DESKTOP_TYPE_DIRECTORY.
216  *
217  * Since: 2.14
218  */
219
220 /**
221  * G_KEY_FILE_DESKTOP_KEY_VERSION:
222  *
223  * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a string
224  * giving the version of the Desktop Entry Specification used for
225  * the desktop entry file.
226  *
227  * Since: 2.14
228  */
229
230 /**
231  * G_KEY_FILE_DESKTOP_KEY_NAME:
232  *
233  * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a localized
234  * string giving the specific name of the desktop entry.
235  *
236  * Since: 2.14
237  */
238
239 /**
240  * G_KEY_FILE_DESKTOP_KEY_GENERIC_NAME:
241  *
242  * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a localized
243  * string giving the generic name of the desktop entry.
244  *
245  * Since: 2.14
246  */
247
248 /**
249  * G_KEY_FILE_DESKTOP_KEY_NO_DISPLAY:
250  *
251  * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a boolean
252  * stating whether the desktop entry should be shown in menus.
253  *
254  * Since: 2.14
255  */
256
257 /**
258  * G_KEY_FILE_DESKTOP_KEY_COMMENT:
259  *
260  * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a localized
261  * string giving the tooltip for the desktop entry.
262  *
263  * Since: 2.14
264  */
265
266 /**
267  * G_KEY_FILE_DESKTOP_KEY_ICON:
268  *
269  * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a localized
270  * string giving the name of the icon to be displayed for the desktop
271  * entry.
272  *
273  * Since: 2.14
274  */
275
276 /**
277  * G_KEY_FILE_DESKTOP_KEY_HIDDEN:
278  *
279  * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a boolean
280  * stating whether the desktop entry has been deleted by the user.
281  *
282  * Since: 2.14
283  */
284
285 /**
286  * G_KEY_FILE_DESKTOP_KEY_ONLY_SHOW_IN:
287  *
288  * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a list of
289  * strings identifying the environments that should display the
290  * desktop entry.
291  *
292  * Since: 2.14
293  */
294
295 /**
296  * G_KEY_FILE_DESKTOP_KEY_NOT_SHOW_IN:
297  *
298  * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a list of
299  * strings identifying the environments that should not display the
300  * desktop entry.
301  *
302  * Since: 2.14
303  */
304
305 /**
306  * G_KEY_FILE_DESKTOP_KEY_TRY_EXEC:
307  *
308  * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a string
309  * giving the file name of a binary on disk used to determine if the
310  * program is actually installed. It is only valid for desktop entries
311  * with the <literal>Application</literal> type.
312  *
313  * Since: 2.14
314  */
315
316 /**
317  * G_KEY_FILE_DESKTOP_KEY_EXEC:
318  *
319  * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a string
320  * giving the command line to execute. It is only valid for desktop
321  * entries with the <literal>Application</literal> type.
322  *
323  * Since: 2.14
324  */
325
326  /**
327   * G_KEY_FILE_DESKTOP_KEY_PATH:
328   *
329   * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a string
330   * containing the working directory to run the program in. It is only
331   * valid for desktop entries with the <literal>Application</literal> type.
332   *
333   * Since: 2.14
334   */
335
336 /**
337  * G_KEY_FILE_DESKTOP_KEY_TERMINAL:
338  *
339  * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a boolean
340  * stating whether the program should be run in a terminal window.
341  * It is only valid for desktop entries with the
342  * <literal>Application</literal> type.
343  *
344  * Since: 2.14
345  */
346
347 /**
348  * G_KEY_FILE_DESKTOP_KEY_MIME_TYPE:
349  *
350  * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a list
351  * of strings giving the MIME types supported by this desktop entry.
352  *
353  * Since: 2.14
354  */
355
356 /**
357  * G_KEY_FILE_DESKTOP_KEY_CATEGORIES:
358  *
359  * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a list
360  * of strings giving the categories in which the desktop entry
361  * should be shown in a menu.
362  *
363  * Since: 2.14
364  */
365
366 /**
367  * G_KEY_FILE_DESKTOP_KEY_STARTUP_NOTIFY:
368  *
369  * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a boolean
370  * stating whether the application supports the
371  * [Startup Notification Protocol Specification](http://www.freedesktop.org/Standards/startup-notification-spec).
372  *
373  * Since: 2.14
374  */
375
376 /**
377  * G_KEY_FILE_DESKTOP_KEY_STARTUP_WM_CLASS:
378  *
379  * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is string
380  * identifying the WM class or name hint of a window that the application
381  * will create, which can be used to emulate Startup Notification with
382  * older applications.
383  *
384  * Since: 2.14
385  */
386
387 /**
388  * G_KEY_FILE_DESKTOP_KEY_URL :
389  *
390  * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a string
391  * giving the URL to access. It is only valid for desktop entries
392  * with the <literal>Link</literal> type.
393  *
394  * Since: 2.14
395  */
396
397 /**
398  * G_KEY_FILE_DESKTOP_TYPE_APPLICATION:
399  *
400  * The value of the #G_KEY_FILE_DESKTOP_KEY_TYPE, key for desktop
401  * entries representing applications.
402  *
403  * Since: 2.14
404  */
405
406 /**
407  * G_KEY_FILE_DESKTOP_TYPE_LINK:
408  *
409  * The value of the #G_KEY_FILE_DESKTOP_KEY_TYPE, key for desktop
410  * entries representing links to documents.
411  *
412  * Since: 2.14
413  */
414
415 /**
416  * G_KEY_FILE_DESKTOP_TYPE_DIRECTORY:
417  *
418  * The value of the #G_KEY_FILE_DESKTOP_KEY_TYPE, key for desktop
419  * entries representing directories.
420  *
421  * Since: 2.14
422  */
423
424 typedef struct _GKeyFileGroup GKeyFileGroup;
425
426 /**
427  * GKeyFile:
428  *
429  * The GKeyFile struct contains only private data
430  * and should not be accessed directly.
431  */
432 struct _GKeyFile
433 {
434   GList *groups;
435   GHashTable *group_hash;
436
437   GKeyFileGroup *start_group;
438   GKeyFileGroup *current_group;
439
440   GString *parse_buffer; /* Holds up to one line of not-yet-parsed data */
441
442   gchar list_separator;
443
444   GKeyFileFlags flags;
445
446   gchar **locales;
447
448   volatile gint ref_count;
449 };
450
451 typedef struct _GKeyFileKeyValuePair GKeyFileKeyValuePair;
452
453 struct _GKeyFileGroup
454 {
455   const gchar *name;  /* NULL for above first group (which will be comments) */
456
457   GKeyFileKeyValuePair *comment; /* Special comment that is stuck to the top of a group */
458
459   GList *key_value_pairs;
460
461   /* Used in parallel with key_value_pairs for
462    * increased lookup performance
463    */
464   GHashTable *lookup_map;
465 };
466
467 struct _GKeyFileKeyValuePair
468 {
469   gchar *key;  /* NULL for comments */
470   gchar *value;
471 };
472
473 static gint                  find_file_in_data_dirs            (const gchar            *file,
474                                                                 const gchar           **data_dirs,
475                                                                 gchar                 **output_file,
476                                                                 GError                **error);
477 static gboolean              g_key_file_load_from_fd           (GKeyFile               *key_file,
478                                                                 gint                    fd,
479                                                                 GKeyFileFlags           flags,
480                                                                 GError                **error);
481 static GList                *g_key_file_lookup_group_node      (GKeyFile               *key_file,
482                                                                 const gchar            *group_name);
483 static GKeyFileGroup        *g_key_file_lookup_group           (GKeyFile               *key_file,
484                                                                 const gchar            *group_name);
485
486 static GList                *g_key_file_lookup_key_value_pair_node  (GKeyFile       *key_file,
487                                                                      GKeyFileGroup  *group,
488                                                                      const gchar    *key);
489 static GKeyFileKeyValuePair *g_key_file_lookup_key_value_pair       (GKeyFile       *key_file,
490                                                                      GKeyFileGroup  *group,
491                                                                      const gchar    *key);
492
493 static void                  g_key_file_remove_group_node          (GKeyFile      *key_file,
494                                                                     GList         *group_node);
495 static void                  g_key_file_remove_key_value_pair_node (GKeyFile      *key_file,
496                                                                     GKeyFileGroup *group,
497                                                                     GList         *pair_node);
498
499 static void                  g_key_file_add_key_value_pair     (GKeyFile               *key_file,
500                                                                 GKeyFileGroup          *group,
501                                                                 GKeyFileKeyValuePair   *pair);
502 static void                  g_key_file_add_key                (GKeyFile               *key_file,
503                                                                 GKeyFileGroup          *group,
504                                                                 const gchar            *key,
505                                                                 const gchar            *value);
506 static void                  g_key_file_add_group              (GKeyFile               *key_file,
507                                                                 const gchar            *group_name);
508 static gboolean              g_key_file_is_group_name          (const gchar *name);
509 static gboolean              g_key_file_is_key_name            (const gchar *name);
510 static void                  g_key_file_key_value_pair_free    (GKeyFileKeyValuePair   *pair);
511 static gboolean              g_key_file_line_is_comment        (const gchar            *line);
512 static gboolean              g_key_file_line_is_group          (const gchar            *line);
513 static gboolean              g_key_file_line_is_key_value_pair (const gchar            *line);
514 static gchar                *g_key_file_parse_value_as_string  (GKeyFile               *key_file,
515                                                                 const gchar            *value,
516                                                                 GSList                **separators,
517                                                                 GError                **error);
518 static gchar                *g_key_file_parse_string_as_value  (GKeyFile               *key_file,
519                                                                 const gchar            *string,
520                                                                 gboolean                escape_separator);
521 static gint                  g_key_file_parse_value_as_integer (GKeyFile               *key_file,
522                                                                 const gchar            *value,
523                                                                 GError                **error);
524 static gchar                *g_key_file_parse_integer_as_value (GKeyFile               *key_file,
525                                                                 gint                    value);
526 static gdouble               g_key_file_parse_value_as_double  (GKeyFile               *key_file,
527                                                                 const gchar            *value,
528                                                                 GError                **error);
529 static gboolean              g_key_file_parse_value_as_boolean (GKeyFile               *key_file,
530                                                                 const gchar            *value,
531                                                                 GError                **error);
532 static gchar                *g_key_file_parse_boolean_as_value (GKeyFile               *key_file,
533                                                                 gboolean                value);
534 static gchar                *g_key_file_parse_value_as_comment (GKeyFile               *key_file,
535                                                                 const gchar            *value);
536 static gchar                *g_key_file_parse_comment_as_value (GKeyFile               *key_file,
537                                                                 const gchar            *comment);
538 static void                  g_key_file_parse_key_value_pair   (GKeyFile               *key_file,
539                                                                 const gchar            *line,
540                                                                 gsize                   length,
541                                                                 GError                **error);
542 static void                  g_key_file_parse_comment          (GKeyFile               *key_file,
543                                                                 const gchar            *line,
544                                                                 gsize                   length,
545                                                                 GError                **error);
546 static void                  g_key_file_parse_group            (GKeyFile               *key_file,
547                                                                 const gchar            *line,
548                                                                 gsize                   length,
549                                                                 GError                **error);
550 static gchar                *key_get_locale                    (const gchar            *key);
551 static void                  g_key_file_parse_data             (GKeyFile               *key_file,
552                                                                 const gchar            *data,
553                                                                 gsize                   length,
554                                                                 GError                **error);
555 static void                  g_key_file_flush_parse_buffer     (GKeyFile               *key_file,
556                                                                 GError                **error);
557
558 G_DEFINE_QUARK (g-key-file-error-quark, g_key_file_error)
559
560 static void
561 g_key_file_init (GKeyFile *key_file)
562 {  
563   key_file->current_group = g_slice_new0 (GKeyFileGroup);
564   key_file->groups = g_list_prepend (NULL, key_file->current_group);
565   key_file->group_hash = g_hash_table_new (g_str_hash, g_str_equal);
566   key_file->start_group = NULL;
567   key_file->parse_buffer = g_string_sized_new (128);
568   key_file->list_separator = ';';
569   key_file->flags = 0;
570   key_file->locales = g_strdupv ((gchar **)g_get_language_names ());
571 }
572
573 static void
574 g_key_file_clear (GKeyFile *key_file)
575 {
576   GList *tmp, *group_node;
577
578   if (key_file->locales) 
579     {
580       g_strfreev (key_file->locales);
581       key_file->locales = NULL;
582     }
583
584   if (key_file->parse_buffer)
585     {
586       g_string_free (key_file->parse_buffer, TRUE);
587       key_file->parse_buffer = NULL;
588     }
589
590   tmp = key_file->groups;
591   while (tmp != NULL)
592     {
593       group_node = tmp;
594       tmp = tmp->next;
595       g_key_file_remove_group_node (key_file, group_node);
596     }
597
598   if (key_file->group_hash != NULL)
599     {
600       g_hash_table_destroy (key_file->group_hash);
601       key_file->group_hash = NULL;
602     }
603
604   g_warn_if_fail (key_file->groups == NULL);
605 }
606
607
608 /**
609  * g_key_file_new:
610  *
611  * Creates a new empty #GKeyFile object. Use
612  * g_key_file_load_from_file(), g_key_file_load_from_data(),
613  * g_key_file_load_from_dirs() or g_key_file_load_from_data_dirs() to
614  * read an existing key file.
615  *
616  * Return value: (transfer full): an empty #GKeyFile.
617  *
618  * Since: 2.6
619  **/
620 GKeyFile *
621 g_key_file_new (void)
622 {
623   GKeyFile *key_file;
624
625   key_file = g_slice_new0 (GKeyFile);
626   key_file->ref_count = 1;
627   g_key_file_init (key_file);
628
629   return key_file;
630 }
631
632 /**
633  * g_key_file_set_list_separator:
634  * @key_file: a #GKeyFile 
635  * @separator: the separator
636  *
637  * Sets the character which is used to separate
638  * values in lists. Typically ';' or ',' are used
639  * as separators. The default list separator is ';'.
640  *
641  * Since: 2.6
642  */
643 void
644 g_key_file_set_list_separator (GKeyFile *key_file,
645                                gchar     separator)
646 {
647   g_return_if_fail (key_file != NULL);
648
649   key_file->list_separator = separator;
650 }
651
652
653 /* Iterates through all the directories in *dirs trying to
654  * open file.  When it successfully locates and opens a file it
655  * returns the file descriptor to the open file.  It also
656  * outputs the absolute path of the file in output_file.
657  */
658 static gint
659 find_file_in_data_dirs (const gchar   *file,
660                         const gchar  **dirs,
661                         gchar        **output_file,
662                         GError       **error)
663 {
664   const gchar **data_dirs, *data_dir;
665   gchar *path;
666   gint fd;
667
668   path = NULL;
669   fd = -1;
670
671   if (dirs == NULL)
672     return fd;
673
674   data_dirs = dirs;
675
676   while (data_dirs && (data_dir = *data_dirs) && fd == -1)
677     {
678       gchar *candidate_file, *sub_dir;
679
680       candidate_file = (gchar *) file;
681       sub_dir = g_strdup ("");
682       while (candidate_file != NULL && fd == -1)
683         {
684           gchar *p;
685
686           path = g_build_filename (data_dir, sub_dir,
687                                    candidate_file, NULL);
688
689           fd = g_open (path, O_RDONLY, 0);
690
691           if (fd == -1)
692             {
693               g_free (path);
694               path = NULL;
695             }
696
697           candidate_file = strchr (candidate_file, '-');
698
699           if (candidate_file == NULL)
700             break;
701
702           candidate_file++;
703
704           g_free (sub_dir);
705           sub_dir = g_strndup (file, candidate_file - file - 1);
706
707           for (p = sub_dir; *p != '\0'; p++)
708             {
709               if (*p == '-')
710                 *p = G_DIR_SEPARATOR;
711             }
712         }
713       g_free (sub_dir);
714       data_dirs++;
715     }
716
717   if (fd == -1)
718     {
719       g_set_error_literal (error, G_KEY_FILE_ERROR,
720                            G_KEY_FILE_ERROR_NOT_FOUND,
721                            _("Valid key file could not be "
722                              "found in search dirs"));
723     }
724
725   if (output_file != NULL && fd > 0)
726     *output_file = g_strdup (path);
727
728   g_free (path);
729
730   return fd;
731 }
732
733 static gboolean
734 g_key_file_load_from_fd (GKeyFile       *key_file,
735                          gint            fd,
736                          GKeyFileFlags   flags,
737                          GError        **error)
738 {
739   GError *key_file_error = NULL;
740   gssize bytes_read;
741   struct stat stat_buf;
742   gchar read_buf[4096];
743   gchar list_separator;
744
745   if (fstat (fd, &stat_buf) < 0)
746     {
747       g_set_error_literal (error, G_FILE_ERROR,
748                            g_file_error_from_errno (errno),
749                            g_strerror (errno));
750       return FALSE;
751     }
752
753   if (!S_ISREG (stat_buf.st_mode))
754     {
755       g_set_error_literal (error, G_KEY_FILE_ERROR,
756                            G_KEY_FILE_ERROR_PARSE,
757                            _("Not a regular file"));
758       return FALSE;
759     }
760
761   list_separator = key_file->list_separator;
762   g_key_file_clear (key_file);
763   g_key_file_init (key_file);
764   key_file->list_separator = list_separator;
765   key_file->flags = flags;
766
767   do
768     {
769       bytes_read = read (fd, read_buf, 4096);
770
771       if (bytes_read == 0)  /* End of File */
772         break;
773
774       if (bytes_read < 0)
775         {
776           if (errno == EINTR || errno == EAGAIN)
777             continue;
778
779           g_set_error_literal (error, G_FILE_ERROR,
780                                g_file_error_from_errno (errno),
781                                g_strerror (errno));
782           return FALSE;
783         }
784
785       g_key_file_parse_data (key_file,
786                              read_buf, bytes_read,
787                              &key_file_error);
788     }
789   while (!key_file_error);
790
791   if (key_file_error)
792     {
793       g_propagate_error (error, key_file_error);
794       return FALSE;
795     }
796
797   g_key_file_flush_parse_buffer (key_file, &key_file_error);
798
799   if (key_file_error)
800     {
801       g_propagate_error (error, key_file_error);
802       return FALSE;
803     }
804
805   return TRUE;
806 }
807
808 /**
809  * g_key_file_load_from_file:
810  * @key_file: an empty #GKeyFile struct
811  * @file: (type filename): the path of a filename to load, in the GLib filename encoding
812  * @flags: flags from #GKeyFileFlags
813  * @error: return location for a #GError, or %NULL
814  *
815  * Loads a key file into an empty #GKeyFile structure.
816  * If the file could not be loaded then @error is set to
817  * either a #GFileError or #GKeyFileError.
818  *
819  * Return value: %TRUE if a key file could be loaded, %FALSE otherwise
820  *
821  * Since: 2.6
822  **/
823 gboolean
824 g_key_file_load_from_file (GKeyFile       *key_file,
825                            const gchar    *file,
826                            GKeyFileFlags   flags,
827                            GError        **error)
828 {
829   GError *key_file_error = NULL;
830   gint fd;
831
832   g_return_val_if_fail (key_file != NULL, FALSE);
833   g_return_val_if_fail (file != NULL, FALSE);
834
835   fd = g_open (file, O_RDONLY, 0);
836
837   if (fd == -1)
838     {
839       g_set_error_literal (error, G_FILE_ERROR,
840                            g_file_error_from_errno (errno),
841                            g_strerror (errno));
842       return FALSE;
843     }
844
845   g_key_file_load_from_fd (key_file, fd, flags, &key_file_error);
846   close (fd);
847
848   if (key_file_error)
849     {
850       g_propagate_error (error, key_file_error);
851       return FALSE;
852     }
853
854   return TRUE;
855 }
856
857 /**
858  * g_key_file_load_from_data:
859  * @key_file: an empty #GKeyFile struct
860  * @data: key file loaded in memory
861  * @length: the length of @data in bytes (or (gsize)-1 if data is nul-terminated)
862  * @flags: flags from #GKeyFileFlags
863  * @error: return location for a #GError, or %NULL
864  *
865  * Loads a key file from memory into an empty #GKeyFile structure.  
866  * If the object cannot be created then %error is set to a #GKeyFileError. 
867  *
868  * Return value: %TRUE if a key file could be loaded, %FALSE otherwise
869  *
870  * Since: 2.6
871  **/
872 gboolean
873 g_key_file_load_from_data (GKeyFile       *key_file,
874                            const gchar    *data,
875                            gsize           length,
876                            GKeyFileFlags   flags,
877                            GError        **error)
878 {
879   GError *key_file_error = NULL;
880   gchar list_separator;
881
882   g_return_val_if_fail (key_file != NULL, FALSE);
883   g_return_val_if_fail (data != NULL || length == 0, FALSE);
884
885   if (length == (gsize)-1)
886     length = strlen (data);
887
888   list_separator = key_file->list_separator;
889   g_key_file_clear (key_file);
890   g_key_file_init (key_file);
891   key_file->list_separator = list_separator;
892   key_file->flags = flags;
893
894   g_key_file_parse_data (key_file, data, length, &key_file_error);
895   
896   if (key_file_error)
897     {
898       g_propagate_error (error, key_file_error);
899       return FALSE;
900     }
901
902   g_key_file_flush_parse_buffer (key_file, &key_file_error);
903   
904   if (key_file_error)
905     {
906       g_propagate_error (error, key_file_error);
907       return FALSE;
908     }
909
910   return TRUE;
911 }
912
913 /**
914  * g_key_file_load_from_dirs:
915  * @key_file: an empty #GKeyFile struct
916  * @file: (type filename): a relative path to a filename to open and parse
917  * @search_dirs: (array zero-terminated=1) (element-type filename): %NULL-terminated array of directories to search
918  * @full_path: (out) (type filename) (allow-none): return location for a string containing the full path
919  *   of the file, or %NULL
920  * @flags: flags from #GKeyFileFlags
921  * @error: return location for a #GError, or %NULL
922  *
923  * This function looks for a key file named @file in the paths
924  * specified in @search_dirs, loads the file into @key_file and
925  * returns the file's full path in @full_path.  If the file could not
926  * be loaded then an %error is set to either a #GFileError or
927  * #GKeyFileError.
928  *
929  * Return value: %TRUE if a key file could be loaded, %FALSE otherwise
930  *
931  * Since: 2.14
932  **/
933 gboolean
934 g_key_file_load_from_dirs (GKeyFile       *key_file,
935                            const gchar    *file,
936                            const gchar   **search_dirs,
937                            gchar         **full_path,
938                            GKeyFileFlags   flags,
939                            GError        **error)
940 {
941   GError *key_file_error = NULL;
942   const gchar **data_dirs;
943   gchar *output_path;
944   gint fd;
945   gboolean found_file;
946
947   g_return_val_if_fail (key_file != NULL, FALSE);
948   g_return_val_if_fail (!g_path_is_absolute (file), FALSE);
949   g_return_val_if_fail (search_dirs != NULL, FALSE);
950
951   found_file = FALSE;
952   data_dirs = search_dirs;
953   output_path = NULL;
954   while (*data_dirs != NULL && !found_file)
955     {
956       g_free (output_path);
957
958       fd = find_file_in_data_dirs (file, data_dirs, &output_path,
959                                    &key_file_error);
960
961       if (fd == -1)
962         {
963           if (key_file_error)
964             g_propagate_error (error, key_file_error);
965           break;
966         }
967
968       found_file = g_key_file_load_from_fd (key_file, fd, flags,
969                                             &key_file_error);
970       close (fd);
971
972       if (key_file_error)
973         {
974           g_propagate_error (error, key_file_error);
975           break;
976         }
977     }
978
979   if (found_file && full_path)
980     *full_path = output_path;
981   else
982     g_free (output_path);
983
984   return found_file;
985 }
986
987 /**
988  * g_key_file_load_from_data_dirs:
989  * @key_file: an empty #GKeyFile struct
990  * @file: (type filename): a relative path to a filename to open and parse
991  * @full_path: (out) (type filename) (allow-none): return location for a string containing the full path
992  *   of the file, or %NULL
993  * @flags: flags from #GKeyFileFlags 
994  * @error: return location for a #GError, or %NULL
995  *
996  * This function looks for a key file named @file in the paths 
997  * returned from g_get_user_data_dir() and g_get_system_data_dirs(), 
998  * loads the file into @key_file and returns the file's full path in 
999  * @full_path.  If the file could not be loaded then an %error is
1000  * set to either a #GFileError or #GKeyFileError.
1001  *
1002  * Return value: %TRUE if a key file could be loaded, %FALSE othewise
1003  * Since: 2.6
1004  **/
1005 gboolean
1006 g_key_file_load_from_data_dirs (GKeyFile       *key_file,
1007                                 const gchar    *file,
1008                                 gchar         **full_path,
1009                                 GKeyFileFlags   flags,
1010                                 GError        **error)
1011 {
1012   gchar **all_data_dirs;
1013   const gchar * user_data_dir;
1014   const gchar * const * system_data_dirs;
1015   gsize i, j;
1016   gboolean found_file;
1017
1018   g_return_val_if_fail (key_file != NULL, FALSE);
1019   g_return_val_if_fail (!g_path_is_absolute (file), FALSE);
1020
1021   user_data_dir = g_get_user_data_dir ();
1022   system_data_dirs = g_get_system_data_dirs ();
1023   all_data_dirs = g_new (gchar *, g_strv_length ((gchar **)system_data_dirs) + 2);
1024
1025   i = 0;
1026   all_data_dirs[i++] = g_strdup (user_data_dir);
1027
1028   j = 0;
1029   while (system_data_dirs[j] != NULL)
1030     all_data_dirs[i++] = g_strdup (system_data_dirs[j++]);
1031   all_data_dirs[i] = NULL;
1032
1033   found_file = g_key_file_load_from_dirs (key_file,
1034                                           file,
1035                                           (const gchar **)all_data_dirs,
1036                                           full_path,
1037                                           flags,
1038                                           error);
1039
1040   g_strfreev (all_data_dirs);
1041
1042   return found_file;
1043 }
1044
1045 /**
1046  * g_key_file_ref: (skip)
1047  * @key_file: a #GKeyFile
1048  *
1049  * Increases the reference count of @key_file.
1050  *
1051  * Returns: the same @key_file.
1052  *
1053  * Since: 2.32
1054  **/
1055 GKeyFile *
1056 g_key_file_ref (GKeyFile *key_file)
1057 {
1058   g_return_val_if_fail (key_file != NULL, NULL);
1059
1060   g_atomic_int_inc (&key_file->ref_count);
1061
1062   return key_file;
1063 }
1064
1065 /**
1066  * g_key_file_free: (skip)
1067  * @key_file: a #GKeyFile
1068  *
1069  * Clears all keys and groups from @key_file, and decreases the
1070  * reference count by 1. If the reference count reaches zero,
1071  * frees the key file and all its allocated memory.
1072  *
1073  * Since: 2.6
1074  **/
1075 void
1076 g_key_file_free (GKeyFile *key_file)
1077 {
1078   g_return_if_fail (key_file != NULL);
1079
1080   g_key_file_clear (key_file);
1081   g_key_file_unref (key_file);
1082 }
1083
1084 /**
1085  * g_key_file_unref:
1086  * @key_file: a #GKeyFile
1087  *
1088  * Decreases the reference count of @key_file by 1. If the reference count
1089  * reaches zero, frees the key file and all its allocated memory.
1090  *
1091  * Since: 2.32
1092  **/
1093 void
1094 g_key_file_unref (GKeyFile *key_file)
1095 {
1096   g_return_if_fail (key_file != NULL);
1097
1098   if (g_atomic_int_dec_and_test (&key_file->ref_count))
1099     {
1100       g_key_file_clear (key_file);
1101       g_slice_free (GKeyFile, key_file);
1102     }
1103 }
1104
1105 /* If G_KEY_FILE_KEEP_TRANSLATIONS is not set, only returns
1106  * true for locales that match those in g_get_language_names().
1107  */
1108 static gboolean
1109 g_key_file_locale_is_interesting (GKeyFile    *key_file,
1110                                   const gchar *locale)
1111 {
1112   gsize i;
1113
1114   if (key_file->flags & G_KEY_FILE_KEEP_TRANSLATIONS)
1115     return TRUE;
1116
1117   for (i = 0; key_file->locales[i] != NULL; i++)
1118     {
1119       if (g_ascii_strcasecmp (key_file->locales[i], locale) == 0)
1120         return TRUE;
1121     }
1122
1123   return FALSE;
1124 }
1125
1126 static void
1127 g_key_file_parse_line (GKeyFile     *key_file,
1128                        const gchar  *line,
1129                        gsize         length,
1130                        GError      **error)
1131 {
1132   GError *parse_error = NULL;
1133   gchar *line_start;
1134
1135   g_return_if_fail (key_file != NULL);
1136   g_return_if_fail (line != NULL);
1137
1138   line_start = (gchar *) line;
1139   while (g_ascii_isspace (*line_start))
1140     line_start++;
1141
1142   if (g_key_file_line_is_comment (line_start))
1143     g_key_file_parse_comment (key_file, line, length, &parse_error);
1144   else if (g_key_file_line_is_group (line_start))
1145     g_key_file_parse_group (key_file, line_start,
1146                             length - (line_start - line),
1147                             &parse_error);
1148   else if (g_key_file_line_is_key_value_pair (line_start))
1149     g_key_file_parse_key_value_pair (key_file, line_start,
1150                                      length - (line_start - line),
1151                                      &parse_error);
1152   else
1153     {
1154       gchar *line_utf8 = _g_utf8_make_valid (line);
1155       g_set_error (error, G_KEY_FILE_ERROR,
1156                    G_KEY_FILE_ERROR_PARSE,
1157                    _("Key file contains line '%s' which is not "
1158                      "a key-value pair, group, or comment"),
1159                    line_utf8);
1160       g_free (line_utf8);
1161
1162       return;
1163     }
1164
1165   if (parse_error)
1166     g_propagate_error (error, parse_error);
1167 }
1168
1169 static void
1170 g_key_file_parse_comment (GKeyFile     *key_file,
1171                           const gchar  *line,
1172                           gsize         length,
1173                           GError      **error)
1174 {
1175   GKeyFileKeyValuePair *pair;
1176   
1177   if (!(key_file->flags & G_KEY_FILE_KEEP_COMMENTS))
1178     return;
1179   
1180   g_warn_if_fail (key_file->current_group != NULL);
1181
1182   pair = g_slice_new (GKeyFileKeyValuePair);
1183   pair->key = NULL;
1184   pair->value = g_strndup (line, length);
1185   
1186   key_file->current_group->key_value_pairs =
1187     g_list_prepend (key_file->current_group->key_value_pairs, pair);
1188 }
1189
1190 static void
1191 g_key_file_parse_group (GKeyFile     *key_file,
1192                         const gchar  *line,
1193                         gsize         length,
1194                         GError      **error)
1195 {
1196   gchar *group_name;
1197   const gchar *group_name_start, *group_name_end;
1198   
1199   /* advance past opening '['
1200    */
1201   group_name_start = line + 1;
1202   group_name_end = line + length - 1;
1203   
1204   while (*group_name_end != ']')
1205     group_name_end--;
1206
1207   group_name = g_strndup (group_name_start, 
1208                           group_name_end - group_name_start);
1209   
1210   if (!g_key_file_is_group_name (group_name))
1211     {
1212       g_set_error (error, G_KEY_FILE_ERROR,
1213                    G_KEY_FILE_ERROR_PARSE,
1214                    _("Invalid group name: %s"), group_name);
1215       g_free (group_name);
1216       return;
1217     }
1218
1219   g_key_file_add_group (key_file, group_name);
1220   g_free (group_name);
1221 }
1222
1223 static void
1224 g_key_file_parse_key_value_pair (GKeyFile     *key_file,
1225                                  const gchar  *line,
1226                                  gsize         length,
1227                                  GError      **error)
1228 {
1229   gchar *key, *value, *key_end, *value_start, *locale;
1230   gsize key_len, value_len;
1231
1232   if (key_file->current_group == NULL || key_file->current_group->name == NULL)
1233     {
1234       g_set_error_literal (error, G_KEY_FILE_ERROR,
1235                            G_KEY_FILE_ERROR_GROUP_NOT_FOUND,
1236                            _("Key file does not start with a group"));
1237       return;
1238     }
1239
1240   key_end = value_start = strchr (line, '=');
1241
1242   g_warn_if_fail (key_end != NULL);
1243
1244   key_end--;
1245   value_start++;
1246
1247   /* Pull the key name from the line (chomping trailing whitespace)
1248    */
1249   while (g_ascii_isspace (*key_end))
1250     key_end--;
1251
1252   key_len = key_end - line + 2;
1253
1254   g_warn_if_fail (key_len <= length);
1255
1256   key = g_strndup (line, key_len - 1);
1257
1258   if (!g_key_file_is_key_name (key))
1259     {
1260       g_set_error (error, G_KEY_FILE_ERROR,
1261                    G_KEY_FILE_ERROR_PARSE,
1262                    _("Invalid key name: %s"), key);
1263       g_free (key);
1264       return; 
1265     }
1266
1267   /* Pull the value from the line (chugging leading whitespace)
1268    */
1269   while (g_ascii_isspace (*value_start))
1270     value_start++;
1271
1272   value_len = line + length - value_start + 1;
1273
1274   value = g_strndup (value_start, value_len);
1275
1276   g_warn_if_fail (key_file->start_group != NULL);
1277
1278   if (key_file->current_group
1279       && key_file->current_group->name
1280       && strcmp (key_file->start_group->name,
1281                  key_file->current_group->name) == 0
1282       && strcmp (key, "Encoding") == 0)
1283     {
1284       if (g_ascii_strcasecmp (value, "UTF-8") != 0)
1285         {
1286           gchar *value_utf8 = _g_utf8_make_valid (value);
1287           g_set_error (error, G_KEY_FILE_ERROR,
1288                        G_KEY_FILE_ERROR_UNKNOWN_ENCODING,
1289                        _("Key file contains unsupported "
1290                          "encoding '%s'"), value_utf8);
1291           g_free (value_utf8);
1292
1293           g_free (key);
1294           g_free (value);
1295           return;
1296         }
1297     }
1298
1299   /* Is this key a translation? If so, is it one that we care about?
1300    */
1301   locale = key_get_locale (key);
1302
1303   if (locale == NULL || g_key_file_locale_is_interesting (key_file, locale))
1304     {
1305       GKeyFileKeyValuePair *pair;
1306
1307       pair = g_slice_new (GKeyFileKeyValuePair);
1308       pair->key = key;
1309       pair->value = value;
1310
1311       g_key_file_add_key_value_pair (key_file, key_file->current_group, pair);
1312     }
1313   else
1314     {
1315       g_free (key);
1316       g_free (value);
1317     }
1318
1319   g_free (locale);
1320 }
1321
1322 static gchar *
1323 key_get_locale (const gchar *key)
1324 {
1325   gchar *locale;
1326
1327   locale = g_strrstr (key, "[");
1328
1329   if (locale && strlen (locale) <= 2)
1330     locale = NULL;
1331
1332   if (locale)
1333     locale = g_strndup (locale + 1, strlen (locale) - 2);
1334
1335   return locale;
1336 }
1337
1338 static void
1339 g_key_file_parse_data (GKeyFile     *key_file,
1340                        const gchar  *data,
1341                        gsize         length,
1342                        GError      **error)
1343 {
1344   GError *parse_error;
1345   gsize i;
1346
1347   g_return_if_fail (key_file != NULL);
1348   g_return_if_fail (data != NULL || length == 0);
1349
1350   parse_error = NULL;
1351
1352   i = 0;
1353   while (i < length)
1354     {
1355       if (data[i] == '\n')
1356         {
1357           if (key_file->parse_buffer->len > 0
1358               && (key_file->parse_buffer->str[key_file->parse_buffer->len - 1]
1359                   == '\r'))
1360             g_string_erase (key_file->parse_buffer,
1361                             key_file->parse_buffer->len - 1,
1362                             1);
1363             
1364           /* When a newline is encountered flush the parse buffer so that the
1365            * line can be parsed.  Note that completely blank lines won't show
1366            * up in the parse buffer, so they get parsed directly.
1367            */
1368           if (key_file->parse_buffer->len > 0)
1369             g_key_file_flush_parse_buffer (key_file, &parse_error);
1370           else
1371             g_key_file_parse_comment (key_file, "", 1, &parse_error);
1372
1373           if (parse_error)
1374             {
1375               g_propagate_error (error, parse_error);
1376               return;
1377             }
1378           i++;
1379         }
1380       else
1381         {
1382           const gchar *start_of_line;
1383           const gchar *end_of_line;
1384           gsize line_length;
1385
1386           start_of_line = data + i;
1387           end_of_line = memchr (start_of_line, '\n', length - i);
1388
1389           if (end_of_line == NULL)
1390             end_of_line = data + length;
1391
1392           line_length = end_of_line - start_of_line;
1393
1394           g_string_append_len (key_file->parse_buffer, start_of_line, line_length);
1395           i += line_length;
1396         }
1397     }
1398 }
1399
1400 static void
1401 g_key_file_flush_parse_buffer (GKeyFile  *key_file,
1402                                GError   **error)
1403 {
1404   GError *file_error = NULL;
1405
1406   g_return_if_fail (key_file != NULL);
1407
1408   file_error = NULL;
1409
1410   if (key_file->parse_buffer->len > 0)
1411     {
1412       g_key_file_parse_line (key_file, key_file->parse_buffer->str,
1413                              key_file->parse_buffer->len,
1414                              &file_error);
1415       g_string_erase (key_file->parse_buffer, 0, -1);
1416
1417       if (file_error)
1418         {
1419           g_propagate_error (error, file_error);
1420           return;
1421         }
1422     }
1423 }
1424
1425 /**
1426  * g_key_file_to_data:
1427  * @key_file: a #GKeyFile
1428  * @length: (out) (allow-none): return location for the length of the
1429  *   returned string, or %NULL
1430  * @error: return location for a #GError, or %NULL
1431  *
1432  * This function outputs @key_file as a string.  
1433  *
1434  * Note that this function never reports an error,
1435  * so it is safe to pass %NULL as @error.
1436  *
1437  * Return value: a newly allocated string holding
1438  *   the contents of the #GKeyFile 
1439  *
1440  * Since: 2.6
1441  **/
1442 gchar *
1443 g_key_file_to_data (GKeyFile  *key_file,
1444                     gsize     *length,
1445                     GError   **error)
1446 {
1447   GString *data_string;
1448   GList *group_node, *key_file_node;
1449
1450   g_return_val_if_fail (key_file != NULL, NULL);
1451
1452   data_string = g_string_new (NULL);
1453
1454   for (group_node = g_list_last (key_file->groups);
1455        group_node != NULL;
1456        group_node = group_node->prev)
1457     {
1458       GKeyFileGroup *group;
1459
1460       group = (GKeyFileGroup *) group_node->data;
1461
1462       /* separate groups by at least an empty line */
1463       if (data_string->len >= 2 &&
1464           data_string->str[data_string->len - 2] != '\n')
1465         g_string_append_c (data_string, '\n');
1466
1467       if (group->comment != NULL)
1468         g_string_append_printf (data_string, "%s\n", group->comment->value);
1469
1470       if (group->name != NULL)
1471         g_string_append_printf (data_string, "[%s]\n", group->name);
1472
1473       for (key_file_node = g_list_last (group->key_value_pairs);
1474            key_file_node != NULL;
1475            key_file_node = key_file_node->prev)
1476         {
1477           GKeyFileKeyValuePair *pair;
1478
1479           pair = (GKeyFileKeyValuePair *) key_file_node->data;
1480
1481           if (pair->key != NULL)
1482             g_string_append_printf (data_string, "%s=%s\n", pair->key, pair->value);
1483           else
1484             g_string_append_printf (data_string, "%s\n", pair->value);
1485         }
1486     }
1487
1488   if (length)
1489     *length = data_string->len;
1490
1491   return g_string_free (data_string, FALSE);
1492 }
1493
1494 /**
1495  * g_key_file_get_keys:
1496  * @key_file: a #GKeyFile
1497  * @group_name: a group name
1498  * @length: (out) (allow-none): return location for the number of keys returned, or %NULL
1499  * @error: return location for a #GError, or %NULL
1500  *
1501  * Returns all keys for the group name @group_name.  The array of
1502  * returned keys will be %NULL-terminated, so @length may
1503  * optionally be %NULL. In the event that the @group_name cannot
1504  * be found, %NULL is returned and @error is set to
1505  * #G_KEY_FILE_ERROR_GROUP_NOT_FOUND.
1506  *
1507  * Return value: (array zero-terminated=1) (transfer full): a newly-allocated %NULL-terminated array of strings.
1508  *     Use g_strfreev() to free it.
1509  *
1510  * Since: 2.6
1511  **/
1512 gchar **
1513 g_key_file_get_keys (GKeyFile     *key_file,
1514                      const gchar  *group_name,
1515                      gsize        *length,
1516                      GError      **error)
1517 {
1518   GKeyFileGroup *group;
1519   GList *tmp;
1520   gchar **keys;
1521   gsize i, num_keys;
1522   
1523   g_return_val_if_fail (key_file != NULL, NULL);
1524   g_return_val_if_fail (group_name != NULL, NULL);
1525   
1526   group = g_key_file_lookup_group (key_file, group_name);
1527   
1528   if (!group)
1529     {
1530       g_set_error (error, G_KEY_FILE_ERROR,
1531                    G_KEY_FILE_ERROR_GROUP_NOT_FOUND,
1532                    _("Key file does not have group '%s'"),
1533                    group_name ? group_name : "(null)");
1534       return NULL;
1535     }
1536
1537   num_keys = 0;
1538   for (tmp = group->key_value_pairs; tmp; tmp = tmp->next)
1539     {
1540       GKeyFileKeyValuePair *pair;
1541
1542       pair = (GKeyFileKeyValuePair *) tmp->data;
1543
1544       if (pair->key)
1545         num_keys++;
1546     }
1547   
1548   keys = g_new (gchar *, num_keys + 1);
1549
1550   i = num_keys - 1;
1551   for (tmp = group->key_value_pairs; tmp; tmp = tmp->next)
1552     {
1553       GKeyFileKeyValuePair *pair;
1554
1555       pair = (GKeyFileKeyValuePair *) tmp->data;
1556
1557       if (pair->key)
1558         {
1559           keys[i] = g_strdup (pair->key);
1560           i--;
1561         }
1562     }
1563
1564   keys[num_keys] = NULL;
1565
1566   if (length)
1567     *length = num_keys;
1568
1569   return keys;
1570 }
1571
1572 /**
1573  * g_key_file_get_start_group:
1574  * @key_file: a #GKeyFile
1575  *
1576  * Returns the name of the start group of the file. 
1577  *
1578  * Return value: The start group of the key file.
1579  *
1580  * Since: 2.6
1581  **/
1582 gchar *
1583 g_key_file_get_start_group (GKeyFile *key_file)
1584 {
1585   g_return_val_if_fail (key_file != NULL, NULL);
1586
1587   if (key_file->start_group)
1588     return g_strdup (key_file->start_group->name);
1589
1590   return NULL;
1591 }
1592
1593 /**
1594  * g_key_file_get_groups:
1595  * @key_file: a #GKeyFile
1596  * @length: (out) (allow-none): return location for the number of returned groups, or %NULL
1597  *
1598  * Returns all groups in the key file loaded with @key_file.  
1599  * The array of returned groups will be %NULL-terminated, so 
1600  * @length may optionally be %NULL.
1601  *
1602  * Return value: (array zero-terminated=1) (transfer full): a newly-allocated %NULL-terminated array of strings.
1603  *   Use g_strfreev() to free it.
1604  * Since: 2.6
1605  **/
1606 gchar **
1607 g_key_file_get_groups (GKeyFile *key_file,
1608                        gsize    *length)
1609 {
1610   GList *group_node;
1611   gchar **groups;
1612   gsize i, num_groups;
1613
1614   g_return_val_if_fail (key_file != NULL, NULL);
1615
1616   num_groups = g_list_length (key_file->groups);
1617
1618   g_return_val_if_fail (num_groups > 0, NULL);
1619
1620   group_node = g_list_last (key_file->groups);
1621   
1622   g_return_val_if_fail (((GKeyFileGroup *) group_node->data)->name == NULL, NULL);
1623
1624   /* Only need num_groups instead of num_groups + 1
1625    * because the first group of the file (last in the
1626    * list) is always the comment group at the top,
1627    * which we skip
1628    */
1629   groups = g_new (gchar *, num_groups);
1630
1631
1632   i = 0;
1633   for (group_node = group_node->prev;
1634        group_node != NULL;
1635        group_node = group_node->prev)
1636     {
1637       GKeyFileGroup *group;
1638
1639       group = (GKeyFileGroup *) group_node->data;
1640
1641       g_warn_if_fail (group->name != NULL);
1642
1643       groups[i++] = g_strdup (group->name);
1644     }
1645   groups[i] = NULL;
1646
1647   if (length)
1648     *length = i;
1649
1650   return groups;
1651 }
1652
1653 /**
1654  * g_key_file_get_value:
1655  * @key_file: a #GKeyFile
1656  * @group_name: a group name
1657  * @key: a key
1658  * @error: return location for a #GError, or %NULL
1659  *
1660  * Returns the raw value associated with @key under @group_name. 
1661  * Use g_key_file_get_string() to retrieve an unescaped UTF-8 string. 
1662  *
1663  * In the event the key cannot be found, %NULL is returned and 
1664  * @error is set to #G_KEY_FILE_ERROR_KEY_NOT_FOUND.  In the 
1665  * event that the @group_name cannot be found, %NULL is returned 
1666  * and @error is set to #G_KEY_FILE_ERROR_GROUP_NOT_FOUND.
1667  *
1668  *
1669  * Return value: a newly allocated string or %NULL if the specified 
1670  *  key cannot be found.
1671  *
1672  * Since: 2.6
1673  **/
1674 gchar *
1675 g_key_file_get_value (GKeyFile     *key_file,
1676                       const gchar  *group_name,
1677                       const gchar  *key,
1678                       GError      **error)
1679 {
1680   GKeyFileGroup *group;
1681   GKeyFileKeyValuePair *pair;
1682   gchar *value = NULL;
1683
1684   g_return_val_if_fail (key_file != NULL, NULL);
1685   g_return_val_if_fail (group_name != NULL, NULL);
1686   g_return_val_if_fail (key != NULL, NULL);
1687   
1688   group = g_key_file_lookup_group (key_file, group_name);
1689
1690   if (!group)
1691     {
1692       g_set_error (error, G_KEY_FILE_ERROR,
1693                    G_KEY_FILE_ERROR_GROUP_NOT_FOUND,
1694                    _("Key file does not have group '%s'"),
1695                    group_name ? group_name : "(null)");
1696       return NULL;
1697     }
1698
1699   pair = g_key_file_lookup_key_value_pair (key_file, group, key);
1700
1701   if (pair)
1702     value = g_strdup (pair->value);
1703   else
1704     g_set_error (error, G_KEY_FILE_ERROR,
1705                  G_KEY_FILE_ERROR_KEY_NOT_FOUND,
1706                  _("Key file does not have key '%s'"), key);
1707
1708   return value;
1709 }
1710
1711 /**
1712  * g_key_file_set_value:
1713  * @key_file: a #GKeyFile
1714  * @group_name: a group name
1715  * @key: a key
1716  * @value: a string
1717  *
1718  * Associates a new value with @key under @group_name.  
1719  *
1720  * If @key cannot be found then it is created. If @group_name cannot 
1721  * be found then it is created. To set an UTF-8 string which may contain 
1722  * characters that need escaping (such as newlines or spaces), use 
1723  * g_key_file_set_string().
1724  *
1725  * Since: 2.6
1726  **/
1727 void
1728 g_key_file_set_value (GKeyFile    *key_file,
1729                       const gchar *group_name,
1730                       const gchar *key,
1731                       const gchar *value)
1732 {
1733   GKeyFileGroup *group;
1734   GKeyFileKeyValuePair *pair;
1735
1736   g_return_if_fail (key_file != NULL);
1737   g_return_if_fail (g_key_file_is_group_name (group_name));
1738   g_return_if_fail (g_key_file_is_key_name (key));
1739   g_return_if_fail (value != NULL);
1740
1741   group = g_key_file_lookup_group (key_file, group_name);
1742
1743   if (!group)
1744     {
1745       g_key_file_add_group (key_file, group_name);
1746       group = (GKeyFileGroup *) key_file->groups->data;
1747
1748       g_key_file_add_key (key_file, group, key, value);
1749     }
1750   else
1751     {
1752       pair = g_key_file_lookup_key_value_pair (key_file, group, key);
1753
1754       if (!pair)
1755         g_key_file_add_key (key_file, group, key, value);
1756       else
1757         {
1758           g_free (pair->value);
1759           pair->value = g_strdup (value);
1760         }
1761     }
1762 }
1763
1764 /**
1765  * g_key_file_get_string:
1766  * @key_file: a #GKeyFile
1767  * @group_name: a group name
1768  * @key: a key
1769  * @error: return location for a #GError, or %NULL
1770  *
1771  * Returns the string value associated with @key under @group_name.
1772  * Unlike g_key_file_get_value(), this function handles escape sequences
1773  * like \s.
1774  *
1775  * In the event the key cannot be found, %NULL is returned and 
1776  * @error is set to #G_KEY_FILE_ERROR_KEY_NOT_FOUND.  In the 
1777  * event that the @group_name cannot be found, %NULL is returned 
1778  * and @error is set to #G_KEY_FILE_ERROR_GROUP_NOT_FOUND.
1779  *
1780  * Return value: a newly allocated string or %NULL if the specified 
1781  *   key cannot be found.
1782  *
1783  * Since: 2.6
1784  **/
1785 gchar *
1786 g_key_file_get_string (GKeyFile     *key_file,
1787                        const gchar  *group_name,
1788                        const gchar  *key,
1789                        GError      **error)
1790 {
1791   gchar *value, *string_value;
1792   GError *key_file_error;
1793
1794   g_return_val_if_fail (key_file != NULL, NULL);
1795   g_return_val_if_fail (group_name != NULL, NULL);
1796   g_return_val_if_fail (key != NULL, NULL);
1797
1798   key_file_error = NULL;
1799
1800   value = g_key_file_get_value (key_file, group_name, key, &key_file_error);
1801
1802   if (key_file_error)
1803     {
1804       g_propagate_error (error, key_file_error);
1805       return NULL;
1806     }
1807
1808   if (!g_utf8_validate (value, -1, NULL))
1809     {
1810       gchar *value_utf8 = _g_utf8_make_valid (value);
1811       g_set_error (error, G_KEY_FILE_ERROR,
1812                    G_KEY_FILE_ERROR_UNKNOWN_ENCODING,
1813                    _("Key file contains key '%s' with value '%s' "
1814                      "which is not UTF-8"), key, value_utf8);
1815       g_free (value_utf8);
1816       g_free (value);
1817
1818       return NULL;
1819     }
1820
1821   string_value = g_key_file_parse_value_as_string (key_file, value, NULL,
1822                                                    &key_file_error);
1823   g_free (value);
1824
1825   if (key_file_error)
1826     {
1827       if (g_error_matches (key_file_error,
1828                            G_KEY_FILE_ERROR,
1829                            G_KEY_FILE_ERROR_INVALID_VALUE))
1830         {
1831           g_set_error (error, G_KEY_FILE_ERROR,
1832                        G_KEY_FILE_ERROR_INVALID_VALUE,
1833                        _("Key file contains key '%s' "
1834                          "which has a value that cannot be interpreted."),
1835                        key);
1836           g_error_free (key_file_error);
1837         }
1838       else
1839         g_propagate_error (error, key_file_error);
1840     }
1841
1842   return string_value;
1843 }
1844
1845 /**
1846  * g_key_file_set_string:
1847  * @key_file: a #GKeyFile
1848  * @group_name: a group name
1849  * @key: a key
1850  * @string: a string
1851  *
1852  * Associates a new string value with @key under @group_name.  
1853  * If @key cannot be found then it is created.  
1854  * If @group_name cannot be found then it is created.
1855  * Unlike g_key_file_set_value(), this function handles characters
1856  * that need escaping, such as newlines.
1857  *
1858  * Since: 2.6
1859  **/
1860 void
1861 g_key_file_set_string (GKeyFile    *key_file,
1862                        const gchar *group_name,
1863                        const gchar *key,
1864                        const gchar *string)
1865 {
1866   gchar *value;
1867
1868   g_return_if_fail (key_file != NULL);
1869   g_return_if_fail (string != NULL);
1870
1871   value = g_key_file_parse_string_as_value (key_file, string, FALSE);
1872   g_key_file_set_value (key_file, group_name, key, value);
1873   g_free (value);
1874 }
1875
1876 /**
1877  * g_key_file_get_string_list:
1878  * @key_file: a #GKeyFile
1879  * @group_name: a group name
1880  * @key: a key
1881  * @length: (out) (allow-none): return location for the number of returned strings, or %NULL
1882  * @error: return location for a #GError, or %NULL
1883  *
1884  * Returns the values associated with @key under @group_name.
1885  *
1886  * In the event the key cannot be found, %NULL is returned and
1887  * @error is set to #G_KEY_FILE_ERROR_KEY_NOT_FOUND.  In the
1888  * event that the @group_name cannot be found, %NULL is returned
1889  * and @error is set to #G_KEY_FILE_ERROR_GROUP_NOT_FOUND.
1890  *
1891  * Return value: (array zero-terminated=1 length=length) (element-type utf8) (transfer full): 
1892  *  a %NULL-terminated string array or %NULL if the specified 
1893  *  key cannot be found. The array should be freed with g_strfreev().
1894  *
1895  * Since: 2.6
1896  **/
1897 gchar **
1898 g_key_file_get_string_list (GKeyFile     *key_file,
1899                             const gchar  *group_name,
1900                             const gchar  *key,
1901                             gsize        *length,
1902                             GError      **error)
1903 {
1904   GError *key_file_error = NULL;
1905   gchar *value, *string_value, **values;
1906   gint i, len;
1907   GSList *p, *pieces = NULL;
1908
1909   g_return_val_if_fail (key_file != NULL, NULL);
1910   g_return_val_if_fail (group_name != NULL, NULL);
1911   g_return_val_if_fail (key != NULL, NULL);
1912
1913   if (length)
1914     *length = 0;
1915
1916   value = g_key_file_get_value (key_file, group_name, key, &key_file_error);
1917
1918   if (key_file_error)
1919     {
1920       g_propagate_error (error, key_file_error);
1921       return NULL;
1922     }
1923
1924   if (!g_utf8_validate (value, -1, NULL))
1925     {
1926       gchar *value_utf8 = _g_utf8_make_valid (value);
1927       g_set_error (error, G_KEY_FILE_ERROR,
1928                    G_KEY_FILE_ERROR_UNKNOWN_ENCODING,
1929                    _("Key file contains key '%s' with value '%s' "
1930                      "which is not UTF-8"), key, value_utf8);
1931       g_free (value_utf8);
1932       g_free (value);
1933
1934       return NULL;
1935     }
1936
1937   string_value = g_key_file_parse_value_as_string (key_file, value, &pieces, &key_file_error);
1938   g_free (value);
1939   g_free (string_value);
1940
1941   if (key_file_error)
1942     {
1943       if (g_error_matches (key_file_error,
1944                            G_KEY_FILE_ERROR,
1945                            G_KEY_FILE_ERROR_INVALID_VALUE))
1946         {
1947           g_set_error (error, G_KEY_FILE_ERROR,
1948                        G_KEY_FILE_ERROR_INVALID_VALUE,
1949                        _("Key file contains key '%s' "
1950                          "which has a value that cannot be interpreted."),
1951                        key);
1952           g_error_free (key_file_error);
1953         }
1954       else
1955         g_propagate_error (error, key_file_error);
1956
1957       g_slist_free_full (pieces, g_free);
1958       return NULL;
1959     }
1960
1961   len = g_slist_length (pieces);
1962   values = g_new (gchar *, len + 1);
1963   for (p = pieces, i = 0; p; p = p->next)
1964     values[i++] = p->data;
1965   values[len] = NULL;
1966
1967   g_slist_free (pieces);
1968
1969   if (length)
1970     *length = len;
1971
1972   return values;
1973 }
1974
1975 /**
1976  * g_key_file_set_string_list:
1977  * @key_file: a #GKeyFile
1978  * @group_name: a group name
1979  * @key: a key
1980  * @list: (array zero-terminated=1 length=length) (element-type utf8): an array of string values
1981  * @length: number of string values in @list
1982  *
1983  * Associates a list of string values for @key under @group_name.
1984  * If @key cannot be found then it is created.
1985  * If @group_name cannot be found then it is created.
1986  *
1987  * Since: 2.6
1988  **/
1989 void
1990 g_key_file_set_string_list (GKeyFile            *key_file,
1991                             const gchar         *group_name,
1992                             const gchar         *key,
1993                             const gchar * const  list[],
1994                             gsize                length)
1995 {
1996   GString *value_list;
1997   gsize i;
1998
1999   g_return_if_fail (key_file != NULL);
2000   g_return_if_fail (list != NULL || length == 0);
2001
2002   value_list = g_string_sized_new (length * 128);
2003   for (i = 0; i < length && list[i] != NULL; i++)
2004     {
2005       gchar *value;
2006
2007       value = g_key_file_parse_string_as_value (key_file, list[i], TRUE);
2008       g_string_append (value_list, value);
2009       g_string_append_c (value_list, key_file->list_separator);
2010
2011       g_free (value);
2012     }
2013
2014   g_key_file_set_value (key_file, group_name, key, value_list->str);
2015   g_string_free (value_list, TRUE);
2016 }
2017
2018 /**
2019  * g_key_file_set_locale_string:
2020  * @key_file: a #GKeyFile
2021  * @group_name: a group name
2022  * @key: a key
2023  * @locale: a locale identifier
2024  * @string: a string
2025  *
2026  * Associates a string value for @key and @locale under @group_name.
2027  * If the translation for @key cannot be found then it is created.
2028  *
2029  * Since: 2.6
2030  **/
2031 void
2032 g_key_file_set_locale_string (GKeyFile     *key_file,
2033                               const gchar  *group_name,
2034                               const gchar  *key,
2035                               const gchar  *locale,
2036                               const gchar  *string)
2037 {
2038   gchar *full_key, *value;
2039
2040   g_return_if_fail (key_file != NULL);
2041   g_return_if_fail (key != NULL);
2042   g_return_if_fail (locale != NULL);
2043   g_return_if_fail (string != NULL);
2044
2045   value = g_key_file_parse_string_as_value (key_file, string, FALSE);
2046   full_key = g_strdup_printf ("%s[%s]", key, locale);
2047   g_key_file_set_value (key_file, group_name, full_key, value);
2048   g_free (full_key);
2049   g_free (value);
2050 }
2051
2052 /**
2053  * g_key_file_get_locale_string:
2054  * @key_file: a #GKeyFile
2055  * @group_name: a group name
2056  * @key: a key
2057  * @locale: (allow-none): a locale identifier or %NULL
2058  * @error: return location for a #GError, or %NULL
2059  *
2060  * Returns the value associated with @key under @group_name
2061  * translated in the given @locale if available.  If @locale is
2062  * %NULL then the current locale is assumed. 
2063  *
2064  * If @key cannot be found then %NULL is returned and @error is set 
2065  * to #G_KEY_FILE_ERROR_KEY_NOT_FOUND. If the value associated
2066  * with @key cannot be interpreted or no suitable translation can
2067  * be found then the untranslated value is returned.
2068  *
2069  * Return value: a newly allocated string or %NULL if the specified 
2070  *   key cannot be found.
2071  *
2072  * Since: 2.6
2073  **/
2074 gchar *
2075 g_key_file_get_locale_string (GKeyFile     *key_file,
2076                               const gchar  *group_name,
2077                               const gchar  *key,
2078                               const gchar  *locale,
2079                               GError      **error)
2080 {
2081   gchar *candidate_key, *translated_value;
2082   GError *key_file_error;
2083   gchar **languages;
2084   gboolean free_languages = FALSE;
2085   gint i;
2086
2087   g_return_val_if_fail (key_file != NULL, NULL);
2088   g_return_val_if_fail (group_name != NULL, NULL);
2089   g_return_val_if_fail (key != NULL, NULL);
2090
2091   candidate_key = NULL;
2092   translated_value = NULL;
2093   key_file_error = NULL;
2094
2095   if (locale)
2096     {
2097       languages = g_get_locale_variants (locale);
2098       free_languages = TRUE;
2099     }
2100   else
2101     {
2102       languages = (gchar **) g_get_language_names ();
2103       free_languages = FALSE;
2104     }
2105   
2106   for (i = 0; languages[i]; i++)
2107     {
2108       candidate_key = g_strdup_printf ("%s[%s]", key, languages[i]);
2109       
2110       translated_value = g_key_file_get_string (key_file,
2111                                                 group_name,
2112                                                 candidate_key, NULL);
2113       g_free (candidate_key);
2114
2115       if (translated_value)
2116         break;
2117
2118       g_free (translated_value);
2119       translated_value = NULL;
2120    }
2121
2122   /* Fallback to untranslated key
2123    */
2124   if (!translated_value)
2125     {
2126       translated_value = g_key_file_get_string (key_file, group_name, key,
2127                                                 &key_file_error);
2128       
2129       if (!translated_value)
2130         g_propagate_error (error, key_file_error);
2131     }
2132
2133   if (free_languages)
2134     g_strfreev (languages);
2135
2136   return translated_value;
2137 }
2138
2139 /**
2140  * g_key_file_get_locale_string_list:
2141  * @key_file: a #GKeyFile
2142  * @group_name: a group name
2143  * @key: a key
2144  * @locale: (allow-none): a locale identifier or %NULL
2145  * @length: (out) (allow-none): return location for the number of returned strings or %NULL
2146  * @error: return location for a #GError or %NULL
2147  *
2148  * Returns the values associated with @key under @group_name
2149  * translated in the given @locale if available.  If @locale is
2150  * %NULL then the current locale is assumed.
2151
2152  * If @key cannot be found then %NULL is returned and @error is set 
2153  * to #G_KEY_FILE_ERROR_KEY_NOT_FOUND. If the values associated
2154  * with @key cannot be interpreted or no suitable translations
2155  * can be found then the untranslated values are returned. The 
2156  * returned array is %NULL-terminated, so @length may optionally 
2157  * be %NULL.
2158  *
2159  * Return value: (array zero-terminated=1 length=length) (element-type utf8) (transfer full): a newly allocated %NULL-terminated string array
2160  *   or %NULL if the key isn't found. The string array should be freed
2161  *   with g_strfreev().
2162  *
2163  * Since: 2.6
2164  **/
2165 gchar **
2166 g_key_file_get_locale_string_list (GKeyFile     *key_file,
2167                                    const gchar  *group_name,
2168                                    const gchar  *key,
2169                                    const gchar  *locale,
2170                                    gsize        *length,
2171                                    GError      **error)
2172 {
2173   GError *key_file_error;
2174   gchar **values, *value;
2175   char list_separator[2];
2176   gsize len;
2177
2178   g_return_val_if_fail (key_file != NULL, NULL);
2179   g_return_val_if_fail (group_name != NULL, NULL);
2180   g_return_val_if_fail (key != NULL, NULL);
2181
2182   key_file_error = NULL;
2183
2184   value = g_key_file_get_locale_string (key_file, group_name, 
2185                                         key, locale,
2186                                         &key_file_error);
2187   
2188   if (key_file_error)
2189     g_propagate_error (error, key_file_error);
2190   
2191   if (!value)
2192     {
2193       if (length)
2194         *length = 0;
2195       return NULL;
2196     }
2197
2198   len = strlen (value);
2199   if (value[len - 1] == key_file->list_separator)
2200     value[len - 1] = '\0';
2201
2202   list_separator[0] = key_file->list_separator;
2203   list_separator[1] = '\0';
2204   values = g_strsplit (value, list_separator, 0);
2205
2206   g_free (value);
2207
2208   if (length)
2209     *length = g_strv_length (values);
2210
2211   return values;
2212 }
2213
2214 /**
2215  * g_key_file_set_locale_string_list:
2216  * @key_file: a #GKeyFile
2217  * @group_name: a group name
2218  * @key: a key
2219  * @locale: a locale identifier
2220  * @list: (array zero-terminated=1 length=length): a %NULL-terminated array of locale string values
2221  * @length: the length of @list
2222  *
2223  * Associates a list of string values for @key and @locale under
2224  * @group_name.  If the translation for @key cannot be found then
2225  * it is created. 
2226  *
2227  * Since: 2.6
2228  **/
2229 void
2230 g_key_file_set_locale_string_list (GKeyFile            *key_file,
2231                                    const gchar         *group_name,
2232                                    const gchar         *key,
2233                                    const gchar         *locale,
2234                                    const gchar * const  list[],
2235                                    gsize                length)
2236 {
2237   GString *value_list;
2238   gchar *full_key;
2239   gsize i;
2240
2241   g_return_if_fail (key_file != NULL);
2242   g_return_if_fail (key != NULL);
2243   g_return_if_fail (locale != NULL);
2244   g_return_if_fail (length != 0);
2245
2246   value_list = g_string_sized_new (length * 128);
2247   for (i = 0; i < length && list[i] != NULL; i++)
2248     {
2249       gchar *value;
2250       
2251       value = g_key_file_parse_string_as_value (key_file, list[i], TRUE);
2252       g_string_append (value_list, value);
2253       g_string_append_c (value_list, key_file->list_separator);
2254
2255       g_free (value);
2256     }
2257
2258   full_key = g_strdup_printf ("%s[%s]", key, locale);
2259   g_key_file_set_value (key_file, group_name, full_key, value_list->str);
2260   g_free (full_key);
2261   g_string_free (value_list, TRUE);
2262 }
2263
2264 /**
2265  * g_key_file_get_boolean:
2266  * @key_file: a #GKeyFile
2267  * @group_name: a group name
2268  * @key: a key
2269  * @error: return location for a #GError
2270  *
2271  * Returns the value associated with @key under @group_name as a
2272  * boolean. 
2273  *
2274  * If @key cannot be found then %FALSE is returned and @error is set
2275  * to #G_KEY_FILE_ERROR_KEY_NOT_FOUND. Likewise, if the value
2276  * associated with @key cannot be interpreted as a boolean then %FALSE
2277  * is returned and @error is set to #G_KEY_FILE_ERROR_INVALID_VALUE.
2278  *
2279  * Return value: the value associated with the key as a boolean, 
2280  *    or %FALSE if the key was not found or could not be parsed.
2281  *
2282  * Since: 2.6
2283  **/
2284 gboolean
2285 g_key_file_get_boolean (GKeyFile     *key_file,
2286                         const gchar  *group_name,
2287                         const gchar  *key,
2288                         GError      **error)
2289 {
2290   GError *key_file_error = NULL;
2291   gchar *value;
2292   gboolean bool_value;
2293
2294   g_return_val_if_fail (key_file != NULL, FALSE);
2295   g_return_val_if_fail (group_name != NULL, FALSE);
2296   g_return_val_if_fail (key != NULL, FALSE);
2297
2298   value = g_key_file_get_value (key_file, group_name, key, &key_file_error);
2299
2300   if (!value)
2301     {
2302       g_propagate_error (error, key_file_error);
2303       return FALSE;
2304     }
2305
2306   bool_value = g_key_file_parse_value_as_boolean (key_file, value,
2307                                                   &key_file_error);
2308   g_free (value);
2309
2310   if (key_file_error)
2311     {
2312       if (g_error_matches (key_file_error,
2313                            G_KEY_FILE_ERROR,
2314                            G_KEY_FILE_ERROR_INVALID_VALUE))
2315         {
2316           g_set_error (error, G_KEY_FILE_ERROR,
2317                        G_KEY_FILE_ERROR_INVALID_VALUE,
2318                        _("Key file contains key '%s' "
2319                          "which has a value that cannot be interpreted."),
2320                        key);
2321           g_error_free (key_file_error);
2322         }
2323       else
2324         g_propagate_error (error, key_file_error);
2325     }
2326
2327   return bool_value;
2328 }
2329
2330 /**
2331  * g_key_file_set_boolean:
2332  * @key_file: a #GKeyFile
2333  * @group_name: a group name
2334  * @key: a key
2335  * @value: %TRUE or %FALSE
2336  *
2337  * Associates a new boolean value with @key under @group_name.
2338  * If @key cannot be found then it is created. 
2339  *
2340  * Since: 2.6
2341  **/
2342 void
2343 g_key_file_set_boolean (GKeyFile    *key_file,
2344                         const gchar *group_name,
2345                         const gchar *key,
2346                         gboolean     value)
2347 {
2348   gchar *result;
2349
2350   g_return_if_fail (key_file != NULL);
2351
2352   result = g_key_file_parse_boolean_as_value (key_file, value);
2353   g_key_file_set_value (key_file, group_name, key, result);
2354   g_free (result);
2355 }
2356
2357 /**
2358  * g_key_file_get_boolean_list:
2359  * @key_file: a #GKeyFile
2360  * @group_name: a group name
2361  * @key: a key
2362  * @length: (out): the number of booleans returned
2363  * @error: return location for a #GError
2364  *
2365  * Returns the values associated with @key under @group_name as
2366  * booleans. 
2367  *
2368  * If @key cannot be found then %NULL is returned and @error is set to
2369  * #G_KEY_FILE_ERROR_KEY_NOT_FOUND. Likewise, if the values associated
2370  * with @key cannot be interpreted as booleans then %NULL is returned
2371  * and @error is set to #G_KEY_FILE_ERROR_INVALID_VALUE.
2372  *
2373  * Return value: (array length=length) (element-type gboolean) (transfer container):
2374  *    the values associated with the key as a list of booleans, or %NULL if the
2375  *    key was not found or could not be parsed. The returned list of booleans
2376  *    should be freed with g_free() when no longer needed.
2377  * 
2378  * Since: 2.6
2379  **/
2380 gboolean *
2381 g_key_file_get_boolean_list (GKeyFile     *key_file,
2382                              const gchar  *group_name,
2383                              const gchar  *key,
2384                              gsize        *length,
2385                              GError      **error)
2386 {
2387   GError *key_file_error;
2388   gchar **values;
2389   gboolean *bool_values;
2390   gsize i, num_bools;
2391
2392   g_return_val_if_fail (key_file != NULL, NULL);
2393   g_return_val_if_fail (group_name != NULL, NULL);
2394   g_return_val_if_fail (key != NULL, NULL);
2395
2396   if (length)
2397     *length = 0;
2398
2399   key_file_error = NULL;
2400
2401   values = g_key_file_get_string_list (key_file, group_name, key,
2402                                        &num_bools, &key_file_error);
2403
2404   if (key_file_error)
2405     g_propagate_error (error, key_file_error);
2406
2407   if (!values)
2408     return NULL;
2409
2410   bool_values = g_new (gboolean, num_bools);
2411
2412   for (i = 0; i < num_bools; i++)
2413     {
2414       bool_values[i] = g_key_file_parse_value_as_boolean (key_file,
2415                                                           values[i],
2416                                                           &key_file_error);
2417
2418       if (key_file_error)
2419         {
2420           g_propagate_error (error, key_file_error);
2421           g_strfreev (values);
2422           g_free (bool_values);
2423
2424           return NULL;
2425         }
2426     }
2427   g_strfreev (values);
2428
2429   if (length)
2430     *length = num_bools;
2431
2432   return bool_values;
2433 }
2434
2435 /**
2436  * g_key_file_set_boolean_list:
2437  * @key_file: a #GKeyFile
2438  * @group_name: a group name
2439  * @key: a key
2440  * @list: (array length=length): an array of boolean values
2441  * @length: length of @list
2442  *
2443  * Associates a list of boolean values with @key under @group_name.  
2444  * If @key cannot be found then it is created.
2445  * If @group_name is %NULL, the start_group is used.
2446  *
2447  * Since: 2.6
2448  **/
2449 void
2450 g_key_file_set_boolean_list (GKeyFile    *key_file,
2451                              const gchar *group_name,
2452                              const gchar *key,
2453                              gboolean     list[],
2454                              gsize        length)
2455 {
2456   GString *value_list;
2457   gsize i;
2458
2459   g_return_if_fail (key_file != NULL);
2460   g_return_if_fail (list != NULL);
2461
2462   value_list = g_string_sized_new (length * 8);
2463   for (i = 0; i < length; i++)
2464     {
2465       gchar *value;
2466
2467       value = g_key_file_parse_boolean_as_value (key_file, list[i]);
2468
2469       g_string_append (value_list, value);
2470       g_string_append_c (value_list, key_file->list_separator);
2471
2472       g_free (value);
2473     }
2474
2475   g_key_file_set_value (key_file, group_name, key, value_list->str);
2476   g_string_free (value_list, TRUE);
2477 }
2478
2479 /**
2480  * g_key_file_get_integer:
2481  * @key_file: a #GKeyFile
2482  * @group_name: a group name
2483  * @key: a key
2484  * @error: return location for a #GError
2485  *
2486  * Returns the value associated with @key under @group_name as an
2487  * integer. 
2488  *
2489  * If @key cannot be found then 0 is returned and @error is set to
2490  * #G_KEY_FILE_ERROR_KEY_NOT_FOUND. Likewise, if the value associated
2491  * with @key cannot be interpreted as an integer then 0 is returned
2492  * and @error is set to #G_KEY_FILE_ERROR_INVALID_VALUE.
2493  *
2494  * Return value: the value associated with the key as an integer, or
2495  *     0 if the key was not found or could not be parsed.
2496  *
2497  * Since: 2.6
2498  **/
2499 gint
2500 g_key_file_get_integer (GKeyFile     *key_file,
2501                         const gchar  *group_name,
2502                         const gchar  *key,
2503                         GError      **error)
2504 {
2505   GError *key_file_error;
2506   gchar *value;
2507   gint int_value;
2508
2509   g_return_val_if_fail (key_file != NULL, -1);
2510   g_return_val_if_fail (group_name != NULL, -1);
2511   g_return_val_if_fail (key != NULL, -1);
2512
2513   key_file_error = NULL;
2514
2515   value = g_key_file_get_value (key_file, group_name, key, &key_file_error);
2516
2517   if (key_file_error)
2518     {
2519       g_propagate_error (error, key_file_error);
2520       return 0;
2521     }
2522
2523   int_value = g_key_file_parse_value_as_integer (key_file, value,
2524                                                  &key_file_error);
2525   g_free (value);
2526
2527   if (key_file_error)
2528     {
2529       if (g_error_matches (key_file_error,
2530                            G_KEY_FILE_ERROR,
2531                            G_KEY_FILE_ERROR_INVALID_VALUE))
2532         {
2533           g_set_error (error, G_KEY_FILE_ERROR,
2534                        G_KEY_FILE_ERROR_INVALID_VALUE,
2535                        _("Key file contains key '%s' in group '%s' "
2536                          "which has a value that cannot be interpreted."),
2537                          key, group_name);
2538           g_error_free (key_file_error);
2539         }
2540       else
2541         g_propagate_error (error, key_file_error);
2542     }
2543
2544   return int_value;
2545 }
2546
2547 /**
2548  * g_key_file_set_integer:
2549  * @key_file: a #GKeyFile
2550  * @group_name: a group name
2551  * @key: a key
2552  * @value: an integer value
2553  *
2554  * Associates a new integer value with @key under @group_name.
2555  * If @key cannot be found then it is created.
2556  *
2557  * Since: 2.6
2558  **/
2559 void
2560 g_key_file_set_integer (GKeyFile    *key_file,
2561                         const gchar *group_name,
2562                         const gchar *key,
2563                         gint         value)
2564 {
2565   gchar *result;
2566
2567   g_return_if_fail (key_file != NULL);
2568
2569   result = g_key_file_parse_integer_as_value (key_file, value);
2570   g_key_file_set_value (key_file, group_name, key, result);
2571   g_free (result);
2572 }
2573
2574 /**
2575  * g_key_file_get_int64:
2576  * @key_file: a non-%NULL #GKeyFile
2577  * @group_name: a non-%NULL group name
2578  * @key: a non-%NULL key
2579  * @error: return location for a #GError
2580  *
2581  * Returns the value associated with @key under @group_name as a signed
2582  * 64-bit integer. This is similar to g_key_file_get_integer() but can return
2583  * 64-bit results without truncation.
2584  *
2585  * Returns: the value associated with the key as a signed 64-bit integer, or
2586  * 0 if the key was not found or could not be parsed.
2587  *
2588  * Since: 2.26
2589  */
2590 gint64
2591 g_key_file_get_int64 (GKeyFile     *key_file,
2592                       const gchar  *group_name,
2593                       const gchar  *key,
2594                       GError      **error)
2595 {
2596   gchar *s, *end;
2597   gint64 v;
2598
2599   g_return_val_if_fail (key_file != NULL, -1);
2600   g_return_val_if_fail (group_name != NULL, -1);
2601   g_return_val_if_fail (key != NULL, -1);
2602
2603   s = g_key_file_get_value (key_file, group_name, key, error);
2604
2605   if (s == NULL)
2606     return 0;
2607
2608   v = g_ascii_strtoll (s, &end, 10);
2609
2610   if (*s == '\0' || *end != '\0')
2611     {
2612       g_set_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE,
2613                    _("Key '%s' in group '%s' has value '%s' "
2614                      "where %s was expected"),
2615                    key, group_name, s, "int64");
2616       g_free (s);
2617       return 0;
2618     }
2619
2620   g_free (s);
2621   return v;
2622 }
2623
2624 /**
2625  * g_key_file_set_int64:
2626  * @key_file: a #GKeyFile
2627  * @group_name: a group name
2628  * @key: a key
2629  * @value: an integer value
2630  *
2631  * Associates a new integer value with @key under @group_name.
2632  * If @key cannot be found then it is created.
2633  *
2634  * Since: 2.26
2635  **/
2636 void
2637 g_key_file_set_int64 (GKeyFile    *key_file,
2638                       const gchar *group_name,
2639                       const gchar *key,
2640                       gint64       value)
2641 {
2642   gchar *result;
2643
2644   g_return_if_fail (key_file != NULL);
2645
2646   result = g_strdup_printf ("%" G_GINT64_FORMAT, value);
2647   g_key_file_set_value (key_file, group_name, key, result);
2648   g_free (result);
2649 }
2650
2651 /**
2652  * g_key_file_get_uint64:
2653  * @key_file: a non-%NULL #GKeyFile
2654  * @group_name: a non-%NULL group name
2655  * @key: a non-%NULL key
2656  * @error: return location for a #GError
2657  *
2658  * Returns the value associated with @key under @group_name as an unsigned
2659  * 64-bit integer. This is similar to g_key_file_get_integer() but can return
2660  * large positive results without truncation.
2661  *
2662  * Returns: the value associated with the key as an unsigned 64-bit integer,
2663  * or 0 if the key was not found or could not be parsed.
2664  *
2665  * Since: 2.26
2666  */
2667 guint64
2668 g_key_file_get_uint64 (GKeyFile     *key_file,
2669                        const gchar  *group_name,
2670                        const gchar  *key,
2671                        GError      **error)
2672 {
2673   gchar *s, *end;
2674   guint64 v;
2675
2676   g_return_val_if_fail (key_file != NULL, -1);
2677   g_return_val_if_fail (group_name != NULL, -1);
2678   g_return_val_if_fail (key != NULL, -1);
2679
2680   s = g_key_file_get_value (key_file, group_name, key, error);
2681
2682   if (s == NULL)
2683     return 0;
2684
2685   v = g_ascii_strtoull (s, &end, 10);
2686
2687   if (*s == '\0' || *end != '\0')
2688     {
2689       g_set_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE,
2690                    _("Key '%s' in group '%s' has value '%s' "
2691                      "where %s was expected"),
2692                    key, group_name, s, "uint64");
2693       g_free (s);
2694       return 0;
2695     }
2696
2697   g_free (s);
2698   return v;
2699 }
2700
2701 /**
2702  * g_key_file_set_uint64:
2703  * @key_file: a #GKeyFile
2704  * @group_name: a group name
2705  * @key: a key
2706  * @value: an integer value
2707  *
2708  * Associates a new integer value with @key under @group_name.
2709  * If @key cannot be found then it is created.
2710  *
2711  * Since: 2.26
2712  **/
2713 void
2714 g_key_file_set_uint64 (GKeyFile    *key_file,
2715                        const gchar *group_name,
2716                        const gchar *key,
2717                        guint64      value)
2718 {
2719   gchar *result;
2720
2721   g_return_if_fail (key_file != NULL);
2722
2723   result = g_strdup_printf ("%" G_GUINT64_FORMAT, value);
2724   g_key_file_set_value (key_file, group_name, key, result);
2725   g_free (result);
2726 }
2727
2728 /**
2729  * g_key_file_get_integer_list:
2730  * @key_file: a #GKeyFile
2731  * @group_name: a group name
2732  * @key: a key
2733  * @length: (out): the number of integers returned
2734  * @error: return location for a #GError
2735  *
2736  * Returns the values associated with @key under @group_name as
2737  * integers. 
2738  *
2739  * If @key cannot be found then %NULL is returned and @error is set to
2740  * #G_KEY_FILE_ERROR_KEY_NOT_FOUND. Likewise, if the values associated
2741  * with @key cannot be interpreted as integers then %NULL is returned
2742  * and @error is set to #G_KEY_FILE_ERROR_INVALID_VALUE.
2743  *
2744  * Return value: (array length=length) (element-type gint) (transfer container):
2745  *     the values associated with the key as a list of integers, or %NULL if
2746  *     the key was not found or could not be parsed. The returned list of
2747  *     integers should be freed with g_free() when no longer needed.
2748  *
2749  * Since: 2.6
2750  **/
2751 gint *
2752 g_key_file_get_integer_list (GKeyFile     *key_file,
2753                              const gchar  *group_name,
2754                              const gchar  *key,
2755                              gsize        *length,
2756                              GError      **error)
2757 {
2758   GError *key_file_error = NULL;
2759   gchar **values;
2760   gint *int_values;
2761   gsize i, num_ints;
2762
2763   g_return_val_if_fail (key_file != NULL, NULL);
2764   g_return_val_if_fail (group_name != NULL, NULL);
2765   g_return_val_if_fail (key != NULL, NULL);
2766
2767   if (length)
2768     *length = 0;
2769
2770   values = g_key_file_get_string_list (key_file, group_name, key,
2771                                        &num_ints, &key_file_error);
2772
2773   if (key_file_error)
2774     g_propagate_error (error, key_file_error);
2775
2776   if (!values)
2777     return NULL;
2778
2779   int_values = g_new (gint, num_ints);
2780
2781   for (i = 0; i < num_ints; i++)
2782     {
2783       int_values[i] = g_key_file_parse_value_as_integer (key_file,
2784                                                          values[i],
2785                                                          &key_file_error);
2786
2787       if (key_file_error)
2788         {
2789           g_propagate_error (error, key_file_error);
2790           g_strfreev (values);
2791           g_free (int_values);
2792
2793           return NULL;
2794         }
2795     }
2796   g_strfreev (values);
2797
2798   if (length)
2799     *length = num_ints;
2800
2801   return int_values;
2802 }
2803
2804 /**
2805  * g_key_file_set_integer_list:
2806  * @key_file: a #GKeyFile
2807  * @group_name: a group name
2808  * @key: a key
2809  * @list: (array length=length): an array of integer values
2810  * @length: number of integer values in @list
2811  *
2812  * Associates a list of integer values with @key under @group_name.  
2813  * If @key cannot be found then it is created.
2814  *
2815  * Since: 2.6
2816  **/
2817 void
2818 g_key_file_set_integer_list (GKeyFile    *key_file,
2819                              const gchar *group_name,
2820                              const gchar *key,
2821                              gint         list[],
2822                              gsize        length)
2823 {
2824   GString *values;
2825   gsize i;
2826
2827   g_return_if_fail (key_file != NULL);
2828   g_return_if_fail (list != NULL);
2829
2830   values = g_string_sized_new (length * 16);
2831   for (i = 0; i < length; i++)
2832     {
2833       gchar *value;
2834
2835       value = g_key_file_parse_integer_as_value (key_file, list[i]);
2836
2837       g_string_append (values, value);
2838       g_string_append_c (values, key_file->list_separator);
2839
2840       g_free (value);
2841     }
2842
2843   g_key_file_set_value (key_file, group_name, key, values->str);
2844   g_string_free (values, TRUE);
2845 }
2846
2847 /**
2848  * g_key_file_get_double:
2849  * @key_file: a #GKeyFile
2850  * @group_name: a group name
2851  * @key: a key
2852  * @error: return location for a #GError
2853  *
2854  * Returns the value associated with @key under @group_name as a
2855  * double. If @group_name is %NULL, the start_group is used.
2856  *
2857  * If @key cannot be found then 0.0 is returned and @error is set to
2858  * #G_KEY_FILE_ERROR_KEY_NOT_FOUND. Likewise, if the value associated
2859  * with @key cannot be interpreted as a double then 0.0 is returned
2860  * and @error is set to #G_KEY_FILE_ERROR_INVALID_VALUE.
2861  *
2862  * Return value: the value associated with the key as a double, or
2863  *     0.0 if the key was not found or could not be parsed.
2864  *
2865  * Since: 2.12
2866  **/
2867 gdouble
2868 g_key_file_get_double  (GKeyFile     *key_file,
2869                         const gchar  *group_name,
2870                         const gchar  *key,
2871                         GError      **error)
2872 {
2873   GError *key_file_error;
2874   gchar *value;
2875   gdouble double_value;
2876
2877   g_return_val_if_fail (key_file != NULL, -1);
2878   g_return_val_if_fail (group_name != NULL, -1);
2879   g_return_val_if_fail (key != NULL, -1);
2880
2881   key_file_error = NULL;
2882
2883   value = g_key_file_get_value (key_file, group_name, key, &key_file_error);
2884
2885   if (key_file_error)
2886     {
2887       g_propagate_error (error, key_file_error);
2888       return 0;
2889     }
2890
2891   double_value = g_key_file_parse_value_as_double (key_file, value,
2892                                                   &key_file_error);
2893   g_free (value);
2894
2895   if (key_file_error)
2896     {
2897       if (g_error_matches (key_file_error,
2898                            G_KEY_FILE_ERROR,
2899                            G_KEY_FILE_ERROR_INVALID_VALUE))
2900         {
2901           g_set_error (error, G_KEY_FILE_ERROR,
2902                        G_KEY_FILE_ERROR_INVALID_VALUE,
2903                        _("Key file contains key '%s' in group '%s' "
2904                          "which has a value that cannot be interpreted."),
2905                        key, group_name);
2906           g_error_free (key_file_error);
2907         }
2908       else
2909         g_propagate_error (error, key_file_error);
2910     }
2911
2912   return double_value;
2913 }
2914
2915 /**
2916  * g_key_file_set_double:
2917  * @key_file: a #GKeyFile
2918  * @group_name: a group name
2919  * @key: a key
2920  * @value: an double value
2921  *
2922  * Associates a new double value with @key under @group_name.
2923  * If @key cannot be found then it is created. 
2924  *
2925  * Since: 2.12
2926  **/
2927 void
2928 g_key_file_set_double  (GKeyFile    *key_file,
2929                         const gchar *group_name,
2930                         const gchar *key,
2931                         gdouble      value)
2932 {
2933   gchar result[G_ASCII_DTOSTR_BUF_SIZE];
2934
2935   g_return_if_fail (key_file != NULL);
2936
2937   g_ascii_dtostr (result, sizeof (result), value);
2938   g_key_file_set_value (key_file, group_name, key, result);
2939 }
2940
2941 /**
2942  * g_key_file_get_double_list:
2943  * @key_file: a #GKeyFile
2944  * @group_name: a group name
2945  * @key: a key
2946  * @length: (out): the number of doubles returned
2947  * @error: return location for a #GError
2948  *
2949  * Returns the values associated with @key under @group_name as
2950  * doubles. 
2951  *
2952  * If @key cannot be found then %NULL is returned and @error is set to
2953  * #G_KEY_FILE_ERROR_KEY_NOT_FOUND. Likewise, if the values associated
2954  * with @key cannot be interpreted as doubles then %NULL is returned
2955  * and @error is set to #G_KEY_FILE_ERROR_INVALID_VALUE.
2956  *
2957  * Return value: (array length=length) (element-type gdouble) (transfer container):
2958  *     the values associated with the key as a list of doubles, or %NULL if the
2959  *     key was not found or could not be parsed. The returned list of doubles
2960  *     should be freed with g_free() when no longer needed.
2961  *
2962  * Since: 2.12
2963  **/
2964 gdouble *
2965 g_key_file_get_double_list  (GKeyFile     *key_file,
2966                              const gchar  *group_name,
2967                              const gchar  *key,
2968                              gsize        *length,
2969                              GError      **error)
2970 {
2971   GError *key_file_error = NULL;
2972   gchar **values;
2973   gdouble *double_values;
2974   gsize i, num_doubles;
2975
2976   g_return_val_if_fail (key_file != NULL, NULL);
2977   g_return_val_if_fail (group_name != NULL, NULL);
2978   g_return_val_if_fail (key != NULL, NULL);
2979
2980   if (length)
2981     *length = 0;
2982
2983   values = g_key_file_get_string_list (key_file, group_name, key,
2984                                        &num_doubles, &key_file_error);
2985
2986   if (key_file_error)
2987     g_propagate_error (error, key_file_error);
2988
2989   if (!values)
2990     return NULL;
2991
2992   double_values = g_new (gdouble, num_doubles);
2993
2994   for (i = 0; i < num_doubles; i++)
2995     {
2996       double_values[i] = g_key_file_parse_value_as_double (key_file,
2997                                                            values[i],
2998                                                            &key_file_error);
2999
3000       if (key_file_error)
3001         {
3002           g_propagate_error (error, key_file_error);
3003           g_strfreev (values);
3004           g_free (double_values);
3005
3006           return NULL;
3007         }
3008     }
3009   g_strfreev (values);
3010
3011   if (length)
3012     *length = num_doubles;
3013
3014   return double_values;
3015 }
3016
3017 /**
3018  * g_key_file_set_double_list:
3019  * @key_file: a #GKeyFile
3020  * @group_name: a group name
3021  * @key: a key
3022  * @list: (array length=length): an array of double values
3023  * @length: number of double values in @list
3024  *
3025  * Associates a list of double values with @key under
3026  * @group_name.  If @key cannot be found then it is created.
3027  *
3028  * Since: 2.12
3029  **/
3030 void
3031 g_key_file_set_double_list (GKeyFile    *key_file,
3032                             const gchar *group_name,
3033                             const gchar *key,
3034                             gdouble      list[],
3035                             gsize        length)
3036 {
3037   GString *values;
3038   gsize i;
3039
3040   g_return_if_fail (key_file != NULL);
3041   g_return_if_fail (list != NULL);
3042
3043   values = g_string_sized_new (length * 16);
3044   for (i = 0; i < length; i++)
3045     {
3046       gchar result[G_ASCII_DTOSTR_BUF_SIZE];
3047
3048       g_ascii_dtostr( result, sizeof (result), list[i] );
3049
3050       g_string_append (values, result);
3051       g_string_append_c (values, key_file->list_separator);
3052     }
3053
3054   g_key_file_set_value (key_file, group_name, key, values->str);
3055   g_string_free (values, TRUE);
3056 }
3057
3058 static gboolean
3059 g_key_file_set_key_comment (GKeyFile     *key_file,
3060                             const gchar  *group_name,
3061                             const gchar  *key,
3062                             const gchar  *comment,
3063                             GError      **error)
3064 {
3065   GKeyFileGroup *group;
3066   GKeyFileKeyValuePair *pair;
3067   GList *key_node, *comment_node, *tmp;
3068   
3069   group = g_key_file_lookup_group (key_file, group_name);
3070   if (!group)
3071     {
3072       g_set_error (error, G_KEY_FILE_ERROR,
3073                    G_KEY_FILE_ERROR_GROUP_NOT_FOUND,
3074                    _("Key file does not have group '%s'"),
3075                    group_name ? group_name : "(null)");
3076
3077       return FALSE;
3078     }
3079
3080   /* First find the key the comments are supposed to be
3081    * associated with
3082    */
3083   key_node = g_key_file_lookup_key_value_pair_node (key_file, group, key);
3084
3085   if (key_node == NULL)
3086     {
3087       g_set_error (error, G_KEY_FILE_ERROR,
3088                    G_KEY_FILE_ERROR_KEY_NOT_FOUND,
3089                    _("Key file does not have key '%s' in group '%s'"),
3090                    key, group->name);
3091       return FALSE;
3092     }
3093
3094   /* Then find all the comments already associated with the
3095    * key and free them
3096    */
3097   tmp = key_node->next;
3098   while (tmp != NULL)
3099     {
3100       pair = (GKeyFileKeyValuePair *) tmp->data;
3101
3102       if (pair->key != NULL)
3103         break;
3104
3105       comment_node = tmp;
3106       tmp = tmp->next;
3107       g_key_file_remove_key_value_pair_node (key_file, group,
3108                                              comment_node); 
3109     }
3110
3111   if (comment == NULL)
3112     return TRUE;
3113
3114   /* Now we can add our new comment
3115    */
3116   pair = g_slice_new (GKeyFileKeyValuePair);
3117   pair->key = NULL;
3118   pair->value = g_key_file_parse_comment_as_value (key_file, comment);
3119   
3120   key_node = g_list_insert (key_node, pair, 1);
3121
3122   return TRUE;
3123 }
3124
3125 static gboolean
3126 g_key_file_set_group_comment (GKeyFile     *key_file,
3127                               const gchar  *group_name,
3128                               const gchar  *comment,
3129                               GError      **error)
3130 {
3131   GKeyFileGroup *group;
3132   
3133   g_return_val_if_fail (g_key_file_is_group_name (group_name), FALSE);
3134
3135   group = g_key_file_lookup_group (key_file, group_name);
3136   if (!group)
3137     {
3138       g_set_error (error, G_KEY_FILE_ERROR,
3139                    G_KEY_FILE_ERROR_GROUP_NOT_FOUND,
3140                    _("Key file does not have group '%s'"),
3141                    group_name ? group_name : "(null)");
3142
3143       return FALSE;
3144     }
3145
3146   /* First remove any existing comment
3147    */
3148   if (group->comment)
3149     {
3150       g_key_file_key_value_pair_free (group->comment);
3151       group->comment = NULL;
3152     }
3153
3154   if (comment == NULL)
3155     return TRUE;
3156
3157   /* Now we can add our new comment
3158    */
3159   group->comment = g_slice_new (GKeyFileKeyValuePair);
3160   group->comment->key = NULL;
3161   group->comment->value = g_key_file_parse_comment_as_value (key_file, comment);
3162
3163   return TRUE;
3164 }
3165
3166 static gboolean
3167 g_key_file_set_top_comment (GKeyFile     *key_file,
3168                             const gchar  *comment,
3169                             GError      **error)
3170 {
3171   GList *group_node;
3172   GKeyFileGroup *group;
3173   GKeyFileKeyValuePair *pair;
3174
3175   /* The last group in the list should be the top (comments only)
3176    * group in the file
3177    */
3178   g_warn_if_fail (key_file->groups != NULL);
3179   group_node = g_list_last (key_file->groups);
3180   group = (GKeyFileGroup *) group_node->data;
3181   g_warn_if_fail (group->name == NULL);
3182
3183   /* Note all keys must be comments at the top of
3184    * the file, so we can just free it all.
3185    */
3186   g_list_free_full (group->key_value_pairs, (GDestroyNotify) g_key_file_key_value_pair_free);
3187   group->key_value_pairs = NULL;
3188
3189   if (comment == NULL)
3190      return TRUE;
3191
3192   pair = g_slice_new (GKeyFileKeyValuePair);
3193   pair->key = NULL;
3194   pair->value = g_key_file_parse_comment_as_value (key_file, comment);
3195   
3196   group->key_value_pairs =
3197     g_list_prepend (group->key_value_pairs, pair);
3198
3199   return TRUE;
3200 }
3201
3202 /**
3203  * g_key_file_set_comment:
3204  * @key_file: a #GKeyFile
3205  * @group_name: (allow-none): a group name, or %NULL
3206  * @key: (allow-none): a key
3207  * @comment: a comment
3208  * @error: return location for a #GError
3209  *
3210  * Places a comment above @key from @group_name.
3211  * If @key is %NULL then @comment will be written above @group_name.  
3212  * If both @key and @group_name  are %NULL, then @comment will be 
3213  * written above the first group in the file.
3214  *
3215  * Returns: %TRUE if the comment was written, %FALSE otherwise
3216  *
3217  * Since: 2.6
3218  **/
3219 gboolean
3220 g_key_file_set_comment (GKeyFile     *key_file,
3221                         const gchar  *group_name,
3222                         const gchar  *key,
3223                         const gchar  *comment,
3224                         GError      **error)
3225 {
3226   g_return_val_if_fail (key_file != NULL, FALSE);
3227
3228   if (group_name != NULL && key != NULL) 
3229     {
3230       if (!g_key_file_set_key_comment (key_file, group_name, key, comment, error))
3231         return FALSE;
3232     } 
3233   else if (group_name != NULL) 
3234     {
3235       if (!g_key_file_set_group_comment (key_file, group_name, comment, error))
3236         return FALSE;
3237     } 
3238   else 
3239     {
3240       if (!g_key_file_set_top_comment (key_file, comment, error))
3241         return FALSE;
3242     }
3243
3244   return TRUE;
3245 }
3246
3247 static gchar *
3248 g_key_file_get_key_comment (GKeyFile     *key_file,
3249                             const gchar  *group_name,
3250                             const gchar  *key,
3251                             GError      **error)
3252 {
3253   GKeyFileGroup *group;
3254   GKeyFileKeyValuePair *pair;
3255   GList *key_node, *tmp;
3256   GString *string;
3257   gchar *comment;
3258
3259   g_return_val_if_fail (g_key_file_is_group_name (group_name), NULL);
3260
3261   group = g_key_file_lookup_group (key_file, group_name);
3262   if (!group)
3263     {
3264       g_set_error (error, G_KEY_FILE_ERROR,
3265                    G_KEY_FILE_ERROR_GROUP_NOT_FOUND,
3266                    _("Key file does not have group '%s'"),
3267                    group_name ? group_name : "(null)");
3268
3269       return NULL;
3270     }
3271
3272   /* First find the key the comments are supposed to be
3273    * associated with
3274    */
3275   key_node = g_key_file_lookup_key_value_pair_node (key_file, group, key);
3276
3277   if (key_node == NULL)
3278     {
3279       g_set_error (error, G_KEY_FILE_ERROR,
3280                    G_KEY_FILE_ERROR_KEY_NOT_FOUND,
3281                    _("Key file does not have key '%s' in group '%s'"),
3282                    key, group->name);
3283       return NULL;
3284     }
3285
3286   string = NULL;
3287
3288   /* Then find all the comments already associated with the
3289    * key and concatentate them.
3290    */
3291   tmp = key_node->next;
3292   if (!key_node->next)
3293     return NULL;
3294
3295   pair = (GKeyFileKeyValuePair *) tmp->data;
3296   if (pair->key != NULL)
3297     return NULL;
3298
3299   while (tmp->next)
3300     {
3301       pair = (GKeyFileKeyValuePair *) tmp->next->data;
3302       
3303       if (pair->key != NULL)
3304         break;
3305
3306       tmp = tmp->next;
3307     }
3308
3309   while (tmp != key_node)
3310     {
3311       pair = (GKeyFileKeyValuePair *) tmp->data;
3312       
3313       if (string == NULL)
3314         string = g_string_sized_new (512);
3315       
3316       comment = g_key_file_parse_value_as_comment (key_file, pair->value);
3317       g_string_append (string, comment);
3318       g_free (comment);
3319       
3320       tmp = tmp->prev;
3321     }
3322
3323   if (string != NULL)
3324     {
3325       comment = string->str;
3326       g_string_free (string, FALSE);
3327     }
3328   else
3329     comment = NULL;
3330
3331   return comment;
3332 }
3333
3334 static gchar *
3335 get_group_comment (GKeyFile       *key_file,
3336                    GKeyFileGroup  *group,
3337                    GError        **error)
3338 {
3339   GString *string;
3340   GList *tmp;
3341   gchar *comment;
3342
3343   string = NULL;
3344
3345   tmp = group->key_value_pairs;
3346   while (tmp)
3347     {
3348       GKeyFileKeyValuePair *pair;
3349
3350       pair = (GKeyFileKeyValuePair *) tmp->data;
3351
3352       if (pair->key != NULL)
3353         {
3354           tmp = tmp->prev;
3355           break;
3356         }
3357
3358       if (tmp->next == NULL)
3359         break;
3360
3361       tmp = tmp->next;
3362     }
3363   
3364   while (tmp != NULL)
3365     {
3366       GKeyFileKeyValuePair *pair;
3367
3368       pair = (GKeyFileKeyValuePair *) tmp->data;
3369
3370       if (string == NULL)
3371         string = g_string_sized_new (512);
3372
3373       comment = g_key_file_parse_value_as_comment (key_file, pair->value);
3374       g_string_append (string, comment);
3375       g_free (comment);
3376
3377       tmp = tmp->prev;
3378     }
3379
3380   if (string != NULL)
3381     return g_string_free (string, FALSE);
3382
3383   return NULL;
3384 }
3385
3386 static gchar *
3387 g_key_file_get_group_comment (GKeyFile     *key_file,
3388                               const gchar  *group_name,
3389                               GError      **error)
3390 {
3391   GList *group_node;
3392   GKeyFileGroup *group;
3393   
3394   group = g_key_file_lookup_group (key_file, group_name);
3395   if (!group)
3396     {
3397       g_set_error (error, G_KEY_FILE_ERROR,
3398                    G_KEY_FILE_ERROR_GROUP_NOT_FOUND,
3399                    _("Key file does not have group '%s'"),
3400                    group_name ? group_name : "(null)");
3401
3402       return NULL;
3403     }
3404
3405   if (group->comment)
3406     return g_strdup (group->comment->value);
3407   
3408   group_node = g_key_file_lookup_group_node (key_file, group_name);
3409   group_node = group_node->next;
3410   group = (GKeyFileGroup *)group_node->data;  
3411   return get_group_comment (key_file, group, error);
3412 }
3413
3414 static gchar *
3415 g_key_file_get_top_comment (GKeyFile  *key_file,
3416                             GError   **error)
3417 {
3418   GList *group_node;
3419   GKeyFileGroup *group;
3420
3421   /* The last group in the list should be the top (comments only)
3422    * group in the file
3423    */
3424   g_warn_if_fail (key_file->groups != NULL);
3425   group_node = g_list_last (key_file->groups);
3426   group = (GKeyFileGroup *) group_node->data;
3427   g_warn_if_fail (group->name == NULL);
3428
3429   return get_group_comment (key_file, group, error);
3430 }
3431
3432 /**
3433  * g_key_file_get_comment:
3434  * @key_file: a #GKeyFile
3435  * @group_name: (allow-none): a group name, or %NULL
3436  * @key: a key
3437  * @error: return location for a #GError
3438  *
3439  * Retrieves a comment above @key from @group_name.
3440  * If @key is %NULL then @comment will be read from above 
3441  * @group_name. If both @key and @group_name are %NULL, then 
3442  * @comment will be read from above the first group in the file.
3443  *
3444  * Returns: a comment that should be freed with g_free()
3445  *
3446  * Since: 2.6
3447  **/
3448 gchar * 
3449 g_key_file_get_comment (GKeyFile     *key_file,
3450                         const gchar  *group_name,
3451                         const gchar  *key,
3452                         GError      **error)
3453 {
3454   g_return_val_if_fail (key_file != NULL, NULL);
3455
3456   if (group_name != NULL && key != NULL)
3457     return g_key_file_get_key_comment (key_file, group_name, key, error);
3458   else if (group_name != NULL)
3459     return g_key_file_get_group_comment (key_file, group_name, error);
3460   else
3461     return g_key_file_get_top_comment (key_file, error);
3462 }
3463
3464 /**
3465  * g_key_file_remove_comment:
3466  * @key_file: a #GKeyFile
3467  * @group_name: (allow-none): a group name, or %NULL
3468  * @key: (allow-none): a key
3469  * @error: return location for a #GError
3470  *
3471  * Removes a comment above @key from @group_name.
3472  * If @key is %NULL then @comment will be removed above @group_name. 
3473  * If both @key and @group_name are %NULL, then @comment will
3474  * be removed above the first group in the file.
3475  *
3476  * Returns: %TRUE if the comment was removed, %FALSE otherwise
3477  *
3478  * Since: 2.6
3479  **/
3480
3481 gboolean
3482 g_key_file_remove_comment (GKeyFile     *key_file,
3483                            const gchar  *group_name,
3484                            const gchar  *key,
3485                            GError      **error)
3486 {
3487   g_return_val_if_fail (key_file != NULL, FALSE);
3488
3489   if (group_name != NULL && key != NULL)
3490     return g_key_file_set_key_comment (key_file, group_name, key, NULL, error);
3491   else if (group_name != NULL)
3492     return g_key_file_set_group_comment (key_file, group_name, NULL, error);
3493   else
3494     return g_key_file_set_top_comment (key_file, NULL, error);
3495 }
3496
3497 /**
3498  * g_key_file_has_group:
3499  * @key_file: a #GKeyFile
3500  * @group_name: a group name
3501  *
3502  * Looks whether the key file has the group @group_name.
3503  *
3504  * Return value: %TRUE if @group_name is a part of @key_file, %FALSE
3505  * otherwise.
3506  * Since: 2.6
3507  **/
3508 gboolean
3509 g_key_file_has_group (GKeyFile    *key_file,
3510                       const gchar *group_name)
3511 {
3512   g_return_val_if_fail (key_file != NULL, FALSE);
3513   g_return_val_if_fail (group_name != NULL, FALSE);
3514
3515   return g_key_file_lookup_group (key_file, group_name) != NULL;
3516 }
3517
3518 /* This code remains from a historical attempt to add a new public API
3519  * which respects the GError rules.
3520  */
3521 static gboolean
3522 g_key_file_has_key_full (GKeyFile     *key_file,
3523                          const gchar  *group_name,
3524                          const gchar  *key,
3525                          gboolean     *has_key,
3526                          GError      **error)
3527 {
3528   GKeyFileKeyValuePair *pair;
3529   GKeyFileGroup *group;
3530
3531   g_return_val_if_fail (key_file != NULL, FALSE);
3532   g_return_val_if_fail (group_name != NULL, FALSE);
3533   g_return_val_if_fail (key != NULL, FALSE);
3534
3535   group = g_key_file_lookup_group (key_file, group_name);
3536
3537   if (!group)
3538     {
3539       g_set_error (error, G_KEY_FILE_ERROR,
3540                    G_KEY_FILE_ERROR_GROUP_NOT_FOUND,
3541                    _("Key file does not have group '%s'"),
3542                    group_name ? group_name : "(null)");
3543
3544       return FALSE;
3545     }
3546
3547   pair = g_key_file_lookup_key_value_pair (key_file, group, key);
3548
3549   if (has_key)
3550     *has_key = pair != NULL;
3551   return TRUE;
3552 }
3553
3554 /**
3555  * g_key_file_has_key: (skip)
3556  * @key_file: a #GKeyFile
3557  * @group_name: a group name
3558  * @key: a key name
3559  * @error: return location for a #GError
3560  *
3561  * Looks whether the key file has the key @key in the group
3562  * @group_name.
3563  *
3564  * Note that this function does not follow the rules for #GError strictly;
3565  * the return value both carries meaning and signals an error.  To use
3566  * this function, you must pass a #GError pointer in @error, and check
3567  * whether it is not %NULL to see if an error occurred.
3568  *
3569  * Language bindings should use g_key_file_get_value() to test whether
3570  * or not a key exists.
3571  *
3572  * Return value: %TRUE if @key is a part of @group_name, %FALSE otherwise
3573  *
3574  * Since: 2.6
3575  **/
3576 gboolean
3577 g_key_file_has_key (GKeyFile     *key_file,
3578                     const gchar  *group_name,
3579                     const gchar  *key,
3580                     GError      **error)
3581 {
3582   GError *temp_error = NULL;
3583   gboolean has_key;
3584
3585   if (g_key_file_has_key_full (key_file, group_name, key, &has_key, &temp_error))
3586     {
3587       return has_key;
3588     }
3589   else
3590     {
3591       g_propagate_error (error, temp_error);
3592       return FALSE;
3593     }
3594 }
3595
3596 static void
3597 g_key_file_add_group (GKeyFile    *key_file,
3598                       const gchar *group_name)
3599 {
3600   GKeyFileGroup *group;
3601
3602   g_return_if_fail (key_file != NULL);
3603   g_return_if_fail (g_key_file_is_group_name (group_name));
3604
3605   group = g_key_file_lookup_group (key_file, group_name);
3606   if (group != NULL)
3607     {
3608       key_file->current_group = group;
3609       return;
3610     }
3611
3612   group = g_slice_new0 (GKeyFileGroup);
3613   group->name = g_strdup (group_name);
3614   group->lookup_map = g_hash_table_new (g_str_hash, g_str_equal);
3615   key_file->groups = g_list_prepend (key_file->groups, group);
3616   key_file->current_group = group;
3617
3618   if (key_file->start_group == NULL)
3619     key_file->start_group = group;
3620
3621   g_hash_table_insert (key_file->group_hash, (gpointer)group->name, group);
3622 }
3623
3624 static void
3625 g_key_file_key_value_pair_free (GKeyFileKeyValuePair *pair)
3626 {
3627   if (pair != NULL)
3628     {
3629       g_free (pair->key);
3630       g_free (pair->value);
3631       g_slice_free (GKeyFileKeyValuePair, pair);
3632     }
3633 }
3634
3635 /* Be careful not to call this function on a node with data in the
3636  * lookup map without removing it from the lookup map, first.
3637  *
3638  * Some current cases where this warning is not a concern are
3639  * when:
3640  *   - the node being removed is a comment node
3641  *   - the entire lookup map is getting destroyed soon after
3642  *     anyway.
3643  */ 
3644 static void
3645 g_key_file_remove_key_value_pair_node (GKeyFile      *key_file,
3646                                        GKeyFileGroup *group,
3647                                        GList         *pair_node)
3648 {
3649
3650   GKeyFileKeyValuePair *pair;
3651
3652   pair = (GKeyFileKeyValuePair *) pair_node->data;
3653
3654   group->key_value_pairs = g_list_remove_link (group->key_value_pairs, pair_node);
3655
3656   g_warn_if_fail (pair->value != NULL);
3657
3658   g_key_file_key_value_pair_free (pair);
3659
3660   g_list_free_1 (pair_node);
3661 }
3662
3663 static void
3664 g_key_file_remove_group_node (GKeyFile *key_file,
3665                               GList    *group_node)
3666 {
3667   GKeyFileGroup *group;
3668   GList *tmp;
3669
3670   group = (GKeyFileGroup *) group_node->data;
3671
3672   if (group->name)
3673     g_hash_table_remove (key_file->group_hash, group->name);
3674
3675   /* If the current group gets deleted make the current group the last
3676    * added group.
3677    */
3678   if (key_file->current_group == group)
3679     {
3680       /* groups should always contain at least the top comment group,
3681        * unless g_key_file_clear has been called
3682        */
3683       if (key_file->groups)
3684         key_file->current_group = (GKeyFileGroup *) key_file->groups->data;
3685       else
3686         key_file->current_group = NULL;
3687     }
3688
3689   /* If the start group gets deleted make the start group the first
3690    * added group.
3691    */
3692   if (key_file->start_group == group)
3693     {
3694       tmp = g_list_last (key_file->groups);
3695       while (tmp != NULL)
3696         {
3697           if (tmp != group_node &&
3698               ((GKeyFileGroup *) tmp->data)->name != NULL)
3699             break;
3700
3701           tmp = tmp->prev;
3702         }
3703
3704       if (tmp)
3705         key_file->start_group = (GKeyFileGroup *) tmp->data;
3706       else
3707         key_file->start_group = NULL;
3708     }
3709
3710   key_file->groups = g_list_remove_link (key_file->groups, group_node);
3711
3712   tmp = group->key_value_pairs;
3713   while (tmp != NULL)
3714     {
3715       GList *pair_node;
3716
3717       pair_node = tmp;
3718       tmp = tmp->next;
3719       g_key_file_remove_key_value_pair_node (key_file, group, pair_node);
3720     }
3721
3722   g_warn_if_fail (group->key_value_pairs == NULL);
3723
3724   if (group->comment)
3725     {
3726       g_key_file_key_value_pair_free (group->comment);
3727       group->comment = NULL;
3728     }
3729
3730   if (group->lookup_map)
3731     {
3732       g_hash_table_destroy (group->lookup_map);
3733       group->lookup_map = NULL;
3734     }
3735
3736   g_free ((gchar *) group->name);
3737   g_slice_free (GKeyFileGroup, group);
3738   g_list_free_1 (group_node);
3739 }
3740
3741 /**
3742  * g_key_file_remove_group:
3743  * @key_file: a #GKeyFile
3744  * @group_name: a group name
3745  * @error: return location for a #GError or %NULL
3746  *
3747  * Removes the specified group, @group_name, 
3748  * from the key file. 
3749  *
3750  * Returns: %TRUE if the group was removed, %FALSE otherwise
3751  *
3752  * Since: 2.6
3753  **/
3754 gboolean
3755 g_key_file_remove_group (GKeyFile     *key_file,
3756                          const gchar  *group_name,
3757                          GError      **error)
3758 {
3759   GList *group_node;
3760
3761   g_return_val_if_fail (key_file != NULL, FALSE);
3762   g_return_val_if_fail (group_name != NULL, FALSE);
3763
3764   group_node = g_key_file_lookup_group_node (key_file, group_name);
3765
3766   if (!group_node)
3767     {
3768       g_set_error (error, G_KEY_FILE_ERROR,
3769                    G_KEY_FILE_ERROR_GROUP_NOT_FOUND,
3770                    _("Key file does not have group '%s'"),
3771                    group_name);
3772       return FALSE;
3773     }
3774
3775   g_key_file_remove_group_node (key_file, group_node);
3776
3777   return TRUE;  
3778 }
3779
3780 static void
3781 g_key_file_add_key_value_pair (GKeyFile             *key_file,
3782                                GKeyFileGroup        *group,
3783                                GKeyFileKeyValuePair *pair)
3784 {
3785   g_hash_table_replace (group->lookup_map, pair->key, pair);
3786   group->key_value_pairs = g_list_prepend (group->key_value_pairs, pair);
3787 }
3788
3789 static void
3790 g_key_file_add_key (GKeyFile      *key_file,
3791                     GKeyFileGroup *group,
3792                     const gchar   *key,
3793                     const gchar   *value)
3794 {
3795   GKeyFileKeyValuePair *pair;
3796
3797   pair = g_slice_new (GKeyFileKeyValuePair);
3798   pair->key = g_strdup (key);
3799   pair->value = g_strdup (value);
3800
3801   g_key_file_add_key_value_pair (key_file, group, pair);
3802 }
3803
3804 /**
3805  * g_key_file_remove_key:
3806  * @key_file: a #GKeyFile
3807  * @group_name: a group name
3808  * @key: a key name to remove
3809  * @error: return location for a #GError or %NULL
3810  *
3811  * Removes @key in @group_name from the key file. 
3812  *
3813  * Returns: %TRUE if the key was removed, %FALSE otherwise
3814  *
3815  * Since: 2.6
3816  **/
3817 gboolean
3818 g_key_file_remove_key (GKeyFile     *key_file,
3819                        const gchar  *group_name,
3820                        const gchar  *key,
3821                        GError      **error)
3822 {
3823   GKeyFileGroup *group;
3824   GKeyFileKeyValuePair *pair;
3825
3826   g_return_val_if_fail (key_file != NULL, FALSE);
3827   g_return_val_if_fail (group_name != NULL, FALSE);
3828   g_return_val_if_fail (key != NULL, FALSE);
3829
3830   pair = NULL;
3831
3832   group = g_key_file_lookup_group (key_file, group_name);
3833   if (!group)
3834     {
3835       g_set_error (error, G_KEY_FILE_ERROR,
3836                    G_KEY_FILE_ERROR_GROUP_NOT_FOUND,
3837                    _("Key file does not have group '%s'"),
3838                    group_name ? group_name : "(null)");
3839       return FALSE;
3840     }
3841
3842   pair = g_key_file_lookup_key_value_pair (key_file, group, key);
3843
3844   if (!pair)
3845     {
3846       g_set_error (error, G_KEY_FILE_ERROR,
3847                    G_KEY_FILE_ERROR_KEY_NOT_FOUND,
3848                    _("Key file does not have key '%s' in group '%s'"),
3849                    key, group->name);
3850       return FALSE;
3851     }
3852
3853   group->key_value_pairs = g_list_remove (group->key_value_pairs, pair);
3854   g_hash_table_remove (group->lookup_map, pair->key);
3855   g_key_file_key_value_pair_free (pair);
3856
3857   return TRUE;
3858 }
3859
3860 static GList *
3861 g_key_file_lookup_group_node (GKeyFile    *key_file,
3862                               const gchar *group_name)
3863 {
3864   GKeyFileGroup *group;
3865   GList *tmp;
3866
3867   for (tmp = key_file->groups; tmp != NULL; tmp = tmp->next)
3868     {
3869       group = (GKeyFileGroup *) tmp->data;
3870
3871       if (group && group->name && strcmp (group->name, group_name) == 0)
3872         break;
3873     }
3874
3875   return tmp;
3876 }
3877
3878 static GKeyFileGroup *
3879 g_key_file_lookup_group (GKeyFile    *key_file,
3880                          const gchar *group_name)
3881 {
3882   return (GKeyFileGroup *)g_hash_table_lookup (key_file->group_hash, group_name);
3883 }
3884
3885 static GList *
3886 g_key_file_lookup_key_value_pair_node (GKeyFile       *key_file,
3887                                        GKeyFileGroup  *group,
3888                                        const gchar    *key)
3889 {
3890   GList *key_node;
3891
3892   for (key_node = group->key_value_pairs;
3893        key_node != NULL;
3894        key_node = key_node->next)
3895     {
3896       GKeyFileKeyValuePair *pair;
3897
3898       pair = (GKeyFileKeyValuePair *) key_node->data; 
3899
3900       if (pair->key && strcmp (pair->key, key) == 0)
3901         break;
3902     }
3903
3904   return key_node;
3905 }
3906
3907 static GKeyFileKeyValuePair *
3908 g_key_file_lookup_key_value_pair (GKeyFile      *key_file,
3909                                   GKeyFileGroup *group,
3910                                   const gchar   *key)
3911 {
3912   return (GKeyFileKeyValuePair *) g_hash_table_lookup (group->lookup_map, key);
3913 }
3914
3915 /* Lines starting with # or consisting entirely of whitespace are merely
3916  * recorded, not parsed. This function assumes all leading whitespace
3917  * has been stripped.
3918  */
3919 static gboolean
3920 g_key_file_line_is_comment (const gchar *line)
3921 {
3922   return (*line == '#' || *line == '\0' || *line == '\n');
3923 }
3924
3925 static gboolean 
3926 g_key_file_is_group_name (const gchar *name)
3927 {
3928   gchar *p, *q;
3929
3930   if (name == NULL)
3931     return FALSE;
3932
3933   p = q = (gchar *) name;
3934   while (*q && *q != ']' && *q != '[' && !g_ascii_iscntrl (*q))
3935     q = g_utf8_find_next_char (q, NULL);
3936   
3937   if (*q != '\0' || q == p)
3938     return FALSE;
3939
3940   return TRUE;
3941 }
3942
3943 static gboolean
3944 g_key_file_is_key_name (const gchar *name)
3945 {
3946   gchar *p, *q;
3947
3948   if (name == NULL)
3949     return FALSE;
3950
3951   p = q = (gchar *) name;
3952   /* We accept a little more than the desktop entry spec says,
3953    * since gnome-vfs uses mime-types as keys in its cache.
3954    */
3955   while (*q && *q != '=' && *q != '[' && *q != ']')
3956     q = g_utf8_find_next_char (q, NULL);
3957   
3958   /* No empty keys, please */
3959   if (q == p)
3960     return FALSE;
3961
3962   /* We accept spaces in the middle of keys to not break
3963    * existing apps, but we don't tolerate initial or final
3964    * spaces, which would lead to silent corruption when
3965    * rereading the file.
3966    */
3967   if (*p == ' ' || q[-1] == ' ')
3968     return FALSE;
3969
3970   if (*q == '[')
3971     {
3972       q++;
3973       while (*q && (g_unichar_isalnum (g_utf8_get_char_validated (q, -1)) || *q == '-' || *q == '_' || *q == '.' || *q == '@'))
3974         q = g_utf8_find_next_char (q, NULL);
3975
3976       if (*q != ']')
3977         return FALSE;     
3978
3979       q++;
3980     }
3981
3982   if (*q != '\0')
3983     return FALSE;
3984
3985   return TRUE;
3986 }
3987
3988 /* A group in a key file is made up of a starting '[' followed by one
3989  * or more letters making up the group name followed by ']'.
3990  */
3991 static gboolean
3992 g_key_file_line_is_group (const gchar *line)
3993 {
3994   gchar *p;
3995
3996   p = (gchar *) line;
3997   if (*p != '[')
3998     return FALSE;
3999
4000   p++;
4001
4002   while (*p && *p != ']')
4003     p = g_utf8_find_next_char (p, NULL);
4004
4005   if (*p != ']')
4006     return FALSE;
4007  
4008   /* silently accept whitespace after the ] */
4009   p = g_utf8_find_next_char (p, NULL);
4010   while (*p == ' ' || *p == '\t')
4011     p = g_utf8_find_next_char (p, NULL);
4012      
4013   if (*p)
4014     return FALSE;
4015
4016   return TRUE;
4017 }
4018
4019 static gboolean
4020 g_key_file_line_is_key_value_pair (const gchar *line)
4021 {
4022   gchar *p;
4023
4024   p = (gchar *) g_utf8_strchr (line, -1, '=');
4025
4026   if (!p)
4027     return FALSE;
4028
4029   /* Key must be non-empty
4030    */
4031   if (*p == line[0])
4032     return FALSE;
4033
4034   return TRUE;
4035 }
4036
4037 static gchar *
4038 g_key_file_parse_value_as_string (GKeyFile     *key_file,
4039                                   const gchar  *value,
4040                                   GSList      **pieces,
4041                                   GError      **error)
4042 {
4043   gchar *string_value, *p, *q0, *q;
4044
4045   string_value = g_new (gchar, strlen (value) + 1);
4046
4047   p = (gchar *) value;
4048   q0 = q = string_value;
4049   while (*p)
4050     {
4051       if (*p == '\\')
4052         {
4053           p++;
4054
4055           switch (*p)
4056             {
4057             case 's':
4058               *q = ' ';
4059               break;
4060
4061             case 'n':
4062               *q = '\n';
4063               break;
4064
4065             case 't':
4066               *q = '\t';
4067               break;
4068
4069             case 'r':
4070               *q = '\r';
4071               break;
4072
4073             case '\\':
4074               *q = '\\';
4075               break;
4076
4077             case '\0':
4078               g_set_error_literal (error, G_KEY_FILE_ERROR,
4079                                    G_KEY_FILE_ERROR_INVALID_VALUE,
4080                                    _("Key file contains escape character "
4081                                      "at end of line"));
4082               break;
4083
4084             default:
4085               if (pieces && *p == key_file->list_separator)
4086                 *q = key_file->list_separator;
4087               else
4088                 {
4089                   *q++ = '\\';
4090                   *q = *p;
4091                   
4092                   if (*error == NULL)
4093                     {
4094                       gchar sequence[3];
4095                       
4096                       sequence[0] = '\\';
4097                       sequence[1] = *p;
4098                       sequence[2] = '\0';
4099                       
4100                       g_set_error (error, G_KEY_FILE_ERROR,
4101                                    G_KEY_FILE_ERROR_INVALID_VALUE,
4102                                    _("Key file contains invalid escape "
4103                                      "sequence '%s'"), sequence);
4104                     }
4105                 }
4106               break;
4107             }
4108         }
4109       else
4110         {
4111           *q = *p;
4112           if (pieces && (*p == key_file->list_separator))
4113             {
4114               *pieces = g_slist_prepend (*pieces, g_strndup (q0, q - q0));
4115               q0 = q + 1; 
4116             }
4117         }
4118
4119       if (*p == '\0')
4120         break;
4121
4122       q++;
4123       p++;
4124     }
4125
4126   *q = '\0';
4127   if (pieces)
4128   {
4129     if (q0 < q)
4130       *pieces = g_slist_prepend (*pieces, g_strndup (q0, q - q0));
4131     *pieces = g_slist_reverse (*pieces);
4132   }
4133
4134   return string_value;
4135 }
4136
4137 static gchar *
4138 g_key_file_parse_string_as_value (GKeyFile    *key_file,
4139                                   const gchar *string,
4140                                   gboolean     escape_separator)
4141 {
4142   gchar *value, *p, *q;
4143   gsize length;
4144   gboolean parsing_leading_space;
4145
4146   length = strlen (string) + 1;
4147
4148   /* Worst case would be that every character needs to be escaped.
4149    * In other words every character turns to two characters
4150    */
4151   value = g_new (gchar, 2 * length);
4152
4153   p = (gchar *) string;
4154   q = value;
4155   parsing_leading_space = TRUE;
4156   while (p < (string + length - 1))
4157     {
4158       gchar escaped_character[3] = { '\\', 0, 0 };
4159
4160       switch (*p)
4161         {
4162         case ' ':
4163           if (parsing_leading_space)
4164             {
4165               escaped_character[1] = 's';
4166               strcpy (q, escaped_character);
4167               q += 2;
4168             }
4169           else
4170             {
4171               *q = *p;
4172               q++;
4173             }
4174           break;
4175         case '\t':
4176           if (parsing_leading_space)
4177             {
4178               escaped_character[1] = 't';
4179               strcpy (q, escaped_character);
4180               q += 2;
4181             }
4182           else
4183             {
4184               *q = *p;
4185               q++;
4186             }
4187           break;
4188         case '\n':
4189           escaped_character[1] = 'n';
4190           strcpy (q, escaped_character);
4191           q += 2;
4192           break;
4193         case '\r':
4194           escaped_character[1] = 'r';
4195           strcpy (q, escaped_character);
4196           q += 2;
4197           break;
4198         case '\\':
4199           escaped_character[1] = '\\';
4200           strcpy (q, escaped_character);
4201           q += 2;
4202           parsing_leading_space = FALSE;
4203           break;
4204         default:
4205           if (escape_separator && *p == key_file->list_separator)
4206             {
4207               escaped_character[1] = key_file->list_separator;
4208               strcpy (q, escaped_character);
4209               q += 2;
4210               parsing_leading_space = TRUE;
4211             }
4212           else 
4213             {
4214               *q = *p;
4215               q++;
4216               parsing_leading_space = FALSE;
4217             }
4218           break;
4219         }
4220       p++;
4221     }
4222   *q = '\0';
4223
4224   return value;
4225 }
4226
4227 static gint
4228 g_key_file_parse_value_as_integer (GKeyFile     *key_file,
4229                                    const gchar  *value,
4230                                    GError      **error)
4231 {
4232   gchar *eof_int;
4233   glong long_value;
4234   gint int_value;
4235
4236   errno = 0;
4237   long_value = strtol (value, &eof_int, 10);
4238
4239   if (*value == '\0' || (*eof_int != '\0' && !g_ascii_isspace(*eof_int)))
4240     {
4241       gchar *value_utf8 = _g_utf8_make_valid (value);
4242       g_set_error (error, G_KEY_FILE_ERROR,
4243                    G_KEY_FILE_ERROR_INVALID_VALUE,
4244                    _("Value '%s' cannot be interpreted "
4245                      "as a number."), value_utf8);
4246       g_free (value_utf8);
4247
4248       return 0;
4249     }
4250
4251   int_value = long_value;
4252   if (int_value != long_value || errno == ERANGE)
4253     {
4254       gchar *value_utf8 = _g_utf8_make_valid (value);
4255       g_set_error (error,
4256                    G_KEY_FILE_ERROR, 
4257                    G_KEY_FILE_ERROR_INVALID_VALUE,
4258                    _("Integer value '%s' out of range"), 
4259                    value_utf8);
4260       g_free (value_utf8);
4261
4262       return 0;
4263     }
4264   
4265   return int_value;
4266 }
4267
4268 static gchar *
4269 g_key_file_parse_integer_as_value (GKeyFile *key_file,
4270                                    gint      value)
4271
4272 {
4273   return g_strdup_printf ("%d", value);
4274 }
4275
4276 static gdouble
4277 g_key_file_parse_value_as_double  (GKeyFile     *key_file,
4278                                    const gchar  *value,
4279                                    GError      **error)
4280 {
4281   gchar *end_of_valid_d;
4282   gdouble double_value = 0;
4283
4284   double_value = g_ascii_strtod (value, &end_of_valid_d);
4285
4286   if (*end_of_valid_d != '\0' || end_of_valid_d == value)
4287     {
4288       gchar *value_utf8 = _g_utf8_make_valid (value);
4289       g_set_error (error, G_KEY_FILE_ERROR,
4290                    G_KEY_FILE_ERROR_INVALID_VALUE,
4291                    _("Value '%s' cannot be interpreted "
4292                      "as a float number."), 
4293                    value_utf8);
4294       g_free (value_utf8);
4295     }
4296
4297   return double_value;
4298 }
4299
4300 static gboolean
4301 g_key_file_parse_value_as_boolean (GKeyFile     *key_file,
4302                                    const gchar  *value,
4303                                    GError      **error)
4304 {
4305   gchar *value_utf8;
4306
4307   if (strcmp (value, "true") == 0 || strcmp (value, "1") == 0)
4308     return TRUE;
4309   else if (strcmp (value, "false") == 0 || strcmp (value, "0") == 0)
4310     return FALSE;
4311
4312   value_utf8 = _g_utf8_make_valid (value);
4313   g_set_error (error, G_KEY_FILE_ERROR,
4314                G_KEY_FILE_ERROR_INVALID_VALUE,
4315                _("Value '%s' cannot be interpreted "
4316                  "as a boolean."), value_utf8);
4317   g_free (value_utf8);
4318
4319   return FALSE;
4320 }
4321
4322 static gchar *
4323 g_key_file_parse_boolean_as_value (GKeyFile *key_file,
4324                                    gboolean  value)
4325 {
4326   if (value)
4327     return g_strdup ("true");
4328   else
4329     return g_strdup ("false");
4330 }
4331
4332 static gchar *
4333 g_key_file_parse_value_as_comment (GKeyFile    *key_file,
4334                                    const gchar *value)
4335 {
4336   GString *string;
4337   gchar **lines;
4338   gsize i;
4339
4340   string = g_string_sized_new (512);
4341
4342   lines = g_strsplit (value, "\n", 0);
4343
4344   for (i = 0; lines[i] != NULL; i++)
4345     {
4346         if (lines[i][0] != '#')
4347            g_string_append_printf (string, "%s\n", lines[i]);
4348         else 
4349            g_string_append_printf (string, "%s\n", lines[i] + 1);
4350     }
4351   g_strfreev (lines);
4352
4353   return g_string_free (string, FALSE);
4354 }
4355
4356 static gchar *
4357 g_key_file_parse_comment_as_value (GKeyFile      *key_file,
4358                                    const gchar   *comment)
4359 {
4360   GString *string;
4361   gchar **lines;
4362   gsize i;
4363
4364   string = g_string_sized_new (512);
4365
4366   lines = g_strsplit (comment, "\n", 0);
4367
4368   for (i = 0; lines[i] != NULL; i++)
4369     g_string_append_printf (string, "#%s%s", lines[i], 
4370                             lines[i + 1] == NULL? "" : "\n");
4371   g_strfreev (lines);
4372
4373   return g_string_free (string, FALSE);
4374 }
4375
4376 /**
4377  * g_key_file_save_to_file:
4378  * @key_file: a #GKeyFile
4379  * @filename: the name of the file to write to
4380  * @error: a pointer to a %NULL #GError, or %NULL
4381  *
4382  * Writes the contents of @key_file to @filename using
4383  * g_file_set_contents().
4384  *
4385  * This function can fail for any of the reasons that
4386  * g_file_set_contents() may fail.
4387  *
4388  * Returns: %TRUE if successful, else %FALSE with @error set
4389  *
4390  * Since: 2.40
4391  */
4392 gboolean
4393 g_key_file_save_to_file (GKeyFile     *key_file,
4394                          const gchar  *filename,
4395                          GError      **error)
4396 {
4397   gchar *contents;
4398   gboolean success;
4399   gsize length;
4400
4401   g_return_val_if_fail (key_file != NULL, FALSE);
4402   g_return_val_if_fail (filename != NULL, FALSE);
4403   g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
4404
4405   contents = g_key_file_to_data (key_file, &length, NULL);
4406   g_assert (contents != NULL);
4407
4408   success = g_file_set_contents (filename, contents, length, error);
4409   g_free (contents);
4410
4411   return success;
4412 }