~ubuntu-branches/ubuntu/utopic/glib2.0/utopic

« back to all changes in this revision

Viewing changes to glib/gkeyfile.c

Tags: upstream-2.12.12
ImportĀ upstreamĀ versionĀ 2.12.12

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* gkeyfile.c - key file parser
 
2
 *
 
3
 *  Copyright 2004  Red Hat, Inc.  
 
4
 *
 
5
 * Written by Ray Strode <rstrode@redhat.com>
 
6
 *            Matthias Clasen <mclasen@redhat.com>
 
7
 *
 
8
 * GLib is free software; you can redistribute it and/or modify it
 
9
 * under the terms of the GNU Lesser General Public License as
 
10
 * published by the Free Software Foundation; either version 2 of the
 
11
 * License, or (at your option) any later version.
 
12
 *
 
13
 * GLib is distributed in the hope that it will be useful,
 
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
16
 * Lesser General Public License for more details.
 
17
 *
 
18
 * You should have received a copy of the GNU Lesser General Public
 
19
 * License along with GLib; see the file COPYING.LIB.  If not,
 
20
 * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 
21
 *   Boston, MA 02111-1307, USA.
 
22
 */
 
23
 
 
24
#include "config.h"
 
25
 
 
26
#include "gkeyfile.h"
 
27
 
 
28
#include <errno.h>
 
29
#include <fcntl.h>
 
30
#include <locale.h>
 
31
#include <string.h>
 
32
#include <stdio.h>
 
33
#include <stdlib.h>
 
34
#include <sys/types.h>
 
35
#include <sys/stat.h>
 
36
#ifdef HAVE_UNISTD_H
 
37
#include <unistd.h>
 
38
#endif
 
39
#ifdef G_OS_WIN32
 
40
#include <io.h>
 
41
 
 
42
#ifndef S_ISREG
 
43
#define S_ISREG(mode) ((mode)&_S_IFREG)
 
44
#endif
 
45
 
 
46
#endif  /* G_OS_WIN23 */
 
47
 
 
48
#include "gconvert.h"
 
49
#include "gdataset.h"
 
50
#include "gerror.h"
 
51
#include "gfileutils.h"
 
52
#include "ghash.h"
 
53
#include "glibintl.h"
 
54
#include "glist.h"
 
55
#include "gslist.h"
 
56
#include "gmem.h"
 
57
#include "gmessages.h"
 
58
#include "gstdio.h"
 
59
#include "gstring.h"
 
60
#include "gstrfuncs.h"
 
61
#include "gutils.h"
 
62
 
 
63
#include "galias.h"
 
64
 
 
65
typedef struct _GKeyFileGroup GKeyFileGroup;
 
66
 
 
67
struct _GKeyFile
 
68
{
 
69
  GList *groups;
 
70
 
 
71
  GKeyFileGroup *start_group;
 
72
  GKeyFileGroup *current_group;
 
73
 
 
74
  GString *parse_buffer; /* Holds up to one line of not-yet-parsed data */
 
75
 
 
76
  /* Used for sizing the output buffer during serialization
 
77
   */
 
78
  gsize approximate_size;
 
79
 
 
80
  gchar list_separator;
 
81
 
 
82
  GKeyFileFlags flags;
 
83
};
 
84
 
 
85
typedef struct _GKeyFileKeyValuePair GKeyFileKeyValuePair;
 
86
 
 
87
struct _GKeyFileGroup
 
88
{
 
89
  const gchar *name;  /* NULL for above first group (which will be comments) */
 
90
 
 
91
  GKeyFileKeyValuePair *comment; /* Special comment that is stuck to the top of a group */
 
92
  gboolean has_trailing_blank_line;
 
93
 
 
94
  GList *key_value_pairs; 
 
95
 
 
96
  /* Used in parallel with key_value_pairs for
 
97
   * increased lookup performance
 
98
   */
 
99
  GHashTable *lookup_map;
 
100
};
 
101
 
 
102
struct _GKeyFileKeyValuePair
 
103
{
 
104
  gchar *key;  /* NULL for comments */
 
105
  gchar *value;
 
106
};
 
107
 
 
108
static gint                  find_file_in_data_dirs            (const gchar            *file,
 
109
                                                                gchar                 **output_file,
 
110
                                                                gchar                ***data_dirs,
 
111
                                                                GError                **error);
 
112
static gboolean              g_key_file_load_from_fd           (GKeyFile               *key_file,
 
113
                                                                gint                    fd,
 
114
                                                                GKeyFileFlags           flags,
 
115
                                                                GError                **error);
 
116
static GList                *g_key_file_lookup_group_node      (GKeyFile               *key_file,
 
117
                                                                const gchar            *group_name);
 
118
static GKeyFileGroup        *g_key_file_lookup_group           (GKeyFile               *key_file,
 
119
                                                                const gchar            *group_name);
 
120
 
 
121
static GList                *g_key_file_lookup_key_value_pair_node  (GKeyFile       *key_file,
 
122
                                                                     GKeyFileGroup  *group,
 
123
                                                                     const gchar    *key);
 
124
static GKeyFileKeyValuePair *g_key_file_lookup_key_value_pair       (GKeyFile       *key_file,
 
125
                                                                     GKeyFileGroup  *group,
 
126
                                                                     const gchar    *key);
 
127
 
 
128
static void                  g_key_file_remove_group_node          (GKeyFile      *key_file,
 
129
                                                                    GList         *group_node);
 
130
static void                  g_key_file_remove_key_value_pair_node (GKeyFile      *key_file,
 
131
                                                                    GKeyFileGroup *group,
 
132
                                                                    GList         *pair_node);
 
133
 
 
134
static void                  g_key_file_add_key                (GKeyFile               *key_file,
 
135
                                                                GKeyFileGroup          *group,
 
136
                                                                const gchar            *key,
 
137
                                                                const gchar            *value);
 
138
static void                  g_key_file_add_group              (GKeyFile               *key_file,
 
139
                                                                const gchar            *group_name);
 
140
static gboolean              g_key_file_is_group_name          (const gchar *name);
 
141
static gboolean              g_key_file_is_key_name            (const gchar *name);
 
142
static void                  g_key_file_key_value_pair_free    (GKeyFileKeyValuePair   *pair);
 
143
static gboolean              g_key_file_line_is_comment        (const gchar            *line);
 
144
static gboolean              g_key_file_line_is_group          (const gchar            *line);
 
145
static gboolean              g_key_file_line_is_key_value_pair (const gchar            *line);
 
146
static gchar                *g_key_file_parse_value_as_string  (GKeyFile               *key_file,
 
147
                                                                const gchar            *value,
 
148
                                                                GSList                **separators,
 
149
                                                                GError                **error);
 
150
static gchar                *g_key_file_parse_string_as_value  (GKeyFile               *key_file,
 
151
                                                                const gchar            *string,
 
152
                                                                gboolean                escape_separator);
 
153
static gint                  g_key_file_parse_value_as_integer (GKeyFile               *key_file,
 
154
                                                                const gchar            *value,
 
155
                                                                GError                **error);
 
156
static gchar                *g_key_file_parse_integer_as_value (GKeyFile               *key_file,
 
157
                                                                gint                    value);
 
158
static gdouble               g_key_file_parse_value_as_double  (GKeyFile               *key_file,
 
159
                                                                const gchar            *value,
 
160
                                                                GError                **error);
 
161
static gboolean              g_key_file_parse_value_as_boolean (GKeyFile               *key_file,
 
162
                                                                const gchar            *value,
 
163
                                                                GError                **error);
 
164
static gchar                *g_key_file_parse_boolean_as_value (GKeyFile               *key_file,
 
165
                                                                gboolean                value);
 
166
static gchar                *g_key_file_parse_value_as_comment (GKeyFile               *key_file,
 
167
                                                                const gchar            *value);
 
168
static gchar                *g_key_file_parse_comment_as_value (GKeyFile               *key_file,
 
169
                                                                const gchar            *comment);
 
170
static void                  g_key_file_parse_key_value_pair   (GKeyFile               *key_file,
 
171
                                                                const gchar            *line,
 
172
                                                                gsize                   length,
 
173
                                                                GError                **error);
 
174
static void                  g_key_file_parse_comment          (GKeyFile               *key_file,
 
175
                                                                const gchar            *line,
 
176
                                                                gsize                   length,
 
177
                                                                GError                **error);
 
178
static void                  g_key_file_parse_group            (GKeyFile               *key_file,
 
179
                                                                const gchar            *line,
 
180
                                                                gsize                   length,
 
181
                                                                GError                **error);
 
182
static gchar                *key_get_locale                    (const gchar            *key);
 
183
static void                  g_key_file_parse_data             (GKeyFile               *key_file,
 
184
                                                                const gchar            *data,
 
185
                                                                gsize                   length,
 
186
                                                                GError                **error);
 
187
static void                  g_key_file_flush_parse_buffer     (GKeyFile               *key_file,
 
188
                                                                GError                **error);
 
189
 
 
190
 
 
191
GQuark
 
192
g_key_file_error_quark (void)
 
193
{
 
194
  return g_quark_from_static_string ("g-key-file-error-quark");
 
195
}
 
196
 
 
197
static void
 
198
g_key_file_init (GKeyFile *key_file)
 
199
{  
 
200
  key_file->current_group = g_new0 (GKeyFileGroup, 1);
 
201
  key_file->groups = g_list_prepend (NULL, key_file->current_group);
 
202
  key_file->start_group = NULL;
 
203
  key_file->parse_buffer = g_string_sized_new (128);
 
204
  key_file->approximate_size = 0;
 
205
  key_file->list_separator = ';';
 
206
  key_file->flags = 0;
 
207
}
 
208
 
 
209
static void
 
210
g_key_file_clear (GKeyFile *key_file)
 
211
{
 
212
  GList *tmp, *group_node;
 
213
 
 
214
  if (key_file->parse_buffer)
 
215
    g_string_free (key_file->parse_buffer, TRUE);
 
216
 
 
217
  tmp = key_file->groups;
 
218
  while (tmp != NULL)
 
219
    {
 
220
      group_node = tmp;
 
221
      tmp = tmp->next;
 
222
      g_key_file_remove_group_node (key_file, group_node);
 
223
    }
 
224
 
 
225
  g_assert (key_file->groups == NULL);
 
226
}
 
227
 
 
228
 
 
229
/**
 
230
 * g_key_file_new:
 
231
 *
 
232
 * Creates a new empty #GKeyFile object. Use g_key_file_load_from_file(),
 
233
 * g_key_file_load_from_data() or g_key_file_load_from_data_dirs() to
 
234
 * read an existing key file.
 
235
 *
 
236
 * Return value: an empty #GKeyFile.
 
237
 *
 
238
 * Since: 2.6
 
239
 **/
 
240
GKeyFile *
 
241
g_key_file_new (void)
 
242
{
 
243
  GKeyFile *key_file;
 
244
 
 
245
  key_file = g_new0 (GKeyFile, 1);
 
246
  g_key_file_init (key_file);
 
247
 
 
248
  return key_file;
 
249
}
 
250
 
 
251
/**
 
252
 * g_key_file_set_list_separator:
 
253
 * @key_file: a #GKeyFile 
 
254
 * @separator: the separator
 
255
 *
 
256
 * Sets the character which is used to separate
 
257
 * values in lists. Typically ';' or ',' are used
 
258
 * as separators. The default list separator is ';'.
 
259
 *
 
260
 * Since: 2.6
 
261
 */
 
262
void
 
263
g_key_file_set_list_separator (GKeyFile *key_file,
 
264
                               gchar     separator)
 
265
{
 
266
  g_return_if_fail (key_file != NULL);
 
267
 
 
268
  key_file->list_separator = separator;
 
269
}
 
270
 
 
271
 
 
272
/* Iterates through all the directories in *dirs trying to
 
273
 * open file.  When it successfully locates and opens a file it
 
274
 * returns the file descriptor to the open file.  It also
 
275
 * outputs the absolute path of the file in output_file and
 
276
 * leaves the unchecked directories in *dirs.
 
277
 */
 
278
static gint
 
279
find_file_in_data_dirs (const gchar   *file,
 
280
                        gchar        **output_file,
 
281
                        gchar       ***dirs,
 
282
                        GError       **error)
 
283
{
 
284
  gchar **data_dirs, *data_dir, *path;
 
285
  gint fd;
 
286
 
 
287
  path = NULL;
 
288
  fd = -1;
 
289
 
 
290
  if (dirs == NULL)
 
291
    return fd;
 
292
 
 
293
  data_dirs = *dirs;
 
294
 
 
295
  while (data_dirs && (data_dir = *data_dirs) && fd < 0)
 
296
    {
 
297
      gchar *candidate_file, *sub_dir;
 
298
 
 
299
      candidate_file = (gchar *) file;
 
300
      sub_dir = g_strdup ("");
 
301
      while (candidate_file != NULL && fd < 0)
 
302
        {
 
303
          gchar *p;
 
304
 
 
305
          path = g_build_filename (data_dir, sub_dir,
 
306
                                   candidate_file, NULL);
 
307
 
 
308
          fd = g_open (path, O_RDONLY, 0);
 
309
 
 
310
          if (fd < 0)
 
311
            {
 
312
              g_free (path);
 
313
              path = NULL;
 
314
            }
 
315
 
 
316
          candidate_file = strchr (candidate_file, '-');
 
317
 
 
318
          if (candidate_file == NULL)
 
319
            break;
 
320
 
 
321
          candidate_file++;
 
322
 
 
323
          g_free (sub_dir);
 
324
          sub_dir = g_strndup (file, candidate_file - file - 1);
 
325
 
 
326
          for (p = sub_dir; *p != '\0'; p++)
 
327
            {
 
328
              if (*p == '-')
 
329
                *p = G_DIR_SEPARATOR;
 
330
            }
 
331
        }
 
332
      g_free (sub_dir);
 
333
      data_dirs++;
 
334
    }
 
335
 
 
336
  *dirs = data_dirs;
 
337
 
 
338
  if (fd < 0)
 
339
    {
 
340
      g_set_error (error, G_KEY_FILE_ERROR,
 
341
                   G_KEY_FILE_ERROR_NOT_FOUND,
 
342
                   _("Valid key file could not be "
 
343
                     "found in data dirs")); 
 
344
    }
 
345
 
 
346
  if (output_file != NULL && fd > 0)
 
347
    *output_file = g_strdup (path);
 
348
 
 
349
  g_free (path);
 
350
 
 
351
  return fd;
 
352
}
 
353
 
 
354
static gboolean
 
355
g_key_file_load_from_fd (GKeyFile       *key_file,
 
356
                         gint            fd,
 
357
                         GKeyFileFlags   flags,
 
358
                         GError        **error)
 
359
{
 
360
  GError *key_file_error = NULL;
 
361
  gssize bytes_read;
 
362
  struct stat stat_buf;
 
363
  gchar read_buf[4096];
 
364
  
 
365
  if (fstat (fd, &stat_buf) < 0)
 
366
    {
 
367
      g_set_error (error, G_FILE_ERROR,
 
368
                   g_file_error_from_errno (errno),
 
369
                   "%s", g_strerror (errno));
 
370
      return FALSE;
 
371
    }
 
372
 
 
373
  if (!S_ISREG (stat_buf.st_mode))
 
374
    {
 
375
      g_set_error (error, G_KEY_FILE_ERROR,
 
376
                   G_KEY_FILE_ERROR_PARSE,
 
377
                   _("Not a regular file"));
 
378
      return FALSE;
 
379
    }
 
380
 
 
381
  if (stat_buf.st_size == 0)
 
382
    {
 
383
      g_set_error (error, G_KEY_FILE_ERROR,
 
384
                   G_KEY_FILE_ERROR_PARSE,
 
385
                   _("File is empty"));
 
386
      return FALSE;
 
387
    }
 
388
 
 
389
  if (key_file->approximate_size > 0)
 
390
    {
 
391
      g_key_file_clear (key_file);
 
392
      g_key_file_init (key_file);
 
393
    }
 
394
  key_file->flags = flags;
 
395
 
 
396
  bytes_read = 0;
 
397
  do
 
398
    {
 
399
      bytes_read = read (fd, read_buf, 4096);
 
400
 
 
401
      if (bytes_read == 0)  /* End of File */
 
402
        break;
 
403
 
 
404
      if (bytes_read < 0)
 
405
        {
 
406
          if (errno == EINTR || errno == EAGAIN)
 
407
            continue;
 
408
 
 
409
          g_set_error (error, G_FILE_ERROR,
 
410
                       g_file_error_from_errno (errno),
 
411
                       "%s", g_strerror (errno));
 
412
          return FALSE;
 
413
        }
 
414
 
 
415
      g_key_file_parse_data (key_file, 
 
416
                             read_buf, bytes_read,
 
417
                             &key_file_error);
 
418
    }
 
419
  while (!key_file_error);
 
420
 
 
421
  if (key_file_error)
 
422
    {
 
423
      g_propagate_error (error, key_file_error);
 
424
      return FALSE;
 
425
    }
 
426
 
 
427
  g_key_file_flush_parse_buffer (key_file, &key_file_error);
 
428
 
 
429
  if (key_file_error)
 
430
    {
 
431
      g_propagate_error (error, key_file_error);
 
432
      return FALSE;
 
433
    }
 
434
 
 
435
  return TRUE;
 
436
}
 
437
 
 
438
/**
 
439
 * g_key_file_load_from_file:
 
440
 * @key_file: an empty #GKeyFile struct
 
441
 * @file: the path of a filename to load, in the GLib file name encoding
 
442
 * @flags: flags from #GKeyFileFlags
 
443
 * @error: return location for a #GError, or %NULL
 
444
 *
 
445
 * Loads a key file into an empty #GKeyFile structure.
 
446
 * If the file could not be loaded then %error is set to 
 
447
 * either a #GFileError or #GKeyFileError.
 
448
 *
 
449
 * Return value: %TRUE if a key file could be loaded, %FALSE othewise
 
450
 * Since: 2.6
 
451
 **/
 
