[glib/new-gsettings] lots of schemas changes
- From: Ryan Lortie <ryanl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib/new-gsettings] lots of schemas changes
- Date: Thu, 15 Apr 2010 17:30:00 +0000 (UTC)
commit a07b0fc2edb7c324cac4433eadb3ac37a29dec6f
Author: Ryan Lortie <desrt desrt ca>
Date: Thu Apr 15 13:10:45 2010 -0400
lots of schemas changes
docs/reference/gio/Makefile.am | 4 +-
gio/gschema-compile.c | 97 +++++++++++++++++++++++++++++++---------
gio/gsettings.c | 71 ++++++++++++++++++-----------
gio/gsettingsschema.c | 55 +++++++++++-----------
gio/gvdb/gvdb-builder.c | 40 +++++++++++++++-
gio/gvdb/gvdb-builder.h | 3 +
gio/gvdb/gvdb-format.h | 26 +++++++++++
gio/gvdb/gvdb-reader.c | 2 +
gio/gvdb/gvdb-reader.h | 2 +
9 files changed, 217 insertions(+), 83 deletions(-)
---
diff --git a/docs/reference/gio/Makefile.am b/docs/reference/gio/Makefile.am
index fcc7890..9ea1904 100644
--- a/docs/reference/gio/Makefile.am
+++ b/docs/reference/gio/Makefile.am
@@ -126,11 +126,11 @@ include $(top_srcdir)/gtk-doc.make
EXTRA_DIST += \
version.xml.in
+if ENABLE_MAN
+
man_MANS = \
gschema-compile.1
-if ENABLE_MAN
-
%.1 : xml/%.xml
@XSLTPROC@ -nonet http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl $<
diff --git a/gio/gschema-compile.c b/gio/gschema-compile.c
index 105bf86..2a7f283 100644
--- a/gio/gschema-compile.c
+++ b/gio/gschema-compile.c
@@ -7,6 +7,9 @@
typedef struct
{
+ gboolean byteswap;
+
+ GVariantBuilder key_options;
GHashTable *schemas;
gchar *schemalist_domain;
@@ -20,7 +23,8 @@ typedef struct
GVariant *value;
GVariant *min, *max;
GVariant *strings;
- gchar *l10n;
+ gchar l10n;
+ gchar *context;
GVariantType *type;
} ParseState;
@@ -112,6 +116,9 @@ start_element (GMarkupParseContext *context,
g_set_error (error, G_MARKUP_ERROR,
G_MARKUP_ERROR_INVALID_CONTENT,
"invalid GVariant type string");
+
+ g_variant_builder_init (&state->key_options,
+ G_VARIANT_TYPE ("a{sv}"));
}
return;
@@ -143,9 +150,12 @@ start_element (GMarkupParseContext *context,
{
if (strcmp (element_name, "default") == 0)
{
- if (COLLECT (STRDUP | OPTIONAL, "l10n", &state->l10n))
+ const gchar *l10n;
+
+ if (COLLECT (STRING | OPTIONAL, "l10n", &l10n,
+ STRDUP | OPTIONAL, "context", &state->context))
{
- if (state->l10n != NULL)
+ if (l10n != NULL)
{
if (!g_hash_table_lookup (state->schema, ".gettext-domain"))
{
@@ -166,22 +176,36 @@ start_element (GMarkupParseContext *context,
".gettext-domain",
domain);
- /* XXX: todo: check l10n category validity */
+ if (strcmp (l10n, "messages") == 0)
+ state->l10n = 'm';
+ else if (strcmp (l10n, "time") == 0)
+ state->l10n = 't';
+ else
+ g_set_error (error, G_MARKUP_ERROR,
+ G_MARKUP_ERROR_INVALID_CONTENT,
+ "unsupported l10n category: %s", l10n);
}
}
+ else
+ {
+ state->l10n = '\0';
+
+ if (state->context != NULL)
+ g_set_error (error, G_MARKUP_ERROR,
+ G_MARKUP_ERROR_INVALID_CONTENT,
+ "translation context given for "
+ " value without l10n enabled");
+ }
state->string = g_string_new (NULL);
}
return;
}
- else if (strcmp (element_name, "summary") == 0)
- {
- NO_ARGS ();
- return;
- }
- else if (strcmp (element_name, "description") == 0)
+ else if (strcmp (element_name, "summary") == 0 ||
+ strcmp (element_name, "description") == 0)
{
+ state->string = g_string_new (NULL);
NO_ARGS ();
return;
}
@@ -238,18 +262,46 @@ end_element (GMarkupParseContext *context,
if (strcmp (element_name, "default") == 0)
{
state->value = g_variant_parse (state->type, state->string->str,
- state->string->str + state->string->len,
- NULL, error);
+ NULL, NULL, error);
+
+ if (state->l10n)
+ {
+ if (state->context)
+ {
+ gint len;
+
+ /* Contextified messages are supported by prepending the
+ * context, followed by '\004' to the start of the message
+ * string. We do that here to save GSettings the work
+ * later on.
+ *
+ * Note: we are about to g_free() the context anyway...
+ */
+ len = strlen (state->context);
+ state->context[len] = '\004';
+ g_string_prepend_len (state->string, state->context, len + 1);
+ }
+
+ g_variant_builder_add (&state->key_options, "{sv}", "l10n",
+ g_variant_new ("(ys)",
+ state->l10n,
+ state->string->str));
+ }
+
+ g_string_free (state->string, TRUE);
+ g_free (state->context);
}
else if (strcmp (element_name, "key") == 0)
{
- if (state->l10n)
- gvdb_item_set_options (state->key,
- g_variant_new_parsed ("{'l10n': < %s >}",
- state->l10n));
gvdb_item_set_value (state->key, state->value);
+ gvdb_item_set_options (state->key,
+ g_variant_builder_end (&state->key_options));
}
+
+ else if (strcmp (element_name, "summary") == 0 ||
+ strcmp (element_name, "description") == 0)
+ g_string_free (state->string, TRUE);
}
static void
@@ -278,12 +330,13 @@ text (GMarkupParseContext *context,
}
static GHashTable *
-parse_gschema_files (gchar **files,
- GError **error)
+parse_gschema_files (gchar **files,
+ gboolean byteswap,
+ GError **error)
{
GMarkupParser parser = { start_element, end_element, text };
GMarkupParseContext *context;
- ParseState state = { 0, };
+ ParseState state = { byteswap, };
const gchar *filename;
context = g_markup_parse_context_new (&parser,
@@ -318,6 +371,7 @@ parse_gschema_files (gchar **files,
int
main (int argc, char **argv)
{
+ gboolean byteswap = G_BYTE_ORDER != G_LITTLE_ENDIAN;
GError *error = NULL;
GHashTable *table;
glob_t matched;
@@ -382,9 +436,8 @@ main (int argc, char **argv)
return 1;
}
- /* FIXME: need a way to specify the output location, for !srcdir builds */
- if (!(table = parse_gschema_files (matched.gl_pathv, &error)) ||
- !gvdb_table_write_contents (table, target, &error))
+ if (!(table = parse_gschema_files (matched.gl_pathv, byteswap, &error)) ||
+ !gvdb_table_write_contents (table, target, byteswap, &error))
{
fprintf (stderr, "%s\n", error->message);
return 1;
diff --git a/gio/gsettings.c b/gio/gsettings.c
index 1e16dd6..b69cd73 100644
--- a/gio/gsettings.c
+++ b/gio/gsettings.c
@@ -658,9 +658,10 @@ GVariant *
g_settings_get_value (GSettings *settings,
const gchar *key)
{
+ const gchar *unparsed = NULL;
GVariant *value, *options;
const GVariantType *type;
- gint lc_category = -1;
+ gchar lc_char = '\0';
GVariant *sval;
gchar *path;
@@ -670,6 +671,11 @@ g_settings_get_value (GSettings *settings,
g_error ("schema '%s' does not contain a key named '%s'\n",
settings->priv->schema_name, key);
+ path = g_strconcat (settings->priv->path, key, NULL);
+ type = g_variant_get_type (sval);
+ value = g_settings_backend_read (settings->priv->backend, path, type);
+ g_free (path);
+
if (options != NULL)
{
GVariantIter iter;
@@ -677,50 +683,59 @@ g_settings_get_value (GSettings *settings,
GVariant *value;
g_variant_iter_init (&iter, options);
- while (g_variant_iter_loop (&iter, "{sv}", &key, &value))
+ while (g_variant_iter_loop (&iter, "{&sv}", &key, &value))
{
- if (strcmp (key, "l10n") == 0 &&
- g_variant_is_of_type (value, G_VARIANT_TYPE_STRING))
- {
- const gchar *category = g_variant_get_string (value, NULL);
-
- if (strcmp (category, "messages") == 0)
- lc_category = LC_MESSAGES;
- else if (strcmp (category, "time") == 0)
- lc_category = LC_TIME;
- else
- g_error ("schema requests unsupported l10n category: %s",
- category);
- }
+ if (strcmp (key, "l10n") == 0 && value == NULL)
+ g_variant_get (value, "(y&s)", &lc_char, &unparsed);
+ else
+ g_warning ("unknown schema extension '%s'", key);
}
}
- path = g_strconcat (settings->priv->path, key, NULL);
- type = g_variant_get_type (sval);
- value = g_settings_backend_read (settings->priv->backend, path, type);
- g_free (path);
-
if (value && !g_variant_is_of_type (value, type))
{
g_variant_unref (value);
value = NULL;
}
- if (value == NULL)
+ if (value == NULL && lc_char != '\0')
+ /* we will need to translate the schema default value */
{
+ const gchar *translated;
+ GError *error = NULL;
+ const gchar *domain;
+ gint lc_category;
+ gchar category;
- if (lc_category != -1)
+ domain = g_settings_schema_get_gettext_domain (settings->priv->schema);
+ g_variant_get (value, "(y&s)", &category, &unparsed);
+
+ if (lc_char == 't')
+ lc_category = LC_TIME;
+ else
+ lc_category = LC_MESSAGES;
+
+ translated = dcgettext (domain, unparsed, lc_category);
+
+ if (translated != unparsed)
+ /* it was translated, so we need to re-parse it */
{
- const gchar *domain;
+ value = g_variant_parse (g_variant_get_type (sval),
+ translated, NULL, NULL, &error);
- domain = g_settings_schema_get_gettext_domain (settings->priv->schema);
+ if (value == NULL)
+ {
+ g_warning ("Failed to parse translated string `%s' for "
+ "key `%s' in schema `%s': %s", unparsed, key,
+ settings->priv->schema_name, error->message);
+ g_warning ("Using untranslated default instead.");
+ g_error_free (error);
- value = g_variant_ref_sink (g_variant_new_string (
- dcgettext (domain,
- g_variant_get_string (sval, NULL),
- lc_category)));
+ value = g_variant_ref (sval);
+ }
}
else
+ /* the string was untranslated, so just use the pre-parsed one */
value = g_variant_ref (sval);
}
diff --git a/gio/gsettingsschema.c b/gio/gsettingsschema.c
index f4103cc..910e1b5 100644
--- a/gio/gsettingsschema.c
+++ b/gio/gsettingsschema.c
@@ -30,6 +30,8 @@ G_DEFINE_TYPE (GSettingsSchema, g_settings_schema, G_TYPE_OBJECT)
struct _GSettingsSchemaPrivate
{
+ const gchar *gettext_domain;
+ const gchar *path;
GvdbTable *table;
gchar *name;
};
@@ -109,6 +111,22 @@ g_settings_schema_class_init (GSettingsSchemaClass *class)
g_type_class_add_private (class, sizeof (GSettingsSchemaPrivate));
}
+static const gchar *
+g_settings_schema_get_string (GSettingsSchema *schema,
+ const gchar *key)
+{
+ const gchar *result = NULL;
+ GVariant *value;
+
+ if ((value = g_settings_schema_get_value (schema, key, NULL)))
+ {
+ result = g_variant_get_string (value, NULL);
+ g_variant_unref (value);
+ }
+
+ return result;
+}
+
GSettingsSchema *
g_settings_schema_new (const gchar *name)
{
@@ -132,6 +150,13 @@ g_settings_schema_new (const gchar *name)
schema = g_object_new (G_TYPE_SETTINGS_SCHEMA, NULL);
schema->priv->name = g_strdup (name);
schema->priv->table = table;
+ schema->priv->path =
+ g_settings_schema_get_string (schema, ".path");
+ schema->priv->gettext_domain =
+ g_settings_schema_get_string (schema, ".gettext-domain");
+
+ if (schema->priv->gettext_domain)
+ bind_textdomain_codeset (schema->priv->gettext_domain, "UTF-8");
return schema;
}
@@ -147,39 +172,13 @@ g_settings_schema_get_value (GSettingsSchema *schema,
const gchar *
g_settings_schema_get_path (GSettingsSchema *schema)
{
- const gchar *result;
- GVariant *value;
-
- value = gvdb_table_get_value (schema->priv->table, ".path", NULL);
-
- if (value && g_variant_is_of_type (value, G_VARIANT_TYPE_STRING))
- {
- result = g_variant_get_string (value, NULL);
- g_variant_unref (value);
- }
- else
- result = NULL;
-
- return result;
+ return schema->priv->path;
}
const gchar *
g_settings_schema_get_gettext_domain (GSettingsSchema *schema)
{
- const gchar *result;
- GVariant *value;
-
- value = gvdb_table_get_value (schema->priv->table, ".gettext-domain", NULL);
-
- if (value && g_variant_is_of_type (value, G_VARIANT_TYPE_STRING))
- {
- result = g_variant_get_string (value, NULL);
- g_variant_unref (value);
- }
- else
- result = NULL;
-
- return result;
+ return schema->priv->gettext_domain;
}
gboolean
diff --git a/gio/gvdb/gvdb-builder.c b/gio/gvdb/gvdb-builder.c
index a59772b..290309c 100644
--- a/gio/gvdb/gvdb-builder.c
+++ b/gio/gvdb/gvdb-builder.c
@@ -1,3 +1,24 @@
+/*
+ * Copyright © 2010 Codethink Limited
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the licence, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Ryan Lortie <desrt desrt ca>
+ */
+
#include "gvdb-builder.h"
#include "gvdb-format.h"
@@ -444,10 +465,22 @@ file_builder_new (void)
static GString *
file_builder_serialise (FileBuilder *fb,
- struct gvdb_pointer root)
+ struct gvdb_pointer root,
+ gboolean byteswap)
{
- struct gvdb_header header = { { GVDB_SIGNATURE0, GVDB_SIGNATURE1 } };
GString *result = g_string_new (NULL);
+ struct gvdb_header header;
+
+ if (byteswap)
+ {
+ header.signature[0] = GUINT32_TO_LE (GVDB_SIGNATURE0);
+ header.signature[1] = GUINT32_TO_LE (GVDB_SIGNATURE1);
+ }
+ else
+ {
+ header.signature[0] = GVDB_SIGNATURE0;
+ header.signature[1] = GVDB_SIGNATURE1;
+ }
result = g_string_new (NULL);
@@ -482,6 +515,7 @@ file_builder_serialise (FileBuilder *fb,
gboolean
gvdb_table_write_contents (GHashTable *table,
const gchar *filename,
+ gboolean byteswap,
GError **error)
{
struct gvdb_pointer root;
@@ -491,7 +525,7 @@ gvdb_table_write_contents (GHashTable *table,
fb = file_builder_new ();
file_builder_add_hash (fb, table, &root);
- str = file_builder_serialise (fb, root);
+ str = file_builder_serialise (fb, root, byteswap);
status = g_file_set_contents (filename, str->str, str->len, error);
g_string_free (str, TRUE);
diff --git a/gio/gvdb/gvdb-builder.h b/gio/gvdb/gvdb-builder.h
index d1a3eac..c0d3b30 100644
--- a/gio/gvdb/gvdb-builder.h
+++ b/gio/gvdb/gvdb-builder.h
@@ -15,6 +15,8 @@
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
+ *
+ * Author: Ryan Lortie <desrt desrt ca>
*/
#ifndef __gvdb_builder_h__
@@ -52,6 +54,7 @@ void gvdb_item_set_parent (GvdbIte
G_GNUC_INTERNAL
gboolean gvdb_table_write_contents (GHashTable *table,
const gchar *filename,
+ gboolean byteswap,
GError **error);
#endif /* __gvdb_builder_h__ */
diff --git a/gio/gvdb/gvdb-format.h b/gio/gvdb/gvdb-format.h
index 73d15b7..e90a4bc 100644
--- a/gio/gvdb/gvdb-format.h
+++ b/gio/gvdb/gvdb-format.h
@@ -1,3 +1,27 @@
+/*
+ * Copyright © 2010 Codethink Limited
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the licence, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Ryan Lortie <desrt desrt ca>
+ */
+
+#ifndef __gvdb_format_h__
+#define __gvdb_format_h__
+
#include <glib.h>
typedef struct { guint16 __value; } guint16_le;
@@ -59,3 +83,5 @@ static inline guint16 guint16_from_le (guint16_le value) {
#define GVDB_SIGNATURE0 1918981703
#define GVDB_SIGNATURE1 1953390953
+
+#endif /* __gvdb_format_h__ */
diff --git a/gio/gvdb/gvdb-reader.c b/gio/gvdb/gvdb-reader.c
index c4ea31b..7fe3d46 100644
--- a/gio/gvdb/gvdb-reader.c
+++ b/gio/gvdb/gvdb-reader.c
@@ -15,6 +15,8 @@
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
+ *
+ * Author: Ryan Lortie <desrt desrt ca>
*/
#include "gvdb-reader.h"
diff --git a/gio/gvdb/gvdb-reader.h b/gio/gvdb/gvdb-reader.h
index fe63e55..03ef97a 100644
--- a/gio/gvdb/gvdb-reader.h
+++ b/gio/gvdb/gvdb-reader.h
@@ -15,6 +15,8 @@
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
+ *
+ * Author: Ryan Lortie <desrt desrt ca>
*/
#ifndef __gvdb_reader_h__
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]