/* gkeyfile.c - key file parser
 *
 *  Copyright 2004  Red Hat, Inc.  
 *  Copyright 2009-2010  Collabora Ltd.
 *  Copyright 2009  Nokia Corporation
 *
 * Written by Ray Strode <rstrode@redhat.com>
 *            Matthias Clasen <mclasen@redhat.com>
 *
 * GLib is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2 of the
 * License, or (at your option) any later version.
 *
 * GLib is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with GLib; see the file COPYING.LIB.  If not,
 * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 *   Boston, MA 02111-1307, USA.
 */

#include "config.h"

#include "gkeyfile.h"
#include "gutils.h"

#include <errno.h>
#include <fcntl.h>
#include <locale.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef G_OS_WIN32
#include <io.h>

#undef fstat
#define fstat(a,b) _fstati64(a,b)
#undef stat
#define stat _stati64

#ifndef S_ISREG
#define S_ISREG(mode) ((mode)&_S_IFREG)
#endif

#endif  /* G_OS_WIN23 */

#include "gconvert.h"
#include "gdataset.h"
#include "gerror.h"
#include "gfileutils.h"
#include "ghash.h"
#include "glibintl.h"
#include "glist.h"
#include "gslist.h"
#include "gmem.h"
#include "gmessages.h"
#include "gstdio.h"
#include "gstring.h"
#include "gstrfuncs.h"
#include "gutils.h"


/**
 * SECTION:keyfile
 * @title: Key-value file parser
 * @short_description: parses .ini-like config files
 *
 * #GKeyFile lets you parse, edit or create files containing groups of
 * key-value pairs, which we call <firstterm>key files</firstterm> for
 * lack of a better name. Several freedesktop.org specifications use
 * key files now, e.g the
 * <ulink url="http://freedesktop.org/Standards/desktop-entry-spec">Desktop
 * Entry Specification</ulink> and the
 * <ulink url="http://freedesktop.org/Standards/icon-theme-spec">Icon
 * Theme Specification</ulink>.
 *
 * The syntax of key files is described in detail in the
 * <ulink url="http://freedesktop.org/Standards/desktop-entry-spec">Desktop
 * Entry Specification</ulink>, here is a quick summary: Key files
 * consists of groups of key-value pairs, interspersed with comments.
 *
 * |[
 * # this is just an example
 * # there can be comments before the first group
 *
 * [First Group]
 *
 * Name=Key File Example\tthis value shows\nescaping
 *
 * # localized strings are stored in multiple key-value pairs
 * Welcome=Hello
 * Welcome[de]=Hallo
 * Welcome[fr_FR]=Bonjour
 * Welcome[it]=Ciao
 * Welcome[be@latin]=Hello
 *
 * [Another Group]
 *
 * Numbers=2;20;-200;0
 *
 * Booleans=true;false;true;true
 * ]|
 *
 * Lines beginning with a '#' and blank lines are considered comments.
 *
 * Groups are started by a header line containing the group name enclosed
 * in '[' and ']', and ended implicitly by the start of the next group or
 * the end of the file. Each key-value pair must be contained in a group.
 *
 * Key-value pairs generally have the form <literal>key=value</literal>,
 * with the exception of localized strings, which have the form
 * <literal>key[locale]=value</literal>, with a locale identifier of the
 * form <literal>lang_COUNTRY@MODIFIER</literal> where
 * <literal>COUNTRY</literal> and <literal>MODIFIER</literal> are optional.
 * Space before and after the '=' character are ignored. Newline, tab,
 * carriage return and backslash characters in value are escaped as \n,
 * \t, \r, and \\, respectively. To preserve leading spaces in values,
 * these can also be escaped as \s.
 *
 * Key files can store strings (possibly with localized variants), integers,
 * booleans and lists of these. Lists are separated by a separator character,
 * typically ';' or ','. To use the list separator character in a value in
 * a list, it has to be escaped by prefixing it with a backslash.
 *
 * This syntax is obviously inspired by the .ini files commonly met
 * on Windows, but there are some important differences:
 * <itemizedlist>
 *   <listitem>.ini files use the ';' character to begin comments,
 *     key files use the '#' character.</listitem>
 *   <listitem>Key files do not allow for ungrouped keys meaning only
 *     comments can precede the first group.</listitem>
 *   <listitem>Key files are always encoded in UTF-8.</listitem>
 *   <listitem>Key and Group names are case-sensitive. For example, a
 *     group called <literal>[GROUP]</literal> is a different from
 *     <literal>[group]</literal>.</listitem>
 *   <listitem>.ini files don't have a strongly typed boolean entry type,
 *     they only have GetProfileInt(). In key files, only
 *     <literal>true</literal> and <literal>false</literal> (in lower case)
 *     are allowed.</listitem>
 *  </itemizedlist>
 *
 * Note that in contrast to the
 * <ulink url="http://freedesktop.org/Standards/desktop-entry-spec">Desktop
 * Entry Specification</ulink>, groups in key files may contain the same
 * key multiple times; the last entry wins. Key files may also contain
 * multiple groups with the same name; they are merged together.
 * Another difference is that keys and group names in key files are not
 * restricted to ASCII characters.
 */

/**
 * G_KEY_FILE_ERROR:
 *
 * Error domain for key file parsing. Errors in this domain will
 * be from the #GKeyFileError enumeration.
 *
 * See #GError for information on error domains.
 */

/**
 * GKeyFileError:
 * @G_KEY_FILE_ERROR_UNKNOWN_ENCODING: the text being parsed was in
 *     an unknown encoding
 * @G_KEY_FILE_ERROR_PARSE: document was ill-formed
 * @G_KEY_FILE_ERROR_NOT_FOUND: the file was not found
 * @G_KEY_FILE_ERROR_KEY_NOT_FOUND: a requested key was not found
 * @G_KEY_FILE_ERROR_GROUP_NOT_FOUND: a requested group was not found
 * @G_KEY_FILE_ERROR_INVALID_VALUE: a value could not be parsed
 *
 * Error codes returned by key file parsing.
 */

/**
 * GKeyFileFlags:
 * @G_KEY_FILE_NONE: No flags, default behaviour
 * @G_KEY_FILE_KEEP_COMMENTS: Use this flag if you plan to write the
 *     (possibly modified) contents of the key file back to a file;
 *     otherwise all comments will be lost when the key file is
 *     written back.
 * @G_KEY_FILE_KEEP_TRANSLATIONS: Use this flag if you plan to write the
 *     (possibly modified) contents of the key file back to a file;
 *     otherwise only the translations for the current language will be
 *     written back.
 *
 * Flags which influence the parsing.
 */

/**
 * G_KEY_FILE_DESKTOP_GROUP:
 *
 * The name of the main group of a desktop entry file, as defined in the
 * <ulink url="http://freedesktop.org/Standards/desktop-entry-spec">Desktop
 * Entry Specification</ulink>. Consult the specification for more
 * details about the meanings of the keys below.
 *
 * Since: 2.14
 */

/**
 * G_KEY_FILE_DESKTOP_KEY_TYPE:
 *
 * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a string
 * giving the type of the desktop entry. Usually
 * #G_KEY_FILE_DESKTOP_TYPE_APPLICATION,
 * #G_KEY_FILE_DESKTOP_TYPE_LINK, or
 * #G_KEY_FILE_DESKTOP_TYPE_DIRECTORY.
 *
 * Since: 2.14
 */

/**
 * G_KEY_FILE_DESKTOP_KEY_VERSION:
 *
 * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a string
 * giving the version of the Desktop Entry Specification used for
 * the desktop entry file.
 *
 * Since: 2.14
 */

/**
 * G_KEY_FILE_DESKTOP_KEY_NAME:
 *
 * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a localized
 * string giving the specific name of the desktop entry.
 *
 * Since: 2.14
 */

/**
 * G_KEY_FILE_DESKTOP_KEY_GENERIC_NAME:
 *
 * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a localized
 * string giving the generic name of the desktop entry.
 *
 * Since: 2.14
 */

/**
 * G_KEY_FILE_DESKTOP_KEY_NO_DISPLAY:
 *
 * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a boolean
 * stating whether the desktop entry should be shown in menus.
 *
 * Since: 2.14
 */

/**
 * G_KEY_FILE_DESKTOP_KEY_COMMENT:
 *
 * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a localized
 * string giving the tooltip for the desktop entry.
 *
 * Since: 2.14
 */

/**
 * G_KEY_FILE_DESKTOP_KEY_ICON:
 *
 * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a localized
 * string giving the name of the icon to be displayed for the desktop
 * entry.
 *
 * Since: 2.14
 */

/**
 * G_KEY_FILE_DESKTOP_KEY_HIDDEN:
 *
 * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a boolean
 * stating whether the desktop entry has been deleted by the user.
 *
 * Since: 2.14
 */

/**
 * G_KEY_FILE_DESKTOP_KEY_ONLY_SHOW_IN:
 *
 * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a list of
 * strings identifying the environments that should display the
 * desktop entry.
 *
 * Since: 2.14
 */

/**
 * G_KEY_FILE_DESKTOP_KEY_NOT_SHOW_IN:
 *
 * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a list of
 * strings identifying the environments that should not display the
 * desktop entry.
 *
 * Since: 2.14
 */

/**
 * G_KEY_FILE_DESKTOP_KEY_TRY_EXEC:
 *
 * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a string
 * giving the file name of a binary on disk used to determine if the
 * program is actually installed. It is only valid for desktop entries
 * with the <literal>Application</literal> type.
 *
 * Since: 2.14
 */

/**
 * G_KEY_FILE_DESKTOP_KEY_EXEC:
 *
 * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a string
 * giving the command line to execute. It is only valid for desktop
 * entries with the <literal>Application</literal> type.
 *
 * Since: 2.14
 */

 /**
  * G_KEY_FILE_DESKTOP_KEY_PATH:
  *
  * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a string
  * containing the working directory to run the program in. It is only
  * valid for desktop entries with the <literal>Application</literal> type.
  *
  * Since: 2.14
  */

/**
 * G_KEY_FILE_DESKTOP_KEY_TERMINAL:
 *
 * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a boolean
 * stating whether the program should be run in a terminal window.
 * It is only valid for desktop entries with the
 * <literal>Application</literal> type.
 *
 * Since: 2.14
 */

/**
 * G_KEY_FILE_DESKTOP_KEY_MIME_TYPE:
 *
 * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a list
 * of strings giving the MIME types supported by this desktop entry.
 *
 * Since: 2.14
 */

/**
 * G_KEY_FILE_DESKTOP_KEY_CATEGORIES:
 *
 * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a list
 * of strings giving the categories in which the desktop entry
 * should be shown in a menu.
 *
 * Since: 2.14
 */

/**
 * G_KEY_FILE_DESKTOP_KEY_STARTUP_NOTIFY:
 *
 * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a boolean
 * stating whether the application supports the <ulink
 * url="http://www.freedesktop.org/Standards/startup-notification-spec">Startup
 * Notification Protocol Specification</ulink>.
 *
 * Since: 2.14
 */

/**
 * G_KEY_FILE_DESKTOP_KEY_STARTUP_WM_CLASS:
 *
 * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is string
 * identifying the WM class or name hint of a window that the application
 * will create, which can be used to emulate Startup Notification with
 * older applications.
 *
 * Since: 2.14
 */

/**
 * G_KEY_FILE_DESKTOP_KEY_URL :
 *
 * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a string
 * giving the URL to access. It is only valid for desktop entries
 * with the <literal>Link</literal> type.
 *
 * Since: 2.14
 */

/**
 * G_KEY_FILE_DESKTOP_TYPE_APPLICATION:
 *
 * The value of the #G_KEY_FILE_DESKTOP_KEY_TYPE, key for desktop
 * entries representing applications.
 *
 * Since: 2.14
 */

/**
 * G_KEY_FILE_DESKTOP_TYPE_LINK:
 *
 * The value of the #G_KEY_FILE_DESKTOP_KEY_TYPE, key for desktop
 * entries representing links to documents.
 *
 * Since: 2.14
 */

/**
 * G_KEY_FILE_DESKTOP_TYPE_DIRECTORY:
 *
 * The value of the #G_KEY_FILE_DESKTOP_KEY_TYPE, key for desktop
 * entries representing directories.
 *
 * Since: 2.14
 */

typedef struct _GKeyFileGroup GKeyFileGroup;

/**
 * GKeyFile:
 *
 * The GKeyFile struct contains only private data
 * and should not be accessed directly.
 */
struct _GKeyFile
{
  GList *groups;
  GHashTable *group_hash;

  GKeyFileGroup *start_group;
  GKeyFileGroup *current_group;

  GString *parse_buffer; /* Holds up to one line of not-yet-parsed data */

  gchar list_separator;

  GKeyFileFlags flags;

  gchar **locales;

  volatile gint ref_count;
};

typedef struct _GKeyFileKeyValuePair GKeyFileKeyValuePair;

struct _GKeyFileGroup
{
  const gchar *name;  /* NULL for above first group (which will be comments) */

  GKeyFileKeyValuePair *comment; /* Special comment that is stuck to the top of a group */

  GList *key_value_pairs;

  /* Used in parallel with key_value_pairs for
   * increased lookup performance
   */
  GHashTable *lookup_map;
};

struct _GKeyFileKeyValuePair
{
  gchar *key;  /* NULL for comments */
  gchar *value;
};

static gint                  find_file_in_data_dirs            (const gchar            *file,
								const gchar           **data_dirs,
								gchar                 **output_file,
								GError                **error);
static gboolean              g_key_file_load_from_fd           (GKeyFile               *key_file,
								gint                    fd,
								GKeyFileFlags           flags,
								GError                **error);
static GList                *g_key_file_lookup_group_node      (GKeyFile               *key_file,
			                                        const gchar            *group_name);
static GKeyFileGroup        *g_key_file_lookup_group           (GKeyFile               *key_file,
								const gchar            *group_name);

static GList                *g_key_file_lookup_key_value_pair_node  (GKeyFile       *key_file,
			                                             GKeyFileGroup  *group,
                                                                     const gchar    *key);
static GKeyFileKeyValuePair *g_key_file_lookup_key_value_pair       (GKeyFile       *key_file,
                                                                     GKeyFileGroup  *group,
                                                                     const gchar    *key);

static void                  g_key_file_remove_group_node          (GKeyFile      *key_file,
							  	    GList         *group_node);
static void                  g_key_file_remove_key_value_pair_node (GKeyFile      *key_file,
                                                                    GKeyFileGroup *group,
                                                                    GList         *pair_node);

static void                  g_key_file_add_key_value_pair     (GKeyFile               *key_file,
                                                                GKeyFileGroup          *group,
                                                                GKeyFileKeyValuePair   *pair);
static void                  g_key_file_add_key                (GKeyFile               *key_file,
								GKeyFileGroup          *group,
								const gchar            *key,
								const gchar            *value);
static void                  g_key_file_add_group              (GKeyFile               *key_file,
								const gchar            *group_name);