452
gboolean
 
453
g_key_file_load_from_file (GKeyFile       *key_file,
 
454
                           const gchar    *file,
 
455
                           GKeyFileFlags   flags,
 
456
                           GError        **error)
 
457
{
 
458
  GError *key_file_error = NULL;
 
459
  gint fd;
 
460
 
 
461
  g_return_val_if_fail (key_file != NULL, FALSE);
 
462
  g_return_val_if_fail (file != NULL, FALSE);
 
463
 
 
464
  fd = g_open (file, O_RDONLY, 0);
 
465
 
 
466
  if (fd < 0)
 
467
    {
 
468
      g_set_error (error, G_FILE_ERROR,
 
469
                   g_file_error_from_errno (errno),
 
470
                   "%s", g_strerror (errno));
 
471
      return FALSE;
 
472
    }
 
473
 
 
474
  g_key_file_load_from_fd (key_file, fd, flags, &key_file_error);
 
475
  close (fd);
 
476
 
 
477
  if (key_file_error)
 
478
    {
 
479
      g_propagate_error (error, key_file_error);
 
480
      return FALSE;
 
481
    }
 
482
 
 
483
  return TRUE;
 
484
}
 
485
 
 
486
/**
 
487
 * g_key_file_load_from_data:
 
488
 * @key_file: an empty #GKeyFile struct
 
489
 * @data: key file loaded in memory.
 
490
 * @length: the length of @data in bytes
 
491
 * @flags: flags from #GKeyFileFlags
 
492
 * @error: return location for a #GError, or %NULL
 
493
 *
 
494
 * Loads a key file from memory into an empty #GKeyFile structure.  If
 
495
 * the object cannot be created then %error is set to a
 
496
 * #GKeyFileError. 
 
497
 *
 
498
 * Return value: %TRUE if a key file could be loaded, %FALSE othewise
 
499
 * Since: 2.6
 
500
 **/
 
501
gboolean
 
502
g_key_file_load_from_data (GKeyFile       *key_file,
 
503
                           const gchar    *data,
 
504
                           gsize           length,
 
505
                           GKeyFileFlags   flags,
 
506
                           GError        **error)
 
507
{
 
508
  GError *key_file_error = NULL;
 
509
 
 
510
  g_return_val_if_fail (key_file != NULL, FALSE);
 
511
  g_return_val_if_fail (data != NULL, FALSE);
 
512
  g_return_val_if_fail (length != 0, FALSE);
 
513
 
 
514
  if (length == (gsize)-1)
 
515
    length = strlen (data);
 
516
 
 
517
  if (key_file->approximate_size > 0)
 
518
    {
 
519
      g_key_file_clear (key_file);
 
520
      g_key_file_init (key_file);
 
521
    }
 
522
  key_file->flags = flags;
 
523
 
 
524
  g_key_file_parse_data (key_file, data, length, &key_file_error);
 
525
  
 
526
  if (key_file_error)
 
527
    {
 
528
      g_propagate_error (error, key_file_error);
 
529
      return FALSE;
 
530
    }
 
531
 
 
532
  g_key_file_flush_parse_buffer (key_file, &key_file_error);
 
533
  
 
534
  if (key_file_error)
 
535
    {
 
536
      g_propagate_error (error, key_file_error);
 
537
      return FALSE;
 
538
    }
 
539
 
 
540
  return TRUE;
 
541
}
 
542
 
 
543
/**
 
544
 * g_key_file_load_from_data_dirs:
 
545
 * @key_file: an empty #GKeyFile struct
 
546
 * @file: a relative path to a filename to open and parse
 
547
 * @full_path: return location for a string containing the full path
 
548
 *   of the file, or %NULL
 
549
 * @flags: flags from #GKeyFileFlags 
 
550
 * @error: return location for a #GError, or %NULL
 
551
 *
 
552
 * This function looks for a key file named @file in the paths 
 
553
 * returned from g_get_user_data_dir() and g_get_system_data_dirs(), 
 
554
 * loads the file into @key_file and returns the file's full path in 
 
555
 * @full_path.  If the file could not be loaded then an %error is
 
556
 * set to either a #GFileError or #GKeyFileError.
 
557
 *
 
558
 * Return value: %TRUE if a key file could be loaded, %FALSE othewise
 
559
 * Since: 2.6
 
560
 **/
 
561
gboolean
 
562
g_key_file_load_from_data_dirs (GKeyFile       *key_file,
 
563
                                const gchar    *file,
 
564
                                gchar         **full_path,
 
565
                                GKeyFileFlags   flags,
 
566
                                GError        **error)
 
567
{
 
568
  GError *key_file_error = NULL;
 
569
  gchar **all_data_dirs, **data_dirs;
 
570
  const gchar * user_data_dir;
 
571
  const gchar * const * system_data_dirs;
 
572
  gsize i, j;
 
573
  gchar *output_path;
 
574
  gint fd;
 
575
  gboolean found_file;
 
576
  
 
577
  g_return_val_if_fail (key_file != NULL, FALSE);
 
578
  g_return_val_if_fail (!g_path_is_absolute (file), FALSE);
 
579
 
 
580
  user_data_dir = g_get_user_data_dir ();
 
581
  system_data_dirs = g_get_system_data_dirs ();
 
582
  all_data_dirs = g_new0 (gchar *, g_strv_length ((gchar **)system_data_dirs) + 2);
 
583
 
 
584
  i = 0;
 
585
  all_data_dirs[i++] = g_strdup (user_data_dir);
 
586
 
 
587
  j = 0;
 
588
  while (system_data_dirs[j] != NULL)
 
589
    all_data_dirs[i++] = g_strdup (system_data_dirs[j++]);
 
590
 
 
591
  found_file = FALSE;
 
592
  data_dirs = all_data_dirs;
 
593
  output_path = NULL;
 
594
  while (*data_dirs != NULL && !found_file)
 
595
    {
 
596
      g_free (output_path);
 
597
 
 
598
      fd = find_file_in_data_dirs (file, &output_path, &data_dirs, 
 
599
                                   &key_file_error);
 
600
      
 
601
      if (fd < 0)
 
602
        {
 
603
          if (key_file_error)
 
604
            g_propagate_error (error, key_file_error);
 
605
          break;
 
606
        }
 
607
 
 
608
      found_file = g_key_file_load_from_fd (key_file, fd, flags,
 
609
                                            &key_file_error);
 
610
      close (fd);
 
611
      
 
612
      if (key_file_error)
 
613
        {
 
614
          g_propagate_error (error, key_file_error);
 
615
          break;
 
616
        }
 
617
    }
 
618
 
 
619
  if (found_file && full_path)
 
620
    *full_path = output_path;
 
621
  else 
 
622
    g_free (output_path);
 
623
 
 
624
  g_strfreev (all_data_dirs);
 
625
 
 
626
  return found_file;
 
627
}
 
628
 
 
629
/**
 
630
 * g_key_file_free:
 
631
 * @key_file: a #GKeyFile
 
632
 *
 
633
 * Frees a #GKeyFile.
 
634
 *
 
635
 * Since: 2.6
 
636
 **/
 
637
void
 
638
g_key_file_free (GKeyFile *key_file)
 
639
{
 
640
  g_return_if_fail (key_file != NULL);
 
641
  
 
642
  g_key_file_clear (key_file);
 
643
  g_free (key_file);
 
644
}
 
645
 
 
646
/* If G_KEY_FILE_KEEP_TRANSLATIONS is not set, only returns
 
647
 * true for locales that match those in g_get_language_names().
 
648
 */
 
649
static gboolean
 
650
g_key_file_locale_is_interesting (GKeyFile    *key_file,
 
651
                                  const gchar *locale)
 
652
{
 
653
  const gchar * const * current_locales;
 
654
  gsize i;
 
655
 
 
656
  if (key_file->flags & G_KEY_FILE_KEEP_TRANSLATIONS)
 
657
    return TRUE;
 
658
 
 
659
  current_locales = g_get_language_names ();
 
660
 
 
661
  for (i = 0; current_locales[i] != NULL; i++)
 
662
    {
 
663
      if (g_ascii_strcasecmp (current_locales[i], locale) == 0)
 
664
        return TRUE;
 
665
    }
 
666
 
 
667
  return FALSE;
 
668
}
 
669
 
 
670
static void
 
671
g_key_file_parse_line (GKeyFile     *key_file,
 
672
                       const gchar  *line,
 
673
                       gsize         length,
 
674
                       GError      **error)
 
675
{
 
676
  GError *parse_error = NULL;
 
677
  gchar *line_start;
 
678
 
 
679
  g_return_if_fail (key_file != NULL);
 
680
  g_return_if_fail (line != NULL);
 
681
 
 
682
  line_start = (gchar *) line;
 
683
  while (g_ascii_isspace (*line_start))
 
684
    line_start++;
 
685
 
 
686
  if (g_key_file_line_is_comment (line_start))
 
687
    g_key_file_parse_comment (key_file, line, length, &parse_error);
 
688
  else if (g_key_file_line_is_group (line_start))
 
689
    g_key_file_parse_group (key_file, line_start,
 
690
                            length - (line_start - line),
 
691
                            &parse_error);
 
692
  else if (g_key_file_line_is_key_value_pair (line_start))
 
693
    g_key_file_parse_key_value_pair (key_file, line_start,
 
694
                                     length - (line_start - line),
 
695
                                     &parse_error);
 
696
  else
 
697
    {
 
698
      gchar *line_utf8 = _g_utf8_make_valid (line);
 
699
      g_set_error (error, G_KEY_FILE_ERROR,
 
700
                   G_KEY_FILE_ERROR_PARSE,
 
701
                   _("Key file contains line '%s' which is not "
 
702
                     "a key-value pair, group, or comment"), 
 
703
                   line_utf8);
 
704
      g_free (line_utf8);
 
705
 
 
706
      return;
 
707
    }
 
708
 
 
709
  if (parse_error)
 
710
    g_propagate_error (error, parse_error);
 
711
}
 
712
 
 
713
static void
 
714
g_key_file_parse_comment (GKeyFile     *key_file,
 
715
                          const gchar  *line,
 
716
                          gsize         length,
 
717
                          GError      **error)
 
718
{
 
719
  GKeyFileKeyValuePair *pair;
 
720
  
 
721
  if (!(key_file->flags & G_KEY_FILE_KEEP_COMMENTS))
 
722
    return;
 
723
  
 
724
  g_assert (key_file->current_group != NULL);
 
725
 
 
726
  pair = g_new0 (GKeyFileKeyValuePair, 1);
 
727
  
 
728
  pair->key = NULL;
 
729
  pair->value = g_strndup (line, length);
 
730
  
 
731
  key_file->current_group->key_value_pairs =
 
732
    g_list_prepend (key_file->current_group->key_value_pairs, pair);
 
733
 
 
734
  if (length == 0 || line[0] != '#')
 
735
    key_file->current_group->has_trailing_blank_line = TRUE;
 
736
}
 
737
 
 
738
static void
 
739
g_key_file_parse_group (GKeyFile     *key_file,
 
740
                        const gchar  *line,
 
741
                        gsize         length,
 
742
                        GError      **error)
 
743
{
 
744
  gchar *group_name;
 
745
  const gchar *group_name_start, *group_name_end;
 
746
  
 
747
  /* advance past opening '['
 
748
   */
 
749
  group_name_start = line + 1;
 
750
  group_name_end = line + length - 1;
 
751
  
 
752
  while (*group_name_end != ']')
 
753
    group_name_end--;
 
754
 
 
755
  group_name = g_strndup (group_name_start, 
 
756
                          group_name_end - group_name_start);
 
757
  
 
758
  if (!g_key_file_is_group_name (group_name))
 
759
    {
 
760
      g_set_error (error, G_KEY_FILE_ERROR,
 
761
                   G_KEY_FILE_ERROR_PARSE,
 
762
                   _("Invalid group name: %s"), group_name);
 
763
      g_free (group_name);
 
764
      return;
 
765
    }
 
766
 
 
767
  g_key_file_add_group (key_file, group_name);
 
768
  g_free (group_name);
 
769
}
 
770
 
 
771
static void
 
772
g_key_file_parse_key_value_pair (GKeyFile     *key_file,
 
773
                                 const gchar  *line,
 
774
                                 gsize         length,
 
775
                                 GError      **error)
 
776
{
 
777
  gchar *key, *value, *key_end, *value_start, *locale;
 
778
  gsize key_len, value_len;
 
779
 
 
780
  if (key_file->current_group == NULL || key_file->current_group->name == NULL)
 
781
    {
 
782
      g_set_error (error, G_KEY_FILE_ERROR,
 
783
                   G_KEY_FILE_ERROR_GROUP_NOT_FOUND,
 
784
                   _("Key file does not start with a group"));
 
785
      return;
 
786
    }
 
787
 
 
788
  key_end = value_start = strchr (line, '=');
 
789
 
 
790
  g_assert (key_end != NULL);
 
791
 
 
792
  key_end--;
 
793
  value_start++;
 
794
 
 
795
  /* Pull the key name from the line (chomping trailing whitespace)
 
796
   */
 
797
  while (g_ascii_isspace (*key_end))
 
798
    key_end--;
 
799
 
 
800
  key_len = key_end - line + 2;
 
801
 
 
802
  g_assert (key_len <= length);
 
803
 
 
804
  key = g_strndup (line, key_len - 1);
 
805
 
 
806
  if (!g_key_file_is_key_name (key))
 
807
    {
 
808
      g_set_error (error, G_KEY_FILE_ERROR,
 
809
                   G_KEY_FILE_ERROR_PARSE,
 
810
                   _("Invalid key name: %s"), key);
 
811
      g_free (key);
 
812
      return; 
 
813
    }
 
814
 
 
815
  /* Pull the value from the line (chugging leading whitespace)
 
816
   */
 
817
  while (g_ascii_isspace (*value_start))
 
818
    value_start++;
 
819
 
 
820
  value_len = line + length - value_start + 1;
 
821
 
 
822
  value = g_strndup (value_start, value_len);
 
823
 
 
824
  g_assert (key_file->start_group != NULL);
 
825
 
 
826
  if (key_file->current_group
 
827
      && key_file->current_group->name
 
828
      && strcmp (key_file->start_group->name,
 
829
                 key_file->current_group->name) == 0
 
830
      && strcmp (key, "Encoding") == 0)
 
831
    {
 
832
      if (g_ascii_strcasecmp (value, "UTF-8") != 0)
 
833
        {
 
834
          gchar *value_utf8 = _g_utf8_make_valid (value);
 
835
          g_set_error (error, G_KEY_FILE_ERROR,
 
836
                       G_KEY_FILE_ERROR_UNKNOWN_ENCODING,
 
837
                       _("Key file contains unsupported "
 
838
                         "encoding '%s'"), value_utf8);
 
839
          g_free (value_utf8);
 
840
 
 
841
          g_free (key);
 
842
          g_free (value);
 
843
          return;
 
844
        }
 
845
    }
 
846
 
 
847
  /* Is this key a translation? If so, is it one that we care about?
 
848
   */
 
849
  locale = key_get_locale (key);
 
850
 
 
851
  if (locale == NULL || g_key_file_locale_is_interesting (key_file, locale))
 
852
    g_key_file_add_key (key_file, key_file->current_group, key, value);
 
853
 
 
854
  g_free (locale);
 
855
  g_free (key);
 
856
  g_free (value);
 
857
}
 
858
 
 
859
static gchar *
 
860
key_get_locale (const gchar *key)
 
861
{
 
862
  gchar *locale;
 
863
 
 
864
  locale = g_strrstr (key, "[");
 
865
 
 
866
  if (locale && strlen (locale) <= 2)
 
867
    locale = NULL;
 
868
 
 
869
  if (locale)
 
870
    locale = g_strndup (locale + 1, strlen (locale) - 2);
 
871
 
 
872
  return locale;
 
873
}
 
874
 
 
875
static void
 
876
g_key_file_parse_data (GKeyFile     *key_file,
 
877
                       const gchar  *data,
 
878
                       gsize         length,
 
879
                       GError      **error)
 
880
{
 
881
  GError *parse_error;
 
882
  gsize i;
 
883
 
 
884
  g_return_if_fail (key_file != NULL);
 
885
  g_return_if_fail (data != NULL);
 
886
 
 
887
  parse_error = NULL;
 
888
 
 
889
  for (i = 0; i < length; i++)
 
890
    {
 
891
      if (data[i] == '\n')
 
892
        {
 
893
          if (i > 0 && data[i - 1] == '\r')
 
894
            g_string_erase (key_file->parse_buffer,
 
895
                            key_file->parse_buffer->len - 1,
 
896
                            1);
 
897
            
 
898
          /* When a newline is encountered flush the parse buffer so that the
 
899
           * line can be parsed.  Note that completely blank lines won't show
 
900
           * up in the parse buffer, so they get parsed directly.
 
901
           */
 
902
          if (key_file->parse_buffer->len > 0)
 
903
            g_key_file_flush_parse_buffer (key_file, &parse_error);
 
904
          else
 
905
            g_key_file_parse_comment (key_file, "", 1, &parse_error);
 
906
 
 
907
          if (parse_error)
 
908
            {
 
909
              g_propagate_error (error, parse_error);
 
910
              return;
 
911
            }
 
912
        }
 
913
      else
 
914
        g_string_append_c (key_file->parse_buffer, data[i]);
 
915
    }
 
916
 
 
917
  key_file->approximate_size += length;
 
918
}
 
919
 
 
920
static void
 
921
g_key_file_flush_parse_buffer (GKeyFile  *key_file,
 
922
                               GError   **error)
 
