Commit 36c9dadf authored by Sven Neumann's avatar Sven Neumann Committed by Sven Neumann

app/config/gimpconfig-deserialize.[ch]

2005-01-24  Sven Neumann  <sven@gimp.org>

	* app/config/gimpconfig-deserialize.[ch]
	* app/config/gimpconfig-serialize.[ch]
	* app/config/gimpconfig.[ch]: factored out some rather obscure
	GimpConfig features that were added solely for gimprc.

	* app/config/Makefile.am
	* app/config/gimprc-deserialize.[ch]
	* app/config/gimprc-serialize.[ch]
	* app/config/gimprc-unknown.[ch]: moved gimprc-specific code to
	these new files.

	* app/config/gimprc.c
	* app/config/test-config.c: changed accordingly.
parent e95243ed
2005-01-24 Sven Neumann <sven@gimp.org>
* app/config/gimpconfig-deserialize.[ch]
* app/config/gimpconfig-serialize.[ch]
* app/config/gimpconfig.[ch]: factored out some rather obscure
GimpConfig features that were added solely for gimprc.
* app/config/Makefile.am
* app/config/gimprc-deserialize.[ch]
* app/config/gimprc-serialize.[ch]
* app/config/gimprc-unknown.[ch]: moved gimprc-specific code to
these new files.
* app/config/gimprc.c
* app/config/test-config.c: changed accordingly.
2005-01-24 Sven Neumann <sven@gimp.org>
* libgimpwidgets/gimpenumcombobox.c
......
......@@ -39,6 +39,12 @@ libappconfig_a_SOURCES = \
gimprc.c \
gimprc.h \
gimprc-blurbs.h \
gimprc-deserialize.c \
gimprc-deserialize.h \
gimprc-serialize.c \
gimprc-serialize.h \
gimprc-unknown.c \
gimprc-unknown.h \
gimpscanner.c \
gimpscanner.h \
gimpxmlparser.c \
......
......@@ -45,11 +45,6 @@
* couldn't parse it.
*/
static GTokenType gimp_config_deserialize_unknown (GimpConfig *config,
GScanner *scanner);
static GTokenType gimp_config_deserialize_property (GimpConfig *config,
GScanner *scanner,
gint nest_level);
static GTokenType gimp_config_deserialize_value (GValue *value,
GimpConfig *config,
GParamSpec *prop_spec,
......@@ -107,23 +102,16 @@ scanner_string_utf8_valid (GScanner *scanner,
* @config: a #GimpConfig.
* @scanner: a #GScanner.
* @nest_level:
* @store_unknown_tokens: %TRUE if you want to store unknown tokens.
*
* This function uses the @scanner to configure the properties of @config.
*
* The store_unknown_tokens parameter is a special feature for #GimpRc.
* If it set to %TRUE, unknown tokens (e.g. tokens that don't refer to
* a property of @config) with string values are attached to @config as
* unknown tokens. GimpConfig has a couple of functions to handle the
* attached key/value pairs.
*
* Return value:
**/
gboolean
gimp_config_deserialize_properties (GimpConfig *config,
GScanner *scanner,
gint nest_level,
gboolean store_unknown_tokens)
gboolean unused)
{
GObjectClass *klass;
GParamSpec **property_specs;
......@@ -166,12 +154,8 @@ gimp_config_deserialize_properties (GimpConfig *config,
{
next = g_scanner_peek_next_token (scanner);
if (next != token &&
! (store_unknown_tokens &&
token == G_TOKEN_SYMBOL && next == G_TOKEN_IDENTIFIER))
{
break;
}
if (next != token)
break;
token = g_scanner_get_next_token (scanner);
......@@ -181,10 +165,6 @@ gimp_config_deserialize_properties (GimpConfig *config,
token = G_TOKEN_SYMBOL;
break;
case G_TOKEN_IDENTIFIER:
token = gimp_config_deserialize_unknown (config, scanner);
break;
case G_TOKEN_SYMBOL:
token = gimp_config_deserialize_property (config,
scanner, nest_level);
......@@ -206,51 +186,10 @@ gimp_config_deserialize_properties (GimpConfig *config,
if (token == G_TOKEN_NONE)
return FALSE;
/* If store_unknown_tokens is TRUE but the unknown token value couldn't
be parsed the default error message is rather confusing.
We try to produce something more meaningful here ... */
if ((store_unknown_tokens &&
token == G_TOKEN_STRING && next == G_TOKEN_IDENTIFIER))
{
g_scanner_unexp_token (scanner, G_TOKEN_SYMBOL, NULL, NULL, NULL,
_("fatal parse error"), TRUE);
return FALSE;
}
return gimp_config_deserialize_return (scanner, token, nest_level);
}
static GTokenType
gimp_config_deserialize_unknown (GimpConfig *config,
GScanner *scanner)
{
gchar *key;
guint old_scope_id;
old_scope_id = g_scanner_set_scope (scanner, 0);
if (g_scanner_peek_next_token (scanner) != G_TOKEN_STRING)
return G_TOKEN_STRING;
key = g_strdup (scanner->value.v_identifier);
g_scanner_get_next_token (scanner);
g_scanner_set_scope (scanner, old_scope_id);
if (!scanner_string_utf8_valid (scanner, key))
{
g_free (key);
return G_TOKEN_NONE;
}
gimp_config_add_unknown_token (config, key, scanner->value.v_string);
g_free (key);
return G_TOKEN_RIGHT_PAREN;
}
static GTokenType
GTokenType
gimp_config_deserialize_property (GimpConfig *config,
GScanner *scanner,
gint nest_level)
......
......@@ -23,10 +23,13 @@
#define __GIMP_CONFIG_DESERIALIZE_H__
gboolean gimp_config_deserialize_properties (GimpConfig *config,
GScanner *scanner,
gint nest_level,
gboolean store_unknown_tokens);
gboolean gimp_config_deserialize_properties (GimpConfig *config,
GScanner *scanner,
gint nest_level,
gboolean unused);
GTokenType gimp_config_deserialize_property (GimpConfig *config,
GScanner *scanner,
gint nest_level);
#endif /* __GIMP_CONFIG_DESERIALIZE_H__ */
......@@ -36,11 +36,6 @@
#include "gimpconfigwriter.h"
static void serialize_unknown_token (const gchar *key,
const gchar *value,
gpointer data);
/**
* gimp_config_serialize_properties:
* @config: a #GimpConfig.
......@@ -137,56 +132,6 @@ gimp_config_serialize_changed_properties (GimpConfig *config,
return TRUE;
}
/**
* gimp_config_serialize_properties_diff:
* @config: a #GimpConfig.
* @compare: a #GimpConfig of the same type as @config.
* @writer: a #GimpConfigWriter.
*
* This function compares @config and @compare and writes all
* properties of @config that have different values than @compare to
* the @writer.
*
* Returns: %TRUE if serialization succeeded, %FALSE otherwise
**/
gboolean
gimp_config_serialize_properties_diff (GimpConfig *config,
GimpConfig *compare,
GimpConfigWriter *writer)
{
GObjectClass *klass;
GList *diff;
GList *list;
g_return_val_if_fail (G_IS_OBJECT (config), FALSE);
g_return_val_if_fail (G_IS_OBJECT (compare), FALSE);
g_return_val_if_fail (G_TYPE_FROM_INSTANCE (config) ==
G_TYPE_FROM_INSTANCE (compare), FALSE);
klass = G_OBJECT_GET_CLASS (config);
diff = gimp_config_diff (config, compare, GIMP_PARAM_SERIALIZE);
if (! diff)
return TRUE;
for (list = diff; list; list = g_list_next (list))
{
GParamSpec *prop_spec = (GParamSpec *) list->data;
if (! (prop_spec->flags & GIMP_PARAM_SERIALIZE))
continue;
if (! gimp_config_serialize_property (config, prop_spec, writer))
return FALSE;
}
g_list_free (diff);
return TRUE;
}
gboolean
gimp_config_serialize_property (GimpConfig *config,
GParamSpec *param_spec,
......@@ -482,38 +427,3 @@ gimp_config_serialize_value (const GValue *value,
return FALSE;
}
/**
* gimp_config_serialize_unknown_tokens:
* @config: a #GimpConfig.
* @writer: a #GimpConfigWriter.
*
* Writes all unknown tokens attached to @config to the @writer. See
* gimp_config_add_unknown_token().
*
* Returns: %TRUE if serialization succeeded, %FALSE otherwise
**/
gboolean
gimp_config_serialize_unknown_tokens (GimpConfig *config,
GimpConfigWriter *writer)
{
g_return_val_if_fail (G_IS_OBJECT (config), FALSE);
gimp_config_writer_linefeed (writer);
gimp_config_foreach_unknown_token (config, serialize_unknown_token, writer);
return TRUE;
}
static void
serialize_unknown_token (const gchar *key,
const gchar *value,
gpointer data)
{
GimpConfigWriter *writer = data;
gimp_config_writer_open (writer, key);
gimp_config_writer_string (writer, value);
gimp_config_writer_close (writer);
}
......@@ -27,12 +27,6 @@ gboolean gimp_config_serialize_properties (GimpConfig *config,
GimpConfigWriter *writer);
gboolean gimp_config_serialize_changed_properties (GimpConfig *config,
GimpConfigWriter *writer);
gboolean gimp_config_serialize_properties_diff (GimpConfig *config,
GimpConfig *compare,
GimpConfigWriter *writer);
gboolean gimp_config_serialize_unknown_tokens (GimpConfig *config,
GimpConfigWriter *writer);
gboolean gimp_config_serialize_property (GimpConfig *config,
GParamSpec *param_spec,
......
......@@ -501,188 +501,3 @@ gimp_config_reset (GimpConfig *config)
GIMP_CONFIG_GET_INTERFACE (config)->reset (config);
}
/*
* Code to store and lookup unknown tokens (string key/value pairs).
*/
#define GIMP_CONFIG_UNKNOWN_TOKENS "gimp-config-unknown-tokens"
typedef struct
{
gchar *key;
gchar *value;
} GimpConfigToken;
static void gimp_config_destroy_unknown_tokens (GSList *unknown_tokens);
/**
* gimp_config_add_unknown_token:
* @config: a #GObject.
* @key: a nul-terminated string to identify the value.
* @value: a nul-terminated string representing the value.
*
* This function allows to add arbitrary key/value pairs to a GObject.
* It's purpose is to attach additional data to a #GimpConfig object
* that can be stored along with the object properties when
* serializing the object to a configuration file. Please note however
* that the default gimp_config_serialize() implementation does not
* serialize unknown tokens.
*
* If you want to remove a key/value pair from the object, call this
* function with a %NULL @value.
**/
void
gimp_config_add_unknown_token (GimpConfig *config,
const gchar *key,
const gchar *value)
{
GimpConfigToken *token;
GSList *unknown_tokens;
GSList *last;
GSList *list;
g_return_if_fail (GIMP_IS_CONFIG (config));
g_return_if_fail (key != NULL);
unknown_tokens = (GSList *) g_object_get_data (G_OBJECT (config),
GIMP_CONFIG_UNKNOWN_TOKENS);
for (last = NULL, list = unknown_tokens;
list;
last = list, list = g_slist_next (list))
{
token = (GimpConfigToken *) list->data;
if (strcmp (token->key, key) == 0)
{
g_free (token->value);
if (value)
{
token->value = g_strdup (value);
}
else
{
g_free (token->key);
unknown_tokens = g_slist_remove (unknown_tokens, token);
g_object_set_data_full (G_OBJECT (config),
GIMP_CONFIG_UNKNOWN_TOKENS,
unknown_tokens,
(GDestroyNotify) gimp_config_destroy_unknown_tokens);
}
return;
}
}
if (!value)
return;
token = g_new (GimpConfigToken, 1);
token->key = g_strdup (key);
token->value = g_strdup (value);
if (last)
{
g_slist_append (last, token);
}
else
{
unknown_tokens = g_slist_append (NULL, token);
g_object_set_data_full (G_OBJECT (config),
GIMP_CONFIG_UNKNOWN_TOKENS,
unknown_tokens,
(GDestroyNotify) gimp_config_destroy_unknown_tokens);
}
}
/**
* gimp_config_lookup_unknown_token:
* @config: a #GObject.
* @key: a nul-terminated string to identify the value.
*
* This function retrieves data that was previously attached using
* gimp_config_add_unknown_token(). You should not free or modify
* the returned string.
*
* Returns: a pointer to a constant string.
**/
const gchar *
gimp_config_lookup_unknown_token (GimpConfig *config,
const gchar *key)
{
GimpConfigToken *token;
GSList *unknown_tokens;
GSList *list;
g_return_val_if_fail (GIMP_IS_CONFIG (config), NULL);
g_return_val_if_fail (key != NULL, NULL);
unknown_tokens = (GSList *) g_object_get_data (G_OBJECT (config),
GIMP_CONFIG_UNKNOWN_TOKENS);
for (list = unknown_tokens; list; list = g_slist_next (list))
{
token = (GimpConfigToken *) list->data;
if (strcmp (token->key, key) == 0)
return token->value;
}
return NULL;
}
/**
* gimp_config_foreach_unknown_token:
* @config: a #GObject.
* @func: a function to call for each key/value pair.
* @user_data: data to pass to @func.
*
* Calls @func for each key/value stored with the @config using
* gimp_config_add_unknown_token().
**/
void
gimp_config_foreach_unknown_token (GimpConfig *config,
GimpConfigForeachFunc func,
gpointer user_data)
{
GimpConfigToken *token;
GSList *unknown_tokens;
GSList *list;
g_return_if_fail (GIMP_IS_CONFIG (config));
g_return_if_fail (func != NULL);
unknown_tokens = (GSList *) g_object_get_data (G_OBJECT (config),
GIMP_CONFIG_UNKNOWN_TOKENS);
for (list = unknown_tokens; list; list = g_slist_next (list))
{
token = (GimpConfigToken *) list->data;
func (token->key, token->value, user_data);
}
}
static void
gimp_config_destroy_unknown_tokens (GSList *unknown_tokens)
{
GimpConfigToken *token;
GSList *list;
for (list = unknown_tokens; list; list = g_slist_next (list))
{
token = (GimpConfigToken *) list->data;
g_free (token->key);
g_free (token->value);
g_free (token);
}
g_slist_free (unknown_tokens);
}
......@@ -59,10 +59,6 @@ struct _GimpConfigInterface
void (* reset) (GimpConfig *config);
};
typedef void (* GimpConfigForeachFunc) (const gchar *key,
const gchar *value,
gpointer user_data);
GType gimp_config_interface_get_type (void) G_GNUC_CONST;
......@@ -95,14 +91,5 @@ gboolean gimp_config_is_equal_to (GimpConfig *a,
GimpConfig *b);
void gimp_config_reset (GimpConfig *config);
void gimp_config_add_unknown_token (GimpConfig *config,
const gchar *key,
const gchar *value);
const gchar * gimp_config_lookup_unknown_token (GimpConfig *config,
const gchar *key);
void gimp_config_foreach_unknown_token (GimpConfig *config,
GimpConfigForeachFunc func,
gpointer user_data);
#endif /* __GIMP_CONFIG_H__ */
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* GimpRc deserialization routines
* Copyright (C) 2001-2002 Sven Neumann <sven@gimp.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "config.h"
#include <glib-object.h>
#include "libgimpcolor/gimpcolor.h"
#include "libgimpmath/gimpmath.h"
#include "config-types.h"
#include "gimpconfig.h"
#include "gimpconfig-deserialize.h"
#include "gimpconfig-params.h"
#include "gimprc-deserialize.h"
#include "gimprc-unknown.h"
#include "gimpscanner.h"
#include "gimp-intl.h"
static GTokenType gimp_rc_deserialize_unknown (GimpConfig *config,
GScanner *scanner);
gboolean
gimp_rc_deserialize (GimpConfig *config,
GScanner *scanner,
gint nest_level,
gpointer data)
{
GObjectClass *klass;
GParamSpec **property_specs;
guint n_property_specs;
guint i;
guint scope_id;
guint old_scope_id;
GTokenType token;
GTokenType next;
g_return_val_if_fail (GIMP_IS_CONFIG (config), FALSE);
klass = G_OBJECT_GET_CLASS (config);
property_specs = g_object_class_list_properties (klass, &n_property_specs);
if (! property_specs)
return TRUE;
scope_id = g_type_qname (G_TYPE_FROM_INSTANCE (config));
old_scope_id = g_scanner_set_scope (scanner, scope_id);
for (i = 0; i < n_property_specs; i++)
{
GParamSpec *prop_spec = property_specs[i];
if (prop_spec->flags & GIMP_PARAM_SERIALIZE)
{
g_scanner_scope_add_symbol (scanner, scope_id,
prop_spec->name, prop_spec);
}
}
g_free (property_specs);
g_object_freeze_notify (G_OBJECT (config));
token = G_TOKEN_LEFT_PAREN;
while (TRUE)
{
next = g_scanner_peek_next_token (scanner);
if (next != token &&
! (token == G_TOKEN_SYMBOL && next == G_TOKEN_IDENTIFIER))
{
break;
}
token = g_scanner_get_next_token (scanner);
switch (token)
{
case G_TOKEN_LEFT_PAREN:
token = G_TOKEN_SYMBOL;
break;
case G_TOKEN_IDENTIFIER:
token = gimp_rc_deserialize_unknown (config, scanner);
break;
case G_TOKEN_SYMBOL:
token = gimp_config_deserialize_property (config,
scanner, nest_level);
break;
case G_TOKEN_RIGHT_PAREN:
token = G_TOKEN_LEFT_PAREN;
break;
default: /* do nothing */
break;
}
}
g_scanner_set_scope (scanner, old_scope_id);
g_object_thaw_notify (G_OBJECT (config));
if (token == G_TOKEN_NONE)
return FALSE;
/* If the unknown token value couldn't be parsed the default error
message is rather confusing. We try to produce something more
meaningful here ...
*/
if (token == G_TOKEN_STRING && next == G_TOKEN_IDENTIFIER)
{
g_scanner_unexp_token (scanner, G_TOKEN_SYMBOL, NULL, NULL, NULL,
_("fatal parse error"), TRUE);
return FALSE;
}
return gimp_config_deserialize_return (scanner, token, nest_level);
}
static GTokenType
gimp_rc_deserialize_unknown (GimpConfig *config,
GScanner *scanner)
{
gchar *key;
guint old_scope_id;
old_scope_id = g_scanner_set_scope (scanner, 0);
if (g_scanner_peek_next_token (scanner) != G_TOKEN_STRING)
return G_TOKEN_STRING;
key = g_strdup (scanner->value.v_identifier);
g_scanner_get_next_token (scanner);
g_scanner_set_scope (scanner, old_scope_id);
if (! g_utf8_validate (scanner->value.v_string, -1, NULL))
{
g_scanner_error (scanner,
_("value for token %s is not a valid UTF-8 string"),
key);
g_free (key);
return G_TOKEN_NONE;
}
gimp_rc_add_unknown_token (config, key, scanner->value.v_string);
g_free (key);
return G_TOKEN_RIGHT_PAREN;
}
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* GimpRc deserialization routines
* Copyright (C) 2001-2005 Sven Neumann <sven@gimp.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef __GIMP_RC_DESERIALIZE_H__
#define __GIMP_RC_DESERIALIZE_H__
gboolean gimp_rc_deserialize (GimpConfig *config,
GScanner *scanner,
gint nest_level,
gpointer data);
#endif /* __GIMP_RC_DESERIALIZE_H__ */
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* GimpRc serialization routines
* Copyright (C) 2001-2005 Sven Neumann <sven@gimp.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "config.h"
#include <glib-object.h>
#include "libgimpbase/gimpbase.h"
#include "config-types.h"