static gboolean              g_key_file_is_group_name          (const gchar *name);
static gboolean              g_key_file_is_key_name            (const gchar *name);
static void                  g_key_file_key_value_pair_free    (GKeyFileKeyValuePair   *pair);
static gboolean              g_key_file_line_is_comment        (const gchar            *line);
static gboolean              g_key_file_line_is_group          (const gchar            *line);
static gboolean              g_key_file_line_is_key_value_pair (const gchar            *line);
static gchar                *g_key_file_parse_value_as_string  (GKeyFile               *key_file,
								const gchar            *value,
								GSList                **separators,
								GError                **error);
static gchar                *g_key_file_parse_string_as_value  (GKeyFile               *key_file,
								const gchar            *string,
								gboolean                escape_separator);
static gint                  g_key_file_parse_value_as_integer (GKeyFile               *key_file,
								const gchar            *value,
								GError                **error);
static gchar                *g_key_file_parse_integer_as_value (GKeyFile               *key_file,
								gint                    value);
static gdouble               g_key_file_parse_value_as_double  (GKeyFile               *key_file,
                                                                const gchar            *value,
                                                                GError                **error);
static gboolean              g_key_file_parse_value_as_boolean (GKeyFile               *key_file,
								const gchar            *value,
								GError                **error);
static gchar                *g_key_file_parse_boolean_as_value (GKeyFile               *key_file,
								gboolean                value);
static gchar                *g_key_file_parse_value_as_comment (GKeyFile               *key_file,
                                                                const gchar            *value);
static gchar                *g_key_file_parse_comment_as_value (GKeyFile               *key_file,
                                                                const gchar            *comment);
static void                  g_key_file_parse_key_value_pair   (GKeyFile               *key_file,
								const gchar            *line,
								gsize                   length,
								GError                **error);
static void                  g_key_file_parse_comment          (GKeyFile               *key_file,
								const gchar            *line,
								gsize                   length,
								GError                **error);
static void                  g_key_file_parse_group            (GKeyFile               *key_file,
								const gchar            *line,
								gsize                   length,
								GError                **error);
static gchar                *key_get_locale                    (const gchar            *key);
static void                  g_key_file_parse_data             (GKeyFile               *key_file,
								const gchar            *data,
								gsize                   length,
								GError                **error);
static void                  g_key_file_flush_parse_buffer     (GKeyFile               *key_file,
								GError                **error);

G_DEFINE_QUARK (g-key-file-error-quark, g_key_file_error)

static void
g_key_file_init (GKeyFile *key_file)
{  
  key_file->current_group = g_slice_new0 (GKeyFileGroup);
  key_file->groups = g_list_prepend (NULL, key_file->current_group);
  key_file->group_hash = g_hash_table_new (g_str_hash, g_str_equal);
  key_file->start_group = NULL;
  key_file->parse_buffer = g_string_sized_new (128);
  key_file->list_separator = ';';
  key_file->flags = 0;
  key_file->locales = g_strdupv ((gchar **)g_get_language_names ());
}

static void
g_key_file_clear (GKeyFile *key_file)
{
  GList *tmp, *group_node;

  if (key_file->locales) 
    {
      g_strfreev (key_file->locales);
      key_file->locales = NULL;
    }

  if (key_file->parse_buffer)
    {
      g_string_free (key_file->parse_buffer, TRUE);
      key_file->parse_buffer = NULL;
    }

  tmp = key_file->groups;
  while (tmp != NULL)
    {
      group_node = tmp;
      tmp = tmp->next;
      g_key_file_remove_group_node (key_file, group_node);
    }

  if (key_file->group_hash != NULL)
    {
      g_hash_table_destroy (key_file->group_hash);
      key_file->group_hash = NULL;
    }

  g_warn_if_fail (key_file->groups == NULL);
}


/**
 * g_key_file_new:
 *
 * Creates a new empty #GKeyFile object. Use
 * g_key_file_load_from_file(), g_key_file_load_from_data(),
 * g_key_file_load_from_dirs() or g_key_file_load_from_data_dirs() to
 * read an existing key file.
 *
 * Return value: (transfer full): an empty #GKeyFile.
 *
 * Since: 2.6
 **/
GKeyFile *
g_key_file_new (void)
{
  GKeyFile *key_file;

  key_file = g_slice_new0 (GKeyFile);
  key_file->ref_count = 1;
  g_key_file_init (key_file);

  return key_file;
}

/**
 * g_key_file_set_list_separator:
 * @key_file: a #GKeyFile 
 * @separator: the separator
 *
 * Sets the character which is used to separate
 * values in lists. Typically ';' or ',' are used
 * as separators. The default list separator is ';'.
 *
 * Since: 2.6
 */
void
g_key_file_set_list_separator (GKeyFile *key_file,
			       gchar     separator)
{
  g_return_if_fail (key_file != NULL);

  key_file->list_separator = separator;
}


/* Iterates through all the directories in *dirs trying to
 * open file.  When it successfully locates and opens a file it
 * returns the file descriptor to the open file.  It also
 * outputs the absolute path of the file in output_file.
 */
static gint
find_file_in_data_dirs (const gchar   *file,
                        const gchar  **dirs,
                        gchar        **output_file,
                        GError       **error)
{
  const gchar **data_dirs, *data_dir;
  gchar *path;
  gint fd;

  path = NULL;
  fd = -1;

  if (dirs == NULL)
    return fd;

  data_dirs = dirs;

  while (data_dirs && (data_dir = *data_dirs) && fd == -1)
    {
      gchar *candidate_file, *sub_dir;

      candidate_file = (gchar *) file;
      sub_dir = g_strdup ("");
      while (candidate_file != NULL && fd == -1)
        {
          gchar *p;

          path = g_build_filename (data_dir, sub_dir,
                                   candidate_file, NULL);

          fd = g_open (path, O_RDONLY, 0);

          if (fd == -1)
            {
              g_free (path);
              path = NULL;
            }

          candidate_file = strchr (candidate_file, '-');

          if (candidate_file == NULL)
            break;

          candidate_file++;

          g_free (sub_dir);
          sub_dir = g_strndup (file, candidate_file - file - 1);

          for (p = sub_dir; *p != '\0'; p++)
            {
              if (*p == '-')
                *p = G_DIR_SEPARATOR;
            }
        }
      g_free (sub_dir);
      data_dirs++;
    }

  if (fd == -1)
    {
      g_set_error_literal (error, G_KEY_FILE_ERROR,
                           G_KEY_FILE_ERROR_NOT_FOUND,
                           _("Valid key file could not be "
                             "found in search dirs"));
    }

  if (output_file != NULL && fd > 0)
    *output_file = g_strdup (path);

  g_free (path);

  return fd;
}

static gboolean
g_key_file_load_from_fd (GKeyFile       *key_file,
			 gint            fd,
			 GKeyFileFlags   flags,
			 GError        **error)
{
  GError *key_file_error = NULL;
  gssize bytes_read;
  struct stat stat_buf;
  gchar read_buf[4096];
  gchar list_separator;

  if (fstat (fd, &stat_buf) < 0)
    {
      g_set_error_literal (error, G_FILE_ERROR,
                           g_file_error_from_errno (errno),
                           g_strerror (errno));
      return FALSE;
    }

  if (!S_ISREG (stat_buf.st_mode))
    {
      g_set_error_literal (error, G_KEY_FILE_ERROR,
                           G_KEY_FILE_ERROR_PARSE,
                           _("Not a regular file"));
      return FALSE;
    }

  list_separator = key_file->list_separator;
  g_key_file_clear (key_file);
  g_key_file_init (key_file);
  key_file->list_separator = list_separator;
  key_file->flags = flags;

  do
    {
      bytes_read = read (fd, read_buf, 4096);

      if (bytes_read == 0)  /* End of File */
        break;

      if (bytes_read < 0)
        {
          if (errno == EINTR || errno == EAGAIN)
            continue;

          g_set_error_literal (error, G_FILE_ERROR,
                               g_file_error_from_errno (errno),
                               g_strerror (errno));
          return FALSE;
        }

      g_key_file_parse_data (key_file,
			     read_buf, bytes_read,
			     &key_file_error);
    }
  while (!key_file_error);

  if (key_file_error)
    {
      g_propagate_error (error, key_file_error);
      return FALSE;
    }

  g_key_file_flush_parse_buffer (key_file, &key_file_error);

  if (key_file_error)
    {
      g_propagate_error (error, key_file_error);
      return FALSE;
    }

  return TRUE;
}

/**
 * g_key_file_load_from_file:
 * @key_file: an empty #GKeyFile struct
 * @file: (type filename): the path of a filename to load, in the GLib filename encoding
 * @flags: flags from #GKeyFileFlags
 * @error: return location for a #GError, or %NULL
 *
 * Loads a key file into an empty #GKeyFile structure.
 * If the file could not be loaded then @error is set to
 * either a #GFileError or #GKeyFileError.
 *
 * Return value: %TRUE if a key file could be loaded, %FALSE otherwise
 *
 * Since: 2.6
 **/
gboolean
g_key_file_load_from_file (GKeyFile       *key_file,
			   const gchar    *file,
			   GKeyFileFlags   flags,
			   GError        **error)
{
  GError *key_file_error = NULL;
  gint fd;

  g_return_val_if_fail (key_file != NULL, FALSE);
  g_return_val_if_fail (file != NULL, FALSE);

  fd = g_open (file, O_RDONLY, 0);

  if (fd == -1)
    {
      g_set_error_literal (error, G_FILE_ERROR,
                           g_file_error_from_errno (errno),
                           g_strerror (errno));
      return FALSE;
    }

  g_key_file_load_from_fd (key_file, fd, flags, &key_file_error);
  close (fd);

  if (key_file_error)
    {
      g_propagate_error (error, key_file_error);
      return FALSE;
    }

  return TRUE;
}

/**
 * g_key_file_load_from_data:
 * @key_file: an empty #GKeyFile struct
 * @data: key file loaded in memory
 * @length: the length of @data in bytes (or -1 if data is nul-terminated)
 * @flags: flags from #GKeyFileFlags
 * @error: return location for a #GError, or %NULL
 *
 * Loads a key file from memory into an empty #GKeyFile structure.  
 * If the object cannot be created then %error is set to a #GKeyFileError. 
 *
 * Return value: %TRUE if a key file could be loaded, %FALSE otherwise
 *
 * Since: 2.6
 **/
gboolean
g_key_file_load_from_data (GKeyFile       *key_file,
			   const gchar    *data,
			   gsize           length,
			   GKeyFileFlags   flags,
			   GError        **error)
{
  GError *key_file_error = NULL;
  gchar list_separator;

  g_return_val_if_fail (key_file != NULL, FALSE);
  g_return_val_if_fail (data != NULL || length == 0, FALSE);

  if (length == (gsize)-1)
    length = strlen (data);

  list_separator = key_file->list_separator;
  g_key_file_clear (key_file);
  g_key_file_init (key_file);
  key_file->list_separator = list_separator;
  key_file->flags = flags;

  g_key_file_parse_data (key_file, data, length, &key_file_error);
  
  if (key_file_error)
    {
      g_propagate_error (error, key_file_error);
      return FALSE;
    }

  g_key_file_flush_parse_buffer (key_file, &key_file_error);
  
  if (key_file_error)
    {
      g_propagate_error (error, key_file_error);
      return FALSE;
    }

  return TRUE;
}

/**
 * g_key_file_load_from_dirs:
 * @key_file: an empty #GKeyFile struct
 * @file: (type filename): a relative path to a filename to open and parse
 * @search_dirs: (array zero-terminated=1) (element-type filename): %NULL-terminated array of directories to search
 * @full_path: (out) (type filename) (allow-none): return location for a string containing the full path
 *   of the file, or %NULL
 * @flags: flags from #GKeyFileFlags
 * @error: return location for a #GError, or %NULL
 *
 * This function looks for a key file named @file in the paths
 * specified in @search_dirs, loads the file into @key_file and
 * returns the file's full path in @full_path.  If the file could not
 * be loaded then an %error is set to either a #GFileError or
 * #GKeyFileError.
 *
 * Return value: %TRUE if a key file could be loaded, %FALSE otherwise
 *
 * Since: 2.14
 **/
gboolean
g_key_file_load_from_dirs (GKeyFile       *key_file,
                           const gchar    *file,
                           const gchar   **search_dirs,
                           gchar         **full_path,
                           GKeyFileFlags   flags,
                           GError        **error)
{
  GError *key_file_error = NULL;
  const gchar **data_dirs;
  gchar *output_path;
  gint fd;
  gboolean found_file;

  g_return_val_if_fail (key_file != NULL, FALSE);
  g_return_val_if_fail (!g_path_is_absolute (file), FALSE);
  g_return_val_if_fail (search_dirs != NULL, FALSE);

  found_file = FALSE;
  data_dirs = search_dirs;
  output_path = NULL;
  while (*data_dirs != NULL && !found_file)
    {
      g_free (output_path);

      fd = find_file_in_data_dirs (file, data_dirs, &output_path,
                                   &key_file_error);

      if (fd == -1)
        {
          if (key_file_error)
            g_propagate_error (error, key_file_error);
 	  break;
        }

      found_file = g_key_file_load_from_fd (key_file, fd, flags,
	                                    &key_file_error);
      close (fd);

      if (key_file_error)
        {
	  g_propagate_error (error, key_file_error);
	  break;
        }
    }

  if (found_file && full_path)
    *full_path = output_path;
  else
    g_free (output_path);

  return found_file;
}

/**
 * g_key_file_load_from_data_dirs:
 * @key_file: an empty #GKeyFile struct
 * @file: (type filename): a relative path to a filename to open and parse
 * @full_path: (out) (type filename) (allow-none): return location for a string containing the full path
 *   of the file, or %NULL
 * @flags: flags from #GKeyFileFlags 
 * @error: return location for a #GError, or %NULL
 *
 * This function looks for a key file named @file in the paths 
 * returned from g_get_user_data_dir() and g_get_system_data_dirs(), 
 * loads the file into @key_file and returns the file's full path in 
 * @full_path.  If the file could not be loaded then an %error is
 * set to either a #GFileError or #GKeyFileError.
 *
 * Return value: %TRUE if a key file could be loaded, %FALSE othewise
 * Since: 2.6
 **/
gboolean
g_key_file_load_from_data_dirs (GKeyFile       *key_file,
				const gchar    *file,
				gchar         **full_path,
				GKeyFileFlags   flags,
				GError        **error)
{
  gchar **all_data_dirs;
  const gchar * user_data_dir;
  const gchar * const * system_data_dirs;
  gsize i, j;
  gboolean found_file;

  g_return_val_if_fail (key_file != NULL, FALSE);
  g_return_val_if_fail (!g_path_is_absolute (file), FALSE);

  user_data_dir = g_get_user_data_dir ();
  system_data_dirs = g_get_system_data_dirs ();
  all_data_dirs = g_new (gchar *, g_strv_length ((gchar **)system_data_dirs) + 2);

  i = 0;
  all_data_dirs[i++] = g_strdup (user_data_dir);

  j = 0;
  while (system_data_dirs[j] != NULL)
    all_data_dirs[i++] = g_strdup (system_data_dirs[j++]);
  all_data_dirs[i] = NULL;

  found_file = g_key_file_load_from_dirs (key_file,
                                          file,
                                          (const gchar **)all_data_dirs,
                                          full_path,
                                          flags,
                                          error);

  g_strfreev (all_data_dirs);

  return found_file;
}

