[glib] GSettings: new <schema> tags 'extends', 'list-of'
- From: Ryan Lortie <ryanl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib] GSettings: new <schema> tags 'extends', 'list-of'
- Date: Tue, 29 Jun 2010 19:58:48 +0000 (UTC)
commit 900a756e8fb70bcd6e725f0696d8094a7208f905
Author: Ryan Lortie <desrt desrt ca>
Date: Tue Jun 29 14:41:04 2010 -0400
GSettings: new <schema> tags 'extends', 'list-of'
Add support for extends='' and list-of='' tags to the <schema> element.
The attributes are parsed and some sanity-checking is done but currently
nothing happens as a result.
Add some tests.
gio/gschema-compile.c | 124 ++++++++++++++++++--
gio/tests/Makefile.am | 10 ++-
gio/tests/gschema-compile.c | 11 ++-
gio/tests/schema-tests/extend-missing.gschema.xml | 3 +
gio/tests/schema-tests/extend-nonlist.gschema.xml | 4 +
gio/tests/schema-tests/extend-self.gschema.xml | 3 +
.../extend-wrong-list-indirect.gschema.xml | 6 +
.../schema-tests/extend-wrong-list.gschema.xml | 5 +
gio/tests/schema-tests/extending.gschema.xml | 21 ++++
.../schema-tests/key-in-list-indirect.gschema.xml | 8 ++
gio/tests/schema-tests/key-in-list.gschema.xml | 6 +
gio/tests/schema-tests/list-of-missing.gschema.xml | 3 +
12 files changed, 192 insertions(+), 12 deletions(-)
---
diff --git a/gio/gschema-compile.c b/gio/gschema-compile.c
index 3ec2621..004a3b1 100644
--- a/gio/gschema-compile.c
+++ b/gio/gschema-compile.c
@@ -671,23 +671,34 @@ is_valid_keyname (const gchar *key,
}
/* Handling of <schema> {{{1 */
-typedef struct
+typedef struct _SchemaState SchemaState;
+struct _SchemaState
{
- gchar *path;
- gchar *gettext_domain;
+ SchemaState *extends;
+
+ gchar *path;
+ gchar *gettext_domain;
+ gchar *extends_name;
+ gchar *list_of;
- GHashTable *keys;
-} SchemaState;
+ GHashTable *keys;
+};
static SchemaState *
schema_state_new (const gchar *path,
- const gchar *gettext_domain)
+ 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);
@@ -740,6 +751,14 @@ schema_state_add_key (SchemaState *state,
GString *enum_data;
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;
@@ -809,13 +828,34 @@ typedef struct
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;
+
if (g_hash_table_lookup (state->schema_table, id))
{
g_set_error (error, G_MARKUP_ERROR,
@@ -824,6 +864,66 @@ parse_state_start_schema (ParseState *state,
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)
+ {
+ if (!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 (extends)
+ {
+ 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,
@@ -833,7 +933,8 @@ parse_state_start_schema (ParseState *state,
return;
}
- state->schema_state = schema_state_new (path, gettext_domain);
+ state->schema_state = schema_state_new (path, gettext_domain,
+ extends, extends_name, list_of);
g_hash_table_insert (state->schema_table, g_strdup (id),
state->schema_state);
}
@@ -900,11 +1001,14 @@ start_element (GMarkupParseContext *context,
{
if (strcmp (element_name, "schema") == 0)
{
- const gchar *id, *path, *gettext_domain;
+ const gchar *id, *path, *gettext_domain, *extends, *list_of;
if (COLLECT (STRING, "id", &id,
OPTIONAL | STRING, "path", &path,
- OPTIONAL | STRING, "gettext-domain", &gettext_domain))
- parse_state_start_schema (state, id, path, gettext_domain, error);
+ 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,
+ extends, list_of, error);
return;
}
diff --git a/gio/tests/Makefile.am b/gio/tests/Makefile.am
index 4cfbb6e..4ddf0d3 100644
--- a/gio/tests/Makefile.am
+++ b/gio/tests/Makefile.am
@@ -302,9 +302,18 @@ 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-missing.gschema.xml \
+ schema-tests/extend-nonlist.gschema.xml \
+ schema-tests/extend-self.gschema.xml \
+ schema-tests/extend-wrong-list-indirect.gschema.xml \
+ schema-tests/extend-wrong-list.gschema.xml \
+ schema-tests/extending.gschema.xml \
schema-tests/from-docs.gschema.xml \
schema-tests/incomplete-list.gschema.xml \
schema-tests/invalid-path.gschema.xml \
+ schema-tests/key-in-list-indirect.gschema.xml \
+ schema-tests/key-in-list.gschema.xml \
+ schema-tests/list-of-missing.gschema.xml \
schema-tests/missing-quotes.gschema.xml \
schema-tests/no-default.gschema.xml \
schema-tests/overflow.gschema.xml \
@@ -320,7 +329,6 @@ schema_tests = \
schema-tests/range.gschema.xml \
schema-tests/wrong-category.gschema.xml
-
EXTRA_DIST += \
socket-common.c \
org.gtk.test.gschema \
diff --git a/gio/tests/gschema-compile.c b/gio/tests/gschema-compile.c
index 48d0ffb..c3961d1 100644
--- a/gio/tests/gschema-compile.c
+++ b/gio/tests/gschema-compile.c
@@ -92,7 +92,16 @@ static const SchemaTest tests[] = {
{ "range-default-low", NULL, "*<default> is not contained in the specified range*" },
{ "range-default-high", NULL, "*<default> is not contained in the specified range*" },
{ "range-parse-error", NULL, "*invalid character in number*" },
- { "from-docs", NULL, NULL }
+ { "from-docs", NULL, NULL },
+ { "extending", NULL, NULL },
+ { "extend-missing", NULL, "*extends not yet existing schema*" },
+ { "extend-nonlist", NULL, "*which is not a list*" },
+ { "extend-self", NULL, "*not yet existing*" },
+ { "extend-wrong-list-indirect", NULL, "*'y' does not extend 'x'*" },
+ { "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*" }
};
int
diff --git a/gio/tests/schema-tests/extend-missing.gschema.xml b/gio/tests/schema-tests/extend-missing.gschema.xml
new file mode 100644
index 0000000..675803a
--- /dev/null
+++ b/gio/tests/schema-tests/extend-missing.gschema.xml
@@ -0,0 +1,3 @@
+<schemalist>
+ <schema id='a' extends='x'/>
+</schemalist>
diff --git a/gio/tests/schema-tests/extend-nonlist.gschema.xml b/gio/tests/schema-tests/extend-nonlist.gschema.xml
new file mode 100644
index 0000000..7008cee
--- /dev/null
+++ b/gio/tests/schema-tests/extend-nonlist.gschema.xml
@@ -0,0 +1,4 @@
+<schemalist>
+ <schema id='a'/> <schema id='x'/>
+ <schema id='b' list-of='x' extends='a'/>
+</schemalist>
diff --git a/gio/tests/schema-tests/extend-self.gschema.xml b/gio/tests/schema-tests/extend-self.gschema.xml
new file mode 100644
index 0000000..f5b0c3d
--- /dev/null
+++ b/gio/tests/schema-tests/extend-self.gschema.xml
@@ -0,0 +1,3 @@
+<schemalist>
+ <schema id='a' extends='a'/>
+</schemalist>
diff --git a/gio/tests/schema-tests/extend-wrong-list-indirect.gschema.xml b/gio/tests/schema-tests/extend-wrong-list-indirect.gschema.xml
new file mode 100644
index 0000000..a336db7
--- /dev/null
+++ b/gio/tests/schema-tests/extend-wrong-list-indirect.gschema.xml
@@ -0,0 +1,6 @@
+<schemalist>
+ <schema id='x'/> <schema id='y'/>
+ <schema id='lx' list-of='x'/>
+ <schema id='lx2' extends='lx'/>
+ <schema id='ly' extends='lx2' list-of='y'/>
+</schemalist>
diff --git a/gio/tests/schema-tests/extend-wrong-list.gschema.xml b/gio/tests/schema-tests/extend-wrong-list.gschema.xml
new file mode 100644
index 0000000..4232dc2
--- /dev/null
+++ b/gio/tests/schema-tests/extend-wrong-list.gschema.xml
@@ -0,0 +1,5 @@
+<schemalist>
+ <schema id='x'/> <schema id='y'/>
+ <schema id='lx' list-of='x'/>
+ <schema id='ly' extends='lx' list-of='y'/>
+</schemalist>
diff --git a/gio/tests/schema-tests/extending.gschema.xml b/gio/tests/schema-tests/extending.gschema.xml
new file mode 100644
index 0000000..98882c7
--- /dev/null
+++ b/gio/tests/schema-tests/extending.gschema.xml
@@ -0,0 +1,21 @@
+<schemalist>
+ <!-- c extends b extends a -->
+ <schema id='a'/>
+ <schema id='b' extends='a'/>
+ <schema id='c' extends='b'/>
+
+ <!-- lists of each -->
+ <schema id='la' list-of='a'/>
+ <schema id='lb' list-of='b'/>
+ <schema id='lc' list-of='c'/>
+
+ <!-- extend 'la', override the list-of to 'b' -->
+ <schema id='lb-la' list-of='b' extends='la'/>
+
+ <!-- extend 'la', override the list-of to 'c' -->
+ <schema id='lc-la' list-of='c' extends='la'/>
+ <!-- extend 'lb', override the list-of to 'c' -->
+ <schema id='lc-lb' list-of='c' extends='lb'/>
+ <!-- extend 'lb-la', override the list-of to 'c' -->
+ <schema id='lc-lb-la' list-of='c' extends='lb-la'/>
+</schemalist>
diff --git a/gio/tests/schema-tests/key-in-list-indirect.gschema.xml b/gio/tests/schema-tests/key-in-list-indirect.gschema.xml
new file mode 100644
index 0000000..6f0bea1
--- /dev/null
+++ b/gio/tests/schema-tests/key-in-list-indirect.gschema.xml
@@ -0,0 +1,8 @@
+<schemalist>
+ <schema id='y'/>
+ <schema id='x' list-of='y'/>
+
+ <schema id='z' extends='x'>
+ <key name='foo' type='s'/>
+ </schema>
+</schemalist>
diff --git a/gio/tests/schema-tests/key-in-list.gschema.xml b/gio/tests/schema-tests/key-in-list.gschema.xml
new file mode 100644
index 0000000..e2a967a
--- /dev/null
+++ b/gio/tests/schema-tests/key-in-list.gschema.xml
@@ -0,0 +1,6 @@
+<schemalist>
+ <schema id='y'/>
+ <schema id='x' list-of='y'>
+ <key name='foo' type='s'/>
+ </schema>
+</schemalist>
diff --git a/gio/tests/schema-tests/list-of-missing.gschema.xml b/gio/tests/schema-tests/list-of-missing.gschema.xml
new file mode 100644
index 0000000..f5ef476
--- /dev/null
+++ b/gio/tests/schema-tests/list-of-missing.gschema.xml
@@ -0,0 +1,3 @@
+<schemalist>
+ <schema id='a' list-of='x'/>
+</schemalist>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]