/*
 * 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 */
#define _GNU_SOURCE
#include "config.h"

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

#include <gi18n.h>

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

/* 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);
}

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

  if (strchr ("ynqiuxtd", *(char *) state->type) == NULL)
    {
      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> can not 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)
            {
              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 dash ('-') "
                         "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 dashes ('--') "
                         "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 "
                     "dash ('-')."), key);
      return FALSE;
    }

  if (i > 32)
    {
      g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
                   _("invalid name '%s': maximum length is 32"), 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,
                           _("can not 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;
    }

  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, "min", &min, STRING, "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 toplevel"), 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)
{
  SchemaState *state;

  state = *state_ptr;
  *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;
  gsize i;

  for (i = 0; i < text_len; i++)
    if (!g_ascii_isspace (text[i]))
      {
        if (state->string)
          g_string_append_len (state->string, text, text_len);

        else
          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
{
  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;
}

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

  id = key;
  state = value;
  root_pair = user_data;

  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->extends_name);

  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)
{
  gboolean success;
  GvdbPair pair;

  gvdb_pair_init (&pair);

  g_hash_table_foreach (schema_table, output_schema, &pair);

  success = gvdb_table_write_contents (pair.table, filename,
                                       G_BYTE_ORDER != G_LITTLE_ENDIAN,
                                       error);
  g_hash_table_unref (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_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 out of 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 uninstall = FALSE;
  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 },
    { "uninstall", 0, 0, G_OPTION_ARG_NONE, &uninstall, N_("This option will be removed soon.") },
    { "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 }
  };

  setlocale (LC_ALL, "");

  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 (stderr, _("No schema files found: "));

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

          else
            fprintf (stderr, _("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: */
