/*
 * Copyright © 2010 Codethink Limited
 *
 * This library 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 licence, or (at your option) any later version.
 *
 * This library 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 this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 *
 * Author: Ryan Lortie <desrt@desrt.ca>
 */

/* Prologue {{{1 */
#include "config.h"

#include <gstdio.h>
#include <gi18n.h>

#include <string.h>
#include <stdio.h>
#include <locale.h>

#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif

#include "gvdb/gvdb-builder.h"
#include "strinfo.c"

#ifdef G_OS_WIN32
#include "glib/glib-private.h"
#endif

static void
strip_string (GString *string)
{
  gint i;

  for (i = 0; g_ascii_isspace (string->str[i]); i++);
  g_string_erase (string, 0, i);

  if (string->len > 0)
    {
      /* len > 0, so there must be at least one non-whitespace character */
      for (i = string->len - 1; g_ascii_isspace (string->str[i]); i--);
      g_string_truncate (string, i + 1);
    }
}

/* Handling of <enum> {{{1 */
typedef struct
{
  GString *strinfo;

  gboolean is_flags;
} EnumState;

static void
enum_state_free (gpointer data)
{
  EnumState *state = data;

  g_string_free (state->strinfo, TRUE);
  g_slice_free (EnumState, state);
}

static EnumState *
enum_state_new (gboolean is_flags)
{
  EnumState *state;

  state = g_slice_new (EnumState);
  state->strinfo = g_string_new (NULL);
  state->is_flags = is_flags;

  return state;
}

static void
enum_state_add_value (EnumState    *state,
                      const gchar  *nick,
                      const gchar  *valuestr,
                      GError      **error)
{
  gint64 value;
  gchar *end;

  if (nick[0] == '\0' || nick[1] == '\0')
    {
      g_set_error (error, G_MARKUP_ERROR,
                   G_MARKUP_ERROR_INVALID_CONTENT,
                   "nick must be a minimum of 2 characters");
      return;
    }

  value = g_ascii_strtoll (valuestr, &end, 0);
  if (*end || state->is_flags ?
                (value > G_MAXUINT32 || value < 0) :
                (value > G_MAXINT32 || value < G_MININT32))
    {
      g_set_error (error, G_MARKUP_ERROR,
                   G_MARKUP_ERROR_INVALID_CONTENT,
                   "invalid numeric value");
      return;
    }

  if (strinfo_builder_contains (state->strinfo, nick))
    {
      g_set_error (error, G_MARKUP_ERROR,
                   G_MARKUP_ERROR_INVALID_CONTENT,
                   "<value nick='%s'/> already specified", nick);
      return;
    }

  if (strinfo_builder_contains_value (state->strinfo, value))
    {
      g_set_error (error, G_MARKUP_ERROR,
                   G_MARKUP_ERROR_INVALID_CONTENT,
                   "value='%s' already specified", valuestr);
      return;
    }

  /* Silently drop the null case if it is mentioned.
   * It is properly denoted with an empty array.
   */
  if (state->is_flags && value == 0)
    return;

  if (state->is_flags && (value & (value - 1)))
    {
      g_set_error (error, G_MARKUP_ERROR,
                   G_MARKUP_ERROR_INVALID_CONTENT,
                   "flags values must have at most 1 bit set");
      return;
    }

  /* Since we reject exact duplicates of value='' and we only allow one
   * bit to be set, it's not possible to have overlaps.
   *
   * If we loosen the one-bit-set restriction we need an overlap check.
   */

  strinfo_builder_append_item (state->strinfo, nick, value);
}

static void
enum_state_end (EnumState **state_ptr,
                GError    **error)
{
  EnumState *state;

  state = *state_ptr;
  *state_ptr = NULL;

  if (state->strinfo->len == 0)
    g_set_error (error,
                 G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
                 "<%s> must contain at least one <value>",
                 state->is_flags ? "flags" : "enum");
}

/* Handling of <key> {{{1 */
typedef struct
{
  /* for <child>, @child_schema will be set.
   * for <key>, everything else will be set.
   */
  gchar        *child_schema;


  GVariantType *type;
  gboolean      have_gettext_domain;

  gchar         l10n;
  gchar        *l10n_context;
  GString      *unparsed_default_value;
  GVariant     *default_value;

  GString      *strinfo;
  gboolean      is_enum;
  gboolean      is_flags;

  GVariant     *minimum;
  GVariant     *maximum;

  gboolean      has_choices;
  gboolean      has_aliases;
  gboolean      is_override;

  gboolean      checked;
  GVariant     *serialised;
} KeyState;

static KeyState *
key_state_new (const gchar *type_string,
               const gchar *gettext_domain,
               gboolean     is_enum,
               gboolean     is_flags,
               GString     *strinfo)
{
  KeyState *state;

  state = g_slice_new0 (KeyState);
  state->type = g_variant_type_new (type_string);
  state->have_gettext_domain = gettext_domain != NULL;
  state->is_enum = is_enum;
  state->is_flags = is_flags;

  if (strinfo)
    state->strinfo = g_string_new_len (strinfo->str, strinfo->len);
  else
    state->strinfo = g_string_new (NULL);

  return state;
}

static KeyState *
key_state_override (KeyState    *state,
                    const gchar *gettext_domain)
{
  KeyState *copy;

  copy = g_slice_new0 (KeyState);
  copy->type = g_variant_type_copy (state->type);
  copy->have_gettext_domain = gettext_domain != NULL;
  copy->strinfo = g_string_new_len (state->strinfo->str,
                                    state->strinfo->len);
  copy->is_enum = state->is_enum;
  copy->is_flags = state->is_flags;
  copy->is_override = TRUE;

  if (state->minimum)
    {
      copy->minimum = g_variant_ref (state->minimum);
      copy->maximum = g_variant_ref (state->maximum);
    }

  return copy;
}

static KeyState *
key_state_new_child (const gchar *child_schema)
{
  KeyState *state;

  state = g_slice_new0 (KeyState);
  state->child_schema = g_strdup (child_schema);

  return state;
}

static gboolean
is_valid_choices (GVariant *variant,
                  GString  *strinfo)
{
  switch (g_variant_classify (variant))
    {
      case G_VARIANT_CLASS_MAYBE:
      case G_VARIANT_CLASS_ARRAY:
        {
          gboolean valid = TRUE;
          GVariantIter iter;

          g_variant_iter_init (&iter, variant);

          while (valid && (variant = g_variant_iter_next_value (&iter)))
            {
              valid = is_valid_choices (variant, strinfo);
              g_variant_unref (variant);
            }

          return valid;
        }

      case G_VARIANT_CLASS_STRING:
        return strinfo_is_string_valid ((const guint32 *) strinfo->str,
                                        strinfo->len / 4,
                                        g_variant_get_string (variant, NULL));

      default:
        g_assert_not_reached ();
    }
}


/* Gets called at </default> </choices> or <range/> to check for
 * validity of the default value so that any inconsistency is
 * reported as soon as it is encountered.
 */