923
{
 
924
  GError *file_error = NULL;
 
925
 
 
926
  g_return_if_fail (key_file != NULL);
 
927
 
 
928
  file_error = NULL;
 
929
 
 
930
  if (key_file->parse_buffer->len > 0)
 
931
    {
 
932
      g_key_file_parse_line (key_file, key_file->parse_buffer->str,
 
933
                             key_file->parse_buffer->len,
 
934
                             &file_error);
 
935
      g_string_erase (key_file->parse_buffer, 0, -1);
 
936
 
 
937
      if (file_error)
 
938
        {
 
939
          g_propagate_error (error, file_error);
 
940
          return;
 
941
        }
 
942
    }
 
943
}
 
944
 
 
945
/**
 
946
 * g_key_file_to_data:
 
947
 * @key_file: a #GKeyFile
 
948
 * @length: return location for the length of the 
 
949
 *   returned string, or %NULL
 
950
 * @error: return location for a #GError, or %NULL
 
951
 *
 
952
 * This function outputs @key_file as a string.  
 
953
 *
 
954
 * Return value: a newly allocated string holding
 
955
 *   the contents of the #GKeyFile 
 
956
 *
 
957
 * Since: 2.6
 
958
 **/
 
959
gchar *
 
960
g_key_file_to_data (GKeyFile  *key_file,
 
961
                    gsize     *length,
 
962
                    GError   **error)
 
963
{
 
964
  GString *data_string;
 
965
  GList *group_node, *key_file_node;
 
966
  gboolean has_blank_line = TRUE;
 
967
 
 
968
  g_return_val_if_fail (key_file != NULL, NULL);
 
969
 
 
970
  data_string = g_string_sized_new (2 * key_file->approximate_size);
 
971
  
 
972
  for (group_node = g_list_last (key_file->groups);
 
973
       group_node != NULL;
 
974
       group_node = group_node->prev)
 
975
    {
 
976
      GKeyFileGroup *group;
 
977
 
 
978
      group = (GKeyFileGroup *) group_node->data;
 
979
 
 
980
      /* separate groups by at least an empty line */
 
981
      if (!has_blank_line)
 
982
        g_string_append_c (data_string, '\n');
 
983
      has_blank_line = group->has_trailing_blank_line;
 
984
 
 
985
      if (group->comment != NULL)
 
986
        g_string_append_printf (data_string, "%s\n", group->comment->value);
 
987
 
 
988
      if (group->name != NULL)
 
989
        g_string_append_printf (data_string, "[%s]\n", group->name);
 
990
 
 
991
      for (key_file_node = g_list_last (group->key_value_pairs);
 
992
           key_file_node != NULL;
 
993
           key_file_node = key_file_node->prev)
 
994
        {
 
995
          GKeyFileKeyValuePair *pair;
 
996
 
 
997
          pair = (GKeyFileKeyValuePair *) key_file_node->data;
 
998
 
 
999
          if (pair->key != NULL)
 
1000
            g_string_append_printf (data_string, "%s=%s\n", pair->key, pair->value);
 
1001
          else
 
1002
            g_string_append_printf (data_string, "%s\n", pair->value);
 
1003
        }
 
1004
    }
 
1005
 
 
1006
  if (length)
 
1007
    *length = data_string->len;
 
1008
 
 
1009
  return g_string_free (data_string, FALSE);
 
1010
}
 
1011
 
 
1012
/**
 
1013
 * g_key_file_get_keys:
 
1014
 * @key_file: a #GKeyFile
 
1015
 * @group_name: a group name
 
1016
 * @length: return location for the number of keys returned, or %NULL
 
1017
 * @error: return location for a #GError, or %NULL
 
1018
 *
 
1019
 * Returns all keys for the group name @group_name.  The array of
 
1020
 * returned keys will be %NULL-terminated, so @length may
 
1021
 * optionally be %NULL. In the event that the @group_name cannot
 
1022
 * be found, %NULL is returned and @error is set to
 
1023
 * #G_KEY_FILE_ERROR_GROUP_NOT_FOUND.
 
1024
 *
 
1025
 * Return value: a newly-allocated %NULL-terminated array of
 
1026
 * strings. Use g_strfreev() to free it.
 
1027
 *
 
1028
 * Since: 2.6
 
1029
 **/
 
1030
gchar **
 
1031
g_key_file_get_keys (GKeyFile     *key_file,
 
1032
                     const gchar  *group_name,
 
1033
                     gsize        *length,
 
1034
                     GError      **error)
 
1035
{
 
1036
  GKeyFileGroup *group;
 
1037
  GList *tmp;
 
1038
  gchar **keys;
 
1039
  gsize i, num_keys;
 
1040
  
 
1041
  g_return_val_if_fail (key_file != NULL, NULL);
 
1042
  g_return_val_if_fail (group_name != NULL, NULL);
 
1043
  
 
1044
  group = g_key_file_lookup_group (key_file, group_name);
 
1045
  
 
1046
  if (!group)
 
1047
    {
 
1048
      g_set_error (error, G_KEY_FILE_ERROR,
 
1049
                   G_KEY_FILE_ERROR_GROUP_NOT_FOUND,
 
1050
                   _("Key file does not have group '%s'"),
 
1051
                   group_name ? group_name : "(null)");
 
1052
      return NULL;
 
1053
    }
 
1054
 
 
1055
  num_keys = 0;
 
1056
  for (tmp = group->key_value_pairs; tmp; tmp = tmp->next)
 
1057
    {
 
1058
      GKeyFileKeyValuePair *pair;
 
1059
 
 
1060
      pair = (GKeyFileKeyValuePair *) tmp->data;
 
1061
 
 
1062
      if (pair->key)
 
1063
        num_keys++;
 
1064
    }
 
1065
  
 
1066
  keys = g_new0 (gchar *, num_keys + 1);
 
1067
 
 
1068
  i = num_keys - 1;
 
1069
  for (tmp = group->key_value_pairs; tmp; tmp = tmp->next)
 
1070
    {
 
1071
      GKeyFileKeyValuePair *pair;
 
1072
 
 
1073
      pair = (GKeyFileKeyValuePair *) tmp->data;
 
1074
 
 
1075
      if (pair->key)
 
1076
        {
 
1077
          keys[i] = g_strdup (pair->key);
 
1078
          i--;
 
1079
        }
 
1080
    }
 
1081
 
 
1082
  keys[num_keys] = NULL;
 
1083
 
 
1084
  if (length)
 
1085
    *length = num_keys;
 
1086
 
 
1087
  return keys;
 
1088
}
 
1089
 
 
1090
/**
 
1091
 * g_key_file_get_start_group:
 
1092
 * @key_file: a #GKeyFile
 
1093
 *
 
1094
 * Returns the name of the start group of the file. 
 
1095
 *
 
1096
 * Return value: The start group of the key file.
 
1097
 *
 
1098
 * Since: 2.6
 
1099
 **/
 
1100
gchar *
 
1101
g_key_file_get_start_group (GKeyFile *key_file)
 
1102
{
 
1103
  g_return_val_if_fail (key_file != NULL, NULL);
 
1104
 
 
1105
  if (key_file->start_group)
 
1106
    return g_strdup (key_file->start_group->name);
 
1107
 
 
1108
  return NULL;
 
1109
}
 
1110
 
 
1111
/**
 
1112
 * g_key_file_get_groups:
 
1113
 * @key_file: a #GKeyFile
 
1114
 * @length: return location for the number of returned groups, or %NULL
 
1115
 *
 
1116
 * Returns all groups in the key file loaded with @key_file.  The
 
1117
 * array of returned groups will be %NULL-terminated, so @length may
 
1118
 * optionally be %NULL.
 
1119
 *
 
1120
 * Return value: a newly-allocated %NULL-terminated array of strings. 
 
1121
 *   Use g_strfreev() to free it.
 
1122
 * Since: 2.6
 
1123
 **/
 
1124
gchar **
 
1125
g_key_file_get_groups (GKeyFile *key_file,
 
1126
                       gsize    *length)
 
1127
{
 
1128
  GList *group_node;
 
1129
  gchar **groups;
 
1130
  gsize i, num_groups;
 
1131
 
 
1132
  g_return_val_if_fail (key_file != NULL, NULL);
 
1133
 
 
1134
  num_groups = g_list_length (key_file->groups);
 
1135
 
 
1136
  g_assert (num_groups > 0);
 
1137
 
 
1138
  /* Only need num_groups instead of num_groups + 1
 
1139
   * because the first group of the file (last in the
 
1140
   * list) is always the comment group at the top,
 
1141
   * which we skip
 
1142
   */
 
1143
  groups = g_new0 (gchar *, num_groups);
 
1144
 
 
1145
  group_node = g_list_last (key_file->groups);
 
1146
  
 
1147
  g_assert (((GKeyFileGroup *) group_node->data)->name == NULL);
 
1148
 
 
1149
  i = 0;
 
1150
  for (group_node = group_node->prev;
 
1151
       group_node != NULL;
 
1152
       group_node = group_node->prev)
 
1153
    {
 
1154
      GKeyFileGroup *group;
 
1155
 
 
1156
      group = (GKeyFileGroup *) group_node->data;
 
1157
 
 
1158
      g_assert (group->name != NULL);
 
1159
 
 
1160
      groups[i++] = g_strdup (group->name);
 
1161
    }
 
1162
  groups[i] = NULL;
 
1163
 
 
1164
  if (length)
 
1165
    *length = i;
 
1166
 
 
1167
  return groups;
 
1168
}
 
1169
 
 
1170
/**
 
1171
 * g_key_file_get_value:
 
1172
 * @key_file: a #GKeyFile
 
1173
 * @group_name: a group name
 
1174
 * @key: a key
 
1175
 * @error: return location for a #GError, or %NULL
 
1176
 *
 
1177
 * Returns the value associated with @key under @group_name.  
 
1178
 *
 
1179
 * In the event the key cannot be found, %NULL is returned and 
 
1180
 * @error is set to #G_KEY_FILE_ERROR_KEY_NOT_FOUND.  In the 
 
1181
 * event that the @group_name cannot be found, %NULL is returned 
 
1182
 * and @error is set to #G_KEY_FILE_ERROR_GROUP_NOT_FOUND.
 
1183
 *
 
1184
 * Return value: a newly allocated string or %NULL if the specified 
 
1185
 *  key cannot be found.
 
1186
 *
 
1187
 * Since: 2.6
 
1188
 **/
 
1189
gchar *
 
1190
g_key_file_get_value (GKeyFile     *key_file,
 
1191
                      const gchar  *group_name,
 
1192
                      const gchar  *key,
 
1193
                      GError      **error)
 
1194
{
 
1195
  GKeyFileGroup *group;
 
1196
  GKeyFileKeyValuePair *pair;
 
1197
  gchar *value = NULL;
 
1198
 
 
1199
  g_return_val_if_fail (key_file != NULL, NULL);
 
1200
  g_return_val_if_fail (group_name != NULL, NULL);
 
1201
  g_return_val_if_fail (key != NULL, NULL);
 
1202
  
 
1203
  group = g_key_file_lookup_group (key_file, group_name);
 
1204
 
 
1205
  if (!group)
 
1206
    {
 
1207
      g_set_error (error, G_KEY_FILE_ERROR,
 
1208
                   G_KEY_FILE_ERROR_GROUP_NOT_FOUND,
 
1209
                   _("Key file does not have group '%s'"),
 
1210
                   group_name ? group_name : "(null)");
 
1211
      return NULL;
 
1212
    }
 
1213
 
 
1214
  pair = g_key_file_lookup_key_value_pair (key_file, group, key);
 
1215
 
 
1216
  if (pair)
 
1217
    value = g_strdup (pair->value);
 
1218
  else
 
1219
    g_set_error (error, G_KEY_FILE_ERROR,
 
1220
                 G_KEY_FILE_ERROR_KEY_NOT_FOUND,
 
1221
                 _("Key file does not have key '%s'"), key);
 
1222
 
 
1223
  return value;
 
1224
}
 
1225
 
 
1226
/**
 
1227
 * g_key_file_set_value:
 
1228
 * @key_file: a #GKeyFile
 
1229
 * @group_name: a group name
 
1230
 * @key: a key
 
1231
 * @value: a string
 
1232
 *
 
1233
 * Associates a new value with @key under @group_name.  If @key
 
1234
 * cannot be found then it is created. If @group_name cannot be
 
1235
 * found then it is created.
 
1236
 *
 
1237
 * Since: 2.6
 
1238
 **/
 
1239
void
 
1240
g_key_file_set_value (GKeyFile    *key_file,
 
1241
                      const gchar *group_name,
 
1242
                      const gchar *key,
 
1243
                      const gchar *value)
 
1244
{
 
1245
  GKeyFileGroup *group;
 
1246
  GKeyFileKeyValuePair *pair;
 
1247
 
 
1248
  g_return_if_fail (key_file != NULL);
 
1249
  g_return_if_fail (g_key_file_is_group_name (group_name));
 
1250
  g_return_if_fail (g_key_file_is_key_name (key));
 
1251
  g_return_if_fail (value != NULL);
 
1252
 
 
1253
  group = g_key_file_lookup_group (key_file, group_name);
 
1254
 
 
1255
  if (!group)
 
1256
    {
 
1257
      g_key_file_add_group (key_file, group_name);
 
1258
      group = (GKeyFileGroup *) key_file->groups->data;
 
1259
 
 
1260
      g_key_file_add_key (key_file, group, key, value);
 
1261
    }
 
1262
  else
 
1263
    {
 
1264
      pair = g_key_file_lookup_key_value_pair (key_file, group, key);
 
1265
 
 
1266
      if (!pair)
 
1267
        g_key_file_add_key (key_file, group, key, value);
 
1268
      else
 
1269
        {
 
1270
          g_free (pair->value);
 
1271
          pair->value = g_strdup (value);
 
1272
        }
 
1273
    }
 
1274
}
 
1275
 
 
1276
/**
 
1277
 * g_key_file_get_string:
 
1278
 * @key_file: a #GKeyFile
 
1279
 * @group_name: a group name
 
1280
 * @key: a key
 
1281
 * @error: return location for a #GError, or %NULL
 
1282
 *
 
1283
 * Returns the value associated with @key under @group_name.  
 
1284
 *
 
1285
 * In the event the key cannot be found, %NULL is returned and 
 
1286
 * @error is set to #G_KEY_FILE_ERROR_KEY_NOT_FOUND.  In the 
 
1287
 * event that the @group_name cannot be found, %NULL is returned 
 
1288
 * and @error is set to #G_KEY_FILE_ERROR_GROUP_NOT_FOUND.
 
1289
 *
 
1290
 * Return value: a newly allocated string or %NULL if the specified 
 
1291
 *   key cannot be found.
 
1292
 *
 
1293
 * Since: 2.6
 
1294
 **/
 
1295
gchar *
 
1296
g_key_file_get_string (GKeyFile     *key_file,
 
1297
                       const gchar  *group_name,
 
1298
                       const gchar  *key,
 
1299
                       GError      **error)
 
1300
{
 
1301
  gchar *value, *string_value;
 
1302
  GError *key_file_error;
 
1303
 
 
1304
  g_return_val_if_fail (key_file != NULL, NULL);
 
1305
  g_return_val_if_fail (group_name != NULL, NULL);
 
1306
  g_return_val_if_fail (key != NULL, NULL);
 
1307
 
 
1308
  key_file_error = NULL;
 
1309
 
 
1310
  value = g_key_file_get_value (key_file, group_name, key, &key_file_error);
 
1311
 
 
1312
  if (key_file_error)
 
1313
    {
 
1314
      g_propagate_error (error, key_file_error);
 
1315
      return NULL;
 
1316
    }
 
1317
 
 
1318
  if (!g_utf8_validate (value, -1, NULL))
 
1319
    {
 
1320
      gchar *value_utf8 = _g_utf8_make_valid (value);
 
1321
      g_set_error (error, G_KEY_FILE_ERROR,
 
1322
                   G_KEY_FILE_ERROR_UNKNOWN_ENCODING,
 
1323
                   _("Key file contains key '%s' with value '%s' "
 
1324
                     "which is not UTF-8"), key, value_utf8);
 
1325
      g_free (value_utf8);
 
1326
      g_free (value);
 
1327
 
 
1328
      return NULL;
 
1329
    }
 
1330
 
 
1331
  string_value = g_key_file_parse_value_as_string (key_file, value, NULL,
 
1332
                                                   &key_file_error);
 
1333
  g_free (value);
 
1334
 
 
1335
  if (key_file_error)
 
1336
    {
 
1337
      if (g_error_matches (key_file_error,
 
1338
                           G_KEY_FILE_ERROR,
 
1339
                           G_KEY_FILE_ERROR_INVALID_VALUE))
 
1340
        {
 
1341
          g_set_error (error, G_KEY_FILE_ERROR,
 
1342
                       G_KEY_FILE_ERROR_INVALID_VALUE,
 
1343
                       _("Key file contains key '%s' "
 
1344
                         "which has value that cannot be interpreted."),
 
1345
                       key);
 
1346
          g_error_free (key_file_error);
 
1347
        }
 
1348
      else
 
1349
        g_propagate_error (error, key_file_error);
 
1350
    }
 
1351
 
 
1352
  return string_value;
 
1353
}
 
1354
 
 
1355
/**
 
1356
 * g_key_file_set_string:
 
1357
 * @key_file: a #GKeyFile
 
1358
 * @group_name: a group name
 
1359
 * @key: a key
 
1360
 * @string: a string
 
1361
 *
 
1362
 * Associates a new string value with @key under @group_name.  If
 
1363
 * @key cannot be found then it is created.  If @group_name
 
1364
 * cannot be found then it is created.
 
1365
 *
 
1366
 * Since: 2.6
 
1367
 **/
 
1368
void
 
1369
g_key_file_set_string (GKeyFile    *key_file,
 
1370
                       const gchar *group_name,
 
1371
                       const gchar *key,
 
1372
                       const gchar *string)
 
1373
{
 
1374
  gchar *value;
 
1375
 
 
1376
  g_return_if_fail (key_file != NULL);
 
1377
  g_return_if_fail (string != NULL);
 
1378
 
 
1379
  value = g_key_file_parse_string_as_value (key_file, string, FALSE);
 
1380
  g_key_file_set_value (key_file, group_name, key, value);
 
1381
  g_free (value);
 
1382
}
 
