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.
This commit is contained in:
Ryan Lortie 2010-06-29 20:24:39 -04:00
parent 900a756e8f
commit 3628b0b499
11 changed files with 284 additions and 12 deletions

View File

@ -122,6 +122,7 @@ typedef struct
gboolean has_choices;
gboolean has_aliases;
gboolean is_override;
gboolean checked;
GVariant *serialised;
@ -146,6 +147,29 @@ key_state_new (const gchar *type_string,
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_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)
{
@ -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,8 +1153,19 @@ 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",

View File

@ -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 \

View File

@ -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

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>