/**
 * g_key_file_ref: (skip)
 * @key_file: a #GKeyFile
 *
 * Increases the reference count of @key_file.
 *
 * Returns: the same @key_file.
 *
 * Since: 2.32
 **/
GKeyFile *
g_key_file_ref (GKeyFile *key_file)
{
  g_return_val_if_fail (key_file != NULL, NULL);

  g_atomic_int_inc (&key_file->ref_count);

  return key_file;
}

/**
 * g_key_file_free: (skip)
 * @key_file: a #GKeyFile
 *
 * Clears all keys and groups from @key_file, and decreases the
 * reference count by 1. If the reference count reaches zero,
 * frees the key file and all its allocated memory.
 *
 * Since: 2.6
 **/
void
g_key_file_free (GKeyFile *key_file)
{
  g_return_if_fail (key_file != NULL);

  g_key_file_clear (key_file);
  g_key_file_unref (key_file);
}

/**
 * g_key_file_unref:
 * @key_file: a #GKeyFile
 *
 * Decreases the reference count of @key_file by 1. If the reference count
 * reaches zero, frees the key file and all its allocated memory.
 *
 * Since: 2.32
 **/
void
g_key_file_unref (GKeyFile *key_file)
{
  g_return_if_fail (key_file != NULL);

  if (g_atomic_int_dec_and_test (&key_file->ref_count))
    {
      g_key_file_clear (key_file);
      g_slice_free (GKeyFile, key_file);
    }
}

/* If G_KEY_FILE_KEEP_TRANSLATIONS is not set, only returns
 * true for locales that match those in g_get_language_names().
 */
static gboolean
g_key_file_locale_is_interesting (GKeyFile    *key_file,
				  const gchar *locale)
{
  gsize i;

  if (key_file->flags & G_KEY_FILE_KEEP_TRANSLATIONS)
    return TRUE;

  for (i = 0; key_file->locales[i] != NULL; i++)
    {
      if (g_ascii_strcasecmp (key_file->locales[i], locale) == 0)
	return TRUE;
    }

  return FALSE;
}

static void
g_key_file_parse_line (GKeyFile     *key_file,
		       const gchar  *line,
		       gsize         length,
		       GError      **error)
{
  GError *parse_error = NULL;
  gchar *line_start;

  g_return_if_fail (key_file != NULL);
  g_return_if_fail (line != NULL);

  line_start = (gchar *) line;
  while (g_ascii_isspace (*line_start))
    line_start++;

  if (g_key_file_line_is_comment (line_start))
    g_key_file_parse_comment (key_file, line, length, &parse_error);
  else if (g_key_file_line_is_group (line_start))
    g_key_file_parse_group (key_file, line_start,
			    length - (line_start - line),
			    &parse_error);
  else if (g_key_file_line_is_key_value_pair (line_start))
    g_key_file_parse_key_value_pair (key_file, line_start,
				     length - (line_start - line),
				     &parse_error);
  else
    {
      gchar *line_utf8 = _g_utf8_make_valid (line);
      g_set_error (error, G_KEY_FILE_ERROR,
                   G_KEY_FILE_ERROR_PARSE,
                   _("Key file contains line '%s' which is not "
                     "a key-value pair, group, or comment"),
                   line_utf8);
      g_free (line_utf8);

      return;
    }

  if (parse_error)
    g_propagate_error (error, parse_error);
}

static void
g_key_file_parse_comment (GKeyFile     *key_file,
			  const gchar  *line,
			  gsize         length,
			  GError      **error)
{
  GKeyFileKeyValuePair *pair;
  
  if (!(key_file->flags & G_KEY_FILE_KEEP_COMMENTS))
    return;
  
  g_warn_if_fail (key_file->current_group != NULL);

  pair = g_slice_new (GKeyFileKeyValuePair);
  pair->key = NULL;
  pair->value = g_strndup (line, length);
  
  key_file->current_group->key_value_pairs =
    g_list_prepend (key_file->current_group->key_value_pairs, pair);
}

static void
g_key_file_parse_group (GKeyFile     *key_file,
			const gchar  *line,
			gsize         length,
			GError      **error)
{
  gchar *group_name;
  const gchar *group_name_start, *group_name_end;
  
  /* advance past opening '['
   */
  group_name_start = line + 1;
  group_name_end = line + length - 1;
  
  while (*group_name_end != ']')
    group_name_end--;

  group_name = g_strndup (group_name_start, 
                          group_name_end - group_name_start);
  
  if (!g_key_file_is_group_name (group_name))
    {
      g_set_error (error, G_KEY_FILE_ERROR,
		   G_KEY_FILE_ERROR_PARSE,
		   _("Invalid group name: %s"), group_name);
      g_free (group_name);
      return;
    }

  g_key_file_add_group (key_file, group_name);
  g_free (group_name);
}

static void
g_key_file_parse_key_value_pair (GKeyFile     *key_file,
				 const gchar  *line,
				 gsize         length,
				 GError      **error)
{
  gchar *key, *value, *key_end, *value_start, *locale;
  gsize key_len, value_len;

  if (key_file->current_group == NULL || key_file->current_group->name == NULL)
    {
      g_set_error_literal (error, G_KEY_FILE_ERROR,
                           G_KEY_FILE_ERROR_GROUP_NOT_FOUND,
                           _("Key file does not start with a group"));
      return;
    }

  key_end = value_start = strchr (line, '=');

  g_warn_if_fail (key_end != NULL);

  key_end--;
  value_start++;

  /* Pull the key name from the line (chomping trailing whitespace)
   */
  while (g_ascii_isspace (*key_end))
    key_end--;

  key_len = key_end - line + 2;

  g_warn_if_fail (key_len <= length);

  key = g_strndup (line, key_len - 1);

  if (!g_key_file_is_key_name (key))
    {
      g_set_error (error, G_KEY_FILE_ERROR,
                   G_KEY_FILE_ERROR_PARSE,
                   _("Invalid key name: %s"), key);
      g_free (key);
      return; 
    }

  /* Pull the value from the line (chugging leading whitespace)
   */
  while (g_ascii_isspace (*value_start))
    value_start++;

  value_len = line + length - value_start + 1;

  value = g_strndup (value_start, value_len);

  g_warn_if_fail (key_file->start_group != NULL);

  if (key_file->current_group
      && key_file->current_group->name
      && strcmp (key_file->start_group->name,
                 key_file->current_group->name) == 0
      && strcmp (key, "Encoding") == 0)
    {
      if (g_ascii_strcasecmp (value, "UTF-8") != 0)
        {
	  gchar *value_utf8 = _g_utf8_make_valid (value);
          g_set_error (error, G_KEY_FILE_ERROR,
                       G_KEY_FILE_ERROR_UNKNOWN_ENCODING,
                       _("Key file contains unsupported "
			 "encoding '%s'"), value_utf8);
	  g_free (value_utf8);

          g_free (key);
          g_free (value);
          return;
        }
    }

  /* Is this key a translation? If so, is it one that we care about?
   */
  locale = key_get_locale (key);

  if (locale == NULL || g_key_file_locale_is_interesting (key_file, locale))
    {
      GKeyFileKeyValuePair *pair;

      pair = g_slice_new (GKeyFileKeyValuePair);
      pair->key = key;
      pair->value = value;

      g_key_file_add_key_value_pair (key_file, key_file->current_group, pair);
    }
  else
    {
      g_free (key);
      g_free (value);
    }

  g_free (locale);
}

static gchar *
key_get_locale (const gchar *key)
{
  gchar *locale;

  locale = g_strrstr (key, "[");

  if (locale && strlen (locale) <= 2)
    locale = NULL;

  if (locale)
    locale = g_strndup (locale + 1, strlen (locale) - 2);

  return locale;
}

static void
g_key_file_parse_data (GKeyFile     *key_file,
		       const gchar  *data,
		       gsize         length,
		       GError      **error)
{
  GError *parse_error;
  gsize i;

  g_return_if_fail (key_file != NULL);
  g_return_if_fail (data != NULL || length == 0);

  parse_error = NULL;

  i = 0;
  while (i < length)
    {
      if (data[i] == '\n')
        {
	  if (key_file->parse_buffer->len > 0
	      && (key_file->parse_buffer->str[key_file->parse_buffer->len - 1]
		  == '\r'))
	    g_string_erase (key_file->parse_buffer,
			    key_file->parse_buffer->len - 1,
			    1);
	    
          /* When a newline is encountered flush the parse buffer so that the
           * line can be parsed.  Note that completely blank lines won't show
           * up in the parse buffer, so they get parsed directly.
           */
          if (key_file->parse_buffer->len > 0)
            g_key_file_flush_parse_buffer (key_file, &parse_error);
          else
            g_key_file_parse_comment (key_file, "", 1, &parse_error);

          if (parse_error)
            {
              g_propagate_error (error, parse_error);
              return;
            }
          i++;
        }
      else
        {
          const gchar *start_of_line;
          const gchar *end_of_line;
          gsize line_length;

          start_of_line = data + i;
          end_of_line = memchr (start_of_line, '\n', length - i);

          if (end_of_line == NULL)
            end_of_line = data + length;

          line_length = end_of_line - start_of_line;

          g_string_append_len (key_file->parse_buffer, start_of_line, line_length);
          i += line_length;
        }
    }
}

static void
g_key_file_flush_parse_buffer (GKeyFile  *key_file,
			       GError   **error)
{
  GError *file_error = NULL;

  g_return_if_fail (key_file != NULL);

  file_error = NULL;

  if (key_file->parse_buffer->len > 0)
    {
      g_key_file_parse_line (key_file, key_file->parse_buffer->str,
			     key_file->parse_buffer->len,
			     &file_error);
      g_string_erase (key_file->parse_buffer, 0, -1);

      if (file_error)
        {
          g_propagate_error (error, file_error);
          return;
        }
    }
}

/**
 * g_key_file_to_data:
 * @key_file: a #GKeyFile
 * @length: (out) (allow-none): return location for the length of the
 *   returned string, or %NULL
 * @error: return location for a #GError, or %NULL
 *
 * This function outputs @key_file as a string.  
 *
 * Note that this function never reports an error,
 * so it is safe to pass %NULL as @error.
 *
 * Return value: a newly allocated string holding
 *   the contents of the #GKeyFile 
 *
 * Since: 2.6
 **/
gchar *
g_key_file_to_data (GKeyFile  *key_file,
		    gsize     *length,
		    GError   **error)
{
  GString *data_string;
  GList *group_node, *key_file_node;

  g_return_val_if_fail (key_file != NULL, NULL);

  data_string = g_string_new (NULL);

  for (group_node = g_list_last (key_file->groups);
       group_node != NULL;
       group_node = group_node->prev)
    {
      GKeyFileGroup *group;

      group = (GKeyFileGroup *) group_node->data;

      /* separate groups by at least an empty line */
      if (data_string->len >= 2 &&
          data_string->str[data_string->len - 2] != '\n')
        g_string_append_c (data_string, '\n');

      if (group->comment != NULL)
        g_string_append_printf (data_string, "%s\n", group->comment->value);

      if (group->name != NULL)
        g_string_append_printf (data_string, "[%s]\n", group->name);

      for (key_file_node = g_list_last (group->key_value_pairs);
           key_file_node != NULL;
           key_file_node = key_file_node->prev)
        {
          GKeyFileKeyValuePair *pair;

          pair = (GKeyFileKeyValuePair *) key_file_node->data;

          if (pair->key != NULL)
            g_string_append_printf (data_string, "%s=%s\n", pair->key, pair->value);
          else
            g_string_append_printf (data_string, "%s\n", pair->value);
        }
    }

  if (length)
    *length = data_string->len;

  return g_string_free (data_string, FALSE);
}

/**
 * g_key_file_get_keys:
 * @key_file: a #GKeyFile
 * @group_name: a group name
 * @length: (out) (allow-none): return location for the number of keys returned, or %NULL
 * @error: return location for a #GError, or %NULL
 *
 * Returns all keys for the group name @group_name.  The array of
 * returned keys will be %NULL-terminated, so @length may
 * optionally be %NULL. In the event that the @group_name cannot
 * be found, %NULL is returned and @error is set to
 * #G_KEY_FILE_ERROR_GROUP_NOT_FOUND.
 *
 * Return value: (array zero-terminated=1) (transfer full): a newly-allocated %NULL-terminated array of strings.
 *     Use g_strfreev() to free it.
 *
 * Since: 2.6
 **/
gchar **
g_key_file_get_keys (GKeyFile     *key_file,
		     const gchar  *group_name,
		     gsize        *length,
		     GError      **error)
{
  GKeyFileGroup *group;
  GList *tmp;
  gchar **keys;
  gsize i, num_keys;
  
  g_return_val_if_fail (key_file != NULL, NULL);
  g_return_val_if_fail (group_name != NULL, NULL);
  
  group = g_key_file_lookup_group (key_file, group_name);
  
  if (!group)
    {
      g_set_error (error, G_KEY_FILE_ERROR,
                   G_KEY_FILE_ERROR_GROUP_NOT_FOUND,
                   _("Key file does not have group '%s'"),
                   group_name ? group_name : "(null)");
      return NULL;
    }

  num_keys = 0;
  for (tmp = group->key_value_pairs; tmp; tmp = tmp->next)
    {
      GKeyFileKeyValuePair *pair;

      pair = (GKeyFileKeyValuePair *) tmp->data;

      if (pair->key)
	num_keys++;
    }
  
  keys = g_new (gchar *, num_keys + 1);

  i = num_keys - 1;
  for (tmp = group->key_value_pairs; tmp; tmp = tmp->next)
    {
      GKeyFileKeyValuePair *pair;

      pair = (GKeyFileKeyValuePair *) tmp->data;

      if (pair->key)
	{
	  keys[i] = g_strdup (pair->key);
	  i--;
	}
    }

  keys[num_keys] = NULL;

  if (length)
    *length = num_keys;

  return keys;
}

/**
 * g_key_file_get_start_group:
 * @key_file: a #GKeyFile
 *
 * Returns the name of the start group of the file. 
 *
 * Return value: The start group of the key file.
 *
 * Since: 2.6
 **/
gchar *
g_key_file_get_start_group (GKeyFile *key_file)
{
  g_return_val_if_fail (key_file != NULL, NULL);

  if (key_file->start_group)
    return g_strdup (key_file->start_group->name);

  return NULL;
}

/**
 * g_key_file_get_groups:
 * @key_file: a #GKeyFile
 * @length: (out) (allow-none): return location for the number of returned groups, or %NULL
 *
 * Returns all groups in the key file loaded with @key_file.  
 * The array of returned groups will be %NULL-terminated, so 
 * @length may optionally be %NULL.
 *
 * Return value: (array zero-terminated=1) (transfer full): a newly-allocated %NULL-terminated array of strings.
 *   Use g_strfreev() to free it.
 * Since: 2.6
 **/