static void
key_state_check_range (KeyState  *state,
                       GError   **error)
{
  if (state->default_value)
    {
      const gchar *tag;

      tag = state->is_override ? "override" : "default";

      if (state->minimum)
        {
          if (g_variant_compare (state->default_value, state->minimum) < 0 ||
              g_variant_compare (state->default_value, state->maximum) > 0)
            {
              g_set_error (error, G_MARKUP_ERROR,
                           G_MARKUP_ERROR_INVALID_CONTENT,
                           "<%s> is not contained in "
                           "the specified range", tag);
            }
        }

      else if (state->strinfo->len)
        {
          if (!is_valid_choices (state->default_value, state->strinfo))
            {
              if (state->is_enum)
                g_set_error (error, G_MARKUP_ERROR,
                             G_MARKUP_ERROR_INVALID_CONTENT,
                             "<%s> is not a valid member of "
                             "the specified enumerated type", tag);

              else if (state->is_flags)
                g_set_error (error, G_MARKUP_ERROR,
                             G_MARKUP_ERROR_INVALID_CONTENT,
                             "<%s> contains string not in the "
                             "specified flags type", tag);

              else
                g_set_error (error, G_MARKUP_ERROR,
                             G_MARKUP_ERROR_INVALID_CONTENT,
                             "<%s> contains string not in "
                             "<choices>", tag);
            }
        }
    }
}

static void
key_state_set_range (KeyState     *state,
                     const gchar  *min_str,
                     const gchar  *max_str,
                     GError      **error)
{
  const struct {
    const gchar  type;
    const gchar *min;
    const gchar *max;
  } table[] = {
    { 'y',                    "0",                  "255" },
    { 'n',               "-32768",                "32767" },
    { 'q',                    "0",                "65535" },
    { 'i',          "-2147483648",           "2147483647" },
    { 'u',                    "0",           "4294967295" },
    { 'x', "-9223372036854775808",  "9223372036854775807" },
    { 't',                    "0", "18446744073709551615" },
    { 'd',                 "-inf",                  "inf" },
  };
  gboolean type_ok = FALSE;
  gint i;

  if (state->minimum)
    {
      g_set_error_literal (error, G_MARKUP_ERROR,
                           G_MARKUP_ERROR_INVALID_CONTENT,
                           "<range/> already specified for this key");
      return;
    }

  for (i = 0; i < G_N_ELEMENTS (table); i++)
    if (*(char *) state->type == table[i].type)
      {
        min_str = min_str ? min_str : table[i].min;
        max_str = max_str ? max_str : table[i].max;
        type_ok = TRUE;
        break;
      }

  if (!type_ok)
    {
      gchar *type = g_variant_type_dup_string (state->type);
      g_set_error (error, G_MARKUP_ERROR,
                  G_MARKUP_ERROR_INVALID_CONTENT,
                  "<range> not allowed for keys of type '%s'", type);
      g_free (type);
      return;
    }

  state->minimum = g_variant_parse (state->type, min_str, NULL, NULL, error);
  if (state->minimum == NULL)
    return;

  state->maximum = g_variant_parse (state->type, max_str, NULL, NULL, error);
  if (state->maximum == NULL)
    return;

  if (g_variant_compare (state->minimum, state->maximum) > 0)
    {
      g_set_error (error, G_MARKUP_ERROR,
                   G_MARKUP_ERROR_INVALID_CONTENT,
                   "<range> specified minimum is greater than maxmimum");
      return;
    }

  key_state_check_range (state, error);
}

static GString *
key_state_start_default (KeyState     *state,
                         const gchar  *l10n,
                         const gchar  *context,
                         GError      **error)
{
  if (l10n != NULL)
    {
      if (strcmp (l10n, "messages") == 0)
        state->l10n = 'm';

      else if (strcmp (l10n, "time") == 0)
        state->l10n = 't';

      else
        {
          g_set_error (error, G_MARKUP_ERROR,
                       G_MARKUP_ERROR_INVALID_CONTENT,
                       "unsupported l10n category: %s", l10n);
          return NULL;
        }

      if (!state->have_gettext_domain)
        {
          g_set_error_literal (error, G_MARKUP_ERROR,
                               G_MARKUP_ERROR_INVALID_CONTENT,
                               "l10n requested, but no "
                               "gettext domain given");
          return NULL;
        }

      state->l10n_context = g_strdup (context);
    }

  else if (context != NULL)
    {
      g_set_error_literal (error, G_MARKUP_ERROR,
                           G_MARKUP_ERROR_INVALID_CONTENT,
                           "translation context given for "
                           " value without l10n enabled");
      return NULL;
    }

  return g_string_new (NULL);
}

static void
key_state_end_default (KeyState  *state,
                       GString  **string,
                       GError   **error)
{
  state->unparsed_default_value = *string;
  *string = NULL;

  state->default_value = g_variant_parse (state->type,
                                          state->unparsed_default_value->str,
                                          NULL, NULL, error);
  key_state_check_range (state, error);
}

static void
key_state_start_choices (KeyState  *state,
                         GError   **error)
{
  const GVariantType *type = state->type;

  if (state->is_enum)
    {
      g_set_error_literal (error, G_MARKUP_ERROR,
                           G_MARKUP_ERROR_INVALID_CONTENT,
                           "<choices> cannot be specified for keys "
                           "tagged as having an enumerated type");
      return;
    }

  if (state->has_choices)
    {
      g_set_error_literal (error, G_MARKUP_ERROR,
                           G_MARKUP_ERROR_INVALID_CONTENT,
                           "<choices> already specified for this key");
      return;
    }

  while (g_variant_type_is_maybe (type) || g_variant_type_is_array (type))
    type = g_variant_type_element (type);

  if (!g_variant_type_equal (type, G_VARIANT_TYPE_STRING))
    {
      gchar *type_string = g_variant_type_dup_string (state->type);
      g_set_error (error, G_MARKUP_ERROR,
                   G_MARKUP_ERROR_INVALID_CONTENT,
                   "<choices> not allowed for keys of type '%s'",
                   type_string);
      g_free (type_string);
      return;
    }
}

static void
key_state_add_choice (KeyState     *state,
                      const gchar  *choice,
                      GError      **error)
{
  if (strinfo_builder_contains (state->strinfo, choice))
    {
      g_set_error (error, G_MARKUP_ERROR,
                   G_MARKUP_ERROR_INVALID_CONTENT,
                   "<choice value='%s'/> already given", choice);
      return;
    }

  strinfo_builder_append_item (state->strinfo, choice, 0);
  state->has_choices = TRUE;
}

static void
key_state_end_choices (KeyState  *state,
                       GError   **error)
{
  if (!state->has_choices)
    {
      g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
                   "<choices> must contain at least one <choice>");
      return;
    }

  key_state_check_range (state, error);
}

static void
key_state_start_aliases (KeyState  *state,
                         GError   **error)
{
  if (state->has_aliases)
    g_set_error_literal (error, G_MARKUP_ERROR,
                         G_MARKUP_ERROR_INVALID_CONTENT,
                         "<aliases> already specified for this key");
  else if (!state->is_flags && !state->is_enum && !state->has_choices)
    g_set_error_literal (error, G_MARKUP_ERROR,
                         G_MARKUP_ERROR_INVALID_CONTENT,
                         "<aliases> can only be specified for keys with "
                         "enumerated or flags types or after <choices>");
}

