diff --git a/ChangeLog b/ChangeLog index e437211acd..6848a903e9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,7 +1,31 @@ +2003-06-23 Sven Neumann + + * app/config/gimpconfig.[ch] + * app/config/gimpconfigwriter.[ch] + * app/config/gimpscanner.[ch]: added support for serializing to + and deserializing from strings. Had to do some smaller changes to + the GimpConfig API. + + * app/config/test-config.c: added a simple test for the new + functions. + + * app/config/gimpconfig-dump.c + * app/config/gimprc.c + * app/core/gimp-documents.c + * app/core/gimp-parasites.c + * app/core/gimp-templates.c + * app/core/gimpunits.c + * app/gui/session.c + * app/plug-in/plug-in-rc.c + * app/tools/tool_options.c + * app/widgets/gimpdevices.c: follow GimpConfig API changes. + + * libgimpbase/gimpparasite.[ch]: declared the return value of + gimp_parasite_data() as gconstpointer. + 2003-06-23 Henrik Brix Andersen - Added a per image configurable grid. - This fixes bug #65198 + Added a per image configurable grid. This fixes bug #65198. * app/core/Makefile.am * app/core/core-types.h: diff --git a/app/config/gimpconfig-dump.c b/app/config/gimpconfig-dump.c index 1db2bda06f..4302f9ddd8 100644 --- a/app/config/gimpconfig-dump.c +++ b/app/config/gimpconfig-dump.c @@ -55,9 +55,11 @@ typedef enum static gint dump_gimprc (DumpFormat format); static void dump_gimprc_system (GObject *rc, - GimpConfigWriter *writer); + GimpConfigWriter *writer, + gint fd); static void dump_gimprc_manpage (GObject *rc, - GimpConfigWriter *writer); + GimpConfigWriter *writer, + gint fd); static gchar * dump_describe_param (GParamSpec *param_spec); static void dump_with_linebreaks (gint fd, const gchar *text); @@ -110,6 +112,7 @@ dump_gimprc (DumpFormat format) { GimpConfigWriter *writer; GObject *rc; + gint fd = 1; if (format == DUMP_NONE) return EXIT_SUCCESS; @@ -120,7 +123,7 @@ dump_gimprc (DumpFormat format) "module-load-inhibit", "foo", /* for completeness */ NULL); - writer = gimp_config_writer_new_from_fd (1); + writer = gimp_config_writer_new_fd (fd); switch (format) { @@ -133,10 +136,10 @@ dump_gimprc (DumpFormat format) g_print ("\n"); break; case DUMP_COMMENT: - dump_gimprc_system (rc, writer); + dump_gimprc_system (rc, writer, fd); break; case DUMP_MANPAGE: - dump_gimprc_manpage (rc, writer); + dump_gimprc_manpage (rc, writer, fd); break; default: break; @@ -167,7 +170,8 @@ static const gchar *system_gimprc_header = static void dump_gimprc_system (GObject *rc, - GimpConfigWriter *writer) + GimpConfigWriter *writer, + gint fd) { GObjectClass *klass; GParamSpec **property_specs; @@ -194,11 +198,10 @@ dump_gimprc_system (GObject *rc, gimp_config_writer_comment (writer, comment); g_free (comment); - write (writer->fd, "#\n", 2); + write (fd, "#\n", 2); } - /* kids, don't try this at home! */ - write (writer->fd, "# ", 2); + write (fd, "# ", 2); gimp_config_serialize_property (rc, prop_spec, writer); gimp_config_writer_linefeed (writer); @@ -296,14 +299,15 @@ static const gchar *man_page_footer = static void dump_gimprc_manpage (GObject *rc, - GimpConfigWriter *writer) + GimpConfigWriter *writer, + gint fd) { GObjectClass *klass; GParamSpec **property_specs; guint n_property_specs; guint i; - write (writer->fd, man_page_header, strlen (man_page_header)); + write (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); @@ -316,16 +320,16 @@ dump_gimprc_manpage (GObject *rc, if (! (prop_spec->flags & GIMP_PARAM_SERIALIZE)) continue; - write (writer->fd, ".TP\n", strlen (".TP\n")); + write (fd, ".TP\n", strlen (".TP\n")); if (gimp_config_serialize_property (rc, prop_spec, writer)) { - write (writer->fd, "\n", 1); + write (fd, "\n", 1); desc = dump_describe_param (prop_spec); - dump_with_linebreaks (writer->fd, desc); - write (writer->fd, "\n", 1); + dump_with_linebreaks (fd, desc); + write (fd, "\n", 1); g_free (desc); } @@ -333,8 +337,8 @@ dump_gimprc_manpage (GObject *rc, g_free (property_specs); - write (writer->fd, man_page_path, strlen (man_page_path)); - write (writer->fd, man_page_footer, strlen (man_page_footer)); + write (fd, man_page_path, strlen (man_page_path)); + write (fd, man_page_footer, strlen (man_page_footer)); } diff --git a/app/config/gimpconfig.c b/app/config/gimpconfig.c index fb1d81c070..ced32b0b61 100644 --- a/app/config/gimpconfig.c +++ b/app/config/gimpconfig.c @@ -171,7 +171,7 @@ gimp_config_iface_reset (GObject *object) } /** - * gimp_config_serialize: + * gimp_config_serialize_to_file: * @object: a #GObject that implements the #GimpConfigInterface. * @filename: the name of the file to write the configuration to. * @header: optional file header (must be ASCII only) @@ -187,12 +187,12 @@ gimp_config_iface_reset (GObject *object) * Return value: %TRUE if serialization succeeded, %FALSE otherwise. **/ gboolean -gimp_config_serialize (GObject *object, - const gchar *filename, - const gchar *header, - const gchar *footer, - gpointer data, - GError **error) +gimp_config_serialize_to_file (GObject *object, + const gchar *filename, + const gchar *header, + const gchar *footer, + gpointer data, + GError **error) { GimpConfigInterface *gimp_config_iface; GimpConfigWriter *writer; @@ -202,11 +202,9 @@ gimp_config_serialize (GObject *object, g_return_val_if_fail (error == NULL || *error == NULL, FALSE); gimp_config_iface = GIMP_GET_CONFIG_INTERFACE (object); - g_return_val_if_fail (gimp_config_iface != NULL, FALSE); - writer = gimp_config_writer_new (filename, TRUE, header, error); - + writer = gimp_config_writer_new_file (filename, TRUE, header, error); if (!writer) return FALSE; @@ -215,6 +213,38 @@ gimp_config_serialize (GObject *object, return gimp_config_writer_finish (writer, footer, error); } +/** + * gimp_config_serialize_to_string: + * @object: a #GObject that implements the #GimpConfigInterface. + * @data: user data passed to the serialize implementation. + * + * Serializes the object properties of @object to a string. + * + * Return value: a newly allocated %NUL-terminated string. + **/ +gchar * +gimp_config_serialize_to_string (GObject *object, + gpointer data) +{ + GimpConfigInterface *gimp_config_iface; + GimpConfigWriter *writer; + GString *str; + + g_return_val_if_fail (G_IS_OBJECT (object), NULL); + + gimp_config_iface = GIMP_GET_CONFIG_INTERFACE (object); + g_return_val_if_fail (gimp_config_iface != NULL, FALSE); + + str = g_string_new (NULL); + writer = gimp_config_writer_new_string (str); + + gimp_config_iface->serialize (object, writer, data); + + gimp_config_writer_finish (writer, NULL, NULL); + + return g_string_free (str, FALSE); +} + /** * gimp_config_deserialize: * @object: a #GObject that implements the #GimpConfigInterface. @@ -230,10 +260,10 @@ gimp_config_serialize (GObject *object, * Return value: %TRUE if deserialization succeeded, %FALSE otherwise. **/ gboolean -gimp_config_deserialize (GObject *object, - const gchar *filename, - gpointer data, - GError **error) +gimp_config_deserialize_file (GObject *object, + const gchar *filename, + gpointer data, + GError **error) { GimpConfigInterface *gimp_config_iface; GScanner *scanner; @@ -244,11 +274,9 @@ gimp_config_deserialize (GObject *object, g_return_val_if_fail (error == NULL || *error == NULL, FALSE); gimp_config_iface = GIMP_GET_CONFIG_INTERFACE (object); - g_return_val_if_fail (gimp_config_iface != NULL, FALSE); - scanner = gimp_scanner_new (filename, error); - + scanner = gimp_scanner_new_file (filename, error); if (! scanner) return FALSE; @@ -262,6 +290,49 @@ gimp_config_deserialize (GObject *object, return success; } +/** + * gimp_config_deserialize_string: + * @object: a #GObject that implements the #GimpConfigInterface. + * @text: string to deserialize (in UTF-8 encoding) + * @text_len: length of @text in bytes or -1 + * @error: + * + * Configures @object from @text. Basically this function creates a + * properly configured #GScanner for you and calls the deserialize + * function of the @object's #GimpConfigInterface. + * + * Return value: %TRUE if deserialization succeeded, %FALSE otherwise. + **/ +gboolean +gimp_config_deserialize_string (GObject *object, + const gchar *text, + gint text_len, + gpointer data, + GError **error) +{ + GimpConfigInterface *gimp_config_iface; + GScanner *scanner; + gboolean success; + + g_return_val_if_fail (G_IS_OBJECT (object), FALSE); + g_return_val_if_fail (text != NULL || text_len == 0, FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + gimp_config_iface = GIMP_GET_CONFIG_INTERFACE (object); + g_return_val_if_fail (gimp_config_iface != NULL, FALSE); + + scanner = gimp_scanner_new_string (text, text_len, error); + + success = gimp_config_iface->deserialize (object, scanner, 0, data); + + gimp_scanner_destroy (scanner); + + if (! success) + g_assert (error == NULL || *error != NULL); + + return success; +} + gboolean gimp_config_deserialize_return (GScanner *scanner, GTokenType expected_token, diff --git a/app/config/gimpconfig.h b/app/config/gimpconfig.h index 50d462d3f8..cc14848adb 100644 --- a/app/config/gimpconfig.h +++ b/app/config/gimpconfig.h @@ -71,17 +71,23 @@ typedef void (* GimpConfigForeachFunc) (const gchar *key, GType gimp_config_interface_get_type (void) G_GNUC_CONST; -gboolean gimp_config_serialize (GObject *object, +gboolean gimp_config_serialize_to_file (GObject *object, const gchar *filename, const gchar *header, const gchar *footer, gpointer data, GError **error); -gboolean gimp_config_deserialize (GObject *object, +gchar * gimp_config_serialize_to_string (GObject *object, + gpointer data); +gboolean gimp_config_deserialize_file (GObject *object, const gchar *filename, gpointer data, GError **error); - +gboolean gimp_config_deserialize_string (GObject *object, + const gchar *text, + gint text_len, + gpointer data, + GError **error); gboolean gimp_config_deserialize_return (GScanner *scanner, GTokenType expected_token, gint nest_level); diff --git a/app/config/gimpconfigwriter.c b/app/config/gimpconfigwriter.c index 218c4a7414..5b38e3a4c9 100644 --- a/app/config/gimpconfigwriter.c +++ b/app/config/gimpconfigwriter.c @@ -47,15 +47,27 @@ #include "gimp-intl.h" +struct _GimpConfigWriter +{ + gint fd; + gchar *filename; + gchar *tmpname; + GError *error; + GString *buffer; + gint depth; + gint marker; +}; + + 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) +gimp_config_writer_new_file (const gchar *filename, + gboolean safe, + const gchar *header, + GError **error) { GimpConfigWriter *writer; gchar *tmpname = NULL; @@ -111,7 +123,7 @@ gimp_config_writer_new (const gchar *filename, } GimpConfigWriter * -gimp_config_writer_new_from_fd (gint fd) +gimp_config_writer_new_fd (gint fd) { GimpConfigWriter *writer; @@ -125,6 +137,20 @@ gimp_config_writer_new_from_fd (gint fd) return writer; } +GimpConfigWriter * +gimp_config_writer_new_string (GString *string) +{ + GimpConfigWriter *writer; + + g_return_val_if_fail (string != NULL, NULL); + + writer = g_new0 (GimpConfigWriter, 1); + + writer->buffer = string; + + return writer; +} + void gimp_config_writer_open (GimpConfigWriter *writer, const gchar *name) @@ -237,13 +263,16 @@ gimp_config_writer_close (GimpConfigWriter *writer) 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); + if (writer->fd) + { + 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); + } } } @@ -273,12 +302,19 @@ gimp_config_writer_finish (GimpConfigWriter *writer, gimp_config_writer_comment (writer, footer); } - success = gimp_config_writer_close_file (writer, error); + if (writer->fd) + { + success = gimp_config_writer_close_file (writer, error); - g_free (writer->filename); - g_free (writer->tmpname); + g_free (writer->filename); + g_free (writer->tmpname); - g_string_free (writer->buffer, TRUE); + g_string_free (writer->buffer, TRUE); + } + else + { + success = TRUE; + } g_free (writer); @@ -335,6 +371,8 @@ static gboolean gimp_config_writer_close_file (GimpConfigWriter *writer, GError **error) { + g_return_val_if_fail (writer->fd != 0, FALSE); + if (! writer->filename) return TRUE; diff --git a/app/config/gimpconfigwriter.h b/app/config/gimpconfigwriter.h index bff89a296e..a0c6804241 100644 --- a/app/config/gimpconfigwriter.h +++ b/app/config/gimpconfigwriter.h @@ -23,24 +23,12 @@ #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, +GimpConfigWriter * gimp_config_writer_new_file (const gchar *filename, gboolean safe, const gchar *header, GError **error); -GimpConfigWriter * gimp_config_writer_new_from_fd (gint fd); +GimpConfigWriter * gimp_config_writer_new_fd (gint fd); +GimpConfigWriter * gimp_config_writer_new_string (GString *string); void gimp_config_writer_open (GimpConfigWriter *writer, const gchar *name); diff --git a/app/config/gimprc.c b/app/config/gimprc.c index 6a8df5057d..91a638489e 100644 --- a/app/config/gimprc.c +++ b/app/config/gimprc.c @@ -287,12 +287,13 @@ gimp_rc_serialize (GObject *object, { if (data && GIMP_IS_RC (data)) { - if (!gimp_config_serialize_properties_diff (object, G_OBJECT (data), writer)) + if (! gimp_config_serialize_properties_diff (object, + G_OBJECT (data), writer)) return FALSE; } else { - if (!gimp_config_serialize_properties (object, writer)) + if (! gimp_config_serialize_properties (object, writer)) return FALSE; } @@ -340,8 +341,8 @@ gimp_rc_load (GimpRc *rc) if (rc->verbose) g_print (_("Parsing '%s'\n"), rc->system_gimprc); - if (! gimp_config_deserialize (G_OBJECT (rc), - rc->system_gimprc, NULL, &error)) + if (! gimp_config_deserialize_file (G_OBJECT (rc), + rc->system_gimprc, NULL, &error)) { if (error->code != GIMP_CONFIG_ERROR_OPEN_ENOENT) g_message (error->message); @@ -352,8 +353,8 @@ gimp_rc_load (GimpRc *rc) if (rc->verbose) g_print (_("Parsing '%s'\n"), rc->user_gimprc); - if (! gimp_config_deserialize (G_OBJECT (rc), - rc->user_gimprc, NULL, &error)) + if (! gimp_config_deserialize_file (G_OBJECT (rc), + rc->user_gimprc, NULL, &error)) { if (error->code != GIMP_CONFIG_ERROR_OPEN_ENOENT) g_message (error->message); @@ -567,16 +568,18 @@ gimp_rc_save (GimpRc *rc) global = g_object_new (GIMP_TYPE_RC, NULL); - gimp_config_deserialize (G_OBJECT (global), rc->system_gimprc, NULL, NULL); + gimp_config_deserialize_file (G_OBJECT (global), + rc->system_gimprc, NULL, NULL); header = g_strconcat (top, rc->system_gimprc, bottom, NULL); if (rc->verbose) g_print (_("Saving '%s'\n"), rc->user_gimprc); - if (! gimp_config_serialize (G_OBJECT (rc), - rc->user_gimprc, header, footer, global, - &error)) + if (! gimp_config_serialize_to_file (G_OBJECT (rc), + rc->user_gimprc, + header, footer, global, + &error)) { g_message (error->message); g_error_free (error); diff --git a/app/config/gimpscanner.c b/app/config/gimpscanner.c index 64ef64dc54..43f854265a 100644 --- a/app/config/gimpscanner.c +++ b/app/config/gimpscanner.c @@ -49,21 +49,23 @@ /* local function prototypes */ -static void gimp_scanner_message (GScanner *scanner, - gchar *message, - gboolean is_error); +static GScanner * gimp_scanner_new (GError **error); +static void gimp_scanner_message (GScanner *scanner, + gchar *message, + gboolean is_error); /* public functions */ GScanner * -gimp_scanner_new (const gchar *filename, - GError **error) +gimp_scanner_new_file (const gchar *filename, + GError **error) { gint fd; GScanner *scanner; g_return_val_if_fail (filename != NULL, NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); fd = open (filename, O_RDONLY); @@ -78,13 +80,43 @@ gimp_scanner_new (const gchar *filename, return NULL; } - scanner = g_scanner_new (NULL); + scanner = gimp_scanner_new (error); g_scanner_input_file (scanner, fd); + scanner->input_name = g_strdup (filename); + + return scanner; +} + +GScanner * +gimp_scanner_new_string (const gchar *text, + gint text_len, + GError **error) +{ + GScanner *scanner; + + g_return_val_if_fail (text != NULL || text_len == 0, NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + + if (text_len < 0) + text_len = strlen (text); + + scanner = gimp_scanner_new (error); + + g_scanner_input_text (scanner, text, text_len); + + return scanner; +} + +static GScanner * +gimp_scanner_new (GError **error) +{ + GScanner *scanner; + + scanner = g_scanner_new (NULL); scanner->user_data = error; scanner->msg_handler = gimp_scanner_message; - scanner->input_name = g_strdup (filename); scanner->config->cset_identifier_first = ( G_CSET_a_2_z G_CSET_A_2_Z ); scanner->config->cset_identifier_nth = ( G_CSET_a_2_z G_CSET_A_2_Z @@ -349,8 +381,13 @@ gimp_scanner_message (GScanner *scanner, /* we don't expect warnings */ g_return_if_fail (is_error); - g_set_error (error, - GIMP_CONFIG_ERROR, GIMP_CONFIG_ERROR_PARSE, - _("Error while parsing '%s' in line %d:\n%s"), - scanner->input_name, scanner->line, message); + if (scanner->input_name) + g_set_error (error, + GIMP_CONFIG_ERROR, GIMP_CONFIG_ERROR_PARSE, + _("Error while parsing '%s' in line %d:\n%s"), + scanner->input_name, scanner->line, message); + else + g_set_error (error, + GIMP_CONFIG_ERROR, GIMP_CONFIG_ERROR_PARSE, + "Error parsing internal buffer: %s", message); } diff --git a/app/config/gimpscanner.h b/app/config/gimpscanner.h index 454dbd3d47..59697750bc 100644 --- a/app/config/gimpscanner.h +++ b/app/config/gimpscanner.h @@ -24,7 +24,10 @@ #define __GIMP_SCANNER_H__ -GScanner * gimp_scanner_new (const gchar *filename, +GScanner * gimp_scanner_new_file (const gchar *filename, + GError **error); +GScanner * gimp_scanner_new_string (const gchar *text, + gint text_len, GError **error); void gimp_scanner_destroy (GScanner *scanner); diff --git a/app/config/test-config.c b/app/config/test-config.c index 65bb8e1330..8693efb880 100644 --- a/app/config/test-config.c +++ b/app/config/test-config.c @@ -33,6 +33,7 @@ #include "gimpconfig.h" #include "gimpconfig-serialize.h" +#include "gimpconfig-utils.h" #include "gimprc.h" @@ -47,8 +48,8 @@ int main (int argc, char *argv[]) { - GimpRc *gimprc; - GimpRc *gimprc2; + GObject *gimprc; + GObject *gimprc2; const gchar *filename = "foorc"; gchar *header; gchar *result; @@ -76,17 +77,16 @@ main (int argc, g_print (" done.\n\n"); g_print (" Adding the unknown token (foobar \"hadjaha\") ..."); - gimp_config_add_unknown_token (G_OBJECT (gimprc), "foobar", "hadjaha"); + gimp_config_add_unknown_token (gimprc, "foobar", "hadjaha"); g_print (" done.\n\n"); g_print (" Serializing %s to '%s' ...", g_type_name (G_TYPE_FROM_INSTANCE (gimprc)), filename); - if (! gimp_config_serialize (G_OBJECT (gimprc), - filename, - "foorc", - "end of foorc", - NULL, &error)) + if (! gimp_config_serialize_to_file (gimprc, + filename, + "foorc", "end of foorc", + NULL, &error)) { g_print ("%s\n", error->message); return EXIT_FAILURE; @@ -98,21 +98,20 @@ main (int argc, NULL); g_print (" Deserializing from '%s' ...\n\n", filename); - if (! gimp_config_deserialize (G_OBJECT (gimprc), filename, NULL, &error)) + if (! gimp_config_deserialize_file (gimprc, filename, NULL, &error)) { g_print ("%s\n", error->message); return EXIT_FAILURE; } header = "\n Unknown string tokens:\n"; - gimp_config_foreach_unknown_token (G_OBJECT (gimprc), - output_unknown_token, &header); + gimp_config_foreach_unknown_token (gimprc, output_unknown_token, &header); g_print ("\n done.\n"); g_print ("\n Changing a property ..."); g_object_set (gimprc, "use-help", FALSE, NULL); g_print ("\n Testing gimp_config_duplicate() ..."); - gimprc2 = GIMP_RC (gimp_config_duplicate (G_OBJECT (gimprc))); + gimprc2 = gimp_config_duplicate (gimprc); g_print (" done.\n"); g_signal_connect (gimprc2, "notify", @@ -124,7 +123,7 @@ main (int argc, g_print ("\n Querying for \"default-comment\" ... "); - result = gimp_rc_query (gimprc2, "default-comment"); + result = gimp_rc_query (GIMP_RC (gimprc2), "default-comment"); if (result) { g_print ("OK, found \"%s\".\n", result); @@ -138,7 +137,7 @@ main (int argc, g_print (" Querying for \"foobar\" ... "); - result = gimp_rc_query (gimprc2, "foobar"); + result = gimp_rc_query (GIMP_RC (gimprc2), "foobar"); if (result && strcmp (result, "hadjaha") == 0) { g_print ("OK, found \"%s\".\n", result); @@ -154,11 +153,11 @@ main (int argc, g_object_unref (gimprc2); g_print ("\n Deserializing from gimpconfig.c (should fail) ..."); - if (! gimp_config_deserialize (G_OBJECT (gimprc), - "gimpconfig.c", NULL, &error)) + if (! gimp_config_deserialize_file (gimprc, "gimpconfig.c", NULL, &error)) { g_print (" OK, failed. The error was:\n %s\n", error->message); g_error_free (error); + error = NULL; } else { @@ -166,6 +165,40 @@ main (int argc, return EXIT_FAILURE; } + g_print ("\n Serializing to a string and back ... "); + + result = gimp_config_serialize_to_string (gimprc, NULL); + + gimprc2 = g_object_new (GIMP_TYPE_RC, NULL); + + if (! gimp_config_deserialize_string (gimprc2, result, -1, NULL, &error)) + { + g_print ("failed!\nThe error was:\n %s\n", error->message); + g_error_free (error); + return EXIT_FAILURE; + } + else + { + GList *diff = gimp_config_diff (gimprc, gimprc2, 0); + + if (diff) + { + GList *list; + + g_print ("succeeded but properties differ:\n"); + for (list = diff; list; list = list->next) + { + GParamSpec *pspec = list->data; + g_print (" %s\n", pspec->name); + } + return EXIT_FAILURE; + } + + g_print ("OK (%d bytes)\n", result ? strlen (result) : 0); + } + + g_free (result); + g_object_unref (gimprc2); g_object_unref (gimprc); g_print ("\nFinished test of GimpConfig.\n\n"); diff --git a/app/core/gimp-documents.c b/app/core/gimp-documents.c index bf1f60e236..c45e6d095a 100644 --- a/app/core/gimp-documents.c +++ b/app/core/gimp-documents.c @@ -45,10 +45,10 @@ gimp_documents_load (Gimp *gimp) filename = gimp_personal_rc_file ("documents"); - if (!gimp_config_deserialize (G_OBJECT (gimp->documents), - filename, - GINT_TO_POINTER (gimp->config->thumbnail_size), - &error)) + if (! gimp_config_deserialize_file (G_OBJECT (gimp->documents), + filename, + GINT_TO_POINTER (gimp->config->thumbnail_size), + &error)) { if (error->code != GIMP_CONFIG_ERROR_OPEN_ENOENT) g_message (error->message); @@ -76,8 +76,10 @@ gimp_documents_save (Gimp *gimp) filename = gimp_personal_rc_file ("documents"); - if (! gimp_config_serialize (G_OBJECT (gimp->documents), - filename, header, footer, NULL, &error)) + if (! gimp_config_serialize_to_file (G_OBJECT (gimp->documents), + filename, + header, footer, NULL, + &error)) { g_message (error->message); g_error_free (error); diff --git a/app/core/gimp-parasites.c b/app/core/gimp-parasites.c index 4c731bbdaf..bbd5dd0ea5 100644 --- a/app/core/gimp-parasites.c +++ b/app/core/gimp-parasites.c @@ -100,8 +100,8 @@ gimp_parasiterc_load (Gimp *gimp) filename = gimp_personal_rc_file ("parasiterc"); - if (! gimp_config_deserialize (G_OBJECT (gimp->parasites), - filename, NULL, &error)) + if (! gimp_config_deserialize_file (G_OBJECT (gimp->parasites), + filename, NULL, &error)) { if (error->code != GIMP_CONFIG_ERROR_OPEN_ENOENT) g_message (error->message); @@ -129,8 +129,10 @@ gimp_parasiterc_save (Gimp *gimp) filename = gimp_personal_rc_file ("parasiterc"); - if (! gimp_config_serialize (G_OBJECT (gimp->parasites), - filename, header, footer, NULL, &error)) + if (! gimp_config_serialize_to_file (G_OBJECT (gimp->parasites), + filename, + header, footer, NULL, + &error)) { g_message (error->message); g_error_free (error); diff --git a/app/core/gimp-templates.c b/app/core/gimp-templates.c index adf3f87486..18efe559be 100644 --- a/app/core/gimp-templates.c +++ b/app/core/gimp-templates.c @@ -45,10 +45,10 @@ gimp_templates_load (Gimp *gimp) filename = gimp_personal_rc_file ("templaterc"); - if (!gimp_config_deserialize (G_OBJECT (gimp->templates), - filename, - NULL, - &error)) + if (!gimp_config_deserialize_file (G_OBJECT (gimp->templates), + filename, + NULL, + &error)) { if (error->code != GIMP_CONFIG_ERROR_OPEN_ENOENT) g_message (error->message); @@ -78,8 +78,10 @@ gimp_templates_save (Gimp *gimp) filename = gimp_personal_rc_file ("templaterc"); - if (! gimp_config_serialize (G_OBJECT (gimp->templates), - filename, header, footer, NULL, &error)) + if (! gimp_config_serialize_to_file (G_OBJECT (gimp->templates), + filename, + header, footer, NULL, + &error)) { g_message (error->message); g_error_free (error); diff --git a/app/core/gimp-units.c b/app/core/gimp-units.c index 47fb077843..2a3d3bcb6d 100644 --- a/app/core/gimp-units.c +++ b/app/core/gimp-units.c @@ -97,7 +97,7 @@ gimp_unitrc_load (Gimp *gimp) g_return_if_fail (GIMP_IS_GIMP (gimp)); filename = gimp_personal_rc_file ("unitrc"); - scanner = gimp_scanner_new (filename, &error); + scanner = gimp_scanner_new_file (filename, &error); g_free (filename); if (! scanner) @@ -174,16 +174,17 @@ gimp_unitrc_save (Gimp *gimp) filename = gimp_personal_rc_file ("unitrc"); - writer = gimp_config_writer_new (filename, - TRUE, - "GIMP units\n\n" - "This file contains the user unit database. " - "You can edit this list with the unit " - "editor. You are not supposed to edit it " - "manually, but of course you can do.\n" - "This file will be entirely rewritten every " - "time you quit the gimp.", - NULL); + writer = + gimp_config_writer_new_file (filename, + TRUE, + "GIMP units\n\n" + "This file contains the user unit database. " + "You can edit this list with the unit " + "editor. You are not supposed to edit it " + "manually, but of course you can do.\n" + "This file will be entirely rewritten every " + "time you quit the gimp.", + NULL); g_free (filename); diff --git a/app/core/gimplayer.c b/app/core/gimplayer.c index 220d4bf37b..4552ff3536 100644 --- a/app/core/gimplayer.c +++ b/app/core/gimplayer.c @@ -1259,7 +1259,7 @@ gimp_layer_boundary (GimpLayer *layer, new_segs[0].y2 = item->offset_y + item->height; new_segs[0].open = 1; - new_segs[1].x1 = item->offset_x; + new_segs[1].x1 = item->offset_x; new_segs[1].y1 = item->offset_y; new_segs[1].x2 = item->offset_x + item->width; new_segs[1].y2 = item->offset_y; diff --git a/app/core/gimptooloptions.c b/app/core/gimptooloptions.c index 56400f7255..0f0f81072b 100644 --- a/app/core/gimptooloptions.c +++ b/app/core/gimptooloptions.c @@ -215,12 +215,12 @@ gimp_tool_options_serialize (GimpToolOptions *tool_options, filename = gimp_tool_options_build_filename (tool_options, extension); - retval = gimp_config_serialize (G_OBJECT (tool_options), - filename, - "GIMP tool options", - "end of tool options", - NULL, - error); + retval = gimp_config_serialize_to_file (G_OBJECT (tool_options), + filename, + "GIMP tool options", + "end of tool options", + NULL, + error); g_free (filename); @@ -240,10 +240,10 @@ gimp_tool_options_deserialize (GimpToolOptions *tool_options, filename = gimp_tool_options_build_filename (tool_options, extension); - retval = gimp_config_deserialize (G_OBJECT (tool_options), - filename, - NULL, - error); + retval = gimp_config_deserialize_file (G_OBJECT (tool_options), + filename, + NULL, + error); g_free (filename); diff --git a/app/core/gimpunits.c b/app/core/gimpunits.c index 47fb077843..2a3d3bcb6d 100644 --- a/app/core/gimpunits.c +++ b/app/core/gimpunits.c @@ -97,7 +97,7 @@ gimp_unitrc_load (Gimp *gimp) g_return_if_fail (GIMP_IS_GIMP (gimp)); filename = gimp_personal_rc_file ("unitrc"); - scanner = gimp_scanner_new (filename, &error); + scanner = gimp_scanner_new_file (filename, &error); g_free (filename); if (! scanner) @@ -174,16 +174,17 @@ gimp_unitrc_save (Gimp *gimp) filename = gimp_personal_rc_file ("unitrc"); - writer = gimp_config_writer_new (filename, - TRUE, - "GIMP units\n\n" - "This file contains the user unit database. " - "You can edit this list with the unit " - "editor. You are not supposed to edit it " - "manually, but of course you can do.\n" - "This file will be entirely rewritten every " - "time you quit the gimp.", - NULL); + writer = + gimp_config_writer_new_file (filename, + TRUE, + "GIMP units\n\n" + "This file contains the user unit database. " + "You can edit this list with the unit " + "editor. You are not supposed to edit it " + "manually, but of course you can do.\n" + "This file will be entirely rewritten every " + "time you quit the gimp.", + NULL); g_free (filename); diff --git a/app/gui/session.c b/app/gui/session.c index ee13f3c998..9eb478d4ae 100644 --- a/app/gui/session.c +++ b/app/gui/session.c @@ -80,7 +80,7 @@ session_init (Gimp *gimp) g_return_if_fail (GIMP_IS_GIMP (gimp)); filename = gimp_personal_rc_file ("sessionrc"); - scanner = gimp_scanner_new (filename, &error); + scanner = gimp_scanner_new_file (filename, &error); g_free (filename); if (! scanner) @@ -205,18 +205,19 @@ session_save (Gimp *gimp) filename = gimp_personal_rc_file ("sessionrc"); - writer = gimp_config_writer_new (filename, - TRUE, - "GIMP sessionrc\n\n" - "This file takes session-specific info " - "(that is info, you want to keep between " - "two gimp-sessions). You are not supposed " - "to edit it manually, but of course you " - "can do.\n" - "This file will be entirely rewritten " - "every time you quit the gimp. If this " - "file isn't found, defaults are used.", - NULL); + writer = + gimp_config_writer_new_file (filename, + TRUE, + "GIMP sessionrc\n\n" + "This file takes session-specific info " + "(that is info, you want to keep between " + "two gimp-sessions). You are not supposed " + "to edit it manually, but of course you " + "can do.\n" + "This file will be entirely rewritten " + "every time you quit the gimp. If this " + "file isn't found, defaults are used.", + NULL); if (!writer) return; diff --git a/app/plug-in/plug-in-rc.c b/app/plug-in/plug-in-rc.c index 161bd0592e..a16333b557 100644 --- a/app/plug-in/plug-in-rc.c +++ b/app/plug-in/plug-in-rc.c @@ -79,7 +79,7 @@ plug_in_rc_parse (Gimp *gimp, g_return_val_if_fail (GIMP_IS_GIMP (gimp), FALSE); g_return_val_if_fail (filename != NULL, FALSE); - scanner = gimp_scanner_new (filename, &error); + scanner = gimp_scanner_new_file (filename, &error); if (! scanner) return TRUE; @@ -391,13 +391,13 @@ plug_in_rc_write (GSList *plug_in_defs, GSList *list2; gint i; - writer = gimp_config_writer_new (filename, - FALSE, - "GIMP plug-ins\n\n" - "This file can safely be removed and will " - "be automatically regenerated by querying " - "the installed plugins.", - error); + writer = gimp_config_writer_new_file (filename, + FALSE, + "GIMP plug-ins\n\n" + "This file can safely be removed and " + "will be automatically regenerated by " + "querying the installed plugins.", + error); if (!writer) return FALSE; diff --git a/app/tools/tool_options.c b/app/tools/tool_options.c index 56400f7255..0f0f81072b 100644 --- a/app/tools/tool_options.c +++ b/app/tools/tool_options.c @@ -215,12 +215,12 @@ gimp_tool_options_serialize (GimpToolOptions *tool_options, filename = gimp_tool_options_build_filename (tool_options, extension); - retval = gimp_config_serialize (G_OBJECT (tool_options), - filename, - "GIMP tool options", - "end of tool options", - NULL, - error); + retval = gimp_config_serialize_to_file (G_OBJECT (tool_options), + filename, + "GIMP tool options", + "end of tool options", + NULL, + error); g_free (filename); @@ -240,10 +240,10 @@ gimp_tool_options_deserialize (GimpToolOptions *tool_options, filename = gimp_tool_options_build_filename (tool_options, extension); - retval = gimp_config_deserialize (G_OBJECT (tool_options), - filename, - NULL, - error); + retval = gimp_config_deserialize_file (G_OBJECT (tool_options), + filename, + NULL, + error); g_free (filename); diff --git a/app/widgets/gimpdevices.c b/app/widgets/gimpdevices.c index 547e8e76c8..5b62037bd2 100644 --- a/app/widgets/gimpdevices.c +++ b/app/widgets/gimpdevices.c @@ -128,10 +128,10 @@ gimp_devices_restore (Gimp *gimp) filename = gimp_personal_rc_file ("devicerc"); - if (! gimp_config_deserialize (G_OBJECT (manager->device_info_list), - filename, - gimp, - &error)) + if (! gimp_config_deserialize_file (G_OBJECT (manager->device_info_list), + filename, + gimp, + &error)) { if (error->code != GIMP_CONFIG_ERROR_OPEN_ENOENT) g_message (error->message); @@ -170,12 +170,12 @@ gimp_devices_save (Gimp *gimp) filename = gimp_personal_rc_file ("devicerc"); - if (! gimp_config_serialize (G_OBJECT (manager->device_info_list), - filename, - "GIMP devicerc", - "end of devicerc", - NULL, - &error)) + if (! gimp_config_serialize_to_file (G_OBJECT (manager->device_info_list), + filename, + "GIMP devicerc", + "end of devicerc", + NULL, + &error)) { g_message (error->message); g_error_free (error); diff --git a/libgimpbase/gimpparasite.c b/libgimpbase/gimpparasite.c index 79e1462b87..e30d67b2ba 100644 --- a/libgimpbase/gimpparasite.c +++ b/libgimpbase/gimpparasite.c @@ -184,7 +184,7 @@ gimp_parasite_name (const GimpParasite *parasite) return NULL; } -gpointer +gconstpointer gimp_parasite_data (const GimpParasite *parasite) { if (parasite) diff --git a/libgimpbase/gimpparasite.h b/libgimpbase/gimpparasite.h index aadbadbd8e..c16e3de023 100644 --- a/libgimpbase/gimpparasite.h +++ b/libgimpbase/gimpparasite.h @@ -50,27 +50,27 @@ struct _GimpParasite }; -GimpParasite * gimp_parasite_new (const gchar *name, - guint32 flags, - guint32 size, - const gpointer data); -void gimp_parasite_free (GimpParasite *parasite); +GimpParasite * gimp_parasite_new (const gchar *name, + guint32 flags, + guint32 size, + const gpointer data); +void gimp_parasite_free (GimpParasite *parasite); -GimpParasite * gimp_parasite_copy (const GimpParasite *parasite); +GimpParasite * gimp_parasite_copy (const GimpParasite *parasite); -gboolean gimp_parasite_compare (const GimpParasite *a, - const GimpParasite *b); +gboolean gimp_parasite_compare (const GimpParasite *a, + const GimpParasite *b); -gboolean gimp_parasite_is_type (const GimpParasite *parasite, - const gchar *name); -gboolean gimp_parasite_is_persistent (const GimpParasite *parasite); -gboolean gimp_parasite_is_undoable (const GimpParasite *parasite); -gboolean gimp_parasite_has_flag (const GimpParasite *parasite, - gulong flag); -gulong gimp_parasite_flags (const GimpParasite *parasite); -const gchar * gimp_parasite_name (const GimpParasite *parasite); -gpointer gimp_parasite_data (const GimpParasite *parasite); -glong gimp_parasite_data_size (const GimpParasite *parasite); +gboolean gimp_parasite_is_type (const GimpParasite *parasite, + const gchar *name); +gboolean gimp_parasite_is_persistent (const GimpParasite *parasite); +gboolean gimp_parasite_is_undoable (const GimpParasite *parasite); +gboolean gimp_parasite_has_flag (const GimpParasite *parasite, + gulong flag); +gulong gimp_parasite_flags (const GimpParasite *parasite); +const gchar * gimp_parasite_name (const GimpParasite *parasite); +gconstpointer gimp_parasite_data (const GimpParasite *parasite); +glong gimp_parasite_data_size (const GimpParasite *parasite); G_END_DECLS diff --git a/libgimpconfig/gimpconfig-iface.c b/libgimpconfig/gimpconfig-iface.c index fb1d81c070..ced32b0b61 100644 --- a/libgimpconfig/gimpconfig-iface.c +++ b/libgimpconfig/gimpconfig-iface.c @@ -171,7 +171,7 @@ gimp_config_iface_reset (GObject *object) } /** - * gimp_config_serialize: + * gimp_config_serialize_to_file: * @object: a #GObject that implements the #GimpConfigInterface. * @filename: the name of the file to write the configuration to. * @header: optional file header (must be ASCII only) @@ -187,12 +187,12 @@ gimp_config_iface_reset (GObject *object) * Return value: %TRUE if serialization succeeded, %FALSE otherwise. **/ gboolean -gimp_config_serialize (GObject *object, - const gchar *filename, - const gchar *header, - const gchar *footer, - gpointer data, - GError **error) +gimp_config_serialize_to_file (GObject *object, + const gchar *filename, + const gchar *header, + const gchar *footer, + gpointer data, + GError **error) { GimpConfigInterface *gimp_config_iface; GimpConfigWriter *writer; @@ -202,11 +202,9 @@ gimp_config_serialize (GObject *object, g_return_val_if_fail (error == NULL || *error == NULL, FALSE); gimp_config_iface = GIMP_GET_CONFIG_INTERFACE (object); - g_return_val_if_fail (gimp_config_iface != NULL, FALSE); - writer = gimp_config_writer_new (filename, TRUE, header, error); - + writer = gimp_config_writer_new_file (filename, TRUE, header, error); if (!writer) return FALSE; @@ -215,6 +213,38 @@ gimp_config_serialize (GObject *object, return gimp_config_writer_finish (writer, footer, error); } +/** + * gimp_config_serialize_to_string: + * @object: a #GObject that implements the #GimpConfigInterface. + * @data: user data passed to the serialize implementation. + * + * Serializes the object properties of @object to a string. + * + * Return value: a newly allocated %NUL-terminated string. + **/ +gchar * +gimp_config_serialize_to_string (GObject *object, + gpointer data) +{ + GimpConfigInterface *gimp_config_iface; + GimpConfigWriter *writer; + GString *str; + + g_return_val_if_fail (G_IS_OBJECT (object), NULL); + + gimp_config_iface = GIMP_GET_CONFIG_INTERFACE (object); + g_return_val_if_fail (gimp_config_iface != NULL, FALSE); + + str = g_string_new (NULL); + writer = gimp_config_writer_new_string (str); + + gimp_config_iface->serialize (object, writer, data); + + gimp_config_writer_finish (writer, NULL, NULL); + + return g_string_free (str, FALSE); +} + /** * gimp_config_deserialize: * @object: a #GObject that implements the #GimpConfigInterface. @@ -230,10 +260,10 @@ gimp_config_serialize (GObject *object, * Return value: %TRUE if deserialization succeeded, %FALSE otherwise. **/ gboolean -gimp_config_deserialize (GObject *object, - const gchar *filename, - gpointer data, - GError **error) +gimp_config_deserialize_file (GObject *object, + const gchar *filename, + gpointer data, + GError **error) { GimpConfigInterface *gimp_config_iface; GScanner *scanner; @@ -244,11 +274,9 @@ gimp_config_deserialize (GObject *object, g_return_val_if_fail (error == NULL || *error == NULL, FALSE); gimp_config_iface = GIMP_GET_CONFIG_INTERFACE (object); - g_return_val_if_fail (gimp_config_iface != NULL, FALSE); - scanner = gimp_scanner_new (filename, error); - + scanner = gimp_scanner_new_file (filename, error); if (! scanner) return FALSE; @@ -262,6 +290,49 @@ gimp_config_deserialize (GObject *object, return success; } +/** + * gimp_config_deserialize_string: + * @object: a #GObject that implements the #GimpConfigInterface. + * @text: string to deserialize (in UTF-8 encoding) + * @text_len: length of @text in bytes or -1 + * @error: + * + * Configures @object from @text. Basically this function creates a + * properly configured #GScanner for you and calls the deserialize + * function of the @object's #GimpConfigInterface. + * + * Return value: %TRUE if deserialization succeeded, %FALSE otherwise. + **/ +gboolean +gimp_config_deserialize_string (GObject *object, + const gchar *text, + gint text_len, + gpointer data, + GError **error) +{ + GimpConfigInterface *gimp_config_iface; + GScanner *scanner; + gboolean success; + + g_return_val_if_fail (G_IS_OBJECT (object), FALSE); + g_return_val_if_fail (text != NULL || text_len == 0, FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + gimp_config_iface = GIMP_GET_CONFIG_INTERFACE (object); + g_return_val_if_fail (gimp_config_iface != NULL, FALSE); + + scanner = gimp_scanner_new_string (text, text_len, error); + + success = gimp_config_iface->deserialize (object, scanner, 0, data); + + gimp_scanner_destroy (scanner); + + if (! success) + g_assert (error == NULL || *error != NULL); + + return success; +} + gboolean gimp_config_deserialize_return (GScanner *scanner, GTokenType expected_token, diff --git a/libgimpconfig/gimpconfig-iface.h b/libgimpconfig/gimpconfig-iface.h index 50d462d3f8..cc14848adb 100644 --- a/libgimpconfig/gimpconfig-iface.h +++ b/libgimpconfig/gimpconfig-iface.h @@ -71,17 +71,23 @@ typedef void (* GimpConfigForeachFunc) (const gchar *key, GType gimp_config_interface_get_type (void) G_GNUC_CONST; -gboolean gimp_config_serialize (GObject *object, +gboolean gimp_config_serialize_to_file (GObject *object, const gchar *filename, const gchar *header, const gchar *footer, gpointer data, GError **error); -gboolean gimp_config_deserialize (GObject *object, +gchar * gimp_config_serialize_to_string (GObject *object, + gpointer data); +gboolean gimp_config_deserialize_file (GObject *object, const gchar *filename, gpointer data, GError **error); - +gboolean gimp_config_deserialize_string (GObject *object, + const gchar *text, + gint text_len, + gpointer data, + GError **error); gboolean gimp_config_deserialize_return (GScanner *scanner, GTokenType expected_token, gint nest_level); diff --git a/libgimpconfig/gimpconfigwriter.c b/libgimpconfig/gimpconfigwriter.c index 218c4a7414..5b38e3a4c9 100644 --- a/libgimpconfig/gimpconfigwriter.c +++ b/libgimpconfig/gimpconfigwriter.c @@ -47,15 +47,27 @@ #include "gimp-intl.h" +struct _GimpConfigWriter +{ + gint fd; + gchar *filename; + gchar *tmpname; + GError *error; + GString *buffer; + gint depth; + gint marker; +}; + + 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) +gimp_config_writer_new_file (const gchar *filename, + gboolean safe, + const gchar *header, + GError **error) { GimpConfigWriter *writer; gchar *tmpname = NULL; @@ -111,7 +123,7 @@ gimp_config_writer_new (const gchar *filename, } GimpConfigWriter * -gimp_config_writer_new_from_fd (gint fd) +gimp_config_writer_new_fd (gint fd) { GimpConfigWriter *writer; @@ -125,6 +137,20 @@ gimp_config_writer_new_from_fd (gint fd) return writer; } +GimpConfigWriter * +gimp_config_writer_new_string (GString *string) +{ + GimpConfigWriter *writer; + + g_return_val_if_fail (string != NULL, NULL); + + writer = g_new0 (GimpConfigWriter, 1); + + writer->buffer = string; + + return writer; +} + void gimp_config_writer_open (GimpConfigWriter *writer, const gchar *name) @@ -237,13 +263,16 @@ gimp_config_writer_close (GimpConfigWriter *writer) 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); + if (writer->fd) + { + 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); + } } } @@ -273,12 +302,19 @@ gimp_config_writer_finish (GimpConfigWriter *writer, gimp_config_writer_comment (writer, footer); } - success = gimp_config_writer_close_file (writer, error); + if (writer->fd) + { + success = gimp_config_writer_close_file (writer, error); - g_free (writer->filename); - g_free (writer->tmpname); + g_free (writer->filename); + g_free (writer->tmpname); - g_string_free (writer->buffer, TRUE); + g_string_free (writer->buffer, TRUE); + } + else + { + success = TRUE; + } g_free (writer); @@ -335,6 +371,8 @@ static gboolean gimp_config_writer_close_file (GimpConfigWriter *writer, GError **error) { + g_return_val_if_fail (writer->fd != 0, FALSE); + if (! writer->filename) return TRUE; diff --git a/libgimpconfig/gimpconfigwriter.h b/libgimpconfig/gimpconfigwriter.h index bff89a296e..a0c6804241 100644 --- a/libgimpconfig/gimpconfigwriter.h +++ b/libgimpconfig/gimpconfigwriter.h @@ -23,24 +23,12 @@ #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, +GimpConfigWriter * gimp_config_writer_new_file (const gchar *filename, gboolean safe, const gchar *header, GError **error); -GimpConfigWriter * gimp_config_writer_new_from_fd (gint fd); +GimpConfigWriter * gimp_config_writer_new_fd (gint fd); +GimpConfigWriter * gimp_config_writer_new_string (GString *string); void gimp_config_writer_open (GimpConfigWriter *writer, const gchar *name); diff --git a/libgimpconfig/gimpscanner.c b/libgimpconfig/gimpscanner.c index 64ef64dc54..43f854265a 100644 --- a/libgimpconfig/gimpscanner.c +++ b/libgimpconfig/gimpscanner.c @@ -49,21 +49,23 @@ /* local function prototypes */ -static void gimp_scanner_message (GScanner *scanner, - gchar *message, - gboolean is_error); +static GScanner * gimp_scanner_new (GError **error); +static void gimp_scanner_message (GScanner *scanner, + gchar *message, + gboolean is_error); /* public functions */ GScanner * -gimp_scanner_new (const gchar *filename, - GError **error) +gimp_scanner_new_file (const gchar *filename, + GError **error) { gint fd; GScanner *scanner; g_return_val_if_fail (filename != NULL, NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); fd = open (filename, O_RDONLY); @@ -78,13 +80,43 @@ gimp_scanner_new (const gchar *filename, return NULL; } - scanner = g_scanner_new (NULL); + scanner = gimp_scanner_new (error); g_scanner_input_file (scanner, fd); + scanner->input_name = g_strdup (filename); + + return scanner; +} + +GScanner * +gimp_scanner_new_string (const gchar *text, + gint text_len, + GError **error) +{ + GScanner *scanner; + + g_return_val_if_fail (text != NULL || text_len == 0, NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + + if (text_len < 0) + text_len = strlen (text); + + scanner = gimp_scanner_new (error); + + g_scanner_input_text (scanner, text, text_len); + + return scanner; +} + +static GScanner * +gimp_scanner_new (GError **error) +{ + GScanner *scanner; + + scanner = g_scanner_new (NULL); scanner->user_data = error; scanner->msg_handler = gimp_scanner_message; - scanner->input_name = g_strdup (filename); scanner->config->cset_identifier_first = ( G_CSET_a_2_z G_CSET_A_2_Z ); scanner->config->cset_identifier_nth = ( G_CSET_a_2_z G_CSET_A_2_Z @@ -349,8 +381,13 @@ gimp_scanner_message (GScanner *scanner, /* we don't expect warnings */ g_return_if_fail (is_error); - g_set_error (error, - GIMP_CONFIG_ERROR, GIMP_CONFIG_ERROR_PARSE, - _("Error while parsing '%s' in line %d:\n%s"), - scanner->input_name, scanner->line, message); + if (scanner->input_name) + g_set_error (error, + GIMP_CONFIG_ERROR, GIMP_CONFIG_ERROR_PARSE, + _("Error while parsing '%s' in line %d:\n%s"), + scanner->input_name, scanner->line, message); + else + g_set_error (error, + GIMP_CONFIG_ERROR, GIMP_CONFIG_ERROR_PARSE, + "Error parsing internal buffer: %s", message); } diff --git a/libgimpconfig/gimpscanner.h b/libgimpconfig/gimpscanner.h index 454dbd3d47..59697750bc 100644 --- a/libgimpconfig/gimpscanner.h +++ b/libgimpconfig/gimpscanner.h @@ -24,7 +24,10 @@ #define __GIMP_SCANNER_H__ -GScanner * gimp_scanner_new (const gchar *filename, +GScanner * gimp_scanner_new_file (const gchar *filename, + GError **error); +GScanner * gimp_scanner_new_string (const gchar *text, + gint text_len, GError **error); void gimp_scanner_destroy (GScanner *scanner);