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>
* themes/Default/images/stock-channels-16.png

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -21,28 +21,19 @@
#include "config.h"
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <sys/stat.h>
#include <sys/types.h>
#include <glib-object.h>
#ifdef G_OS_WIN32
#include <io.h>
#endif
#include "libgimpcolor/gimpcolor.h"
#include "config-types.h"
#include "gimpconfig.h"
#include "gimpconfig-serialize.h"
#include "gimpconfig-deserialize.h"
#include "gimpconfig-utils.h"
#include "gimpconfigwriter.h"
#include "gimpscanner.h"
#include "libgimp/gimpintl.h"
@ -52,20 +43,19 @@
* The GimpConfig serialization and deserialization interface.
*/
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,
gint fd,
gint indent_level,
gpointer data);
static gboolean gimp_config_iface_deserialize (GObject *object,
GScanner *scanner,
gint nest_level,
gpointer data);
static GObject *gimp_config_iface_duplicate (GObject *object);
static gboolean gimp_config_iface_equal (GObject *a,
GObject *b);
static void gimp_config_iface_reset (GObject *object);
static gboolean gimp_config_iface_serialize (GObject *object,
GimpConfigWriter *writer,
gpointer data);
static gboolean gimp_config_iface_deserialize (GObject *object,
GScanner *scanner,
gint nest_level,
gpointer data);
static GObject *gimp_config_iface_duplicate (GObject *object);
static gboolean gimp_config_iface_equal (GObject *a,
GObject *b);
static void gimp_config_iface_reset (GObject *object);
GType
@ -106,12 +96,11 @@ gimp_config_iface_init (GimpConfigInterface *gimp_config_iface)
}
static gboolean
gimp_config_iface_serialize (GObject *object,
gint fd,
gint indent_level,
gpointer data)
gimp_config_iface_serialize (GObject *object,
GimpConfigWriter *writer,
gpointer data)
{
return gimp_config_serialize_properties (object, fd, indent_level);
return gimp_config_serialize_properties (object, writer);
}
static gboolean
@ -185,8 +174,8 @@ gimp_config_iface_reset (GObject *object)
* gimp_config_serialize:
* @object: a #GObject that implements the #GimpConfigInterface.
* @filename: the name of the file to write the configuration to.
* @header: optional file header (should be a comment)
* @footer: optional file footer (should be a comment)
* @header: optional file header (must be ASCII only)
* @footer: optional file footer (must be ASCII only)
* @data: user data passed to the serialize implementation.
* @error:
*
@ -206,9 +195,7 @@ gimp_config_serialize (GObject *object,
GError **error)
{
GimpConfigInterface *gimp_config_iface;
gboolean success = TRUE;
gchar *tmpname;
gint fd;
GimpConfigWriter *writer;
g_return_val_if_fail (G_IS_OBJECT (object), 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);
tmpname = g_strconcat (filename, "XXXXXX", NULL);
fd = g_mkstemp (tmpname);
writer = gimp_config_writer_new (filename, TRUE, header, error);
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;
}
if (!writer)
return FALSE;
if (header)
success = (write (fd, header, strlen (header)) != -1 &&
write (fd, "\n", 1) != -1);
gimp_config_iface->serialize (object, writer, data);
if (success)
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;
return gimp_config_writer_finish (writer, footer, error);
}
/**

View File

@ -40,29 +40,28 @@ struct _GimpConfigInterface
{
GTypeInterface base_iface;
gboolean (* serialize) (GObject *object,
gint fd,
gint indent_level,
gpointer data);
gboolean (* deserialize) (GObject *object,
GScanner *scanner,
gint nest_level,
gpointer data);
gboolean (* serialize_property) (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec,
GString *string);
gboolean (* deserialize_property) (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec,
GScanner *scanner,
GTokenType *expected);
GObject * (* duplicate) (GObject *object);
gboolean (* equal) (GObject *a,
GObject *b);
void (* reset) (GObject *object);
gboolean (* serialize) (GObject *object,
GimpConfigWriter *writer,
gpointer data);
gboolean (* deserialize) (GObject *object,
GScanner *scanner,
gint nest_level,
gpointer data);
gboolean (* serialize_property) (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec,
GimpConfigWriter *writer);
gboolean (* deserialize_property) (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec,
GScanner *scanner,
GTokenType *expected);
GObject * (* duplicate) (GObject *object);
gboolean (* equal) (GObject *a,
GObject *b);
void (* reset) (GObject *object);
};
typedef void (* GimpConfigForeachFunc) (const gchar *key,

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

@ -57,34 +57,33 @@ enum
};
static void gimp_rc_class_init (GimpRcClass *klass);
static void gimp_rc_config_iface_init (gpointer iface,
gpointer iface_data);
static void gimp_rc_init (GimpRc *rc);
static void gimp_rc_dispose (GObject *object);
static void gimp_rc_finalize (GObject *object);
static void gimp_rc_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec);
static void gimp_rc_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec);
static gboolean gimp_rc_serialize (GObject *object,
gint fd,
gint indent_level,
gpointer data);
static gboolean gimp_rc_deserialize (GObject *object,
GScanner *scanner,
gint nest_level,
gpointer data);
static GObject * gimp_rc_duplicate (GObject *object);
static void gimp_rc_load (GimpRc *rc);
static gboolean gimp_rc_idle_save (GimpRc *rc);
static void gimp_rc_notify (GimpRc *rc,
GParamSpec *param,
gpointer data);
static void gimp_rc_class_init (GimpRcClass *klass);
static void gimp_rc_config_iface_init (gpointer iface,
gpointer iface_data);
static void gimp_rc_init (GimpRc *rc);
static void gimp_rc_dispose (GObject *object);
static void gimp_rc_finalize (GObject *object);
static void gimp_rc_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec);
static void gimp_rc_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec);
static gboolean gimp_rc_serialize (GObject *object,
GimpConfigWriter *writer,
gpointer data);
static gboolean gimp_rc_deserialize (GObject *object,
GScanner *scanner,
gint nest_level,
gpointer data);
static GObject * gimp_rc_duplicate (GObject *object);
static void gimp_rc_load (GimpRc *rc);
static gboolean gimp_rc_idle_save (GimpRc *rc);
static void gimp_rc_notify (GimpRc *rc,
GParamSpec *param,
gpointer data);
static GObjectClass *parent_class = NULL;
@ -282,27 +281,22 @@ gimp_rc_config_iface_init (gpointer iface,
}
static gboolean
gimp_rc_serialize (GObject *object,
gint fd,
gint indent_level,
gpointer data)
gimp_rc_serialize (GObject *object,
GimpConfigWriter *writer,
gpointer data)
{
if (data && GIMP_IS_RC (data))
{
if (!gimp_config_serialize_properties_diff (object, G_OBJECT (data),
fd, indent_level))
if (!gimp_config_serialize_properties_diff (object, G_OBJECT (data), writer))
return FALSE;
}
else
{
if (!gimp_config_serialize_properties (object, fd, indent_level))
if (!gimp_config_serialize_properties (object, writer))
return FALSE;
}
if (write (fd, "\n", 1) < 0)
return FALSE;
return gimp_config_serialize_unknown_tokens (object, fd, indent_level);
return gimp_config_serialize_unknown_tokens (object, writer);
}
static gboolean
@ -558,17 +552,16 @@ gimp_rc_save (GimpRc *rc)
GError *error = NULL;
const gchar *top =
"# GIMP gimprc\n"
"#\n"
"# This is your personal gimprc file. Any variable defined in this file\n"
"# takes precedence over the value defined in the system-wide gimprc:\n"
"# ";
"GIMP gimprc\n"
"\n"
"This is your personal gimprc file. Any variable defined in this file "
"takes precedence over the value defined in the system-wide gimprc: ";
const gchar *bottom =
"\n"
"# Most values can be set within The GIMP by changing some options in\n"
"# the Preferences dialog.\n";
"Most values can be set within The GIMP by changing some options in "
"the Preferences dialog.";
const gchar *footer =
"# end of gimprc\n";
"end of gimprc";
g_return_if_fail (GIMP_IS_RC (rc));

View File

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

View File

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

View File

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

View File

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

View File

@ -40,6 +40,7 @@
#include "config/gimpconfig.h"
#include "config/gimpconfig-deserialize.h"
#include "config/gimpconfigwriter.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 gboolean gimp_container_serialize (GObject *object,
gint fd,
gint indent_level,
GimpConfigWriter *writer,
gpointer data);
static gboolean gimp_container_deserialize (GObject *object,
GScanner *scanner,
@ -384,10 +384,9 @@ gimp_container_get_memsize (GimpObject *object)
typedef struct
{
gint fd;
gint indent_level;
gpointer data;
gboolean success;
GimpConfigWriter *writer;
gpointer data;
gboolean success;
} SerializeData;
static void
@ -395,7 +394,6 @@ gimp_container_serialize_foreach (GObject *object,
SerializeData *serialize_data)
{
GimpConfigInterface *config_iface;
GString *str;
const gchar *name;
config_iface = GIMP_GET_CONFIG_INTERFACE (object);
@ -406,12 +404,8 @@ gimp_container_serialize_foreach (GObject *object,
if (! serialize_data->success)
return;
str = g_string_new (NULL);
gimp_config_string_indent (str, serialize_data->indent_level);
g_string_append_printf (str, "(%s ",
g_type_name (G_TYPE_FROM_INSTANCE (object)));
gimp_config_writer_open (serialize_data->writer,
g_type_name (G_TYPE_FROM_INSTANCE (object)));
name = gimp_object_get_name (GIMP_OBJECT (object));
@ -420,52 +414,33 @@ gimp_container_serialize_foreach (GObject *object,
gchar *escaped;
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);
}
else
{
g_string_append_printf (str, "NULL\n");
}
if (write (serialize_data->fd, str->str, str->len) == -1)
{
serialize_data->success = FALSE;
return;
gimp_config_writer_print (serialize_data->writer, "NULL", 4);
}
serialize_data->success = config_iface->serialize (object,
serialize_data->fd,
serialize_data->indent_level + 1,
serialize_data->writer,
serialize_data->data);
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;
gimp_config_writer_close (serialize_data->writer);
}
static gboolean
gimp_container_serialize (GObject *object,
gint fd,
gint indent_level,
gpointer data)
gimp_container_serialize (GObject *object,
GimpConfigWriter *writer,
gpointer data)
{
GimpContainer *container;
SerializeData serialize_data;
container = GIMP_CONTAINER (object);
serialize_data.fd = fd;
serialize_data.indent_level = indent_level;
serialize_data.data = data;
serialize_data.success = TRUE;
serialize_data.writer = writer;
serialize_data.data = data;
serialize_data.success = TRUE;
gimp_container_foreach (container,
(GFunc) gimp_container_serialize_foreach,

View File

@ -51,6 +51,7 @@
#include "config/gimpconfig.h"
#include "config/gimpconfig-types.h"
#include "config/gimpconfig-params.h"
#include "config/gimpconfigwriter.h"
#include "config/gimpscanner.h"
#include "libgimp/gimpintl.h"
@ -86,21 +87,20 @@ static void gimp_context_get_property (GObject *object,
GParamSpec *pspec);
static gsize gimp_context_get_memsize (GimpObject *object);
static gboolean gimp_context_serialize (GObject *object,
gint fd,
gint indent_level,
gpointer data);
static gboolean gimp_context_serialize_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec,
GString *string);
static gboolean gimp_context_deserialize_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec,
GScanner *scanner,
GTokenType *expected);
static gboolean gimp_context_serialize (GObject *object,
GimpConfigWriter *writer,
gpointer data);
static gboolean gimp_context_serialize_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec,
GimpConfigWriter *writer);
static gboolean gimp_context_deserialize_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec,
GScanner *scanner,
GTokenType *expected);
/* image */
static void gimp_context_image_removed (GimpContainer *container,
@ -978,20 +978,19 @@ gimp_context_get_memsize (GimpObject *object)
}
static gboolean
gimp_context_serialize (GObject *object,
gint fd,
gint indent_level,
gpointer data)
gimp_context_serialize (GObject *object,
GimpConfigWriter *writer,
gpointer data)
{
return gimp_config_serialize_changed_properties (object, fd, indent_level);
return gimp_config_serialize_changed_properties (object, writer);
}
static gboolean
gimp_context_serialize_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec,
GString *string)
gimp_context_serialize_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec,
GimpConfigWriter *writer)
{
GimpContext *context;
GimpObject *serialize_obj;
@ -1023,12 +1022,12 @@ gimp_context_serialize_property (GObject *object,
gchar *escaped;
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);
}
else
{
g_string_append_printf (string, "NULL");
gimp_config_writer_print (writer, "NULL", 4);
}
return TRUE;