static void
key_state_add_alias (KeyState     *state,
                     const gchar  *alias,
                     const gchar  *target,
                     GError      **error)
{
  if (strinfo_builder_contains (state->strinfo, alias))
    {
      if (strinfo_is_string_valid ((guint32 *) state->strinfo->str,
                                   state->strinfo->len / 4,
                                   alias))
        {
          if (state->is_enum)
            g_set_error (error, G_MARKUP_ERROR,
                         G_MARKUP_ERROR_INVALID_CONTENT,
                         "<alias value='%s'/> given when '%s' is already "
                         "a member of the enumerated type", alias, alias);

          else
            g_set_error (error, G_MARKUP_ERROR,
                         G_MARKUP_ERROR_INVALID_CONTENT,
                         "<alias value='%s'/> given when "
                         "<choice value='%s'/> was already given",
                         alias, alias);
        }

      else
        g_set_error (error, G_MARKUP_ERROR,
                     G_MARKUP_ERROR_INVALID_CONTENT,
                     "<alias value='%s'/> already specified", alias);

      return;
    }

  if (!strinfo_builder_append_alias (state->strinfo, alias, target))
    {
      g_set_error (error, G_MARKUP_ERROR,
                   G_MARKUP_ERROR_INVALID_CONTENT,
                   "alias target '%s' is not in %s", target,
                   state->is_enum ? "enumerated type" : "<choices>");
      return;
    }

  state->has_aliases = TRUE;
}

static void
key_state_end_aliases (KeyState  *state,
                       GError   **error)
{
  if (!state->has_aliases)
    {
      g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
                   "<aliases> must contain at least one <alias>");
      return;
    }
}

static gboolean
key_state_check (KeyState  *state,
                 GError   **error)
{
  if (state->checked)
    return TRUE;

  return state->checked = TRUE;
}

static GVariant *
key_state_serialise (KeyState *state)
{
  if (state->serialised == NULL)
    {
      if (state->child_schema)
        {
          state->serialised = g_variant_new_string (state->child_schema);
        }

      else
        {
          GVariantBuilder builder;

          g_assert (key_state_check (state, NULL));

          g_variant_builder_init (&builder, G_VARIANT_TYPE_TUPLE);

          /* default value */
          g_variant_builder_add_value (&builder, state->default_value);

          /* translation */
          if (state->l10n)
            {
              /* We are going to store the untranslated default for
               * runtime translation according to the current locale.
               * We need to strip leading and trailing whitespace from
               * the string so that it's exactly the same as the one
               * that ended up in the .po file for translation.
               *
               * We want to do this so that
               *
               *   <default l10n='messages'>
               *     ['a', 'b', 'c']
               *   </default>
               *
               * ends up in the .po file like "['a', 'b', 'c']",
               * omitting the extra whitespace at the start and end.
               */
              strip_string (state->unparsed_default_value);

              if (state->l10n_context)
                {
                  gint len;

                  /* Contextified messages are supported by prepending
                   * the context, followed by '\004' to the start of the
                   * message string.  We do that here to save GSettings
                   * the work later on.
                   */
                  len = strlen (state->l10n_context);
                  state->l10n_context[len] = '\004';
                  g_string_prepend_len (state->unparsed_default_value,
                                        state->l10n_context, len + 1);
                  g_free (state->l10n_context);
                  state->l10n_context = NULL;
                }

              g_variant_builder_add (&builder, "(y(y&s))", 'l', state->l10n,
                                     state->unparsed_default_value->str);
              g_string_free (state->unparsed_default_value, TRUE);
              state->unparsed_default_value = NULL;
            }

          /* choice, aliases, enums */
          if (state->strinfo->len)
            {
              GVariant *array;
              guint32 *words;
              gpointer data;
              gsize size;
              gint i;

              data = state->strinfo->str;
              size = state->strinfo->len;

              words = data;
              for (i = 0; i < size / sizeof (guint32); i++)
                words[i] = GUINT32_TO_LE (words[i]);

              array = g_variant_new_from_data (G_VARIANT_TYPE ("au"),
                                               data, size, TRUE,
                                               g_free, data);

              g_string_free (state->strinfo, FALSE);
              state->strinfo = NULL;

              g_variant_builder_add (&builder, "(y@au)",
                                     state->is_flags ? 'f' :
                                     state->is_enum ? 'e' : 'c',
                                     array);
            }

          /* range */
          if (state->minimum || state->maximum)
            g_variant_builder_add (&builder, "(y(**))", 'r',
                                   state->minimum, state->maximum);

          state->serialised = g_variant_builder_end (&builder);
        }

      g_variant_ref_sink (state->serialised);
    }

  return g_variant_ref (state->serialised);
}

static void
key_state_free (gpointer data)
{
  KeyState *state = data;

  if (state->type)
    g_variant_type_free (state->type);

  g_free (state->l10n_context);

  if (state->unparsed_default_value)
    g_string_free (state->unparsed_default_value, TRUE);

  if (state->default_value)
    g_variant_unref (state->default_value);

  if (state->strinfo)
    g_string_free (state->strinfo, TRUE);

  if (state->minimum)
    g_variant_unref (state->minimum);

  if (state->maximum)
    g_variant_unref (state->maximum);

  if (state->serialised)
    g_variant_unref (state->serialised);

  g_slice_free (KeyState, state);
}

/* Key name validity {{{1 */
static gboolean allow_any_name = FALSE;

static gboolean
is_valid_keyname (const gchar  *key,
                  GError      **error)
{
  gint i;

  if (key[0] == '\0')
    {
      g_set_error_literal (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
                           _("empty names are not permitted"));
      return FALSE;
    }

  if (allow_any_name)
    return TRUE;

  if (!g_ascii_islower (key[0]))
    {
      g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
                   _("invalid name '%s': names must begin "
                     "with a lowercase letter"), key);
      return FALSE;
    }

  for (i = 1; key[i]; i++)
    {
      if (key[i] != '-' &&
          !g_ascii_islower (key[i]) &&
          !g_ascii_isdigit (key[i]))
        {
          g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
                       _("invalid name '%s': invalid character '%c'; "
                         "only lowercase letters, numbers and hyphen ('-') "
                         "are permitted."), key, key[i]);
          return FALSE;
        }

      if (key[i] == '-' && key[i + 1] == '-')
        {
          g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
                       _("invalid name '%s': two successive hyphens ('--') "
                         "are not permitted."), key);
          return FALSE;
        }
    }

  if (key[i - 1] == '-')
    {
      g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
                   _("invalid name '%s': the last character may not be a "
                     "hyphen ('-')."), key);
      return FALSE;
    }

  if (i > 1024)
    {
      g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
                   _("invalid name '%s': maximum length is 1024"), key);
      return FALSE;
    }

  return TRUE;
}

/* Handling of <schema> {{{1 */
typedef struct _SchemaState SchemaState;
struct _SchemaState
{
  SchemaState *extends;

  gchar       *path;
  gchar       *gettext_domain;
  gchar       *extends_name;
  gchar       *list_of;

  GHashTable  *keys;
};