gchar **
g_key_file_get_groups (GKeyFile *key_file,
		       gsize    *length)
{
  GList *group_node;
  gchar **groups;
  gsize i, num_groups;

  g_return_val_if_fail (key_file != NULL, NULL);

  num_groups = g_list_length (key_file->groups);

  g_return_val_if_fail (num_groups > 0, NULL);

  group_node = g_list_last (key_file->groups);
  
  g_return_val_if_fail (((GKeyFileGroup *) group_node->data)->name == NULL, NULL);

  /* Only need num_groups instead of num_groups + 1
   * because the first group of the file (last in the
   * list) is always the comment group at the top,
   * which we skip
   */
  groups = g_new (gchar *, num_groups);


  i = 0;
  for (group_node = group_node->prev;
       group_node != NULL;
       group_node = group_node->prev)
    {
      GKeyFileGroup *group;

      group = (GKeyFileGroup *) group_node->data;

      g_warn_if_fail (group->name != NULL);

      groups[i++] = g_strdup (group->name);
    }
  groups[i] = NULL;

  if (length)
    *length = i;

  return groups;
}

/**
 * g_key_file_get_value:
 * @key_file: a #GKeyFile
 * @group_name: a group name
 * @key: a key
 * @error: return location for a #GError, or %NULL
 *
 * Returns the raw value associated with @key under @group_name. 
 * Use g_key_file_get_string() to retrieve an unescaped UTF-8 string. 
 *
 * In the event the key cannot be found, %NULL is returned and 
 * @error is set to #G_KEY_FILE_ERROR_KEY_NOT_FOUND.  In the 
 * event that the @group_name cannot be found, %NULL is returned 
 * and @error is set to #G_KEY_FILE_ERROR_GROUP_NOT_FOUND.
 *
 *
 * Return value: a newly allocated string or %NULL if the specified 
 *  key cannot be found.
 *
 * Since: 2.6
 **/
gchar *
g_key_file_get_value (GKeyFile     *key_file,
		      const gchar  *group_name,
		      const gchar  *key,
		      GError      **error)
{
  GKeyFileGroup *group;
  GKeyFileKeyValuePair *pair;
  gchar *value = NULL;

  g_return_val_if_fail (key_file != NULL, NULL);
  g_return_val_if_fail (group_name != NULL, NULL);
  g_return_val_if_fail (key != NULL, NULL);
  
  group = g_key_file_lookup_group (key_file, group_name);

  if (!group)
    {
      g_set_error (error, G_KEY_FILE_ERROR,
                   G_KEY_FILE_ERROR_GROUP_NOT_FOUND,
                   _("Key file does not have group '%s'"),
                   group_name ? group_name : "(null)");
      return NULL;
    }

  pair = g_key_file_lookup_key_value_pair (key_file, group, key);

  if (pair)
    value = g_strdup (pair->value);
  else
    g_set_error (error, G_KEY_FILE_ERROR,
                 G_KEY_FILE_ERROR_KEY_NOT_FOUND,
                 _("Key file does not have key '%s'"), key);

  return value;
}

/**
 * g_key_file_set_value:
 * @key_file: a #GKeyFile
 * @group_name: a group name
 * @key: a key
 * @value: a string
 *
 * Associates a new value with @key under @group_name.  
 *
 * If @key cannot be found then it is created. If @group_name cannot 
 * be found then it is created. To set an UTF-8 string which may contain 
 * characters that need escaping (such as newlines or spaces), use 
 * g_key_file_set_string().
 *
 * Since: 2.6
 **/
void
g_key_file_set_value (GKeyFile    *key_file,
		      const gchar *group_name,
		      const gchar *key,
		      const gchar *value)
{
  GKeyFileGroup *group;
  GKeyFileKeyValuePair *pair;

  g_return_if_fail (key_file != NULL);
  g_return_if_fail (g_key_file_is_group_name (group_name));
  g_return_if_fail (g_key_file_is_key_name (key));
  g_return_if_fail (value != NULL);

  group = g_key_file_lookup_group (key_file, group_name);

  if (!group)
    {
      g_key_file_add_group (key_file, group_name);
      group = (GKeyFileGroup *) key_file->groups->data;

      g_key_file_add_key (key_file, group, key, value);
    }
  else
    {
      pair = g_key_file_lookup_key_value_pair (key_file, group, key);

      if (!pair)
        g_key_file_add_key (key_file, group, key, value);
      else
        {
          g_free (pair->value);
          pair->value = g_strdup (value);
        }
    }
}

/**
 * g_key_file_get_string:
 * @key_file: a #GKeyFile
 * @group_name: a group name
 * @key: a key
 * @error: return location for a #GError, or %NULL
 *
 * Returns the string value associated with @key under @group_name.
 * Unlike g_key_file_get_value(), this function handles escape sequences
 * like \s.
 *
 * In the event the key cannot be found, %NULL is returned and 
 * @error is set to #G_KEY_FILE_ERROR_KEY_NOT_FOUND.  In the 
 * event that the @group_name cannot be found, %NULL is returned 
 * and @error is set to #G_KEY_FILE_ERROR_GROUP_NOT_FOUND.
 *
 * Return value: a newly allocated string or %NULL if the specified 
 *   key cannot be found.
 *
 * Since: 2.6
 **/
gchar *
g_key_file_get_string (GKeyFile     *key_file,
		       const gchar  *group_name,
		       const gchar  *key,
		       GError      **error)
{
  gchar *value, *string_value;
  GError *key_file_error;

  g_return_val_if_fail (key_file != NULL, NULL);
  g_return_val_if_fail (group_name != NULL, NULL);
  g_return_val_if_fail (key != NULL, NULL);

  key_file_error = NULL;

  value = g_key_file_get_value (key_file, group_name, key, &key_file_error);

  if (key_file_error)
    {
      g_propagate_error (error, key_file_error);
      return NULL;
    }

  if (!g_utf8_validate (value, -1, NULL))
    {
      gchar *value_utf8 = _g_utf8_make_valid (value);
      g_set_error (error, G_KEY_FILE_ERROR,
                   G_KEY_FILE_ERROR_UNKNOWN_ENCODING,
                   _("Key file contains key '%s' with value '%s' "
                     "which is not UTF-8"), key, value_utf8);
      g_free (value_utf8);
      g_free (value);

      return NULL;
    }

  string_value = g_key_file_parse_value_as_string (key_file, value, NULL,
						   &key_file_error);
  g_free (value);

  if (key_file_error)
    {
      if (g_error_matches (key_file_error,
                           G_KEY_FILE_ERROR,
                           G_KEY_FILE_ERROR_INVALID_VALUE))
        {
          g_set_error (error, G_KEY_FILE_ERROR,
                       G_KEY_FILE_ERROR_INVALID_VALUE,
                       _("Key file contains key '%s' "
                         "which has a value that cannot be interpreted."),
                       key);
          g_error_free (key_file_error);
        }
      else
        g_propagate_error (error, key_file_error);
    }

  return string_value;
}

/**
 * g_key_file_set_string:
 * @key_file: a #GKeyFile
 * @group_name: a group name
 * @key: a key
 * @string: a string
 *
 * Associates a new string value with @key under @group_name.  
 * If @key cannot be found then it is created.  
 * If @group_name cannot be found then it is created.
 * Unlike g_key_file_set_value(), this function handles characters
 * that need escaping, such as newlines.
 *
 * Since: 2.6
 **/
void
g_key_file_set_string (GKeyFile    *key_file,
		       const gchar *group_name,
		       const gchar *key,
		       const gchar *string)
{
  gchar *value;

  g_return_if_fail (key_file != NULL);
  g_return_if_fail (string != NULL);

  value = g_key_file_parse_string_as_value (key_file, string, FALSE);
  g_key_file_set_value (key_file, group_name, key, value);
  g_free (value);
}

/**
 * g_key_file_get_string_list:
 * @key_file: a #GKeyFile
 * @group_name: a group name
 * @key: a key
 * @length: (out) (allow-none): return location for the number of returned strings, or %NULL
 * @error: return location for a #GError, or %NULL
 *
 * Returns the values associated with @key under @group_name.
 *
 * In the event the key cannot be found, %NULL is returned and
 * @error is set to #G_KEY_FILE_ERROR_KEY_NOT_FOUND.  In the
 * event that the @group_name cannot be found, %NULL is returned
 * and @error is set to #G_KEY_FILE_ERROR_GROUP_NOT_FOUND.
 *
 * Return value: (array zero-terminated=1 length=length) (element-type utf8) (transfer full): 
 *  a %NULL-terminated string array or %NULL if the specified 
 *  key cannot be found. The array should be freed with g_strfreev().
 *
 * Since: 2.6
 **/
gchar **
g_key_file_get_string_list (GKeyFile     *key_file,
			    const gchar  *group_name,
			    const gchar  *key,
			    gsize        *length,
			    GError      **error)
{
  GError *key_file_error = NULL;
  gchar *value, *string_value, **values;
  gint i, len;
  GSList *p, *pieces = NULL;

  g_return_val_if_fail (key_file != NULL, NULL);
  g_return_val_if_fail (group_name != NULL, NULL);
  g_return_val_if_fail (key != NULL, NULL);

  if (length)
    *length = 0;

  value = g_key_file_get_value (key_file, group_name, key, &key_file_error);

  if (key_file_error)
    {
      g_propagate_error (error, key_file_error);
      return NULL;
    }

  if (!g_utf8_validate (value, -1, NULL))
    {
      gchar *value_utf8 = _g_utf8_make_valid (value);
      g_set_error (error, G_KEY_FILE_ERROR,
                   G_KEY_FILE_ERROR_UNKNOWN_ENCODING,
                   _("Key file contains key '%s' with value '%s' "
                     "which is not UTF-8"), key, value_utf8);
      g_free (value_utf8);
      g_free (value);

      return NULL;
    }

  string_value = g_key_file_parse_value_as_string (key_file, value, &pieces, &key_file_error);
  g_free (value);
  g_free (string_value);

  if (key_file_error)
    {
      if (g_error_matches (key_file_error,
                           G_KEY_FILE_ERROR,
                           G_KEY_FILE_ERROR_INVALID_VALUE))
        {
          g_set_error (error, G_KEY_FILE_ERROR,
                       G_KEY_FILE_ERROR_INVALID_VALUE,
                       _("Key file contains key '%s' "
                         "which has a value that cannot be interpreted."),
                       key);
          g_error_free (key_file_error);
        }
      else
        g_propagate_error (error, key_file_error);

      g_slist_free_full (pieces, g_free);
      return NULL;
    }

  len = g_slist_length (pieces);
  values = g_new (gchar *, len + 1);
  for (p = pieces, i = 0; p; p = p->next)
    values[i++] = p->data;
  values[len] = NULL;

  g_slist_free (pieces);

  if (length)
    *length = len;

  return values;
}

/**
 * g_key_file_set_string_list:
 * @key_file: a #GKeyFile
 * @group_name: a group name
 * @key: a key
 * @list: (array zero-terminated=1 length=length) (element-type utf8): an array of string values
 * @length: number of string values in @list
 *
 * Associates a list of string values for @key under @group_name.
 * If @key cannot be found then it is created.
 * If @group_name cannot be found then it is created.
 *
 * Since: 2.6
 **/
void
g_key_file_set_string_list (GKeyFile            *key_file,
			    const gchar         *group_name,
			    const gchar         *key,
			    const gchar * const  list[],
			    gsize                length)
{
  GString *value_list;
  gsize i;

  g_return_if_fail (key_file != NULL);
  g_return_if_fail (list != NULL || length == 0);

  value_list = g_string_sized_new (length * 128);
  for (i = 0; i < length && list[i] != NULL; i++)
    {
      gchar *value;

      value = g_key_file_parse_string_as_value (key_file, list[i], TRUE);
      g_string_append (value_list, value);
      g_string_append_c (value_list, key_file->list_separator);

      g_free (value);
    }

  g_key_file_set_value (key_file, group_name, key, value_list->str);
  g_string_free (value_list, TRUE);
}

/**
 * g_key_file_set_locale_string:
 * @key_file: a #GKeyFile
 * @group_name: a group name
 * @key: a key
 * @locale: a locale identifier
 * @string: a string
 *
 * Associates a string value for @key and @locale under @group_name.
 * If the translation for @key cannot be found then it is created.
 *
 * Since: 2.6
 **/
void
g_key_file_set_locale_string (GKeyFile     *key_file,
			      const gchar  *group_name,
			      const gchar  *key,
			      const gchar  *locale,
			      const gchar  *string)
{
  gchar *full_key, *value;

  g_return_if_fail (key_file != NULL);
  g_return_if_fail (key != NULL);
  g_return_if_fail (locale != NULL);
  g_return_if_fail (string != NULL);

  value = g_key_file_parse_string_as_value (key_file, string, FALSE);
  full_key = g_strdup_printf ("%s[%s]", key, locale);
  g_key_file_set_value (key_file, group_name, full_key, value);
  g_free (full_key);
  g_free (value);
}

/**
 * g_key_file_get_locale_string:
 * @key_file: a #GKeyFile
 * @group_name: a group name
 * @key: a key
 * @locale: (allow-none): a locale identifier or %NULL
 * @error: return location for a #GError, or %NULL
 *
 * Returns the value associated with @key under @group_name
 * translated in the given @locale if available.  If @locale is
 * %NULL then the current locale is assumed. 
 *
 * If @key cannot be found then %NULL is returned and @error is set 
 * to #G_KEY_FILE_ERROR_KEY_NOT_FOUND. If the value associated
 * with @key cannot be interpreted or no suitable translation can
 * be found then the untranslated value is returned.
 *
 * Return value: a newly allocated string or %NULL if the specified 
 *   key cannot be found.
 *
 * Since: 2.6
 **/
gchar *
g_key_file_get_locale_string (GKeyFile     *key_file,
			      const gchar  *group_name,
			      const gchar  *key,
			      const gchar  *locale,
			      GError      **error)
{
  gchar *candidate_key, *translated_value;
  GError *key_file_error;
  gchar **languages;
  gboolean free_languages = FALSE;
  gint i;

  g_return_val_if_fail (key_file != NULL, NULL);
  g_return_val_if_fail (group_name != NULL, NULL);
  g_return_val_if_fail (key != NULL, NULL);

  candidate_key = NULL;
  translated_value = NULL;
  key_file_error = NULL;

  if (locale)
    {
      languages = g_get_locale_variants (locale);
      free_languages = TRUE;
    }
  else
    {
      languages = (gchar **) g_get_language_names ();
      free_languages = FALSE;
    }
  
  for (i = 0; languages[i]; i++)
    {
      candidate_key = g_strdup_printf ("%s[%s]", key, languages[i]);
      
      translated_value = g_key_file_get_string (key_file,
						group_name,
						candidate_key, NULL);
      g_free (candidate_key);

      if (translated_value)
	break;

      g_free (translated_value);
      translated_value = NULL;
   }

  /* Fallback to untranslated key
   */
  if (!translated_value)
    {
      translated_value = g_key_file_get_string (key_file, group_name, key,
						&key_file_error);
      
      if (!translated_value)
        g_propagate_error (error, key_file_error);
    }

  if (free_languages)
    g_strfreev (languages);

  return translated_value;
}