1383
 
 
1384
/**
 
1385
 * g_key_file_get_string_list:
 
1386
 * @key_file: a #GKeyFile
 
1387
 * @group_name: a group name
 
1388
 * @key: a key
 
1389
 * @length: return location for the number of returned strings, or %NULL
 
1390
 * @error: return location for a #GError, or %NULL
 
1391
 *
 
1392
 * Returns the values associated with @key under @group_name.
 
1393
 *
 
1394
 * In the event the key cannot be found, %NULL is returned and
 
1395
 * @error is set to #G_KEY_FILE_ERROR_KEY_NOT_FOUND.  In the
 
1396
 * event that the @group_name cannot be found, %NULL is returned
 
1397
 * and @error is set to #G_KEY_FILE_ERROR_GROUP_NOT_FOUND.
 
1398
 *
 
1399
 * Return value: a %NULL-terminated string array or %NULL if the specified 
 
1400
 *   key cannot be found. The array should be freed with g_strfreev().
 
1401
 *
 
1402
 * Since: 2.6
 
1403
 **/
 
1404
gchar **
 
1405
g_key_file_get_string_list (GKeyFile     *key_file,
 
1406
                            const gchar  *group_name,
 
1407
                            const gchar  *key,
 
1408
                            gsize        *length,
 
1409
                            GError      **error)
 
1410
{
 
1411
  GError *key_file_error = NULL;
 
1412
  gchar *value, *string_value, **values;
 
1413
  gint i, len;
 
1414
  GSList *p, *pieces = NULL;
 
1415
 
 
1416
  g_return_val_if_fail (key_file != NULL, NULL);
 
1417
  g_return_val_if_fail (group_name != NULL, NULL);
 
1418
  g_return_val_if_fail (key != NULL, NULL);
 
1419
 
 
1420
  value = g_key_file_get_value (key_file, group_name, key, &key_file_error);
 
1421
 
 
1422
  if (key_file_error)
 
1423
    {
 
1424
      g_propagate_error (error, key_file_error);
 
1425
      return NULL;
 
1426
    }
 
1427
 
 
1428
  if (!g_utf8_validate (value, -1, NULL))
 
1429
    {
 
1430
      gchar *value_utf8 = _g_utf8_make_valid (value);
 
1431
      g_set_error (error, G_KEY_FILE_ERROR,
 
1432
                   G_KEY_FILE_ERROR_UNKNOWN_ENCODING,
 
1433
                   _("Key file contains key '%s' with value '%s' "
 
1434
                     "which is not UTF-8"), key, value_utf8);
 
1435
      g_free (value_utf8);
 
1436
      g_free (value);
 
1437
 
 
1438
      return NULL;
 
1439
    }
 
1440
 
 
1441
  string_value = g_key_file_parse_value_as_string (key_file, value, &pieces, &key_file_error);
 
1442
  g_free (value);
 
1443
  g_free (string_value);
 
1444
 
 
1445
  if (key_file_error)
 
1446
    {
 
1447
      if (g_error_matches (key_file_error,
 
1448
                           G_KEY_FILE_ERROR,
 
1449
                           G_KEY_FILE_ERROR_INVALID_VALUE))
 
1450
        {
 
1451
          g_set_error (error, G_KEY_FILE_ERROR,
 
1452
                       G_KEY_FILE_ERROR_INVALID_VALUE,
 
1453
                       _("Key file contains key '%s' "
 
1454
                         "which has value that cannot be interpreted."),
 
1455
                       key);
 
1456
          g_error_free (key_file_error);
 
1457
        }
 
1458
      else
 
1459
        g_propagate_error (error, key_file_error);
 
1460
    }
 
1461
 
 
1462
  len = g_slist_length (pieces);
 
1463
  values = g_new0 (gchar *, len + 1); 
 
1464
  for (p = pieces, i = 0; p; p = p->next)
 
1465
    values[i++] = p->data;
 
1466
  values[len] = NULL;
 
1467
 
 
1468
  g_slist_free (pieces);
 
1469
 
 
1470
  if (length)
 
1471
    *length = len;
 
1472
 
 
1473
  return values;
 
1474
}
 
1475
 
 
1476
/**
 
1477
 * g_key_file_set_string_list:
 
1478
 * @key_file: a #GKeyFile
 
1479
 * @group_name: a group name
 
1480
 * @key: a key
 
1481
 * @list: an array of locale string values
 
1482
 * @length: number of locale string values in @list
 
1483
 *
 
1484
 * Associates a list of string values for @key under @group_name.
 
1485
 * If @key cannot be found then it is created.  If @group_name 
 
1486
 * cannot be found then it is created.
 
1487
 *
 
1488
 * Since: 2.6
 
1489
 **/
 
1490
void
 
1491
g_key_file_set_string_list (GKeyFile            *key_file,
 
1492
                            const gchar         *group_name,
 
1493
                            const gchar         *key,
 
1494
                            const gchar * const  list[],
 
1495
                            gsize                length)
 
1496
{
 
1497
  GString *value_list;
 
1498
  gsize i;
 
1499
 
 
1500
  g_return_if_fail (key_file != NULL);
 
1501
  g_return_if_fail (list != NULL);
 
1502
 
 
1503
  value_list = g_string_sized_new (length * 128);
 
1504
  for (i = 0; i < length && list[i] != NULL; i++)
 
1505
    {
 
1506
      gchar *value;
 
1507
 
 
1508
      value = g_key_file_parse_string_as_value (key_file, list[i], TRUE);
 
1509
      g_string_append (value_list, value);
 
1510
      g_string_append_c (value_list, key_file->list_separator);
 
1511
 
 
1512
      g_free (value);
 
1513
    }
 
1514
 
 
1515
  g_key_file_set_value (key_file, group_name, key, value_list->str);
 
1516
  g_string_free (value_list, TRUE);
 
1517
}
 
1518
 
 
1519
/**
 
1520
 * g_key_file_set_locale_string:
 
1521
 * @key_file: a #GKeyFile
 
1522
 * @group_name: a group name
 
1523
 * @key: a key
 
1524
 * @locale: a locale
 
1525
 * @string: a string
 
1526
 *
 
1527
 * Associates a string value for @key and @locale under
 
1528
 * @group_name.  If the translation for @key cannot be found 
 
1529
 * then it is created.
 
1530
 *
 
1531
 * Since: 2.6
 
1532
 **/
 
1533
void
 
1534
g_key_file_set_locale_string (GKeyFile     *key_file,
 
1535
                              const gchar  *group_name,
 
1536
                              const gchar  *key,
 
1537
                              const gchar  *locale,
 
1538
                              const gchar  *string)
 
1539
{
 
1540
  gchar *full_key, *value;
 
1541
 
 
1542
  g_return_if_fail (key_file != NULL);
 
1543
  g_return_if_fail (key != NULL);
 
1544
  g_return_if_fail (locale != NULL);
 
1545
  g_return_if_fail (string != NULL);
 
1546
 
 
1547
  value = g_key_file_parse_string_as_value (key_file, string, FALSE);
 
1548
  full_key = g_strdup_printf ("%s[%s]", key, locale);
 
1549
  g_key_file_set_value (key_file, group_name, full_key, value);
 
1550
  g_free (full_key);
 
1551
  g_free (value);
 
1552
}
 
1553
 
 
1554
extern GSList *_g_compute_locale_variants (const gchar *locale);
 
1555
 
 
1556
/**
 
1557
 * g_key_file_get_locale_string:
 
1558
 * @key_file: a #GKeyFile
 
1559
 * @group_name: a group name
 
1560
 * @key: a key
 
1561
 * @locale: a locale or %NULL
 
1562
 * @error: return location for a #GError, or %NULL
 
1563
 *
 
1564
 * Returns the value associated with @key under @group_name
 
1565
 * translated in the given @locale if available.  If @locale is
 
1566
 * %NULL then the current locale is assumed. 
 
1567
 *
 
1568
 * If @key cannot be found then %NULL is returned and @error is set to
 
1569
 * #G_KEY_FILE_ERROR_KEY_NOT_FOUND. If the value associated
 
1570
 * with @key cannot be interpreted or no suitable translation can
 
1571
 * be found then the untranslated value is returned.
 
1572
 *
 
1573
 * Return value: a newly allocated string or %NULL if the specified 
 
1574
 *   key cannot be found.
 
1575
 *
 
1576
 * Since: 2.6
 
1577
 **/
 
1578
gchar *
 
1579
g_key_file_get_locale_string (GKeyFile     *key_file,
 
1580
                              const gchar  *group_name,
 
1581
                              const gchar  *key,
 
1582
                              const gchar  *locale,
 
1583
                              GError      **error)
 
1584
{
 
1585
  gchar *candidate_key, *translated_value;
 
1586
  GError *key_file_error;
 
1587
  gchar **languages;
 
1588
  gboolean free_languages = FALSE;
 
1589
  gint i;
 
1590
 
 
1591
  g_return_val_if_fail (key_file != NULL, NULL);
 
1592
  g_return_val_if_fail (group_name != NULL, NULL);
 
1593
  g_return_val_if_fail (key != NULL, NULL);
 
1594
 
 
1595
  candidate_key = NULL;
 
1596
  translated_value = NULL;
 
1597
  key_file_error = NULL;
 
1598
 
 
1599
  if (locale)
 
1600
    {
 
1601
      GSList *l, *list;
 
1602
 
 
1603
      list = _g_compute_locale_variants (locale);
 
1604
 
 
1605
      languages = g_new0 (gchar *, g_slist_length (list) + 1);
 
1606
      for (l = list, i = 0; l; l = l->next, i++)
 
1607
        languages[i] = l->data;
 
1608
      languages[i] = NULL;
 
1609
 
 
1610
      g_slist_free (list);
 
1611
      free_languages = TRUE;
 
1612
    }
 
1613
  else
 
1614
    {
 
1615
      languages = (gchar **) g_get_language_names ();
 
1616
      free_languages = FALSE;
 
1617
    }
 
1618
  
 
1619
  for (i = 0; languages[i]; i++)
 
1620
    {
 
1621
      candidate_key = g_strdup_printf ("%s[%s]", key, languages[i]);
 
1622
      
 
1623
      translated_value = g_key_file_get_string (key_file,
 
1624
                                                group_name,
 
1625
                                                candidate_key, NULL);
 
1626
      g_free (candidate_key);
 
1627
 
 
1628
      if (translated_value)
 
1629
        break;
 
1630
 
 
1631
      g_free (translated_value);
 
1632
      translated_value = NULL;
 
1633
   }
 
1634
 
 
1635
  /* Fallback to untranslated key
 
1636
   */
 
1637
  if (!translated_value)
 
1638
    {
 
1639
      translated_value = g_key_file_get_string (key_file, group_name, key,
 
1640
                                                &key_file_error);
 
1641
      
 
1642
      if (!translated_value)
 
1643
        g_propagate_error (error, key_file_error);
 
1644
    }
 
1645
 
 
1646
  if (free_languages)
 
1647
    g_strfreev (languages);
 
1648
 
 
1649
  return translated_value;
 
1650
}
 
1651
 
 
1652
/** 
 
1653
 * g_key_file_get_locale_string_list: 
 
1654
 * @key_file: a #GKeyFile
 
1655
 * @group_name: a group name
 
1656
 * @key: a key
 
1657
 * @locale: a locale
 
1658
 * @length: return location for the number of returned strings or %NULL
 
1659
 * @error: return location for a #GError or %NULL
 
1660
 *
 
1661
 * Returns the values associated with @key under @group_name
 
1662
 * translated in the given @locale if available.  If @locale is
 
1663
 * %NULL then the current locale is assumed.
 
1664
 
 
1665
 * If @key cannot be found then %NULL is returned and @error is set to
 
1666
 * #G_KEY_FILE_ERROR_KEY_NOT_FOUND. If the values associated
 
1667
 * with @key cannot be interpreted or no suitable translations
 
1668
 * can be found then the untranslated values are returned.
 
1669
 * The returned array is %NULL-terminated, so @length may optionally be %NULL.
 
1670
 *
 
1671
 * Return value: a newly allocated %NULL-terminated string array
 
1672
 *   or %NULL if the key isn't found. The string array should be freed
 
1673
 *   with g_strfreev().
 
1674
 *
 
1675
 * Since: 2.6
 
1676
 **/
 
1677
gchar **
 
1678
g_key_file_get_locale_string_list (GKeyFile     *key_file,
 
1679
                                   const gchar  *group_name,
 
1680
                                   const gchar  *key,
 
1681
                                   const gchar  *locale,
 
1682
                                   gsize        *length,
 
1683
                                   GError      **error)
 
1684
{
 
1685
  GError *key_file_error;
 
1686
  gchar **values, *value;
 
1687
 
 
1688
  g_return_val_if_fail (key_file != NULL, NULL);
 
1689
  g_return_val_if_fail (group_name != NULL, NULL);
 
1690
  g_return_val_if_fail (key != NULL, NULL);
 
1691
 
 
1692
  key_file_error = NULL;
 
1693
 
 
1694
  value = g_key_file_get_locale_string (key_file, group_name, 
 
1695
                                        key, locale,
 
1696
                                        &key_file_error);
 
1697
  
 
1698
  if (key_file_error)
 
1699
    g_propagate_error (error, key_file_error);
 
1700
  
 
1701
  if (!value)
 
1702
    return NULL;
 
1703
 
 
1704
  if (value[strlen (value) - 1] == ';')
 
1705
    value[strlen (value) - 1] = '\0';
 
1706
 
 
1707
  values = g_strsplit (value, ";", 0);
 
1708
 
 
1709
  g_free (value);
 
1710
 
 
1711
  if (length)
 
1712
    *length = g_strv_length (values);
 
1713
 
 
1714
  return values;
 
1715
}
 
1716
 
 
1717
/**
 
1718
 * g_key_file_set_locale_string_list:
 
1719
 * @key_file: a #GKeyFile
 
1720
 * @group_name: a group name
 
1721
 * @key: a key
 
1722
 * @locale: a locale
 
1723
 * @list: a %NULL-terminated array of locale string values
 
1724
 * @length: the length of @list
 
1725
 *
 
1726
 * Associates a list of string values for @key and @locale under
 
1727
 * @group_name.  If the translation for @key cannot be found then
 
1728
 * it is created. 
 
1729
 *
 
1730
 * Since: 2.6
 
1731
 **/
 
1732
void
 
1733
g_key_file_set_locale_string_list (GKeyFile            *key_file,
 
1734
                                   const gchar         *group_name,
 
1735
                                   const gchar         *key,
 
1736
                                   const gchar         *locale,
 
1737
                                   const gchar * const  list[],
 
1738
                                   gsize                length)
 
1739
{
 
1740
  GString *value_list;
 
1741
  gchar *full_key;
 
1742
  gsize i;
 
1743
 
 
1744
  g_return_if_fail (key_file != NULL);
 
1745
  g_return_if_fail (key != NULL);
 
1746
  g_return_if_fail (locale != NULL);
 
1747
  g_return_if_fail (length != 0);
 
1748
 
 
1749
  value_list = g_string_sized_new (length * 128);
 
1750
  for (i = 0; i < length && list[i] != NULL; i++)
 
1751
    {
 
1752
      gchar *value;
 
1753
      
 
1754
      value = g_key_file_parse_string_as_value (key_file, list[i], TRUE);
 
1755
      
 
1756
      g_string_append (value_list, value);
 
1757
      g_string_append_c (value_list, ';');
 
1758
 
 
1759
      g_free (value);
 
1760
    }
 
1761
 
 
1762
  full_key = g_strdup_printf ("%s[%s]", key, locale);
 
1763
  g_key_file_set_value (key_file, group_name, full_key, value_list->str);
 
1764
  g_free (full_key);
 
1765
  g_string_free (value_list, TRUE);
 
1766
}
 
1767
 
 
1768
/**
 
1769
 * g_key_file_get_boolean:
 
1770
 * @key_file: a #GKeyFile
 
1771
 * @group_name: a group name
 
1772
 * @key: a key
 
1773
 * @error: return location for a #GError
 
1774
 *
 
1775
 * Returns the value associated with @key under @group_name as a
 
1776
 * boolean. 
 
1777
 *
 
1778
 * If @key cannot be found then the return value is undefined and
 
1779
 * @error is set to #G_KEY_FILE_ERROR_KEY_NOT_FOUND. Likewise, if
 
1780
 * the value associated with @key cannot be interpreted as a boolean
 
1781
 * then the return value is also undefined and @error is set to
 
1782
 * #G_KEY_FILE_ERROR_INVALID_VALUE.
 
1783
 *
 
1784
 * Return value: the value associated with the key as a boolean
 
1785
 * Since: 2.6
 
1786
 **/
 
1787
gboolean
 
1788
g_key_file_get_boolean (GKeyFile     *key_file,
 
1789
                        const gchar  *group_name,
 
1790
                        const gchar  *key,
 
1791
                        GError      **error)
 
1792
{
 
1793
  GError *key_file_error = NULL;
 
1794
  gchar *value;
 
1795
  gboolean bool_value;
 
1796
 
 
1797
  g_return_val_if_fail (key_file != NULL, FALSE);
 
1798
  g_return_val_if_fail (group_name != NULL, FALSE);
 
1799
  g_return_val_if_fail (key != NULL, FALSE);
 
1800
 
 
1801
  value = g_key_file_get_value (key_file, group_name, key, &key_file_error);
 
1802
 
 
1803
  if (!value)
 
1804
    {
 
1805
      g_propagate_error (error, key_file_error);
 
1806
      return FALSE;
 
1807
    }
 
1808
 
 
1809
  bool_value = g_key_file_parse_value_as_boolean (key_file, value,
 
1810
                                                  &key_file_error);
 
1811
  g_free (value);
 
1812
 
 
1813
  if (key_file_error)
 
1814
    {
 
1815
      if (g_error_matches (key_file_error,
 
1816
                           G_KEY_FILE_ERROR,
 
1817
                           G_KEY_FILE_ERROR_INVALID_VALUE))
 
1818
        {
 
1819
          g_set_error (error, G_KEY_FILE_ERROR,
 
1820
                       G_KEY_FILE_ERROR_INVALID_VALUE,
 
1821
                       _("Key file contains key '%s' "
 
1822
                         "which has value that cannot be interpreted."),
 
1823
                       key);
 
1824
          g_error_free (key_file_error);
 
1825
        }
 
1826
      else
 
1827
        g_propagate_error (error, key_file_error);
 
1828
    }
 
1829
 
 
1830
  return bool_value;
 
1831
}
 