static SchemaState *
schema_state_new (const gchar  *path,
                  const gchar  *gettext_domain,
                  SchemaState  *extends,
                  const gchar  *extends_name,
                  const gchar  *list_of)
{
  SchemaState *state;

  state = g_slice_new (SchemaState);
  state->path = g_strdup (path);
  state->gettext_domain = g_strdup (gettext_domain);
  state->extends = extends;
  state->extends_name = g_strdup (extends_name);
  state->list_of = g_strdup (list_of);
  state->keys = g_hash_table_new_full (g_str_hash, g_str_equal,
                                       g_free, key_state_free);

  return state;
}

static void
schema_state_free (gpointer data)
{
  SchemaState *state = data;

  g_free (state->path);
  g_free (state->gettext_domain);
  g_hash_table_unref (state->keys);
}

static void
schema_state_add_child (SchemaState  *state,
                        const gchar  *name,
                        const gchar  *schema,
                        GError      **error)
{
  gchar *childname;

  if (!is_valid_keyname (name, error))
    return;

  childname = g_strconcat (name, "/", NULL);

  if (g_hash_table_lookup (state->keys, childname))
    {
      g_set_error (error, G_MARKUP_ERROR,
                   G_MARKUP_ERROR_INVALID_CONTENT,
                   _("<child name='%s'> already specified"), name);
      return;
    }

  g_hash_table_insert (state->keys, childname,
                       key_state_new_child (schema));
}

static KeyState *
schema_state_add_key (SchemaState  *state,
                      GHashTable   *enum_table,
                      GHashTable   *flags_table,
                      const gchar  *name,
                      const gchar  *type_string,
                      const gchar  *enum_type,
                      const gchar  *flags_type,
                      GError      **error)
{
  SchemaState *node;
  GString *strinfo;
  KeyState *key;

  if (state->list_of)
    {
      g_set_error_literal (error, G_MARKUP_ERROR,
                           G_MARKUP_ERROR_INVALID_CONTENT,
                           _("cannot add keys to a 'list-of' schema"));
      return NULL;
    }

  if (!is_valid_keyname (name, error))
    return NULL;

  if (g_hash_table_lookup (state->keys, name))
    {
      g_set_error (error, G_MARKUP_ERROR,
                   G_MARKUP_ERROR_INVALID_CONTENT,
                   _("<key name='%s'> already specified"), name);
      return NULL;
    }

  for (node = state; node; node = node->extends)
    if (node->extends)
      {
        KeyState *shadow;

        shadow = g_hash_table_lookup (node->extends->keys, name);

        /* in case of <key> <override> <key> make sure we report the
         * location of the original <key>, not the <override>.
         */
        if (shadow && !shadow->is_override)
          {
            g_set_error (error, G_MARKUP_ERROR,
                         G_MARKUP_ERROR_INVALID_CONTENT,
                         _("<key name='%s'> shadows <key name='%s'> in "
                           "<schema id='%s'>; use <override> to modify value"),
                         name, name, node->extends_name);
            return NULL;
          }
      }

  if ((type_string != NULL) + (enum_type != NULL) + (flags_type != NULL) != 1)
    {
      g_set_error (error, G_MARKUP_ERROR,
                   G_MARKUP_ERROR_MISSING_ATTRIBUTE,
                   _("exactly one of 'type', 'enum' or 'flags' must "
                     "be specified as an attribute to <key>"));
      return NULL;
    }

  if (type_string == NULL) /* flags or enums was specified */
    {
      EnumState *enum_state;

      if (enum_type)
        enum_state = g_hash_table_lookup (enum_table, enum_type);
      else
        enum_state = g_hash_table_lookup (flags_table, flags_type);


      if (enum_state == NULL)
        {
          g_set_error (error, G_MARKUP_ERROR,
                       G_MARKUP_ERROR_INVALID_CONTENT,
                       _("<%s id='%s'> not (yet) defined."),
                       flags_type ? "flags"    : "enum",
                       flags_type ? flags_type : enum_type);
          return NULL;
        }

      type_string = flags_type ? "as" : "s";
      strinfo = enum_state->strinfo;
    }
  else
    {
      if (!g_variant_type_string_is_valid (type_string))
        {
          g_set_error (error, G_MARKUP_ERROR,
                       G_MARKUP_ERROR_INVALID_CONTENT,
                       _("invalid GVariant type string '%s'"), type_string);
          return NULL;
        }

      strinfo = NULL;
    }

  key = key_state_new (type_string, state->gettext_domain,
                       enum_type != NULL, flags_type != NULL, strinfo);
  g_hash_table_insert (state->keys, g_strdup (name), key);

  return key;
}

static void
schema_state_add_override (SchemaState  *state,
                           KeyState    **key_state,
                           GString     **string,
                           const gchar  *key,
                           const gchar  *l10n,
                           const gchar  *context,
                           GError      **error)
{
  SchemaState *parent;
  KeyState *original;

  if (state->extends == NULL)
    {
      g_set_error_literal (error, G_MARKUP_ERROR,
                           G_MARKUP_ERROR_INVALID_CONTENT,
                           _("<override> given but schema isn't "
                             "extending anything"));
      return;
    }

  for (parent = state->extends; parent; parent = parent->extends)
    if ((original = g_hash_table_lookup (parent->keys, key)))
      break;

  if (original == NULL)
    {
      g_set_error (error, G_MARKUP_ERROR,
                   G_MARKUP_ERROR_INVALID_CONTENT,
                   _("no <key name='%s'> to override"), key);
      return;
    }

  if (g_hash_table_lookup (state->keys, key))
    {
      g_set_error (error, G_MARKUP_ERROR,
                   G_MARKUP_ERROR_INVALID_CONTENT,
                   _("<override name='%s'> already specified"), key);
      return;
    }

  *key_state = key_state_override (original, state->gettext_domain);
  *string = key_state_start_default (*key_state, l10n, context, error);
  g_hash_table_insert (state->keys, g_strdup (key), *key_state);
}

static void
override_state_end (KeyState **key_state,
                    GString  **string,
                    GError   **error)
{
  key_state_end_default (*key_state, string, error);
  *key_state = NULL;
}

/* Handling of toplevel state {{{1 */
typedef struct
{
  GHashTable  *schema_table;            /* string -> SchemaState */
  GHashTable  *flags_table;             /* string -> EnumState */
  GHashTable  *enum_table;              /* string -> EnumState */

  GSList      *this_file_schemas;       /* strings: <schema>s in this file */
  GSList      *this_file_flagss;        /* strings: <flags>s in this file */
  GSList      *this_file_enums;         /* strings: <enum>s in this file */

  gchar       *schemalist_domain;       /* the <schemalist> gettext domain */

  SchemaState *schema_state;            /* non-NULL when inside <schema> */
  KeyState    *key_state;               /* non-NULL when inside <key> */
  EnumState   *enum_state;              /* non-NULL when inside <enum> */

  GString     *string;                  /* non-NULL when accepting text */
} ParseState;

static gboolean
is_subclass (const gchar *class_name,
             const gchar *possible_parent,
             GHashTable  *schema_table)
{
  SchemaState *class;

  if (strcmp (class_name, possible_parent) == 0)
    return TRUE;

  class = g_hash_table_lookup (schema_table, class_name);
  g_assert (class != NULL);

  return class->extends_name &&
         is_subclass (class->extends_name, possible_parent, schema_table);
}

