Coverage Report

Created: 2025-11-24 06:16

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