1832
 
 
1833
/**
 
1834
 * g_key_file_set_boolean:
 
1835
 * @key_file: a #GKeyFile
 
1836
 * @group_name: a group name
 
1837
 * @key: a key
 
1838
 * @value: %TRUE or %FALSE
 
1839
 *
 
1840
 * Associates a new boolean value with @key under @group_name.
 
1841
 * If @key cannot be found then it is created. 
 
1842
 *
 
1843
 * Since: 2.6
 
1844
 **/
 
1845
void
 
1846
g_key_file_set_boolean (GKeyFile    *key_file,
 
1847
                        const gchar *group_name,
 
1848
                        const gchar *key,
 
1849
                        gboolean     value)
 
1850
{
 
1851
  gchar *result;
 
1852
 
 
1853
  g_return_if_fail (key_file != NULL);
 
1854
 
 
1855
  result = g_key_file_parse_boolean_as_value (key_file, value);
 
1856
  g_key_file_set_value (key_file, group_name, key, result);
 
1857
  g_free (result);
 
1858
}
 
1859
 
 
1860
/**
 
1861
 * g_key_file_get_boolean_list:
 
1862
 * @key_file: a #GKeyFile
 
1863
 * @group_name: a group name
 
1864
 * @key: a key
 
1865
 * @length: the number of booleans returned
 
1866
 * @error: return location for a #GError
 
1867
 *
 
1868
 * Returns the values associated with @key under @group_name as
 
1869
 * booleans. If @group_name is %NULL, the start_group is used.
 
1870
 *
 
1871
 * If @key cannot be found then the return value is undefined and
 
1872
 * @error is set to #G_KEY_FILE_ERROR_KEY_NOT_FOUND. Likewise, if
 
1873
 * the values associated with @key cannot be interpreted as booleans
 
1874
 * then the return value is also undefined and @error is set to
 
1875
 * #G_KEY_FILE_ERROR_INVALID_VALUE.
 
1876
 *
 
1877
 * Return value: the values associated with the key as a boolean
 
1878
 * 
 
1879
 * Since: 2.6
 
1880
 **/
 
1881
gboolean *
 
1882
g_key_file_get_boolean_list (GKeyFile     *key_file,
 
1883
                             const gchar  *group_name,
 
1884
                             const gchar  *key,
 
1885
                             gsize        *length,
 
1886
                             GError      **error)
 
1887
{
 
1888
  GError *key_file_error;
 
1889
  gchar **values;
 
1890
  gboolean *bool_values;
 
1891
  gsize i, num_bools;
 
1892
 
 
1893
  g_return_val_if_fail (key_file != NULL, NULL);
 
1894
  g_return_val_if_fail (group_name != NULL, NULL);
 
1895
  g_return_val_if_fail (key != NULL, NULL);
 
1896
 
 
1897
  key_file_error = NULL;
 
1898
 
 
1899
  values = g_key_file_get_string_list (key_file, group_name, key,
 
1900
                                       &num_bools, &key_file_error);
 
1901
 
 
1902
  if (key_file_error)
 
1903
    g_propagate_error (error, key_file_error);
 
1904
 
 
1905
  if (!values)
 
1906
    return NULL;
 
1907
 
 
1908
  bool_values = g_new0 (gboolean, num_bools);
 
1909
 
 
1910
  for (i = 0; i < num_bools; i++)
 
1911
    {
 
1912
      bool_values[i] = g_key_file_parse_value_as_boolean (key_file,
 
1913
                                                          values[i],
 
1914
                                                          &key_file_error);
 
1915
 
 
1916
      if (key_file_error)
 
1917
        {
 
1918
          g_propagate_error (error, key_file_error);
 
1919
          g_strfreev (values);
 
1920
          g_free (bool_values);
 
1921
 
 
1922
          return NULL;
 
1923
        }
 
1924
    }
 
1925
  g_strfreev (values);
 
1926
 
 
1927
  if (length)
 
1928
    *length = num_bools;
 
1929
 
 
1930
  return bool_values;
 
1931
}
 
1932
 
 
1933
/**
 
1934
 * g_key_file_set_boolean_list:
 
1935
 * @key_file: a #GKeyFile
 
1936
 * @group_name: a group name
 
1937
 * @key: a key
 
1938
 * @list: an array of boolean values
 
1939
 * @length: length of @list
 
1940
 *
 
1941
 * Associates a list of boolean values with @key under
 
1942
 * @group_name.  If @key cannot be found then it is created.
 
1943
 * If @group_name is %NULL, the start_group is used.
 
1944
 *
 
1945
 * Since: 2.6
 
1946
 **/
 
1947
void
 
1948
g_key_file_set_boolean_list (GKeyFile    *key_file,
 
1949
                             const gchar *group_name,
 
1950
                             const gchar *key,
 
1951
                             gboolean     list[],
 
1952
                             gsize        length)
 
1953
{
 
1954
  GString *value_list;
 
1955
  gsize i;
 
1956
 
 
1957
  g_return_if_fail (key_file != NULL);
 
1958
  g_return_if_fail (list != NULL);
 
1959
 
 
1960
  value_list = g_string_sized_new (length * 8);
 
1961
  for (i = 0; i < length; i++)
 
1962
    {
 
1963
      gchar *value;
 
1964
 
 
1965
      value = g_key_file_parse_boolean_as_value (key_file, list[i]);
 
1966
 
 
1967
      g_string_append (value_list, value);
 
1968
      g_string_append_c (value_list, key_file->list_separator);
 
1969
 
 
1970
      g_free (value);
 
1971
    }
 
1972
 
 
1973
  g_key_file_set_value (key_file, group_name, key, value_list->str);
 
1974
  g_string_free (value_list, TRUE);
 
1975
}
 
1976
 
 
1977
/**
 
1978
 * g_key_file_get_integer:
 
1979
 * @key_file: a #GKeyFile
 
1980
 * @group_name: a group name
 
1981
 * @key: a key
 
1982
 * @error: return location for a #GError
 
1983
 *
 
1984
 * Returns the value associated with @key under @group_name as an
 
1985
 * integer. If @group_name is %NULL, the start_group is used.
 
1986
 *
 
1987
 * If @key cannot be found then the return value is undefined and
 
1988
 * @error is set to #G_KEY_FILE_ERROR_KEY_NOT_FOUND. Likewise, if
 
1989
 * the value associated with @key cannot be interpreted as an integer
 
1990
 * then the return value is also undefined and @error is set to
 
1991
 * #G_KEY_FILE_ERROR_INVALID_VALUE.
 
1992
 *
 
1993
 * Return value: the value associated with the key as an integer.
 
1994
 *
 
1995
 * Since: 2.6
 
1996
 **/
 
1997
gint
 
1998
g_key_file_get_integer (GKeyFile     *key_file,
 
1999
                        const gchar  *group_name,
 
2000
                        const gchar  *key,
 
2001
                        GError      **error)
 
2002
{
 
2003
  GError *key_file_error;
 
2004
  gchar *value;
 
2005
  gint int_value;
 
2006
 
 
2007
  g_return_val_if_fail (key_file != NULL, -1);
 
2008
  g_return_val_if_fail (group_name != NULL, -1);
 
2009
  g_return_val_if_fail (key != NULL, -1);
 
2010
 
 
2011
  key_file_error = NULL;
 
2012
 
 
2013
  value = g_key_file_get_value (key_file, group_name, key, &key_file_error);
 
2014
 
 
2015
  if (key_file_error)
 
2016
    {
 
2017
      g_propagate_error (error, key_file_error);
 
2018
      return 0;
 
2019
    }
 
2020
 
 
2021
  int_value = g_key_file_parse_value_as_integer (key_file, value,
 
2022
                                                 &key_file_error);
 
2023
  g_free (value);
 
2024
 
 
2025
  if (key_file_error)
 
2026
    {
 
2027
      if (g_error_matches (key_file_error,
 
2028
                           G_KEY_FILE_ERROR,
 
2029
                           G_KEY_FILE_ERROR_INVALID_VALUE))
 
2030
        {
 
2031
          g_set_error (error, G_KEY_FILE_ERROR,
 
2032
                       G_KEY_FILE_ERROR_INVALID_VALUE,
 
2033
                       _("Key file contains key '%s' in group '%s' "
 
2034
                         "which has value that cannot be interpreted."), key, 
 
2035
                       group_name);
 
2036
          g_error_free (key_file_error);
 
2037
        }
 
2038
      else
 
2039
        g_propagate_error (error, key_file_error);
 
2040
    }
 
2041
 
 
2042
  return int_value;
 
2043
}
 
2044
 
 
2045
/**
 
2046
 * g_key_file_set_integer:
 
2047
 * @key_file: a #GKeyFile
 
2048
 * @group_name: a group name
 
2049
 * @key: a key
 
2050
 * @value: an integer value
 
2051
 *
 
2052
 * Associates a new integer value with @key under @group_name.
 
2053
 * If @key cannot be found then it is created.
 
2054
 *
 
2055
 * Since: 2.6
 
2056
 **/
 
2057
void
 
2058
g_key_file_set_integer (GKeyFile    *key_file,
 
2059
                        const gchar *group_name,
 
2060
                        const gchar *key,
 
2061
                        gint         value)
 
2062
{
 
2063
  gchar *result;
 
2064
 
 
2065
  g_return_if_fail (key_file != NULL);
 
2066
 
 
2067
  result = g_key_file_parse_integer_as_value (key_file, value);
 
2068
  g_key_file_set_value (key_file, group_name, key, result);
 
2069
  g_free (result);
 
2070
}
 
2071
 
 
2072
/**
 
2073
 * g_key_file_get_integer_list:
 
2074
 * @key_file: a #GKeyFile
 
2075
 * @group_name: a group name
 
2076
 * @key: a key
 
2077
 * @length: the number of integers returned
 
2078
 * @error: return location for a #GError
 
2079
 *
 
2080
 * Returns the values associated with @key under @group_name as
 
2081
 * integers. 
 
2082
 *
 
2083
 * If @key cannot be found then the return value is undefined and
 
2084
 * @error is set to #G_KEY_FILE_ERROR_KEY_NOT_FOUND. Likewise, if
 
2085
 * the values associated with @key cannot be interpreted as integers
 
2086
 * then the return value is also undefined and @error is set to
 
2087
 * #G_KEY_FILE_ERROR_INVALID_VALUE.
 
2088
 *
 
2089
 * Return value: the values associated with the key as a integer
 
2090
 *
 
2091
 * Since: 2.6
 
2092
 **/
 
2093
gint *
 
2094
g_key_file_get_integer_list (GKeyFile     *key_file,
 
2095
                             const gchar  *group_name,
 
2096
                             const gchar  *key,
 
2097
                             gsize        *length,
 
2098
                             GError      **error)
 
2099
{
 
2100
  GError *key_file_error = NULL;
 
2101
  gchar **values;
 
2102
  gint *int_values;
 
2103
  gsize i, num_ints;
 
2104
 
 
2105
  g_return_val_if_fail (key_file != NULL, NULL);
 
2106
  g_return_val_if_fail (group_name != NULL, NULL);
 
2107
  g_return_val_if_fail (key != NULL, NULL);
 
2108
 
 
2109
  values = g_key_file_get_string_list (key_file, group_name, key,
 
2110
                                       &num_ints, &key_file_error);
 
2111
 
 
2112
  if (key_file_error)
 
2113
    g_propagate_error (error, key_file_error);
 
2114
 
 
2115
  if (!values)
 
2116
    return NULL;
 
2117
 
 
2118
  int_values = g_new0 (gint, num_ints);
 
2119
 
 
2120
  for (i = 0; i < num_ints; i++)
 
2121
    {
 
2122
      int_values[i] = g_key_file_parse_value_as_integer (key_file,
 
2123
                                                         values[i],
 
2124
                                                         &key_file_error);
 
2125
 
 
2126
      if (key_file_error)
 
2127
        {
 
2128
          g_propagate_error (error, key_file_error);
 
2129
          g_strfreev (values);
 
2130
          g_free (int_values);
 
2131
 
 
2132
          return NULL;
 
2133
        }
 
2134
    }
 
2135
  g_strfreev (values);
 
2136
 
 
2137
  if (length)
 
2138
    *length = num_ints;
 
2139
 
 
2140
  return int_values;
 
2141
}
 
2142
 
 
2143
/**
 
2144
 * g_key_file_set_integer_list:
 
2145
 * @key_file: a #GKeyFile
 
2146
 * @group_name: a group name
 
2147
 * @key: a key
 
2148
 * @list: an array of integer values
 
2149
 * @length: number of integer values in @list
 
2150
 *
 
2151
 * Associates a list of integer values with @key under
 
2152
 * @group_name.  If @key cannot be found then it is created.
 
2153
 *
 
2154
 * Since: 2.6
 
2155
 **/
 
2156
void
 
2157
g_key_file_set_integer_list (GKeyFile     *key_file,
 
2158
                             const gchar  *group_name,
 
2159
                             const gchar  *key,
 
2160
                             gint          list[],
 
2161
                             gsize         length)
 
2162
{
 
2163
  GString *values;
 
2164
  gsize i;
 
2165
 
 
2166
  g_return_if_fail (key_file != NULL);
 
2167
  g_return_if_fail (list != NULL);
 
2168
 
 
2169
  values = g_string_sized_new (length * 16);
 
2170
  for (i = 0; i < length; i++)
 
2171
    {
 
2172
      gchar *value;
 
2173
 
 
2174
      value = g_key_file_parse_integer_as_value (key_file, list[i]);
 
2175
 
 
2176
      g_string_append (values, value);
 
2177
      g_string_append_c (values, ';');
 
2178
 
 
2179
      g_free (value);
 
2180
    }
 
2181
 
 
2182
  g_key_file_set_value (key_file, group_name, key, values->str);
 
2183
  g_string_free (values, TRUE);
 
2184
}
 
2185
 
 
2186
/**
 
2187
 * g_key_file_get_double:
 
2188
 * @key_file: a #GKeyFile
 
2189
 * @group_name: a group name
 
2190
 * @key: a key
 
2191
 * @error: return location for a #GError
 
2192
 *
 
2193
 * Returns the value associated with @key under @group_name as an
 
2194
 * integer. If @group_name is %NULL, the start_group is used.
 
2195
 *
 
2196
 * If @key cannot be found then the return value is undefined and
 
2197
 * @error is set to #G_KEY_FILE_ERROR_KEY_NOT_FOUND. Likewise, if
 
2198
 * the value associated with @key cannot be interpreted as a double
 
2199
 * then the return value is also undefined and @error is set to
 
2200
 * #G_KEY_FILE_ERROR_INVALID_VALUE.
 
2201
 *
 
2202
 * Return value: the value associated with the key as a double.
 
2203
 *
 
2204
 * Since: 2.12
 
2205
 **/
 
2206
gdouble
 
2207
g_key_file_get_double  (GKeyFile     *key_file,
 
2208
                        const gchar  *group_name,
 
2209
                        const gchar  *key,
 
2210
                        GError      **error)
 
2211
{
 
2212
  GError *key_file_error;
 
2213
  gchar *value;
 
2214
  gdouble double_value;
 
2215
 
 
2216
  g_return_val_if_fail (key_file != NULL, -1);
 
2217
  g_return_val_if_fail (group_name != NULL, -1);
 
2218
  g_return_val_if_fail (key != NULL, -1);
 
2219
 
 
2220
  key_file_error = NULL;
 
2221
 
 
2222
  value = g_key_file_get_value (key_file, group_name, key, &key_file_error);
 
2223
 
 
2224
  if (key_file_error)
 
2225
    {
 
2226
      g_propagate_error (error, key_file_error);
 
2227
      return 0;
 
2228
    }
 
2229
 
 
2230
  double_value = g_key_file_parse_value_as_double (key_file, value,
 
2231
                                                  &key_file_error);
 
2232
  g_free (value);
 
2233
 
 
2234
  if (key_file_error)
 
2235
    {
 
2236
      if (g_error_matches (key_file_error,
 
2237
                           G_KEY_FILE_ERROR,
 
2238
                           G_KEY_FILE_ERROR_INVALID_VALUE))
 
2239
        {
 
2240
          g_set_error (error, G_KEY_FILE_ERROR,
 
2241
                       G_KEY_FILE_ERROR_INVALID_VALUE,
 
2242
                       _("Key file contains key '%s' in group '%s' "
 
2243
                         "which has value that cannot be interpreted."), key,
 
2244
                       group_name);
 
2245
          g_error_free (key_file_error);
 
2246
        }
 
2247
      else
 
2248
        g_propagate_error (error, key_file_error);
 
2249
    }
 
2250
 
 
2251
  return double_value;
 
2252
}
 
2253
 
 
2254
/**
 
2255
 * g_key_file_set_double:
 
2256
 * @key_file: a #GKeyFile
 
2257
 * @group_name: a group name
 
2258
 * @key: a key
 
2259
 * @value: an double value
 
2260
 *
 
2261
 * Associates a new double value with @key under @group_name.
 
2262
 * If @key cannot be found then it is created. If @group_name
 
2263
 * is %NULL, the start group is used.
 
2264
 *
 
2265
 * Since: 2.12
 
2266
 **/
 
2267
void
 
2268
g_key_file_set_double  (GKeyFile    *key_file,
 
2269
                        const gchar *group_name,
 
2270
                        const gchar *key,
 
2271
                        gdouble      value)
 