static void
parse_state_start_schema (ParseState  *state,
                          const gchar  *id,
                          const gchar  *path,
                          const gchar  *gettext_domain,
                          const gchar  *extends_name,
                          const gchar  *list_of,
                          GError      **error)
{
  SchemaState *extends;
  gchar *my_id;

  if (g_hash_table_lookup (state->schema_table, id))
    {
      g_set_error (error, G_MARKUP_ERROR,
                   G_MARKUP_ERROR_INVALID_CONTENT,
                   _("<schema id='%s'> already specified"), id);
      return;
    }

  if (extends_name)
    {
      extends = g_hash_table_lookup (state->schema_table, extends_name);

      if (extends == NULL)
        {
          g_set_error (error, G_MARKUP_ERROR,
                       G_MARKUP_ERROR_INVALID_CONTENT,
                       _("<schema id='%s'> extends not-yet-existing "
                         "schema '%s'"), id, extends_name);
          return;
        }
    }
  else
    extends = NULL;

  if (list_of)
    {
      SchemaState *tmp;

      if (!(tmp = g_hash_table_lookup (state->schema_table, list_of)))
        {
          g_set_error (error, G_MARKUP_ERROR,
                       G_MARKUP_ERROR_INVALID_CONTENT,
                       _("<schema id='%s'> is list of not-yet-existing "
                         "schema '%s'"), id, list_of);
          return;
        }

      if (tmp->path)
        {
          g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
                       _("Can not be a list of a schema with a path"));
          return;
        }
    }

  if (extends)
    {
      if (extends->path)
        {
          g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
                       _("Can not extend a schema with a path"));
          return;
        }

      if (list_of)
        {
          if (extends->list_of == NULL)
            {
              g_set_error (error, G_MARKUP_ERROR,
                           G_MARKUP_ERROR_INVALID_CONTENT,
                           _("<schema id='%s'> is a list, extending "
                             "<schema id='%s'> which is not a list"),
                           id, extends_name);
              return;
            }

          if (!is_subclass (list_of, extends->list_of, state->schema_table))
            {
              g_set_error (error, G_MARKUP_ERROR,
                           G_MARKUP_ERROR_INVALID_CONTENT,
                           _("<schema id='%s' list-of='%s'> extends <schema "
                             "id='%s' list-of='%s'> but '%s' does not "
                             "extend '%s'"), id, list_of, extends_name,
                           extends->list_of, list_of, extends->list_of);
              return;
            }
        }
      else
        /* by default we are a list of the same thing that the schema
         * we are extending is a list of (which might be nothing)
         */
        list_of = extends->list_of;
    }

  if (path && !(g_str_has_prefix (path, "/") && g_str_has_suffix (path, "/")))
    {
      g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
                   _("a path, if given, must begin and end with a slash"));
      return;
    }

  if (path && list_of && !g_str_has_suffix (path, ":/"))
    {
      g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
                   _("the path of a list must end with ':/'"));
      return;
    }

  if (path && (g_str_has_prefix (path, "/apps/") ||
               g_str_has_prefix (path, "/desktop/") ||
               g_str_has_prefix (path, "/system/")))
    g_printerr ("warning: Schema '%s' has path '%s'.  Paths starting with "
                "'/apps/', '/desktop/' or '/system/' are deprecated.\n", id, path);

  state->schema_state = schema_state_new (path, gettext_domain,
                                          extends, extends_name, list_of);

  my_id = g_strdup (id);
  state->this_file_schemas = g_slist_prepend (state->this_file_schemas, my_id);
  g_hash_table_insert (state->schema_table, my_id, state->schema_state);
}

static void
parse_state_start_enum (ParseState   *state,
                        const gchar  *id,
                        gboolean      is_flags,
                        GError      **error)
{
  GSList **list = is_flags ? &state->this_file_flagss : &state->this_file_enums;
  GHashTable *table = is_flags ? state->flags_table : state->enum_table;
  gchar *my_id;

  if (g_hash_table_lookup (table, id))
    {
      g_set_error (error, G_MARKUP_ERROR,
                   G_MARKUP_ERROR_INVALID_CONTENT,
                   _("<%s id='%s'> already specified"),
                   is_flags ? "flags" : "enum", id);
      return;
    }

  state->enum_state = enum_state_new (is_flags);

  my_id = g_strdup (id);
  *list = g_slist_prepend (*list, my_id);
  g_hash_table_insert (table, my_id, state->enum_state);
}

/* GMarkup Parser Functions {{{1 */

