From 110efe528c208d33eb76a37d75fd11f17c643dfd Mon Sep 17 00:00:00 2001 From: Michael Natterer Date: Sun, 2 Jun 2002 19:48:01 +0000 Subject: [PATCH] parse sessionrc using GScanner. 2002-06-02 Michael Natterer * app/gui/session.c: parse sessionrc using GScanner. * app/config/gimpscanner.[ch]: added utility function gimp_scanner_parse_string_list(). Fixed the color parser's parse error detection. * app/gimprc.c: removed the sessionrc parsing stuff. * app/config/gimpconfig-params.c (gimp_param_spec_color): no need to set the param_spec's value_type, it already gets set by it's base class' instance_init() function. --- ChangeLog | 15 ++ app/config/gimpconfig-params.c | 2 - app/config/gimpscanner.c | 74 ++++++++- app/config/gimpscanner.h | 2 + app/gimprc.c | 295 +-------------------------------- app/gui/session.c | 270 +++++++++++++++++++++++++++++- libgimpconfig/gimpscanner.c | 74 ++++++++- libgimpconfig/gimpscanner.h | 2 + 8 files changed, 424 insertions(+), 310 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5ecf485f54..e44ebacdf2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2002-06-02 Michael Natterer + + * app/gui/session.c: parse sessionrc using GScanner. + + * app/config/gimpscanner.[ch]: added utility function + gimp_scanner_parse_string_list(). Fixed the color parser's parse + error detection. + + * app/gimprc.c: removed the sessionrc parsing stuff. + + * app/config/gimpconfig-params.c (gimp_param_spec_color): no need + to set the param_spec's value_type, it already gets set by it's + base class' instance_init() function. + 2002-06-02 Maurits Rijk * plug-ins/imagemap/imap_about.c: bumped version number to 2.0 @@ -88,6 +102,7 @@ more distiguishable from the transform tools * themes/Default/images/stock-plugin-16.png: Xtns>plugin-details icon + 2002-06-01 Michael Natterer * app/paint/gimpclone.[ch]: removed all global variables, factored diff --git a/app/config/gimpconfig-params.c b/app/config/gimpconfig-params.c index 560ae6916b..c8c616479a 100644 --- a/app/config/gimpconfig-params.c +++ b/app/config/gimpconfig-params.c @@ -173,8 +173,6 @@ gimp_param_spec_color (const gchar *name, cspec->default_value = *default_value; - G_PARAM_SPEC (cspec)->value_type = GIMP_TYPE_COLOR; - return G_PARAM_SPEC (cspec); } diff --git a/app/config/gimpscanner.c b/app/config/gimpscanner.c index 78ca4f306c..220d423828 100644 --- a/app/config/gimpscanner.c +++ b/app/config/gimpscanner.c @@ -210,6 +210,7 @@ gimp_scanner_parse_color (GScanner *scanner, guint scope_id; guint old_scope_id; GTokenType token; + GimpRGB color; scope_id = g_quark_from_static_string ("gimp_scanner_parse_color"); old_scope_id = g_scanner_set_scope (scanner, scope_id); @@ -241,7 +242,6 @@ gimp_scanner_parse_color (GScanner *scanner, 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; @@ -284,13 +284,12 @@ gimp_scanner_parse_color (GScanner *scanner, 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: + token = G_TOKEN_NONE; /* indicates success */ goto finish; default: /* do nothing */ @@ -300,16 +299,81 @@ gimp_scanner_parse_color (GScanner *scanner, finish: - if (token != G_TOKEN_RIGHT_PAREN) + if (token != G_TOKEN_NONE) { g_scanner_get_next_token (scanner); g_scanner_unexp_token (scanner, token, NULL, NULL, NULL, _("fatal parse error"), TRUE); } + else + { + *dest = color; + } g_scanner_set_scope (scanner, old_scope_id); - return (token == G_TOKEN_RIGHT_PAREN); + return (token == G_TOKEN_NONE); +} + +gboolean +gimp_scanner_parse_string_list (GScanner *scanner, + GList **dest) +{ + GTokenType token; + GList *list = NULL; + + 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_STRING; + break; + + case G_TOKEN_STRING: + do + { + list = g_list_append (list, g_strdup (scanner->value.v_string)); + + token = g_scanner_peek_next_token (scanner); + if (token == G_TOKEN_STRING) + g_scanner_get_next_token (scanner); + } + while (token == G_TOKEN_STRING); + token = G_TOKEN_RIGHT_PAREN; + break; + + case G_TOKEN_RIGHT_PAREN: + token = G_TOKEN_NONE; /* indicates success */ + goto finish; + + default: /* do nothing */ + break; + } + } + + finish: + + if (token != G_TOKEN_NONE) + { + g_list_foreach (list, (GFunc) g_free, NULL); + g_list_free (list); + list = NULL; + + g_scanner_get_next_token (scanner); + g_scanner_unexp_token (scanner, token, NULL, NULL, NULL, + _("fatal parse error"), TRUE); + } + else + { + *dest = list; + } + + return (token == G_TOKEN_NONE); } diff --git a/app/config/gimpscanner.h b/app/config/gimpscanner.h index 454dbd3d47..c4a5b20324 100644 --- a/app/config/gimpscanner.h +++ b/app/config/gimpscanner.h @@ -42,6 +42,8 @@ gboolean gimp_scanner_parse_float (GScanner *scanner, gdouble *dest); gboolean gimp_scanner_parse_color (GScanner *scanner, GimpRGB *dest); +gboolean gimp_scanner_parse_string_list (GScanner *scanner, + GList **dest); #endif /* __GIMP_SCANNER_H__ */ diff --git a/app/gimprc.c b/app/gimprc.c index 9dbaa492a1..08d95d6f79 100644 --- a/app/gimprc.c +++ b/app/gimprc.c @@ -42,13 +42,7 @@ #include "core/gimp.h" #include "core/gimpcoreconfig.h" -#include "core/gimptoolinfo.h" -#include "widgets/gimpdialogfactory.h" - -/*#include "tools/gimptool.h"*/ - -#include "gui/color-notebook.h" #include "gui/menus.h" #include "app_procs.h" @@ -82,8 +76,6 @@ typedef enum TT_INTERP, TT_XPREVSIZE, TT_XUNIT, - TT_XSESSIONINFO, - TT_XCOLORHISTORY, TT_XNAVPREVSIZE, TT_XTHUMBSIZE, TT_XHELPBROWSER, @@ -129,12 +121,9 @@ static gint parse_preview_size (gpointer val1p, gpointer val2p) static gint parse_nav_preview_size (gpointer val1p, gpointer val2p); static gint parse_thumbnail_size (gpointer val1p, gpointer val2p); static gint parse_units (gpointer val1p, gpointer val2p); -static gint parse_session_info (gpointer val1p, gpointer val2p); static gint parse_help_browser (gpointer val1p, gpointer val2p); static gint parse_cursor_mode (gpointer val1p, gpointer val2p); -static gint parse_color_history (gpointer val1p, gpointer val2p); -static gint parse_color (GimpRGB *color); static gint parse_unknown (gchar *token_sym); static inline gchar * string_to_str (gpointer val1p, gpointer val2p); @@ -252,7 +241,6 @@ static ParseFunc funcs[] = { "always-restore-session", TT_BOOLEAN, &gimprc.always_restore_session , NULL }, { "show-tips", TT_BOOLEAN, &gimprc.show_tips, NULL }, { "dont-show-tips", TT_BOOLEAN, NULL, &gimprc.show_tips }, - { "last-tip-shown", TT_INT, &gimprc.last_tip, NULL }, { "show-tool-tips", TT_BOOLEAN, &gimprc.show_tool_tips, NULL }, { "dont-show-tool-tips", TT_BOOLEAN, NULL, &gimprc.show_tool_tips }, { "default-dot-for-dot", TT_BOOLEAN, &gimprc.default_dot_for_dot, NULL }, @@ -271,10 +259,7 @@ static ParseFunc funcs[] = { "cursor-mode", TT_XCURSORMODE, &gimprc.cursor_mode, NULL }, { "disable-tearoff-menus", TT_BOOLEAN, &gimprc.disable_tearoff_menus, NULL }, { "theme-path", TT_PATH, &gimprc.theme_path, NULL }, - { "theme", TT_STRING, &gimprc.theme, NULL }, - - { "session-info", TT_XSESSIONINFO, NULL, NULL }, - { "color-history", TT_XCOLORHISTORY, NULL, NULL } + { "theme", TT_STRING, &gimprc.theme, NULL } }; @@ -889,10 +874,6 @@ parse_statement (void) return parse_thumbnail_size (func->val1p, func->val2p); case TT_XUNIT: return parse_units (func->val1p, func->val2p); - case TT_XSESSIONINFO: - return parse_session_info (func->val1p, func->val2p); - case TT_XCOLORHISTORY: - return parse_color_history (func->val1p, func->val2p); case TT_XHELPBROWSER: return parse_help_browser (func->val1p, func->val2p); case TT_XCURSORMODE: @@ -1394,85 +1375,6 @@ parse_units (gpointer val1p, return OK; } -static gint -parse_color (GimpRGB *color) -{ - gdouble col[4] = { 0.0, 0.0, 0.0, GIMP_OPACITY_OPAQUE }; - gint token; - gint i; - gint n_channels; - gboolean is_hsv; - - g_return_val_if_fail (color != NULL, ERROR); - - token = peek_next_token (); - if (!token || (token != TOKEN_LEFT_PAREN)) - return ERROR; - token = get_next_token (); - - token = peek_next_token (); - if (!token || (token != TOKEN_SYMBOL)) - return ERROR; - token = get_next_token (); - - if (! strcmp ("color-rgb", token_sym)) - { - is_hsv = FALSE; - n_channels = 3; - } - else if (! strcmp ("color-rgba", token_sym)) - { - is_hsv = FALSE; - n_channels = 4; - } - else if (! strcmp ("color-hsv", token_sym)) - { - is_hsv = TRUE; - n_channels = 3; - } - else if (! strcmp ("color-hsva", token_sym)) - { - is_hsv = TRUE; - n_channels = 4; - } - else - { - return ERROR; - } - - for (i = 0; i < n_channels; i++) - { - token = peek_next_token (); - if (!token || (token != TOKEN_NUMBER)) - return ERROR; - token = get_next_token (); - - col[i] = token_num; - } - - 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); - } - - token = peek_next_token (); - if (!token || (token != TOKEN_RIGHT_PAREN)) - return ERROR; - token = get_next_token (); - - return OK; -} - static gchar * transform_path (gchar *path, gboolean destroy) @@ -1638,198 +1540,6 @@ transform_path (gchar *path, return new_path; } -static gint -parse_session_info (gpointer val1p, - gpointer val2p) -{ - gint token; - GimpDialogFactory *factory; - GimpSessionInfo *info = NULL; - - token = peek_next_token (); - if (!token || (token != TOKEN_STRING)) - goto error; - token = get_next_token (); - - factory = gimp_dialog_factory_from_name (token_str); - - if (! factory) - goto error; - - token = peek_next_token (); - if (!token || (token != TOKEN_STRING)) - goto error; - token = get_next_token (); - - info = g_new0 (GimpSessionInfo, 1); - - if (strcmp (token_str, "dock")) - { - info->toplevel_entry = gimp_dialog_factory_find_entry (factory, token_str); - - if (! info->toplevel_entry) - goto error; - } - - /* Parse options for session info */ - - while (peek_next_token () == TOKEN_LEFT_PAREN) - { - token = get_next_token (); - - token = peek_next_token (); - if (!token || (token != TOKEN_SYMBOL)) - goto error; - token = get_next_token (); - - if (!strcmp ("position", token_sym)) - { - token = peek_next_token (); - if (!token || (token != TOKEN_NUMBER)) - goto error; - token = get_next_token (); - info->x = token_int; - - token = peek_next_token (); - if (!token || (token != TOKEN_NUMBER)) - goto error; - token = get_next_token (); - info->y = token_int; - } - else if (!strcmp ("size", token_sym)) - { - token = peek_next_token (); - if (!token || (token != TOKEN_NUMBER)) - goto error; - token = get_next_token (); - info->width = token_int; - - token = peek_next_token (); - if (!token || (token != TOKEN_NUMBER)) - goto error; - token = get_next_token (); - info->height = token_int; - } - else if (!strcmp ("open-on-exit", token_sym)) - { - info->open = TRUE; - } - else if (!strcmp ("aux-info", token_sym)) - { - token = peek_next_token (); - if (!token || (token != TOKEN_LEFT_PAREN)) - goto error; - token = get_next_token (); - - while (peek_next_token () == TOKEN_STRING) - { - token = get_next_token (); - - info->aux_info = g_list_append (info->aux_info, - g_strdup (token_str)); - } - - token = peek_next_token (); - if (!token || (token != TOKEN_RIGHT_PAREN)) - goto error; - token = get_next_token (); - } - else if (!strcmp ("dock", token_sym)) - { - if (info->toplevel_entry) - goto error; - - while (peek_next_token () == TOKEN_LEFT_PAREN) - { - token = get_next_token (); - - info->sub_dialogs = g_list_prepend (info->sub_dialogs, NULL); - - while (peek_next_token () == TOKEN_STRING) - { - token = get_next_token (); - - info->sub_dialogs->data = - g_list_append (info->sub_dialogs->data, - g_strdup (token_str)); - } - - token = peek_next_token (); - if (!token || (token != TOKEN_RIGHT_PAREN)) - goto error; - token = get_next_token (); - - if (! g_list_length (info->sub_dialogs->data)) - { - info->sub_dialogs = g_list_remove (info->sub_dialogs, - info->sub_dialogs->data); - } - } - - info->sub_dialogs = g_list_reverse (info->sub_dialogs); - } - else - { - goto error; - } - - token = peek_next_token (); - if (!token || (token != TOKEN_RIGHT_PAREN)) - goto error; - token = get_next_token (); - } - - if (!token || (token != TOKEN_RIGHT_PAREN)) - goto error; - token = get_next_token (); - - factory->session_infos = g_list_append (factory->session_infos, info); - - return OK; - - error: - if (info) - { - GList *list; - - for (list = info->sub_dialogs; list; list = g_list_next (list)) - { - g_list_foreach (list->data, (GFunc) g_free, NULL); - g_list_free (list->data); - } - - g_list_free (info->sub_dialogs); - g_free (info); - } - - return ERROR; -} - -static gint -parse_color_history (gpointer val1p, - gpointer val2p) -{ - gint token = 0; - GimpRGB color; - - /* Parse one color per line: (color r g b a) */ - - while (peek_next_token () == TOKEN_LEFT_PAREN) - { - if (parse_color (&color) == ERROR) - return ERROR; - - color_history_add_color_from_rc (&color); - } - - token = peek_next_token (); - if (!token || (token != TOKEN_RIGHT_PAREN)) - return ERROR; - token = get_next_token (); - - return OK; -} - static gint parse_help_browser (gpointer val1p, gpointer val2p) @@ -1978,9 +1688,6 @@ gimprc_value_to_str (const gchar *name) return cursor_mode_to_str (func->val1p, func->val2p); case TT_XCOMMENT: return comment_to_str (func->val1p, func->val2p); - case TT_XSESSIONINFO: - case TT_XCOLORHISTORY: - return NULL; } } diff --git a/app/gui/session.c b/app/gui/session.c index 81e2f94c9c..7cd2856e70 100644 --- a/app/gui/session.c +++ b/app/gui/session.c @@ -19,7 +19,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - #include "config.h" #include @@ -32,6 +31,8 @@ #include "core/gimp.h" +#include "config/gimpscanner.h" + #include "widgets/gimpdialogfactory.h" #include "color-notebook.h" @@ -39,27 +40,139 @@ #include "gimprc.h" +#include "libgimp/gimpintl.h" + + +/* local function prototypes */ + +static GTokenType session_info_deserialize (GScanner *scanner, + Gimp *gimp); /* public functions */ +enum +{ + SESSION_INFO = 1, + COLOR_HISTORY, + LAST_TIP_SHOWN, + + SESSION_INFO_POSITION, + SESSION_INFO_SIZE, + SESSION_INFO_OPEN, + SESSION_INFO_AUX, + SESSION_INFO_DOCK +}; + void session_init (Gimp *gimp) { - gchar *filename; + gchar *filename; + GScanner *scanner; + GTokenType token; + GError *error = NULL; g_return_if_fail (GIMP_IS_GIMP (gimp)); filename = gimp_personal_rc_file ("sessionrc"); + scanner = gimp_scanner_new (filename, &error); + g_free (filename); - if (! gimprc_parse_file (filename)) + if (! scanner) { /* always show L&C&P, Tool Options and Brushes on first invocation */ /* TODO */ + + return; } - g_free (filename); + g_scanner_scope_add_symbol (scanner, 0, "session-info", + GINT_TO_POINTER (SESSION_INFO)); + g_scanner_scope_add_symbol (scanner, 0, "color-history", + GINT_TO_POINTER (COLOR_HISTORY)); + g_scanner_scope_add_symbol (scanner, 0, "last-tip-shown", + GINT_TO_POINTER (LAST_TIP_SHOWN)); + + g_scanner_scope_add_symbol (scanner, SESSION_INFO, "position", + GINT_TO_POINTER (SESSION_INFO_POSITION)); + g_scanner_scope_add_symbol (scanner, SESSION_INFO, "size", + GINT_TO_POINTER (SESSION_INFO_SIZE)); + g_scanner_scope_add_symbol (scanner, SESSION_INFO, "open-on-exit", + GINT_TO_POINTER (SESSION_INFO_OPEN)); + g_scanner_scope_add_symbol (scanner, SESSION_INFO, "aux-info", + GINT_TO_POINTER (SESSION_INFO_AUX)); + g_scanner_scope_add_symbol (scanner, SESSION_INFO, "dock", + GINT_TO_POINTER (SESSION_INFO_DOCK)); + + 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: + if (scanner->value.v_symbol == GINT_TO_POINTER (SESSION_INFO)) + { + g_scanner_set_scope (scanner, SESSION_INFO); + token = session_info_deserialize (scanner, gimp); + + if (token == G_TOKEN_RIGHT_PAREN) + g_scanner_set_scope (scanner, 0); + } + else if (scanner->value.v_symbol == GINT_TO_POINTER (COLOR_HISTORY)) + { + while (g_scanner_peek_next_token (scanner) == G_TOKEN_LEFT_PAREN) + { + GimpRGB color; + + if (! gimp_scanner_parse_color (scanner, &color)) + goto error; + + color_history_add_color_from_rc (&color); + } + } + else if (scanner->value.v_symbol == GINT_TO_POINTER (LAST_TIP_SHOWN)) + { + token = G_TOKEN_INT; + + if (! gimp_scanner_parse_int (scanner, &gimprc.last_tip)) + break; + } + token = G_TOKEN_RIGHT_PAREN; + break; + + case G_TOKEN_RIGHT_PAREN: + token = G_TOKEN_LEFT_PAREN; + break; + + default: /* do nothing */ + break; + } + } + + 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); + } + + error: + + if (error) + { + g_message (error->message); + g_clear_error (&error); + } + + gimp_scanner_destroy (scanner); } void @@ -102,3 +215,152 @@ session_save (Gimp *gimp) fclose (fp); } + + +/* private functions */ + +static GTokenType +session_info_deserialize (GScanner *scanner, + Gimp *gimp) +{ + GimpDialogFactory *factory; + GimpSessionInfo *info = NULL; + GTokenType token; + gchar *factory_name; + gchar *entry_name; + + token = G_TOKEN_STRING; + + if (! gimp_scanner_parse_string (scanner, &factory_name)) + goto error; + + factory = gimp_dialog_factory_from_name (factory_name); + g_free (factory_name); + + if (! factory) + goto error; + + if (! gimp_scanner_parse_string (scanner, &entry_name)) + goto error; + + info = g_new0 (GimpSessionInfo, 1); + + if (strcmp (entry_name, "dock")) + { + info->toplevel_entry = gimp_dialog_factory_find_entry (factory, + entry_name); + g_free (entry_name); + + if (! info->toplevel_entry) + goto error; + } + else + { + g_free (entry_name); + } + + 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: + switch (GPOINTER_TO_INT (scanner->value.v_symbol)) + { + case SESSION_INFO_POSITION: + token = G_TOKEN_INT; + if (! gimp_scanner_parse_int (scanner, &info->x)) + goto error; + if (! gimp_scanner_parse_int (scanner, &info->y)) + goto error; + break; + + case SESSION_INFO_SIZE: + token = G_TOKEN_INT; + if (! gimp_scanner_parse_int (scanner, &info->width)) + goto error; + if (! gimp_scanner_parse_int (scanner, &info->height)) + goto error; + break; + + case SESSION_INFO_OPEN: + info->open = TRUE; + break; + + case SESSION_INFO_AUX: + if (! gimp_scanner_parse_string_list (scanner, &info->aux_info)) + { + token = G_TOKEN_NONE; + goto error; + } + break; + + case SESSION_INFO_DOCK: + if (info->toplevel_entry) + goto error; + + while (g_scanner_peek_next_token (scanner) == G_TOKEN_LEFT_PAREN) + { + GList *list = NULL; + + if (! gimp_scanner_parse_string_list (scanner, &list)) + { + token = G_TOKEN_NONE; + goto error; + } + + info->sub_dialogs = g_list_append (info->sub_dialogs, list); + } + break; + + default: + break; + } + token = G_TOKEN_RIGHT_PAREN; + break; + + case G_TOKEN_RIGHT_PAREN: + token = G_TOKEN_LEFT_PAREN; + break; + + default: + break; + } + } + + if (token == G_TOKEN_LEFT_PAREN) + { + token = G_TOKEN_RIGHT_PAREN; + + if (g_scanner_peek_next_token (scanner) == token) + { + factory->session_infos = g_list_append (factory->session_infos, info); + } + + return token; + } + + error: + if (info) + { + GList *list; + + for (list = info->sub_dialogs; list; list = g_list_next (list)) + { + g_list_foreach (list->data, (GFunc) g_free, NULL); + g_list_free (list->data); + } + + g_list_free (info->sub_dialogs); + g_free (info); + } + + return token; +} diff --git a/libgimpconfig/gimpscanner.c b/libgimpconfig/gimpscanner.c index 78ca4f306c..220d423828 100644 --- a/libgimpconfig/gimpscanner.c +++ b/libgimpconfig/gimpscanner.c @@ -210,6 +210,7 @@ gimp_scanner_parse_color (GScanner *scanner, guint scope_id; guint old_scope_id; GTokenType token; + GimpRGB color; scope_id = g_quark_from_static_string ("gimp_scanner_parse_color"); old_scope_id = g_scanner_set_scope (scanner, scope_id); @@ -241,7 +242,6 @@ gimp_scanner_parse_color (GScanner *scanner, 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; @@ -284,13 +284,12 @@ gimp_scanner_parse_color (GScanner *scanner, 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: + token = G_TOKEN_NONE; /* indicates success */ goto finish; default: /* do nothing */ @@ -300,16 +299,81 @@ gimp_scanner_parse_color (GScanner *scanner, finish: - if (token != G_TOKEN_RIGHT_PAREN) + if (token != G_TOKEN_NONE) { g_scanner_get_next_token (scanner); g_scanner_unexp_token (scanner, token, NULL, NULL, NULL, _("fatal parse error"), TRUE); } + else + { + *dest = color; + } g_scanner_set_scope (scanner, old_scope_id); - return (token == G_TOKEN_RIGHT_PAREN); + return (token == G_TOKEN_NONE); +} + +gboolean +gimp_scanner_parse_string_list (GScanner *scanner, + GList **dest) +{ + GTokenType token; + GList *list = NULL; + + 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_STRING; + break; + + case G_TOKEN_STRING: + do + { + list = g_list_append (list, g_strdup (scanner->value.v_string)); + + token = g_scanner_peek_next_token (scanner); + if (token == G_TOKEN_STRING) + g_scanner_get_next_token (scanner); + } + while (token == G_TOKEN_STRING); + token = G_TOKEN_RIGHT_PAREN; + break; + + case G_TOKEN_RIGHT_PAREN: + token = G_TOKEN_NONE; /* indicates success */ + goto finish; + + default: /* do nothing */ + break; + } + } + + finish: + + if (token != G_TOKEN_NONE) + { + g_list_foreach (list, (GFunc) g_free, NULL); + g_list_free (list); + list = NULL; + + g_scanner_get_next_token (scanner); + g_scanner_unexp_token (scanner, token, NULL, NULL, NULL, + _("fatal parse error"), TRUE); + } + else + { + *dest = list; + } + + return (token == G_TOKEN_NONE); } diff --git a/libgimpconfig/gimpscanner.h b/libgimpconfig/gimpscanner.h index 454dbd3d47..c4a5b20324 100644 --- a/libgimpconfig/gimpscanner.h +++ b/libgimpconfig/gimpscanner.h @@ -42,6 +42,8 @@ gboolean gimp_scanner_parse_float (GScanner *scanner, gdouble *dest); gboolean gimp_scanner_parse_color (GScanner *scanner, GimpRGB *dest); +gboolean gimp_scanner_parse_string_list (GScanner *scanner, + GList **dest); #endif /* __GIMP_SCANNER_H__ */