View File

@ -32,6 +32,7 @@
#include "core-types.h"
#include "config/gimpconfig.h"
#include "config/gimpconfigwriter.h"
#include "config/gimpscanner.h"
#include "gimp.h"
@ -39,16 +40,15 @@
#include "gimpimagefile.h"
static void gimp_document_list_config_iface_init (gpointer iface,
gpointer iface_data);
static gboolean gimp_document_list_serialize (GObject *object,
gint fd,
gint indent_level,
gpointer data);
static gboolean gimp_document_list_deserialize (GObject *object,
GScanner *scanner,
gint nest_level,
gpointer data);
static void gimp_document_list_config_iface_init (gpointer iface,
gpointer iface_data);
static gboolean gimp_document_list_serialize (GObject *object,
GimpConfigWriter *writer,
gpointer data);
static gboolean gimp_document_list_deserialize (GObject *object,
GScanner *scanner,
gint nest_level,
gpointer data);
static const gchar *document_symbol = "document";
@ -103,30 +103,25 @@ gimp_document_list_config_iface_init (gpointer iface,
}
static gboolean
gimp_document_list_serialize (GObject *object,
gint fd,
gint indent_level,
gpointer data)
gimp_document_list_serialize (GObject *object,
GimpConfigWriter *writer,
gpointer data)
{
GList *list;
GString *str;
str = g_string_new (NULL);
GList *list;
for (list = GIMP_LIST (object)->list; list; list = list->next)
{
gchar *escaped;
gimp_config_writer_open (writer, document_symbol);
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);
if (write (fd, str->str, str->len) == -1)
return FALSE;
gimp_config_writer_close (writer);
}
g_string_free (str, TRUE);
return TRUE;
}