/* Start element {{{2 */
static void
start_element (GMarkupParseContext  *context,
               const gchar          *element_name,
               const gchar         **attribute_names,
               const gchar         **attribute_values,
               gpointer              user_data,
               GError              **error)
{
  ParseState *state = user_data;
  const GSList *element_stack;
  const gchar *container;

  element_stack = g_markup_parse_context_get_element_stack (context);
  container = element_stack->next ? element_stack->next->data : NULL;

#define COLLECT(first, ...) \
  g_markup_collect_attributes (element_name,                                 \
                               attribute_names, attribute_values, error,     \
                               first, __VA_ARGS__, G_MARKUP_COLLECT_INVALID)
#define OPTIONAL   G_MARKUP_COLLECT_OPTIONAL
#define STRDUP     G_MARKUP_COLLECT_STRDUP
#define STRING     G_MARKUP_COLLECT_STRING
#define NO_ATTRS()  COLLECT (G_MARKUP_COLLECT_INVALID, NULL)

  /* Toplevel items {{{3 */
  if (container == NULL)
    {
      if (strcmp (element_name, "schemalist") == 0)
        {
          COLLECT (OPTIONAL | STRDUP,
                   "gettext-domain",
                   &state->schemalist_domain);
          return;
        }
    }


  /* children of <schemalist> {{{3 */
  else if (strcmp (container, "schemalist") == 0)
    {
      if (strcmp (element_name, "schema") == 0)
        {
          const gchar *id, *path, *gettext_domain, *extends, *list_of;
          if (COLLECT (STRING, "id", &id,
                       OPTIONAL | STRING, "path", &path,
                       OPTIONAL | STRING, "gettext-domain", &gettext_domain,
                       OPTIONAL | STRING, "extends", &extends,
                       OPTIONAL | STRING, "list-of", &list_of))
            parse_state_start_schema (state, id, path,
                                      gettext_domain ? gettext_domain
                                                     : state->schemalist_domain,
                                      extends, list_of, error);
          return;
        }

      else if (strcmp (element_name, "enum") == 0)
        {
          const gchar *id;
          if (COLLECT (STRING, "id", &id))
            parse_state_start_enum (state, id, FALSE, error);
          return;
        }

      else if (strcmp (element_name, "flags") == 0)
        {
          const gchar *id;
          if (COLLECT (STRING, "id", &id))
            parse_state_start_enum (state, id, TRUE, error);
          return;
        }
    }


  /* children of <schema> {{{3 */
  else if (strcmp (container, "schema") == 0)
    {
      if (strcmp (element_name, "key") == 0)
        {
          const gchar *name, *type_string, *enum_type, *flags_type;

          if (COLLECT (STRING,            "name",  &name,
                       OPTIONAL | STRING, "type",  &type_string,
                       OPTIONAL | STRING, "enum",  &enum_type,
                       OPTIONAL | STRING, "flags", &flags_type))

            state->key_state = schema_state_add_key (state->schema_state,
                                                     state->enum_table,
                                                     state->flags_table,
                                                     name, type_string,
                                                     enum_type, flags_type,
                                                     error);
          return;
        }
      else if (strcmp (element_name, "child") == 0)
        {
          const gchar *name, *schema;

          if (COLLECT (STRING, "name", &name, STRING, "schema", &schema))
            schema_state_add_child (state->schema_state,
                                    name, schema, error);
          return;
        }
      else if (strcmp (element_name, "override") == 0)
        {
          const gchar *name, *l10n, *context;

          if (COLLECT (STRING,            "name",    &name,
                       OPTIONAL | STRING, "l10n",    &l10n,
                       OPTIONAL | STRING, "context", &context))
            schema_state_add_override (state->schema_state,
                                       &state->key_state, &state->string,
                                       name, l10n, context, error);
          return;
        }
    }

  /* children of <key> {{{3 */
  else if (strcmp (container, "key") == 0)
    {
      if (strcmp (element_name, "default") == 0)
        {
          const gchar *l10n, *context;
          if (COLLECT (STRING | OPTIONAL, "l10n",    &l10n,
                       STRING | OPTIONAL, "context", &context))
            state->string = key_state_start_default (state->key_state,
                                                     l10n, context, error);
          return;
        }

      else if (strcmp (element_name, "summary") == 0 ||
               strcmp (element_name, "description") == 0)
        {
          if (NO_ATTRS ())
            state->string = g_string_new (NULL);
          return;
        }

      else if (strcmp (element_name, "range") == 0)
        {
          const gchar *min, *max;
          if (COLLECT (STRING | OPTIONAL, "min", &min,
                       STRING | OPTIONAL, "max", &max))
            key_state_set_range (state->key_state, min, max, error);
          return;
        }

      else if (strcmp (element_name, "choices") == 0)
        {
          if (NO_ATTRS ())
            key_state_start_choices (state->key_state, error);
          return;
        }

      else if (strcmp (element_name, "aliases") == 0)
        {
          if (NO_ATTRS ())
            key_state_start_aliases (state->key_state, error);
          return;
        }
    }


  /* children of <choices> {{{3 */
  else if (strcmp (container, "choices") == 0)
    {
      if (strcmp (element_name, "choice") == 0)
        {
          const gchar *value;
          if (COLLECT (STRING, "value", &value))
            key_state_add_choice (state->key_state, value, error);
          return;
        }
    }


  /* children of <aliases> {{{3 */
  else if (strcmp (container, "aliases") == 0)
    {
      if (strcmp (element_name, "alias") == 0)
        {
          const gchar *value, *target;
          if (COLLECT (STRING, "value", &value, STRING, "target", &target))
            key_state_add_alias (state->key_state, value, target, error);
          return;
        }
    }


  /* children of <enum> {{{3 */
  else if (strcmp (container, "enum") == 0 ||
           strcmp (container, "flags") == 0)
    {
      if (strcmp (element_name, "value") == 0)
        {
          const gchar *nick, *valuestr;
          if (COLLECT (STRING, "nick", &nick,
                       STRING, "value", &valuestr))
            enum_state_add_value (state->enum_state, nick, valuestr, error);
          return;
        }
    }
  /* 3}}} */

  if (container)
    g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_UNKNOWN_ELEMENT,
                 _("Element <%s> not allowed inside <%s>"),
                 element_name, container);
  else
    g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_UNKNOWN_ELEMENT,
                 _("Element <%s> not allowed at the top level"), element_name);
}
/* 2}}} */
/* End element {{{2 */

static void
key_state_end (KeyState **state_ptr,
               GError   **error)
{
  KeyState *state;

  state = *state_ptr;
  *state_ptr = NULL;

  if (state->default_value == NULL)
    {
      g_set_error_literal (error,
                           G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
                           "element <default> is required in <key>");
      return;
    }
}

static void
schema_state_end (SchemaState **state_ptr,
                  GError      **error)
{
  *state_ptr = NULL;
}

static void
end_element (GMarkupParseContext  *context,
             const gchar          *element_name,
             gpointer              user_data,
             GError              **error)
{
  ParseState *state = user_data;

  if (strcmp (element_name, "schemalist") == 0)
    {
      g_free (state->schemalist_domain);
      state->schemalist_domain = NULL;
    }

  else if (strcmp (element_name, "enum") == 0 ||
           strcmp (element_name, "flags") == 0)
    enum_state_end (&state->enum_state, error);

  else if (strcmp (element_name, "schema") == 0)
    schema_state_end (&state->schema_state, error);

  else if (strcmp (element_name, "override") == 0)
    override_state_end (&state->key_state, &state->string, error);

  else if (strcmp (element_name, "key") == 0)
    key_state_end (&state->key_state, error);

  else if (strcmp (element_name, "default") == 0)
    key_state_end_default (state->key_state, &state->string, error);

  else if (strcmp (element_name, "choices") == 0)
    key_state_end_choices (state->key_state, error);

  else if (strcmp (element_name, "aliases") == 0)
    key_state_end_aliases (state->key_state, error);

  if (state->string)
    {
      g_string_free (state->string, TRUE);
      state->string = NULL;
    }
}
/* Text {{{2 */
static void
text (GMarkupParseContext  *context,
      const gchar          *text,
      gsize                 text_len,
      gpointer              user_data,
      GError              **error)
{
  ParseState *state = user_data;

  if (state->string)
    {
      /* we are expecting a string, so store the text data.
       *
       * we store the data verbatim here and deal with whitespace
       * later on.  there are two reasons for that:
       *
       *  1) whitespace is handled differently depending on the tag
       *     type.
       *
       *  2) we could do leading whitespace removal by refusing to
       *     insert it into state->string if it's at the start, but for
       *     trailing whitespace, we have no idea if there is another
       *     text() call coming or not.
       */
      g_string_append_len (state->string, text, text_len);
    }
  else
    {
      /* string is not expected: accept (and ignore) pure whitespace */
      gsize i;

      for (i = 0; i < text_len; i++)
        if (!g_ascii_isspace (text[i]))
          {
            g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
                         _("text may not appear inside <%s>"),
                         g_markup_parse_context_get_element (context));
            break;
          }
    }
}

/* Write to GVDB {{{1 */
typedef struct
{
  GHashTable *table;
  GvdbItem *root;
} GvdbPair;

static void
gvdb_pair_init (GvdbPair *pair)
{
  pair->table = gvdb_hash_table_new (NULL, NULL);
  pair->root = gvdb_hash_table_insert (pair->table, "");
}

typedef struct
{
  GHashTable *schema_table;
  GvdbPair root_pair;
} WriteToFileData;

typedef struct
{
  GHashTable *schema_table;
  GvdbPair pair;
  gboolean l10n;
} OutputSchemaData;