/**
 * g_key_file_get_locale_string_list:
 * @key_file: a #GKeyFile
 * @group_name: a group name
 * @key: a key
 * @locale: (allow-none): a locale identifier or %NULL
 * @length: (out) (allow-none): return location for the number of returned strings or %NULL
 * @error: return location for a #GError or %NULL
 *
 * Returns the values associated with @key under @group_name
 * translated in the given @locale if available.  If @locale is
 * %NULL then the current locale is assumed.

 * If @key cannot be found then %NULL is returned and @error is set 
 * to #G_KEY_FILE_ERROR_KEY_NOT_FOUND. If the values associated
 * with @key cannot be interpreted or no suitable translations
 * can be found then the untranslated values are returned. The 
 * returned array is %NULL-terminated, so @length may optionally 
 * be %NULL.
 *
 * Return value: (array zero-terminated=1 length=length) (element-type utf8) (transfer full): a newly allocated %NULL-terminated string array
 *   or %NULL if the key isn't found. The string array should be freed
 *   with g_strfreev().
 *
 * Since: 2.6
 **/
gchar **
g_key_file_get_locale_string_list (GKeyFile     *key_file,
				   const gchar  *group_name,
				   const gchar  *key,
				   const gchar  *locale,
				   gsize        *length,
				   GError      **error)
{
  GError *key_file_error;
  gchar **values, *value;
  char list_separator[2];
  gsize len;

  g_return_val_if_fail (key_file != NULL, NULL);
  g_return_val_if_fail (group_name != NULL, NULL);
  g_return_val_if_fail (key != NULL, NULL);

  key_file_error = NULL;

  value = g_key_file_get_locale_string (key_file, group_name, 
					key, locale,
					&key_file_error);
  
  if (key_file_error)
    g_propagate_error (error, key_file_error);
  
  if (!value)
    {
      if (length)
        *length = 0;
      return NULL;
    }

  len = strlen (value);
  if (value[len - 1] == key_file->list_separator)
    value[len - 1] = '\0';

  list_separator[0] = key_file->list_separator;
  list_separator[1] = '\0';
  values = g_strsplit (value, list_separator, 0);

  g_free (value);

  if (length)
    *length = g_strv_length (values);

  return values;
}

/**
 * g_key_file_set_locale_string_list:
 * @key_file: a #GKeyFile
 * @group_name: a group name
 * @key: a key
 * @locale: a locale identifier
 * @list: (array zero-terminated=1 length=length): a %NULL-terminated array of locale string values
 * @length: the length of @list
 *
 * Associates a list of string values for @key and @locale under
 * @group_name.  If the translation for @key cannot be found then
 * it is created. 
 *
 * Since: 2.6
 **/
void
g_key_file_set_locale_string_list (GKeyFile            *key_file,
				   const gchar         *group_name,
				   const gchar         *key,
				   const gchar         *locale,
				   const gchar * const  list[],
				   gsize                length)
{
  GString *value_list;
  gchar *full_key;
  gsize i;

  g_return_if_fail (key_file != NULL);
  g_return_if_fail (key != NULL);
  g_return_if_fail (locale != NULL);
  g_return_if_fail (length != 0);

  value_list = g_string_sized_new (length * 128);
  for (i = 0; i < length && list[i] != NULL; i++)
    {
      gchar *value;
      
      value = g_key_file_parse_string_as_value (key_file, list[i], TRUE);
      g_string_append (value_list, value);
      g_string_append_c (value_list, key_file->list_separator);

      g_free (value);
    }

  full_key = g_strdup_printf ("%s[%s]", key, locale);
  g_key_file_set_value (key_file, group_name, full_key, value_list->str);
  g_free (full_key);
  g_string_free (value_list, TRUE);
}

/**
 * g_key_file_get_boolean:
 * @key_file: a #GKeyFile
 * @group_name: a group name
 * @key: a key
 * @error: return location for a #GError
 *
 * Returns the value associated with @key under @group_name as a
 * boolean. 
 *
 * If @key cannot be found then %FALSE is returned and @error is set
 * to #G_KEY_FILE_ERROR_KEY_NOT_FOUND. Likewise, if the value
 * associated with @key cannot be interpreted as a boolean then %FALSE
 * is returned and @error is set to #G_KEY_FILE_ERROR_INVALID_VALUE.
 *
 * Return value: the value associated with the key as a boolean, 
 *    or %FALSE if the key was not found or could not be parsed.
 *
 * Since: 2.6
 **/
gboolean
g_key_file_get_boolean (GKeyFile     *key_file,
			const gchar  *group_name,
			const gchar  *key,
			GError      **error)
{
  GError *key_file_error = NULL;
  gchar *value;
  gboolean bool_value;

  g_return_val_if_fail (key_file != NULL, FALSE);
  g_return_val_if_fail (group_name != NULL, FALSE);
  g_return_val_if_fail (key != NULL, FALSE);

  value = g_key_file_get_value (key_file, group_name, key, &key_file_error);

  if (!value)
    {
      g_propagate_error (error, key_file_error);
      return FALSE;
    }

  bool_value = g_key_file_parse_value_as_boolean (key_file, value,
						  &key_file_error);
  g_free (value);

  if (key_file_error)
    {
      if (g_error_matches (key_file_error,
                           G_KEY_FILE_ERROR,
                           G_KEY_FILE_ERROR_INVALID_VALUE))
        {
          g_set_error (error, G_KEY_FILE_ERROR,
                       G_KEY_FILE_ERROR_INVALID_VALUE,
                       _("Key file contains key '%s' "
                         "which has a value that cannot be interpreted."),
                       key);
          g_error_free (key_file_error);
        }
      else
        g_propagate_error (error, key_file_error);
    }

  return bool_value;
}

/**
 * g_key_file_set_boolean:
 * @key_file: a #GKeyFile
 * @group_name: a group name
 * @key: a key
 * @value: %TRUE or %FALSE
 *
 * Associates a new boolean value with @key under @group_name.
 * If @key cannot be found then it is created. 
 *
 * Since: 2.6
 **/
void
g_key_file_set_boolean (GKeyFile    *key_file,
			const gchar *group_name,
			const gchar *key,
			gboolean     value)
{
  gchar *result;

  g_return_if_fail (key_file != NULL);

  result = g_key_file_parse_boolean_as_value (key_file, value);
  g_key_file_set_value (key_file, group_name, key, result);
  g_free (result);
}

/**
 * g_key_file_get_boolean_list:
 * @key_file: a #GKeyFile
 * @group_name: a group name
 * @key: a key
 * @length: (out): the number of booleans returned
 * @error: return location for a #GError
 *
 * Returns the values associated with @key under @group_name as
 * booleans. 
 *
 * If @key cannot be found then %NULL is returned and @error is set to
 * #G_KEY_FILE_ERROR_KEY_NOT_FOUND. Likewise, if the values associated
 * with @key cannot be interpreted as booleans then %NULL is returned
 * and @error is set to #G_KEY_FILE_ERROR_INVALID_VALUE.
 *
 * Return value: (array length=length) (element-type gboolean) (transfer container):
 *    the values associated with the key as a list of booleans, or %NULL if the
 *    key was not found or could not be parsed. The returned list of booleans
 *    should be freed with g_free() when no longer needed.
 * 
 * Since: 2.6
 **/
gboolean *
g_key_file_get_boolean_list (GKeyFile     *key_file,
			     const gchar  *group_name,
			     const gchar  *key,
			     gsize        *length,
			     GError      **error)
{
  GError *key_file_error;
  gchar **values;
  gboolean *bool_values;
  gsize i, num_bools;

  g_return_val_if_fail (key_file != NULL, NULL);
  g_return_val_if_fail (group_name != NULL, NULL);
  g_return_val_if_fail (key != NULL, NULL);

  if (length)
    *length = 0;

  key_file_error = NULL;

  values = g_key_file_get_string_list (key_file, group_name, key,
				       &num_bools, &key_file_error);

  if (key_file_error)
    g_propagate_error (error, key_file_error);

  if (!values)
    return NULL;

  bool_values = g_new (gboolean, num_bools);

  for (i = 0; i < num_bools; i++)
    {
      bool_values[i] = g_key_file_parse_value_as_boolean (key_file,
							  values[i],
							  &key_file_error);

      if (key_file_error)
        {
          g_propagate_error (error, key_file_error);
          g_strfreev (values);
          g_free (bool_values);

          return NULL;
        }
    }
  g_strfreev (values);

  if (length)
    *length = num_bools;

  return bool_values;
}

/**
 * g_key_file_set_boolean_list:
 * @key_file: a #GKeyFile
 * @group_name: a group name
 * @key: a key
 * @list: (array length=length): an array of boolean values
 * @length: length of @list
 *
 * Associates a list of boolean values with @key under @group_name.  
 * If @key cannot be found then it is created.
 * If @group_name is %NULL, the start_group is used.
 *
 * Since: 2.6
 **/
void
g_key_file_set_boolean_list (GKeyFile    *key_file,
			     const gchar *group_name,
			     const gchar *key,
			     gboolean     list[],
			     gsize        length)
{
  GString *value_list;
  gsize i;

  g_return_if_fail (key_file != NULL);
  g_return_if_fail (list != NULL);

  value_list = g_string_sized_new (length * 8);
  for (i = 0; i < length; i++)
    {
      gchar *value;

      value = g_key_file_parse_boolean_as_value (key_file, list[i]);

      g_string_append (value_list, value);
      g_string_append_c (value_list, key_file->list_separator);

      g_free (value);
    }

  g_key_file_set_value (key_file, group_name, key, value_list->str);
  g_string_free (value_list, TRUE);
}

/**
 * g_key_file_get_integer:
 * @key_file: a #GKeyFile
 * @group_name: a group name
 * @key: a key
 * @error: return location for a #GError
 *
 * Returns the value associated with @key under @group_name as an
 * integer. 
 *
 * If @key cannot be found then 0 is returned and @error is set to
 * #G_KEY_FILE_ERROR_KEY_NOT_FOUND. Likewise, if the value associated
 * with @key cannot be interpreted as an integer then 0 is returned
 * and @error is set to #G_KEY_FILE_ERROR_INVALID_VALUE.
 *
 * Return value: the value associated with the key as an integer, or
 *     0 if the key was not found or could not be parsed.
 *
 * Since: 2.6
 **/
gint
g_key_file_get_integer (GKeyFile     *key_file,
			const gchar  *group_name,
			const gchar  *key,
			GError      **error)
{
  GError *key_file_error;
  gchar *value;
  gint int_value;

  g_return_val_if_fail (key_file != NULL, -1);
  g_return_val_if_fail (group_name != NULL, -1);
  g_return_val_if_fail (key != NULL, -1);

  key_file_error = NULL;

  value = g_key_file_get_value (key_file, group_name, key, &key_file_error);

  if (key_file_error)
    {
      g_propagate_error (error, key_file_error);
      return 0;
    }

  int_value = g_key_file_parse_value_as_integer (key_file, value,
						 &key_file_error);
  g_free (value);

  if (key_file_error)
    {
      if (g_error_matches (key_file_error,
                           G_KEY_FILE_ERROR,
                           G_KEY_FILE_ERROR_INVALID_VALUE))
        {
          g_set_error (error, G_KEY_FILE_ERROR,
                       G_KEY_FILE_ERROR_INVALID_VALUE,
                       _("Key file contains key '%s' in group '%s' "
                         "which has a value that cannot be interpreted."),
                         key, group_name);
          g_error_free (key_file_error);
        }
      else
        g_propagate_error (error, key_file_error);
    }

  return int_value;
}

/**
 * g_key_file_set_integer:
 * @key_file: a #GKeyFile
 * @group_name: a group name
 * @key: a key
 * @value: an integer value
 *
 * Associates a new integer value with @key under @group_name.
 * If @key cannot be found then it is created.
 *
 * Since: 2.6
 **/
void
g_key_file_set_integer (GKeyFile    *key_file,
			const gchar *group_name,
			const gchar *key,
			gint         value)
{
  gchar *result;

  g_return_if_fail (key_file != NULL);

  result = g_key_file_parse_integer_as_value (key_file, value);
  g_key_file_set_value (key_file, group_name, key, result);
  g_free (result);
}

/**
 * g_key_file_get_int64:
 * @key_file: a non-%NULL #GKeyFile
 * @group_name: a non-%NULL group name
 * @key: a non-%NULL key
 * @error: return location for a #GError
 *
 * Returns the value associated with @key under @group_name as a signed
 * 64-bit integer. This is similar to g_key_file_get_integer() but can return
 * 64-bit results without truncation.
 *
 * Returns: the value associated with the key as a signed 64-bit integer, or
 * 0 if the key was not found or could not be parsed.
 *
 * Since: 2.26
 */
gint64
g_key_file_get_int64 (GKeyFile     *key_file,
                      const gchar  *group_name,
                      const gchar  *key,
                      GError      **error)
{
  gchar *s, *end;
  gint64 v;

  g_return_val_if_fail (key_file != NULL, -1);
  g_return_val_if_fail (group_name != NULL, -1);
  g_return_val_if_fail (key != NULL, -1);

  s = g_key_file_get_value (key_file, group_name, key, error);

  if (s == NULL)
    return 0;

  v = g_ascii_strtoll (s, &end, 10);

  if (*s == '\0' || *end != '\0')
    {
      g_set_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE,
                   _("Key '%s' in group '%s' has value '%s' "
                     "where %s was expected"),
                   key, group_name, s, "int64");
      g_free (s);
      return 0;
    }

  g_free (s);
  return v;
}

/**
 * g_key_file_set_int64:
 * @key_file: a #GKeyFile
 * @group_name: a group name
 * @key: a key
 * @value: an integer value
 *
 * Associates a new integer value with @key under @group_name.
 * If @key cannot be found then it is created.
 *
 * Since: 2.26
 **/
void
g_key_file_set_int64 (GKeyFile    *key_file,
                      const gchar *group_name,
                      const gchar *key,
                      gint64       value)
{
  gchar *result;

  g_return_if_fail (key_file != NULL);

  result = g_strdup_printf ("%" G_GINT64_FORMAT, value);
  g_key_file_set_value (key_file, group_name, key, result);
  g_free (result);
}

/**
 * g_key_file_get_uint64:
 * @key_file: a non-%NULL #GKeyFile
 * @group_name: a non-%NULL group name
 * @key: a non-%NULL key
 * @error: return location for a #GError
 *
 * Returns the value associated with @key under @group_name as an unsigned
 * 64-bit integer. This is similar to g_key_file_get_integer() but can return
 * large positive results without truncation.
 *
 * Returns: the value associated with the key as an unsigned 64-bit integer,
 * or 0 if the key was not found or could not be parsed.
 *
 * Since: 2.26
 */
