diff --git a/ChangeLog b/ChangeLog index be84584c5a..b0f1105f75 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,22 @@ +2003-09-15 Sven Neumann + + * app/config/Makefile.am + * app/config/config-types.h + * app/config/gimpxmlparser.[ch]: new files that hold a simple XML + parser based on GMarkupParser. It's not a full-featured XML parser; + it only adds transparent handling of encodings to GMarkupParser + and provides a convenient API to deal with files or IO channels. + + * app/vectors/gimpvectors-import.c: use the new GimpXmlParser. + + * app/vectors/gimpvectors-export.c: write encoding attribute. + + * app/tips-dialog.c + * app/tips-parser.c: use the new GimpXmlParser. + + * app/vectors/Makefile.am: had to add one of those truly ugly + hacks here in order to get the application linked. + 2003-09-15 Michael Natterer * app/widgets/gimpitemtreeview.c (gimp_item_tree_view_constructor): diff --git a/app/config/Makefile.am b/app/config/Makefile.am index 4bd521a680..f431414282 100644 --- a/app/config/Makefile.am +++ b/app/config/Makefile.am @@ -37,7 +37,9 @@ libappconfig_a_SOURCES = \ gimprc.h \ gimprc-blurbs.h \ gimpscanner.c \ - gimpscanner.h + gimpscanner.h \ + gimpxmlparser.c \ + gimpxmlparser.h AM_CPPFLAGS = \ -DG_LOG_DOMAIN=\"Gimp-Config\" \ diff --git a/app/config/config-types.h b/app/config/config-types.h index 6b9ef07d9f..09a8513a8a 100644 --- a/app/config/config-types.h +++ b/app/config/config-types.h @@ -31,6 +31,7 @@ typedef struct _GimpPluginConfig GimpPluginConfig; typedef struct _GimpRc GimpRc; typedef struct _GimpConfigWriter GimpConfigWriter; +typedef struct _GimpXmlParser GimpXmlParser; #endif /* __CONFIG_TYPES_H__ */ diff --git a/app/config/gimpxmlparser.c b/app/config/gimpxmlparser.c new file mode 100644 index 0000000000..2e2053e803 --- /dev/null +++ b/app/config/gimpxmlparser.c @@ -0,0 +1,248 @@ +/* The GIMP -- an image manipulation program + * Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis + * + * GimpXmlParser + * Copyright (C) 2003 Sven Neumann + * + * 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 + +#include + +#include "config-types.h" + +#include "gimpxmlparser.h" + + +struct _GimpXmlParser +{ + GMarkupParseContext *context; +}; + + +static gchar * parse_encoding (const gchar *text, + gint text_len); + + +/** + * gimp_xml_parser_new: + * @parser: a #GMarkupParser + * @user_data: user data to pass to #GMarkupParser functions + * + * GimpXmlParser is a thin wrapper around GMarkupParser. This function + * creates one for you and sets up a GMarkupParseContext. + * + * Return value: a new #GimpXmlParser + **/ +GimpXmlParser * +gimp_xml_parser_new (const GMarkupParser *markup_parser, + gpointer user_data) +{ + GimpXmlParser *parser; + + g_return_val_if_fail (markup_parser != NULL, NULL); + + parser = g_new (GimpXmlParser, 1); + + parser->context = g_markup_parse_context_new (markup_parser, + 0, user_data, NULL); + + return parser; +} + +/** + * gimp_xml_parser_parse_file: + * @parser: a #GimpXmlParser + * @filename: name of a file to parse + * @error: return location for possible errors + * + * This function creates a GIOChannel for @filename and calls + * gimp_xml_parser_parse_io_channel() for you. + * + * Return value: %TRUE on success, %FALSE otherwise + **/ +gboolean +gimp_xml_parser_parse_file (GimpXmlParser *parser, + const gchar *filename, + GError **error) +{ + GIOChannel *io; + gboolean success; + + g_return_val_if_fail (parser != NULL, FALSE); + g_return_val_if_fail (filename != NULL, FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + io = g_io_channel_new_file (filename, "r", error); + if (!io) + return FALSE; + + success = gimp_xml_parser_parse_io_channel (parser, io, error); + + g_io_channel_unref (io); + + return success; +} + +/** + * gimp_xml_parser_parse_io_channel: + * @parser: a #GimpXmlParser + * @io: a #GIOChannel + * @error: return location for possible errors + * + * Makes @parser read from the specified @io channel. This function + * returns when the GIOChannel becomes empty (end of file) or an + * error occurs, either reading from @io or parsing the read data. + * + * This function tries to determine the character encoding from the + * XML header and converts the content to UTF-8 for you. + * + * Return value: %TRUE on success, %FALSE otherwise + **/ +gboolean +gimp_xml_parser_parse_io_channel (GimpXmlParser *parser, + GIOChannel *io, + GError **error) +{ + GIOStatus status; + guchar buffer[8196]; + gsize len = 0; + gsize bytes; + const gchar *io_encoding; + gchar *encoding = NULL; + + g_return_val_if_fail (parser != NULL, FALSE); + g_return_val_if_fail (io != NULL, FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + io_encoding = g_io_channel_get_encoding (io); + if (io_encoding && strcmp (io_encoding, "UTF-8")) + { + g_warning ("gimp_xml_parser_parse_io_channel():\n" + "The encoding has already been set on this GIOChannel!"); + return FALSE; + } + + /* try to determine the encoding */ + while (len < sizeof (buffer) && !encoding) + { + status = g_io_channel_read_chars (io, + buffer + len, 1, &bytes, error); + len += bytes; + + if (status == G_IO_STATUS_ERROR) + return FALSE; + if (status == G_IO_STATUS_EOF) + break; + + encoding = parse_encoding (buffer, len); + } + + if (encoding) + { + if (!g_io_channel_set_encoding (io, encoding, error)) + return FALSE; + + g_free (encoding); + } + + while (TRUE) + { + if (!g_markup_parse_context_parse (parser->context, buffer, len, error)) + return FALSE; + + status = g_io_channel_read_chars (io, + buffer, sizeof (buffer), &len, error); + + switch (status) + { + case G_IO_STATUS_ERROR: + return FALSE; + case G_IO_STATUS_EOF: + return g_markup_parse_context_end_parse (parser->context, error); + case G_IO_STATUS_NORMAL: + case G_IO_STATUS_AGAIN: + break; + } + } +} + +/** + * gimp_xml_parser_free: + * @parser: a #GimpXmlParser + * + * Frees the resources allocated for @parser. You must not access + * @parser after calling this function. + **/ +void +gimp_xml_parser_free (GimpXmlParser *parser) +{ + g_return_if_fail (parser != NULL); + + g_markup_parse_context_free (parser->context); + g_free (parser); +} + + +static gchar * +parse_encoding (const gchar *text, + gint text_len) +{ + const gchar *start; + const gchar *end; + gint i; + + g_return_val_if_fail (text, NULL); + + if (text_len < 20) + return NULL; + + start = g_strstr_len (text, text_len, ""); + if (!end) + return NULL; + + text_len = end - start; + if (text_len < 12) + return NULL; + + start = g_strstr_len (start + 1, text_len - 1, "encoding="); + if (!start) + return NULL; + + start += 9; + if (*start != '\"' && *start != '\'') + return NULL; + + text_len = end - start; + if (text_len < 1) + return NULL; + + for (i = 1; i < text_len; i++) + if (start[i] == start[0]) + break; + + if (i == text_len || i < 3) + return NULL; + + return g_strndup (start + 1, i - 1); +} diff --git a/app/config/gimpxmlparser.h b/app/config/gimpxmlparser.h new file mode 100644 index 0000000000..d9515550ee --- /dev/null +++ b/app/config/gimpxmlparser.h @@ -0,0 +1,37 @@ +/* The GIMP -- an image manipulation program + * Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis + * + * GimpXmlParser + * Copyright (C) 2003 Sven Neumann + * + * 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_XML_PARSER_H__ +#define __GIMP_XML_PARSER_H__ + + +GimpXmlParser * gimp_xml_parser_new (const GMarkupParser *markup_parser, + gpointer user_data); +gboolean gimp_xml_parser_parse_file (GimpXmlParser *parser, + const gchar *filename, + GError **error); +gboolean gimp_xml_parser_parse_io_channel (GimpXmlParser *parser, + GIOChannel *io, + GError **error); +void gimp_xml_parser_free (GimpXmlParser *parser); + + +#endif /* __GIMP_XML_PARSER_H__ */ diff --git a/app/dialogs/tips-dialog.c b/app/dialogs/tips-dialog.c index 3761b41af1..280096847d 100644 --- a/app/dialogs/tips-dialog.c +++ b/app/dialogs/tips-dialog.c @@ -79,16 +79,37 @@ tips_dialog_create (Gimp *gimp) GError *error = NULL; gchar *filename; - filename = g_build_filename (gimp_data_directory (), "tips", + filename = g_build_filename (gimp_data_directory (), "tips", "gimp-tips.xml", NULL); tips = gimp_tips_from_file (filename, &error); g_free (filename); - if (error) + if (!tips) { - tips = g_list_prepend (tips, - gimp_tip_new (_("The GIMP tips file could not be parsed correctly!"), error->message)); + GimpTip *tip; + + if (error->code == G_FILE_ERROR_NOENT) + { + tip = gimp_tip_new (_("Your GIMP tips file appears to be missing!"), + NULL); + tip->thetip = g_strdup_printf (_("There should be a file called '%s'. " + "Please check your installation."), + filename); + } + else + { + tip = gimp_tip_new (_("The GIMP tips file could not be parsed!"), + error->message); + } + + tips = g_list_prepend (tips, tip); + g_error_free (error); + } + else if (error) + { + g_printerr ("Error while parsing '%s': %s", + filename, error->message); g_error_free (error); } } @@ -122,7 +143,7 @@ tips_dialog_create (Gimp *gimp) config); vbox = gtk_vbox_new (FALSE, 0); - gtk_container_add (GTK_CONTAINER (tips_dialog), vbox); + gtk_container_add (GTK_CONTAINER (tips_dialog), vbox); gtk_widget_show (vbox); hbox = gtk_hbox_new (FALSE, 4); @@ -151,7 +172,7 @@ tips_dialog_create (Gimp *gimp) gtk_box_pack_end (GTK_BOX (hbox), vbox2, FALSE, FALSE, 0); gtk_widget_show (vbox2); - filename = g_build_filename (gimp_data_directory (), + filename = g_build_filename (gimp_data_directory (), "images", "wilber-tips.png", NULL); wilber = gdk_pixbuf_new_from_file (filename, NULL); g_free (filename); @@ -250,7 +271,7 @@ tips_set_labels (GimpTip *tip) gtk_widget_show (welcome_label); else gtk_widget_hide (welcome_label); - + gtk_label_set_markup (GTK_LABEL (welcome_label), tip->welcome); gtk_label_set_markup (GTK_LABEL (thetip_label), tip->thetip); } diff --git a/app/dialogs/tips-parser.c b/app/dialogs/tips-parser.c index 136799829e..aa22b9007f 100644 --- a/app/dialogs/tips-parser.c +++ b/app/dialogs/tips-parser.c @@ -21,11 +21,13 @@ #include "config.h" -#include #include #include +#include "config/config-types.h" +#include "config/gimpxmlparser.h" + #include "tips-parser.h" #include "gimp-intl.h" @@ -51,7 +53,6 @@ typedef enum typedef struct _TipsParser TipsParser; struct _TipsParser { - const gchar *filename; TipsParserState state; TipsParserState last_known_state; const gchar *locale; @@ -80,9 +81,6 @@ static void tips_parser_characters (GMarkupParseContext *context, gsize text_len, gpointer user_data, GError **error); -static void tips_parser_error (GMarkupParseContext *context, - GError *error, - gpointer user_data); static void tips_parser_start_markup (TipsParser *parser, const gchar *markup_name); @@ -103,7 +101,7 @@ static const GMarkupParser markup_parser = tips_parser_end_element, tips_parser_characters, NULL, /* passthrough */ - tips_parser_error + NULL /* error */ }; @@ -134,44 +132,30 @@ gimp_tip_free (GimpTip *tip) * gimp_tips_from_file: * @filename: the name of the tips file to parse * @error: return location for a #GError - * + * * Reads a gimp-tips XML file, creates a new #GimpTip for * each tip entry and returns a #GList of them. If a parser * error occurs at some point, the uncompleted list is * returned and @error is set (unless @error is %NULL). * The message set in @error contains a detailed description * of the problem. - * + * * Return value: a #Glist of #GimpTips. **/ GList * gimp_tips_from_file (const gchar *filename, GError **error) { - GMarkupParseContext *context; - TipsParser *parser; - const gchar *tips_locale; - FILE *fp; - gsize bytes; - gchar buf[4096]; - GList *tips = NULL; + GimpXmlParser *xml_parser; + TipsParser *parser; + const gchar *tips_locale; + GList *tips = NULL; g_return_val_if_fail (filename != NULL, NULL); g_return_val_if_fail (error == NULL || *error == NULL, NULL); - fp = fopen (filename, "r"); - if (!fp) - { - g_set_error (error, 0, 0, - _("Your GIMP tips file appears to be missing! " - "There should be a file called '%s'. " - "Please check your installation."), filename); - return NULL; - } - parser = g_new0 (TipsParser, 1); - parser->filename = filename; - parser->value = g_string_new (NULL); + parser->value = g_string_new (NULL); /* This is a special string to specify the language identifier to look for in the gimp-tips.xml file. Please translate the C in it @@ -189,17 +173,11 @@ gimp_tips_from_file (const gchar *filename, else g_warning ("Wrong translation for 'tips-locale:', fix the translation!"); - context = g_markup_parse_context_new (&markup_parser, 0, parser, NULL); + xml_parser = gimp_xml_parser_new (&markup_parser, parser); - while ((bytes = fread (buf, sizeof (gchar), sizeof (buf), fp)) > 0 && - g_markup_parse_context_parse (context, buf, bytes, error)) - ; + gimp_xml_parser_parse_file (xml_parser, filename, error); - if (error == NULL || *error == NULL) - g_markup_parse_context_end_parse (context, error); - - fclose (fp); - g_markup_parse_context_free (context); + gimp_xml_parser_free (xml_parser); tips = g_list_reverse (parser->tips); @@ -249,7 +227,7 @@ tips_parser_start_element (GMarkupParseContext *context, else tips_parser_start_unknown (parser); break; - + case TIPS_IN_TIP: if (strcmp (element_name, "welcome") == 0) { @@ -264,10 +242,10 @@ tips_parser_start_element (GMarkupParseContext *context, else tips_parser_start_unknown (parser); break; - + case TIPS_IN_WELCOME: case TIPS_IN_THETIP: - if (strcmp (element_name, "b" ) == 0 || + if (strcmp (element_name, "b" ) == 0 || strcmp (element_name, "big") == 0 || strcmp (element_name, "tt" ) == 0) tips_parser_start_markup (parser, element_name); @@ -304,7 +282,7 @@ tips_parser_end_element (GMarkupParseContext *context, parser->current_tip = NULL; parser->state = TIPS_IN_TIPS; break; - + case TIPS_IN_WELCOME: if (parser->markup_depth == 0) { @@ -350,7 +328,7 @@ tips_parser_characters (GMarkupParseContext *context, { gint i; - /* strip tabs, newlines and adjacent whitespace */ + /* strip tabs, newlines and adjacent whitespace */ for (i = 0; i < text_len; i++) { if (text[i] != ' ' && @@ -367,16 +345,6 @@ tips_parser_characters (GMarkupParseContext *context, } } -static void -tips_parser_error (GMarkupParseContext *context, - GError *error, - gpointer user_data) -{ - TipsParser *parser = (TipsParser *) user_data; - - g_warning ("%s: %s", parser->filename, error->message); -} - static void tips_parser_start_markup (TipsParser *parser, const gchar *markup_name) @@ -411,7 +379,7 @@ tips_parser_end_unknown (TipsParser *parser) g_assert (parser->unknown_depth > 0 && parser->state == TIPS_IN_UNKNOWN); parser->unknown_depth--; - + if (parser->unknown_depth == 0) parser->state = parser->last_known_state; } @@ -428,7 +396,7 @@ tips_parser_parse_locale (TipsParser *parser, if (strcmp (*names, "xml:lang") == 0 && **values) { parser->locale_state = (parser->locale && - strcmp (*values, parser->locale) == 0 ? + strcmp (*values, parser->locale) == 0 ? TIPS_LOCALE_MATCH : TIPS_LOCALE_MISMATCH); } @@ -439,7 +407,7 @@ tips_parser_parse_locale (TipsParser *parser, static void tips_parser_set_by_locale (TipsParser *parser, - gchar **dest) + gchar **dest) { switch (parser->locale_state) { @@ -459,7 +427,7 @@ tips_parser_set_by_locale (TipsParser *parser, g_free (*dest); *dest = g_strdup (parser->value->str); break; - + case TIPS_LOCALE_MISMATCH: break; } diff --git a/app/gui/tips-dialog.c b/app/gui/tips-dialog.c index 3761b41af1..280096847d 100644 --- a/app/gui/tips-dialog.c +++ b/app/gui/tips-dialog.c @@ -79,16 +79,37 @@ tips_dialog_create (Gimp *gimp) GError *error = NULL; gchar *filename; - filename = g_build_filename (gimp_data_directory (), "tips", + filename = g_build_filename (gimp_data_directory (), "tips", "gimp-tips.xml", NULL); tips = gimp_tips_from_file (filename, &error); g_free (filename); - if (error) + if (!tips) { - tips = g_list_prepend (tips, - gimp_tip_new (_("The GIMP tips file could not be parsed correctly!"), error->message)); + GimpTip *tip; + + if (error->code == G_FILE_ERROR_NOENT) + { + tip = gimp_tip_new (_("Your GIMP tips file appears to be missing!"), + NULL); + tip->thetip = g_strdup_printf (_("There should be a file called '%s'. " + "Please check your installation."), + filename); + } + else + { + tip = gimp_tip_new (_("The GIMP tips file could not be parsed!"), + error->message); + } + + tips = g_list_prepend (tips, tip); + g_error_free (error); + } + else if (error) + { + g_printerr ("Error while parsing '%s': %s", + filename, error->message); g_error_free (error); } } @@ -122,7 +143,7 @@ tips_dialog_create (Gimp *gimp) config); vbox = gtk_vbox_new (FALSE, 0); - gtk_container_add (GTK_CONTAINER (tips_dialog), vbox); + gtk_container_add (GTK_CONTAINER (tips_dialog), vbox); gtk_widget_show (vbox); hbox = gtk_hbox_new (FALSE, 4); @@ -151,7 +172,7 @@ tips_dialog_create (Gimp *gimp) gtk_box_pack_end (GTK_BOX (hbox), vbox2, FALSE, FALSE, 0); gtk_widget_show (vbox2); - filename = g_build_filename (gimp_data_directory (), + filename = g_build_filename (gimp_data_directory (), "images", "wilber-tips.png", NULL); wilber = gdk_pixbuf_new_from_file (filename, NULL); g_free (filename); @@ -250,7 +271,7 @@ tips_set_labels (GimpTip *tip) gtk_widget_show (welcome_label); else gtk_widget_hide (welcome_label); - + gtk_label_set_markup (GTK_LABEL (welcome_label), tip->welcome); gtk_label_set_markup (GTK_LABEL (thetip_label), tip->thetip); } diff --git a/app/gui/tips-parser.c b/app/gui/tips-parser.c index 136799829e..aa22b9007f 100644 --- a/app/gui/tips-parser.c +++ b/app/gui/tips-parser.c @@ -21,11 +21,13 @@ #include "config.h" -#include #include #include +#include "config/config-types.h" +#include "config/gimpxmlparser.h" + #include "tips-parser.h" #include "gimp-intl.h" @@ -51,7 +53,6 @@ typedef enum typedef struct _TipsParser TipsParser; struct _TipsParser { - const gchar *filename; TipsParserState state; TipsParserState last_known_state; const gchar *locale; @@ -80,9 +81,6 @@ static void tips_parser_characters (GMarkupParseContext *context, gsize text_len, gpointer user_data, GError **error); -static void tips_parser_error (GMarkupParseContext *context, - GError *error, - gpointer user_data); static void tips_parser_start_markup (TipsParser *parser, const gchar *markup_name); @@ -103,7 +101,7 @@ static const GMarkupParser markup_parser = tips_parser_end_element, tips_parser_characters, NULL, /* passthrough */ - tips_parser_error + NULL /* error */ }; @@ -134,44 +132,30 @@ gimp_tip_free (GimpTip *tip) * gimp_tips_from_file: * @filename: the name of the tips file to parse * @error: return location for a #GError - * + * * Reads a gimp-tips XML file, creates a new #GimpTip for * each tip entry and returns a #GList of them. If a parser * error occurs at some point, the uncompleted list is * returned and @error is set (unless @error is %NULL). * The message set in @error contains a detailed description * of the problem. - * + * * Return value: a #Glist of #GimpTips. **/ GList * gimp_tips_from_file (const gchar *filename, GError **error) { - GMarkupParseContext *context; - TipsParser *parser; - const gchar *tips_locale; - FILE *fp; - gsize bytes; - gchar buf[4096]; - GList *tips = NULL; + GimpXmlParser *xml_parser; + TipsParser *parser; + const gchar *tips_locale; + GList *tips = NULL; g_return_val_if_fail (filename != NULL, NULL); g_return_val_if_fail (error == NULL || *error == NULL, NULL); - fp = fopen (filename, "r"); - if (!fp) - { - g_set_error (error, 0, 0, - _("Your GIMP tips file appears to be missing! " - "There should be a file called '%s'. " - "Please check your installation."), filename); - return NULL; - } - parser = g_new0 (TipsParser, 1); - parser->filename = filename; - parser->value = g_string_new (NULL); + parser->value = g_string_new (NULL); /* This is a special string to specify the language identifier to look for in the gimp-tips.xml file. Please translate the C in it @@ -189,17 +173,11 @@ gimp_tips_from_file (const gchar *filename, else g_warning ("Wrong translation for 'tips-locale:', fix the translation!"); - context = g_markup_parse_context_new (&markup_parser, 0, parser, NULL); + xml_parser = gimp_xml_parser_new (&markup_parser, parser); - while ((bytes = fread (buf, sizeof (gchar), sizeof (buf), fp)) > 0 && - g_markup_parse_context_parse (context, buf, bytes, error)) - ; + gimp_xml_parser_parse_file (xml_parser, filename, error); - if (error == NULL || *error == NULL) - g_markup_parse_context_end_parse (context, error); - - fclose (fp); - g_markup_parse_context_free (context); + gimp_xml_parser_free (xml_parser); tips = g_list_reverse (parser->tips); @@ -249,7 +227,7 @@ tips_parser_start_element (GMarkupParseContext *context, else tips_parser_start_unknown (parser); break; - + case TIPS_IN_TIP: if (strcmp (element_name, "welcome") == 0) { @@ -264,10 +242,10 @@ tips_parser_start_element (GMarkupParseContext *context, else tips_parser_start_unknown (parser); break; - + case TIPS_IN_WELCOME: case TIPS_IN_THETIP: - if (strcmp (element_name, "b" ) == 0 || + if (strcmp (element_name, "b" ) == 0 || strcmp (element_name, "big") == 0 || strcmp (element_name, "tt" ) == 0) tips_parser_start_markup (parser, element_name); @@ -304,7 +282,7 @@ tips_parser_end_element (GMarkupParseContext *context, parser->current_tip = NULL; parser->state = TIPS_IN_TIPS; break; - + case TIPS_IN_WELCOME: if (parser->markup_depth == 0) { @@ -350,7 +328,7 @@ tips_parser_characters (GMarkupParseContext *context, { gint i; - /* strip tabs, newlines and adjacent whitespace */ + /* strip tabs, newlines and adjacent whitespace */ for (i = 0; i < text_len; i++) { if (text[i] != ' ' && @@ -367,16 +345,6 @@ tips_parser_characters (GMarkupParseContext *context, } } -static void -tips_parser_error (GMarkupParseContext *context, - GError *error, - gpointer user_data) -{ - TipsParser *parser = (TipsParser *) user_data; - - g_warning ("%s: %s", parser->filename, error->message); -} - static void tips_parser_start_markup (TipsParser *parser, const gchar *markup_name) @@ -411,7 +379,7 @@ tips_parser_end_unknown (TipsParser *parser) g_assert (parser->unknown_depth > 0 && parser->state == TIPS_IN_UNKNOWN); parser->unknown_depth--; - + if (parser->unknown_depth == 0) parser->state = parser->last_known_state; } @@ -428,7 +396,7 @@ tips_parser_parse_locale (TipsParser *parser, if (strcmp (*names, "xml:lang") == 0 && **values) { parser->locale_state = (parser->locale && - strcmp (*values, parser->locale) == 0 ? + strcmp (*values, parser->locale) == 0 ? TIPS_LOCALE_MATCH : TIPS_LOCALE_MISMATCH); } @@ -439,7 +407,7 @@ tips_parser_parse_locale (TipsParser *parser, static void tips_parser_set_by_locale (TipsParser *parser, - gchar **dest) + gchar **dest) { switch (parser->locale_state) { @@ -459,7 +427,7 @@ tips_parser_set_by_locale (TipsParser *parser, g_free (*dest); *dest = g_strdup (parser->value->str); break; - + case TIPS_LOCALE_MISMATCH: break; } diff --git a/app/vectors/Makefile.am b/app/vectors/Makefile.am index 288a442016..5b13e57d3c 100644 --- a/app/vectors/Makefile.am +++ b/app/vectors/Makefile.am @@ -35,4 +35,6 @@ libappvectors_a_SOURCES = \ gimpvectors-preview.c \ gimpvectors-preview.h +## This is a truly ugly hack +libappvectors_a_LIBADD = ../config/gimpxmlparser.o diff --git a/app/vectors/gimpvectors-export.c b/app/vectors/gimpvectors-export.c index 503399e944..53f6bf0bf1 100644 --- a/app/vectors/gimpvectors-export.c +++ b/app/vectors/gimpvectors-export.c @@ -78,7 +78,7 @@ gimp_vectors_export (const GimpImage *image, } fprintf (file, - "\n" + "\n" "\n"); fprintf (file, diff --git a/app/vectors/gimpvectors-import.c b/app/vectors/gimpvectors-import.c index 2dbd98479b..844c7f19c8 100644 --- a/app/vectors/gimpvectors-import.c +++ b/app/vectors/gimpvectors-import.c @@ -24,7 +24,6 @@ #include "config.h" -#include #include #include @@ -34,6 +33,8 @@ #include "vectors-types.h" +#include "config/gimpxmlparser.h" + #include "core/gimpimage.h" #include "core/gimpimage-undo.h" @@ -134,32 +135,19 @@ gimp_vectors_import (GimpImage *image, gboolean merge, GError **error) { - GMarkupParseContext *context; - FILE *file; - GQueue *stack; - GList *paths; - SvgHandler *base; - gboolean success = TRUE; - gsize bytes; - gchar buf[4096]; + GimpXmlParser *parser; + GQueue *stack; + GList *paths; + SvgHandler *base; + gboolean success = TRUE; g_return_val_if_fail (GIMP_IS_IMAGE (image), FALSE); g_return_val_if_fail (filename != NULL, FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - file = fopen (filename, "r"); - if (!file) - { - g_set_error (error, 0, 0, - _("Failed to open file: '%s': %s"), - filename, g_strerror (errno)); - return FALSE; - } - stack = g_queue_new (); /* the base of the stack, defines the size of the view-port */ - base = g_new0 (SvgHandler, 1); base->name = "image"; base->width = image->width; @@ -167,17 +155,11 @@ gimp_vectors_import (GimpImage *image, g_queue_push_head (stack, base); - context = g_markup_parse_context_new (&markup_parser, 0, stack, NULL); + parser = gimp_xml_parser_new (&markup_parser, stack); - while (success && - (bytes = fread (buf, sizeof (gchar), sizeof (buf), file)) > 0) - success = g_markup_parse_context_parse (context, buf, bytes, error); + success = gimp_xml_parser_parse_file (parser, filename, error); - if (success) - success = g_markup_parse_context_end_parse (context, error); - - fclose (file); - g_markup_parse_context_free (context); + gimp_xml_parser_free (parser); if (success) {