static void
output_key (gpointer key,
            gpointer value,
            gpointer user_data)
{
  OutputSchemaData *data;
  const gchar *name;
  KeyState *state;
  GvdbItem *item;

  name = key;
  state = value;
  data = user_data;

  item = gvdb_hash_table_insert (data->pair.table, name);
  gvdb_item_set_parent (item, data->pair.root);
  gvdb_item_set_value (item, key_state_serialise (state));

  if (state->l10n)
    data->l10n = TRUE;

  if (state->child_schema &&
      !g_hash_table_lookup (data->schema_table, state->child_schema))
    g_printerr ("warning: undefined reference to <schema id='%s'/>\n",
                state->child_schema);
}

static void
output_schema (gpointer key,
               gpointer value,
               gpointer user_data)
{
  WriteToFileData *wtf_data = user_data;
  OutputSchemaData data;
  GvdbPair *root_pair;
  SchemaState *state;
  const gchar *id;
  GvdbItem *item;

  id = key;
  state = value;
  root_pair = &wtf_data->root_pair;

  data.schema_table = wtf_data->schema_table;
  gvdb_pair_init (&data.pair);
  data.l10n = FALSE;

  item = gvdb_hash_table_insert (root_pair->table, id);
  gvdb_item_set_parent (item, root_pair->root);
  gvdb_item_set_hash_table (item, data.pair.table);

  g_hash_table_foreach (state->keys, output_key, &data);

  if (state->path)
    gvdb_hash_table_insert_string (data.pair.table, ".path", state->path);

  if (state->extends_name)
    gvdb_hash_table_insert_string (data.pair.table, ".extends",
                                   state->extends_name);

  if (state->list_of)
    gvdb_hash_table_insert_string (data.pair.table, ".list-of",
                                   state->list_of);

  if (data.l10n)
    gvdb_hash_table_insert_string (data.pair.table,
                                   ".gettext-domain",
                                   state->gettext_domain);
}

static gboolean
write_to_file (GHashTable   *schema_table,
               const gchar  *filename,
               GError      **error)
{
  WriteToFileData data;
  gboolean success;

  data.schema_table = schema_table;

  gvdb_pair_init (&data.root_pair);

  g_hash_table_foreach (schema_table, output_schema, &data);

  success = gvdb_table_write_contents (data.root_pair.table, filename,
                                       G_BYTE_ORDER != G_LITTLE_ENDIAN,
                                       error);
  g_hash_table_unref (data.root_pair.table);

  return success;
}

/* Parser driver {{{1 */
static GHashTable *
parse_gschema_files (gchar    **files,
                     gboolean   strict)
{
  GMarkupParser parser = { start_element, end_element, text };
  ParseState state = { 0, };
  const gchar *filename;
  GError *error = NULL;

  state.enum_table = g_hash_table_new_full (g_str_hash, g_str_equal,
                                            g_free, enum_state_free);

  state.flags_table = g_hash_table_new_full (g_str_hash, g_str_equal,
                                             g_free, enum_state_free);

  state.schema_table = g_hash_table_new_full (g_str_hash, g_str_equal,
                                              g_free, schema_state_free);

  while ((filename = *files++) != NULL)
    {
      GMarkupParseContext *context;
      gchar *contents;
      gsize size;

      if (!g_file_get_contents (filename, &contents, &size, &error))
        {
          fprintf (stderr, "%s\n", error->message);
          g_clear_error (&error);
          continue;
        }

      context = g_markup_parse_context_new (&parser,
                                            G_MARKUP_TREAT_CDATA_AS_TEXT |
                                            G_MARKUP_PREFIX_ERROR_POSITION,
                                            &state, NULL);


      if (!g_markup_parse_context_parse (context, contents, size, &error) ||
          !g_markup_parse_context_end_parse (context, &error))
        {
          GSList *item;

          /* back out any changes from this file */
          for (item = state.this_file_schemas; item; item = item->next)
            g_hash_table_remove (state.schema_table, item->data);

          for (item = state.this_file_flagss; item; item = item->next)
            g_hash_table_remove (state.flags_table, item->data);

          for (item = state.this_file_enums; item; item = item->next)
            g_hash_table_remove (state.enum_table, item->data);

          /* let them know */
          fprintf (stderr, "%s: %s.  ", filename, error->message);
          g_clear_error (&error);

          if (strict)
            {
              /* Translators: Do not translate "--strict". */
              fprintf (stderr, _("--strict was specified; exiting.\n"));
              g_hash_table_unref (state.schema_table);
              g_hash_table_unref (state.flags_table);
              g_hash_table_unref (state.enum_table);

              return NULL;
            }
          else
            fprintf (stderr, _("This entire file has been ignored.\n"));
        }

      /* cleanup */
      g_markup_parse_context_free (context);
      g_slist_free (state.this_file_schemas);
      g_slist_free (state.this_file_flagss);
      g_slist_free (state.this_file_enums);
      state.this_file_schemas = NULL;
      state.this_file_flagss = NULL;
      state.this_file_enums = NULL;
    }

  g_hash_table_unref (state.flags_table);
  g_hash_table_unref (state.enum_table);

  return state.schema_table;
}

static gint
compare_strings (gconstpointer a,
                 gconstpointer b)
{
  gchar *one = *(gchar **) a;
  gchar *two = *(gchar **) b;
  gint cmp;

  cmp = g_str_has_suffix (two, ".enums.xml") -
        g_str_has_suffix (one, ".enums.xml");

  if (!cmp)
    cmp = strcmp (one, two);

  return cmp;
}