guint64
g_key_file_get_uint64 (GKeyFile     *key_file,
                       const gchar  *group_name,
                       const gchar  *key,
                       GError      **error)
{
  gchar *s, *end;
  guint64 v;

  g_return_val_if_fail (key_file != NULL, -1);
  g_return_val_if_fail (group_name != NULL, -1);
  g_return_val_if_fail (key != NULL, -1);

  s = g_key_file_get_value (key_file, group_name, key, error);

  if (s == NULL)
    return 0;

  v = g_ascii_strtoull (s, &end, 10);

  if (*s == '\0' || *end != '\0')
    {
      g_set_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE,
                   _("Key '%s' in group '%s' has value '%s' "
                     "where %s was expected"),
                   key, group_name, s, "uint64");
      g_free (s);
      return 0;
    }

  g_free (s);
  return v;
}

/**
 * g_key_file_set_uint64:
 * @key_file: a #GKeyFile
 * @group_name: a group name
 * @key: a key
 * @value: an integer value
 *
 * Associates a new integer value with @key under @group_name.
 * If @key cannot be found then it is created.
 *
 * Since: 2.26
 **/
void
g_key_file_set_uint64 (GKeyFile    *key_file,
                       const gchar *group_name,
                       const gchar *key,
                       guint64      value)
{
  gchar *result;

  g_return_if_fail (key_file != NULL);

  result = g_strdup_printf ("%" G_GUINT64_FORMAT, value);
  g_key_file_set_value (key_file, group_name, key, result);
  g_free (result);
}

/**
 * g_key_file_get_integer_list:
 * @key_file: a #GKeyFile
 * @group_name: a group name
 * @key: a key
 * @length: (out): the number of integers returned
 * @error: return location for a #GError
 *
 * Returns the values associated with @key under @group_name as
 * integers. 
 *
 * If @key cannot be found then %NULL is returned and @error is set to
 * #G_KEY_FILE_ERROR_KEY_NOT_FOUND. Likewise, if the values associated
 * with @key cannot be interpreted as integers then %NULL is returned
 * and @error is set to #G_KEY_FILE_ERROR_INVALID_VALUE.
 *
 * Return value: (array length=length) (element-type gint) (transfer container):
 *     the values associated with the key as a list of integers, or %NULL if
 *     the key was not found or could not be parsed. The returned list of
 *     integers should be freed with g_free() when no longer needed.
 *
 * Since: 2.6
 **/
gint *
g_key_file_get_integer_list (GKeyFile     *key_file,
			     const gchar  *group_name,
			     const gchar  *key,
			     gsize        *length,
			     GError      **error)
{
  GError *key_file_error = NULL;
  gchar **values;
  gint *int_values;
  gsize i, num_ints;

  g_return_val_if_fail (key_file != NULL, NULL);
  g_return_val_if_fail (group_name != NULL, NULL);
  g_return_val_if_fail (key != NULL, NULL);

  if (length)
    *length = 0;

  values = g_key_file_get_string_list (key_file, group_name, key,
				       &num_ints, &key_file_error);

  if (key_file_error)
    g_propagate_error (error, key_file_error);

  if (!values)
    return NULL;

  int_values = g_new (gint, num_ints);

  for (i = 0; i < num_ints; i++)
    {
      int_values[i] = g_key_file_parse_value_as_integer (key_file,
							 values[i],
							 &key_file_error);

      if (key_file_error)
        {
          g_propagate_error (error, key_file_error);
          g_strfreev (values);
          g_free (int_values);

          return NULL;
        }
    }
  g_strfreev (values);

  if (length)
    *length = num_ints;

  return int_values;
}

/**
 * g_key_file_set_integer_list:
 * @key_file: a #GKeyFile
 * @group_name: a group name
 * @key: a key
 * @list: (array length=length): an array of integer values
 * @length: number of integer values in @list
 *
 * Associates a list of integer values with @key under @group_name.  
 * If @key cannot be found then it is created.
 *
 * Since: 2.6
 **/
void
g_key_file_set_integer_list (GKeyFile    *key_file,
			     const gchar *group_name,
			     const gchar *key,
			     gint         list[],
			     gsize        length)
{
  GString *values;
  gsize i;

  g_return_if_fail (key_file != NULL);
  g_return_if_fail (list != NULL);

  values = g_string_sized_new (length * 16);
  for (i = 0; i < length; i++)
    {
      gchar *value;

      value = g_key_file_parse_integer_as_value (key_file, list[i]);

      g_string_append (values, value);
      g_string_append_c (values, key_file->list_separator);

      g_free (value);
    }

  g_key_file_set_value (key_file, group_name, key, values->str);
  g_string_free (values, TRUE);
}

/**
 * g_key_file_get_double:
 * @key_file: a #GKeyFile
 * @group_name: a group name
 * @key: a key
 * @error: return location for a #GError
 *
 * Returns the value associated with @key under @group_name as a
 * double. If @group_name is %NULL, the start_group is used.
 *
 * If @key cannot be found then 0.0 is returned and @error is set to
 * #G_KEY_FILE_ERROR_KEY_NOT_FOUND. Likewise, if the value associated
 * with @key cannot be interpreted as a double then 0.0 is returned
 * and @error is set to #G_KEY_FILE_ERROR_INVALID_VALUE.
 *
 * Return value: the value associated with the key as a double, or
 *     0.0 if the key was not found or could not be parsed.
 *
 * Since: 2.12
 **/
gdouble
g_key_file_get_double  (GKeyFile     *key_file,
                        const gchar  *group_name,
                        const gchar  *key,
                        GError      **error)
{
  GError *key_file_error;
  gchar *value;
  gdouble double_value;

  g_return_val_if_fail (key_file != NULL, -1);
  g_return_val_if_fail (group_name != NULL, -1);
  g_return_val_if_fail (key != NULL, -1);

  key_file_error = NULL;

  value = g_key_file_get_value (key_file, group_name, key, &key_file_error);

  if (key_file_error)
    {
      g_propagate_error (error, key_file_error);
      return 0;
    }

  double_value = g_key_file_parse_value_as_double (key_file, value,
                                                  &key_file_error);
  g_free (value);

  if (key_file_error)
    {
      if (g_error_matches (key_file_error,
                           G_KEY_FILE_ERROR,
                           G_KEY_FILE_ERROR_INVALID_VALUE))
        {
          g_set_error (error, G_KEY_FILE_ERROR,
                       G_KEY_FILE_ERROR_INVALID_VALUE,
                       _("Key file contains key '%s' in group '%s' "
                         "which has a value that cannot be interpreted."),
                       key, group_name);
          g_error_free (key_file_error);
        }
      else
        g_propagate_error (error, key_file_error);
    }

  return double_value;
}

/**
 * g_key_file_set_double:
 * @key_file: a #GKeyFile
 * @group_name: a group name
 * @key: a key
 * @value: an double value
 *
 * Associates a new double value with @key under @group_name.
 * If @key cannot be found then it is created. 
 *
 * Since: 2.12
 **/
void
g_key_file_set_double  (GKeyFile    *key_file,
                        const gchar *group_name,
                        const gchar *key,
                        gdouble      value)
{
  gchar result[G_ASCII_DTOSTR_BUF_SIZE];

  g_return_if_fail (key_file != NULL);

  g_ascii_dtostr (result, sizeof (result), value);
  g_key_file_set_value (key_file, group_name, key, result);
}

/**
 * g_key_file_get_double_list:
 * @key_file: a #GKeyFile
 * @group_name: a group name
 * @key: a key
 * @length: (out): the number of doubles returned
 * @error: return location for a #GError
 *
 * Returns the values associated with @key under @group_name as
 * doubles. 
 *
 * If @key cannot be found then %NULL is returned and @error is set to
 * #G_KEY_FILE_ERROR_KEY_NOT_FOUND. Likewise, if the values associated
 * with @key cannot be interpreted as doubles then %NULL is returned
 * and @error is set to #G_KEY_FILE_ERROR_INVALID_VALUE.
 *
 * Return value: (array length=length) (element-type gdouble) (transfer container):
 *     the values associated with the key as a list of doubles, or %NULL if the
 *     key was not found or could not be parsed. The returned list of doubles
 *     should be freed with g_free() when no longer needed.
 *
 * Since: 2.12
 **/
gdouble *
g_key_file_get_double_list  (GKeyFile     *key_file,
                             const gchar  *group_name,
                             const gchar  *key,
                             gsize        *length,
                             GError      **error)
{
  GError *key_file_error = NULL;
  gchar **values;
  gdouble *double_values;
  gsize i, num_doubles;

  g_return_val_if_fail (key_file != NULL, NULL);
  g_return_val_if_fail (group_name != NULL, NULL);
  g_return_val_if_fail (key != NULL, NULL);

  if (length)
    *length = 0;

  values = g_key_file_get_string_list (key_file, group_name, key,
                                       &num_doubles, &key_file_error);

  if (key_file_error)
    g_propagate_error (error, key_file_error);

  if (!values)
    return NULL;

  double_values = g_new (gdouble, num_doubles);

  for (i = 0; i < num_doubles; i++)
    {
      double_values[i] = g_key_file_parse_value_as_double (key_file,
							   values[i],
							   &key_file_error);

      if (key_file_error)
        {
          g_propagate_error (error, key_file_error);
          g_strfreev (values);
          g_free (double_values);

          return NULL;
        }
    }
  g_strfreev (values);

  if (length)
    *length = num_doubles;

  return double_values;
}

/**
 * g_key_file_set_double_list:
 * @key_file: a #GKeyFile
 * @group_name: a group name
 * @key: a key
 * @list: (array length=length): an array of double values
 * @length: number of double values in @list
 *
 * Associates a list of double values with @key under
 * @group_name.  If @key cannot be found then it is created.
 *
 * Since: 2.12
 **/
void
g_key_file_set_double_list (GKeyFile    *key_file,
			    const gchar *group_name,
			    const gchar *key,
			    gdouble      list[],
			    gsize        length)
{
  GString *values;
  gsize i;

  g_return_if_fail (key_file != NULL);
  g_return_if_fail (list != NULL);

  values = g_string_sized_new (length * 16);
  for (i = 0; i < length; i++)
    {
      gchar result[G_ASCII_DTOSTR_BUF_SIZE];

      g_ascii_dtostr( result, sizeof (result), list[i] );

      g_string_append (values, result);
      g_string_append_c (values, key_file->list_separator);
    }

  g_key_file_set_value (key_file, group_name, key, values->str);
  g_string_free (values, TRUE);
}

static gboolean
g_key_file_set_key_comment (GKeyFile     *key_file,
                            const gchar  *group_name,
                            const gchar  *key,
                            const gchar  *comment,
                            GError      **error)
{
  GKeyFileGroup *group;
  GKeyFileKeyValuePair *pair;
  GList *key_node, *comment_node, *tmp;
  
  group = g_key_file_lookup_group (key_file, group_name);
  if (!group)
    {
      g_set_error (error, G_KEY_FILE_ERROR,
                   G_KEY_FILE_ERROR_GROUP_NOT_FOUND,
                   _("Key file does not have group '%s'"),
                   group_name ? group_name : "(null)");

      return FALSE;
    }

  /* First find the key the comments are supposed to be
   * associated with
   */
  key_node = g_key_file_lookup_key_value_pair_node (key_file, group, key);

  if (key_node == NULL)
    {
      g_set_error (error, G_KEY_FILE_ERROR,
                   G_KEY_FILE_ERROR_KEY_NOT_FOUND,
                   _("Key file does not have key '%s' in group '%s'"),
                   key, group->name);
      return FALSE;
    }

  /* Then find all the comments already associated with the
   * key and free them
   */
  tmp = key_node->next;
  while (tmp != NULL)
    {
      pair = (GKeyFileKeyValuePair *) tmp->data;

      if (pair->key != NULL)
        break;

      comment_node = tmp;
      tmp = tmp->next;
      g_key_file_remove_key_value_pair_node (key_file, group,
                                             comment_node); 
    }

  if (comment == NULL)
    return TRUE;

  /* Now we can add our new comment
   */
  pair = g_slice_new (GKeyFileKeyValuePair);
  pair->key = NULL;
  pair->value = g_key_file_parse_comment_as_value (key_file, comment);
  
  key_node = g_list_insert (key_node, pair, 1);

  return TRUE;
}

static gboolean
g_key_file_set_group_comment (GKeyFile     *key_file,
                              const gchar  *group_name,
                              const gchar  *comment,
                              GError      **error)
{
  GKeyFileGroup *group;
  
  g_return_val_if_fail (g_key_file_is_group_name (group_name), FALSE);

  group = g_key_file_lookup_group (key_file, group_name);
  if (!group)
    {
      g_set_error (error, G_KEY_FILE_ERROR,
                   G_KEY_FILE_ERROR_GROUP_NOT_FOUND,
                   _("Key file does not have group '%s'"),
                   group_name ? group_name : "(null)");

      return FALSE;
    }

  /* First remove any existing comment
   */
  if (group->comment)
    {
      g_key_file_key_value_pair_free (group->comment);
      group->comment = NULL;
    }

  if (comment == NULL)
    return TRUE;

  /* Now we can add our new comment
   */
  group->comment = g_slice_new (GKeyFileKeyValuePair);
  group->comment->key = NULL;
  group->comment->value = g_key_file_parse_comment_as_value (key_file, comment);

  return TRUE;
}

static gboolean
g_key_file_set_top_comment (GKeyFile     *key_file,
                            const gchar  *comment,
                            GError      **error)
{
  GList *group_node;
  GKeyFileGroup *group;
  GKeyFileKeyValuePair *pair;

  /* The last group in the list should be the top (comments only)
   * group in the file
   */
  g_warn_if_fail (key_file->groups != NULL);
  group_node = g_list_last (key_file->groups);
  group = (GKeyFileGroup *) group_node->data;
  g_warn_if_fail (group->name == NULL);

  /* Note all keys must be comments at the top of
   * the file, so we can just free it all.
   */
  g_list_free_full (group->key_value_pairs, (GDestroyNotify) g_key_file_key_value_pair_free);
  group->key_value_pairs = NULL;

  if (comment == NULL)
     return TRUE;

  pair = g_slice_new (GKeyFileKeyValuePair);
  pair->key = NULL;
  pair->value = g_key_file_parse_comment_as_value (key_file, comment);
  
  group->key_value_pairs =
    g_list_prepend (group->key_value_pairs, pair);

  return TRUE;
}

/**
 * g_key_file_set_comment:
 * @key_file: a #GKeyFile
 * @group_name: (allow-none): a group name, or %NULL
 * @key: (allow-none): a key
 * @comment: a comment
 * @error: return location for a #GError
 *
 * Places a comment above @key from @group_name.
 * If @key is %NULL then @comment will be written above @group_name.  
 * If both @key and @group_name  are %NULL, then @comment will be 
 * written above the first group in the file.
 *
 * Returns: %TRUE if the comment was written, %FALSE otherwise
 *
 * Since: 2.6
 **/
