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