static gboolean
set_overrides (GHashTable  *schema_table,
               gchar      **files,
               gboolean     strict)
{
  const gchar *filename;
  GError *error = NULL;

  while ((filename = *files++))
    {
      GKeyFile *key_file;
      gchar **groups;
      gint i;

      key_file = g_key_file_new ();
      if (!g_key_file_load_from_file (key_file, filename, 0, &error))
        {
          fprintf (stderr, "%s: %s.  ", filename, error->message);
          g_key_file_free (key_file);
          g_clear_error (&error);

          if (!strict)
            {
              fprintf (stderr, _("Ignoring this file.\n"));
              continue;
            }

          fprintf (stderr, _("--strict was specified; exiting.\n"));
          return FALSE;
        }

      groups = g_key_file_get_groups (key_file, NULL);

      for (i = 0; groups[i]; i++)
        {
          const gchar *group = groups[i];
          SchemaState *schema;
          gchar **keys;
          gint j;

          schema = g_hash_table_lookup (schema_table, group);

          if (schema == NULL)
            /* Having the schema not be installed is expected to be a
             * common case.  Don't even emit an error message about
             * that.
             */
            continue;

          keys = g_key_file_get_keys (key_file, group, NULL, NULL);
          g_assert (keys != NULL);

          for (j = 0; keys[j]; j++)
            {
              const gchar *key = keys[j];
              KeyState *state;
              GVariant *value;
              gchar *string;

              state = g_hash_table_lookup (schema->keys, key);

              if (state == NULL)
                {
                  fprintf (stderr, _("No such key `%s' in schema `%s' as "
                                     "specified in override file `%s'"),
                           key, group, filename);

                  if (!strict)
                    {
                      fprintf (stderr, _("; ignoring override for this key.\n"));
                      continue;
                    }

                  fprintf (stderr, _(" and --strict was specified; exiting.\n"));
                  g_key_file_free (key_file);
                  g_strfreev (groups);
                  g_strfreev (keys);

                  return FALSE;
                }

              string = g_key_file_get_value (key_file, group, key, NULL);
              g_assert (string != NULL);

              value = g_variant_parse (state->type, string,
                                       NULL, NULL, &error);

              if (value == NULL)
                {
                  fprintf (stderr, _("error parsing key `%s' in schema `%s' "
                                     "as specified in override file `%s': "
                                     "%s."),
                           key, group, filename, error->message);

                  g_clear_error (&error);
                  g_free (string);

                  if (!strict)
                    {
                      fprintf (stderr, _("Ignoring override for this key.\n"));
                      continue;
                    }

                  fprintf (stderr, _("--strict was specified; exiting.\n"));
                  g_key_file_free (key_file);
                  g_strfreev (groups);
                  g_strfreev (keys);

                  return FALSE;
                }

              if (state->minimum)
                {
                  if (g_variant_compare (value, state->minimum) < 0 ||
                      g_variant_compare (value, state->maximum) > 0)
                    {
                      fprintf (stderr,
                               _("override for key `%s' in schema `%s' in "
                                 "override file `%s' is outside the range "
                                 "given in the schema"),
                               key, group, filename);

                      g_variant_unref (value);
                      g_free (string);

                      if (!strict)
                        {
                          fprintf (stderr, _("; ignoring override for this key.\n"));
                          continue;
                        }

                      fprintf (stderr, _(" and --strict was specified; exiting.\n"));
                      g_key_file_free (key_file);
                      g_strfreev (groups);
                      g_strfreev (keys);

                      return FALSE;
                    }
                }

              else if (state->strinfo->len)
                {
                  if (!is_valid_choices (value, state->strinfo))
                    {
                      fprintf (stderr,
                               _("override for key `%s' in schema `%s' in "
                                 "override file `%s' is not in the list "
                                 "of valid choices"),
                               key, group, filename);

                      g_variant_unref (value);
                      g_free (string);

                      if (!strict)
                        {
                          fprintf (stderr, _("; ignoring override for this key.\n"));
                          continue;
                        }

                      fprintf (stderr, _(" and --strict was specified; exiting.\n"));
                      g_key_file_free (key_file);
                      g_strfreev (groups);
                      g_strfreev (keys);

                      return FALSE;
                    }
                }

              g_variant_unref (state->default_value);
              state->default_value = value;
              g_free (string);
            }

          g_strfreev (keys);
        }

      g_strfreev (groups);
    }

  return TRUE;
}

int
main (int argc, char **argv)
{
  GError *error;
  GHashTable *table;
  GDir *dir;
  const gchar *file;
  gchar *srcdir;
  gchar *targetdir = NULL;
  gchar *target;
  gboolean dry_run = FALSE;
  gboolean strict = FALSE;
  gchar **schema_files = NULL;
  gchar **override_files = NULL;
  GOptionContext *context;
  GOptionEntry entries[] = {
    { "targetdir", 0, 0, G_OPTION_ARG_FILENAME, &targetdir, N_("where to store the gschemas.compiled file"), N_("DIRECTORY") },
    { "strict", 0, 0, G_OPTION_ARG_NONE, &strict, N_("Abort on any errors in schemas"), NULL },
    { "dry-run", 0, 0, G_OPTION_ARG_NONE, &dry_run, N_("Do not write the gschema.compiled file"), NULL },
    { "allow-any-name", 0, 0, G_OPTION_ARG_NONE, &allow_any_name, N_("Do not enforce key name restrictions") },

    /* These options are only for use in the gschema-compile tests */
    { "schema-file", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_FILENAME_ARRAY, &schema_files, NULL, NULL },
    { NULL }
  };

#ifdef G_OS_WIN32
  gchar *tmp;
#endif

  setlocale (LC_ALL, "");
  textdomain (GETTEXT_PACKAGE);

#ifdef G_OS_WIN32
  tmp = _glib_get_locale_dir ();
  bindtextdomain (GETTEXT_PACKAGE, tmp);
  g_free (tmp);
#else
  bindtextdomain (GETTEXT_PACKAGE, GLIB_LOCALE_DIR);
#endif

#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
  bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
#endif

  context = g_option_context_new (N_("DIRECTORY"));
  g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);
  g_option_context_set_summary (context,
    N_("Compile all GSettings schema files into a schema cache.\n"
       "Schema files are required to have the extension .gschema.xml,\n"
       "and the cache file is called gschemas.compiled."));
  g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE);

  error = NULL;
  if (!g_option_context_parse (context, &argc, &argv, &error))
    {
      fprintf (stderr, "%s\n", error->message);
      return 1;
    }

  g_option_context_free (context);

  if (!schema_files && argc != 2)
    {
      fprintf (stderr, _("You should give exactly one directory name\n"));
      return 1;
    }

  srcdir = argv[1];

  if (targetdir == NULL)
    targetdir = srcdir;

  target = g_build_filename (targetdir, "gschemas.compiled", NULL);

  if (!schema_files)
    {
      GPtrArray *overrides;
      GPtrArray *files;

      files = g_ptr_array_new ();
      overrides = g_ptr_array_new ();

      dir = g_dir_open (srcdir, 0, &error);
      if (dir == NULL)
        {
          fprintf (stderr, "%s\n", error->message);
          return 1;
        }

      while ((file = g_dir_read_name (dir)) != NULL)
        {
          if (g_str_has_suffix (file, ".gschema.xml") ||
              g_str_has_suffix (file, ".enums.xml"))
            g_ptr_array_add (files, g_build_filename (srcdir, file, NULL));

          else if (g_str_has_suffix (file, ".gschema.override"))
            g_ptr_array_add (overrides,
                             g_build_filename (srcdir, file, NULL));
        }

      if (files->len == 0)
        {
          fprintf (stdout, _("No schema files found: "));

          if (g_unlink (target))
            fprintf (stdout, _("doing nothing.\n"));

          else
            fprintf (stdout, _("removed existing output file.\n"));

          return 0;
        }
      g_ptr_array_sort (files, compare_strings);
      g_ptr_array_add (files, NULL);

      g_ptr_array_sort (overrides, compare_strings);
      g_ptr_array_add (overrides, NULL);

      schema_files = (char **) g_ptr_array_free (files, FALSE);
      override_files = (gchar **) g_ptr_array_free (overrides, FALSE);
    }

  if ((table = parse_gschema_files (schema_files, strict)) == NULL)
    {
      g_free (target);
      return 1;
    }

  if (override_files != NULL &&
      !set_overrides (table, override_files, strict))
    {
      g_free (target);
      return 1;
    }

  if (!dry_run && !write_to_file (table, target, &error))
    {
      fprintf (stderr, "%s\n", error->message);
      g_free (target);
      return 1;
    }

  g_free (target);

  return 0;
}

/* Epilogue {{{1 */

/* vim:set foldmethod=marker: */