2272
{
 
2273
  gchar result[G_ASCII_DTOSTR_BUF_SIZE];
 
2274
 
 
2275
  g_return_if_fail (key_file != NULL);
 
2276
 
 
2277
  g_ascii_dtostr (result, sizeof (result), value);
 
2278
  g_key_file_set_value (key_file, group_name, key, result);
 
2279
}
 
2280
 
 
2281
/**
 
2282
 * g_key_file_get_double_list:
 
2283
 * @key_file: a #GKeyFile
 
2284
 * @group_name: a group name
 
2285
 * @key: a key
 
2286
 * @length: the number of doubles returned
 
2287
 * @error: return location for a #GError
 
2288
 *
 
2289
 * Returns the values associated with @key under @group_name as
 
2290
 * doubles. If @group_name is %NULL, the start group is used.
 
2291
 *
 
2292
 * If @key cannot be found then the return value is undefined and
 
2293
 * @error is set to #G_KEY_FILE_ERROR_KEY_NOT_FOUND. Likewise, if
 
2294
 * the values associated with @key cannot be interpreted as doubles
 
2295
 * then the return value is also undefined and @error is set to
 
2296
 * #G_KEY_FILE_ERROR_INVALID_VALUE.
 
2297
 *
 
2298
 * Return value: the values associated with the key as a double
 
2299
 *
 
2300
 * Since: 2.12
 
2301
 **/
 
2302
gdouble *
 
2303
g_key_file_get_double_list  (GKeyFile     *key_file,
 
2304
                             const gchar  *group_name,
 
2305
                             const gchar  *key,
 
2306
                             gsize        *length,
 
2307
                             GError      **error)
 
2308
{
 
2309
  GError *key_file_error = NULL;
 
2310
  gchar **values;
 
2311
  gdouble *double_values;
 
2312
  gsize i, num_doubles;
 
2313
 
 
2314
  g_return_val_if_fail (key_file != NULL, NULL);
 
2315
  g_return_val_if_fail (group_name != NULL, NULL);
 
2316
  g_return_val_if_fail (key != NULL, NULL);
 
2317
 
 
2318
  values = g_key_file_get_string_list (key_file, group_name, key,
 
2319
                                       &num_doubles, &key_file_error);
 
2320
 
 
2321
  if (key_file_error)
 
2322
    g_propagate_error (error, key_file_error);
 
2323
 
 
2324
  if (!values)
 
2325
    return NULL;
 
2326
 
 
2327
  double_values = g_new0 (gdouble, num_doubles);
 
2328
 
 
2329
  for (i = 0; i < num_doubles; i++)
 
2330
    {
 
2331
      double_values[i] = g_key_file_parse_value_as_double (key_file,
 
2332
                                                           values[i],
 
2333
                                                           &key_file_error);
 
2334
 
 
2335
      if (key_file_error)
 
2336
        {
 
2337
          g_propagate_error (error, key_file_error);
 
2338
          g_strfreev (values);
 
2339
          g_free (double_values);
 
2340
 
 
2341
          return NULL;
 
2342
        }
 
2343
    }
 
2344
  g_strfreev (values);
 
2345
 
 
2346
  if (length)
 
2347
    *length = num_doubles;
 
2348
 
 
2349
  return double_values;
 
2350
}
 
2351
 
 
2352
/**
 
2353
 * g_key_file_set_double_list:
 
2354
 * @key_file: a #GKeyFile
 
2355
 * @group_name: a group name
 
2356
 * @key: a key
 
2357
 * @list: an array of double values
 
2358
 * @length: number of double values in @list
 
2359
 *
 
2360
 * Associates a list of double values with @key under
 
2361
 * @group_name.  If @key cannot be found then it is created.
 
2362
 * If @group_name is %NULL the start group is used.
 
2363
 *
 
2364
 * Since: 2.12
 
2365
 **/
 
2366
void
 
2367
g_key_file_set_double_list (GKeyFile     *key_file,
 
2368
                            const gchar  *group_name,
 
2369
                            const gchar  *key,
 
2370
                            gdouble       list[],
 
2371
                            gsize         length)
 
2372
{
 
2373
  GString *values;
 
2374
  gsize i;
 
2375
 
 
2376
  g_return_if_fail (key_file != NULL);
 
2377
  g_return_if_fail (list != NULL);
 
2378
 
 
2379
  values = g_string_sized_new (length * 16);
 
2380
  for (i = 0; i < length; i++)
 
2381
    {
 
2382
      gchar result[G_ASCII_DTOSTR_BUF_SIZE];
 
2383
 
 
2384
      g_ascii_dtostr( result, sizeof (result), list[i] );
 
2385
 
 
2386
      g_string_append (values, result);
 
2387
      g_string_append_c (values, ';');
 
2388
    }
 
2389
 
 
2390
  g_key_file_set_value (key_file, group_name, key, values->str);
 
2391
  g_string_free (values, TRUE);
 
2392
}
 
2393
 
 
2394
static void
 
2395
g_key_file_set_key_comment (GKeyFile             *key_file,
 
2396
                            const gchar          *group_name,
 
2397
                            const gchar          *key,
 
2398
                            const gchar          *comment,
 
2399
                            GError              **error)
 
2400
{
 
2401
  GKeyFileGroup *group;
 
2402
  GKeyFileKeyValuePair *pair;
 
2403
  GList *key_node, *comment_node, *tmp;
 
2404
  
 
2405
  group = g_key_file_lookup_group (key_file, group_name);
 
2406
  if (!group)
 
2407
    {
 
2408
      g_set_error (error, G_KEY_FILE_ERROR,
 
2409
                   G_KEY_FILE_ERROR_GROUP_NOT_FOUND,
 
2410
                   _("Key file does not have group '%s'"),
 
2411
                   group_name ? group_name : "(null)");
 
2412
 
 
2413
      return;
 
2414
    }
 
2415
 
 
2416
  /* First find the key the comments are supposed to be
 
2417
   * associated with
 
2418
   */
 
2419
  key_node = g_key_file_lookup_key_value_pair_node (key_file, group, key);
 
2420
 
 
2421
  if (key_node == NULL)
 
2422
    {
 
2423
      g_set_error (error, G_KEY_FILE_ERROR,
 
2424
                   G_KEY_FILE_ERROR_KEY_NOT_FOUND,
 
2425
                   _("Key file does not have key '%s' in group '%s'"),
 
2426
                   key, group->name);
 
2427
      return;
 
2428
    }
 
2429
 
 
2430
  /* Then find all the comments already associated with the
 
2431
   * key and free them
 
2432
   */
 
2433
  tmp = key_node->next;
 
2434
  while (tmp != NULL)
 
2435
    {
 
2436
      GKeyFileKeyValuePair *pair;
 
2437
 
 
2438
      pair = (GKeyFileKeyValuePair *) tmp->data;
 
2439
 
 
2440
      if (pair->key != NULL)
 
2441
        break;
 
2442
 
 
2443
      comment_node = tmp;
 
2444
      tmp = tmp->next;
 
2445
      g_key_file_remove_key_value_pair_node (key_file, group,
 
2446
                                             comment_node); 
 
2447
    }
 
2448
 
 
2449
  if (comment == NULL)
 
2450
    return;
 
2451
 
 
2452
  /* Now we can add our new comment
 
2453
   */
 
2454
  pair = g_new0 (GKeyFileKeyValuePair, 1);
 
2455
  
 
2456
  pair->key = NULL;
 
2457
  pair->value = g_key_file_parse_comment_as_value (key_file, comment);
 
2458
  
 
2459
  key_node = g_list_insert (key_node, pair, 1);
 
2460
}
 
2461
 
 
2462
static void
 
2463
g_key_file_set_group_comment (GKeyFile             *key_file,
 
2464
                              const gchar          *group_name,
 
2465
                              const gchar          *comment,
 
2466
                              GError              **error)
 
2467
{
 
2468
  GKeyFileGroup *group;
 
2469
  
 
2470
  g_return_if_fail (g_key_file_is_group_name (group_name));
 
2471
 
 
2472
  group = g_key_file_lookup_group (key_file, group_name);
 
2473
  if (!group)
 
2474
    {
 
2475
      g_set_error (error, G_KEY_FILE_ERROR,
 
2476
                   G_KEY_FILE_ERROR_GROUP_NOT_FOUND,
 
2477
                   _("Key file does not have group '%s'"),
 
2478
                   group_name ? group_name : "(null)");
 
2479
 
 
2480
      return;
 
2481
    }
 
2482
 
 
2483
  /* First remove any existing comment
 
2484
   */
 
2485
  if (group->comment)
 
2486
    {
 
2487
      g_key_file_key_value_pair_free (group->comment);
 
2488
      group->comment = NULL;
 
2489
    }
 
2490
 
 
2491
  if (comment == NULL)
 
2492
    return;
 
2493
 
 
2494
  /* Now we can add our new comment
 
2495
   */
 
2496
  group->comment = g_new0 (GKeyFileKeyValuePair, 1);
 
2497
  
 
2498
  group->comment->key = NULL;
 
2499
  group->comment->value = g_key_file_parse_comment_as_value (key_file, comment);
 
2500
}
 
2501
 
 
2502
static void
 
2503
g_key_file_set_top_comment (GKeyFile             *key_file,
 
2504
                            const gchar          *comment,
 
2505
                            GError              **error)
 
2506
{
 
2507
  GList *group_node;
 
2508
  GKeyFileGroup *group;
 
2509
  GKeyFileKeyValuePair *pair;
 
2510
 
 
2511
  /* The last group in the list should be the top (comments only)
 
2512
   * group in the file
 
2513
   */
 
2514
  g_assert (key_file->groups != NULL);
 
2515
  group_node = g_list_last (key_file->groups);
 
2516
  group = (GKeyFileGroup *) group_node->data;
 
2517
  g_assert (group->name == NULL);
 
2518
 
 
2519
  /* Note all keys must be comments at the top of
 
2520
   * the file, so we can just free it all.
 
2521
   */
 
2522
  if (group->key_value_pairs != NULL)
 
2523
    {
 
2524
      g_list_foreach (group->key_value_pairs, 
 
2525
                      (GFunc) g_key_file_key_value_pair_free, 
 
2526
                      NULL);
 
2527
      g_list_free (group->key_value_pairs);
 
2528
      group->key_value_pairs = NULL;
 
2529
    }
 
2530
 
 
2531
  if (comment == NULL)
 
2532
     return;
 
2533
 
 
2534
  pair = g_new0 (GKeyFileKeyValuePair, 1);
 
2535
  
 
2536
  pair->key = NULL;
 
2537
  pair->value = g_key_file_parse_comment_as_value (key_file, comment);
 
2538
  
 
2539
  group->key_value_pairs =
 
2540
    g_list_prepend (group->key_value_pairs, pair);
 
2541
}
 
2542
 
 
2543
/**
 
2544
 * g_key_file_set_comment:
 
2545
 * @key_file: a #GKeyFile
 
2546
 * @group_name: a group name, or %NULL
 
2547
 * @key: a key
 
2548
 * @comment: a comment
 
2549
 * @error: return location for a #GError
 
2550
 *
 
2551
 * Places a comment above @key from @group_name.
 
2552
 * @group_name. If @key is %NULL then @comment will
 
2553
 * be written above @group_name.  If both @key
 
2554
 * and @group_name are NULL, then @comment will
 
2555
 * be written above the first group in the file.
 
2556
 *
 
2557
 * Since: 2.6
 
2558
 **/
 
2559
void
 
2560
g_key_file_set_comment (GKeyFile             *key_file,
 
2561
                        const gchar          *group_name,
 
2562
                        const gchar          *key,
 
2563
                        const gchar          *comment,
 
2564
                        GError              **error)
 
2565
{
 
2566
  g_return_if_fail (key_file != NULL);
 
2567
 
 
2568
  if (group_name != NULL && key != NULL)
 
2569
    g_key_file_set_key_comment (key_file, group_name, key, comment, error);
 
2570
  else if (group_name != NULL)
 
2571
    g_key_file_set_group_comment (key_file, group_name, comment, error);
 
2572
  else
 
2573
    g_key_file_set_top_comment (key_file, comment, error);
 
2574
 
 
2575
  if (comment != NULL)
 
2576
    key_file->approximate_size += strlen (comment);
 
2577
}
 
2578
 
 
2579
static gchar *
 
2580
g_key_file_get_key_comment (GKeyFile             *key_file,
 
2581
                            const gchar          *group_name,
 
2582
                            const gchar          *key,
 
2583
                            GError              **error)
 
2584
{
 
2585
  GKeyFileGroup *group;
 
2586
  GKeyFileKeyValuePair *pair;
 
2587
  GList *key_node, *tmp;
 
2588
  GString *string;
 
2589
  gchar *comment;
 
2590
 
 
2591
  g_return_val_if_fail (g_key_file_is_group_name (group_name), NULL);
 
2592
 
 
2593
  group = g_key_file_lookup_group (key_file, group_name);
 
2594
  if (!group)
 
2595
    {
 
2596
      g_set_error (error, G_KEY_FILE_ERROR,
 
2597
                   G_KEY_FILE_ERROR_GROUP_NOT_FOUND,
 
2598
                   _("Key file does not have group '%s'"),
 
2599
                   group_name ? group_name : "(null)");
 
2600
 
 
2601
      return NULL;
 
2602
    }
 
2603
 
 
2604
  /* First find the key the comments are supposed to be
 
2605
   * associated with
 
2606
   */
 
2607
  key_node = g_key_file_lookup_key_value_pair_node (key_file, group, key);
 
2608
 
 
2609
  if (key_node == NULL)
 
2610
    {
 
2611
      g_set_error (error, G_KEY_FILE_ERROR,
 
2612
                   G_KEY_FILE_ERROR_KEY_NOT_FOUND,
 
2613
                   _("Key file does not have key '%s' in group '%s'"),
 
2614
                   key, group->name);
 
2615
      return NULL;
 
2616
    }
 
2617
 
 
2618
  string = NULL;
 
2619
 
 
2620
  /* Then find all the comments already associated with the
 
2621
   * key and concatentate them.
 
2622
   */
 
2623
  tmp = key_node->next;
 
2624
  if (!key_node->next)
 
2625
    return NULL;
 
2626
 
 
2627
  pair = (GKeyFileKeyValuePair *) tmp->data;
 
2628
  if (pair->key != NULL)
 
2629
    return NULL;
 
2630
 
 
2631
  while (tmp->next)
 
2632
    {
 
2633
      pair = (GKeyFileKeyValuePair *) tmp->next->data;
 
2634
      
 
2635
      if (pair->key != NULL)
 
2636
        break;
 
2637
 
 
2638
      tmp = tmp->next;
 
2639
    }
 
2640
 
 
2641
  while (tmp != key_node)
 
2642
    {
 
2643
      GKeyFileKeyValuePair *pair;
 
2644
      
 
2645
      pair = (GKeyFileKeyValuePair *) tmp->data;
 
2646
      
 
2647
      if (string == NULL)
 
2648
        string = g_string_sized_new (512);
 
2649
      
 
2650
      comment = g_key_file_parse_value_as_comment (key_file, pair->value);
 
2651
      g_string_append (string, comment);
 
2652
      g_free (comment);
 
2653
      
 
2654
      tmp = tmp->prev;
 
2655
    }
 
2656
 
 
2657
  if (string != NULL)
 
2658
    {
 
2659
      comment = string->str;
 
2660
      g_string_free (string, FALSE);
 
2661
    }
 
2662
  else
 
2663
    comment = NULL;
 
2664
 
 
2665
  return comment;
 
2666
}
 
2667
 
 
2668
static gchar *
 
2669
get_group_comment (GKeyFile       *key_file,
 
2670
                   GKeyFileGroup  *group,
 
2671
                   GError        **error)
 
2672
{
 
2673
  GString *string;
 
2674
  GList *tmp;
 
2675
  gchar *comment;
 
2676
 
 
2677
  string = NULL;
 
2678
 
 
2679
  tmp = group->key_value_pairs;
 
2680
  while (tmp)
 
2681
    {
 
2682
      GKeyFileKeyValuePair *pair;
 
2683
 
 
2684
      pair = (GKeyFileKeyValuePair *) tmp->data;
 
2685
 
 
2686
      if (pair->key != NULL)
 
2687
        {
 
2688
          tmp = tmp->prev;
 
2689
          break;
 
2690
        }
 
2691
 
 
2692
      if (tmp->next == NULL)
 
2693
        break;
 
2694
 
 
2695
      tmp = tmp->next;
 
2696
    }
 
2697
  
 
2698
  while (tmp != NULL)
 
2699
    {
 
2700
      GKeyFileKeyValuePair *pair;
 
2701
 
 
2702
      pair = (GKeyFileKeyValuePair *) tmp->data;
 
2703
 
 
2704
      if (string == NULL)
 
2705
        string = g_string_sized_new (512);
 
2706
 
 
2707
      comment = g_key_file_parse_value_as_comment (key_file, pair->value);
 
2708
      g_string_append (string, comment);
 
2709
      g_free (comment);
 
2710
 
 
2711
      tmp = tmp->prev;
 
2712
    }
 
2713
 
 
2714
  if (string != NULL)
 
2715
    return g_string_free (string, FALSE);
 
2716
 
 
2717
  return NULL;
 
2718
}
 
2719
 
 
2720
static gchar *
 
2721
g_key_file_get_group_comment (GKeyFile             *key_file,
 
2722
                              const gchar          *group_name,
 
2723
                              GError              **error)
 
