diff --git a/ChangeLog b/ChangeLog index 7cae1da517..6e682c808d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,20 @@ +2002-05-31 Michael Natterer + + * app/config/gimpscanner.[ch]: configure the scanner the same + way GimpConfig did (scanner->user_data is, if set, a GError). + Added gimp_scanner_parse_color(). Added "GError **error" to + gimp_scanner_new(). + + * app/config/gimpconfig.c: use gimp_scanner_new(). + + * app/config/gimpconfig-deserialize.c: use gimp_scanner_parse_color(). + + * app/core/gimpunits.c + * app/plug-in/plug-in-rc.c: changed accordingly. + + * app/plug-in/plug-in-rc.c: made the main parse loops consistent + with the other places using GScanner. + 2002-05-31 Maurits Rijk * plug-ins/common/checkerboard.c: applied patch from Jeroen Lamain diff --git a/app/config/gimpconfig-deserialize.c b/app/config/gimpconfig-deserialize.c index 90dcb8252d..d619b1b76f 100644 --- a/app/config/gimpconfig-deserialize.c +++ b/app/config/gimpconfig-deserialize.c @@ -505,119 +505,19 @@ gimp_config_deserialize_path (GValue *value, return G_TOKEN_RIGHT_PAREN; } -enum -{ - COLOR_RGB = 1, - COLOR_RGBA, - COLOR_HSV, - COLOR_HSVA -}; - static GTokenType gimp_config_deserialize_color (GValue *value, GParamSpec *prop_spec, GScanner *scanner) { - guint scope_id; - guint old_scope_id; - GTokenType token; + GimpRGB color; - scope_id = g_quark_from_static_string ("gimp_config_deserialize_color"); - old_scope_id = g_scanner_set_scope (scanner, scope_id); + if (! gimp_scanner_parse_color (scanner, &color)) + return G_TOKEN_NONE; - if (! g_scanner_scope_lookup_symbol (scanner, scope_id, "color-rgb")) - { - g_scanner_scope_add_symbol (scanner, scope_id, - "color-rgb", GINT_TO_POINTER (COLOR_RGB)); - g_scanner_scope_add_symbol (scanner, scope_id, - "color-rgba", GINT_TO_POINTER (COLOR_RGBA)); - g_scanner_scope_add_symbol (scanner, scope_id, - "color-hsv", GINT_TO_POINTER (COLOR_HSV)); - g_scanner_scope_add_symbol (scanner, scope_id, - "color-hsva", GINT_TO_POINTER (COLOR_HSVA)); - } + g_value_set_boxed (value, &color); - token = G_TOKEN_LEFT_PAREN; - - while (g_scanner_peek_next_token (scanner) == token) - { - token = g_scanner_get_next_token (scanner); - - switch (token) - { - case G_TOKEN_LEFT_PAREN: - token = G_TOKEN_SYMBOL; - break; - - case G_TOKEN_SYMBOL: - { - gdouble col[4] = { 0.0, 0.0, 0.0, 1.0 }; - GimpRGB color; - gint n_channels = 4; - gboolean is_hsv = FALSE; - gint i; - - switch (GPOINTER_TO_INT (scanner->value.v_symbol)) - { - case COLOR_RGB: - n_channels = 3; - /* fallthrough */ - case COLOR_RGBA: - break; - - case COLOR_HSV: - n_channels = 3; - /* fallthrough */ - case COLOR_HSVA: - is_hsv = TRUE; - break; - } - - token = G_TOKEN_FLOAT; - - for (i = 0; i < n_channels; i++) - { - if (g_scanner_peek_next_token (scanner) != token) - goto finish; - - token = g_scanner_get_next_token (scanner); - - col[i] = scanner->value.v_float; - } - - if (is_hsv) - { - GimpHSV hsv; - - gimp_hsva_set (&hsv, col[0], col[1], col[2], col[3]); - gimp_hsv_clamp (&hsv); - - gimp_hsv_to_rgb (&hsv, &color); - } - else - { - gimp_rgba_set (&color, col[0], col[1], col[2], col[3]); - gimp_rgb_clamp (&color); - } - - g_value_set_boxed (value, &color); - } - token = G_TOKEN_RIGHT_PAREN; - break; - - case G_TOKEN_RIGHT_PAREN: - goto finish; - - default: /* do nothing */ - break; - } - } - - finish: - - g_scanner_set_scope (scanner, old_scope_id); - - return token; + return G_TOKEN_RIGHT_PAREN; } static GTokenType @@ -635,12 +535,9 @@ gimp_config_deserialize_value_array (GValue *value, array_spec = G_PARAM_SPEC_VALUE_ARRAY (prop_spec); - if (g_scanner_peek_next_token (scanner) != G_TOKEN_INT) + if (! gimp_scanner_parse_int (scanner, &n_values)) return G_TOKEN_INT; - g_scanner_get_next_token (scanner); - n_values = scanner->value.v_int; - array = g_value_array_new (n_values); for (i = 0; i < n_values; i++) diff --git a/app/config/gimpconfig.c b/app/config/gimpconfig.c index c7d6207359..73457a6bfd 100644 --- a/app/config/gimpconfig.c +++ b/app/config/gimpconfig.c @@ -33,10 +33,13 @@ #include +#include "libgimpcolor/gimpcolor.h" + #include "gimpconfig.h" #include "gimpconfig-serialize.h" #include "gimpconfig-deserialize.h" #include "gimpconfig-utils.h" +#include "gimpscanner.h" #include "libgimp/gimpintl.h" @@ -58,9 +61,6 @@ static gboolean gimp_config_iface_deserialize (GObject *object, static GObject *gimp_config_iface_duplicate (GObject *object); static gboolean gimp_config_iface_equal (GObject *a, GObject *b); -static void gimp_config_scanner_message (GScanner *scanner, - gchar *message, - gboolean is_error); GType @@ -293,7 +293,6 @@ gimp_config_deserialize (GObject *object, GError **error) { GimpConfigInterface *gimp_config_iface; - gint fd; GScanner *scanner; gboolean success; @@ -305,36 +304,14 @@ gimp_config_deserialize (GObject *object, g_return_val_if_fail (gimp_config_iface != NULL, FALSE); - fd = open (filename, O_RDONLY); + scanner = gimp_scanner_new (filename, error); - if (fd == -1) - { - g_set_error (error, - GIMP_CONFIG_ERROR, - (errno == ENOENT ? - GIMP_CONFIG_ERROR_OPEN_ENOENT : GIMP_CONFIG_ERROR_OPEN), - _("Failed to open file: '%s': %s"), - filename, g_strerror (errno)); - return FALSE; - } - - scanner = g_scanner_new (NULL); - - g_scanner_input_file (scanner, fd); - - scanner->user_data = error; - scanner->msg_handler = gimp_config_scanner_message; - scanner->input_name = 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 "-_" ); - - scanner->config->scan_identifier_1char = TRUE; + if (! scanner) + return FALSE; success = gimp_config_iface->deserialize (object, scanner, 0, data); - g_scanner_destroy (scanner); - close (fd); + gimp_scanner_destroy (scanner); if (! success) g_assert (error == NULL || *error != NULL); @@ -404,22 +381,6 @@ gimp_config_string_indent (GString *string, g_string_append_len (string, " ", 4); } -static void -gimp_config_scanner_message (GScanner *scanner, - gchar *message, - gboolean is_error) -{ - GError **error = scanner->user_data; - - /* 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); -} - /** * gimp_config_duplicate: * @object: a #GObject that implements the #GimpConfigInterface. diff --git a/app/config/gimpscanner.c b/app/config/gimpscanner.c index aca3eef2fa..78ca4f306c 100644 --- a/app/config/gimpscanner.c +++ b/app/config/gimpscanner.c @@ -22,6 +22,7 @@ #include "config.h" +#include #include #include #ifdef HAVE_UNISTD_H @@ -35,13 +36,26 @@ #include #endif +#include "libgimpcolor/gimpcolor.h" + +#include "gimpconfig.h" #include "gimpscanner.h" #include "libgimp/gimpintl.h" +/* local function prototypes */ + +static void gimp_scanner_message (GScanner *scanner, + gchar *message, + gboolean is_error); + + +/* public functions */ + GScanner * -gimp_scanner_new (const gchar *filename) +gimp_scanner_new (const gchar *filename, + GError **error) { gint fd; GScanner *scanner; @@ -51,15 +65,28 @@ gimp_scanner_new (const gchar *filename) fd = open (filename, O_RDONLY); if (fd == -1) - return NULL; + { + g_set_error (error, + GIMP_CONFIG_ERROR, + (errno == ENOENT ? + GIMP_CONFIG_ERROR_OPEN_ENOENT : GIMP_CONFIG_ERROR_OPEN), + _("Failed to open file: '%s': %s"), + filename, g_strerror (errno)); + return NULL; + } scanner = g_scanner_new (NULL); - scanner->config->cset_identifier_first = ( G_CSET_a_2_z ); - scanner->config->cset_identifier_nth = ( G_CSET_a_2_z "-_" ); - g_scanner_input_file (scanner, fd); - scanner->input_name = g_strdup (filename); + + 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 "-_" ); + + scanner->config->scan_identifier_1char = TRUE; return scanner; } @@ -167,3 +194,139 @@ gimp_scanner_parse_float (GScanner *scanner, return TRUE; } + +enum +{ + COLOR_RGB = 1, + COLOR_RGBA, + COLOR_HSV, + COLOR_HSVA +}; + +gboolean +gimp_scanner_parse_color (GScanner *scanner, + GimpRGB *dest) +{ + guint scope_id; + guint old_scope_id; + GTokenType token; + + scope_id = g_quark_from_static_string ("gimp_scanner_parse_color"); + old_scope_id = g_scanner_set_scope (scanner, scope_id); + + if (! g_scanner_scope_lookup_symbol (scanner, scope_id, "color-rgb")) + { + g_scanner_scope_add_symbol (scanner, scope_id, + "color-rgb", GINT_TO_POINTER (COLOR_RGB)); + g_scanner_scope_add_symbol (scanner, scope_id, + "color-rgba", GINT_TO_POINTER (COLOR_RGBA)); + g_scanner_scope_add_symbol (scanner, scope_id, + "color-hsv", GINT_TO_POINTER (COLOR_HSV)); + g_scanner_scope_add_symbol (scanner, scope_id, + "color-hsva", GINT_TO_POINTER (COLOR_HSVA)); + } + + token = G_TOKEN_LEFT_PAREN; + + while (g_scanner_peek_next_token (scanner) == token) + { + token = g_scanner_get_next_token (scanner); + + switch (token) + { + case G_TOKEN_LEFT_PAREN: + token = G_TOKEN_SYMBOL; + break; + + case G_TOKEN_SYMBOL: + { + gdouble col[4] = { 0.0, 0.0, 0.0, 1.0 }; + GimpRGB color; + gint n_channels = 4; + gboolean is_hsv = FALSE; + gint i; + + switch (GPOINTER_TO_INT (scanner->value.v_symbol)) + { + case COLOR_RGB: + n_channels = 3; + /* fallthrough */ + case COLOR_RGBA: + break; + + case COLOR_HSV: + n_channels = 3; + /* fallthrough */ + case COLOR_HSVA: + is_hsv = TRUE; + break; + } + + token = G_TOKEN_FLOAT; + + for (i = 0; i < n_channels; i++) + { + if (! gimp_scanner_parse_float (scanner, &col[i])) + goto finish; + } + + if (is_hsv) + { + GimpHSV hsv; + + gimp_hsva_set (&hsv, col[0], col[1], col[2], col[3]); + gimp_hsv_clamp (&hsv); + + gimp_hsv_to_rgb (&hsv, &color); + } + else + { + gimp_rgba_set (&color, col[0], col[1], col[2], col[3]); + gimp_rgb_clamp (&color); + } + + *dest = color; + } + token = G_TOKEN_RIGHT_PAREN; + break; + + case G_TOKEN_RIGHT_PAREN: + goto finish; + + default: /* do nothing */ + break; + } + } + + finish: + + if (token != G_TOKEN_RIGHT_PAREN) + { + g_scanner_get_next_token (scanner); + g_scanner_unexp_token (scanner, token, NULL, NULL, NULL, + _("fatal parse error"), TRUE); + } + + g_scanner_set_scope (scanner, old_scope_id); + + return (token == G_TOKEN_RIGHT_PAREN); +} + + +/* private functions */ + +static void +gimp_scanner_message (GScanner *scanner, + gchar *message, + gboolean is_error) +{ + GError **error = scanner->user_data; + + /* 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); +} diff --git a/app/config/gimpscanner.h b/app/config/gimpscanner.h index 24ae929d03..454dbd3d47 100644 --- a/app/config/gimpscanner.h +++ b/app/config/gimpscanner.h @@ -24,21 +24,24 @@ #define __GIMP_SCANNER_H__ -GScanner * gimp_scanner_new (const gchar *filename); -void gimp_scanner_destroy (GScanner *scanner); +GScanner * gimp_scanner_new (const gchar *filename, + GError **error); +void gimp_scanner_destroy (GScanner *scanner); -gboolean gimp_scanner_parse_token (GScanner *scanner, - GTokenType token); -gboolean gimp_scanner_parse_identifier (GScanner *scanner, - const gchar *identifier); -gboolean gimp_scanner_parse_string (GScanner *scanner, - gchar **dest); -gboolean gimp_scanner_parse_string_no_validate (GScanner *scanner, - gchar **dest); -gboolean gimp_scanner_parse_int (GScanner *scanner, - gint *dest); -gboolean gimp_scanner_parse_float (GScanner *scanner, - gdouble *dest); +gboolean gimp_scanner_parse_token (GScanner *scanner, + GTokenType token); +gboolean gimp_scanner_parse_identifier (GScanner *scanner, + const gchar *identifier); +gboolean gimp_scanner_parse_string (GScanner *scanner, + gchar **dest); +gboolean gimp_scanner_parse_string_no_validate (GScanner *scanner, + gchar **dest); +gboolean gimp_scanner_parse_int (GScanner *scanner, + gint *dest); +gboolean gimp_scanner_parse_float (GScanner *scanner, + gdouble *dest); +gboolean gimp_scanner_parse_color (GScanner *scanner, + GimpRGB *dest); #endif /* __GIMP_SCANNER_H__ */ diff --git a/app/core/gimp-units.c b/app/core/gimp-units.c index 0b3bb9d489..d463ea8676 100644 --- a/app/core/gimp-units.c +++ b/app/core/gimp-units.c @@ -93,11 +93,12 @@ gimp_unitrc_load (Gimp *gimp) gchar *filename; GScanner *scanner; GTokenType token; + GError *error = NULL; g_return_if_fail (GIMP_IS_GIMP (gimp)); filename = gimp_personal_rc_file ("unitrc"); - scanner = gimp_scanner_new (filename); + scanner = gimp_scanner_new (filename, &error); g_free (filename); if (! scanner) @@ -156,6 +157,9 @@ gimp_unitrc_load (Gimp *gimp) g_scanner_unexp_token (scanner, token, NULL, NULL, scanner->scope_id == 0 ? "unit-info" : NULL, _("fatal parse error"), TRUE); + + g_message (error->message); + g_clear_error (&error); } gimp_scanner_destroy (scanner); diff --git a/app/core/gimpunits.c b/app/core/gimpunits.c index 0b3bb9d489..d463ea8676 100644 --- a/app/core/gimpunits.c +++ b/app/core/gimpunits.c @@ -93,11 +93,12 @@ gimp_unitrc_load (Gimp *gimp) gchar *filename; GScanner *scanner; GTokenType token; + GError *error = NULL; g_return_if_fail (GIMP_IS_GIMP (gimp)); filename = gimp_personal_rc_file ("unitrc"); - scanner = gimp_scanner_new (filename); + scanner = gimp_scanner_new (filename, &error); g_free (filename); if (! scanner) @@ -156,6 +157,9 @@ gimp_unitrc_load (Gimp *gimp) g_scanner_unexp_token (scanner, token, NULL, NULL, scanner->scope_id == 0 ? "unit-info" : NULL, _("fatal parse error"), TRUE); + + g_message (error->message); + g_clear_error (&error); } gimp_scanner_destroy (scanner); diff --git a/app/plug-in/plug-in-rc.c b/app/plug-in/plug-in-rc.c index 2387ffb2ac..e6a7903f62 100644 --- a/app/plug-in/plug-in-rc.c +++ b/app/plug-in/plug-in-rc.c @@ -72,10 +72,11 @@ plug_in_rc_parse (const gchar *filename) { GScanner *scanner; GTokenType token; + GError *error = NULL; g_return_val_if_fail (filename != NULL, FALSE); - scanner = gimp_scanner_new (filename); + scanner = gimp_scanner_new (filename, &error); if (! scanner) return TRUE; @@ -94,12 +95,9 @@ plug_in_rc_parse (const gchar *filename) "proc-arg", GINT_TO_POINTER (PROC_ARG)); token = G_TOKEN_LEFT_PAREN; - - do - { - if (g_scanner_get_next_token (scanner) != token) - break; + while (g_scanner_peek_next_token (scanner) == token) + { token = g_scanner_get_next_token (scanner); switch (token) @@ -125,13 +123,15 @@ plug_in_rc_parse (const gchar *filename) break; } } - while (token != G_TOKEN_EOF); if (token != G_TOKEN_LEFT_PAREN) { g_scanner_get_next_token (scanner); g_scanner_unexp_token (scanner, token, NULL, NULL, NULL, _("fatal parse error"), TRUE); + + g_message (error->message); + g_clear_error (&error); } gimp_scanner_destroy (scanner); @@ -161,11 +161,8 @@ plug_in_def_deserialize (GScanner *scanner) token = G_TOKEN_LEFT_PAREN; - do + while (g_scanner_peek_next_token (scanner) == token) { - if (g_scanner_peek_next_token (scanner) != token) - break; - token = g_scanner_get_next_token (scanner); switch (token) @@ -216,7 +213,6 @@ plug_in_def_deserialize (GScanner *scanner) break; } } - while (token != G_TOKEN_EOF); if (token == G_TOKEN_LEFT_PAREN) { diff --git a/libgimpconfig/gimpconfig-deserialize.c b/libgimpconfig/gimpconfig-deserialize.c index 90dcb8252d..d619b1b76f 100644 --- a/libgimpconfig/gimpconfig-deserialize.c +++ b/libgimpconfig/gimpconfig-deserialize.c @@ -505,119 +505,19 @@ gimp_config_deserialize_path (GValue *value, return G_TOKEN_RIGHT_PAREN; } -enum -{ - COLOR_RGB = 1, - COLOR_RGBA, - COLOR_HSV, - COLOR_HSVA -}; - static GTokenType gimp_config_deserialize_color (GValue *value, GParamSpec *prop_spec, GScanner *scanner) { - guint scope_id; - guint old_scope_id; - GTokenType token; + GimpRGB color; - scope_id = g_quark_from_static_string ("gimp_config_deserialize_color"); - old_scope_id = g_scanner_set_scope (scanner, scope_id); + if (! gimp_scanner_parse_color (scanner, &color)) + return G_TOKEN_NONE; - if (! g_scanner_scope_lookup_symbol (scanner, scope_id, "color-rgb")) - { - g_scanner_scope_add_symbol (scanner, scope_id, - "color-rgb", GINT_TO_POINTER (COLOR_RGB)); - g_scanner_scope_add_symbol (scanner, scope_id, - "color-rgba", GINT_TO_POINTER (COLOR_RGBA)); - g_scanner_scope_add_symbol (scanner, scope_id, - "color-hsv", GINT_TO_POINTER (COLOR_HSV)); - g_scanner_scope_add_symbol (scanner, scope_id, - "color-hsva", GINT_TO_POINTER (COLOR_HSVA)); - } + g_value_set_boxed (value, &color); - token = G_TOKEN_LEFT_PAREN; - - while (g_scanner_peek_next_token (scanner) == token) - { - token = g_scanner_get_next_token (scanner); - - switch (token) - { - case G_TOKEN_LEFT_PAREN: - token = G_TOKEN_SYMBOL; - break; - - case G_TOKEN_SYMBOL: - { - gdouble col[4] = { 0.0, 0.0, 0.0, 1.0 }; - GimpRGB color; - gint n_channels = 4; - gboolean is_hsv = FALSE; - gint i; - - switch (GPOINTER_TO_INT (scanner->value.v_symbol)) - { - case COLOR_RGB: - n_channels = 3; - /* fallthrough */ - case COLOR_RGBA: - break; - - case COLOR_HSV: - n_channels = 3; - /* fallthrough */ - case COLOR_HSVA: - is_hsv = TRUE; - break; - } - - token = G_TOKEN_FLOAT; - - for (i = 0; i < n_channels; i++) - { - if (g_scanner_peek_next_token (scanner) != token) - goto finish; - - token = g_scanner_get_next_token (scanner); - - col[i] = scanner->value.v_float; - } - - if (is_hsv) - { - GimpHSV hsv; - - gimp_hsva_set (&hsv, col[0], col[1], col[2], col[3]); - gimp_hsv_clamp (&hsv); - - gimp_hsv_to_rgb (&hsv, &color); - } - else - { - gimp_rgba_set (&color, col[0], col[1], col[2], col[3]); - gimp_rgb_clamp (&color); - } - - g_value_set_boxed (value, &color); - } - token = G_TOKEN_RIGHT_PAREN; - break; - - case G_TOKEN_RIGHT_PAREN: - goto finish; - - default: /* do nothing */ - break; - } - } - - finish: - - g_scanner_set_scope (scanner, old_scope_id); - - return token; + return G_TOKEN_RIGHT_PAREN; } static GTokenType @@ -635,12 +535,9 @@ gimp_config_deserialize_value_array (GValue *value, array_spec = G_PARAM_SPEC_VALUE_ARRAY (prop_spec); - if (g_scanner_peek_next_token (scanner) != G_TOKEN_INT) + if (! gimp_scanner_parse_int (scanner, &n_values)) return G_TOKEN_INT; - g_scanner_get_next_token (scanner); - n_values = scanner->value.v_int; - array = g_value_array_new (n_values); for (i = 0; i < n_values; i++) diff --git a/libgimpconfig/gimpconfig-iface.c b/libgimpconfig/gimpconfig-iface.c index c7d6207359..73457a6bfd 100644 --- a/libgimpconfig/gimpconfig-iface.c +++ b/libgimpconfig/gimpconfig-iface.c @@ -33,10 +33,13 @@ #include +#include "libgimpcolor/gimpcolor.h" + #include "gimpconfig.h" #include "gimpconfig-serialize.h" #include "gimpconfig-deserialize.h" #include "gimpconfig-utils.h" +#include "gimpscanner.h" #include "libgimp/gimpintl.h" @@ -58,9 +61,6 @@ static gboolean gimp_config_iface_deserialize (GObject *object, static GObject *gimp_config_iface_duplicate (GObject *object); static gboolean gimp_config_iface_equal (GObject *a, GObject *b); -static void gimp_config_scanner_message (GScanner *scanner, - gchar *message, - gboolean is_error); GType @@ -293,7 +293,6 @@ gimp_config_deserialize (GObject *object, GError **error) { GimpConfigInterface *gimp_config_iface; - gint fd; GScanner *scanner; gboolean success; @@ -305,36 +304,14 @@ gimp_config_deserialize (GObject *object, g_return_val_if_fail (gimp_config_iface != NULL, FALSE); - fd = open (filename, O_RDONLY); + scanner = gimp_scanner_new (filename, error); - if (fd == -1) - { - g_set_error (error, - GIMP_CONFIG_ERROR, - (errno == ENOENT ? - GIMP_CONFIG_ERROR_OPEN_ENOENT : GIMP_CONFIG_ERROR_OPEN), - _("Failed to open file: '%s': %s"), - filename, g_strerror (errno)); - return FALSE; - } - - scanner = g_scanner_new (NULL); - - g_scanner_input_file (scanner, fd); - - scanner->user_data = error; - scanner->msg_handler = gimp_config_scanner_message; - scanner->input_name = 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 "-_" ); - - scanner->config->scan_identifier_1char = TRUE; + if (! scanner) + return FALSE; success = gimp_config_iface->deserialize (object, scanner, 0, data); - g_scanner_destroy (scanner); - close (fd); + gimp_scanner_destroy (scanner); if (! success) g_assert (error == NULL || *error != NULL); @@ -404,22 +381,6 @@ gimp_config_string_indent (GString *string, g_string_append_len (string, " ", 4); } -static void -gimp_config_scanner_message (GScanner *scanner, - gchar *message, - gboolean is_error) -{ - GError **error = scanner->user_data; - - /* 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); -} - /** * gimp_config_duplicate: * @object: a #GObject that implements the #GimpConfigInterface. diff --git a/libgimpconfig/gimpscanner.c b/libgimpconfig/gimpscanner.c index aca3eef2fa..78ca4f306c 100644 --- a/libgimpconfig/gimpscanner.c +++ b/libgimpconfig/gimpscanner.c @@ -22,6 +22,7 @@ #include "config.h" +#include #include #include #ifdef HAVE_UNISTD_H @@ -35,13 +36,26 @@ #include #endif +#include "libgimpcolor/gimpcolor.h" + +#include "gimpconfig.h" #include "gimpscanner.h" #include "libgimp/gimpintl.h" +/* local function prototypes */ + +static void gimp_scanner_message (GScanner *scanner, + gchar *message, + gboolean is_error); + + +/* public functions */ + GScanner * -gimp_scanner_new (const gchar *filename) +gimp_scanner_new (const gchar *filename, + GError **error) { gint fd; GScanner *scanner; @@ -51,15 +65,28 @@ gimp_scanner_new (const gchar *filename) fd = open (filename, O_RDONLY); if (fd == -1) - return NULL; + { + g_set_error (error, + GIMP_CONFIG_ERROR, + (errno == ENOENT ? + GIMP_CONFIG_ERROR_OPEN_ENOENT : GIMP_CONFIG_ERROR_OPEN), + _("Failed to open file: '%s': %s"), + filename, g_strerror (errno)); + return NULL; + } scanner = g_scanner_new (NULL); - scanner->config->cset_identifier_first = ( G_CSET_a_2_z ); - scanner->config->cset_identifier_nth = ( G_CSET_a_2_z "-_" ); - g_scanner_input_file (scanner, fd); - scanner->input_name = g_strdup (filename); + + 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 "-_" ); + + scanner->config->scan_identifier_1char = TRUE; return scanner; } @@ -167,3 +194,139 @@ gimp_scanner_parse_float (GScanner *scanner, return TRUE; } + +enum +{ + COLOR_RGB = 1, + COLOR_RGBA, + COLOR_HSV, + COLOR_HSVA +}; + +gboolean +gimp_scanner_parse_color (GScanner *scanner, + GimpRGB *dest) +{ + guint scope_id; + guint old_scope_id; + GTokenType token; + + scope_id = g_quark_from_static_string ("gimp_scanner_parse_color"); + old_scope_id = g_scanner_set_scope (scanner, scope_id); + + if (! g_scanner_scope_lookup_symbol (scanner, scope_id, "color-rgb")) + { + g_scanner_scope_add_symbol (scanner, scope_id, + "color-rgb", GINT_TO_POINTER (COLOR_RGB)); + g_scanner_scope_add_symbol (scanner, scope_id, + "color-rgba", GINT_TO_POINTER (COLOR_RGBA)); + g_scanner_scope_add_symbol (scanner, scope_id, + "color-hsv", GINT_TO_POINTER (COLOR_HSV)); + g_scanner_scope_add_symbol (scanner, scope_id, + "color-hsva", GINT_TO_POINTER (COLOR_HSVA)); + } + + token = G_TOKEN_LEFT_PAREN; + + while (g_scanner_peek_next_token (scanner) == token) + { + token = g_scanner_get_next_token (scanner); + + switch (token) + { + case G_TOKEN_LEFT_PAREN: + token = G_TOKEN_SYMBOL; + break; + + case G_TOKEN_SYMBOL: + { + gdouble col[4] = { 0.0, 0.0, 0.0, 1.0 }; + GimpRGB color; + gint n_channels = 4; + gboolean is_hsv = FALSE; + gint i; + + switch (GPOINTER_TO_INT (scanner->value.v_symbol)) + { + case COLOR_RGB: + n_channels = 3; + /* fallthrough */ + case COLOR_RGBA: + break; + + case COLOR_HSV: + n_channels = 3; + /* fallthrough */ + case COLOR_HSVA: + is_hsv = TRUE; + break; + } + + token = G_TOKEN_FLOAT; + + for (i = 0; i < n_channels; i++) + { + if (! gimp_scanner_parse_float (scanner, &col[i])) + goto finish; + } + + if (is_hsv) + { + GimpHSV hsv; + + gimp_hsva_set (&hsv, col[0], col[1], col[2], col[3]); + gimp_hsv_clamp (&hsv); + + gimp_hsv_to_rgb (&hsv, &color); + } + else + { + gimp_rgba_set (&color, col[0], col[1], col[2], col[3]); + gimp_rgb_clamp (&color); + } + + *dest = color; + } + token = G_TOKEN_RIGHT_PAREN; + break; + + case G_TOKEN_RIGHT_PAREN: + goto finish; + + default: /* do nothing */ + break; + } + } + + finish: + + if (token != G_TOKEN_RIGHT_PAREN) + { + g_scanner_get_next_token (scanner); + g_scanner_unexp_token (scanner, token, NULL, NULL, NULL, + _("fatal parse error"), TRUE); + } + + g_scanner_set_scope (scanner, old_scope_id); + + return (token == G_TOKEN_RIGHT_PAREN); +} + + +/* private functions */ + +static void +gimp_scanner_message (GScanner *scanner, + gchar *message, + gboolean is_error) +{ + GError **error = scanner->user_data; + + /* 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); +} diff --git a/libgimpconfig/gimpscanner.h b/libgimpconfig/gimpscanner.h index 24ae929d03..454dbd3d47 100644 --- a/libgimpconfig/gimpscanner.h +++ b/libgimpconfig/gimpscanner.h @@ -24,21 +24,24 @@ #define __GIMP_SCANNER_H__ -GScanner * gimp_scanner_new (const gchar *filename); -void gimp_scanner_destroy (GScanner *scanner); +GScanner * gimp_scanner_new (const gchar *filename, + GError **error); +void gimp_scanner_destroy (GScanner *scanner); -gboolean gimp_scanner_parse_token (GScanner *scanner, - GTokenType token); -gboolean gimp_scanner_parse_identifier (GScanner *scanner, - const gchar *identifier); -gboolean gimp_scanner_parse_string (GScanner *scanner, - gchar **dest); -gboolean gimp_scanner_parse_string_no_validate (GScanner *scanner, - gchar **dest); -gboolean gimp_scanner_parse_int (GScanner *scanner, - gint *dest); -gboolean gimp_scanner_parse_float (GScanner *scanner, - gdouble *dest); +gboolean gimp_scanner_parse_token (GScanner *scanner, + GTokenType token); +gboolean gimp_scanner_parse_identifier (GScanner *scanner, + const gchar *identifier); +gboolean gimp_scanner_parse_string (GScanner *scanner, + gchar **dest); +gboolean gimp_scanner_parse_string_no_validate (GScanner *scanner, + gchar **dest); +gboolean gimp_scanner_parse_int (GScanner *scanner, + gint *dest); +gboolean gimp_scanner_parse_float (GScanner *scanner, + gdouble *dest); +gboolean gimp_scanner_parse_color (GScanner *scanner, + GimpRGB *dest); #endif /* __GIMP_SCANNER_H__ */