From de0464cf891c386b0166066ac797255cd973b6e2 Mon Sep 17 00:00:00 2001 From: Ryan Lortie Date: Thu, 24 Jun 2010 12:25:48 -0400 Subject: [PATCH] Tweak GSettings key/schema listing APIs --- docs/reference/gio/gio-sections.txt | 4 +- gio/gio.symbols | 2 +- gio/gsettings.c | 12 ++-- gio/gsettings.h | 4 +- gio/gsettingsschema.c | 89 ++++++++++++++++++++--------- 5 files changed, 75 insertions(+), 36 deletions(-) diff --git a/docs/reference/gio/gio-sections.txt b/docs/reference/gio/gio-sections.txt index 5c6228421..b1d86d19b 100644 --- a/docs/reference/gio/gio-sections.txt +++ b/docs/reference/gio/gio-sections.txt @@ -2135,7 +2135,6 @@ GSettingsBackendPrivate gsettings GSettings GSettings -g_settings_schema_exists g_settings_new g_settings_new_with_path g_settings_new_with_backend @@ -2149,6 +2148,9 @@ g_settings_apply g_settings_revert g_settings_get_has_unapplied g_settings_get_child + + +g_settings_list_schemas g_settings_list_keys diff --git a/gio/gio.symbols b/gio/gio.symbols index 6ac8b5900..e2bb8daa7 100644 --- a/gio/gio.symbols +++ b/gio/gio.symbols @@ -1442,7 +1442,7 @@ g_keyfile_settings_backend_new #if IN_HEADER(__G_SETTINGS_H__) #if IN_FILE(__G_SETTINGS_SCHEMA_C__) -g_settings_schema_exists +g_settings_list_schemas #endif #if IN_FILE(__G_SETTINGS_C__) diff --git a/gio/gsettings.c b/gio/gsettings.c index a9dabbdbb..157edd34a 100644 --- a/gio/gsettings.c +++ b/gio/gsettings.c @@ -1867,21 +1867,21 @@ g_settings_get_child (GSettings *settings, * (since you should already know what keys are in your schema). This * function is intended for introspection reasons. * - * You should free the return value with g_strfreev() when you are done - * with it. + * You should free the return value with g_free() when you are done with + * it. */ -gchar ** +const gchar ** g_settings_list_keys (GSettings *settings) { const GQuark *keys; - gchar **strv; + const gchar **strv; gint n_keys; gint i; keys = g_settings_schema_list (settings->priv->schema, &n_keys); - strv = g_new (gchar *, n_keys + 1); + strv = g_new (const gchar *, n_keys + 1); for (i = 0; i < n_keys; i++) - strv[i] = g_strdup (g_quark_to_string (keys[i])); + strv[i] = g_quark_to_string (keys[i]); strv[i] = NULL; return strv; diff --git a/gio/gsettings.h b/gio/gsettings.h index ee5aac68b..c3cbb488f 100644 --- a/gio/gsettings.h +++ b/gio/gsettings.h @@ -70,7 +70,7 @@ struct _GSettings GType g_settings_get_type (void); -gboolean g_settings_schema_exists (const gchar *schema_name); +const gchar * const * g_settings_list_schemas (void); GSettings * g_settings_new (const gchar *schema); GSettings * g_settings_new_with_path (const gchar *schema, const gchar *path); @@ -79,7 +79,7 @@ GSettings * g_settings_new_with_backend (const g GSettings * g_settings_new_with_backend_and_path (const gchar *schema, GSettingsBackend *backend, const gchar *path); -gchar ** g_settings_list_keys (GSettings *settings); +const gchar ** g_settings_list_keys (GSettings *settings); gboolean g_settings_set_value (GSettings *settings, const gchar *key, diff --git a/gio/gsettingsschema.c b/gio/gsettingsschema.c index 67d11644d..87506c0e6 100644 --- a/gio/gsettingsschema.c +++ b/gio/gsettingsschema.c @@ -53,7 +53,8 @@ initialise_schema_sources (void) gchar *filename; GvdbTable *table; - filename = g_build_filename (*dir, "glib-2.0", "schemas", "gschemas.compiled", NULL); + filename = g_build_filename (*dir, "glib-2.0", "schemas", + "gschemas.compiled", NULL); table = gvdb_table_new (filename, TRUE, NULL); if (table != NULL) @@ -82,6 +83,67 @@ initialise_schema_sources (void) } } +static void +add_item (gpointer key, + gpointer value, + gpointer user_data) +{ + gchar ***ptr = user_data; + + *(*ptr)++ = (gchar *) key; +} + +/** + * g_settings_list_schemas: + * Returns: a list of the schemas installed on the system + * + * Returns a list of GSettings schemas that are available. The list + * must not be modified or freed. + **/ +const gchar * const * +g_settings_list_schemas (void) +{ + static gsize schema_list; + + if (g_once_init_enter (&schema_list)) + { + GHashTable *builder; + GSList *source; + gchar **list; + gchar **ptr; + gint i; + + initialise_schema_sources (); + + builder = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); + + for (source = schema_sources; source; source = source->next) + { + list = gvdb_table_list (source->data, ""); + + if (list) + { + for (i = 0; list[i]; i++) + g_hash_table_insert (builder, list[i], NULL); + + /* not strfreev: we stole the strings into the hashtable */ + g_free (list); + } + } + + ptr = list = g_new (gchar *, g_hash_table_size (builder) + 1); + g_hash_table_foreach (builder, add_item, &ptr); + *ptr = NULL; + + g_hash_table_steal_all (builder); + g_hash_table_unref (builder); + + g_once_init_leave (&schema_list, (gsize) list); + } + + return (const gchar **) schema_list; +} + static void g_settings_schema_finalize (GObject *object) { @@ -237,28 +299,3 @@ g_settings_schema_list (GSettingsSchema *schema, *n_items = schema->priv->n_items; return schema->priv->items; } - -/** - * g_settings_schema_exists: - * @schema_name: the schema name to query for - * Returns: %TRUE if @schema_name exists - * - * Checks if the named schema is installed. - **/ -gboolean -g_settings_schema_exists (const gchar *schema_name) -{ - GSList *source; - - initialise_schema_sources (); - - for (source = schema_sources; source; source = source->next) - { - GvdbTable *file = source->data; - - if (gvdb_table_get_table (file, schema_name)) - return TRUE; - } - - return FALSE; -}