2724
{
 
2725
  GList *group_node;
 
2726
  GKeyFileGroup *group;
 
2727
  
 
2728
  group_node = g_key_file_lookup_group_node (key_file, group_name);
 
2729
  if (!group_node)
 
2730
    {
 
2731
      g_set_error (error, G_KEY_FILE_ERROR,
 
2732
                   G_KEY_FILE_ERROR_GROUP_NOT_FOUND,
 
2733
                   _("Key file does not have group '%s'"),
 
2734
                   group_name ? group_name : "(null)");
 
2735
 
 
2736
      return NULL;
 
2737
    }
 
2738
 
 
2739
  group = (GKeyFileGroup *)group_node->data;
 
2740
  if (group->comment)
 
2741
    return g_strdup (group->comment->value);
 
2742
  
 
2743
  group_node = group_node->next;
 
2744
  group = (GKeyFileGroup *)group_node->data;  
 
2745
  return get_group_comment (key_file, group, error);
 
2746
}
 
2747
 
 
2748
static gchar *
 
2749
g_key_file_get_top_comment (GKeyFile             *key_file,
 
2750
                            GError              **error)
 
2751
{
 
2752
  GList *group_node;
 
2753
  GKeyFileGroup *group;
 
2754
 
 
2755
  /* The last group in the list should be the top (comments only)
 
2756
   * group in the file
 
2757
   */
 
2758
  g_assert (key_file->groups != NULL);
 
2759
  group_node = g_list_last (key_file->groups);
 
2760
  group = (GKeyFileGroup *) group_node->data;
 
2761
  g_assert (group->name == NULL);
 
2762
 
 
2763
  return get_group_comment (key_file, group, error);
 
2764
}
 
2765
 
 
2766
/**
 
2767
 * g_key_file_get_comment:
 
2768
 * @key_file: a #GKeyFile
 
2769
 * @group_name: a group name, or %NULL
 
2770
 * @key: a key
 
2771
 * @error: return location for a #GError
 
2772
 *
 
2773
 * Retrieves a comment above @key from @group_name.
 
2774
 * @group_name. If @key is %NULL then @comment will
 
2775
 * be read from above @group_name.  If both @key
 
2776
 * and @group_name are NULL, then @comment will
 
2777
 * be read from above the first group in the file.
 
2778
 *
 
2779
 * Returns: a comment that should be freed with g_free()
 
2780
 *
 
2781
 * Since: 2.6
 
2782
 **/
 
2783
gchar * 
 
2784
g_key_file_get_comment (GKeyFile             *key_file,
 
2785
                        const gchar          *group_name,
 
2786
                        const gchar          *key,
 
2787
                        GError              **error)
 
2788
{
 
2789
  g_return_val_if_fail (key_file != NULL, NULL);
 
2790
 
 
2791
  if (group_name != NULL && key != NULL)
 
2792
    return g_key_file_get_key_comment (key_file, group_name, key, error);
 
2793
  else if (group_name != NULL)
 
2794
    return g_key_file_get_group_comment (key_file, group_name, error);
 
2795
  else
 
2796
    return g_key_file_get_top_comment (key_file, error);
 
2797
}
 
2798
 
 
2799
/**
 
2800
 * g_key_file_remove_comment:
 
2801
 * @key_file: a #GKeyFile
 
2802
 * @group_name: a group name, or %NULL
 
2803
 * @key: a key
 
2804
 * @error: return location for a #GError
 
2805
 *
 
2806
 * Removes a comment above @key from @group_name.
 
2807
 * @group_name. If @key is %NULL then @comment will
 
2808
 * be written above @group_name.  If both @key
 
2809
 * and @group_name are NULL, then @comment will
 
2810
 * be written above the first group in the file.
 
2811
 *
 
2812
 * Since: 2.6
 
2813
 **/
 
2814
 
 
2815
void
 
2816
g_key_file_remove_comment (GKeyFile             *key_file,
 
2817
                           const gchar          *group_name,
 
2818
                           const gchar          *key,
 
2819
                           GError              **error)
 
2820
{
 
2821
  g_return_if_fail (key_file != NULL);
 
2822
 
 
2823
  if (group_name != NULL && key != NULL)
 
2824
    g_key_file_set_key_comment (key_file, group_name, key, NULL, error);
 
2825
  else if (group_name != NULL)
 
2826
    g_key_file_set_group_comment (key_file, group_name, NULL, error);
 
2827
  else
 
2828
    g_key_file_set_top_comment (key_file, NULL, error);
 
2829
}
 
2830
 
 
2831
/**
 
2832
 * g_key_file_has_group:
 
2833
 * @key_file: a #GKeyFile
 
2834
 * @group_name: a group name
 
2835
 *
 
2836
 * Looks whether the key file has the group @group_name.
 
2837
 *
 
2838
 * Return value: %TRUE if @group_name is a part of @key_file, %FALSE
 
2839
 * otherwise.
 
2840
 * Since: 2.6
 
2841
 **/
 
2842
gboolean
 
2843
g_key_file_has_group (GKeyFile    *key_file,
 
2844
                      const gchar *group_name)
 
2845
{
 
2846
  g_return_val_if_fail (key_file != NULL, FALSE);
 
2847
  g_return_val_if_fail (group_name != NULL, FALSE);
 
2848
 
 
2849
  return g_key_file_lookup_group_node (key_file, group_name) != NULL;
 
2850
}
 
2851
 
 
2852
/**
 
2853
 * g_key_file_has_key:
 
2854
 * @key_file: a #GKeyFile
 
2855
 * @group_name: a group name
 
2856
 * @key: a key name
 
2857
 * @error: return location for a #GError
 
2858
 *
 
2859
 * Looks whether the key file has the key @key in the group
 
2860
 * @group_name. 
 
2861
 *
 
2862
 * Return value: %TRUE if @key is a part of @group_name, %FALSE
 
2863
 * otherwise.
 
2864
 *
 
2865
 * Since: 2.6
 
2866
 **/
 
2867
gboolean
 
2868
g_key_file_has_key (GKeyFile     *key_file,
 
2869
                    const gchar  *group_name,
 
2870
                    const gchar  *key,
 
2871
                    GError      **error)
 
2872
{
 
2873
  GKeyFileKeyValuePair *pair;
 
2874
  GKeyFileGroup *group;
 
2875
 
 
2876
  g_return_val_if_fail (key_file != NULL, FALSE);
 
2877
  g_return_val_if_fail (group_name != NULL, FALSE);
 
2878
  g_return_val_if_fail (key != NULL, FALSE);
 
2879
 
 
2880
  group = g_key_file_lookup_group (key_file, group_name);
 
2881
 
 
2882
  if (!group)
 
2883
    {
 
2884
      g_set_error (error, G_KEY_FILE_ERROR,
 
2885
                   G_KEY_FILE_ERROR_GROUP_NOT_FOUND,
 
2886
                   _("Key file does not have group '%s'"),
 
2887
                   group_name ? group_name : "(null)");
 
2888
 
 
2889
      return FALSE;
 
2890
    }
 
2891
 
 
2892
  pair = g_key_file_lookup_key_value_pair (key_file, group, key);
 
2893
 
 
2894
  return pair != NULL;
 
2895
}
 
2896
 
 
2897
static void
 
2898
g_key_file_add_group (GKeyFile    *key_file,
 
2899
                      const gchar *group_name)
 
2900
{
 
2901
  GKeyFileGroup *group;
 
2902
 
 
2903
  g_return_if_fail (key_file != NULL);
 
2904
  g_return_if_fail (g_key_file_is_group_name (group_name));
 
2905
 
 
2906
  group = g_key_file_lookup_group (key_file, group_name);
 
2907
  if (group != NULL)
 
2908
    {
 
2909
      key_file->current_group = group;
 
2910
      return;
 
2911
    }
 
2912
 
 
2913
  group = g_new0 (GKeyFileGroup, 1);
 
2914
  group->name = g_strdup (group_name);
 
2915
  group->lookup_map = g_hash_table_new (g_str_hash, g_str_equal);
 
2916
  key_file->groups = g_list_prepend (key_file->groups, group);
 
2917
  key_file->approximate_size += strlen (group_name) + 3;
 
2918
  key_file->current_group = group;
 
2919
 
 
2920
  if (key_file->start_group == NULL)
 
2921
    key_file->start_group = group;
 
2922
}
 
2923
 
 
2924
static void
 
2925
g_key_file_key_value_pair_free (GKeyFileKeyValuePair *pair)
 
2926
{
 
2927
  if (pair != NULL)
 
2928
    {
 
2929
      g_free (pair->key);
 
2930
      g_free (pair->value);
 
2931
      g_free (pair);
 
2932
    }
 
2933
}
 
2934
 
 
2935
/* Be careful not to call this function on a node with data in the
 
2936
 * lookup map without removing it from the lookup map, first.
 
2937
 *
 
2938
 * Some current cases where this warning is not a concern are
 
2939
 * when:
 
2940
 *   - the node being removed is a comment node
 
2941
 *   - the entire lookup map is getting destroyed soon after
 
2942
 *     anyway.
 
2943
 */ 
 
2944
static void
 
2945
g_key_file_remove_key_value_pair_node (GKeyFile      *key_file,
 
2946
                                       GKeyFileGroup *group,
 
2947
                                       GList         *pair_node)
 
2948
{
 
2949
 
 
2950
  GKeyFileKeyValuePair *pair;
 
2951
 
 
2952
  pair = (GKeyFileKeyValuePair *) pair_node->data;
 
2953
 
 
2954
  group->key_value_pairs = g_list_remove_link (group->key_value_pairs, pair_node);
 
2955
 
 
2956
  if (pair->key != NULL)
 
2957
    key_file->approximate_size -= strlen (pair->key) + 1;
 
2958
 
 
2959
  g_assert (pair->value != NULL);
 
2960
  key_file->approximate_size -= strlen (pair->value);
 
2961
 
 
2962
  g_key_file_key_value_pair_free (pair);
 
2963
 
 
2964
  g_list_free_1 (pair_node);
 
2965
}
 
2966
 
 
2967
static void
 
2968
g_key_file_remove_group_node (GKeyFile *key_file,
 
2969
                              GList    *group_node)
 
2970
{
 
2971
  GKeyFileGroup *group;
 
2972
  GList *tmp;
 
2973
 
 
2974
  group = (GKeyFileGroup *) group_node->data;
 
2975
 
 
2976
  /* If the current group gets deleted make the current group the last
 
2977
   * added group.
 
2978
   */
 
2979
  if (key_file->current_group == group)
 
2980
    {
 
2981
      /* groups should always contain at least the top comment group,
 
2982
       * unless g_key_file_clear has been called
 
2983
       */
 
2984
      if (key_file->groups)
 
2985
        key_file->current_group = (GKeyFileGroup *) key_file->groups->data;
 
2986
      else
 
2987
        key_file->current_group = NULL;
 
2988
    }
 
2989
 
 
2990
  /* If the start group gets deleted make the start group the first
 
2991
   * added group.
 
2992
   */
 
2993
  if (key_file->start_group == group)
 
2994
    {
 
2995
      tmp = g_list_last (key_file->groups);
 
2996
      while (tmp != NULL)
 
2997
        {
 
2998
          if (tmp != group_node &&
 
2999
              ((GKeyFileGroup *) tmp->data)->name != NULL)
 
3000
            break;
 
3001
 
 
3002
          tmp = tmp->prev;
 
3003
        }
 
3004
 
 
3005
      if (tmp)
 
3006
        key_file->start_group = (GKeyFileGroup *) tmp->data;
 
3007
      else
 
3008
        key_file->start_group = NULL;
 
3009
    }
 
3010
 
 
3011
  key_file->groups = g_list_remove_link (key_file->groups, group_node);
 
3012
 
 
3013
  if (group->name != NULL)
 
3014
    key_file->approximate_size -= strlen (group->name) + 3;
 
3015
 
 
3016
  tmp = group->key_value_pairs;
 
3017
  while (tmp != NULL)
 
3018
    {
 
3019
      GList *pair_node;
 
3020
 
 
3021
      pair_node = tmp;
 
3022
      tmp = tmp->next;
 
3023
      g_key_file_remove_key_value_pair_node (key_file, group, pair_node);
 
3024
    }
 
3025
 
 
3026
  g_assert (group->key_value_pairs == NULL);
 
3027
 
 
3028
  if (group->lookup_map)
 
3029
    {
 
3030
      g_hash_table_destroy (group->lookup_map);
 
3031
      group->lookup_map = NULL;
 
3032
    }
 
3033
 
 
3034
  g_free ((gchar *) group->name);
 
3035
  g_free (group);
 
3036
  g_list_free_1 (group_node);
 
3037
}
 
3038
 
 
3039
/**
 
3040
 * g_key_file_remove_group:
 
3041
 * @key_file: a #GKeyFile
 
3042
 * @group_name: a group name
 
3043
 * @error: return location for a #GError or %NULL
 
3044
 *
 
3045
 * Removes the specified group, @group_name, 
 
3046
 * from the key file. 
 
3047
 *
 
3048
 * Since: 2.6
 
3049
 **/
 
3050
void
 
3051
g_key_file_remove_group (GKeyFile     *key_file,
 
3052
                         const gchar  *group_name,
 
3053
                         GError      **error)
 
3054
{
 
3055
  GList *group_node;
 
3056
 
 
3057
  g_return_if_fail (key_file != NULL);
 
3058
  g_return_if_fail (group_name != NULL);
 
3059
 
 
3060
  group_node = g_key_file_lookup_group_node (key_file, group_name);
 
3061
 
 
3062
  if (!group_node)
 
3063
    {
 
3064
      g_set_error (error, G_KEY_FILE_ERROR,
 
3065
                   G_KEY_FILE_ERROR_GROUP_NOT_FOUND,
 
3066
                   _("Key file does not have group '%s'"),
 
3067
                   group_name);
 
3068
      return;
 
3069
    }
 
3070
 
 
3071
    g_key_file_remove_group_node (key_file, group_node);
 
3072
}
 
3073
 
 
3074
static void
 
3075
g_key_file_add_key (GKeyFile      *key_file,
 
3076
                    GKeyFileGroup *group,
 
3077
                    const gchar   *key,
 
3078
                    const gchar   *value)
 
3079
{
 
3080
  GKeyFileKeyValuePair *pair;
 
3081
 
 
3082
  pair = g_new0 (GKeyFileKeyValuePair, 1);
 
3083
 
 
3084
  pair->key = g_strdup (key);
 
3085
  pair->value = g_strdup (value);
 
3086
 
 
3087
  g_hash_table_replace (group->lookup_map, pair->key, pair);
 
3088
  group->key_value_pairs = g_list_prepend (group->key_value_pairs, pair);
 
3089
  group->has_trailing_blank_line = FALSE;
 
3090
  key_file->approximate_size += strlen (key) + strlen (value) + 2;
 
3091
}
 
3092
 
 
3093
/**
 
3094
 * g_key_file_remove_key:
 
3095
 * @key_file: a #GKeyFile
 
3096
 * @group_name: a group name
 
3097
 * @key: a key name to remove
 
3098
 * @error: return location for a #GError or %NULL
 
3099
 *
 
3100
 * Removes @key in @group_name from the key file. 
 
3101
 *
 
3102
 * Since: 2.6
 
3103
 **/
 
3104
void
 
3105
g_key_file_remove_key (GKeyFile     *key_file,
 
3106
                       const gchar  *group_name,
 
3107
                       const gchar  *key,
 
3108
                       GError      **error)
 
3109
{
 
3110
  GKeyFileGroup *group;
 
3111
  GKeyFileKeyValuePair *pair;
 
3112
 
 
3113
  g_return_if_fail (key_file != NULL);
 
3114
  g_return_if_fail (group_name != NULL);
 
3115
  g_return_if_fail (key != NULL);
 
3116
 
 
3117
  pair = NULL;
 
3118
 
 
3119
  group = g_key_file_lookup_group (key_file, group_name);
 
3120
  if (!group)
 
3121
    {
 
3122
      g_set_error (error, G_KEY_FILE_ERROR,
 
3123
                   G_KEY_FILE_ERROR_GROUP_NOT_FOUND,
 
3124
                   _("Key file does not have group '%s'"),
 
3125
                   group_name ? group_name : "(null)");
 
3126
      return;
 
3127
    }
 
3128
 
 
3129
  pair = g_key_file_lookup_key_value_pair (key_file, group, key);
 
3130
 
 
3131
  if (!pair)
 
3132
    {
 
3133
      g_set_error (error, G_KEY_FILE_ERROR,
 
3134
                   G_KEY_FILE_ERROR_KEY_NOT_FOUND,
 
3135
                   _("Key file does not have key '%s' in group '%s'"),
 
3136
                   key, group->name);
 
3137
      return;
 
3138
    }
 
3139
 
 
3140
  key_file->approximate_size -= strlen (pair->key) + strlen (pair->value) + 2;
 
3141
 
 
3142
  group->key_value_pairs = g_list_remove (group->key_value_pairs, pair);
 
3143
  g_hash_table_remove (group->lookup_map, pair->key);  
 
3144
  g_key_file_key_value_pair_free (pair);
 
3145
}
 
3146
 
 
3147
static GList *
 
3148
g_key_file_lookup_group_node (GKeyFile    *key_file,
 
3149
                              const gchar *group_name)
 
3150
{
 
3151
  GKeyFileGroup *group;
 
3152
  GList *tmp;
 
3153
 
 
3154
  for (tmp = key_file->groups; tmp != NULL; tmp = tmp->next)
 
3155
    {
 
3156
      group = (GKeyFileGroup *) tmp->data;
 
3157
 
 
3158
      if (group && group->name && strcmp (group->name, group_name) == 0)
 
3159
        break;
 
3160
    }
 
3161
 
 
3162
  return tmp;
 
3163
}
 
3164
 
 
3165
static GKeyFileGroup *
 
3166
g_key_file_lookup_group (GKeyFile    *key_file,
 
3167
                         const gchar *group_name)
 
3168
{
 
3169
  GList *group_node;
 
3170
 
 
3171
  group_node = g_key_file_lookup_group_node (key_file, group_name);
 
3172
 
 
3173
  if (group_node != NULL)
 
3174
    return (GKeyFileGroup *) group_node->data; 
 
3175
 
 
3176
  return NULL;
 
3177
}
 
3178
 
 
3179
static GList *
 
