[glib] GSettings: add <override>, tests, modify output



commit 3628b0b4992e9d1c915c38f8844eab9ba7a7112f
Author: Ryan Lortie <desrt desrt ca>
Date:   Tue Jun 29 20:24:39 2010 -0400

    GSettings: add <override>, tests, modify output
    
    Add <override> tag, more tests, and actually output the results of these
    new tags to the gschemas.compiled file.

 gio/gschema-compile.c                              |  149 ++++++++++++++++++--
 gio/tests/Makefile.am                              |    8 +
 gio/tests/gschema-compile.c                        |   10 ++-
 .../extend-and-shadow-indirect.gschema.xml         |   17 +++
 .../schema-tests/extend-and-shadow.gschema.xml     |   17 +++
 .../schema-tests/override-missing.gschema.xml      |   11 ++
 .../schema-tests/override-range-error.gschema.xml  |   12 ++
 .../schema-tests/override-then-key.gschema.xml     |   15 ++
 gio/tests/schema-tests/override-twice.gschema.xml  |   12 ++
 .../schema-tests/override-type-error.gschema.xml   |   11 ++
 gio/tests/schema-tests/override.gschema.xml        |   34 +++++
 11 files changed, 284 insertions(+), 12 deletions(-)
---
diff --git a/gio/gschema-compile.c b/gio/gschema-compile.c
index 004a3b1..37ddf33 100644
--- a/gio/gschema-compile.c
+++ b/gio/gschema-compile.c
@@ -122,6 +122,7 @@ typedef struct
 
   gboolean      has_choices;
   gboolean      has_aliases;
+  gboolean      is_override;
 
   gboolean      checked;
   GVariant     *serialised;
@@ -147,6 +148,29 @@ key_state_new (const gchar *type_string,
 }
 
 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_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;
@@ -201,6 +225,10 @@ key_state_check_range (KeyState  *state,
 {
   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 ||
@@ -208,8 +236,8 @@ key_state_check_range (KeyState  *state,
             {
               g_set_error (error, G_MARKUP_ERROR,
                            G_MARKUP_ERROR_INVALID_CONTENT,
-                           "<default> is not contained in "
-                           "the specified range");
+                           "<%s> is not contained in "
+                           "the specified range", tag);
             }
         }
 
@@ -218,16 +246,16 @@ key_state_check_range (KeyState  *state,
           if (!is_valid_choices (state->default_value, state->strinfo))
             {
               if (state->is_enum)
-                g_set_error_literal (error, G_MARKUP_ERROR,
-                                     G_MARKUP_ERROR_INVALID_CONTENT,
-                                     "<default> is not a valid member of "
-                                     "the specified enumerated type");
+                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
-                g_set_error_literal (error, G_MARKUP_ERROR,
-                                     G_MARKUP_ERROR_INVALID_CONTENT,
-                                     "<default> contains string not in "
-                                     "<choices>");
+                g_set_error (error, G_MARKUP_ERROR,
+                             G_MARKUP_ERROR_INVALID_CONTENT,
+                             "<%s> contains string not in "
+                             "<choices>", tag);
             }
         }
     }