gboolean
g_key_file_set_comment (GKeyFile     *key_file,
                        const gchar  *group_name,
                        const gchar  *key,
                        const gchar  *comment,
                        GError      **error)
{
  g_return_val_if_fail (key_file != NULL, FALSE);

  if (group_name != NULL && key != NULL) 
    {
      if (!g_key_file_set_key_comment (key_file, group_name, key, comment, error))
        return FALSE;
    } 
  else if (group_name != NULL) 
    {
      if (!g_key_file_set_group_comment (key_file, group_name, comment, error))
        return FALSE;
    } 
  else 
    {
      if (!g_key_file_set_top_comment (key_file, comment, error))
        return FALSE;
    }

  return TRUE;
}

static gchar *
g_key_file_get_key_comment (GKeyFile     *key_file,
                            const gchar  *group_name,
                            const gchar  *key,
                            GError      **error)
{
  GKeyFileGroup *group;
  GKeyFileKeyValuePair *pair;
  GList *key_node, *tmp;
  GString *string;
  gchar *comment;

  g_return_val_if_fail (g_key_file_is_group_name (group_name), NULL);

  group = g_key_file_lookup_group (key_file, group_name);
  if (!group)
    {
      g_set_error (error, G_KEY_FILE_ERROR,
                   G_KEY_FILE_ERROR_GROUP_NOT_FOUND,
                   _("Key file does not have group '%s'"),
                   group_name ? group_name : "(null)");

      return NULL;
    }

  /* First find the key the comments are supposed to be
   * associated with
   */
  key_node = g_key_file_lookup_key_value_pair_node (key_file, group, key);

  if (key_node == NULL)
    {
      g_set_error (error, G_KEY_FILE_ERROR,
                   G_KEY_FILE_ERROR_KEY_NOT_FOUND,
                   _("Key file does not have key '%s' in group '%s'"),
                   key, group->name);
      return NULL;
    }

  string = NULL;

  /* Then find all the comments already associated with the
   * key and concatentate them.
   */
  tmp = key_node->next;
  if (!key_node->next)
    return NULL;

  pair = (GKeyFileKeyValuePair *) tmp->data;
  if (pair->key != NULL)
    return NULL;

  while (tmp->next)
    {
      pair = (GKeyFileKeyValuePair *) tmp->next->data;
      
      if (pair->key != NULL)
        break;

      tmp = tmp->next;
    }

  while (tmp != key_node)
    {
      pair = (GKeyFileKeyValuePair *) tmp->data;
      
      if (string == NULL)
	string = g_string_sized_new (512);
      
      comment = g_key_file_parse_value_as_comment (key_file, pair->value);
      g_string_append (string, comment);
      g_free (comment);
      
      tmp = tmp->prev;
    }

  if (string != NULL)
    {
      comment = string->str;
      g_string_free (string, FALSE);
    }
  else
    comment = NULL;

  return comment;
}

static gchar *
get_group_comment (GKeyFile       *key_file,
		   GKeyFileGroup  *group,
		   GError        **error)
{
  GString *string;
  GList *tmp;
  gchar *comment;

  string = NULL;

  tmp = group->key_value_pairs;
  while (tmp)
    {
      GKeyFileKeyValuePair *pair;

      pair = (GKeyFileKeyValuePair *) tmp->data;

      if (pair->key != NULL)
	{
	  tmp = tmp->prev;
	  break;
	}

      if (tmp->next == NULL)
	break;

      tmp = tmp->next;
    }
  
  while (tmp != NULL)
    {
      GKeyFileKeyValuePair *pair;

      pair = (GKeyFileKeyValuePair *) tmp->data;

      if (string == NULL)
        string = g_string_sized_new (512);

      comment = g_key_file_parse_value_as_comment (key_file, pair->value);
      g_string_append (string, comment);
      g_free (comment);

      tmp = tmp->prev;
    }

  if (string != NULL)
    return g_string_free (string, FALSE);

  return NULL;
}

static gchar *
g_key_file_get_group_comment (GKeyFile     *key_file,
                              const gchar  *group_name,
                              GError      **error)
{
  GList *group_node;
  GKeyFileGroup *group;
  
  group = g_key_file_lookup_group (key_file, group_name);
  if (!group)
    {
      g_set_error (error, G_KEY_FILE_ERROR,
                   G_KEY_FILE_ERROR_GROUP_NOT_FOUND,
                   _("Key file does not have group '%s'"),
                   group_name ? group_name : "(null)");

      return NULL;
    }

  if (group->comment)
    return g_strdup (group->comment->value);
  
  group_node = g_key_file_lookup_group_node (key_file, group_name);
  group_node = group_node->next;
  group = (GKeyFileGroup *)group_node->data;  
  return get_group_comment (key_file, group, error);
}

static gchar *
g_key_file_get_top_comment (GKeyFile  *key_file,
                            GError   **error)
{
  GList *group_node;
  GKeyFileGroup *group;

  /* The last group in the list should be the top (comments only)
   * group in the file
   */
  g_warn_if_fail (key_file->groups != NULL);
  group_node = g_list_last (key_file->groups);
  group = (GKeyFileGroup *) group_node->data;
  g_warn_if_fail (group->name == NULL);

  return get_group_comment (key_file, group, error);
}

/**
 * g_key_file_get_comment:
 * @key_file: a #GKeyFile
 * @group_name: (allow-none): a group name, or %NULL
 * @key: a key
 * @error: return location for a #GError
 *
 * Retrieves a comment above @key from @group_name.
 * If @key is %NULL then @comment will be read from above 
 * @group_name. If both @key and @group_name are %NULL, then 
 * @comment will be read from above the first group in the file.
 *
 * Returns: a comment that should be freed with g_free()
 *
 * Since: 2.6
 **/
gchar * 
g_key_file_get_comment (GKeyFile     *key_file,
                        const gchar  *group_name,
                        const gchar  *key,
                        GError      **error)
{
  g_return_val_if_fail (key_file != NULL, NULL);

  if (group_name != NULL && key != NULL)
    return g_key_file_get_key_comment (key_file, group_name, key, error);
  else if (group_name != NULL)
    return g_key_file_get_group_comment (key_file, group_name, error);
  else
    return g_key_file_get_top_comment (key_file, error);
}

/**
 * g_key_file_remove_comment:
 * @key_file: a #GKeyFile
 * @group_name: (allow-none): a group name, or %NULL
 * @key: (allow-none): a key
 * @error: return location for a #GError
 *
 * Removes a comment above @key from @group_name.
 * If @key is %NULL then @comment will be removed above @group_name. 
 * If both @key and @group_name are %NULL, then @comment will
 * be removed above the first group in the file.
 *
 * Returns: %TRUE if the comment was removed, %FALSE otherwise
 *
 * Since: 2.6
 **/

gboolean
g_key_file_remove_comment (GKeyFile     *key_file,
                           const gchar  *group_name,
                           const gchar  *key,
                           GError      **error)
{
  g_return_val_if_fail (key_file != NULL, FALSE);

  if (group_name != NULL && key != NULL)
    return g_key_file_set_key_comment (key_file, group_name, key, NULL, error);
  else if (group_name != NULL)
    return g_key_file_set_group_comment (key_file, group_name, NULL, error);
  else
    return g_key_file_set_top_comment (key_file, NULL, error);
}

/**
 * g_key_file_has_group:
 * @key_file: a #GKeyFile
 * @group_name: a group name
 *
 * Looks whether the key file has the group @group_name.
 *
 * Return value: %TRUE if @group_name is a part of @key_file, %FALSE
 * otherwise.
 * Since: 2.6
 **/
gboolean
g_key_file_has_group (GKeyFile    *key_file,
		      const gchar *group_name)
{
  g_return_val_if_fail (key_file != NULL, FALSE);
  g_return_val_if_fail (group_name != NULL, FALSE);

  return g_key_file_lookup_group (key_file, group_name) != NULL;
}

/* This code remains from a historical attempt to add a new public API
 * which respects the GError rules.
 */
static gboolean
g_key_file_has_key_full (GKeyFile     *key_file,
			 const gchar  *group_name,
			 const gchar  *key,
			 gboolean     *has_key,
			 GError      **error)
{
  GKeyFileKeyValuePair *pair;
  GKeyFileGroup *group;

  g_return_val_if_fail (key_file != NULL, FALSE);
  g_return_val_if_fail (group_name != NULL, FALSE);
  g_return_val_if_fail (key != NULL, FALSE);

  group = g_key_file_lookup_group (key_file, group_name);

  if (!group)
    {
      g_set_error (error, G_KEY_FILE_ERROR,
                   G_KEY_FILE_ERROR_GROUP_NOT_FOUND,
                   _("Key file does not have group '%s'"),
                   group_name ? group_name : "(null)");

      return FALSE;
    }

  pair = g_key_file_lookup_key_value_pair (key_file, group, key);

  if (has_key)
    *has_key = pair != NULL;
  return TRUE;
}

/**
 * g_key_file_has_key: (skip)
 * @key_file: a #GKeyFile
 * @group_name: a group name
 * @key: a key name
 * @error: return location for a #GError
 *
 * Looks whether the key file has the key @key in the group
 * @group_name.
 *
 * <note>This function does not follow the rules for #GError strictly;
 * the return value both carries meaning and signals an error.  To use
 * this function, you must pass a #GError pointer in @error, and check
 * whether it is not %NULL to see if an error occurred.</note>
 *
 * Language bindings should use g_key_file_get_value() to test whether
 * or not a key exists.
 *
 * Return value: %TRUE if @key is a part of @group_name, %FALSE
 * otherwise.
 *
 * Since: 2.6
 **/
gboolean
g_key_file_has_key (GKeyFile     *key_file,
		    const gchar  *group_name,
		    const gchar  *key,
		    GError      **error)
{
  GError *temp_error = NULL;
  gboolean has_key;

  if (g_key_file_has_key_full (key_file, group_name, key, &has_key, &temp_error))
    {
      return has_key;
    }
  else
    {
      g_propagate_error (error, temp_error);
      return FALSE;
    }
}

static void
g_key_file_add_group (GKeyFile    *key_file,
		      const gchar *group_name)
{
  GKeyFileGroup *group;

  g_return_if_fail (key_file != NULL);
  g_return_if_fail (g_key_file_is_group_name (group_name));

  group = g_key_file_lookup_group (key_file, group_name);
  if (group != NULL)
    {
      key_file->current_group = group;
      return;
    }

  group = g_slice_new0 (GKeyFileGroup);
  group->name = g_strdup (group_name);
  group->lookup_map = g_hash_table_new (g_str_hash, g_str_equal);
  key_file->groups = g_list_prepend (key_file->groups, group);
  key_file->current_group = group;

  if (key_file->start_group == NULL)
    key_file->start_group = group;

  g_hash_table_insert (key_file->group_hash, (gpointer)group->name, group);
}

static void
g_key_file_key_value_pair_free (GKeyFileKeyValuePair *pair)
{
  if (pair != NULL)
    {
      g_free (pair->key);
      g_free (pair->value);
      g_slice_free (GKeyFileKeyValuePair, pair);
    }
}

/* Be careful not to call this function on a node with data in the
 * lookup map without removing it from the lookup map, first.
 *
 * Some current cases where this warning is not a concern are
 * when:
 *   - the node being removed is a comment node
 *   - the entire lookup map is getting destroyed soon after
 *     anyway.
 */ 
static void
g_key_file_remove_key_value_pair_node (GKeyFile      *key_file,
                                       GKeyFileGroup *group,
			               GList         *pair_node)
{

  GKeyFileKeyValuePair *pair;

  pair = (GKeyFileKeyValuePair *) pair_node->data;

  group->key_value_pairs = g_list_remove_link (group->key_value_pairs, pair_node);

  g_warn_if_fail (pair->value != NULL);

  g_key_file_key_value_pair_free (pair);

  g_list_free_1 (pair_node);
}

static void
g_key_file_remove_group_node (GKeyFile *key_file,
			      GList    *group_node)
{
  GKeyFileGroup *group;
  GList *tmp;

  group = (GKeyFileGroup *) group_node->data;

  if (group->name)
    g_hash_table_remove (key_file->group_hash, group->name);

  /* If the current group gets deleted make the current group the last
   * added group.
   */
  if (key_file->current_group == group)
    {
      /* groups should always contain at least the top comment group,
       * unless g_key_file_clear has been called
       */
      if (key_file->groups)
        key_file->current_group = (GKeyFileGroup *) key_file->groups->data;
      else
        key_file->current_group = NULL;
    }

  /* If the start group gets deleted make the start group the first
   * added group.
   */
  if (key_file->start_group == group)
    {
      tmp = g_list_last (key_file->groups);
      while (tmp != NULL)
	{
	  if (tmp != group_node &&
	      ((GKeyFileGroup *) tmp->data)->name != NULL)
	    break;

	  tmp = tmp->prev;
	}

      if (tmp)
        key_file->start_group = (GKeyFileGroup *) tmp->data;
      else
        key_file->start_group = NULL;
    }

  key_file->groups = g_list_remove_link (key_file->groups, group_node);

  tmp = group->key_value_pairs;
  while (tmp != NULL)
    {
      GList *pair_node;

      pair_node = tmp;
      tmp = tmp->next;
      g_key_file_remove_key_value_pair_node (key_file, group, pair_node);
    }

  g_warn_if_fail (group->key_value_pairs == NULL);

  if (group->comment)
    {
      g_key_file_key_value_pair_free (group->comment);
      group->comment = NULL;
    }

  if (group->lookup_map)
    {
      g_hash_table_destroy (group->lookup_map);
      group->lookup_map = NULL;
    }

  g_free ((gchar *) group->name);
  g_slice_free (GKeyFileGroup, group);
  g_list_free_1 (group_node);
}

/**
 * g_key_file_remove_group:
 * @key_file: a #GKeyFile
 * @group_name: a group name
 * @error: return location for a #GError or %NULL
 *
 * Removes the specified group, @group_name, 
 * from the key file. 
 *
 * Returns: %TRUE if the group was removed, %FALSE otherwise
 *
 * Since: 2.6
 **/
gboolean
g_key_file_remove_group (GKeyFile     *key_file,
			 const gchar  *group_name,
			 GError      **error)
{
  GList *group_node;

  g_return_val_if_fail (key_file != NULL, FALSE);
  g_return_val_if_fail (group_name != NULL, FALSE);

  group_node = g_key_file_lookup_group_node (key_file, group_name);

  if (!group_node)
    {
      g_set_error (error, G_KEY_FILE_ERROR,
		   G_KEY_FILE_ERROR_GROUP_NOT_FOUND,
		   _("Key file does not have group '%s'"),
		   group_name);
      return FALSE;
    }

  g_key_file_remove_group_node (key_file, group_node);

  return TRUE;  
}

static void
g_key_file_add_key_value_pair (GKeyFile             *key_file,
                               GKeyFileGroup        *group,
                               GKeyFileKeyValuePair *pair)
{
  g_hash_table_replace (group->lookup_map, pair->key, pair);
  group->key_value_pairs = g_list_prepend (group->key_value_pairs, pair);
}

static void
g_key_file_add_key (GKeyFile      *key_file,
		    GKeyFileGroup *group,
		    const gchar   *key,
		    const gchar   *value)
{
  GKeyFileKeyValuePair *pair;

  pair = g_slice_new (GKeyFileKeyValuePair);
  pair->key = g_strdup (key);
  pair->value = g_strdup (value);

  g_key_file_add_key_value_pair (key_file, group, pair);
}

