Coverage Report

Created: 2026-09-13 06:25

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