@@ -749,6 +777,7 @@ schema_state_add_key (SchemaState  *state,
                       GError      **error)
 {
   GString *enum_data;
+  SchemaState *node;
   KeyState *key;
 
   if (state->list_of)
@@ -770,6 +799,27 @@ schema_state_add_key (SchemaState  *state,
       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))
     {
       g_set_error (error, G_MARKUP_ERROR,
@@ -813,6 +863,61 @@ schema_state_add_key (SchemaState  *state,
   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
 {
@@ -1048,9 +1153,20 @@ start_element (GMarkupParseContext  *context,
                                     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)
     {
@@ -1195,6 +1311,9 @@ end_element (GMarkupParseContext  *context,
   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);
 
@@ -1308,6 +1427,14 @@ output_schema (gpointer key,
   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",
diff --git a/gio/tests/Makefile.am b/gio/tests/Makefile.am
index 4ddf0d3..d95c618 100644
--- a/gio/tests/Makefile.am
+++ b/gio/tests/Makefile.am
@@ -302,6 +302,8 @@ schema_tests = \
 	schema-tests/enum-with-repeated-alias.gschema.xml		\
 	schema-tests/enum-with-shadow-alias.gschema.xml			\
 	schema-tests/enum.gschema.xml					\
+	schema-tests/extend-and-shadow-indirect.gschema.xml		\
+	schema-tests/extend-and-shadow.gschema.xml			\
 	schema-tests/extend-missing.gschema.xml				\
 	schema-tests/extend-nonlist.gschema.xml				\
 	schema-tests/extend-self.gschema.xml				\
@@ -317,6 +319,12 @@ schema_tests = \
 	schema-tests/missing-quotes.gschema.xml				\
 	schema-tests/no-default.gschema.xml				\
 	schema-tests/overflow.gschema.xml				\
+	schema-tests/override-missing.gschema.xml			\
+	schema-tests/override-range-error.gschema.xml			\
+	schema-tests/override-then-key.gschema.xml			\
+	schema-tests/override-twice.gschema.xml				\
+	schema-tests/override-type-error.gschema.xml			\
+	schema-tests/override.gschema.xml				\
 	schema-tests/range-badtype.gschema.xml				\
 	schema-tests/range-default-high.gschema.xml			\
 	schema-tests/range-default-low.gschema.xml			\
diff --git a/gio/tests/gschema-compile.c b/gio/tests/gschema-compile.c
index c3961d1..983a1c8 100644
--- a/gio/tests/gschema-compile.c
+++ b/gio/tests/gschema-compile.c
@@ -101,7 +101,15 @@ static const SchemaTest tests[] = {
   { "extend-wrong-list",            NULL, "*'y' does not extend 'x'*"                           },
   { "key-in-list-indirect",         NULL, "*can not add keys to a list*"                        },
   { "key-in-list",                  NULL, "*can not add keys to a list*"                        },
-  { "list-of-missing",              NULL, "*is list of not yet existing schema*"                }
+  { "list-of-missing",              NULL, "*is list of not yet existing schema*"                },
+  { "extend-and-shadow",            NULL, "*shadows*use <override>*"                            },
+  { "extend-and-shadow-indirect",   NULL, "*shadows*use <override>*"                            },
+  { "override",                     NULL, NULL                                                  },
+  { "override-missing",             NULL, "*no <key name='bar'> to override*"                   },
+  { "override-range-error",         NULL, "*<override> is not contained in the specified range*"},
+  { "override-then-key",            NULL, "*shadows <key name='foo'> in <schema id='base'>*"    },
+  { "override-twice",               NULL, "*<override name='foo'> already specified*"           },
+  { "override-type-error",          NULL, "*invalid character in number*"                       }
 };
 
 int
diff --git a/gio/tests/schema-tests/extend-and-shadow-indirect.gschema.xml b/gio/tests/schema-tests/extend-and-shadow-indirect.gschema.xml
new file mode 100644
index 0000000..dc066dd
--- /dev/null
+++ b/gio/tests/schema-tests/extend-and-shadow-indirect.gschema.xml
@@ -0,0 +1,17 @@
+<schemalist>
+  <schema id='a'>
+    <key name='foo' type='s'>
+      <default>''</default>
+    </key>
+  </schema>
+
+  <schema id='b' extends='a'>
+    <key name='bar' type='s'>
+      <default>''</default>
+    </key>
+  </schema>
+
+  <schema id='c' extends='b'>
+    <key name='foo' type='s'/>
+  </schema>
+</schemalist>
diff --git a/gio/tests/schema-tests/extend-and-shadow.gschema.xml b/gio/tests/schema-tests/extend-and-shadow.gschema.xml
new file mode 100644
index 0000000..79935b4
--- /dev/null
+++ b/gio/tests/schema-tests/extend-and-shadow.gschema.xml
@@ -0,0 +1,17 @@
+<schemalist>
+  <schema id='a'>
+    <key name='foo' type='s'>
+      <default>''</default>
+    </key>
+  </schema>
+
+  <schema id='b' extends='a'>
+    <key name='bar' type='s'>
+      <default>''</default>
+    </key>
+  </schema>
+
+  <schema id='c' extends='a'>
+    <key name='foo' type='s'/>
+  </schema>
+</schemalist>
diff --git a/gio/tests/schema-tests/override-missing.gschema.xml b/gio/tests/schema-tests/override-missing.gschema.xml
new file mode 100644
index 0000000..9a3c781
--- /dev/null
+++ b/gio/tests/schema-tests/override-missing.gschema.xml
@@ -0,0 +1,11 @@
+<schemalist>
+  <schema id='base'>
+    <key name='foo' type='s'>
+      <default>'bar'</default>
+    </key>
+  </schema>
+
+  <schema id='sub' extends='base'>
+    <override name='bar'>'baz'</override>
+  </schema>
+</schemalist>
diff --git a/gio/tests/schema-tests/override-range-error.gschema.xml b/gio/tests/schema-tests/override-range-error.gschema.xml
new file mode 100644
index 0000000..4887ac3
--- /dev/null
+++ b/gio/tests/schema-tests/override-range-error.gschema.xml
@@ -0,0 +1,12 @@
+<schemalist>
+  <schema id='base'>
+    <key name='ranged' type='i'>
+      <range min='0' max='22'/>
+      <default>10</default>
+    </key>
+  </schema>
+
+  <schema id='sub' extends='base'>
+    <override name='ranged'>77</override>
+  </schema>
+</schemalist>
diff --git a/gio/tests/schema-tests/override-then-key.gschema.xml b/gio/tests/schema-tests/override-then-key.gschema.xml
new file mode 100644
index 0000000..85b70bd
--- /dev/null
+++ b/gio/tests/schema-tests/override-then-key.gschema.xml
@@ -0,0 +1,15 @@
+<schemalist>
+  <schema id='base'>
+    <key name='foo' type='s'>
+      <default>'bar'</default>
+    </key>
+  </schema>
+
+  <schema id='sub' extends='base'>
+    <override name='foo'>'baz'</override>
+  </schema>
+
+  <schema id='sub2' extends='sub'>
+    <key name='foo' type='s'/>
+  </schema>
+</schemalist>
diff --git a/gio/tests/schema-tests/override-twice.gschema.xml b/gio/tests/schema-tests/override-twice.gschema.xml
new file mode 100644
index 0000000..fe6bb64
--- /dev/null
+++ b/gio/tests/schema-tests/override-twice.gschema.xml
@@ -0,0 +1,12 @@
+<schemalist>
+  <schema id='base'>
+    <key name='foo' type='s'>
+      <default>'bar'</default>
+    </key>
+  </schema>
+
+  <schema id='sub' extends='base'>
+    <override name='foo'>'baz'</override>
+    <override name='foo'>'baz'</override>
+  </schema>
+</schemalist>
diff --git a/gio/tests/schema-tests/override-type-error.gschema.xml b/gio/tests/schema-tests/override-type-error.gschema.xml
new file mode 100644
index 0000000..a16ec02
--- /dev/null
+++ b/gio/tests/schema-tests/override-type-error.gschema.xml
@@ -0,0 +1,11 @@
+<schemalist>
+  <schema id='base'>
+    <key name='foo' type='i'>
+      <default>10</default>
+    </key>
+  </schema>
+
+  <schema id='sub' extends='base'>
+    <override name='foo'>37.5</override>
+  </schema>
+</schemalist>
diff --git a/gio/tests/schema-tests/override.gschema.xml b/gio/tests/schema-tests/override.gschema.xml
new file mode 100644
index 0000000..6309884
--- /dev/null
+++ b/gio/tests/schema-tests/override.gschema.xml
@@ -0,0 +1,34 @@
+<schemalist>
+  <schema id='base'>
+    <key name='foo' type='s'>
+      <default>'bar'</default>
+    </key>
+
+    <key name='ranged' type='i'>
+      <range min='0' max='22'/>
+      <default>10</default>
+    </key>
+
+    <key name='choice' type='s'>
+      <choices>
+        <choice value='a'/>
+        <choice value='aaa'/>
+        <choice value='aaaaa'/>
+      </choices>
+      <default>'aaaaa'</default>
+    </key>
+  </schema>
+
+  <schema id='sub' extends='base'>
+  </schema>
+
+  <schema id='sub2' extends='base'>
+    <override name='foo'>'baz'</override>
+    <override name='ranged'>0</override>
+    <override name='choice'>'aaa'</override>
+  </schema>
+
+  <schema id='sub3' extends='sub2'>
+    <override name='foo'>'foo'</override>
+  </schema>
+</schemalist>



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