/**
 * g_key_file_remove_key:
 * @key_file: a #GKeyFile
 * @group_name: a group name
 * @key: a key name to remove
 * @error: return location for a #GError or %NULL
 *
 * Removes @key in @group_name from the key file. 
 *
 * Returns: %TRUE if the key was removed, %FALSE otherwise
 *
 * Since: 2.6
 **/
gboolean
g_key_file_remove_key (GKeyFile     *key_file,
		       const gchar  *group_name,
		       const gchar  *key,
		       GError      **error)
{
  GKeyFileGroup *group;
  GKeyFileKeyValuePair *pair;

  g_return_val_if_fail (key_file != NULL, FALSE);
  g_return_val_if_fail (group_name != NULL, FALSE);
  g_return_val_if_fail (key != NULL, FALSE);

  pair = NULL;

  group = g_key_file_lookup_group (key_file, group_name);
  if (!group)
    {
      g_set_error (error, G_KEY_FILE_ERROR,
                   G_KEY_FILE_ERROR_GROUP_NOT_FOUND,
                   _("Key file does not have group '%s'"),
                   group_name ? group_name : "(null)");
      return FALSE;
    }

  pair = g_key_file_lookup_key_value_pair (key_file, group, key);

  if (!pair)
    {
      g_set_error (error, G_KEY_FILE_ERROR,
                   G_KEY_FILE_ERROR_KEY_NOT_FOUND,
                   _("Key file does not have key '%s' in group '%s'"),
		   key, group->name);
      return FALSE;
    }

  group->key_value_pairs = g_list_remove (group->key_value_pairs, pair);
  g_hash_table_remove (group->lookup_map, pair->key);
  g_key_file_key_value_pair_free (pair);

  return TRUE;
}

static GList *
g_key_file_lookup_group_node (GKeyFile    *key_file,
			      const gchar *group_name)
{
  GKeyFileGroup *group;
  GList *tmp;

  for (tmp = key_file->groups; tmp != NULL; tmp = tmp->next)
    {
      group = (GKeyFileGroup *) tmp->data;

      if (group && group->name && strcmp (group->name, group_name) == 0)
        break;
    }

  return tmp;
}

static GKeyFileGroup *
g_key_file_lookup_group (GKeyFile    *key_file,
			 const gchar *group_name)
{
  return (GKeyFileGroup *)g_hash_table_lookup (key_file->group_hash, group_name);
}

static GList *
g_key_file_lookup_key_value_pair_node (GKeyFile       *key_file,
			               GKeyFileGroup  *group,
                                       const gchar    *key)
{
  GList *key_node;

  for (key_node = group->key_value_pairs;
       key_node != NULL;
       key_node = key_node->next)
    {
      GKeyFileKeyValuePair *pair;

      pair = (GKeyFileKeyValuePair *) key_node->data; 

      if (pair->key && strcmp (pair->key, key) == 0)
        break;
    }

  return key_node;
}

static GKeyFileKeyValuePair *
g_key_file_lookup_key_value_pair (GKeyFile      *key_file,
				  GKeyFileGroup *group,
				  const gchar   *key)
{
  return (GKeyFileKeyValuePair *) g_hash_table_lookup (group->lookup_map, key);
}

/* Lines starting with # or consisting entirely of whitespace are merely
 * recorded, not parsed. This function assumes all leading whitespace
 * has been stripped.
 */
static gboolean
g_key_file_line_is_comment (const gchar *line)
{
  return (*line == '#' || *line == '\0' || *line == '\n');
}

static gboolean 
g_key_file_is_group_name (const gchar *name)
{
  gchar *p, *q;

  if (name == NULL)
    return FALSE;

  p = q = (gchar *) name;
  while (*q && *q != ']' && *q != '[' && !g_ascii_iscntrl (*q))
    q = g_utf8_find_next_char (q, NULL);
  
  if (*q != '\0' || q == p)
    return FALSE;

  return TRUE;
}

static gboolean
g_key_file_is_key_name (const gchar *name)
{
  gchar *p, *q;

  if (name == NULL)
    return FALSE;

  p = q = (gchar *) name;
  /* We accept a little more than the desktop entry spec says,
   * since gnome-vfs uses mime-types as keys in its cache.
   */
  while (*q && *q != '=' && *q != '[' && *q != ']')
    q = g_utf8_find_next_char (q, NULL);
  
  /* No empty keys, please */
  if (q == p)
    return FALSE;

  /* We accept spaces in the middle of keys to not break
   * existing apps, but we don't tolerate initial or final
   * spaces, which would lead to silent corruption when
   * rereading the file.
   */
  if (*p == ' ' || q[-1] == ' ')
    return FALSE;

  if (*q == '[')
    {
      q++;
      while (*q && (g_unichar_isalnum (g_utf8_get_char_validated (q, -1)) || *q == '-' || *q == '_' || *q == '.' || *q == '@'))
        q = g_utf8_find_next_char (q, NULL);

      if (*q != ']')
        return FALSE;     

      q++;
    }

  if (*q != '\0')
    return FALSE;

  return TRUE;
}

/* A group in a key file is made up of a starting '[' followed by one
 * or more letters making up the group name followed by ']'.
 */
static gboolean
g_key_file_line_is_group (const gchar *line)
{
  gchar *p;

  p = (gchar *) line;
  if (*p != '[')
    return FALSE;

  p++;

  while (*p && *p != ']')
    p = g_utf8_find_next_char (p, NULL);

  if (*p != ']')
    return FALSE;
 
  /* silently accept whitespace after the ] */
  p = g_utf8_find_next_char (p, NULL);
  while (*p == ' ' || *p == '\t')
    p = g_utf8_find_next_char (p, NULL);
     
  if (*p)
    return FALSE;

  return TRUE;
}

static gboolean
g_key_file_line_is_key_value_pair (const gchar *line)
{
  gchar *p;

  p = (gchar *) g_utf8_strchr (line, -1, '=');

  if (!p)
    return FALSE;

  /* Key must be non-empty
   */
  if (*p == line[0])
    return FALSE;

  return TRUE;
}

static gchar *
g_key_file_parse_value_as_string (GKeyFile     *key_file,
				  const gchar  *value,
				  GSList      **pieces,
				  GError      **error)
{
  gchar *string_value, *p, *q0, *q;

  string_value = g_new (gchar, strlen (value) + 1);

  p = (gchar *) value;
  q0 = q = string_value;
  while (*p)
    {
      if (*p == '\\')
        {
          p++;

          switch (*p)
            {
            case 's':
              *q = ' ';
              break;

            case 'n':
              *q = '\n';
              break;

            case 't':
              *q = '\t';
              break;

            case 'r':
              *q = '\r';
              break;

            case '\\':
              *q = '\\';
              break;

	    case '\0':
	      g_set_error_literal (error, G_KEY_FILE_ERROR,
                                   G_KEY_FILE_ERROR_INVALID_VALUE,
                                   _("Key file contains escape character "
                                     "at end of line"));
	      break;

            default:
	      if (pieces && *p == key_file->list_separator)
		*q = key_file->list_separator;
	      else
		{
		  *q++ = '\\';
		  *q = *p;
		  
		  if (*error == NULL)
		    {
		      gchar sequence[3];
		      
		      sequence[0] = '\\';
		      sequence[1] = *p;
		      sequence[2] = '\0';
		      
		      g_set_error (error, G_KEY_FILE_ERROR,
				   G_KEY_FILE_ERROR_INVALID_VALUE,
				   _("Key file contains invalid escape "
				     "sequence '%s'"), sequence);
		    }
		}
              break;
            }
        }
      else
	{
	  *q = *p;
	  if (pieces && (*p == key_file->list_separator))
	    {
	      *pieces = g_slist_prepend (*pieces, g_strndup (q0, q - q0));
	      q0 = q + 1; 
	    }
	}

      if (*p == '\0')
	break;

      q++;
      p++;
    }

  *q = '\0';
  if (pieces)
  {
    if (q0 < q)
      *pieces = g_slist_prepend (*pieces, g_strndup (q0, q - q0));
    *pieces = g_slist_reverse (*pieces);
  }

  return string_value;
}

static gchar *
g_key_file_parse_string_as_value (GKeyFile    *key_file,
				  const gchar *string,
				  gboolean     escape_separator)
{
  gchar *value, *p, *q;
  gsize length;
  gboolean parsing_leading_space;

  length = strlen (string) + 1;

  /* Worst case would be that every character needs to be escaped.
   * In other words every character turns to two characters
   */
  value = g_new (gchar, 2 * length);

  p = (gchar *) string;
  q = value;
  parsing_leading_space = TRUE;
  while (p < (string + length - 1))
    {
      gchar escaped_character[3] = { '\\', 0, 0 };

      switch (*p)
        {
        case ' ':
          if (parsing_leading_space)
            {
              escaped_character[1] = 's';
              strcpy (q, escaped_character);
              q += 2;
            }
          else
            {
	      *q = *p;
	      q++;
            }
          break;
        case '\t':
          if (parsing_leading_space)
            {
              escaped_character[1] = 't';
              strcpy (q, escaped_character);
              q += 2;
            }
          else
            {
	      *q = *p;
	      q++;
            }
          break;
        case '\n':
          escaped_character[1] = 'n';
          strcpy (q, escaped_character);
          q += 2;
          break;
        case '\r':
          escaped_character[1] = 'r';
          strcpy (q, escaped_character);
          q += 2;
          break;
        case '\\':
          escaped_character[1] = '\\';
          strcpy (q, escaped_character);
          q += 2;
          parsing_leading_space = FALSE;
          break;
        default:
	  if (escape_separator && *p == key_file->list_separator)
	    {
	      escaped_character[1] = key_file->list_separator;
	      strcpy (q, escaped_character);
	      q += 2;
              parsing_leading_space = TRUE;
	    }
	  else 
	    {
	      *q = *p;
	      q++;
              parsing_leading_space = FALSE;
	    }
          break;
        }
      p++;
    }
  *q = '\0';

  return value;
}

static gint
g_key_file_parse_value_as_integer (GKeyFile     *key_file,
				   const gchar  *value,
				   GError      **error)
{
  gchar *eof_int;
  glong long_value;
  gint int_value;

  errno = 0;
  long_value = strtol (value, &eof_int, 10);

  if (*value == '\0' || (*eof_int != '\0' && !g_ascii_isspace(*eof_int)))
    {
      gchar *value_utf8 = _g_utf8_make_valid (value);
      g_set_error (error, G_KEY_FILE_ERROR,
		   G_KEY_FILE_ERROR_INVALID_VALUE,
		   _("Value '%s' cannot be interpreted "
		     "as a number."), value_utf8);
      g_free (value_utf8);

      return 0;
    }

  int_value = long_value;
  if (int_value != long_value || errno == ERANGE)
    {
      gchar *value_utf8 = _g_utf8_make_valid (value);
      g_set_error (error,
		   G_KEY_FILE_ERROR, 
		   G_KEY_FILE_ERROR_INVALID_VALUE,
		   _("Integer value '%s' out of range"), 
		   value_utf8);
      g_free (value_utf8);

      return 0;
    }
  
  return int_value;
}

static gchar *
g_key_file_parse_integer_as_value (GKeyFile *key_file,
				   gint      value)

{
  return g_strdup_printf ("%d", value);
}

static gdouble
g_key_file_parse_value_as_double  (GKeyFile     *key_file,
                                   const gchar  *value,
                                   GError      **error)
{
  gchar *end_of_valid_d;
  gdouble double_value = 0;

  double_value = g_ascii_strtod (value, &end_of_valid_d);

  if (*end_of_valid_d != '\0' || end_of_valid_d == value)
    {
      gchar *value_utf8 = _g_utf8_make_valid (value);
      g_set_error (error, G_KEY_FILE_ERROR,
		   G_KEY_FILE_ERROR_INVALID_VALUE,
		   _("Value '%s' cannot be interpreted "
		     "as a float number."), 
		   value_utf8);
      g_free (value_utf8);
    }

  return double_value;
}

static gboolean
g_key_file_parse_value_as_boolean (GKeyFile     *key_file,
				   const gchar  *value,
				   GError      **error)
{
  gchar *value_utf8;

  if (strcmp (value, "true") == 0 || strcmp (value, "1") == 0)
    return TRUE;
  else if (strcmp (value, "false") == 0 || strcmp (value, "0") == 0)
    return FALSE;

  value_utf8 = _g_utf8_make_valid (value);
  g_set_error (error, G_KEY_FILE_ERROR,
               G_KEY_FILE_ERROR_INVALID_VALUE,
               _("Value '%s' cannot be interpreted "
		 "as a boolean."), value_utf8);
  g_free (value_utf8);

  return FALSE;
}

static gchar *
g_key_file_parse_boolean_as_value (GKeyFile *key_file,
				   gboolean  value)
{
  if (value)
    return g_strdup ("true");
  else
    return g_strdup ("false");
}

static gchar *
g_key_file_parse_value_as_comment (GKeyFile    *key_file,
                                   const gchar *value)
{
  GString *string;
  gchar **lines;
  gsize i;

  string = g_string_sized_new (512);

  lines = g_strsplit (value, "\n", 0);

  for (i = 0; lines[i] != NULL; i++)
    {
        if (lines[i][0] != '#')
           g_string_append_printf (string, "%s\n", lines[i]);
        else 
           g_string_append_printf (string, "%s\n", lines[i] + 1);
    }
  g_strfreev (lines);

  return g_string_free (string, FALSE);
}

static gchar *
g_key_file_parse_comment_as_value (GKeyFile      *key_file,
                                   const gchar   *comment)
{
  GString *string;
  gchar **lines;
  gsize i;

  string = g_string_sized_new (512);

  lines = g_strsplit (comment, "\n", 0);

  for (i = 0; lines[i] != NULL; i++)
    g_string_append_printf (string, "#%s%s", lines[i], 
                            lines[i + 1] == NULL? "" : "\n");
  g_strfreev (lines);

  return g_string_free (string, FALSE);
}

/**
 * g_key_file_save_to_file:
 * @key_file: a #GKeyFile
 * @filename: the name of the file to write to
 * @error: a pointer to a %NULL #GError, or %NULL
 *
 * Writes the contents of @key_file to @filename using
 * g_file_set_contents().
 *
 * This function can fail for any of the reasons that
 * g_file_set_contents() may fail.
 *
 * Returns: %TRUE if successful, else %FALSE with @error set
 *
 * Since: 2.40
 */
gboolean
g_key_file_save_to_file (GKeyFile     *key_file,
                         const gchar  *filename,
                         GError      **error)
{
  gchar *contents;
  gboolean success;
  gsize length;

  g_return_val_if_fail (key_file != NULL, FALSE);
  g_return_val_if_fail (filename != NULL, FALSE);
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

  contents = g_key_file_to_data (key_file, &length, NULL);
  g_assert (contents != NULL);

  success = g_file_set_contents (filename, contents, length, error);
  g_free (contents);

  return success;
}
