lots of schemas changes

This commit is contained in:
Ryan Lortie
2010-04-15 13:10:45 -04:00
parent 106716d8ec
commit a07b0fc2ed
9 changed files with 217 additions and 83 deletions

View File

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

View File

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

View File

@@ -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);
}

View File

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

View File

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

View File

@@ -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__ */

View File

@@ -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__ */

View File

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

View File

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