app/config/Makefile.am new files featuring a simple config file writer.

2003-03-05  Sven Neumann  <sven@gimp.org>

	* app/config/Makefile.am
	* app/config/gimpconfigwriter.[ch]: new files featuring a simple
	config file writer.

	* app/config/gimpconfig-serialize.[ch]
	* app/config/gimpconfig.[ch]: changed the serialize routines to
	use a GimpConfigWriter instead of passing around a file descriptor
	and the indentation level.

	* app/config/config-types.h
	* app/config/gimpconfig-deserialize.c
	* app/config/gimpconfig-dump.c
	* app/config/gimpconfig-utils.c
	* app/config/gimprc.c
	* app/config/gimpscanner.c
	* app/config/test-config.c
	* app/core/gimp-documents.c
	* app/core/gimp-parasites.c
	* app/core/gimpcontainer.c
	* app/core/gimpcontext.c
	* app/core/gimpdocumentlist.c
	* app/core/gimpparasitelist.c
	* app/gui/test-commands.c
	* app/tools/tool_options.c
	* app/widgets/gimpdevices.c: changed accordingly.

	* libgimpwidgets/gimpwidgets.c: documentation updates.

	* app/core/gimpitem.c: removed a redundant type-check.
This commit is contained in:
Sven Neumann 2003-03-05 20:21:50 +00:00 committed by Sven Neumann
parent 614ff00629
commit d457b9eb9b
36 changed files with 1390 additions and 693 deletions

View File

@ -1,3 +1,35 @@
2003-03-05 Sven Neumann <sven@gimp.org>
* app/config/Makefile.am
* app/config/gimpconfigwriter.[ch]: new files featuring a simple
config file writer.
* app/config/gimpconfig-serialize.[ch]
* app/config/gimpconfig.[ch]: changed the serialize routines to
use a GimpConfigWriter instead of passing around a file descriptor
and the indentation level.
* app/config/config-types.h
* app/config/gimpconfig-deserialize.c
* app/config/gimpconfig-dump.c
* app/config/gimpconfig-utils.c
* app/config/gimprc.c
* app/config/gimpscanner.c
* app/config/test-config.c
* app/core/gimp-documents.c
* app/core/gimp-parasites.c
* app/core/gimpcontainer.c
* app/core/gimpcontext.c
* app/core/gimpdocumentlist.c
* app/core/gimpparasitelist.c
* app/gui/test-commands.c
* app/tools/tool_options.c
* app/widgets/gimpdevices.c: changed accordingly.
* libgimpwidgets/gimpwidgets.c: documentation updates.
* app/core/gimpitem.c: removed a redundant type-check.
2003-03-05 Michael Natterer <mitch@gimp.org> 2003-03-05 Michael Natterer <mitch@gimp.org>
* themes/Default/images/stock-channels-16.png * themes/Default/images/stock-channels-16.png

View File

@ -19,6 +19,8 @@ libappconfig_a_SOURCES = \
gimpconfig-types.h \ gimpconfig-types.h \
gimpconfig-utils.c \ gimpconfig-utils.c \
gimpconfig-utils.h \ gimpconfig-utils.h \
gimpconfigwriter.c \
gimpconfigwriter.h \
gimpbaseconfig.c \ gimpbaseconfig.c \
gimpbaseconfig.h \ gimpbaseconfig.h \
gimpcoreconfig.c \ gimpcoreconfig.c \

View File

@ -30,5 +30,7 @@ typedef struct _GimpGuiConfig GimpGuiConfig;
typedef struct _GimpPluginConfig GimpPluginConfig; typedef struct _GimpPluginConfig GimpPluginConfig;
typedef struct _GimpRc GimpRc; typedef struct _GimpRc GimpRc;
typedef struct _GimpConfigWriter GimpConfigWriter;
#endif /* __CONFIG_TYPES_H__ */ #endif /* __CONFIG_TYPES_H__ */

View File

@ -34,6 +34,8 @@
#include "libgimpbase/gimpbase.h" #include "libgimpbase/gimpbase.h"
#include "libgimpcolor/gimpcolor.h" #include "libgimpcolor/gimpcolor.h"
#include "config-types.h"
#include "gimpconfig.h" #include "gimpconfig.h"
#include "gimpconfig-deserialize.h" #include "gimpconfig-deserialize.h"
#include "gimpconfig-params.h" #include "gimpconfig-params.h"

View File

