/*
 * 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"

/* 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)
{
  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> 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 > 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,
                           _("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 | 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 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)
{
  *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
{
  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->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)
{
  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_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 }
  };

#ifdef G_OS_WIN32
  extern gchar *_glib_get_locale_dir (void);
  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: */
