[glib/enums] enum stuff



commit f13146a71146ee50db38acd4c035553841ab4265
Author: Ryan Lortie <desrt desrt ca>
Date:   Fri May 14 01:53:31 2010 +0200

    enum stuff

 gio/gio.symbols                    |    2 +
 gio/gschema-compile.c              |  205 +++++++++++++++++++++----
 gio/gsettings.c                    |  304 ++++++++++++++++++++++++++++--------
 gio/gsettings.h                    |    5 +
 gio/gsettingsbackend.c             |   27 +++-
 gio/pltcheck.sh                    |    1 +
 gio/tests/org.gtk.test.gschema.xml |   14 ++
 7 files changed, 461 insertions(+), 97 deletions(-)
---
diff --git a/gio/gio.symbols b/gio/gio.symbols
index c7adc7c..55c4817 100644
--- a/gio/gio.symbols
+++ b/gio/gio.symbols
@@ -1444,6 +1444,8 @@ g_settings_get_double
 g_settings_set_double
 g_settings_get_boolean
 g_settings_set_boolean
+g_settings_get_enum
+g_settings_set_enum
 #endif
 #endif
 
diff --git a/gio/gschema-compile.c b/gio/gschema-compile.c
index f8b535a..c0b787b 100644
--- a/gio/gschema-compile.c
+++ b/gio/gschema-compile.c
@@ -30,12 +30,35 @@
 
 #include "gvdb/gvdb-builder.h"
 
+static gpointer
+g_memmem (gconstpointer haystack,
+          gsize         haystack_len,
+          gconstpointer needle,
+          gsize         needle_len)
+{
+#ifndef HAVE_MEMMEM
+  while (needle_len <= haystack_len)
+    {
+      if (memcmp (haystack, needle, needle_len) == 0)
+        return (gpointer) haystack;
+
+      haystack = ((gchar *) haystack) + 1;
+      haystack_len--;
+    }
+
+  return NULL;
+#else
+  return memmem (haystack, haystack_len, needle, needle_len);
+#endif
+}
+
 typedef struct
 {
   gboolean byteswap;
 
   GVariantBuilder key_options;
   GHashTable *schemas;
+  GHashTable *enums;
   gchar *schemalist_domain;
 
   GHashTable *schema;
@@ -51,6 +74,8 @@ typedef struct
   gchar l10n;
   gchar *context;
   GVariantType *type;
+
+  GString *enumdesc;
 } ParseState;
 
 static gboolean allow_any_name = FALSE;