View File

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

View File

@ -33,6 +33,7 @@
#include "core-types.h"
#include "config/gimpconfig.h"
#include "config/gimpconfigwriter.h"
#include "config/gimpscanner.h"
#include "gimpmarshal.h"
@ -54,18 +55,17 @@ static gsize gimp_parasite_list_get_memsize (GimpObject *object);
static void gimp_parasite_list_config_iface_init (gpointer iface,
gpointer iface_data);
static gboolean gimp_parasite_list_serialize (GObject *list,
gint fd,
gint indent_level,
gpointer data);
static gboolean gimp_parasite_list_deserialize (GObject *list,
GScanner *scanner,
gint nest_level,
gpointer data);
static gboolean gimp_parasite_list_serialize (GObject *list,
GimpConfigWriter *writer,
gpointer data);
static gboolean gimp_parasite_list_deserialize (GObject *list,
GScanner *scanner,
gint nest_level,
gpointer data);
static void parasite_serialize (const gchar *key,
GimpParasite *parasite,
gint *fd_ptr);
GimpConfigWriter *writer);
static void parasite_copy (const gchar *key,
GimpParasite *parasite,
GimpParasiteList *list);
@ -233,16 +233,16 @@ gimp_parasite_list_get_memsize (GimpObject *object)
}
static gboolean
gimp_parasite_list_serialize (GObject *list,
gint fd,
gint indent_level,
gpointer data)
gimp_parasite_list_serialize (GObject *list,
GimpConfigWriter *writer,
gpointer data)
{
if (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
@ -444,25 +444,22 @@ gimp_parasite_list_find (GimpParasiteList *list,
static void
parasite_serialize (const gchar *key,
GimpParasite *parasite,
gint *fd_ptr)
parasite_serialize (const gchar *key,
GimpParasite *parasite,
GimpConfigWriter *writer)
{
GString *str;
const gchar *data;
guint32 len;
/* return if write failed earlier */
if (*fd_ptr == -1)
return;
if (! gimp_parasite_is_persistent (parasite))
return;
gimp_config_writer_open (writer, parasite_symbol);
str = g_string_sized_new (64);
g_string_printf (str, "(%s \"%s\" %lu \"",
parasite_symbol,
g_string_printf (str, "\"%s\" %lu \"",
gimp_parasite_name (parasite),
gimp_parasite_flags (parasite));
@ -492,12 +489,12 @@ parasite_serialize (const gchar *key,
}
}
g_string_append (str, "\")\n\n");
if (write (*fd_ptr, str->str, str->len) == -1)
*fd_ptr = -1;
gimp_config_writer_print (writer, str->str, str->len);
g_string_free (str, TRUE);
gimp_config_writer_close (writer);
gimp_config_writer_linefeed (writer);
}
static void

View File

@ -217,8 +217,8 @@ gimp_tool_options_serialize (GimpToolOptions *tool_options,
retval = gimp_config_serialize (G_OBJECT (tool_options),
filename,
"# tool options\n",
"# end tool options",
"GIMP tool options",
"end of tool options",
NULL,
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)),
filename,
"# test-context\n",
"# end of test-context\n",
"GIMP test-context",
"end of test-context",
NULL,
&error))
{

View File

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

View File

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

View File

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

View File

@ -21,28 +21,19 @@
#include "config.h"
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <sys/stat.h>
#include <sys/types.h>
#include <glib-object.h>
#ifdef G_OS_WIN32
#include <io.h>
#endif
#include "libgimpcolor/gimpcolor.h"
#include "config-types.h"
#include "gimpconfig.h"
#include "gimpconfig-serialize.h"
#include "gimpconfig-deserialize.h"
#include "gimpconfig-utils.h"
#include "gimpconfigwriter.h"
#include "gimpscanner.h"
#include "libgimp/gimpintl.h"
@ -52,20 +43,19 @@
* The GimpConfig serialization and deserialization interface.
*/
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,
gint fd,
gint indent_level,
gpointer data);
static gboolean gimp_config_iface_deserialize (GObject *object,
GScanner *scanner,
gint nest_level,
gpointer data);
static GObject *gimp_config_iface_duplicate (GObject *object);
static gboolean gimp_config_iface_equal (GObject *a,
GObject *b);
static void gimp_config_iface_reset (GObject *object);
static gboolean gimp_config_iface_serialize (GObject *object,
GimpConfigWriter *writer,
gpointer data);
static gboolean gimp_config_iface_deserialize (GObject *object,
GScanner *scanner,
gint nest_level,
gpointer data);
static GObject *gimp_config_iface_duplicate (GObject *object);
static gboolean gimp_config_iface_equal (GObject *a,
GObject *b);
static void gimp_config_iface_reset (GObject *object);
GType
@ -106,12 +96,11 @@ gimp_config_iface_init (GimpConfigInterface *gimp_config_iface)
}
static gboolean
gimp_config_iface_serialize (GObject *object,
gint fd,
gint indent_level,
gpointer data)
gimp_config_iface_serialize (GObject *object,
GimpConfigWriter *writer,
gpointer data)
{
return gimp_config_serialize_properties (object, fd, indent_level);
return gimp_config_serialize_properties (object, writer);
}
static gboolean
@ -185,8 +174,8 @@ gimp_config_iface_reset (GObject *object)
* gimp_config_serialize:
* @object: a #GObject that implements the #GimpConfigInterface.
* @filename: the name of the file to write the configuration to.
* @header: optional file header (should be a comment)
* @footer: optional file footer (should be a comment)
* @header: optional file header (must be ASCII only)
* @footer: optional file footer (must be ASCII only)
* @data: user data passed to the serialize implementation.
* @error:
*
@ -206,9 +195,7 @@ gimp_config_serialize (GObject *object,
GError **error)
{
GimpConfigInterface *gimp_config_iface;
gboolean success = TRUE;
gchar *tmpname;
gint fd;
GimpConfigWriter *writer;
g_return_val_if_fail (G_IS_OBJECT (object), 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);
tmpname = g_strconcat (filename, "XXXXXX", NULL);
fd = g_mkstemp (tmpname);
writer = gimp_config_writer_new (filename, TRUE, header, error);
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;
}
if (!writer)
return FALSE;
if (header)
success = (write (fd, header, strlen (header)) != -1 &&
write (fd, "\n", 1) != -1);
gimp_config_iface->serialize (object, writer, data);
if (success)
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;
return gimp_config_writer_finish (writer, footer, error);
}
/**

View File

@ -40,29 +40,28 @@ struct _GimpConfigInterface
{
GTypeInterface base_iface;
gboolean (* serialize) (GObject *object,
gint fd,
gint indent_level,
gpointer data);
gboolean (* deserialize) (GObject *object,
GScanner *scanner,
gint nest_level,
gpointer data);
gboolean (* serialize_property) (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec,
GString *string);
gboolean (* deserialize_property) (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec,
GScanner *scanner,
GTokenType *expected);
GObject * (* duplicate) (GObject *object);
gboolean (* equal) (GObject *a,
GObject *b);
void (* reset) (GObject *object);
gboolean (* serialize) (GObject *object,
GimpConfigWriter *writer,
gpointer data);
gboolean (* deserialize) (GObject *object,
GScanner *scanner,
gint nest_level,
gpointer data);
gboolean (* serialize_property) (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec,
GimpConfigWriter *writer);
gboolean (* deserialize_property) (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec,
GScanner *scanner,
GTokenType *expected);
GObject * (* duplicate) (GObject *object);
gboolean (* equal) (GObject *a,
GObject *b);
void (* reset) (GObject *object);
};
typedef void (* GimpConfigForeachFunc) (const gchar *key,

View File

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

View File

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

View File

@ -27,6 +27,8 @@
#include "libgimpbase/gimpenv.h"
#include "config-types.h"
#include "gimpconfig.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 "config-types.h"
#include "gimpconfig.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
* 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.
**/
GtkObject *
@ -880,9 +877,6 @@ gimp_scale_entry_new (GtkTable *table,
* This function creates a #GtkLabel, a #GimpColorScale and a
* #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.
**/
GtkObject *
@ -955,15 +949,14 @@ gimp_random_seed_update (GtkWidget *widget,
* gimp_random_seed_new:
* @seed: A pointer to the variable which stores the random seed.
*
* Note that this widget automatically sets tooltips with
* gimp_help_set_help_data(), so you'll have to initialize GIMP's help
* system with gimp_help_init() before using it.
* Creates a widget that allows the user to control how the random number
* generator is initialized.
*
* Returns: A #GtkHBox containing a #GtkSpinButton for the seed and
* a #GtkButton for setting a random seed.
**/
GtkWidget *
gimp_random_seed_new (guint *seed)
gimp_random_seed_new (guint *seed)
{
GtkWidget *hbox;
GtkWidget *spinbutton;