3180
g_key_file_lookup_key_value_pair_node (GKeyFile       *key_file,
 
3181
                                       GKeyFileGroup  *group,
 
3182
                                       const gchar    *key)
 
3183
{
 
3184
  GList *key_node;
 
3185
 
 
3186
  for (key_node = group->key_value_pairs;
 
3187
       key_node != NULL;
 
3188
       key_node = key_node->next)
 
3189
    {
 
3190
      GKeyFileKeyValuePair *pair;
 
3191
 
 
3192
      pair = (GKeyFileKeyValuePair *) key_node->data; 
 
3193
 
 
3194
      if (pair->key && strcmp (pair->key, key) == 0)
 
3195
        break;
 
3196
    }
 
3197
 
 
3198
  return key_node;
 
3199
}
 
3200
 
 
3201
static GKeyFileKeyValuePair *
 
3202
g_key_file_lookup_key_value_pair (GKeyFile      *key_file,
 
3203
                                  GKeyFileGroup *group,
 
3204
                                  const gchar   *key)
 
3205
{
 
3206
  return (GKeyFileKeyValuePair *) g_hash_table_lookup (group->lookup_map, key);
 
3207
}
 
3208
 
 
3209
/* Lines starting with # or consisting entirely of whitespace are merely
 
3210
 * recorded, not parsed. This function assumes all leading whitespace
 
3211
 * has been stripped.
 
3212
 */
 
3213
static gboolean
 
3214
g_key_file_line_is_comment (const gchar *line)
 
3215
{
 
3216
  return (*line == '#' || *line == '\0' || *line == '\n');
 
3217
}
 
3218
 
 
3219
static gboolean 
 
3220
g_key_file_is_group_name (const gchar *name)
 
3221
{
 
3222
  gchar *p, *q;
 
3223
 
 
3224
  if (name == NULL)
 
3225
    return FALSE;
 
3226
 
 
3227
  p = q = (gchar *) name;
 
3228
  while (*q && *q != ']' && *q != '[' && !g_ascii_iscntrl (*q))
 
3229
    q = g_utf8_next_char (q);
 
3230
  
 
3231
  if (*q != '\0' || q == p)
 
3232
    return FALSE;
 
3233
 
 
3234
  return TRUE;
 
3235
}
 
3236
 
 
3237
static gboolean
 
3238
g_key_file_is_key_name (const gchar *name)
 
3239
{
 
3240
  gchar *p, *q;
 
3241
 
 
3242
  if (name == NULL)
 
3243
    return FALSE;
 
3244
 
 
3245
  p = q = (gchar *) name;
 
3246
  /* We accept a little more than the desktop entry spec says,
 
3247
   * since gnome-vfs uses mime-types as keys in its cache.
 
3248
   */
 
3249
  while (*q && *q != '=' && *q != '[' && *q != ']')
 
3250
    q = g_utf8_next_char (q);
 
3251
  
 
3252
  /* No empty keys, please */
 
3253
  if (q == p)
 
3254
    return FALSE;
 
3255
 
 
3256
  /* We accept spaces in the middle of keys to not break
 
3257
   * existing apps, but we don't tolerate initial of final
 
3258
   * spaces, which would lead to silent corruption when
 
3259
   * rereading the file.
 
3260
   */
 
3261
  if (*p == ' ' || q[-1] == ' ')
 
3262
    return FALSE;
 
3263
 
 
3264
  if (*q == '[')
 
3265
    {
 
3266
      q++;
 
3267
      while (*q && (g_unichar_isalnum (g_utf8_get_char (q)) || *q == '-' || *q == '_' || *q == '.' || *q == '@'))
 
3268
        q = g_utf8_next_char (q);
 
3269
 
 
3270
      if (*q != ']')
 
3271
        return FALSE;     
 
3272
 
 
3273
      q++;
 
3274
    }
 
3275
 
 
3276
  if (*q != '\0')
 
3277
    return FALSE;
 
3278
 
 
3279
  return TRUE;
 
3280
}
 
3281
 
 
3282
/* A group in a key file is made up of a starting '[' followed by one
 
3283
 * or more letters making up the group name followed by ']'.
 
3284
 */
 
3285
static gboolean
 
3286
g_key_file_line_is_group (const gchar *line)
 
3287
{
 
3288
  gchar *p;
 
3289
 
 
3290
  p = (gchar *) line;
 
3291
  if (*p != '[')
 
3292
    return FALSE;
 
3293
 
 
3294
  p++;
 
3295
 
 
3296
  while (*p && *p != ']')
 
3297
    p = g_utf8_next_char (p);
 
3298
 
 
3299
  if (*p != ']')
 
3300
    return FALSE;
 
3301
 
 
3302
  /* silently accept whitespace after the ] */
 
3303
  p = g_utf8_next_char (p);
 
3304
  while (*p == ' ' || *p == '\t')
 
3305
    p = g_utf8_next_char (p);
 
3306
     
 
3307
  if (*p)
 
3308
    return FALSE;
 
3309
 
 
3310
  return TRUE;
 
3311
}
 
3312
 
 
3313
static gboolean
 
3314
g_key_file_line_is_key_value_pair (const gchar *line)
 
3315
{
 
3316
  gchar *p;
 
3317
 
 
3318
  p = (gchar *) g_utf8_strchr (line, -1, '=');
 
3319
 
 
3320
  if (!p)
 
3321
    return FALSE;
 
3322
 
 
3323
  /* Key must be non-empty
 
3324
   */
 
3325
  if (*p == line[0])
 
3326
    return FALSE;
 
3327
 
 
3328
  return TRUE;
 
3329
}
 
3330
 
 
3331
static gchar *
 
3332
g_key_file_parse_value_as_string (GKeyFile     *key_file,
 
3333
                                  const gchar  *value,
 
3334
                                  GSList      **pieces,
 
3335
                                  GError      **error)
 
3336
{
 
3337
  gchar *string_value, *p, *q0, *q;
 
3338
 
 
3339
  string_value = g_new0 (gchar, strlen (value) + 1);
 
3340
 
 
3341
  p = (gchar *) value;
 
3342
  q0 = q = string_value;
 
3343
  while (*p)
 
3344
    {
 
3345
      if (*p == '\\')
 
3346
        {
 
3347
          p++;
 
3348
 
 
3349
          switch (*p)
 
3350
            {
 
3351
            case 's':
 
3352
              *q = ' ';
 
3353
              break;
 
3354
 
 
3355
            case 'n':
 
3356
              *q = '\n';
 
3357
              break;
 
3358
 
 
3359
            case 't':
 
3360
              *q = '\t';
 
3361
              break;
 
3362
 
 
3363
            case 'r':
 
3364
              *q = '\r';
 
3365
              break;
 
3366
 
 
3367
            case '\\':
 
3368
              *q = '\\';
 
3369
              break;
 
3370
 
 
3371
            case '\0':
 
3372
              g_set_error (error, G_KEY_FILE_ERROR,
 
3373
                           G_KEY_FILE_ERROR_INVALID_VALUE,
 
3374
                           _("Key file contains escape character "
 
3375
                             "at end of line"));
 
3376
              break;
 
3377
 
 
3378
            default:
 
3379
              if (pieces && *p == key_file->list_separator)
 
3380
                *q = key_file->list_separator;
 
3381
              else
 
3382
                {
 
3383
                  *q++ = '\\';
 
3384
                  *q = *p;
 
3385
                  
 
3386
                  if (*error == NULL)
 
3387
                    {
 
3388
                      gchar sequence[3];
 
3389
                      
 
3390
                      sequence[0] = '\\';
 
3391
                      sequence[1] = *p;
 
3392
                      sequence[2] = '\0';
 
3393
                      
 
3394
                      g_set_error (error, G_KEY_FILE_ERROR,
 
3395
                                   G_KEY_FILE_ERROR_INVALID_VALUE,
 
3396
                                   _("Key file contains invalid escape "
 
3397
                                     "sequence '%s'"), sequence);
 
3398
                    }
 
3399
                }
 
3400
              break;
 
3401
            }
 
3402
        }
 
3403
      else
 
3404
        {
 
3405
          *q = *p;
 
3406
          if (pieces && (*p == key_file->list_separator))
 
3407
            {
 
3408
              *pieces = g_slist_prepend (*pieces, g_strndup (q0, q - q0));
 
3409
              q0 = q + 1; 
 
3410
            }
 
3411
        }
 
3412
 
 
3413
      if (*p == '\0')
 
3414
        break;
 
3415
 
 
3416
      q++;
 
3417
      p++;
 
3418
    }
 
3419
 
 
3420
  *q = '\0';
 
3421
  if (pieces)
 
3422
  {
 
3423
    if (q0 < q)
 
3424
      *pieces = g_slist_prepend (*pieces, g_strndup (q0, q - q0));
 
3425
    *pieces = g_slist_reverse (*pieces);
 
3426
  }
 
3427
 
 
3428
  return string_value;
 
3429
}
 
3430
 
 
3431
static gchar *
 
3432
g_key_file_parse_string_as_value (GKeyFile    *key_file,
 
3433
                                  const gchar *string,
 
3434
                                  gboolean     escape_separator)
 
3435
{
 
3436
  gchar *value, *p, *q;
 
3437
  gsize length;
 
3438
  gboolean parsing_leading_space;
 
3439
 
 
3440
  length = strlen (string) + 1;
 
3441
 
 
3442
  /* Worst case would be that every character needs to be escaped.
 
3443
   * In other words every character turns to two characters
 
3444
   */
 
3445
  value = g_new0 (gchar, 2 * length);
 
3446
 
 
3447
  p = (gchar *) string;
 
3448
  q = value;
 
3449
  parsing_leading_space = TRUE;
 
3450
  while (p < (string + length - 1))
 
3451
    {
 
3452
      gchar escaped_character[3] = { '\\', 0, 0 };
 
3453
 
 
3454
      switch (*p)
 
3455
        {
 
3456
        case ' ':
 
3457
          if (parsing_leading_space)
 
3458
            {
 
3459
              escaped_character[1] = 's';
 
3460
              strcpy (q, escaped_character);
 
3461
              q += 2;
 
3462
            }
 
3463
          else
 
3464
            {
 
3465
              *q = *p;
 
3466
              q++;
 
3467
            }
 
3468
          break;
 
3469
        case '\t':
 
3470
          if (parsing_leading_space)
 
3471
            {
 
3472
              escaped_character[1] = 't';
 
3473
              strcpy (q, escaped_character);
 
3474
              q += 2;
 
3475
            }
 
3476
          else
 
3477
            {
 
3478
              *q = *p;
 
3479
              q++;
 
3480
            }
 
3481
          break;
 
3482
        case '\n':
 
3483
          escaped_character[1] = 'n';
 
3484
          strcpy (q, escaped_character);
 
3485
          q += 2;
 
3486
          break;
 
3487
        case '\r':
 
3488
          escaped_character[1] = 'r';
 
3489
          strcpy (q, escaped_character);
 
3490
          q += 2;
 
3491
          break;
 
3492
        case '\\':
 
3493
          escaped_character[1] = '\\';
 
3494
          strcpy (q, escaped_character);
 
3495
          q += 2;
 
3496
          parsing_leading_space = FALSE;
 
3497
          break;
 
3498
        default:
 
3499
          if (escape_separator && *p == key_file->list_separator)
 
3500
            {
 
3501
              escaped_character[1] = key_file->list_separator;
 
3502
              strcpy (q, escaped_character);
 
3503
              q += 2;
 
3504
              parsing_leading_space = TRUE;
 
3505
            }
 
3506
          else 
 
3507
            {
 
3508
              *q = *p;
 
3509
              q++;
 
3510
              parsing_leading_space = FALSE;
 
3511
            }
 
3512
          break;
 
3513
        }
 
3514
      p++;
 
3515
    }
 
3516
  *q = '\0';
 
3517
 
 
3518
  return value;
 
3519
}
 
3520
 
 
3521
static gint
 
3522
g_key_file_parse_value_as_integer (GKeyFile     *key_file,
 
3523
                                   const gchar  *value,
 
3524
                                   GError      **error)
 
3525
{
 
3526
  gchar *end_of_valid_int;
 
3527
  glong long_value;
 
3528
  gint int_value;
 
3529
 
 
3530
  errno = 0;
 
3531
  long_value = strtol (value, &end_of_valid_int, 10);
 
3532
 
 
3533
  if (*value == '\0' || *end_of_valid_int != '\0')
 
3534
    {
 
3535
      gchar *value_utf8 = _g_utf8_make_valid (value);
 
3536
      g_set_error (error, G_KEY_FILE_ERROR,
 
3537
                   G_KEY_FILE_ERROR_INVALID_VALUE,
 
3538
                   _("Value '%s' cannot be interpreted "
 
3539
                     "as a number."), value_utf8);
 
3540
      g_free (value_utf8);
 
3541
 
 
3542
      return 0;
 
3543
    }
 
3544
 
 
3545
  int_value = long_value;
 
3546
  if (int_value != long_value || errno == ERANGE)
 
3547
    {
 
3548
      gchar *value_utf8 = _g_utf8_make_valid (value);
 
3549
      g_set_error (error,
 
3550
                   G_KEY_FILE_ERROR, 
 
3551
                   G_KEY_FILE_ERROR_INVALID_VALUE,
 
3552
                   _("Integer value '%s' out of range"), 
 
3553
                   value_utf8);
 
3554
      g_free (value_utf8);
 
3555
 
 
3556
      return 0;
 
3557
    }
 
3558
  
 
3559
  return int_value;
 
3560
}
 
3561
 
 
3562
static gchar *
 
3563
g_key_file_parse_integer_as_value (GKeyFile *key_file,
 
3564
                                   gint      value)
 
3565
 
 
3566
{
 
3567
  return g_strdup_printf ("%d", value);
 
3568
}
 
3569
 
 
3570
static gdouble
 
3571
g_key_file_parse_value_as_double  (GKeyFile     *key_file,
 
3572
                                   const gchar  *value,
 
3573
                                   GError      **error)
 
3574
{
 
3575
  gchar *end_of_valid_d;
 
3576
  gdouble double_value = 0;
 
3577
 
 
3578
  double_value = g_ascii_strtod (value, &end_of_valid_d);
 
3579
 
 
3580
  if (*end_of_valid_d != '\0' || end_of_valid_d == value)
 
3581
    {
 
3582
      gchar *value_utf8 = _g_utf8_make_valid (value);
 
3583
      g_set_error (error, G_KEY_FILE_ERROR,
 
3584
                   G_KEY_FILE_ERROR_INVALID_VALUE,
 
3585
                   _("Value '%s' cannot be interpreted "
 
3586
                     "as a float number."), 
 
3587
                   value_utf8);
 
3588
      g_free (value_utf8);
 
3589
    }
 
3590
 
 
3591
  return double_value;
 
3592
}
 
3593
 
 
3594
static gboolean
 
3595
g_key_file_parse_value_as_boolean (GKeyFile     *key_file,
 
3596
                                   const gchar  *value,
 
3597
                                   GError      **error)
 
3598
{
 
3599
  gchar *value_utf8;
 
3600
 
 
3601
  if (value)
 
3602
    {
 
3603
      if (strcmp (value, "true") == 0 || strcmp (value, "1") == 0)
 
3604
        return TRUE;
 
3605
      else if (strcmp (value, "false") == 0 || strcmp (value, "0") == 0)
 
3606
        return FALSE;
 
3607
    }
 
3608
 
 
3609
  value_utf8 = _g_utf8_make_valid (value);
 
3610
  g_set_error (error, G_KEY_FILE_ERROR,
 
3611
               G_KEY_FILE_ERROR_INVALID_VALUE,
 
3612
               _("Value '%s' cannot be interpreted "
 
3613
                 "as a boolean."), value_utf8);
 
3614
  g_free (value_utf8);
 
3615
 
 
3616
  return FALSE;
 
3617
}
 
3618
 
 
3619
static gchar *
 
3620
g_key_file_parse_boolean_as_value (GKeyFile *key_file,
 
3621
                                   gboolean  value)
 
3622
{
 
3623
  if (value)
 
3624
    return g_strdup ("true");
 
3625
  else
 
3626
    return g_strdup ("false");
 
3627
}
 
3628
 
 
3629
static gchar *
 
3630
g_key_file_parse_value_as_comment (GKeyFile    *key_file,
 
3631
                                   const gchar *value)
 
3632
{
 
3633
  GString *string;
 
3634
  gchar **lines;
 
3635
  gsize i;
 
3636
 
 
3637
  string = g_string_sized_new (512);
 
3638
 
 
3639
  lines = g_strsplit (value, "\n", 0);
 
3640
 
 
3641
  for (i = 0; lines[i] != NULL; i++)
 
3642
    {
 
3643
        if (lines[i][0] != '#')
 
3644
           g_string_append_printf (string, "%s\n", lines[i]);
 
3645
        else 
 
3646
           g_string_append_printf (string, "%s\n", lines[i] + 1);
 
3647
    }
 
3648
  g_strfreev (lines);
 
3649
 
 
3650
  return g_string_free (string, FALSE);
 
3651
}
 
3652
 
 
3653
static gchar *
 
3654
g_key_file_parse_comment_as_value (GKeyFile      *key_file,
 
3655
                                   const gchar   *comment)
 
3656
{
 
3657
  GString *string;
 
3658
  gchar **lines;
 
3659
  gsize i;
 
3660
 
 
3661
  string = g_string_sized_new (512);
 
3662
 
 
3663
  lines = g_strsplit (comment, "\n", 0);
 
3664
 
 
3665
  for (i = 0; lines[i] != NULL; i++)
 
3666
    g_string_append_printf (string, "#%s%s", lines[i], 
 
3667
                            lines[i + 1] == NULL? "" : "\n");
 
3668
  g_strfreev (lines);
 
3669
 
 
3670
  return g_string_free (string, FALSE);
 
3671
}
 
3672
 
 
3673
#define __G_KEY_FILE_C__
 
3674
#include "galiasdef.c"