mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-08-02 15:33:39 +02:00
GSettings: New schema source from path, bytes and resource
This commit is contained in:
@@ -21,6 +21,7 @@
|
||||
#include "config.h"
|
||||
|
||||
#include "glib-private.h"
|
||||
#include "gresource.h"
|
||||
#include "gsettingsschema-internal.h"
|
||||
#include "gsettings.h"
|
||||
|
||||
@@ -156,6 +157,20 @@ struct _GSettingsSchema
|
||||
gint ref_count;
|
||||
};
|
||||
|
||||
/*
|
||||
* @G_SETTINGS_SCHEMA_SOURCE_FILE: The schema source was created from a path or directory
|
||||
* @G_SETTINGS_SCHEMA_SOURCE_RESOURCE: The schema source was created from a resource
|
||||
* @G_SETTINGS_SCHEMA_SOURCE_BYTES: The schema source was created from #GBytes
|
||||
*
|
||||
* Type of a #GSettingsSchemaSource. It indicates how the source was created.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
G_SETTINGS_SCHEMA_SOURCE_FILE,
|
||||
G_SETTINGS_SCHEMA_SOURCE_RESOURCE,
|
||||
G_SETTINGS_SCHEMA_SOURCE_BYTES
|
||||
} GSettingsSchemaSourceType;
|
||||
|
||||
/**
|
||||
* G_TYPE_SETTINGS_SCHEMA_SOURCE:
|
||||
*
|
||||
@@ -184,7 +199,18 @@ G_DEFINE_BOXED_TYPE (GSettingsSchema, g_settings_schema, g_settings_schema_ref,
|
||||
struct _GSettingsSchemaSource
|
||||
{
|
||||
GSettingsSchemaSource *parent;
|
||||
gchar *directory;
|
||||
|
||||
GSettingsSchemaSourceType type;
|
||||
union {
|
||||
struct {
|
||||
char *directory;
|
||||
} file;
|
||||
struct {
|
||||
char *path;
|
||||
GResourceLookupFlags lookup_flags;
|
||||
} resource;
|
||||
} type_data;
|
||||
|
||||
GvdbTable *table;
|
||||
GHashTable **text_tables;
|
||||
|
||||
@@ -230,7 +256,18 @@ g_settings_schema_source_unref (GSettingsSchemaSource *source)
|
||||
if (source->parent)
|
||||
g_settings_schema_source_unref (source->parent);
|
||||
gvdb_table_free (source->table);
|
||||
g_free (source->directory);
|
||||
|
||||
switch (source->type)
|
||||
{
|
||||
case G_SETTINGS_SCHEMA_SOURCE_FILE:
|
||||
g_free (source->type_data.file.directory);
|
||||
break;
|
||||
case G_SETTINGS_SCHEMA_SOURCE_RESOURCE:
|
||||
g_free(source->type_data.resource.path);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (source->text_tables)
|
||||
{
|
||||
@@ -282,6 +319,8 @@ g_settings_schema_source_unref (GSettingsSchemaSource *source)
|
||||
* @parent should probably be given as the default schema source, as
|
||||
* returned by g_settings_schema_source_get_default().
|
||||
*
|
||||
* Returns: (transfer full): a new #GSettingsSchemaSource, or %NULL
|
||||
*
|
||||
* Since: 2.32
|
||||
**/
|
||||
GSettingsSchemaSource *
|
||||
@@ -291,22 +330,158 @@ g_settings_schema_source_new_from_directory (const gchar *directory,
|
||||
GError **error)
|
||||
{
|
||||
GSettingsSchemaSource *source;
|
||||
GvdbTable *table;
|
||||
gchar *filename;
|
||||
|
||||
filename = g_build_filename (directory, "gschemas.compiled", NULL);
|
||||
table = gvdb_table_new (filename, trusted, error);
|
||||
source = g_settings_schema_source_new_from_path (filename, parent, trusted, error);
|
||||
g_free (filename);
|
||||
|
||||
return source;
|
||||
}
|
||||
|
||||
/**
|
||||
* g_settings_schema_source_new_from_path:
|
||||
* @path: (type filename): the filename of a compiled schema source
|
||||
* @parent: (nullable): a #GSettingsSchemaSource, or %NULL
|
||||
* @trusted: %TRUE, if the directory is trusted
|
||||
* @error: a pointer to a #GError pointer set to %NULL, or %NULL
|
||||
*
|
||||
* Almost identical to g_settings_schema_source_new_from_directory() but
|
||||
* takes a path to a compiled schema file directly instead of to the
|
||||
* directory it is in.
|
||||
*
|
||||
* Returns: (transfer full): a new #GSettingsSchemaSource, or %NULL
|
||||
*
|
||||
* Since: 2.78
|
||||
**/
|
||||
GSettingsSchemaSource *
|
||||
g_settings_schema_source_new_from_path (const gchar *path,
|
||||
GSettingsSchemaSource *parent,
|
||||
gboolean trusted,
|
||||
GError **error)
|
||||
{
|
||||
GSettingsSchemaSource *source;
|
||||
GvdbTable *table;
|
||||
|
||||
g_return_val_if_fail (path != NULL, NULL);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
|
||||
|
||||
table = gvdb_table_new (path, trusted, error);
|
||||
if (table == NULL)
|
||||
return NULL;
|
||||
|
||||
source = g_slice_new (GSettingsSchemaSource);
|
||||
source->directory = g_strdup (directory);
|
||||
source = g_slice_new0 (GSettingsSchemaSource);
|
||||
source->parent = parent ? g_settings_schema_source_ref (parent) : NULL;
|
||||
source->text_tables = NULL;
|
||||
source->table = table;
|
||||
source->ref_count = 1;
|
||||
source->type = G_SETTINGS_SCHEMA_SOURCE_FILE;
|
||||
source->type_data.file.directory = g_path_get_dirname (path);
|
||||
|
||||
return source;
|
||||
}
|
||||
|
||||
/**
|
||||
* g_settings_schema_source_new_from_bytes:
|
||||
* @bytes: a #GBytes
|
||||
* @parent: (nullable): a #GSettingsSchemaSource, or %NULL
|
||||
* @trusted: %TRUE, if the data is trusted
|
||||
* @error: a pointer to a #GError pointer set to %NULL, or %NULL
|
||||
*
|
||||
* Attempts to create a new schema source corresponding to the contents
|
||||
* of @bytes, which should contain the data as produced by the
|
||||
* [glib-compile-schemas][glib-compile-schemas] tool.
|
||||
*
|
||||
* This should only be used in standalone applications and should not
|
||||
* be used in situations where settings are shared with other applications.
|
||||
*
|
||||
* Note that g_settings_schema_key_get_summary() and
|
||||
* g_settings_schema_key_get_description() will always return %NULL for
|
||||
* a #GSettingsSchemaKey belonging to a #GSettingsSchema created from a
|
||||
* schema source returned by this function.
|
||||
*
|
||||
* See g_settings_schema_source_new_from_directory() for more information.
|
||||
*
|
||||
* Returns: (transfer full) (nullable): a new #GSettingsSchemaSource, or %NULL
|
||||
*
|
||||
* Since: 2.78
|
||||
**/
|
||||
GSettingsSchemaSource *
|
||||
g_settings_schema_source_new_from_bytes (GBytes *bytes,
|
||||
GSettingsSchemaSource *parent,
|
||||
gboolean trusted,
|
||||
GError **error)
|
||||
{
|
||||
GSettingsSchemaSource *source;
|
||||
GvdbTable *table;
|
||||
|
||||
g_return_val_if_fail (bytes != NULL, NULL);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
|
||||
|
||||
table = gvdb_table_new_from_bytes (bytes, trusted, error);
|
||||
if (table == NULL)
|
||||
return NULL;
|
||||
|
||||
source = g_slice_new0 (GSettingsSchemaSource);
|
||||
source->parent = parent ? g_settings_schema_source_ref (parent) : NULL;
|
||||
source->table = table;
|
||||
source->ref_count = 1;
|
||||
source->type = G_SETTINGS_SCHEMA_SOURCE_BYTES;
|
||||
|
||||
return source;
|
||||
}
|
||||
|
||||
/**
|
||||
* g_settings_schema_source_new_from_resource:
|
||||
* @path: the resource path
|
||||
* @lookup_flags: A #GResourceLookupFlags
|
||||
* @parent: (nullable): a #GSettingsSchemaSource, or %NULL
|
||||
* @trusted: %TRUE, if the resource is trusted
|
||||
* @error: a pointer to a #GError pointer set to %NULL, or %NULL
|
||||
*
|
||||
* Attempts to create a new schema source corresponding to the contents
|
||||
* of the given resource, which should contain the data as produced by the
|
||||
* [glib-compile-schemas][glib-compile-schemas] tool.
|
||||
*
|
||||
* This should only be used in standalone applications and should not
|
||||
* be used in situations where settings are shared with other applications.
|
||||
*
|
||||
* Note that for g_settings_schema_key_get_summary() and
|
||||
* g_settings_schema_key_get_description() to work, an XML schema resource
|
||||
* $path.xml must be present.
|
||||
*
|
||||
* See g_settings_schema_source_new_from_directory() for more information.
|
||||
*
|
||||
* Returns: (transfer full): a new #GSettingsSchemaSource, or %NULL
|
||||
*
|
||||
* Since: 2.78
|
||||
**/
|
||||
GSettingsSchemaSource *
|
||||
g_settings_schema_source_new_from_resource (const gchar *path,
|
||||
GResourceLookupFlags lookup_flags,
|
||||
GSettingsSchemaSource *parent,
|
||||
gboolean trusted,
|
||||
GError **error)
|
||||
{
|
||||
GSettingsSchemaSource *source;
|
||||
GBytes *bytes;
|
||||
|
||||
g_return_val_if_fail (path != NULL, NULL);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
|
||||
|
||||
bytes = g_resources_lookup_data (path, lookup_flags, error);
|
||||
if (bytes == NULL)
|
||||
return NULL;
|
||||
|
||||
source = g_settings_schema_source_new_from_bytes (bytes, parent, trusted, error);
|
||||
if (source == NULL) {
|
||||
g_bytes_unref (bytes);
|
||||
return NULL;
|
||||
}
|
||||
g_bytes_unref (bytes);
|
||||
|
||||
source->type = G_SETTINGS_SCHEMA_SOURCE_RESOURCE;
|
||||
source->type_data.resource.path = g_strdup (path);
|
||||
source->type_data.resource.lookup_flags = lookup_flags;
|
||||
|
||||
return source;
|
||||
}
|
||||
@@ -680,12 +855,35 @@ text (GMarkupParseContext *context,
|
||||
}
|
||||
|
||||
static void
|
||||
parse_into_text_tables (const gchar *directory,
|
||||
parse_into_text_tables (const char *data,
|
||||
gsize size,
|
||||
GHashTable *summaries,
|
||||
GHashTable *descriptions)
|
||||
{
|
||||
GMarkupParser parser = { start_element, end_element, text, NULL, NULL };
|
||||
TextTableParseInfo info = { summaries, descriptions, NULL, NULL, NULL, NULL };
|
||||
GMarkupParseContext *context;
|
||||
|
||||
context = g_markup_parse_context_new (&parser, G_MARKUP_TREAT_CDATA_AS_TEXT, &info, NULL);
|
||||
/* Ignore errors here, this is best effort only. */
|
||||
if (g_markup_parse_context_parse (context, data, size, NULL))
|
||||
(void) g_markup_parse_context_end_parse (context, NULL);
|
||||
g_markup_parse_context_free (context);
|
||||
|
||||
/* Clean up dangling stuff in case there was an error. */
|
||||
g_slist_free_full (info.gettext_domain, g_free);
|
||||
g_slist_free_full (info.schema_id, g_free);
|
||||
g_slist_free_full (info.key_name, g_free);
|
||||
|
||||
if (info.string)
|
||||
g_string_free (info.string, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
parse_into_text_tables_directory (const gchar *directory,
|
||||
GHashTable *summaries,
|
||||
GHashTable *descriptions)
|
||||
{
|
||||
const gchar *basename;
|
||||
GDir *dir;
|
||||
|
||||
@@ -699,29 +897,7 @@ parse_into_text_tables (const gchar *directory,
|
||||
filename = g_build_filename (directory, basename, NULL);
|
||||
if (g_file_get_contents (filename, &contents, &size, NULL))
|
||||
{
|
||||
GMarkupParseContext *context;
|
||||
|
||||
context = g_markup_parse_context_new (&parser, G_MARKUP_TREAT_CDATA_AS_TEXT, &info, NULL);
|
||||
/* Ignore errors here, this is best effort only. */
|
||||
if (g_markup_parse_context_parse (context, contents, size, NULL))
|
||||
(void) g_markup_parse_context_end_parse (context, NULL);
|
||||
g_markup_parse_context_free (context);
|
||||
|
||||
/* Clean up dangling stuff in case there was an error. */
|
||||
g_slist_free_full (info.gettext_domain, g_free);
|
||||
g_slist_free_full (info.schema_id, g_free);
|
||||
g_slist_free_full (info.key_name, g_free);
|
||||
|
||||
info.gettext_domain = NULL;
|
||||
info.schema_id = NULL;
|
||||
info.key_name = NULL;
|
||||
|
||||
if (info.string)
|
||||
{
|
||||
g_string_free (info.string, TRUE);
|
||||
info.string = NULL;
|
||||
}
|
||||
|
||||
parse_into_text_tables (contents, size, summaries, descriptions);
|
||||
g_free (contents);
|
||||
}
|
||||
|
||||
@@ -731,6 +907,68 @@ parse_into_text_tables (const gchar *directory,
|
||||
g_dir_close (dir);
|
||||
}
|
||||
|
||||
static void
|
||||
parse_into_text_tables_resource (const char *path,
|
||||
GResourceLookupFlags lookup_flags,
|
||||
GHashTable *summaries,
|
||||
GHashTable *descriptions)
|
||||
{
|
||||
char *xml_path;
|
||||
GError *error = NULL;
|
||||
GBytes *bytes;
|
||||
const char *data;
|
||||
gsize size, i;
|
||||
char **resources;
|
||||
|
||||
/* First try loading the XML schema data from @path + '.xml'. */
|
||||
xml_path = g_strdup_printf ("%s.xml", path);
|
||||
bytes = g_resources_lookup_data (xml_path, lookup_flags, &error);
|
||||
g_free (xml_path);
|
||||
if (bytes)
|
||||
{
|
||||
data = g_bytes_get_data (bytes, &size);
|
||||
parse_into_text_tables (data, size, summaries, descriptions);
|
||||
g_bytes_unref (bytes);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!g_error_matches (error, G_RESOURCE_ERROR, G_RESOURCE_ERROR_NOT_FOUND))
|
||||
{
|
||||
g_error_free (error);
|
||||
return;
|
||||
}
|
||||
g_error_free (error);
|
||||
|
||||
/* If there is no singular @path + '.xml' resource, try to load all
|
||||
* resources from under the @path + '.xml/' path.
|
||||
*/
|
||||
xml_path = g_strdup_printf ("%s.xml/", path);
|
||||
resources = g_resources_enumerate_children (xml_path, lookup_flags, NULL);
|
||||
if (!resources)
|
||||
{
|
||||
g_free (xml_path);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; resources[i] != NULL; i++)
|
||||
{
|
||||
char *child_path;
|
||||
|
||||
child_path = g_strconcat (xml_path, resources[i], NULL);
|
||||
bytes = g_resources_lookup_data (child_path, lookup_flags, NULL);
|
||||
g_free (child_path);
|
||||
if (!bytes)
|
||||
continue;
|
||||
|
||||
data = g_bytes_get_data (bytes, &size);
|
||||
parse_into_text_tables (data, size, summaries, descriptions);
|
||||
g_bytes_unref (bytes);
|
||||
}
|
||||
|
||||
g_free (xml_path);
|
||||
g_strfreev (resources);
|
||||
}
|
||||
|
||||
static GHashTable **
|
||||
g_settings_schema_source_get_text_tables (GSettingsSchemaSource *source)
|
||||
{
|
||||
@@ -742,8 +980,19 @@ g_settings_schema_source_get_text_tables (GSettingsSchemaSource *source)
|
||||
text_tables[0] = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_hash_table_unref);
|
||||
text_tables[1] = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_hash_table_unref);
|
||||
|
||||
if (source->directory)
|
||||
parse_into_text_tables (source->directory, text_tables[0], text_tables[1]);
|
||||
if (source->type == G_SETTINGS_SCHEMA_SOURCE_FILE)
|
||||
{
|
||||
parse_into_text_tables_directory (source->type_data.file.directory, text_tables[0], text_tables[1]);
|
||||
}
|
||||
else if (source->type == G_SETTINGS_SCHEMA_SOURCE_RESOURCE)
|
||||
{
|
||||
parse_into_text_tables_resource (source->type_data.resource.path, source->type_data.resource.lookup_flags,
|
||||
text_tables[0], text_tables[1]);
|
||||
}
|
||||
else if (source->type == G_SETTINGS_SCHEMA_SOURCE_BYTES)
|
||||
{
|
||||
/* Nothing to do in this case. */
|
||||
}
|
||||
|
||||
g_once_init_leave_pointer (&source->text_tables, text_tables);
|
||||
}
|
||||
@@ -1704,6 +1953,12 @@ g_settings_schema_key_get_name (GSettingsSchemaKey *key)
|
||||
* If no summary has been provided in the schema for @key, returns
|
||||
* %NULL.
|
||||
*
|
||||
* This function only works on keys belonging to a #GSettingsSchema
|
||||
* created from a #GSettingsSchemaSource created with
|
||||
* g_settings_schema_source_new_from_directory() or
|
||||
* g_settings_schema_source_new_from_path(), and requires the source
|
||||
* XML file to be present in the same directory as the compiled schema.
|
||||
*
|
||||
* The summary is a short description of the purpose of the key; usually
|
||||
* one short sentence. Summaries can be translated and the value
|
||||
* returned from this function is is the current locale.
|
||||
@@ -1738,6 +1993,12 @@ g_settings_schema_key_get_summary (GSettingsSchemaKey *key)
|
||||
* If no description has been provided in the schema for @key, returns
|
||||
* %NULL.
|
||||
*
|
||||
* This function only works on keys belonging to a #GSettingsSchema
|
||||
* created from a #GSettingsSchemaSource created with
|
||||
* g_settings_schema_source_new_from_directory() or
|
||||
* g_settings_schema_source_new_from_path(), and requires the source
|
||||
* XML file to be present in the same directory as the compiled schema.
|
||||
*
|
||||
* The description can be one sentence to several paragraphs in length.
|
||||
* Paragraphs are delimited with a double newline. Descriptions can be
|
||||
* translated and the value returned from this function is is the
|
||||
|
@@ -23,6 +23,7 @@
|
||||
|
||||
#include <glib-object.h>
|
||||
#include <gio/gio-visibility.h>
|
||||
#include <gio/gioenums.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
@@ -47,6 +48,25 @@ GSettingsSchemaSource * g_settings_schema_source_new_from_directory (const g
|
||||
gboolean trusted,
|
||||
GError **error);
|
||||
|
||||
GIO_AVAILABLE_IN_2_78
|
||||
GSettingsSchemaSource * g_settings_schema_source_new_from_path (const gchar *path,
|
||||
GSettingsSchemaSource *parent,
|
||||
gboolean trusted,
|
||||
GError **error);
|
||||
|
||||
GIO_AVAILABLE_IN_2_78
|
||||
GSettingsSchemaSource * g_settings_schema_source_new_from_bytes (GBytes *bytes,
|
||||
GSettingsSchemaSource *parent,
|
||||
gboolean trusted,
|
||||
GError **error);
|
||||
|
||||
GIO_AVAILABLE_IN_2_78
|
||||
GSettingsSchemaSource * g_settings_schema_source_new_from_resource (const gchar *path,
|
||||
GResourceLookupFlags lookup_flags,
|
||||
GSettingsSchemaSource *parent,
|
||||
gboolean trusted,
|
||||
GError **error);
|
||||
|
||||
GIO_AVAILABLE_IN_2_32
|
||||
GSettingsSchema * g_settings_schema_source_lookup (GSettingsSchemaSource *source,
|
||||
const gchar *schema_id,
|
||||
|
@@ -2811,7 +2811,7 @@ G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
}
|
||||
|
||||
static void
|
||||
test_schema_source (void)
|
||||
test_schema_source_directory (void)
|
||||
{
|
||||
GSettingsSchemaSource *parent;
|
||||
GSettingsSchemaSource *source;
|
||||
@@ -2910,6 +2910,325 @@ test_schema_source (void)
|
||||
g_object_unref (backend);
|
||||
}
|
||||
|
||||
static void
|
||||
test_schema_source_path (void)
|
||||
{
|
||||
GSettingsSchemaSource *parent;
|
||||
GSettingsSchemaSource *source;
|
||||
GSettingsBackend *backend;
|
||||
GSettingsSchema *schema;
|
||||
GError *error = NULL;
|
||||
GSettings *settings, *child;
|
||||
gboolean enabled;
|
||||
|
||||
backend = g_settings_backend_get_default ();
|
||||
|
||||
/* make sure it fails properly */
|
||||
parent = g_settings_schema_source_get_default ();
|
||||
source = g_settings_schema_source_new_from_path ("/path/that/does/not/exist/gschemas.compiled", parent, TRUE, &error);
|
||||
g_assert_null (source);
|
||||
g_assert_error (error, G_FILE_ERROR, G_FILE_ERROR_NOENT);
|
||||
g_clear_error (&error);
|
||||
|
||||
/* Test error handling of corrupt compiled files. */
|
||||
source = g_settings_schema_source_new_from_path ("schema-source-corrupt/gschemas.compiled", parent, TRUE, &error);
|
||||
g_assert_error (error, G_FILE_ERROR, G_FILE_ERROR_INVAL);
|
||||
g_assert_null (source);
|
||||
g_clear_error (&error);
|
||||
|
||||
/* Test error handling of empty compiled files. */
|
||||
source = g_settings_schema_source_new_from_path ("schema-source-empty/gschemas.compiled", parent, TRUE, &error);
|
||||
g_assert_error (error, G_FILE_ERROR, G_FILE_ERROR_INVAL);
|
||||
g_assert_null (source);
|
||||
g_clear_error (&error);
|
||||
|
||||
/* create a source with the parent */
|
||||
source = g_settings_schema_source_new_from_path ("schema-source/gschemas.compiled", parent, TRUE, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_nonnull (source);
|
||||
|
||||
/* check recursive lookups are working */
|
||||
schema = g_settings_schema_source_lookup (source, "org.gtk.test", TRUE);
|
||||
g_assert_nonnull (schema);
|
||||
g_settings_schema_unref (schema);
|
||||
|
||||
/* check recursive lookups for non-existent schemas */
|
||||
schema = g_settings_schema_source_lookup (source, "org.gtk.doesnotexist", TRUE);
|
||||
g_assert_null (schema);
|
||||
|
||||
/* check non-recursive for schema that only exists in lower layers */
|
||||
schema = g_settings_schema_source_lookup (source, "org.gtk.test", FALSE);
|
||||
g_assert_null (schema);
|
||||
|
||||
/* check non-recursive lookup for non-existent */
|
||||
schema = g_settings_schema_source_lookup (source, "org.gtk.doesnotexist", FALSE);
|
||||
g_assert_null (schema);
|
||||
|
||||
/* check non-recursive for schema that exists in toplevel */
|
||||
schema = g_settings_schema_source_lookup (source, "org.gtk.schemasourcecheck", FALSE);
|
||||
g_assert_nonnull (schema);
|
||||
g_settings_schema_unref (schema);
|
||||
|
||||
/* check recursive for schema that exists in toplevel */
|
||||
schema = g_settings_schema_source_lookup (source, "org.gtk.schemasourcecheck", TRUE);
|
||||
g_assert_nonnull (schema);
|
||||
|
||||
/* try to use it for something */
|
||||
settings = g_settings_new_full (schema, backend, "/test/");
|
||||
g_settings_schema_unref (schema);
|
||||
enabled = FALSE;
|
||||
g_settings_get (settings, "enabled", "b", &enabled);
|
||||
g_assert_true (enabled);
|
||||
|
||||
/* Check that child schemas are resolved from the correct schema source, see glib#1884 */
|
||||
child = g_settings_get_child (settings, "child");
|
||||
g_settings_get (settings, "enabled", "b", &enabled);
|
||||
|
||||
g_object_unref (child);
|
||||
g_object_unref (settings);
|
||||
g_settings_schema_source_unref (source);
|
||||
|
||||
/* try again, but with no parent */
|
||||
source = g_settings_schema_source_new_from_path ("schema-source/gschemas.compiled", NULL, FALSE, NULL);
|
||||
g_assert_nonnull (source);
|
||||
|
||||
/* should not find it this time, even if recursive... */
|
||||
schema = g_settings_schema_source_lookup (source, "org.gtk.test", FALSE);
|
||||
g_assert_null (schema);
|
||||
schema = g_settings_schema_source_lookup (source, "org.gtk.test", TRUE);
|
||||
g_assert_null (schema);
|
||||
|
||||
/* should still find our own... */
|
||||
schema = g_settings_schema_source_lookup (source, "org.gtk.schemasourcecheck", TRUE);
|
||||
g_assert_nonnull (schema);
|
||||
g_settings_schema_unref (schema);
|
||||
schema = g_settings_schema_source_lookup (source, "org.gtk.schemasourcecheck", FALSE);
|
||||
g_assert_nonnull (schema);
|
||||
g_settings_schema_unref (schema);
|
||||
|
||||
g_settings_schema_source_unref (source);
|
||||
g_object_unref (backend);
|
||||
}
|
||||
|
||||
static void
|
||||
test_schema_source_bytes (void)
|
||||
{
|
||||
GSettingsSchemaSource *parent;
|
||||
GSettingsSchemaSource *source;
|
||||
GSettingsBackend *backend;
|
||||
GSettingsSchema *schema;
|
||||
GError *error = NULL;
|
||||
GSettings *settings, *child;
|
||||
gboolean enabled;
|
||||
GFile *corrupt_schema_file, *empty_schema_file, *normal_schema_file;
|
||||
GBytes *corrupt_schema_bytes, *empty_schema_bytes, *normal_schema_bytes;
|
||||
|
||||
backend = g_settings_backend_get_default ();
|
||||
|
||||
parent = g_settings_schema_source_get_default ();
|
||||
|
||||
/* Read the schemas into bytes */
|
||||
corrupt_schema_file = g_file_new_for_path("schema-source-corrupt/gschemas.compiled");
|
||||
corrupt_schema_bytes = g_file_load_bytes(corrupt_schema_file, NULL, NULL, NULL);
|
||||
empty_schema_file = g_file_new_for_path("schema-source-empty/gschemas.compiled");
|
||||
empty_schema_bytes = g_file_load_bytes(empty_schema_file, NULL, NULL, NULL);
|
||||
normal_schema_file = g_file_new_for_path("schema-source/gschemas.compiled");
|
||||
normal_schema_bytes = g_file_load_bytes(normal_schema_file, NULL, NULL, NULL);
|
||||
|
||||
/* Test error handling of corrupt compiled files. */
|
||||
source = g_settings_schema_source_new_from_bytes (corrupt_schema_bytes, parent, TRUE, &error);
|
||||
g_assert_error (error, G_FILE_ERROR, G_FILE_ERROR_INVAL);
|
||||
g_assert_null (source);
|
||||
g_clear_error (&error);
|
||||
|
||||
/* Test error handling of empty compiled files. */
|
||||
source = g_settings_schema_source_new_from_bytes (empty_schema_bytes, parent, TRUE, &error);
|
||||
g_assert_error (error, G_FILE_ERROR, G_FILE_ERROR_INVAL);
|
||||
g_assert_null (source);
|
||||
g_clear_error (&error);
|
||||
|
||||
/* create a source with the parent */
|
||||
source = g_settings_schema_source_new_from_bytes (normal_schema_bytes, parent, TRUE, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_nonnull (source);
|
||||
|
||||
/* check recursive lookups are working */
|
||||
schema = g_settings_schema_source_lookup (source, "org.gtk.test", TRUE);
|
||||
g_assert_nonnull (schema);
|
||||
g_settings_schema_unref (schema);
|
||||
|
||||
/* check recursive lookups for non-existent schemas */
|
||||
schema = g_settings_schema_source_lookup (source, "org.gtk.doesnotexist", TRUE);
|
||||
g_assert_null (schema);
|
||||
|
||||
/* check non-recursive for schema that only exists in lower layers */
|
||||
schema = g_settings_schema_source_lookup (source, "org.gtk.test", FALSE);
|
||||
g_assert_null (schema);
|
||||
|
||||
/* check non-recursive lookup for non-existent */
|
||||
schema = g_settings_schema_source_lookup (source, "org.gtk.doesnotexist", FALSE);
|
||||
g_assert_null (schema);
|
||||
|
||||
/* check non-recursive for schema that exists in toplevel */
|
||||
schema = g_settings_schema_source_lookup (source, "org.gtk.schemasourcecheck", FALSE);
|
||||
g_assert_nonnull (schema);
|
||||
g_settings_schema_unref (schema);
|
||||
|
||||
/* check recursive for schema that exists in toplevel */
|
||||
schema = g_settings_schema_source_lookup (source, "org.gtk.schemasourcecheck", TRUE);
|
||||
g_assert_nonnull (schema);
|
||||
|
||||
/* try to use it for something */
|
||||
settings = g_settings_new_full (schema, backend, "/test/");
|
||||
g_settings_schema_unref (schema);
|
||||
enabled = FALSE;
|
||||
g_settings_get (settings, "enabled", "b", &enabled);
|
||||
g_assert_true (enabled);
|
||||
|
||||
/* Check that child schemas are resolved from the correct schema source, see glib#1884 */
|
||||
child = g_settings_get_child (settings, "child");
|
||||
g_settings_get (settings, "enabled", "b", &enabled);
|
||||
|
||||
g_object_unref (child);
|
||||
g_object_unref (settings);
|
||||
g_settings_schema_source_unref (source);
|
||||
g_bytes_unref(empty_schema_bytes);
|
||||
g_object_unref(empty_schema_file);
|
||||
g_bytes_unref(corrupt_schema_bytes);
|
||||
g_object_unref(corrupt_schema_file);
|
||||
|
||||
/* try again, but with no parent */
|
||||
source = g_settings_schema_source_new_from_bytes (normal_schema_bytes, NULL, FALSE, NULL);
|
||||
g_assert_nonnull (source);
|
||||
|
||||
/* should not find it this time, even if recursive... */
|
||||
schema = g_settings_schema_source_lookup (source, "org.gtk.test", FALSE);
|
||||
g_assert_null (schema);
|
||||
schema = g_settings_schema_source_lookup (source, "org.gtk.test", TRUE);
|
||||
g_assert_null (schema);
|
||||
|
||||
/* should still find our own... */
|
||||
schema = g_settings_schema_source_lookup (source, "org.gtk.schemasourcecheck", TRUE);
|
||||
g_assert_nonnull (schema);
|
||||
g_settings_schema_unref (schema);
|
||||
schema = g_settings_schema_source_lookup (source, "org.gtk.schemasourcecheck", FALSE);
|
||||
g_assert_nonnull (schema);
|
||||
g_settings_schema_unref (schema);
|
||||
|
||||
g_settings_schema_source_unref (source);
|
||||
g_bytes_unref(normal_schema_bytes);
|
||||
g_object_unref(normal_schema_file);
|
||||
|
||||
g_object_unref (backend);
|
||||
}
|
||||
|
||||
static void
|
||||
test_schema_source_resource (void)
|
||||
{
|
||||
GSettingsSchemaSource *parent;
|
||||
GSettingsSchemaSource *source;
|
||||
GSettingsBackend *backend;
|
||||
GSettingsSchema *schema;
|
||||
GSettingsSchemaKey *key;
|
||||
GError *error = NULL;
|
||||
GSettings *settings, *child;
|
||||
gboolean enabled;
|
||||
|
||||
backend = g_settings_backend_get_default ();
|
||||
|
||||
parent = g_settings_schema_source_get_default ();
|
||||
|
||||
/* Test error handling of corrupt compiled files. */
|
||||
source = g_settings_schema_source_new_from_resource ("/schema-source-corrupt/gschemas.compiled", G_RESOURCE_LOOKUP_FLAGS_NONE, parent, TRUE, &error);
|
||||
g_assert_error (error, G_FILE_ERROR, G_FILE_ERROR_INVAL);
|
||||
g_assert_null (source);
|
||||
g_clear_error (&error);
|
||||
|
||||
/* Test error handling of empty compiled files. */
|
||||
source = g_settings_schema_source_new_from_resource ("/schema-source-empty/gschemas.compiled", G_RESOURCE_LOOKUP_FLAGS_NONE, parent, TRUE, &error);
|
||||
g_assert_error (error, G_FILE_ERROR, G_FILE_ERROR_INVAL);
|
||||
g_assert_null (source);
|
||||
g_clear_error (&error);
|
||||
|
||||
/* create a source with the parent */
|
||||
source = g_settings_schema_source_new_from_resource ("/schema-source/gschemas.compiled", G_RESOURCE_LOOKUP_FLAGS_NONE, parent, TRUE, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_nonnull (source);
|
||||
|
||||
/* check recursive lookups are working */
|
||||
schema = g_settings_schema_source_lookup (source, "org.gtk.test", TRUE);
|
||||
g_assert_nonnull (schema);
|
||||
g_settings_schema_unref (schema);
|
||||
|
||||
/* check recursive lookups for non-existent schemas */
|
||||
schema = g_settings_schema_source_lookup (source, "org.gtk.doesnotexist", TRUE);
|
||||
g_assert_null (schema);
|
||||
|
||||
/* check non-recursive for schema that only exists in lower layers */
|
||||
schema = g_settings_schema_source_lookup (source, "org.gtk.test", FALSE);
|
||||
g_assert_null (schema);
|
||||
|
||||
/* check non-recursive lookup for non-existent */
|
||||
schema = g_settings_schema_source_lookup (source, "org.gtk.doesnotexist", FALSE);
|
||||
g_assert_null (schema);
|
||||
|
||||
/* check non-recursive for schema that exists in toplevel */
|
||||
schema = g_settings_schema_source_lookup (source, "org.gtk.schemasourcecheck", FALSE);
|
||||
g_assert_nonnull (schema);
|
||||
g_settings_schema_unref (schema);
|
||||
|
||||
/* check recursive for schema that exists in toplevel */
|
||||
schema = g_settings_schema_source_lookup (source, "org.gtk.schemasourcecheck", TRUE);
|
||||
g_assert_nonnull (schema);
|
||||
|
||||
/* check summary and description lookup */
|
||||
key = g_settings_schema_get_key (schema, "enabled");
|
||||
g_assert_cmpstr (g_settings_schema_key_get_summary (key), ==, "Boolean setting test");
|
||||
g_assert_cmpstr (g_settings_schema_key_get_description (key), ==, "Setting to test boolean settings");
|
||||
g_settings_schema_key_unref (key);
|
||||
key = g_settings_schema_get_key (schema, "nosummary");
|
||||
g_assert_null (g_settings_schema_key_get_summary (key));
|
||||
g_assert_null (g_settings_schema_key_get_description (key));
|
||||
g_settings_schema_key_unref (key);
|
||||
|
||||
/* try to use it for something */
|
||||
settings = g_settings_new_full (schema, backend, "/test/");
|
||||
g_settings_schema_unref (schema);
|
||||
enabled = FALSE;
|
||||
g_settings_get (settings, "enabled", "b", &enabled);
|
||||
g_assert_true (enabled);
|
||||
|
||||
/* Check that child schemas are resolved from the correct schema source, see glib#1884 */
|
||||
child = g_settings_get_child (settings, "child");
|
||||
g_settings_get (settings, "enabled", "b", &enabled);
|
||||
|
||||
g_object_unref (child);
|
||||
g_object_unref (settings);
|
||||
g_settings_schema_source_unref (source);
|
||||
|
||||
/* try again, but with no parent */
|
||||
source = g_settings_schema_source_new_from_resource ("/schema-source/gschemas.compiled", G_RESOURCE_LOOKUP_FLAGS_NONE, NULL, TRUE, &error);
|
||||
g_assert_nonnull (source);
|
||||
|
||||
/* should not find it this time, even if recursive... */
|
||||
schema = g_settings_schema_source_lookup (source, "org.gtk.test", FALSE);
|
||||
g_assert_null (schema);
|
||||
schema = g_settings_schema_source_lookup (source, "org.gtk.test", TRUE);
|
||||
g_assert_null (schema);
|
||||
|
||||
/* should still find our own... */
|
||||
schema = g_settings_schema_source_lookup (source, "org.gtk.schemasourcecheck", TRUE);
|
||||
g_assert_nonnull (schema);
|
||||
g_settings_schema_unref (schema);
|
||||
schema = g_settings_schema_source_lookup (source, "org.gtk.schemasourcecheck", FALSE);
|
||||
g_assert_nonnull (schema);
|
||||
g_settings_schema_unref (schema);
|
||||
|
||||
g_settings_schema_source_unref (source);
|
||||
|
||||
g_object_unref (backend);
|
||||
}
|
||||
|
||||
static void
|
||||
test_schema_list_keys (void)
|
||||
{
|
||||
@@ -3269,6 +3588,7 @@ main (int argc, char *argv[])
|
||||
gchar *schema_text;
|
||||
gchar *override_text;
|
||||
gchar *enums;
|
||||
GResource *loaded_resource;
|
||||
gint result;
|
||||
const KeyfileTestData keyfile_test_data_explicit_path = { "/tests/", "root", "tests", "/" };
|
||||
const KeyfileTestData keyfile_test_data_empty_path = { "/", "root", "root", "/" };
|
||||
@@ -3296,6 +3616,7 @@ main (int argc, char *argv[])
|
||||
GError *local_error = NULL;
|
||||
char *subprocess_stdout = NULL;
|
||||
|
||||
gboolean rv;
|
||||
/* A GVDB header is 6 guint32s, and requires a magic number in the first
|
||||
* two guint32s. A set of zero bytes of a greater length is considered
|
||||
* corrupt. */
|
||||
@@ -3329,6 +3650,10 @@ main (int argc, char *argv[])
|
||||
g_assert_true (g_file_set_contents ("org.gtk.test.gschema.override", override_text, -1, NULL));
|
||||
g_free (override_text);
|
||||
|
||||
g_assert_true (g_file_get_contents (SRCDIR "/schema_from_resource_test.gresource.xml", &override_text, NULL, NULL));
|
||||
g_assert_true (g_file_set_contents ("schema_from_resource_test.gresource.xml", override_text, -1, NULL));
|
||||
g_free (override_text);
|
||||
|
||||
g_remove ("gschemas.compiled");
|
||||
/* #GLIB_COMPILE_SCHEMAS is defined in meson.build */
|
||||
g_assert_true (g_spawn_command_line_sync (GLIB_COMPILE_SCHEMAS " --targetdir=. "
|
||||
@@ -3342,6 +3667,7 @@ main (int argc, char *argv[])
|
||||
g_assert_cmpint (result, ==, 0);
|
||||
|
||||
g_remove ("schema-source/gschemas.compiled");
|
||||
g_remove ("schema-source/org.gtk.schemasourcecheck.gschema.xml");
|
||||
g_mkdir ("schema-source", 0777);
|
||||
g_assert_true (g_spawn_command_line_sync (GLIB_COMPILE_SCHEMAS " --targetdir=schema-source "
|
||||
"--schema-file=" SRCDIR "/org.gtk.schemasourcecheck.gschema.xml",
|
||||
@@ -3351,6 +3677,10 @@ main (int argc, char *argv[])
|
||||
g_clear_pointer (&subprocess_stdout, g_free);
|
||||
g_assert_cmpint (result, ==, 0);
|
||||
|
||||
g_assert_true (g_file_get_contents (SRCDIR "/org.gtk.schemasourcecheck.gschema.xml", &override_text, NULL, NULL));
|
||||
g_assert_true (g_file_set_contents ("schema-source/org.gtk.schemasourcecheck.gschema.xml", override_text, -1, NULL));
|
||||
g_free (override_text);
|
||||
|
||||
g_remove ("schema-source-corrupt/gschemas.compiled");
|
||||
g_mkdir ("schema-source-corrupt", 0777);
|
||||
g_file_set_contents ("schema-source-corrupt/gschemas.compiled",
|
||||
@@ -3365,6 +3695,23 @@ main (int argc, char *argv[])
|
||||
"", 0,
|
||||
&local_error);
|
||||
g_assert_no_error (local_error);
|
||||
|
||||
/* #GLIB_COMPILE_RESOURCES is defined in meson.build */
|
||||
rv = g_spawn_command_line_sync (GLIB_COMPILE_RESOURCES
|
||||
" schema_from_resource_test.gresource.xml "
|
||||
"--target=schema_from_resource_test.gresource",
|
||||
NULL, NULL, &result, &local_error);
|
||||
g_assert_no_error (local_error);
|
||||
g_assert_true (rv);
|
||||
rv = g_spawn_check_wait_status (result, &local_error);
|
||||
g_assert_no_error (local_error);
|
||||
g_assert_true (rv);
|
||||
g_remove ("schema_from_resource_test.gresource.xml");
|
||||
|
||||
loaded_resource = g_resource_load ("schema_from_resource_test.gresource", &local_error);
|
||||
g_remove ("schema_from_resource_test.gresource");
|
||||
g_assert_no_error (local_error);
|
||||
g_resources_register (loaded_resource);
|
||||
}
|
||||
|
||||
g_test_add_func ("/gsettings/basic", test_basic);
|
||||
@@ -3437,7 +3784,10 @@ main (int argc, char *argv[])
|
||||
g_test_add_func ("/gsettings/list-schemas", test_list_schemas);
|
||||
g_test_add_func ("/gsettings/mapped", test_get_mapped);
|
||||
g_test_add_func ("/gsettings/get-range", test_get_range);
|
||||
g_test_add_func ("/gsettings/schema-source", test_schema_source);
|
||||
g_test_add_func ("/gsettings/schema-source/directory", test_schema_source_directory);
|
||||
g_test_add_func ("/gsettings/schema-source/path", test_schema_source_path);
|
||||
g_test_add_func ("/gsettings/schema-source/bytes", test_schema_source_bytes);
|
||||
g_test_add_func ("/gsettings/schema-source/resource", test_schema_source_resource);
|
||||
g_test_add_func ("/gsettings/schema-list-keys", test_schema_list_keys);
|
||||
g_test_add_func ("/gsettings/actions", test_actions);
|
||||
g_test_add_func ("/gsettings/null-backend", test_null_backend);
|
||||
|
@@ -9,6 +9,7 @@ test_c_args = [
|
||||
'-DG_LOG_DOMAIN="GLib-GIO"',
|
||||
'-DGLIB_MKENUMS="@0@"'.format(glib_mkenums.full_path()),
|
||||
'-DGLIB_COMPILE_SCHEMAS="@0@"'.format(glib_compile_schemas.full_path()),
|
||||
'-DGLIB_COMPILE_RESOURCES="@0@"'.format(glib_compile_resources.full_path()),
|
||||
'-UG_DISABLE_ASSERT',
|
||||
]
|
||||
|
||||
@@ -631,7 +632,7 @@ if host_machine.system() != 'windows'
|
||||
'c_args' : ['-DSRCDIR="@0@"'.format(meson.current_source_dir()),
|
||||
'-DTEST_LOCALE_PATH="@0@"'.format(test_mo_dir)],
|
||||
'install' : false,
|
||||
'depends' : glib_compile_schemas,
|
||||
'depends' : [glib_compile_schemas, glib_compile_resources],
|
||||
# FIXME: https://gitlab.gnome.org/GNOME/glib/-/issues/3148
|
||||
'can_fail' : host_system == 'gnu',
|
||||
},
|
||||
|
@@ -2,6 +2,13 @@
|
||||
<schema id="org.gtk.schemasourcecheck">
|
||||
<key name="enabled" type="b">
|
||||
<default>true</default>
|
||||
<summary>Boolean setting test</summary>
|
||||
<description>
|
||||
Setting to test boolean settings
|
||||
</description>
|
||||
</key>
|
||||
<key name="nosummary" type="b">
|
||||
<default>true</default>
|
||||
</key>
|
||||
<child name="child" schema="org.gtk.schemasourcecheck" />
|
||||
</schema>
|
||||
|
14
gio/tests/schema_from_resource_test.gresource.xml
Normal file
14
gio/tests/schema_from_resource_test.gresource.xml
Normal file
@@ -0,0 +1,14 @@
|
||||
<gresources>
|
||||
<gresource>
|
||||
<file>schema-source-corrupt/gschemas.compiled</file>
|
||||
</gresource>
|
||||
<gresource>
|
||||
<file>schema-source-empty/gschemas.compiled</file>
|
||||
</gresource>
|
||||
<gresource>
|
||||
<file>schema-source/gschemas.compiled</file>
|
||||
</gresource>
|
||||
<gresource>
|
||||
<file alias="schema-source/gschemas.compiled.xml">schema-source/org.gtk.schemasourcecheck.gschema.xml</file>
|
||||
</gresource>
|
||||
</gresources>
|
Submodule subprojects/gvdb deleted from 2b42fc75f0
Reference in New Issue
Block a user