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