@@ -139,40 +164,53 @@ type_allows_range (const GVariantType *type)
 
 static gboolean
 is_valid_choices (GVariant    *variant,
-                  const gchar *choices)
+                  const gchar *choices,
+                  gsize        choices_size)
 {
   switch (g_variant_classify (variant))
     {
       case G_VARIANT_CLASS_MAYBE:
       case G_VARIANT_CLASS_ARRAY:
         {
-          gsize i, n;
-          GVariant *child;
-          gboolean is_valid;
+          gboolean valid = TRUE;
+          GVariantIter iter;
 
-          n = g_variant_n_children (variant);
-          for (i = 0; i < n; ++i)
-            {
-              child = g_variant_get_child_value (variant, i);
-              is_valid = is_valid_choices (child, choices);
-              g_variant_unref (child);
+          g_variant_iter_init (&iter, variant);
 
-              if (!is_valid)
-                return FALSE;
+          while (valid && (variant = g_variant_iter_next_value (&iter)))
+            {
+              valid = is_valid_choices (variant, choices, choices_size);
+              g_variant_unref (variant);
             }
 
-          return TRUE;
+          return valid;
         }
 
       case G_VARIANT_CLASS_STRING:
         {
+          gchar stack_buffer[64];
           const gchar *string;
+          gboolean matched;
+          gchar *buffer;
+          gsize length;
+
+          string = g_variant_get_string (variant, &length);
+
+          if (length + 2 <= sizeof stack_buffer)
+            buffer = stack_buffer;
+          else
+            buffer = g_malloc (length + 2);
 
-          g_variant_get (variant, "&s", &string);
+          buffer[0] = '\0';
+          memcpy (buffer + 1, string, length + 1);
 
-          while ((choices = strstr (choices, string)) && choices[-1] != 0xff);
+          matched = g_memmem (choices, choices_size,
+                              buffer, length + 2) != NULL;
 
-          return choices != NULL;
+          if (buffer != stack_buffer)
+            g_free (buffer);
+
+          return matched;
         }
 
       default:
@@ -241,18 +279,64 @@ start_element (GMarkupParseContext  *context,
             }
           return;
         }
+
+      if (strcmp (element_name, "enum") == 0)
+        {
+          const gchar *id;
+
+          if (COLLECT (STRING, "id", &id))
+            {
+              if (g_hash_table_lookup (state->enums, id))
+                g_set_error (error, G_MARKUP_ERROR,
+                             G_MARKUP_ERROR_INVALID_CONTENT,
+                             "<enum id='%s'> already specified", id);
+
+                g_hash_table_insert (state->enums, g_strdup (id),
+                                     state->enumdesc = g_string_new (NULL));
+            }
+
+          return;
+        }
     }
   else if (strcmp (container, "schema") == 0)
     {
       if (strcmp (element_name, "key") == 0)
         {
-          const gchar *name, *type;
+          const gchar *name, *type, *enumtype;
 
-          if (COLLECT (STRING, "name", &name, STRING, "type", &type))
+          if (COLLECT (STRING, "name", &name,
+                       OPTIONAL | STRING, "type", &type,
+                       OPTIONAL | STRING, "enum", &enumtype))
             {
+              GString *enumdata = NULL;
+
               if (!is_valid_keyname (name, error))
                 return;
 
+              if ((type == NULL) == (enumtype == NULL))
+                {
+                  g_set_error (error, G_MARKUP_ERROR,
+                               G_MARKUP_ERROR_MISSING_ATTRIBUTE,
+                               "exactly one of 'type' or 'enum' must "
+                               "be specified as an attribute to <key>");
+                  return;
+                }
+
+              if (enumtype)
+                {
+                  enumdata = g_hash_table_lookup (state->enums, enumtype);
+
+                  if (enumdata == NULL)
+                    {
+                      g_set_error (error, G_MARKUP_ERROR,
+                                   G_MARKUP_ERROR_INVALID_CONTENT,
+                                   "<enum id='%s'> not (yet) defined.", enumtype);
+                      return;
+                    }
+
+                  type = "s";
+                }
+
               if (!g_hash_table_lookup (state->schema, name))
                 {
                   state->key = gvdb_hash_table_insert (state->schema, name);
@@ -278,6 +362,16 @@ start_element (GMarkupParseContext  *context,
 
               g_variant_builder_init (&state->key_options,
                                       G_VARIANT_TYPE ("a{sv}"));
+
+              if (enumdata != NULL)
+                {
+                  GVariant *array;
+
+                  array = g_variant_new_byte_array (enumdata->str,
+                                                    enumdata->len);
+                  g_variant_builder_add (&state->key_options,
+                                         "{sv}", "enum", array);
+                }
             }
 
           return;
@@ -423,13 +517,14 @@ start_element (GMarkupParseContext  *context,
               gchar *type = g_variant_type_dup_string (state->type);
               g_set_error (error, G_MARKUP_ERROR,
                            G_MARKUP_ERROR_INVALID_CONTENT,
-                           "Element <%s> not allowed for keys of type \"%s\"\n",
+                           "Element <%s> not allowed for keys of type '%s'",
                            element_name, type);
               g_free (type);
               return;
             }
 
-          state->choices = g_string_new ("\xff");
+          state->choices = g_string_new (NULL);
+          g_string_append_c (state->choices, 0);
 
           NO_ATTRS ();
           return;
@@ -442,7 +537,62 @@ start_element (GMarkupParseContext  *context,
           const gchar *value;
 
           if (COLLECT (STRING, "value", &value))
-            g_string_append_printf (state->choices, "%s\xff", value);
+            g_string_append_len (state->choices, value, strlen (value) + 1);
+
+          return;
+        }
+    }
+  else if (strcmp (container, "enum") == 0)
+    {
+      if (strcmp (element_name, "value") == 0)
+        {
+          const gchar *nick, *valuestr;
+
+          if (COLLECT (STRING, "nick", &nick,
+                       STRING, "value", &valuestr))
+            {
+              gint64 big_value;
+              guint32 value;
+              gsize before;
+              gchar *end;
+
+              if (nick[0] == '\0' || nick[1] == '\0')
+                {
+                  g_set_error (error, G_MARKUP_ERROR,
+                               G_MARKUP_ERROR_INVALID_CONTENT,
+                               "enum nick must be a minimum of 2 characters");
+                  return;
+                }
+
+              big_value = g_ascii_strtoll (valuestr, &end, 0);
+              if (*end || big_value > G_MAXINT32 || big_value < G_MININT32)
+                {
+                  g_set_error (error, G_MARKUP_ERROR,
+                               G_MARKUP_ERROR_INVALID_CONTENT,
+                               "invalid numeric value");
+                  return;
+                }
+
+              value = big_value;
+              value = GUINT32_TO_LE (value);
+
+              g_string_append_len (state->enumdesc, (gpointer) &value, 4);
+
+              before = state->enumdesc->len;
+              g_string_append_c (state->enumdesc, 0xff);
+              g_string_append (state->enumdesc, nick);
+              g_string_append_c (state->enumdesc, 0);
+              while (~state->enumdesc->len & 3)
+                g_string_append_c (state->enumdesc, 0);
+              g_string_append_c (state->enumdesc, 0xff);
+
+              if (g_memmem (state->enumdesc->str, before,
+                            state->enumdesc->str + before,
+                            state->enumdesc->len - before))
+                g_set_error (error, G_MARKUP_ERROR,
+                             G_MARKUP_ERROR_INVALID_CONTENT,
+                             "<value nick='%s'> already specified", nick);
+            }
 
           return;
         }
@@ -527,7 +677,9 @@ end_element (GMarkupParseContext  *context,
         }
       else if (state->choices != NULL)
         {
-          if (!is_valid_choices (state->value, state->choices->str))
+          if (!is_valid_choices (state->value,
+                                 state->choices->str,
+                                 state->choices->len))
             {
               g_set_error_literal (error, G_MARKUP_ERROR,
                                    G_MARKUP_ERROR_INVALID_CONTENT,
@@ -554,12 +706,10 @@ end_element (GMarkupParseContext  *context,
 
   else if (strcmp (element_name, "choices") == 0)
     {
-      gchar *choices;
-
-      choices = g_string_free (state->choices, FALSE);
       g_variant_builder_add (&state->key_options, "{sv}", "choices",
-                             g_variant_new_byte_array (choices, -1));
-      g_free (choices);
+                             g_variant_new_byte_array (state->choices->str,
+                                                       state->choices->len));
+      g_string_free (state->choices, TRUE);
     }
 }
 
@@ -601,6 +751,7 @@ parse_gschema_files (gchar    **files,
   context = g_markup_parse_context_new (&parser,
                                         G_MARKUP_PREFIX_ERROR_POSITION,
                                         &state, NULL);
+  state.enums = gvdb_hash_table_new (NULL, NULL);
   state.schemas = gvdb_hash_table_new (NULL, NULL);
 
   while ((filename = *files++) != NULL)
diff --git a/gio/gsettings.c b/gio/gsettings.c
index 8f77c8f..d9716db 100644
--- a/gio/gsettings.c
+++ b/gio/gsettings.c
@@ -144,6 +144,28 @@
  *  </refsect2>
  */
 
+static gpointer
+g_memmem (gconstpointer haystack,
+          gsize         haystack_len,
+          gconstpointer needle,
+          gsize         needle_len)
+{
+#ifndef HAVE_MEMMEM
+  while (needle_len <= haystack_len)
+    {
+      if (memcmp (haystack, needle, needle_len) == 0)
+        return (gpointer) haystack;
+
+      haystack = ((gchar *) haystack) + 1;
+      haystack_len--;
+    }
+
+  return NULL;
+#else
+  return memmem (haystack, haystack_len, needle, needle_len);
+#endif
+}
+
 struct _GSettingsPrivate
 {
   GSettingsBackend *backend;
@@ -717,6 +739,180 @@ g_settings_class_init (GSettingsClass *class)
 
 }
 
+typedef struct
+{
+  GSettings *settings;
+  const gchar *key;
+
+  GSettingsSchema *schema;
+
+  const gchar *enumdata;
+  gsize enumsize;
+
+  const gchar *unparsed;
+  gchar lc_char;
+
+  const GVariantType *type;
+  GVariant *value;
+} GSettingsKeyInfo;
+
+static GVariant *
+g_settings_get_translated_default (GSettingsKeyInfo *info)
+{
+  const gchar *translated;
+  GError *error = NULL;
+  const gchar *domain;
+  gint lc_category;
+  GVariant *value;
+
+  if (info->lc_char == '\0')
+    return NULL;
+
+  domain = g_settings_schema_get_gettext_domain (info->schema);
+
+  if (info->lc_char == 't')
+    lc_category = LC_TIME;
+  else
+    lc_category = LC_MESSAGES;
+
+  translated = dcgettext (domain, info->unparsed, lc_category);
+
+  if (translated == info->unparsed)
+    return NULL;
+
+  value = g_variant_parse (info->type, translated, NULL, NULL, &error);
+
+  if (value == NULL)
+    {
+      g_warning ("Failed to parse translated string `%s' for "
+                 "key `%s' in schema `%s': %s", info->unparsed, info->key,
+                 info->settings->priv->schema_name, error->message);
+      g_warning ("Using untranslated default instead.");
+      g_error_free (error);
+    }
+
+  return value;
+}
+
+static gboolean
+g_settings_to_enum (GSettingsKeyInfo *info,
+                    GVariant         *value,
+                    gint             *result)
+{
+  const gchar *str;
+  gsize length;
+
+  if (info->enumdata == NULL)
+    {
+      g_critical ("g_settings_get_enum() called on key '%s' which is not "
+                  "associated with an enumerated type", info->key);
+      *(gint *) result = 0;
+
+      return TRUE;
+    }
+
+  str = g_variant_get_string (value, &length);
+
+  if (2 < length && length <= 64)
+    {
+      guint32 *found_value;
+      gchar buffer[80];
+      gint pad;
+
+      pad = (2u - length) & 3;
+      buffer[0] = '\xff';
+      memcpy (buffer + 1, str, length + 1);
+      memset (buffer + length + 2, 0, pad);
+      buffer[length + pad + 2] = '\xff';
+      length += pad + 2;
+
+      found_value = g_memmem (info->enumdata, info->enumsize, buffer, length);
+
+      if (found_value)
+        {
+          *result = GUINT32_FROM_LE (found_value[-1]);
+          return TRUE;
+        }
+    }
+
+  return FALSE;
+}
+
+static GVariant *
+g_settings_from_enum (GSettingsKeyInfo *info,
+                      gint              value)
+{
+  guint32 pattern[] = { -1u, value, -1u };
+  const gchar *found_nick;
+
+  pattern[1] = GUINT32_TO_LE (pattern[1]);
+  found_nick = g_memmem (info->enumdata, info->enumsize,
+                         ((gchar *) pattern) + 3, 6);
+
+  if (found_nick)
+    return g_variant_new_string (found_nick + 6);
+
+  return NULL;
+}
+
+static GSettingsKeyInfo
+g_settings_find_key (GSettings   *settings,
+                     const gchar *key)
+{
+  GSettingsKeyInfo info = { settings, key, settings->priv->schema };
+  GSettingsSchema *schema;
+  GVariant *array;
+
+  schema = settings->priv->schema;
+  info.value = g_settings_schema_get_value (schema, key, &array);
+
+  if G_UNLIKELY (info.value == NULL)
+    g_error ("schema '%s' does not contain a key named '%s'",
+             settings->priv->schema_name, key);
+
+  info.type = g_variant_get_type (info.value);
+
+  if (array != NULL)
+    {
+      GVariant *option_value;
+      const gchar *option;
+      GVariantIter iter;
+
+      g_variant_iter_init (&iter, array);
+      while (g_variant_iter_loop (&iter, "{&sv}", &option, &option_value))
+        {
+          if (strcmp (option, "l10n") == 0)
+            g_variant_get (option_value, "(y&s)",
+                           &info.lc_char, &info.unparsed);
+
+          else if (strcmp (option, "enum") == 0)
+            info.enumdata = g_variant_get_byte_array (option_value,
+                                                      &info.enumsize);
+
+          else
+            g_warning ("unknown schema extension '%s'", option);
+        }
+
+      g_variant_unref (array);
+    }
+
+  return info;
+}
+
+static GVariant *
+g_settings_get_from_backend (GSettingsKeyInfo *info)
+{
+  GVariant *value;
+  gchar *path;
+
+  path = g_strconcat (info->settings->priv->path, info->key, NULL);
+  value = g_settings_backend_read (info->settings->priv->backend,
+                                   path, info->type, FALSE);
+  g_free (path);
+
+  return value;
+}
+
 /**
  * g_settings_get_value:
  * @settings: a #GSettings object
@@ -734,91 +930,73 @@ GVariant *
 g_settings_get_value (GSettings   *settings,
                       const gchar *key)
 {
-  const gchar *unparsed = NULL;
-  GVariant *value, *options;
-  const GVariantType *type;
-  gchar lc_char = '\0';
-  GVariant *sval;
-  gchar *path;
+  GSettingsKeyInfo info;
+  GVariant *value;
 
   g_return_val_if_fail (G_IS_SETTINGS (settings), NULL);
+  g_return_val_if_fail (key != NULL, NULL);
 
-  sval = g_settings_schema_get_value (settings->priv->schema, key, &options);
+  info = g_settings_find_key (settings, key);
+  value = g_settings_get_from_backend (&info);
 
-  if G_UNLIKELY (sval == NULL)
-    g_error ("schema '%s' does not contain a key named '%s'",
-             settings->priv->schema_name, key);
+  if (value == NULL)
+    value = g_settings_get_translated_default (&info);
 
-  path = g_strconcat (settings->priv->path, key, NULL);
-  type = g_variant_get_type (sval);
-  value = g_settings_backend_read (settings->priv->backend, path, type, FALSE);
-  g_free (path);
+  if (value == NULL)
+    value = g_variant_ref (info.value);
 
-  if (options != NULL)
-    {
-      GVariantIter iter;
-      const gchar *option;
-      GVariant *option_value;
+  g_variant_unref (info.value);
 
-      g_variant_iter_init (&iter, options);
-      while (g_variant_iter_loop (&iter, "{&sv}", &option, &option_value))
-        {
-          if (strcmp (option, "l10n") == 0)
-            g_variant_get (option_value, "(y&s)", &lc_char, &unparsed);
-          else
-            g_warning ("unknown schema extension '%s'", option);
-        }
-    }
+  return value;
+}
+
+gint
+g_settings_get_enum (GSettings   *settings,
+                     const gchar *key)
+{
+  GSettingsKeyInfo info;
+  GVariant *value;
+  gint result;
+
+  g_return_val_if_fail (G_IS_SETTINGS (settings), -1);
+  g_return_val_if_fail (key != NULL, -1);
 
-  if (value && !g_variant_is_of_type (value, type))
+  info = g_settings_find_key (settings, key);
+  value = g_settings_get_from_backend (&info);
+
+  if (value != NULL && !g_settings_to_enum (&info, value, &result))
     {
       g_variant_unref (value);
       value = NULL;
     }
 
-  if (value == NULL && lc_char != '\0')
-  /* we will need to translate the schema default value */
+  if (value == NULL)
     {
-      const gchar *translated;
-      GError *error = NULL;
-      const gchar *domain;
-      gint lc_category;
+      value = g_settings_get_translated_default (&info);
 
-      domain = g_settings_schema_get_gettext_domain (settings->priv->schema);
-
-      if (lc_char == 't')
-        lc_category = LC_TIME;
-      else
-        lc_category = LC_MESSAGES;
-
-      translated = dcgettext (domain, unparsed, lc_category);
-
-      if (translated != unparsed)
-        /* it was translated, so we need to re-parse it */
+      if (value != NULL && !g_settings_to_enum (&info, value, &result))
         {
-          value = g_variant_parse (g_variant_get_type (sval),
-                                   translated, NULL, NULL, &error);
-
-          if (value == NULL)
-            {
-              g_warning ("Failed to parse translated string `%s' for "
-                         "key `%s' in schema `%s': %s", unparsed, key,
-                         settings->priv->schema_name, error->message);
-              g_warning ("Using untranslated default instead.");
-              g_error_free (error);
-            }
+          g_variant_unref (value);
+          value = NULL;
         }
     }
 
   if (value == NULL)
-    /* either translation failed or there was none to do.
-     * use the pre-compiled default.
-     */
-    value = g_variant_ref (sval);
+    g_settings_to_enum (&info, info.value, &result);
+  else
+    g_variant_unref (value);
 
-  g_variant_unref (sval);
+  g_variant_unref (info.value);
 
-  return value;
+  return result;
+}
+
+gboolean
+g_settings_set_enum (GSettings   *settings,
+                     const gchar *key,
+                     gint         value)
+{
+  return FALSE;
 }
 
 /**
diff --git a/gio/gsettings.h b/gio/gsettings.h
index 440ce03..3cb9a7a 100644
--- a/gio/gsettings.h
+++ b/gio/gsettings.h
@@ -119,6 +119,11 @@ gboolean                g_settings_set_strv                             (GSettin
                                                                          const gchar        *key,
                                                                          const gchar *const *value,
                                                                          gssize              length);
+gint                    g_settings_get_enum                             (GSettings          *settings,
+                                                                         const gchar        *key);
+gboolean                g_settings_set_enum                             (GSettings          *settings,
+                                                                         const gchar        *key,
+                                                                         gint                value);
 
 GSettings *             g_settings_get_child                            (GSettings          *settings,
                                                                          const gchar        *name);
diff --git a/gio/gsettingsbackend.c b/gio/gsettingsbackend.c
index b5699b4..f925177 100644
--- a/gio/gsettingsbackend.c
+++ b/gio/gsettingsbackend.c
@@ -509,7 +509,8 @@ g_settings_backend_changed_tree (GSettingsBackend *backend,
  * g_settings_backend_read:
  * @backend: a #GSettingsBackend implementation
  * @key: the key to read
- * @expected_type: a #GVariantType hint
+ * @expected_type: a #GVariantType
+ * @default_value: if the default value should be returned
  * @returns: the value that was read, or %NULL
  *
  * Reads a key. This call will never block.
@@ -517,11 +518,13 @@ g_settings_backend_changed_tree (GSettingsBackend *backend,
  * If the key exists, the value associated with it will be returned.
  * If the key does not exist, %NULL will be returned.
  *
- * If @expected_type is given, it serves as a type hint to the backend.
- * If you expect a key of a certain type then you should give
- * @expected_type to increase your chances of getting it.  Some backends
- * may ignore this argument and return values of a different type; it is
- * mostly used by backends that don't store strong type information.
+ * The returned value will be of the type given in @expected_type.  If
+ * the backend stored a value of a different type then %NULL will be
+ * returned.
+ *
+ * If @default_value is %TRUE then this gets the default value from the
+ * backend (ie: the one that the backend would contain if
+ * g_settings_reset() were called).
  */
 GVariant *
 g_settings_backend_read (GSettingsBackend   *backend,
@@ -529,8 +532,18 @@ g_settings_backend_read (GSettingsBackend   *backend,
                          const GVariantType *expected_type,
                          gboolean            default_value)
 {
-  return G_SETTINGS_BACKEND_GET_CLASS (backend)
+  GVariant *value;
+
+  value = G_SETTINGS_BACKEND_GET_CLASS (backend)
     ->read (backend, key, expected_type, default_value);
+
+  if G_UNLIKELY (value && !g_variant_is_of_type (value, expected_type))
+    {
+      g_variant_unref (value);
+      value = NULL;
+    }
+
+  return value;
 }
 
 /*< private >
diff --git a/gio/pltcheck.sh b/gio/pltcheck.sh
index a6cbe48..4c9b259 100755
--- a/gio/pltcheck.sh
+++ b/gio/pltcheck.sh
@@ -9,6 +9,7 @@ if ! which readelf 2>/dev/null >/dev/null; then
 	exit 0
 fi
 
+<<<<<<< HEAD
 SKIP='\<g_access\|\<g_array_\|\<g_ascii\|\<g_list_\|\<g_assertion_message\|\<g_warn_message\|\<g_atomic\|\<g_bit_\|\<g_boxed\|\<g_build_filename\|\<g_byte_array\|\<g_checksum\|\<g_child_watch\|\<g_clear_error\|\<g_convert\|\<g_dir_\|\<g_enum_\|\<g_error_\|\<g_prefix_error\|\<g_file_error_quark\|\<g_file_get_contents\|\<g_file_set_contents\|\<g_file_test\|\<g_file_read_link\|\<g_filename_\|\<g_find_program_in_path\|\<g_flags_\|\<g_free\|\<g_get_\|\<g_getenv\|\<g_setenv\|\<g_hash_table_\|\<g_hostname_\|\<g_iconv\|\<g_idle_\|\<g_intern_static_string\|\<g_io_add_watch\|\<g_io_channel_\|\<g_io_create_watch\|\<g_key_file_\|\<g_listenv\|\<g_locale_to_utf8\|\<g_log\|\<g_main_context_\|\<g_main_current_source\|\<g_main_loop_\|\<g_malloc\|\<g_markup_\|\<g_mkdir_\|\<g_mkstemp\|\<g_module_\|\<g_object_\|\<g_once_\|\<g_param_spec_\|\<g_path_\|\<g_poll\|\<g_printerr\|\<g_propagate_error\|\<g_ptr_array_\|\<g_qsort_\|\<g_quark_\|\<g_queue_\|\<g_random_int_range\|\<g_realloc\|\<g_return_if_f
 ail\|\<g_set_error\|\<g_shell_\|\<g_signal_\|\<g_slice_\|\<g_slist_\|\<g_snprintf\|\<g_source_\|\<g_spawn_\|\<g_static_\|\<g_str\|\<g_thread_pool_\|\<g_time_val_add\|\<g_timeout_\|\<g_type_\|\<g_unlink\|\<g_uri_\|\<g_utf8_\|\<g_value_\|\<g_tree_\|\<g_variant_\|\<g_mapped_file_\|\<g_intern_string\>\|\<g_compute_checksum\|\<g_memdup\|\<g_print\|\<g_random_int\|\<g_propagate_prefixed_e\|\<g_thread_create_full\|\<g_int_hash\|\<g_file_open_tmp\|\<g_thread_self\|\<g_usleep'
 
 for so in .libs/lib*.so; do
diff --git a/gio/tests/org.gtk.test.gschema.xml b/gio/tests/org.gtk.test.gschema.xml
index 9d1a821..48259f9 100644
--- a/gio/tests/org.gtk.test.gschema.xml
+++ b/gio/tests/org.gtk.test.gschema.xml
@@ -92,4 +92,18 @@
     </key>
   </schema>
 
+  <enum id='org.gtk.test.TestEnum'>
+    <value nick='invalid' value='0'/>
+    <value nick='foo' value='1'/>
+    <value nick='bar' value='2'/>
+    <value nick='baz' value='3'/>
+    <value nick='quux' value='4'/>
+  </enum>
+    
+  <schema id='org.gtk.test.enums' path='/tests/enums/'>
+    <key name='test' enum='org.gtk.test.TestEnum'>
+      <default>'bar'</default>
+    </key>
+  </schema>
+
 </schemalist>



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]