@ -40,6 +40,7 @@
#include "gimpconfig-params.h" #include "gimpconfig-params.h"
#include "gimpconfig-serialize.h" #include "gimpconfig-serialize.h"
#include "gimpconfig-types.h" #include "gimpconfig-types.h"
#include "gimpconfigwriter.h"
#include "gimprc.h" #include "gimprc.h"
@ -52,12 +53,11 @@ typedef enum
} DumpFormat; } DumpFormat;
static gint dump_gimprc (DumpFormat format, static gint dump_gimprc (DumpFormat format);
gint fd);
static void dump_gimprc_system (GObject *rc, static void dump_gimprc_system (GObject *rc,
gint fd); GimpConfigWriter *writer);
static void dump_gimprc_manpage (GObject *rc, static void dump_gimprc_manpage (GObject *rc,
gint fd); GimpConfigWriter *writer);
static gchar * dump_describe_param (GParamSpec *param_spec); static gchar * dump_describe_param (GParamSpec *param_spec);
static void dump_with_linebreaks (gint fd, static void dump_with_linebreaks (gint fd,
const gchar *text); const gchar *text);
@ -102,13 +102,13 @@ main (int argc,
} }
} }
return dump_gimprc (format, 1); return dump_gimprc (format);
} }
static gint static gint
dump_gimprc (DumpFormat format, dump_gimprc (DumpFormat format)
gint fd)
{ {
GimpConfigWriter *writer;
GObject *rc; GObject *rc;
if (format == DUMP_NONE) if (format == DUMP_NONE)
@ -120,23 +120,30 @@ dump_gimprc (DumpFormat format,
"module-load-inhibit", "foo", /* for completeness */ "module-load-inhibit", "foo", /* for completeness */
NULL); NULL);
writer = gimp_config_writer_new_from_fd (1);
switch (format) switch (format)
{ {
case DUMP_DEFAULT: case DUMP_DEFAULT:
g_print ("# Dump of the GIMP default configuration\n\n"); gimp_config_writer_comment (writer,
gimp_config_serialize_properties (rc, 1, 0); "Dump of the GIMP default configuration");
gimp_config_writer_linefeed (writer);
gimp_config_serialize_properties (rc, writer);
g_print ("\n"); g_print ("\n");
break; break;
case DUMP_COMMENT: case DUMP_COMMENT:
dump_gimprc_system (rc, fd); dump_gimprc_system (rc, writer);
break; break;
case DUMP_MANPAGE: case DUMP_MANPAGE:
dump_gimprc_manpage (rc, fd); dump_gimprc_manpage (rc, writer);
break; break;
default: default:
break; break;
} }
gimp_config_writer_finish (writer, NULL, NULL);
g_object_unref (rc); g_object_unref (rc);
return EXIT_SUCCESS; return EXIT_SUCCESS;
@ -144,33 +151,31 @@ dump_gimprc (DumpFormat format,
static const gchar *system_gimprc_header = static const gchar *system_gimprc_header =
"# This is the system-wide gimprc file. Any change made in this file\n" "This is the system-wide gimprc file. Any change made in this file "
"# will affect all users of this system, provided that they are not\n" "will affect all users of this system, provided that they are not "
"# overriding the default values in their personal gimprc file.\n" "overriding the default values in their personal gimprc file.\n"
"#\n"
"# Lines that start with a '#' are comments. Blank lines are ignored.\n"
"#\n"
"# By default everything in this file is commented out. The file then\n"
"# documents the default values and shows what changes are possible.\n"
"\n" "\n"
"# The variable ${gimp_dir} is set to the value of the environment\n" "Lines that start with a '#' are comments. Blank lines are ignored.\n"
"# variable GIMP_DIRECTORY or, if that is not set, the compiled-in\n" "\n"
"# default value is used. If GIMP_DIRECTORY is not an absolute path,\n" "By default everything in this file is commented out. The file then "
"# it is interpreted relative to your home directory.\n" "documents the default values and shows what changes are possible.\n"
"\n"; "\n"
"The variable ${gimp_dir} is set to the value of the environment "
"variable GIMP_DIRECTORY or, if that is not set, the compiled-in "
"default value is used. If GIMP_DIRECTORY is not an absolute path, "
"it is interpreted relative to your home directory.";
static void static void
dump_gimprc_system (GObject *rc, dump_gimprc_system (GObject *rc,
gint fd) GimpConfigWriter *writer)
{ {
GObjectClass *klass; GObjectClass *klass;
GParamSpec **property_specs; GParamSpec **property_specs;
GString *str;
guint n_property_specs; guint n_property_specs;
guint i; guint i;
str = g_string_new (system_gimprc_header); gimp_config_writer_comment (writer, system_gimprc_header);
write (fd, str->str, str->len); gimp_config_writer_linefeed (writer);
klass = G_OBJECT_GET_CLASS (rc); klass = G_OBJECT_GET_CLASS (rc);
property_specs = g_object_class_list_properties (klass, &n_property_specs); property_specs = g_object_class_list_properties (klass, &n_property_specs);
@ -183,25 +188,23 @@ dump_gimprc_system (GObject *rc,
if (! (prop_spec->flags & GIMP_PARAM_SERIALIZE)) if (! (prop_spec->flags & GIMP_PARAM_SERIALIZE))
continue; continue;
g_string_truncate (str, 0);
comment = dump_describe_param (prop_spec); comment = dump_describe_param (prop_spec);
if (comment) if (comment)
{ {
gimp_config_serialize_comment (str, comment); gimp_config_writer_comment (writer, comment);
g_free (comment); g_free (comment);
g_string_append (str, "#\n");
write (writer->fd, "#\n", 2);
} }
g_string_append (str, "# "); /* kids, don't try this at home! */
write (fd, str->str, str->len); write (writer->fd, "# ", 2);
if (gimp_config_serialize_property (rc, prop_spec, fd, 0)) gimp_config_serialize_property (rc, prop_spec, writer);
write (fd, "\n", 1); gimp_config_writer_linefeed (writer);
} }
g_free (property_specs); g_free (property_specs);
g_string_free (str, TRUE);
} }
@ -293,14 +296,14 @@ static const gchar *man_page_footer =
static void static void
dump_gimprc_manpage (GObject *rc, dump_gimprc_manpage (GObject *rc,
gint fd) GimpConfigWriter *writer)
{ {
GObjectClass *klass; GObjectClass *klass;
GParamSpec **property_specs; GParamSpec **property_specs;
guint n_property_specs; guint n_property_specs;
guint i; guint i;
write (fd, man_page_header, strlen (man_page_header)); write (writer->fd, man_page_header, strlen (man_page_header));
klass = G_OBJECT_GET_CLASS (rc); klass = G_OBJECT_GET_CLASS (rc);
property_specs = g_object_class_list_properties (klass, &n_property_specs); property_specs = g_object_class_list_properties (klass, &n_property_specs);
@ -313,16 +316,16 @@ dump_gimprc_manpage (GObject *rc,
if (! (prop_spec->flags & GIMP_PARAM_SERIALIZE)) if (! (prop_spec->flags & GIMP_PARAM_SERIALIZE))
continue; continue;
write (fd, ".TP\n", strlen (".TP\n")); write (writer->fd, ".TP\n", strlen (".TP\n"));
if (gimp_config_serialize_property (rc, prop_spec, fd, 0)) if (gimp_config_serialize_property (rc, prop_spec, writer))
{ {
write (fd, "\n", 1); write (writer->fd, "\n", 1);
desc = dump_describe_param (prop_spec); desc = dump_describe_param (prop_spec);
dump_with_linebreaks (fd, desc); dump_with_linebreaks (writer->fd, desc);
write (fd, "\n", 1); write (writer->fd, "\n", 1);
g_free (desc); g_free (desc);
} }
@ -330,8 +333,8 @@ dump_gimprc_manpage (GObject *rc,
g_free (property_specs); g_free (property_specs);
write (fd, man_page_path, strlen (man_page_path)); write (writer->fd, man_page_path, strlen (man_page_path));
write (fd, man_page_footer, strlen (man_page_footer)); write (writer->fd, man_page_footer, strlen (man_page_footer));
} }

View File

@ -36,11 +36,14 @@
#include "libgimpbase/gimpbase.h" #include "libgimpbase/gimpbase.h"
#include "libgimpcolor/gimpcolor.h" #include "libgimpcolor/gimpcolor.h"
#include "config-types.h"
#include "gimpconfig.h" #include "gimpconfig.h"
#include "gimpconfig-params.h" #include "gimpconfig-params.h"
#include "gimpconfig-serialize.h" #include "gimpconfig-serialize.h"
#include "gimpconfig-types.h" #include "gimpconfig-types.h"
#include "gimpconfig-utils.h" #include "gimpconfig-utils.h"
#include "gimpconfigwriter.h"
static void serialize_unknown_token (const gchar *key, static void serialize_unknown_token (const gchar *key,
@ -51,14 +54,13 @@ static void serialize_unknown_token (const gchar *key,
/** /**
* gimp_config_serialize_properties: * gimp_config_serialize_properties:
* @object: a #GObject. * @object: a #GObject.
* @fd: a file descriptor to write to. * @writer: a #GimpConfigWriter.
* *
* This function writes all object properties to the file descriptor @fd. * This function writes all object properties to the @writer.
**/ **/
gboolean gboolean
gimp_config_serialize_properties (GObject *object, gimp_config_serialize_properties (GObject *object,
gint fd, GimpConfigWriter *writer)
gint indent_level)
{ {
GObjectClass *klass; GObjectClass *klass;
GParamSpec **property_specs; GParamSpec **property_specs;
@ -81,8 +83,7 @@ gimp_config_serialize_properties (GObject *object,
if (! (prop_spec->flags & GIMP_PARAM_SERIALIZE)) if (! (prop_spec->flags & GIMP_PARAM_SERIALIZE))
continue; continue;
if (! gimp_config_serialize_property (object, prop_spec, if (! gimp_config_serialize_property (object, prop_spec, writer))
fd, indent_level))
return FALSE; return FALSE;
} }
@ -94,15 +95,14 @@ gimp_config_serialize_properties (GObject *object,
/** /**
* gimp_config_serialize_changed_properties: * gimp_config_serialize_changed_properties:
* @object: a #GObject. * @object: a #GObject.
* @fd: a file descriptor to write to. * @writer: a #GimpConfigWriter.
* *
* This function writes all object properties that have been changed from * This function writes all object properties that have been changed from
* their default values to the file descriptor @fd. * their default values to the @writer.
**/ **/
gboolean gboolean
gimp_config_serialize_changed_properties (GObject *object, gimp_config_serialize_changed_properties (GObject *object,
gint fd, GimpConfigWriter *writer)
gint indent_level)
{ {
GObjectClass *klass; GObjectClass *klass;
GParamSpec **property_specs; GParamSpec **property_specs;
@ -131,8 +131,7 @@ gimp_config_serialize_changed_properties (GObject *object,
if (! g_param_value_defaults (prop_spec, &value)) if (! g_param_value_defaults (prop_spec, &value))
{ {
if (! gimp_config_serialize_property (object, prop_spec, if (! gimp_config_serialize_property (object, prop_spec, writer))
fd, indent_level))
return FALSE; return FALSE;
} }
@ -148,17 +147,16 @@ gimp_config_serialize_changed_properties (GObject *object,
* gimp_config_serialize_properties_diff: * gimp_config_serialize_properties_diff:
* @object: a #GObject. * @object: a #GObject.
* @compare: a #GObject of the same type as @object. * @compare: a #GObject of the same type as @object.
* @fd: a file descriptor to write to. * @writer: a #GimpConfigWriter.
* *
* This function compares @object and @compare and writes all * This function compares @object and @compare and writes all
* properties of @object that have different values than @compare to * properties of @object that have different values than @compare to
* the file descriptor @fd. * the @writer.
**/ **/
gboolean gboolean
gimp_config_serialize_properties_diff (GObject *object, gimp_config_serialize_properties_diff (GObject *object,
GObject *compare, GObject *compare,
gint fd, GimpConfigWriter *writer)
gint indent_level)
{ {
GObjectClass *klass; GObjectClass *klass;
GList *diff; GList *diff;
@ -183,8 +181,7 @@ gimp_config_serialize_properties_diff (GObject *object,
if (! (prop_spec->flags & GIMP_PARAM_SERIALIZE)) if (! (prop_spec->flags & GIMP_PARAM_SERIALIZE))
continue; continue;
if (! gimp_config_serialize_property (object, prop_spec, if (! gimp_config_serialize_property (object, prop_spec, writer))
fd, indent_level))
return FALSE; return FALSE;
} }
@ -197,22 +194,18 @@ gimp_config_serialize_properties_diff (GObject *object,
gboolean gboolean
gimp_config_serialize_property (GObject *object, gimp_config_serialize_property (GObject *object,
GParamSpec *param_spec, GParamSpec *param_spec,
gint fd, GimpConfigWriter *writer)
gint indent_level)
{ {
GTypeClass *owner_class; GTypeClass *owner_class;
GimpConfigInterface *config_iface; GimpConfigInterface *config_iface;
GimpConfigInterface *parent_iface = NULL; GimpConfigInterface *parent_iface = NULL;
GString *str;
GValue value = { 0, }; GValue value = { 0, };
gboolean success = FALSE; gboolean success = FALSE;
if (! (param_spec->flags & GIMP_PARAM_SERIALIZE)) if (! (param_spec->flags & GIMP_PARAM_SERIALIZE))
return FALSE; return FALSE;
str = g_string_new (NULL); gimp_config_writer_open (writer, param_spec->name);
gimp_config_string_indent (str, indent_level);
g_string_append_printf (str, "(%s ", param_spec->name);
g_value_init (&value, param_spec->value_type); g_value_init (&value, param_spec->value_type);
g_object_get_property (object, param_spec->name, &value); g_object_get_property (object, param_spec->name, &value);
@ -249,7 +242,7 @@ gimp_config_serialize_property (GObject *object,
param_spec->param_id, param_spec->param_id,
(const GValue *) &value, (const GValue *) &value,
param_spec, param_spec,
str)) writer))
{ {
success = TRUE; success = TRUE;
} }
@ -273,48 +266,45 @@ gimp_config_serialize_property (GObject *object,
success = TRUE; success = TRUE;
if (gimp_config_iface) if (gimp_config_iface)
{ success = gimp_config_iface->serialize (prop_object, writer, NULL);
g_string_append_c (str, '\n');
write (fd, str->str, str->len);
g_string_truncate (str, 0);
success = gimp_config_iface->serialize (prop_object,
fd, indent_level + 1,
NULL);
success = TRUE;
}
} }
else else
{ {
GString *str = g_string_new (NULL);
success = gimp_config_serialize_value (&value, str, TRUE); success = gimp_config_serialize_value (&value, str, TRUE);
if (success)
gimp_config_writer_print (writer, str->str, str->len);
g_string_free (str, TRUE);
} }
} }
if (success) if (success)
{ {
g_string_append (str, ")\n"); gimp_config_writer_close (writer);
if (write (fd, str->str, str->len) == -1)
success = FALSE;
} }
else
if (! success)
{ {
gimp_config_writer_revert (writer);
/* don't warn for empty string properties */ /* don't warn for empty string properties */
if (G_VALUE_HOLDS_STRING (&value)) if (G_VALUE_HOLDS_STRING (&value))
{
success = TRUE; success = TRUE;
}
else else
{
g_warning ("couldn't serialize property %s::%s of type %s", g_warning ("couldn't serialize property %s::%s of type %s",
g_type_name (G_TYPE_FROM_INSTANCE (object)), g_type_name (G_TYPE_FROM_INSTANCE (object)),
param_spec->name, param_spec->name,
g_type_name (param_spec->value_type)); g_type_name (param_spec->value_type));
} }
}
g_value_unset (&value); g_value_unset (&value);
g_string_free (str, TRUE);
return success; return success;
} }
@ -467,25 +457,21 @@ gimp_config_serialize_value (const GValue *value,
/** /**
* gimp_config_serialize_unknown_tokens: * gimp_config_serialize_unknown_tokens:
* @object: a #GObject. * @object: a #GObject.
* @fd: a file descriptor to write to. * @writer: a #GimpConfigWriter.
* *
* Writes all unknown tokens attached to #object to the file descriptor @fd. * Writes all unknown tokens attached to #object to the @writer. See
* See gimp_config_add_unknown_token(). * gimp_config_add_unknown_token().
**/ **/
gboolean gboolean
gimp_config_serialize_unknown_tokens (GObject *object, gimp_config_serialize_unknown_tokens (GObject *object,
gint fd, GimpConfigWriter *writer)
gint indent_level)
{ {
GString *str;
g_return_val_if_fail (G_IS_OBJECT (object), FALSE); g_return_val_if_fail (G_IS_OBJECT (object), FALSE);
str = g_string_new (NULL); gimp_config_writer_linefeed (writer);
gimp_config_foreach_unknown_token (object, serialize_unknown_token, writer);
gimp_config_foreach_unknown_token (object, serialize_unknown_token, str); return TRUE;
return (write (fd, str->str, str->len) != -1);
} }
@ -538,9 +524,14 @@ serialize_unknown_token (const gchar *key,
const gchar *value, const gchar *value,
gpointer data) gpointer data)
{ {
gchar *escaped = g_strescape (value, NULL); GimpConfigWriter *writer = data;
gchar *escaped;
g_string_append_printf ((GString *) data, "(%s \"%s\")\n", key, escaped); escaped = g_strescape (value, NULL);
gimp_config_writer_open (writer, key);
gimp_config_writer_printf (writer, "\"%s\"", escaped);
gimp_config_writer_close (writer);
g_free (escaped); g_free (escaped);
} }

View File

@ -24,27 +24,24 @@
gboolean gimp_config_serialize_properties (GObject *object, gboolean gimp_config_serialize_properties (GObject *object,
gint fd, GimpConfigWriter *writer);
gint indent_level);
gboolean gimp_config_serialize_changed_properties (GObject *object, gboolean gimp_config_serialize_changed_properties (GObject *object,
gint fd, GimpConfigWriter *writer);
gint indent_level);
gboolean gimp_config_serialize_properties_diff (GObject *object, gboolean gimp_config_serialize_properties_diff (GObject *object,
GObject *compare, GObject *compare,
gint fd, GimpConfigWriter *writer);
gint indent_level);
gboolean gimp_config_serialize_unknown_tokens (GObject *object, gboolean gimp_config_serialize_unknown_tokens (GObject *object,
gint fd, GimpConfigWriter *writer);
gint indent_level);
gboolean gimp_config_serialize_property (GObject *object, gboolean gimp_config_serialize_property (GObject *object,
GParamSpec *param_spec, GParamSpec *param_spec,
gint fd, GimpConfigWriter *writer);
gint indent_level);
gboolean gimp_config_serialize_value (const GValue *value, gboolean gimp_config_serialize_value (const GValue *value,
GString *str, GString *str,
gboolean escaped); gboolean escaped);
void gimp_config_serialize_comment (GString *str, void gimp_config_serialize_comment (GString *str,
const gchar *comment); const gchar *comment);
#endif /* __GIMP_CONFIG_SERIALIZE_H__ */ #endif /* __GIMP_CONFIG_SERIALIZE_H__ */

View File

@ -27,6 +27,8 @@
#include "libgimpbase/gimpenv.h" #include "libgimpbase/gimpenv.h"
#include "config-types.h"
#include "gimpconfig.h" #include "gimpconfig.h"
#include "gimpconfig-utils.h" #include "gimpconfig-utils.h"

View File

@ -21,28 +21,19 @@
#include "config.h" #include "config.h"
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h> #include <string.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <sys/stat.h>
#include <sys/types.h>
#include <glib-object.h> #include <glib-object.h>
#ifdef G_OS_WIN32
#include <io.h>
#endif
#include "libgimpcolor/gimpcolor.h" #include "libgimpcolor/gimpcolor.h"
#include "config-types.h"
#include "gimpconfig.h" #include "gimpconfig.h"
#include "gimpconfig-serialize.h" #include "gimpconfig-serialize.h"
#include "gimpconfig-deserialize.h" #include "gimpconfig-deserialize.h"
#include "gimpconfig-utils.h" #include "gimpconfig-utils.h"
#include "gimpconfigwriter.h"
#include "gimpscanner.h" #include "gimpscanner.h"
#include "libgimp/gimpintl.h" #include "libgimp/gimpintl.h"
@ -55,8 +46,7 @@
static void gimp_config_iface_init (GimpConfigInterface *gimp_config_iface); static void gimp_config_iface_init (GimpConfigInterface *gimp_config_iface);
static gboolean gimp_config_iface_serialize (GObject *object, static gboolean gimp_config_iface_serialize (GObject *object,
gint fd, GimpConfigWriter *writer,
gint indent_level,
gpointer data); gpointer data);
static gboolean gimp_config_iface_deserialize (GObject *object, static gboolean gimp_config_iface_deserialize (GObject *object,
GScanner *scanner, GScanner *scanner,
@ -107,11 +97,10 @@ gimp_config_iface_init (GimpConfigInterface *gimp_config_iface)
static gboolean static gboolean
gimp_config_iface_serialize (GObject *object, gimp_config_iface_serialize (GObject *object,
gint fd, GimpConfigWriter *writer,
gint indent_level,
gpointer data) gpointer data)
{ {
return gimp_config_serialize_properties (object, fd, indent_level); return gimp_config_serialize_properties (object, writer);
} }
static gboolean static gboolean
@ -185,8 +174,8 @@ gimp_config_iface_reset (GObject *object)
* gimp_config_serialize: * gimp_config_serialize:
* @object: a #GObject that implements the #GimpConfigInterface. * @object: a #GObject that implements the #GimpConfigInterface.
* @filename: the name of the file to write the configuration to. * @filename: the name of the file to write the configuration to.
* @header: optional file header (should be a comment) * @header: optional file header (must be ASCII only)
* @footer: optional file footer (should be a comment) * @footer: optional file footer (must be ASCII only)
* @data: user data passed to the serialize implementation. * @data: user data passed to the serialize implementation.
* @error: * @error:
* *
@ -206,9 +195,7 @@ gimp_config_serialize (GObject *object,
GError **error) GError **error)
{ {
GimpConfigInterface *gimp_config_iface; GimpConfigInterface *gimp_config_iface;
gboolean success = TRUE; GimpConfigWriter *writer;
gchar *tmpname;
gint fd;
g_return_val_if_fail (G_IS_OBJECT (object), FALSE); g_return_val_if_fail (G_IS_OBJECT (object), FALSE);
g_return_val_if_fail (filename != NULL, FALSE); g_return_val_if_fail (filename != NULL, FALSE);
@ -218,78 +205,14 @@ gimp_config_serialize (GObject *object,
g_return_val_if_fail (gimp_config_iface != NULL, FALSE); g_return_val_if_fail (gimp_config_iface != NULL, FALSE);
tmpname = g_strconcat (filename, "XXXXXX", NULL); writer = gimp_config_writer_new (filename, TRUE, header, error);
fd = g_mkstemp (tmpname); if (!writer)
if (fd == -1)
{
g_set_error (error,
GIMP_CONFIG_ERROR, GIMP_CONFIG_ERROR_WRITE,
_("Failed to create temporary file for '%s': %s"),
filename, g_strerror (errno));
g_free (tmpname);
return FALSE; return FALSE;
}
if (header) gimp_config_iface->serialize (object, writer, data);
success = (write (fd, header, strlen (header)) != -1 &&
write (fd, "\n", 1) != -1);
if (success) return gimp_config_writer_finish (writer, footer, error);
success = gimp_config_iface->serialize (object, fd, 0, data);
if (success && footer)
success = (write (fd, "\n", 1) != -1 &&
write (fd, footer, strlen (footer)) != -1 &&
write (fd, "\n", 1) != -1);
if (close (fd) != 0)
success = FALSE;
if (! success)
{
gchar *msg;
if (g_file_test (filename, G_FILE_TEST_EXISTS))
{
msg = g_strdup_printf (_("Error when writing to temporary file for '%s': %s\n"
"The original file has not been touched."),
filename, g_strerror (errno));
}
else
{
msg = g_strdup_printf (_("Error when writing to temporary file for '%s': %s\n"
"No file has been created."),
filename, g_strerror (errno));
}
g_set_error (error, GIMP_CONFIG_ERROR, GIMP_CONFIG_ERROR_WRITE, msg);
unlink (tmpname);
}
#ifdef G_OS_WIN32
/* win32 rename can't overwrite */
if (success)
unlink (filename);
#endif
if (success && rename (tmpname, filename) == -1)
{
g_set_error (error,
GIMP_CONFIG_ERROR, GIMP_CONFIG_ERROR_WRITE,
_("Failed to create file '%s': %s"),
filename, g_strerror (errno));
unlink (tmpname);
success = FALSE;
}
g_free (tmpname);
return success;
} }
/** /**

View File

@ -41,8 +41,7 @@ struct _GimpConfigInterface
GTypeInterface base_iface; GTypeInterface base_iface;
gboolean (* serialize) (GObject *object, gboolean (* serialize) (GObject *object,
gint fd, GimpConfigWriter *writer,
gint indent_level,
gpointer data); gpointer data);
gboolean (* deserialize) (GObject *object, gboolean (* deserialize) (GObject *object,
GScanner *scanner, GScanner *scanner,
@ -52,7 +51,7 @@ struct _GimpConfigInterface
guint property_id, guint property_id,
const GValue *value, const GValue *value,
GParamSpec *pspec, GParamSpec *pspec,
GString *string); GimpConfigWriter *writer);
gboolean (* deserialize_property) (GObject *object, gboolean (* deserialize_property) (GObject *object,
guint property_id, guint property_id,
GValue *value, GValue *value,

View File

@ -0,0 +1,374 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* GimpConfigWriter
* Copyright (C) 2003 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 <errno.h>
#include <fcntl.h>
#include <stdio.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <glib-object.h>
#ifdef G_OS_WIN32
#include <io.h>
#endif
#include "config-types.h"
#include "gimpconfig.h"
#include "gimpconfig-serialize.h"
#include "gimpconfigwriter.h"
#include "libgimp/gimpintl.h"
static gboolean gimp_config_writer_close_file (GimpConfigWriter *writer,
GError **error);
GimpConfigWriter *
gimp_config_writer_new (const gchar *filename,
gboolean safe,
const gchar *header,
GError **error)
{
GimpConfigWriter *writer;
gchar *tmpname = NULL;
gint fd;
g_return_val_if_fail (filename != NULL, NULL);
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
if (safe)
{
tmpname = g_strconcat (filename, "XXXXXX", NULL);
fd = g_mkstemp (tmpname);
if (fd == -1)
{
g_set_error (error,
GIMP_CONFIG_ERROR, GIMP_CONFIG_ERROR_WRITE,
_("Failed to create temporary file for '%s': %s"),
filename, g_strerror (errno));
g_free (tmpname);
return NULL;
}
}
else
{
fd = open (filename, O_WRONLY);
if (fd == -1)
{
g_set_error (error,
GIMP_CONFIG_ERROR, GIMP_CONFIG_ERROR_WRITE,
_("Failed to open '%s' for writing: %s"),
filename, g_strerror (errno));
return NULL;
}
}
writer = g_new0 (GimpConfigWriter, 1);
writer->fd = fd;
writer->filename = g_strdup (filename);
writer->tmpname = tmpname;
writer->buffer = g_string_new (NULL);
if (header)
{
gimp_config_writer_comment (writer, header);
gimp_config_writer_linefeed (writer);
}
return writer;
}
GimpConfigWriter *
gimp_config_writer_new_from_fd (gint fd)
{
GimpConfigWriter *writer;
g_return_val_if_fail (fd > 0, NULL);
writer = g_new0 (GimpConfigWriter, 1);
writer->fd = fd;
writer->buffer = g_string_new (NULL);
return writer;
}
void
gimp_config_writer_open (GimpConfigWriter *writer,
const gchar *name)
{
g_return_if_fail (writer != NULL);
if (writer->error)
return;
/* store the current buffer length so we can revert to this state */
writer->marker = writer->buffer->len;
if (writer->depth > 0)
{
g_string_append_c (writer->buffer, '\n');
gimp_config_string_indent (writer->buffer, writer->depth);
}
writer->depth++;
g_string_append_printf (writer->buffer, "(%s", name);
}
void
gimp_config_writer_print (GimpConfigWriter *writer,
const gchar *string,
gint len)
{
g_return_if_fail (writer != NULL);
g_return_if_fail (len == 0 || string != NULL);
if (writer->error)
return;
if (len < 0)
len = strlen (string);
g_string_append_c (writer->buffer, ' ');
g_string_append_len (writer->buffer, string, len);
}
void
gimp_config_writer_printf (GimpConfigWriter *writer,
const gchar *format,
...)
{
gchar *buffer;
va_list args;
g_return_if_fail (writer != NULL);
g_return_if_fail (format != NULL);
if (writer->error)
return;
g_string_append_c (writer->buffer, ' ');
va_start (args, format);
buffer = g_strdup_vprintf (format, args);
va_end (args);
g_string_append (writer->buffer, buffer);
g_free (buffer);
}
void
gimp_config_writer_revert (GimpConfigWriter *writer)
{
g_return_if_fail (writer != NULL);
g_return_if_fail (writer->depth > 0);
if (writer->error)
return;
g_string_truncate (writer->buffer, writer->marker);
writer->depth--;
}
void
gimp_config_writer_close (GimpConfigWriter *writer)
{
g_return_if_fail (writer != NULL);
g_return_if_fail (writer->depth > 0);
if (writer->error)
return;
g_string_append_c (writer->buffer, ')');
if (--writer->depth == 0)
{
g_string_append_c (writer->buffer, '\n');
if (write (writer->fd, writer->buffer->str, writer->buffer->len) < 0)
g_set_error (&writer->error, GIMP_CONFIG_ERROR, GIMP_CONFIG_ERROR_WRITE,
g_strerror (errno));
g_string_truncate (writer->buffer, 0);
}
}
gboolean
gimp_config_writer_finish (GimpConfigWriter *writer,
const gchar *footer,
GError **error)
{
gboolean success = TRUE;
g_return_val_if_fail (writer != NULL, FALSE);
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
if (writer->depth < 0)
{
g_warning ("gimp_config_writer_finish: depth < 0 !!");
}
else
{
while (writer->depth)
gimp_config_writer_close (writer);
}
if (footer)
{
gimp_config_writer_linefeed (writer);
gimp_config_writer_comment (writer, footer);
}
success = gimp_config_writer_close_file (writer, error);
g_free (writer->filename);
g_free (writer->tmpname);
g_string_free (writer->buffer, TRUE);
g_free (writer);
return success;
}
void
gimp_config_writer_linefeed (GimpConfigWriter *writer)
{
g_return_if_fail (writer != NULL);
g_return_if_fail (writer->depth == 0);
g_return_if_fail (writer->buffer->len == 0);
if (writer->error)
return;
if (write (writer->fd, "\n", 1) < 0)
g_set_error (&writer->error, GIMP_CONFIG_ERROR, GIMP_CONFIG_ERROR_WRITE,
g_strerror (errno));
}
void
gimp_config_writer_comment (GimpConfigWriter *writer,
const gchar *comment)
{
g_return_if_fail (writer != NULL);
g_return_if_fail (writer->depth == 0);
g_return_if_fail (writer->buffer->len == 0);
if (writer->error)
return;
if (!comment)
return;
gimp_config_serialize_comment (writer->buffer, comment);
if (write (writer->fd, writer->buffer->str, writer->buffer->len) < 0)
g_set_error (&writer->error, GIMP_CONFIG_ERROR, GIMP_CONFIG_ERROR_WRITE,
g_strerror (errno));
g_string_truncate (writer->buffer, 0);
}
static gboolean
gimp_config_writer_close_file (GimpConfigWriter *writer,
GError **error)
{
if (! writer->filename)
return TRUE;
if (writer->error)
{
close (writer->fd);
if (writer->tmpname)
unlink (writer->tmpname);
return TRUE;
}
if (close (writer->fd) != 0)
{
if (writer->tmpname)
{
if (g_file_test (writer->filename, G_FILE_TEST_EXISTS))
{
g_set_error (error, GIMP_CONFIG_ERROR, GIMP_CONFIG_ERROR_WRITE,
_("Error writing to temporary file for '%s': %s\n"
"The original file has not been touched."),
writer->filename, g_strerror (errno));
}
else
{
g_set_error (error, GIMP_CONFIG_ERROR, GIMP_CONFIG_ERROR_WRITE,
_("Error writing to temporary file for '%s': %s\n"
"No file has been created."),
writer->filename, g_strerror (errno));
}
unlink (writer->tmpname);
}
else
{
g_set_error (error, GIMP_CONFIG_ERROR, GIMP_CONFIG_ERROR_WRITE,
_("Error writing to '%s': %s"),
writer->filename, g_strerror (errno));
}
return FALSE;
}
if (writer->tmpname)
{
#ifdef G_OS_WIN32
/* win32 rename can't overwrite */
unlink (writer->filename);
#endif
if (rename (writer->tmpname, writer->filename) == -1)
{
g_set_error (error,
GIMP_CONFIG_ERROR, GIMP_CONFIG_ERROR_WRITE,
_("Failed to create file '%s': %s"),
writer->filename, g_strerror (errno));
unlink (writer->tmpname);
return FALSE;
}
}
return TRUE;
}

View File

@ -0,0 +1,65 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* GimpConfigWriter
* Copyright (C) 2003 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_CONFIG_WRITER_H__
#define __GIMP_CONFIG_WRITER_H__
struct _GimpConfigWriter
{
/*< private >*/
gint fd;
gchar *filename;
gchar *tmpname;
GError *error;
GString *buffer;
gint depth;
gint marker;
};
GimpConfigWriter * gimp_config_writer_new (const gchar *filename,
gboolean safe,
const gchar *header,
GError **error);
GimpConfigWriter * gimp_config_writer_new_from_fd (gint fd);
void gimp_config_writer_open (GimpConfigWriter *writer,
const gchar *name);
void gimp_config_writer_print (GimpConfigWriter *writer,
const gchar *string,
gint len);
void gimp_config_writer_printf (GimpConfigWriter *writer,
const gchar *format,
...);
void gimp_config_writer_revert (GimpConfigWriter *writer);
void gimp_config_writer_close (GimpConfigWriter *writer);
void gimp_config_writer_linefeed (GimpConfigWriter *writer);
void gimp_config_writer_comment (GimpConfigWriter *writer,
const gchar *comment);
gboolean gimp_config_writer_finish (GimpConfigWriter *writer,
const gchar *footer,
GError **error);
#endif /* __GIMP_CONFIG_WRITER_H__ */

View File

@ -72,8 +72,7 @@ static void gimp_rc_get_property (GObject *object,
GValue *value, GValue *value,
GParamSpec *pspec); GParamSpec *pspec);
static gboolean gimp_rc_serialize (GObject *object, static gboolean gimp_rc_serialize (GObject *object,
gint fd, GimpConfigWriter *writer,
gint indent_level,
gpointer data); gpointer data);
static gboolean gimp_rc_deserialize (GObject *object, static gboolean gimp_rc_deserialize (GObject *object,
GScanner *scanner, GScanner *scanner,
@ -283,26 +282,21 @@ gimp_rc_config_iface_init (gpointer iface,
static gboolean static gboolean
gimp_rc_serialize (GObject *object, gimp_rc_serialize (GObject *object,
gint fd, GimpConfigWriter *writer,
gint indent_level,
gpointer data) gpointer data)
{ {
if (data && GIMP_IS_RC (data)) if (data && GIMP_IS_RC (data))
{ {
if (!gimp_config_serialize_properties_diff (object, G_OBJECT (data), if (!gimp_config_serialize_properties_diff (object, G_OBJECT (data), writer))
fd, indent_level))
return FALSE; return FALSE;
} }
else else
{ {
if (!gimp_config_serialize_properties (object, fd, indent_level)) if (!gimp_config_serialize_properties (object, writer))
return FALSE; return FALSE;
} }
if (write (fd, "\n", 1) < 0) return gimp_config_serialize_unknown_tokens (object, writer);
return FALSE;
return gimp_config_serialize_unknown_tokens (object, fd, indent_level);
} }
static gboolean static gboolean
@ -558,17 +552,16 @@ gimp_rc_save (GimpRc *rc)
GError *error = NULL; GError *error = NULL;
const gchar *top = const gchar *top =
"# GIMP gimprc\n" "GIMP gimprc\n"
"#\n" "\n"
"# This is your personal gimprc file. Any variable defined in this file\n" "This is your personal gimprc file. Any variable defined in this file "
"# takes precedence over the value defined in the system-wide gimprc:\n" "takes precedence over the value defined in the system-wide gimprc: ";
"# ";
const gchar *bottom = const gchar *bottom =
"\n" "\n"
"# Most values can be set within The GIMP by changing some options in\n" "Most values can be set within The GIMP by changing some options in "
"# the Preferences dialog.\n"; "the Preferences dialog.";
const gchar *footer = const gchar *footer =
"# end of gimprc\n"; "end of gimprc";
g_return_if_fail (GIMP_IS_RC (rc)); g_return_if_fail (GIMP_IS_RC (rc));

View File

@ -39,6 +39,8 @@
#include "libgimpcolor/gimpcolor.h" #include "libgimpcolor/gimpcolor.h"
#include "config-types.h"
#include "gimpconfig.h" #include "gimpconfig.h"
#include "gimpscanner.h" #include "gimpscanner.h"

View File

@ -84,8 +84,8 @@ main (int argc,
if (! gimp_config_serialize (G_OBJECT (gimprc), if (! gimp_config_serialize (G_OBJECT (gimprc),
filename, filename,
"# foorc\n", "foorc",
"# end of foorc\n", "end of foorc",
NULL, &error)) NULL, &error))
{ {
g_print ("%s\n", error->message); g_print ("%s\n", error->message);

View File

@ -62,11 +62,11 @@ void
gimp_documents_save (Gimp *gimp) gimp_documents_save (Gimp *gimp)
{ {
const gchar *header = const gchar *header =
"# GIMP documents\n" "GIMP documents\n"
"#\n" "\n"
"# This file will be entirely rewritten every time you quit the gimp.\n"; "This file will be entirely rewritten every time you quit the gimp.";
const gchar *footer = const gchar *footer =
"# end of documents\n"; "end of documents";
gchar *filename; gchar *filename;
GError *error = NULL; GError *error = NULL;

View File

@ -115,11 +115,11 @@ void
gimp_parasiterc_save (Gimp *gimp) gimp_parasiterc_save (Gimp *gimp)
{ {
const gchar *header = const gchar *header =
"# GIMP parasiterc\n" "GIMP parasiterc\n"
"#\n" "\n"
"# This file will be entirely rewritten every time you quit the gimp.\n"; "This file will be entirely rewritten every time you quit the gimp.";
const gchar *footer = const gchar *footer =
"# end of parasiterc"; "end of parasiterc";
gchar *filename; gchar *filename;
GError *error = NULL; GError *error = NULL;

View File

@ -40,6 +40,7 @@
#include "config/gimpconfig.h" #include "config/gimpconfig.h"
#include "config/gimpconfig-deserialize.h" #include "config/gimpconfig-deserialize.h"
#include "config/gimpconfigwriter.h"
#include "config/gimpscanner.h" #include "config/gimpscanner.h"
@ -100,8 +101,7 @@ static void gimp_container_get_property (GObject *object,
static gsize gimp_container_get_memsize (GimpObject *object); static gsize gimp_container_get_memsize (GimpObject *object);
static gboolean gimp_container_serialize (GObject *object, static gboolean gimp_container_serialize (GObject *object,
gint fd, GimpConfigWriter *writer,
gint indent_level,
gpointer data); gpointer data);
static gboolean gimp_container_deserialize (GObject *object, static gboolean gimp_container_deserialize (GObject *object,
GScanner *scanner, GScanner *scanner,
@ -384,8 +384,7 @@ gimp_container_get_memsize (GimpObject *object)
typedef struct typedef struct
{ {
gint fd; GimpConfigWriter *writer;
gint indent_level;
gpointer data; gpointer data;
gboolean success; gboolean success;
} SerializeData; } SerializeData;
@ -395,7 +394,6 @@ gimp_container_serialize_foreach (GObject *object,
SerializeData *serialize_data) SerializeData *serialize_data)
{ {
GimpConfigInterface *config_iface; GimpConfigInterface *config_iface;
GString *str;
const gchar *name; const gchar *name;
config_iface = GIMP_GET_CONFIG_INTERFACE (object); config_iface = GIMP_GET_CONFIG_INTERFACE (object);
@ -406,11 +404,7 @@ gimp_container_serialize_foreach (GObject *object,
if (! serialize_data->success) if (! serialize_data->success)
return; return;
str = g_string_new (NULL); gimp_config_writer_open (serialize_data->writer,
gimp_config_string_indent (str, serialize_data->indent_level);
g_string_append_printf (str, "(%s ",
g_type_name (G_TYPE_FROM_INSTANCE (object))); g_type_name (G_TYPE_FROM_INSTANCE (object)));
name = gimp_object_get_name (GIMP_OBJECT (object)); name = gimp_object_get_name (GIMP_OBJECT (object));
@ -420,41 +414,23 @@ gimp_container_serialize_foreach (GObject *object,
gchar *escaped; gchar *escaped;
escaped = g_strescape (name, NULL); escaped = g_strescape (name, NULL);
g_string_append_printf (str, "\"%s\"\n", escaped); gimp_config_writer_printf (serialize_data->writer, "\"%s\"", escaped);
g_free (escaped); g_free (escaped);
} }
else else
{ {
g_string_append_printf (str, "NULL\n"); gimp_config_writer_print (serialize_data->writer, "NULL", 4);
}
if (write (serialize_data->fd, str->str, str->len) == -1)
{
serialize_data->success = FALSE;
return;
} }
serialize_data->success = config_iface->serialize (object, serialize_data->success = config_iface->serialize (object,
serialize_data->fd, serialize_data->writer,
serialize_data->indent_level + 1,
serialize_data->data); serialize_data->data);
gimp_config_writer_close (serialize_data->writer);
if (! serialize_data->success)
return;
if (serialize_data->indent_level > 0)
g_string_assign (str, ")");
else
g_string_assign (str, ")\n");
if (write (serialize_data->fd, str->str, str->len) == -1)
serialize_data->success = FALSE;
} }
static gboolean static gboolean
gimp_container_serialize (GObject *object, gimp_container_serialize (GObject *object,
gint fd, GimpConfigWriter *writer,
gint indent_level,
gpointer data) gpointer data)
{ {
GimpContainer *container; GimpContainer *container;
@ -462,8 +438,7 @@ gimp_container_serialize (GObject *object,
container = GIMP_CONTAINER (object); container = GIMP_CONTAINER (object);
serialize_data.fd = fd; serialize_data.writer = writer;
serialize_data.indent_level = indent_level;
serialize_data.data = data; serialize_data.data = data;
serialize_data.success = TRUE; serialize_data.success = TRUE;

View File

@ -51,6 +51,7 @@
#include "config/gimpconfig.h" #include "config/gimpconfig.h"
#include "config/gimpconfig-types.h" #include "config/gimpconfig-types.h"
#include "config/gimpconfig-params.h" #include "config/gimpconfig-params.h"
#include "config/gimpconfigwriter.h"
#include "config/gimpscanner.h" #include "config/gimpscanner.h"
#include "libgimp/gimpintl.h" #include "libgimp/gimpintl.h"
@ -87,14 +88,13 @@ static void gimp_context_get_property (GObject *object,
static gsize gimp_context_get_memsize (GimpObject *object); static gsize gimp_context_get_memsize (GimpObject *object);
static gboolean gimp_context_serialize (GObject *object, static gboolean gimp_context_serialize (GObject *object,
gint fd, GimpConfigWriter *writer,
gint indent_level,
gpointer data); gpointer data);
static gboolean gimp_context_serialize_property (GObject *object, static gboolean gimp_context_serialize_property (GObject *object,
guint property_id, guint property_id,
const GValue *value, const GValue *value,
GParamSpec *pspec, GParamSpec *pspec,
GString *string); GimpConfigWriter *writer);
static gboolean gimp_context_deserialize_property (GObject *object, static gboolean gimp_context_deserialize_property (GObject *object,
guint property_id, guint property_id,
GValue *value, GValue *value,
@ -979,11 +979,10 @@ gimp_context_get_memsize (GimpObject *object)
static gboolean static gboolean
gimp_context_serialize (GObject *object, gimp_context_serialize (GObject *object,
gint fd, GimpConfigWriter *writer,
gint indent_level,
gpointer data) gpointer data)
{ {
return gimp_config_serialize_changed_properties (object, fd, indent_level); return gimp_config_serialize_changed_properties (object, writer);
} }
static gboolean static gboolean
@ -991,7 +990,7 @@ gimp_context_serialize_property (GObject *object,
guint property_id, guint property_id,
const GValue *value, const GValue *value,
GParamSpec *pspec, GParamSpec *pspec,
GString *string) GimpConfigWriter *writer)
{ {
GimpContext *context; GimpContext *context;
GimpObject *serialize_obj; GimpObject *serialize_obj;
@ -1023,12 +1022,12 @@ gimp_context_serialize_property (GObject *object,
gchar *escaped; gchar *escaped;
escaped = g_strescape (gimp_object_get_name (serialize_obj), NULL); escaped = g_strescape (gimp_object_get_name (serialize_obj), NULL);
g_string_append_printf (string, "\"%s\"", escaped); gimp_config_writer_printf (writer, "\"%s\"", escaped);
g_free (escaped); g_free (escaped);
} }
else else
{ {
g_string_append_printf (string, "NULL"); gimp_config_writer_print (writer, "NULL", 4);
} }
return TRUE; return TRUE;

View File

@ -32,6 +32,7 @@
#include "core-types.h" #include "core-types.h"
#include "config/gimpconfig.h" #include "config/gimpconfig.h"
#include "config/gimpconfigwriter.h"
#include "config/gimpscanner.h" #include "config/gimpscanner.h"
#include "gimp.h" #include "gimp.h"
@ -42,8 +43,7 @@
static void gimp_document_list_config_iface_init (gpointer iface, static void gimp_document_list_config_iface_init (gpointer iface,
gpointer iface_data); gpointer iface_data);
static gboolean gimp_document_list_serialize (GObject *object, static gboolean gimp_document_list_serialize (GObject *object,
gint fd, GimpConfigWriter *writer,
gint indent_level,
gpointer data); gpointer data);
static gboolean gimp_document_list_deserialize (GObject *object, static gboolean gimp_document_list_deserialize (GObject *object,
GScanner *scanner, GScanner *scanner,
@ -104,29 +104,24 @@ gimp_document_list_config_iface_init (gpointer iface,
static gboolean static gboolean
gimp_document_list_serialize (GObject *object, gimp_document_list_serialize (GObject *object,
gint fd, GimpConfigWriter *writer,
gint indent_level,
gpointer data) gpointer data)
{ {
GList *list; GList *list;
GString *str;
str = g_string_new (NULL);
for (list = GIMP_LIST (object)->list; list; list = list->next) for (list = GIMP_LIST (object)->list; list; list = list->next)
{ {
gchar *escaped; gchar *escaped;
gimp_config_writer_open (writer, document_symbol);
escaped = g_strescape (GIMP_OBJECT (list->data)->name, NULL); escaped = g_strescape (GIMP_OBJECT (list->data)->name, NULL);
g_string_printf (str, "(%s \"%s\")\n", document_symbol, escaped); gimp_config_writer_printf (writer, "\"%s\"", escaped);
g_free (escaped); g_free (escaped);
if (write (fd, str->str, str->len) == -1) gimp_config_writer_close (writer);
return FALSE;
} }
g_string_free (str, TRUE);
return TRUE; return TRUE;
} }

View File

@ -143,11 +143,7 @@ gimp_item_init (GimpItem *item)
static void static void
gimp_item_finalize (GObject *object) gimp_item_finalize (GObject *object)
{ {
GimpItem *item; GimpItem *item = GIMP_ITEM (object);
g_return_if_fail (GIMP_IS_ITEM (object));
item = GIMP_ITEM (object);
if (item->gimage && item->gimage->gimp) if (item->gimage && item->gimage->gimp)
{ {

View File

@ -33,6 +33,7 @@
#include "core-types.h" #include "core-types.h"
#include "config/gimpconfig.h" #include "config/gimpconfig.h"
#include "config/gimpconfigwriter.h"
#include "config/gimpscanner.h" #include "config/gimpscanner.h"
#include "gimpmarshal.h" #include "gimpmarshal.h"
@ -55,8 +56,7 @@ static gsize gimp_parasite_list_get_memsize (GimpObject *object);
static void gimp_parasite_list_config_iface_init (gpointer iface, static void gimp_parasite_list_config_iface_init (gpointer iface,
gpointer iface_data); gpointer iface_data);
static gboolean gimp_parasite_list_serialize (GObject *list, static gboolean gimp_parasite_list_serialize (GObject *list,
gint fd, GimpConfigWriter *writer,
gint indent_level,
gpointer data); gpointer data);
static gboolean gimp_parasite_list_deserialize (GObject *list, static gboolean gimp_parasite_list_deserialize (GObject *list,
GScanner *scanner, GScanner *scanner,
@ -65,7 +65,7 @@ static gboolean gimp_parasite_list_deserialize (GObject *list,
static void parasite_serialize (const gchar *key, static void parasite_serialize (const gchar *key,
GimpParasite *parasite, GimpParasite *parasite,
gint *fd_ptr); GimpConfigWriter *writer);
static void parasite_copy (const gchar *key, static void parasite_copy (const gchar *key,
GimpParasite *parasite, GimpParasite *parasite,
GimpParasiteList *list); GimpParasiteList *list);
@ -234,15 +234,15 @@ gimp_parasite_list_get_memsize (GimpObject *object)
static gboolean static gboolean
gimp_parasite_list_serialize (GObject *list, gimp_parasite_list_serialize (GObject *list,
gint fd, GimpConfigWriter *writer,
gint indent_level,
gpointer data) gpointer data)
{ {
if (GIMP_PARASITE_LIST (list)->table) if (GIMP_PARASITE_LIST (list)->table)
g_hash_table_foreach (GIMP_PARASITE_LIST (list)->table, g_hash_table_foreach (GIMP_PARASITE_LIST (list)->table,
(GHFunc) parasite_serialize, &fd); (GHFunc) parasite_serialize,
writer);
return (fd != -1); return TRUE;
} }
static gboolean static gboolean
@ -446,23 +446,20 @@ gimp_parasite_list_find (GimpParasiteList *list,
static void static void
parasite_serialize (const gchar *key, parasite_serialize (const gchar *key,
GimpParasite *parasite, GimpParasite *parasite,
gint *fd_ptr) GimpConfigWriter *writer)
{ {
GString *str; GString *str;
const gchar *data; const gchar *data;
guint32 len; guint32 len;
/* return if write failed earlier */
if (*fd_ptr == -1)
return;
if (! gimp_parasite_is_persistent (parasite)) if (! gimp_parasite_is_persistent (parasite))
return; return;
gimp_config_writer_open (writer, parasite_symbol);
str = g_string_sized_new (64); str = g_string_sized_new (64);
g_string_printf (str, "(%s \"%s\" %lu \"", g_string_printf (str, "\"%s\" %lu \"",
parasite_symbol,
gimp_parasite_name (parasite), gimp_parasite_name (parasite),
gimp_parasite_flags (parasite)); gimp_parasite_flags (parasite));
@ -492,12 +489,12 @@ parasite_serialize (const gchar *key,
} }
} }
g_string_append (str, "\")\n\n"); gimp_config_writer_print (writer, str->str, str->len);
if (write (*fd_ptr, str->str, str->len) == -1)
*fd_ptr = -1;
g_string_free (str, TRUE); g_string_free (str, TRUE);
gimp_config_writer_close (writer);
gimp_config_writer_linefeed (writer);
} }
static void static void

View File

@ -217,8 +217,8 @@ gimp_tool_options_serialize (GimpToolOptions *tool_options,
retval = gimp_config_serialize (G_OBJECT (tool_options), retval = gimp_config_serialize (G_OBJECT (tool_options),
filename, filename,
"# tool options\n", "GIMP tool options",
"# end tool options", "end of tool options",
NULL, NULL,
error); error);

View File

@ -301,8 +301,8 @@ test_serialize_context_cmd_callback (GtkWidget *widget,
if (! gimp_config_serialize (G_OBJECT (gimp_get_user_context (gimp)), if (! gimp_config_serialize (G_OBJECT (gimp_get_user_context (gimp)),
filename, filename,
"# test-context\n", "GIMP test-context",
"# end of test-context\n", "end of test-context",
NULL, NULL,
&error)) &error))
{ {

View File

@ -217,8 +217,8 @@ gimp_tool_options_serialize (GimpToolOptions *tool_options,
retval = gimp_config_serialize (G_OBJECT (tool_options), retval = gimp_config_serialize (G_OBJECT (tool_options),
filename, filename,
"# tool options\n", "GIMP tool options",
"# end tool options", "end of tool options",
NULL, NULL,
error); error);

View File

@ -172,8 +172,8 @@ gimp_devices_save (Gimp *gimp)
if (! gimp_config_serialize (G_OBJECT (manager->device_info_list), if (! gimp_config_serialize (G_OBJECT (manager->device_info_list),
filename, filename,
"# GIMP devicerc\n", "GIMP devicerc",
"# end devicerc", "end of devicerc",
NULL, NULL,
&error)) &error))
{ {

View File

@ -34,6 +34,8 @@
#include "libgimpbase/gimpbase.h" #include "libgimpbase/gimpbase.h"
#include "libgimpcolor/gimpcolor.h" #include "libgimpcolor/gimpcolor.h"
#include "config-types.h"
#include "gimpconfig.h" #include "gimpconfig.h"
#include "gimpconfig-deserialize.h" #include "gimpconfig-deserialize.h"
#include "gimpconfig-params.h" #include "gimpconfig-params.h"

View File

@ -21,28 +21,19 @@
#include "config.h" #include "config.h"
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h> #include <string.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <sys/stat.h>
#include <sys/types.h>
#include <glib-object.h> #include <glib-object.h>
#ifdef G_OS_WIN32
#include <io.h>
#endif
#include "libgimpcolor/gimpcolor.h" #include "libgimpcolor/gimpcolor.h"
#include "config-types.h"
#include "gimpconfig.h" #include "gimpconfig.h"
#include "gimpconfig-serialize.h" #include "gimpconfig-serialize.h"
#include "gimpconfig-deserialize.h" #include "gimpconfig-deserialize.h"
#include "gimpconfig-utils.h" #include "gimpconfig-utils.h"
#include "gimpconfigwriter.h"
#include "gimpscanner.h" #include "gimpscanner.h"
#include "libgimp/gimpintl.h" #include "libgimp/gimpintl.h"
@ -55,8 +46,7 @@
static void gimp_config_iface_init (GimpConfigInterface *gimp_config_iface); static void gimp_config_iface_init (GimpConfigInterface *gimp_config_iface);
static gboolean gimp_config_iface_serialize (GObject *object, static gboolean gimp_config_iface_serialize (GObject *object,
gint fd, GimpConfigWriter *writer,
gint indent_level,
gpointer data); gpointer data);
static gboolean gimp_config_iface_deserialize (GObject *object, static gboolean gimp_config_iface_deserialize (GObject *object,
GScanner *scanner, GScanner *scanner,
@ -107,11 +97,10 @@ gimp_config_iface_init (GimpConfigInterface *gimp_config_iface)
static gboolean static gboolean
gimp_config_iface_serialize (GObject *object, gimp_config_iface_serialize (GObject *object,
gint fd, GimpConfigWriter *writer,
gint indent_level,
gpointer data) gpointer data)
{ {
return gimp_config_serialize_properties (object, fd, indent_level); return gimp_config_serialize_properties (object, writer);
} }
static gboolean static gboolean
@ -185,8 +174,8 @@ gimp_config_iface_reset (GObject *object)
* gimp_config_serialize: * gimp_config_serialize:
* @object: a #GObject that implements the #GimpConfigInterface. * @object: a #GObject that implements the #GimpConfigInterface.
* @filename: the name of the file to write the configuration to. * @filename: the name of the file to write the configuration to.
* @header: optional file header (should be a comment) * @header: optional file header (must be ASCII only)
* @footer: optional file footer (should be a comment) * @footer: optional file footer (must be ASCII only)
* @data: user data passed to the serialize implementation. * @data: user data passed to the serialize implementation.
* @error: * @error:
* *
@ -206,9 +195,7 @@ gimp_config_serialize (GObject *object,
GError **error) GError **error)
{ {
GimpConfigInterface *gimp_config_iface; GimpConfigInterface *gimp_config_iface;
gboolean success = TRUE; GimpConfigWriter *writer;
gchar *tmpname;
gint fd;
g_return_val_if_fail (G_IS_OBJECT (object), FALSE); g_return_val_if_fail (G_IS_OBJECT (object), FALSE);
g_return_val_if_fail (filename != NULL, FALSE); g_return_val_if_fail (filename != NULL, FALSE);
@ -218,78 +205,14 @@ gimp_config_serialize (GObject *object,
g_return_val_if_fail (gimp_config_iface != NULL, FALSE); g_return_val_if_fail (gimp_config_iface != NULL, FALSE);
tmpname = g_strconcat (filename, "XXXXXX", NULL); writer = gimp_config_writer_new (filename, TRUE, header, error);
fd = g_mkstemp (tmpname); if (!writer)
if (fd == -1)
{
g_set_error (error,
GIMP_CONFIG_ERROR, GIMP_CONFIG_ERROR_WRITE,
_("Failed to create temporary file for '%s': %s"),
filename, g_strerror (errno));
g_free (tmpname);
return FALSE; return FALSE;
}
if (header) gimp_config_iface->serialize (object, writer, data);
success = (write (fd, header, strlen (header)) != -1 &&
write (fd, "\n", 1) != -1);
if (success) return gimp_config_writer_finish (writer, footer, error);
success = gimp_config_iface->serialize (object, fd, 0, data);
if (success && footer)
success = (write (fd, "\n", 1) != -1 &&
write (fd, footer, strlen (footer)) != -1 &&
write (fd, "\n", 1) != -1);
if (close (fd) != 0)
success = FALSE;
if (! success)
{
gchar *msg;
if (g_file_test (filename, G_FILE_TEST_EXISTS))
{
msg = g_strdup_printf (_("Error when writing to temporary file for '%s': %s\n"
"The original file has not been touched."),
filename, g_strerror (errno));
}
else
{
msg = g_strdup_printf (_("Error when writing to temporary file for '%s': %s\n"
"No file has been created."),
filename, g_strerror (errno));
}
g_set_error (error, GIMP_CONFIG_ERROR, GIMP_CONFIG_ERROR_WRITE, msg);
unlink (tmpname);
}
#ifdef G_OS_WIN32
/* win32 rename can't overwrite */
if (success)
unlink (filename);
#endif
if (success && rename (tmpname, filename) == -1)
{
g_set_error (error,
GIMP_CONFIG_ERROR, GIMP_CONFIG_ERROR_WRITE,
_("Failed to create file '%s': %s"),
filename, g_strerror (errno));
unlink (tmpname);
success = FALSE;
}
g_free (tmpname);
return success;
} }
/** /**

View File

@ -41,8 +41,7 @@ struct _GimpConfigInterface
GTypeInterface base_iface; GTypeInterface base_iface;
gboolean (* serialize) (GObject *object, gboolean (* serialize) (GObject *object,
gint fd, GimpConfigWriter *writer,
gint indent_level,
gpointer data); gpointer data);
gboolean (* deserialize) (GObject *object, gboolean (* deserialize) (GObject *object,
GScanner *scanner, GScanner *scanner,
@ -52,7 +51,7 @@ struct _GimpConfigInterface
guint property_id, guint property_id,
const GValue *value, const GValue *value,
GParamSpec *pspec, GParamSpec *pspec,
GString *string); GimpConfigWriter *writer);
gboolean (* deserialize_property) (GObject *object, gboolean (* deserialize_property) (GObject *object,
guint property_id, guint property_id,
GValue *value, GValue *value,

View File

@ -36,11 +36,14 @@
#include "libgimpbase/gimpbase.h" #include "libgimpbase/gimpbase.h"
#include "libgimpcolor/gimpcolor.h" #include "libgimpcolor/gimpcolor.h"
#include "config-types.h"
#include "gimpconfig.h" #include "gimpconfig.h"
#include "gimpconfig-params.h" #include "gimpconfig-params.h"
#include "gimpconfig-serialize.h" #include "gimpconfig-serialize.h"
#include "gimpconfig-types.h" #include "gimpconfig-types.h"
#include "gimpconfig-utils.h" #include "gimpconfig-utils.h"
#include "gimpconfigwriter.h"
static void serialize_unknown_token (const gchar *key, static void serialize_unknown_token (const gchar *key,
@ -51,14 +54,13 @@ static void serialize_unknown_token (const gchar *key,
/** /**
* gimp_config_serialize_properties: * gimp_config_serialize_properties:
* @object: a #GObject. * @object: a #GObject.
* @fd: a file descriptor to write to. * @writer: a #GimpConfigWriter.
* *
* This function writes all object properties to the file descriptor @fd. * This function writes all object properties to the @writer.
**/ **/
gboolean gboolean
gimp_config_serialize_properties (GObject *object, gimp_config_serialize_properties (GObject *object,
gint fd, GimpConfigWriter *writer)
gint indent_level)
{ {
GObjectClass *klass; GObjectClass *klass;
GParamSpec **property_specs; GParamSpec **property_specs;
@ -81,8 +83,7 @@ gimp_config_serialize_properties (GObject *object,
if (! (prop_spec->flags & GIMP_PARAM_SERIALIZE)) if (! (prop_spec->flags & GIMP_PARAM_SERIALIZE))
continue; continue;
if (! gimp_config_serialize_property (object, prop_spec, if (! gimp_config_serialize_property (object, prop_spec, writer))
fd, indent_level))
return FALSE; return FALSE;
} }
@ -94,15 +95,14 @@ gimp_config_serialize_properties (GObject *object,
/** /**
* gimp_config_serialize_changed_properties: * gimp_config_serialize_changed_properties:
* @object: a #GObject. * @object: a #GObject.
* @fd: a file descriptor to write to. * @writer: a #GimpConfigWriter.
* *
* This function writes all object properties that have been changed from * This function writes all object properties that have been changed from
* their default values to the file descriptor @fd. * their default values to the @writer.
**/ **/
gboolean gboolean
gimp_config_serialize_changed_properties (GObject *object, gimp_config_serialize_changed_properties (GObject *object,
gint fd, GimpConfigWriter *writer)
gint indent_level)
{ {
GObjectClass *klass; GObjectClass *klass;
GParamSpec **property_specs; GParamSpec **property_specs;
@ -131,8 +131,7 @@ gimp_config_serialize_changed_properties (GObject *object,
if (! g_param_value_defaults (prop_spec, &value)) if (! g_param_value_defaults (prop_spec, &value))
{ {
if (! gimp_config_serialize_property (object, prop_spec, if (! gimp_config_serialize_property (object, prop_spec, writer))
fd, indent_level))
return FALSE; return FALSE;
} }
@ -148,17 +147,16 @@ gimp_config_serialize_changed_properties (GObject *object,
* gimp_config_serialize_properties_diff: * gimp_config_serialize_properties_diff:
* @object: a #GObject. * @object: a #GObject.
* @compare: a #GObject of the same type as @object. * @compare: a #GObject of the same type as @object.
* @fd: a file descriptor to write to. * @writer: a #GimpConfigWriter.
* *
* This function compares @object and @compare and writes all * This function compares @object and @compare and writes all
* properties of @object that have different values than @compare to * properties of @object that have different values than @compare to
* the file descriptor @fd. * the @writer.
**/ **/
gboolean gboolean
gimp_config_serialize_properties_diff (GObject *object, gimp_config_serialize_properties_diff (GObject *object,
GObject *compare, GObject *compare,
gint fd, GimpConfigWriter *writer)
gint indent_level)
{ {
GObjectClass *klass; GObjectClass *klass;
GList *diff; GList *diff;
@ -183,8 +181,7 @@ gimp_config_serialize_properties_diff (GObject *object,
if (! (prop_spec->flags & GIMP_PARAM_SERIALIZE)) if (! (prop_spec->flags & GIMP_PARAM_SERIALIZE))
continue; continue;
if (! gimp_config_serialize_property (object, prop_spec, if (! gimp_config_serialize_property (object, prop_spec, writer))
fd, indent_level))
return FALSE; return FALSE;
} }
@ -197,22 +194,18 @@ gimp_config_serialize_properties_diff (GObject *object,
gboolean gboolean
gimp_config_serialize_property (GObject *object, gimp_config_serialize_property (GObject *object,
GParamSpec *param_spec, GParamSpec *param_spec,
gint fd, GimpConfigWriter *writer)
gint indent_level)
{ {
GTypeClass *owner_class; GTypeClass *owner_class;
GimpConfigInterface *config_iface; GimpConfigInterface *config_iface;
GimpConfigInterface *parent_iface = NULL; GimpConfigInterface *parent_iface = NULL;
GString *str;
GValue value = { 0, }; GValue value = { 0, };
gboolean success = FALSE; gboolean success = FALSE;
if (! (param_spec->flags & GIMP_PARAM_SERIALIZE)) if (! (param_spec->flags & GIMP_PARAM_SERIALIZE))
return FALSE; return FALSE;
str = g_string_new (NULL); gimp_config_writer_open (writer, param_spec->name);
gimp_config_string_indent (str, indent_level);
g_string_append_printf (str, "(%s ", param_spec->name);
g_value_init (&value, param_spec->value_type); g_value_init (&value, param_spec->value_type);
g_object_get_property (object, param_spec->name, &value); g_object_get_property (object, param_spec->name, &value);
@ -249,7 +242,7 @@ gimp_config_serialize_property (GObject *object,
param_spec->param_id, param_spec->param_id,
(const GValue *) &value, (const GValue *) &value,
param_spec, param_spec,
str)) writer))
{ {
success = TRUE; success = TRUE;
} }
@ -273,48 +266,45 @@ gimp_config_serialize_property (GObject *object,
success = TRUE; success = TRUE;
if (gimp_config_iface) if (gimp_config_iface)
{ success = gimp_config_iface->serialize (prop_object, writer, NULL);
g_string_append_c (str, '\n');
write (fd, str->str, str->len);
g_string_truncate (str, 0);
success = gimp_config_iface->serialize (prop_object,
fd, indent_level + 1,
NULL);
success = TRUE;
}
} }
else else
{ {
GString *str = g_string_new (NULL);
success = gimp_config_serialize_value (&value, str, TRUE); success = gimp_config_serialize_value (&value, str, TRUE);
if (success)
gimp_config_writer_print (writer, str->str, str->len);
g_string_free (str, TRUE);
} }
} }
if (success) if (success)
{ {
g_string_append (str, ")\n"); gimp_config_writer_close (writer);
if (write (fd, str->str, str->len) == -1)
success = FALSE;
} }
else
if (! success)
{ {
gimp_config_writer_revert (writer);
/* don't warn for empty string properties */ /* don't warn for empty string properties */
if (G_VALUE_HOLDS_STRING (&value)) if (G_VALUE_HOLDS_STRING (&value))
{
success = TRUE; success = TRUE;
}
else else
{
g_warning ("couldn't serialize property %s::%s of type %s", g_warning ("couldn't serialize property %s::%s of type %s",
g_type_name (G_TYPE_FROM_INSTANCE (object)), g_type_name (G_TYPE_FROM_INSTANCE (object)),
param_spec->name, param_spec->name,
g_type_name (param_spec->value_type)); g_type_name (param_spec->value_type));
} }
}
g_value_unset (&value); g_value_unset (&value);
g_string_free (str, TRUE);
return success; return success;
} }
@ -467,25 +457,21 @@ gimp_config_serialize_value (const GValue *value,
/** /**
* gimp_config_serialize_unknown_tokens: * gimp_config_serialize_unknown_tokens:
* @object: a #GObject. * @object: a #GObject.
* @fd: a file descriptor to write to. * @writer: a #GimpConfigWriter.
* *
* Writes all unknown tokens attached to #object to the file descriptor @fd. * Writes all unknown tokens attached to #object to the @writer. See
* See gimp_config_add_unknown_token(). * gimp_config_add_unknown_token().
**/ **/
gboolean gboolean
gimp_config_serialize_unknown_tokens (GObject *object, gimp_config_serialize_unknown_tokens (GObject *object,
gint fd, GimpConfigWriter *writer)
gint indent_level)
{ {
GString *str;
g_return_val_if_fail (G_IS_OBJECT (object), FALSE); g_return_val_if_fail (G_IS_OBJECT (object), FALSE);
str = g_string_new (NULL); gimp_config_writer_linefeed (writer);
gimp_config_foreach_unknown_token (object, serialize_unknown_token, writer);
gimp_config_foreach_unknown_token (object, serialize_unknown_token, str); return TRUE;
return (write (fd, str->str, str->len) != -1);
} }
@ -538,9 +524,14 @@ serialize_unknown_token (const gchar *key,
const gchar *value, const gchar *value,
gpointer data) gpointer data)
{ {
gchar *escaped = g_strescape (value, NULL); GimpConfigWriter *writer = data;
gchar *escaped;
g_string_append_printf ((GString *) data, "(%s \"%s\")\n", key, escaped); escaped = g_strescape (value, NULL);
gimp_config_writer_open (writer, key);
gimp_config_writer_printf (writer, "\"%s\"", escaped);
gimp_config_writer_close (writer);
g_free (escaped); g_free (escaped);
} }

View File

@ -24,27 +24,24 @@
gboolean gimp_config_serialize_properties (GObject *object, gboolean gimp_config_serialize_properties (GObject *object,
gint fd, GimpConfigWriter *writer);
gint indent_level);
gboolean gimp_config_serialize_changed_properties (GObject *object, gboolean gimp_config_serialize_changed_properties (GObject *object,
gint fd, GimpConfigWriter *writer);
gint indent_level);
gboolean gimp_config_serialize_properties_diff (GObject *object, gboolean gimp_config_serialize_properties_diff (GObject *object,
GObject *compare, GObject *compare,
gint fd, GimpConfigWriter *writer);
gint indent_level);
gboolean gimp_config_serialize_unknown_tokens (GObject *object, gboolean gimp_config_serialize_unknown_tokens (GObject *object,
gint fd, GimpConfigWriter *writer);
gint indent_level);
gboolean gimp_config_serialize_property (GObject *object, gboolean gimp_config_serialize_property (GObject *object,
GParamSpec *param_spec, GParamSpec *param_spec,
gint fd, GimpConfigWriter *writer);
gint indent_level);
gboolean gimp_config_serialize_value (const GValue *value, gboolean gimp_config_serialize_value (const GValue *value,
GString *str, GString *str,
gboolean escaped); gboolean escaped);
void gimp_config_serialize_comment (GString *str, void gimp_config_serialize_comment (GString *str,
const gchar *comment); const gchar *comment);
#endif /* __GIMP_CONFIG_SERIALIZE_H__ */ #endif /* __GIMP_CONFIG_SERIALIZE_H__ */

View File

@ -27,6 +27,8 @@
#include "libgimpbase/gimpenv.h" #include "libgimpbase/gimpenv.h"
#include "config-types.h"
#include "gimpconfig.h" #include "gimpconfig.h"
#include "gimpconfig-utils.h" #include "gimpconfig-utils.h"

View File

@ -0,0 +1,374 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* GimpConfigWriter
* Copyright (C) 2003 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 <errno.h>
#include <fcntl.h>
#include <stdio.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <glib-object.h>
#ifdef G_OS_WIN32
#include <io.h>
#endif
#include "config-types.h"
#include "gimpconfig.h"
#include "gimpconfig-serialize.h"
#include "gimpconfigwriter.h"
#include "libgimp/gimpintl.h"
static gboolean gimp_config_writer_close_file (GimpConfigWriter *writer,
GError **error);
GimpConfigWriter *
gimp_config_writer_new (const gchar *filename,
gboolean safe,
const gchar *header,
GError **error)
{
GimpConfigWriter *writer;
gchar *tmpname = NULL;
gint fd;
g_return_val_if_fail (filename != NULL, NULL);
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
if (safe)
{
tmpname = g_strconcat (filename, "XXXXXX", NULL);
fd = g_mkstemp (tmpname);
if (fd == -1)
{
g_set_error (error,
GIMP_CONFIG_ERROR, GIMP_CONFIG_ERROR_WRITE,
_("Failed to create temporary file for '%s': %s"),
filename, g_strerror (errno));
g_free (tmpname);
return NULL;
}
}
else
{
fd = open (filename, O_WRONLY);
if (fd == -1)
{
g_set_error (error,
GIMP_CONFIG_ERROR, GIMP_CONFIG_ERROR_WRITE,
_("Failed to open '%s' for writing: %s"),
filename, g_strerror (errno));
return NULL;
}
}
writer = g_new0 (GimpConfigWriter, 1);
writer->fd = fd;
writer->filename = g_strdup (filename);
writer->tmpname = tmpname;
writer->buffer = g_string_new (NULL);
if (header)
{
gimp_config_writer_comment (writer, header);
gimp_config_writer_linefeed (writer);
}
return writer;
}
GimpConfigWriter *
gimp_config_writer_new_from_fd (gint fd)
{
GimpConfigWriter *writer;
g_return_val_if_fail (fd > 0, NULL);
writer = g_new0 (GimpConfigWriter, 1);
writer->fd = fd;
writer->buffer = g_string_new (NULL);
return writer;
}
void
gimp_config_writer_open (GimpConfigWriter *writer,
const gchar *name)
{
g_return_if_fail (writer != NULL);
if (writer->error)
return;
/* store the current buffer length so we can revert to this state */
writer->marker = writer->buffer->len;
if (writer->depth > 0)
{
g_string_append_c (writer->buffer, '\n');
gimp_config_string_indent (writer->buffer, writer->depth);
}
writer->depth++;
g_string_append_printf (writer->buffer, "(%s", name);
}
void
gimp_config_writer_print (GimpConfigWriter *writer,
const gchar *string,
gint len)
{
g_return_if_fail (writer != NULL);
g_return_if_fail (len == 0 || string != NULL);
if (writer->error)
return;
if (len < 0)
len = strlen (string);
g_string_append_c (writer->buffer, ' ');
g_string_append_len (writer->buffer, string, len);
}
void
gimp_config_writer_printf (GimpConfigWriter *writer,
const gchar *format,
...)
{
gchar *buffer;
va_list args;
g_return_if_fail (writer != NULL);
g_return_if_fail (format != NULL);
if (writer->error)
return;
g_string_append_c (writer->buffer, ' ');
va_start (args, format);
buffer = g_strdup_vprintf (format, args);
va_end (args);
g_string_append (writer->buffer, buffer);
g_free (buffer);
}
void
gimp_config_writer_revert (GimpConfigWriter *writer)
{
g_return_if_fail (writer != NULL);
g_return_if_fail (writer->depth > 0);
if (writer->error)
return;
g_string_truncate (writer->buffer, writer->marker);
writer->depth--;
}
void
gimp_config_writer_close (GimpConfigWriter *writer)
{
g_return_if_fail (writer != NULL);
g_return_if_fail (writer->depth > 0);
if (writer->error)
return;
g_string_append_c (writer->buffer, ')');
if (--writer->depth == 0)
{
g_string_append_c (writer->buffer, '\n');
if (write (writer->fd, writer->buffer->str, writer->buffer->len) < 0)
g_set_error (&writer->error, GIMP_CONFIG_ERROR, GIMP_CONFIG_ERROR_WRITE,
g_strerror (errno));
g_string_truncate (writer->buffer, 0);
}
}
gboolean
gimp_config_writer_finish (GimpConfigWriter *writer,
const gchar *footer,
GError **error)
{
gboolean success = TRUE;
g_return_val_if_fail (writer != NULL, FALSE);
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
if (writer->depth < 0)
{
g_warning ("gimp_config_writer_finish: depth < 0 !!");
}
else
{
while (writer->depth)
gimp_config_writer_close (writer);
}
if (footer)
{
gimp_config_writer_linefeed (writer);
gimp_config_writer_comment (writer, footer);
}
success = gimp_config_writer_close_file (writer, error);
g_free (writer->filename);
g_free (writer->tmpname);
g_string_free (writer->buffer, TRUE);
g_free (writer);
return success;
}
void
gimp_config_writer_linefeed (GimpConfigWriter *writer)
{
g_return_if_fail (writer != NULL);
g_return_if_fail (writer->depth == 0);
g_return_if_fail (writer->buffer->len == 0);
if (writer->error)
return;
if (write (writer->fd, "\n", 1) < 0)
g_set_error (&writer->error, GIMP_CONFIG_ERROR, GIMP_CONFIG_ERROR_WRITE,
g_strerror (errno));
}
void
gimp_config_writer_comment (GimpConfigWriter *writer,
const gchar *comment)
{
g_return_if_fail (writer != NULL);
g_return_if_fail (writer->depth == 0);
g_return_if_fail (writer->buffer->len == 0);
if (writer->error)
return;
if (!comment)
return;
gimp_config_serialize_comment (writer->buffer, comment);
if (write (writer->fd, writer->buffer->str, writer->buffer->len) < 0)
g_set_error (&writer->error, GIMP_CONFIG_ERROR, GIMP_CONFIG_ERROR_WRITE,
g_strerror (errno));
g_string_truncate (writer->buffer, 0);
}
static gboolean
gimp_config_writer_close_file (GimpConfigWriter *writer,
GError **error)
{
if (! writer->filename)
return TRUE;
if (writer->error)
{
close (writer->fd);
if (writer->tmpname)
unlink (writer->tmpname);
return TRUE;
}
if (close (writer->fd) != 0)
{
if (writer->tmpname)
{
if (g_file_test (writer->filename, G_FILE_TEST_EXISTS))
{
g_set_error (error, GIMP_CONFIG_ERROR, GIMP_CONFIG_ERROR_WRITE,
_("Error writing to temporary file for '%s': %s\n"
"The original file has not been touched."),
writer->filename, g_strerror (errno));
}
else
{
g_set_error (error, GIMP_CONFIG_ERROR, GIMP_CONFIG_ERROR_WRITE,
_("Error writing to temporary file for '%s': %s\n"
"No file has been created."),
writer->filename, g_strerror (errno));
}
unlink (writer->tmpname);
}
else
{
g_set_error (error, GIMP_CONFIG_ERROR, GIMP_CONFIG_ERROR_WRITE,
_("Error writing to '%s': %s"),
writer->filename, g_strerror (errno));
}
return FALSE;
}
if (writer->tmpname)
{
#ifdef G_OS_WIN32
/* win32 rename can't overwrite */
unlink (writer->filename);
#endif
if (rename (writer->tmpname, writer->filename) == -1)
{
g_set_error (error,
GIMP_CONFIG_ERROR, GIMP_CONFIG_ERROR_WRITE,
_("Failed to create file '%s': %s"),
writer->filename, g_strerror (errno));
unlink (writer->tmpname);
return FALSE;
}
}
return TRUE;
}

View File

@ -0,0 +1,65 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* GimpConfigWriter
* Copyright (C) 2003 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_CONFIG_WRITER_H__
#define __GIMP_CONFIG_WRITER_H__
struct _GimpConfigWriter
{
/*< private >*/
gint fd;
gchar *filename;
gchar *tmpname;
GError *error;
GString *buffer;
gint depth;
gint marker;
};
GimpConfigWriter * gimp_config_writer_new (const gchar *filename,
gboolean safe,
const gchar *header,
GError **error);
GimpConfigWriter * gimp_config_writer_new_from_fd (gint fd);
void gimp_config_writer_open (GimpConfigWriter *writer,
const gchar *name);
void gimp_config_writer_print (GimpConfigWriter *writer,
const gchar *string,
gint len);
void gimp_config_writer_printf (GimpConfigWriter *writer,
const gchar *format,
...);
void gimp_config_writer_revert (GimpConfigWriter *writer);
void gimp_config_writer_close (GimpConfigWriter *writer);
void gimp_config_writer_linefeed (GimpConfigWriter *writer);
void gimp_config_writer_comment (GimpConfigWriter *writer,
const gchar *comment);
gboolean gimp_config_writer_finish (GimpConfigWriter *writer,
const gchar *footer,
GError **error);
#endif /* __GIMP_CONFIG_WRITER_H__ */

View File

@ -39,6 +39,8 @@
#include "libgimpcolor/gimpcolor.h" #include "libgimpcolor/gimpcolor.h"
#include "config-types.h"
#include "gimpconfig.h" #include "gimpconfig.h"
#include "gimpscanner.h" #include "gimpscanner.h"

View File

@ -823,9 +823,6 @@ gimp_scale_entry_new_internal (gboolean color_scale,
* This function creates a #GtkLabel, a #GtkHScale and a #GtkSpinButton and * This function creates a #GtkLabel, a #GtkHScale and a #GtkSpinButton and
* attaches them to a 3-column #GtkTable. * attaches them to a 3-column #GtkTable.
* *
* Note that if you pass a @tooltip or @help_data to this function you'll
* have to initialize GIMP's help system with gimp_help_init() before using it.
*
* Returns: The #GtkSpinButton's #GtkAdjustment. * Returns: The #GtkSpinButton's #GtkAdjustment.
**/ **/
GtkObject * GtkObject *
@ -880,9 +877,6 @@ gimp_scale_entry_new (GtkTable *table,
* This function creates a #GtkLabel, a #GimpColorScale and a * This function creates a #GtkLabel, a #GimpColorScale and a
* #GtkSpinButton and attaches them to a 3-column #GtkTable. * #GtkSpinButton and attaches them to a 3-column #GtkTable.
* *
* Note that if you pass a @tooltip or @help_data to this function you'll
* have to initialize GIMP's help system with gimp_help_init() before using it.
*
* Returns: The #GtkSpinButton's #GtkAdjustment. * Returns: The #GtkSpinButton's #GtkAdjustment.
**/ **/
GtkObject * GtkObject *
@ -955,9 +949,8 @@ gimp_random_seed_update (GtkWidget *widget,
* gimp_random_seed_new: * gimp_random_seed_new:
* @seed: A pointer to the variable which stores the random seed. * @seed: A pointer to the variable which stores the random seed.
* *
* Note that this widget automatically sets tooltips with * Creates a widget that allows the user to control how the random number
* gimp_help_set_help_data(), so you'll have to initialize GIMP's help * generator is initialized.
* system with gimp_help_init() before using it.
* *
* Returns: A #GtkHBox containing a #GtkSpinButton for the seed and * Returns: A #GtkHBox containing a #GtkSpinButton for the seed and
* a #GtkButton for setting a random seed. * a #GtkButton for setting a random seed.