[glib/gsettings] full support for non-cached schema reading
- From: Ryan Lortie <ryanl src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [glib/gsettings] full support for non-cached schema reading
- Date: Mon, 5 Oct 2009 20:45:36 +0000 (UTC)
commit 97bb280adba6d1c7151b109189bcaca1b4082064
Author: Ryan Lortie <desrt desrt ca>
Date: Mon Oct 5 13:10:42 2009 -0400
full support for non-cached schema reading
gio/Makefile.am | 4 +-
gio/gsettings-update-schema-cache.c | 77 +++++++++++++++++++++++++++++++++--
gio/gsettingsschema.c | 66 +++++++++++++++++++++++++++--
3 files changed, 137 insertions(+), 10 deletions(-)
---
diff --git a/gio/Makefile.am b/gio/Makefile.am
index 5ec46b4..6bb2947 100644
--- a/gio/Makefile.am
+++ b/gio/Makefile.am
@@ -41,6 +41,8 @@ TESTS = abicheck.sh pltcheck.sh
endif
endif
+GSETTINGS_SCHEMA_COMPILER = $(libexecdir)/gsettings-update-schema-cache
+
AM_CPPFLAGS = \
-DG_LOG_DOMAIN=\"GLib-GIO\" \
-I$(top_builddir) \
@@ -51,7 +53,7 @@ AM_CPPFLAGS = \
-DG_DISABLE_DEPRECATED \
-DGIO_COMPILATION \
-DGIO_MODULE_DIR=\"$(GIO_MODULE_DIR)\" \
- -DGSETTINGS_SCHEMAS_DIR=\"$(datadir)/gsettings/schemas\"
+ -DGSETTINGS_SCHEMA_COMPILER=\"$(GSETTINGS_SCHEMA_COMPILER)\"
lib_LTLIBRARIES = libgio-2.0.la
diff --git a/gio/gsettings-update-schema-cache.c b/gio/gsettings-update-schema-cache.c
index 4c23fe8..c376cbd 100644
--- a/gio/gsettings-update-schema-cache.c
+++ b/gio/gsettings-update-schema-cache.c
@@ -889,14 +889,83 @@ compile_directory (const gchar *dirname)
write_cache (cache);
}
+static void
+single_schema_to_stdout (const gchar *schema_name,
+ const gchar *filename)
+{
+ TokenStream stream = { };
+ GError *error = NULL;
+ gconstpointer data;
+ GVariant *variant;
+ gchar *contents;
+ Schema *schema;
+ gsize length;
+ Cache *cache;
+ gsize i;
+
+ cache = cache_new ();
+
+ if (!g_file_get_contents (filename, &contents, &length, &error))
+ g_error ("%s: %s\n", filename, error->message);
+
+ stream.stream = contents;
+ stream.start = contents;
+ stream.end = contents + length;
+
+ if (!read_file (&stream, cache))
+ {
+ show_error_message (&stream, filename);
+ g_assert_not_reached ();
+ }
+
+ schema = g_hash_table_lookup (cache->schemas, schema_name);
+
+ if (schema == NULL)
+ g_error ("schema `%s' not found in `%s'", schema_name, filename);
+
+ variant = g_variant_ref_sink (serialise_schema (schema));
+ length = g_variant_get_size (variant);
+ data = g_variant_get_data (variant);
+
+ for (i = 0; i < length;)
+ {
+ gssize count = fwrite (data + i, 1, length - i, stdout);
+ if (count <= 0)
+ g_error ("error on write to stdout: %s\n", g_strerror (errno));
+ i += count;
+ }
+
+ g_variant_unref (variant);
+}
+
int
main (int argc, char **argv)
{
- if (argc == 1)
- g_warning ("nothing to do");
+ argv++;
+
+ if (g_strcmp0 (*argv, "--compile-one-schema") == 0)
+ {
+ const gchar *schema_name;
+ const gchar *filename;
- while (*++argv)
- compile_directory (*argv);
+ argv++;
+
+ if ((schema_name = *argv++) == NULL)
+ g_error ("missing argument to `--compile-one-schema'");
+
+ if ((filename = *argv++) == NULL || *argv != NULL)
+ g_error ("expected one filename to follow schema name");
+
+ single_schema_to_stdout (schema_name, filename);
+ }
+ else
+ {
+ if (!*argv)
+ g_warning ("nothing to do");
+
+ while (*argv)
+ compile_directory (*argv++);
+ }
return 0;
}
diff --git a/gio/gsettingsschema.c b/gio/gsettingsschema.c
index 5131fdd..03714a6 100644
--- a/gio/gsettingsschema.c
+++ b/gio/gsettingsschema.c
@@ -10,8 +10,11 @@
#include "gsettingsschema.h"
+#include <sys/wait.h>
#include <sys/stat.h>
+#include <unistd.h>
#include <string.h>
+#include <errno.h>
#include "gioalias.h"
@@ -110,10 +113,63 @@ g_settings_schema_initialise_directories (void)
}
static GVariant *
-g_settings_schema_compile (const gchar *filename)
+g_settings_schema_compile (const gchar *filename,
+ const gchar *schema_name)
{
- g_print ("compiling %s\n", filename);
- return NULL;
+ const gchar *argv[] = { GSETTINGS_SCHEMA_COMPILER,
+ "--compile-one-schema",
+ schema_name, filename, NULL };
+ GError *error = NULL;
+ gint out_fd, status;
+ gint data_size;
+ gint allocated;
+ gssize count;
+ gchar *data;
+ GPid pid;
+
+ /* can't use g_spawn_sync because it uses nul-terminated strings */
+ if (!g_spawn_async_with_pipes (/* working directory */ NULL,
+ (gchar **) argv,
+ /* environment */ NULL,
+ G_SPAWN_DO_NOT_REAP_CHILD,
+ /* child setup */ NULL,
+ /* child setup user_data */ NULL,
+ &pid,
+ /* stdin pipe */ NULL,
+ &out_fd,
+ /* stderr pipe */ NULL,
+ &error))
+ g_error ("%s", error->message);
+
+ count = allocated = data_size = 0;
+ data = NULL;
+
+ /* read the stdout until EOF */
+ do
+ if ((data_size += count) + 1024 > allocated)
+ data = g_realloc (data, allocated = (data_size + 1024) * 2);
+ while ((count = read (out_fd, data + data_size, 1024)) > 0);
+
+ data = g_realloc (data, data_size);
+ close (out_fd);
+
+ if (count < 0)
+ g_error ("GSettings: reading from schema compiler: %s\n",
+ g_strerror (errno));
+
+ while ((pid = waitpid (pid, &status, 0)) < 0 && errno == EINTR);
+
+ if (pid < 0)
+ g_error ("GSettings: waitpid() on schema compiler: %s\n",
+ g_strerror (errno));
+
+ g_spawn_close_pid (pid);
+
+ if (status != 0)
+ g_error ("GSettings schema compiler: exit code %d\n", status);
+
+ return g_variant_from_data (G_VARIANT_TYPE ("(asmsa{s(sv)}a{ss})"),
+ data, data_size, 0, g_free, data);
}
static GVariant *
@@ -127,7 +183,7 @@ g_settings_schema_scan_dir (const gchar *directory,
gint end;
directory_length = strlen (directory);
- name_length = strlen (schema_name);
+ name_length = strcspn (schema_name, "/");
path = g_malloc (directory_length + 1 + name_length + 1 + 7 + 1);
/* directory / schema_name . schemas \0 */
@@ -146,7 +202,7 @@ g_settings_schema_scan_dir (const gchar *directory,
if (path[end] != '.')
break;
- value = g_settings_schema_compile (path);
+ value = g_settings_schema_compile (path, schema_name);
}
g_free (path);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]