static GTokenType gimp_config_deserialize_value_array (GValue *value, GimpConfig *config, GParamSpec *prop_spec, GScanner *scanner) { GParamSpecValueArray *array_spec; GValueArray *array; GValue array_value = { 0, }; gint n_values; GTokenType token; gint i; array_spec = G_PARAM_SPEC_VALUE_ARRAY (prop_spec); if (! gimp_scanner_parse_int (scanner, &n_values)) return G_TOKEN_INT; array = g_value_array_new (n_values); for (i = 0; i < n_values; i++) { g_value_init (&array_value, array_spec->element_spec->value_type); token = gimp_config_deserialize_value (&array_value, config, array_spec->element_spec, scanner); if (token == G_TOKEN_RIGHT_PAREN) g_value_array_append (array, &array_value); g_value_unset (&array_value); if (token != G_TOKEN_RIGHT_PAREN) return token; } g_value_take_boxed (value, array); return G_TOKEN_RIGHT_PAREN; }
static GTokenType gimp_unitrc_unit_info_deserialize (GScanner *scanner, Gimp *gimp) { gchar *identifier = NULL; gdouble factor = 1.0; gint digits = 2.0; gchar *symbol = NULL; gchar *abbreviation = NULL; gchar *singular = NULL; gchar *plural = NULL; GTokenType token; if (! gimp_scanner_parse_string (scanner, &identifier)) return G_TOKEN_STRING; 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 UNIT_FACTOR: token = G_TOKEN_FLOAT; if (! gimp_scanner_parse_float (scanner, &factor)) goto cleanup; break; case UNIT_DIGITS: token = G_TOKEN_INT; if (! gimp_scanner_parse_int (scanner, &digits)) goto cleanup; break; case UNIT_SYMBOL: token = G_TOKEN_STRING; if (! gimp_scanner_parse_string (scanner, &symbol)) goto cleanup; break; case UNIT_ABBREV: token = G_TOKEN_STRING; if (! gimp_scanner_parse_string (scanner, &abbreviation)) goto cleanup; break; case UNIT_SINGULAR: token = G_TOKEN_STRING; if (! gimp_scanner_parse_string (scanner, &singular)) goto cleanup; break; case UNIT_PLURAL: token = G_TOKEN_STRING; if (! gimp_scanner_parse_string (scanner, &plural)) goto cleanup; 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) { GimpUnit unit = _gimp_unit_new (gimp, identifier, factor, digits, symbol, abbreviation, singular, plural); /* make the unit definition persistent */ _gimp_unit_set_deletion_flag (gimp, unit, FALSE); } } cleanup: g_free (identifier); g_free (symbol); g_free (abbreviation); g_free (singular); g_free (plural); return token; }
GTokenType gimp_session_info_book_deserialize (GScanner *scanner, gint scope, GimpSessionInfoBook **book) { GimpSessionInfoBook *info; GTokenType token; g_return_val_if_fail (scanner != NULL, G_TOKEN_LEFT_PAREN); g_return_val_if_fail (book != NULL, G_TOKEN_LEFT_PAREN); g_scanner_scope_add_symbol (scanner, scope, "position", GINT_TO_POINTER (SESSION_INFO_BOOK_POSITION)); g_scanner_scope_add_symbol (scanner, scope, "current-page", GINT_TO_POINTER (SESSION_INFO_BOOK_CURRENT_PAGE)); g_scanner_scope_add_symbol (scanner, scope, "dockable", GINT_TO_POINTER (SESSION_INFO_BOOK_DOCKABLE)); info = gimp_session_info_book_new (); 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)) { GimpSessionInfoDockable *dockable; case SESSION_INFO_BOOK_POSITION: token = G_TOKEN_INT; if (! gimp_scanner_parse_int (scanner, &info->position)) goto error; break; case SESSION_INFO_BOOK_CURRENT_PAGE: token = G_TOKEN_INT; if (! gimp_scanner_parse_int (scanner, &info->current_page)) goto error; break; case SESSION_INFO_BOOK_DOCKABLE: g_scanner_set_scope (scanner, scope + 1); token = gimp_session_info_dockable_deserialize (scanner, scope + 1, &dockable); if (token == G_TOKEN_LEFT_PAREN) { info->dockables = g_list_append (info->dockables, dockable); g_scanner_set_scope (scanner, scope); } else goto error; break; default: goto error; } token = G_TOKEN_RIGHT_PAREN; break; case G_TOKEN_RIGHT_PAREN: token = G_TOKEN_LEFT_PAREN; break; default: break; } } *book = info; g_scanner_scope_remove_symbol (scanner, scope, "position"); g_scanner_scope_remove_symbol (scanner, scope, "current-page"); g_scanner_scope_remove_symbol (scanner, scope, "dockable"); return token; error: *book = NULL; gimp_session_info_book_free (info); return token; }
void session_init (Gimp *gimp) { gchar *filename; GScanner *scanner; GTokenType token; GError *error = NULL; g_return_if_fail (GIMP_IS_GIMP (gimp)); filename = session_filename (gimp); scanner = gimp_scanner_new_file (filename, &error); if (! scanner && error->code == GIMP_CONFIG_ERROR_OPEN_ENOENT) { g_clear_error (&error); g_free (filename); filename = g_build_filename (gimp_sysconf_directory (), "sessionrc", NULL); scanner = gimp_scanner_new_file (filename, NULL); } if (! scanner) { g_clear_error (&error); g_free (filename); return; } if (gimp->be_verbose) g_print ("Parsing '%s'\n", gimp_filename_to_utf8 (filename)); g_scanner_scope_add_symbol (scanner, 0, "session-info", GINT_TO_POINTER (SESSION_INFO)); g_scanner_scope_add_symbol (scanner, 0, "hide-docks", GINT_TO_POINTER (HIDE_DOCKS)); g_scanner_scope_add_symbol (scanner, 0, "single-window-mode", GINT_TO_POINTER (SINGLE_WINDOW_MODE)); g_scanner_scope_add_symbol (scanner, 0, "last-tip-shown", GINT_TO_POINTER (LAST_TIP_SHOWN)); 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)) { GimpDialogFactory *factory = NULL; GimpSessionInfo *info = NULL; gchar *factory_name = NULL; gchar *entry_name = NULL; GimpDialogFactoryEntry *entry = NULL; token = G_TOKEN_STRING; if (! gimp_scanner_parse_string (scanner, &factory_name)) break; /* In versions <= GIMP 2.6 there was a "toolbox", a * "dock", a "display" and a "toplevel" factory. These * are now merged to a single gimp_dialog_factory_get_singleton (). We * need the legacy name though, so keep it around. */ factory = gimp_dialog_factory_get_singleton (); info = gimp_session_info_new (); /* GIMP 2.6 has the entry name as part of the * session-info header, so try to get it */ gimp_scanner_parse_string (scanner, &entry_name); if (entry_name) { /* Previously, GimpDock was a toplevel. That is why * versions <= GIMP 2.6 has "dock" as the entry name. We * want "dock" to be interpreted as 'dock window' * however so have some special-casing for that. When * the entry name is "dock" the factory name is either * "dock" or "toolbox". */ if (strcmp (entry_name, "dock") == 0) { entry = gimp_dialog_factory_find_entry (factory, (strcmp (factory_name, "toolbox") == 0 ? "gimp-toolbox-window" : "gimp-dock-window")); } else { entry = gimp_dialog_factory_find_entry (factory, entry_name); } } /* We're done with these now */ g_free (factory_name); g_free (entry_name); /* We can get the factory entry either now (the GIMP <= * 2.6 way), or when we deserialize (the GIMP 2.8 way) */ if (entry) { gimp_session_info_set_factory_entry (info, entry); } /* Always try to deserialize */ if (gimp_config_deserialize (GIMP_CONFIG (info), scanner, 1, NULL)) { /* Make sure we got a factory entry either the 2.6 * or 2.8 way */ if (gimp_session_info_get_factory_entry (info)) { GIMP_LOG (DIALOG_FACTORY, "successfully parsed and added session info %p", info); gimp_dialog_factory_add_session_info (factory, info); } else { GIMP_LOG (DIALOG_FACTORY, "failed to parse session info %p, not adding", info); } g_object_unref (info); } else { g_object_unref (info); break; } } else if (scanner->value.v_symbol == GINT_TO_POINTER (HIDE_DOCKS)) { gboolean hide_docks; token = G_TOKEN_IDENTIFIER; if (! gimp_scanner_parse_boolean (scanner, &hide_docks)) break; g_object_set (gimp->config, "hide-docks", hide_docks, NULL); } else if (scanner->value.v_symbol == GINT_TO_POINTER (SINGLE_WINDOW_MODE)) { gboolean single_window_mode; token = G_TOKEN_IDENTIFIER; if (! gimp_scanner_parse_boolean (scanner, &single_window_mode)) break; g_object_set (gimp->config, "single-window-mode", single_window_mode, NULL); } else if (scanner->value.v_symbol == GINT_TO_POINTER (LAST_TIP_SHOWN)) { gint last_tip_shown; token = G_TOKEN_INT; if (! gimp_scanner_parse_int (scanner, &last_tip_shown)) break; g_object_set (gimp->config, "last-tip-shown", last_tip_shown, NULL); } 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); } if (error) { gimp_message_literal (gimp, NULL, GIMP_MESSAGE_ERROR, error->message); g_clear_error (&error); gimp_config_file_backup_on_error (filename, "sessionrc", NULL); } gimp_scanner_destroy (scanner); g_free (filename); dialogs_load_recent_docks (gimp); }
GSList * plug_in_rc_parse (Gimp *gimp, GFile *file, GError **error) { GScanner *scanner; GEnumClass *enum_class; GSList *plug_in_defs = NULL; gint protocol_version = GIMP_PROTOCOL_VERSION; gint file_version = PLUG_IN_RC_FILE_VERSION; GTokenType token; g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL); g_return_val_if_fail (G_IS_FILE (file), NULL); g_return_val_if_fail (error == NULL || *error == NULL, NULL); scanner = gimp_scanner_new_gfile (file, error); if (! scanner) return NULL; enum_class = g_type_class_ref (GIMP_TYPE_ICON_TYPE); g_scanner_scope_add_symbol (scanner, 0, "protocol-version", GINT_TO_POINTER (PROTOCOL_VERSION)); g_scanner_scope_add_symbol (scanner, 0, "file-version", GINT_TO_POINTER (FILE_VERSION)); g_scanner_scope_add_symbol (scanner, 0, "plug-in-def", GINT_TO_POINTER (PLUG_IN_DEF)); g_scanner_scope_add_symbol (scanner, PLUG_IN_DEF, "proc-def", GINT_TO_POINTER (PROC_DEF)); g_scanner_scope_add_symbol (scanner, PLUG_IN_DEF, "locale-def", GINT_TO_POINTER (LOCALE_DEF)); g_scanner_scope_add_symbol (scanner, PLUG_IN_DEF, "help-def", GINT_TO_POINTER (HELP_DEF)); g_scanner_scope_add_symbol (scanner, PLUG_IN_DEF, "has-init", GINT_TO_POINTER (HAS_INIT)); g_scanner_scope_add_symbol (scanner, PLUG_IN_DEF, "proc-arg", GINT_TO_POINTER (PROC_ARG)); g_scanner_scope_add_symbol (scanner, PLUG_IN_DEF, "menu-path", GINT_TO_POINTER (MENU_PATH)); g_scanner_scope_add_symbol (scanner, PLUG_IN_DEF, "icon", GINT_TO_POINTER (ICON)); g_scanner_scope_add_symbol (scanner, PLUG_IN_DEF, "load-proc", GINT_TO_POINTER (LOAD_PROC)); g_scanner_scope_add_symbol (scanner, PLUG_IN_DEF, "save-proc", GINT_TO_POINTER (SAVE_PROC)); g_scanner_scope_add_symbol (scanner, LOAD_PROC, "extension", GINT_TO_POINTER (EXTENSION)); g_scanner_scope_add_symbol (scanner, LOAD_PROC, "prefix", GINT_TO_POINTER (PREFIX)); g_scanner_scope_add_symbol (scanner, LOAD_PROC, "magic", GINT_TO_POINTER (MAGIC)); g_scanner_scope_add_symbol (scanner, LOAD_PROC, "mime-type", GINT_TO_POINTER (MIME_TYPE)); g_scanner_scope_add_symbol (scanner, LOAD_PROC, "handles-uri", GINT_TO_POINTER (HANDLES_URI)); g_scanner_scope_add_symbol (scanner, LOAD_PROC, "thumb-loader", GINT_TO_POINTER (THUMB_LOADER)); g_scanner_scope_add_symbol (scanner, SAVE_PROC, "extension", GINT_TO_POINTER (EXTENSION)); g_scanner_scope_add_symbol (scanner, SAVE_PROC, "prefix", GINT_TO_POINTER (PREFIX)); g_scanner_scope_add_symbol (scanner, SAVE_PROC, "mime-type", GINT_TO_POINTER (MIME_TYPE)); g_scanner_scope_add_symbol (scanner, SAVE_PROC, "handles-uri", GINT_TO_POINTER (HANDLES_URI)); token = G_TOKEN_LEFT_PAREN; while (protocol_version == GIMP_PROTOCOL_VERSION && file_version == PLUG_IN_RC_FILE_VERSION && 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 PROTOCOL_VERSION: token = G_TOKEN_INT; if (gimp_scanner_parse_int (scanner, &protocol_version)) token = G_TOKEN_RIGHT_PAREN; break; case FILE_VERSION: token = G_TOKEN_INT; if (gimp_scanner_parse_int (scanner, &file_version)) token = G_TOKEN_RIGHT_PAREN; break; case PLUG_IN_DEF: g_scanner_set_scope (scanner, PLUG_IN_DEF); token = plug_in_def_deserialize (gimp, scanner, &plug_in_defs); g_scanner_set_scope (scanner, 0); break; default: break; } break; case G_TOKEN_RIGHT_PAREN: token = G_TOKEN_LEFT_PAREN; break; default: /* do nothing */ break; } } if (protocol_version != GIMP_PROTOCOL_VERSION || file_version != PLUG_IN_RC_FILE_VERSION || token != G_TOKEN_LEFT_PAREN) { if (protocol_version != GIMP_PROTOCOL_VERSION) { g_set_error (error, GIMP_CONFIG_ERROR, GIMP_CONFIG_ERROR_VERSION, _("Skipping '%s': wrong GIMP protocol version."), gimp_file_get_utf8_name (file)); } else if (file_version != PLUG_IN_RC_FILE_VERSION) { g_set_error (error, GIMP_CONFIG_ERROR, GIMP_CONFIG_ERROR_VERSION, _("Skipping '%s': wrong pluginrc file format version."), gimp_file_get_utf8_name (file)); } else { g_scanner_get_next_token (scanner); g_scanner_unexp_token (scanner, token, NULL, NULL, NULL, _("fatal parse error"), TRUE); } g_slist_free_full (plug_in_defs, (GDestroyNotify) g_object_unref); plug_in_defs = NULL; } g_type_class_unref (enum_class); gimp_scanner_destroy (scanner); return g_slist_reverse (plug_in_defs); }
static GTokenType plug_in_proc_arg_deserialize (GScanner *scanner, Gimp *gimp, GimpProcedure *procedure, gboolean return_value) { GTokenType token; gint arg_type; gchar *name = NULL; gchar *desc = NULL; GParamSpec *pspec; if (! gimp_scanner_parse_token (scanner, G_TOKEN_LEFT_PAREN)) { token = G_TOKEN_LEFT_PAREN; goto error; } if (! gimp_scanner_parse_token (scanner, G_TOKEN_SYMBOL) || GPOINTER_TO_INT (scanner->value.v_symbol) != PROC_ARG) { token = G_TOKEN_SYMBOL; goto error; } if (! gimp_scanner_parse_int (scanner, (gint *) &arg_type)) { token = G_TOKEN_INT; goto error; } if (! gimp_scanner_parse_string (scanner, &name)) { token = G_TOKEN_STRING; goto error; } if (! gimp_scanner_parse_string (scanner, &desc)) { token = G_TOKEN_STRING; goto error; } if (! gimp_scanner_parse_token (scanner, G_TOKEN_RIGHT_PAREN)) { token = G_TOKEN_RIGHT_PAREN; goto error; } token = G_TOKEN_LEFT_PAREN; pspec = gimp_pdb_compat_param_spec (gimp, arg_type, name, desc); if (return_value) gimp_procedure_add_return_value (procedure, pspec); else gimp_procedure_add_argument (procedure, pspec); error: g_free (name); g_free (desc); return token; }
static GTokenType plug_in_icon_deserialize (GScanner *scanner, GimpPlugInProcedure *proc) { GEnumClass *enum_class; GEnumValue *enum_value; GimpIconType icon_type; gint icon_data_length; gchar *icon_name; guint8 *icon_data; if (! gimp_scanner_parse_token (scanner, G_TOKEN_LEFT_PAREN)) return G_TOKEN_LEFT_PAREN; if (! gimp_scanner_parse_token (scanner, G_TOKEN_SYMBOL) || GPOINTER_TO_INT (scanner->value.v_symbol) != ICON) return G_TOKEN_SYMBOL; enum_class = g_type_class_peek (GIMP_TYPE_ICON_TYPE); switch (g_scanner_peek_next_token (scanner)) { case G_TOKEN_IDENTIFIER: g_scanner_get_next_token (scanner); enum_value = g_enum_get_value_by_nick (G_ENUM_CLASS (enum_class), scanner->value.v_identifier); if (!enum_value) enum_value = g_enum_get_value_by_name (G_ENUM_CLASS (enum_class), scanner->value.v_identifier); if (!enum_value) { g_scanner_error (scanner, _("invalid value '%s' for icon type"), scanner->value.v_identifier); return G_TOKEN_NONE; } break; case G_TOKEN_INT: g_scanner_get_next_token (scanner); enum_value = g_enum_get_value (enum_class, (gint) scanner->value.v_int64); if (!enum_value) { g_scanner_error (scanner, _("invalid value '%ld' for icon type"), (glong) scanner->value.v_int64); return G_TOKEN_NONE; } break; default: return G_TOKEN_IDENTIFIER; } icon_type = enum_value->value; if (! gimp_scanner_parse_int (scanner, &icon_data_length)) return G_TOKEN_INT; switch (icon_type) { case GIMP_ICON_TYPE_ICON_NAME: case GIMP_ICON_TYPE_IMAGE_FILE: icon_data_length = -1; if (! gimp_scanner_parse_string_no_validate (scanner, &icon_name)) return G_TOKEN_STRING; icon_data = (guint8 *) icon_name; break; case GIMP_ICON_TYPE_INLINE_PIXBUF: if (icon_data_length < 0) return G_TOKEN_STRING; if (! gimp_scanner_parse_data (scanner, icon_data_length, &icon_data)) return G_TOKEN_STRING; break; } gimp_plug_in_procedure_take_icon (proc, icon_type, icon_data, icon_data_length); if (! gimp_scanner_parse_token (scanner, G_TOKEN_RIGHT_PAREN)) return G_TOKEN_RIGHT_PAREN; return G_TOKEN_LEFT_PAREN; }
static GTokenType plug_in_procedure_deserialize (GScanner *scanner, Gimp *gimp, GFile *file, GimpPlugInProcedure **proc) { GimpProcedure *procedure; GTokenType token; gchar *str; gint proc_type; gint n_args; gint n_return_vals; gint n_menu_paths; gint i; if (! gimp_scanner_parse_string (scanner, &str)) return G_TOKEN_STRING; if (! gimp_scanner_parse_int (scanner, &proc_type)) { g_free (str); return G_TOKEN_INT; } procedure = gimp_plug_in_procedure_new (proc_type, file); *proc = GIMP_PLUG_IN_PROCEDURE (procedure); gimp_object_take_name (GIMP_OBJECT (procedure), gimp_canonicalize_identifier (str)); procedure->original_name = str; if (! gimp_scanner_parse_string (scanner, &procedure->blurb)) return G_TOKEN_STRING; if (! gimp_scanner_parse_string (scanner, &procedure->help)) return G_TOKEN_STRING; if (! gimp_scanner_parse_string (scanner, &procedure->author)) return G_TOKEN_STRING; if (! gimp_scanner_parse_string (scanner, &procedure->copyright)) return G_TOKEN_STRING; if (! gimp_scanner_parse_string (scanner, &procedure->date)) return G_TOKEN_STRING; if (! gimp_scanner_parse_string (scanner, &(*proc)->menu_label)) return G_TOKEN_STRING; if (! gimp_scanner_parse_int (scanner, &n_menu_paths)) return G_TOKEN_INT; for (i = 0; i < n_menu_paths; i++) { token = plug_in_menu_path_deserialize (scanner, *proc); if (token != G_TOKEN_LEFT_PAREN) return token; } token = plug_in_icon_deserialize (scanner, *proc); if (token != G_TOKEN_LEFT_PAREN) return token; token = plug_in_file_proc_deserialize (scanner, *proc); if (token != G_TOKEN_LEFT_PAREN) return token; if (! gimp_scanner_parse_string (scanner, &str)) return G_TOKEN_STRING; gimp_plug_in_procedure_set_image_types (*proc, str); g_free (str); if (! gimp_scanner_parse_int (scanner, (gint *) &n_args)) return G_TOKEN_INT; if (! gimp_scanner_parse_int (scanner, (gint *) &n_return_vals)) return G_TOKEN_INT; for (i = 0; i < n_args; i++) { token = plug_in_proc_arg_deserialize (scanner, gimp, procedure, FALSE); if (token != G_TOKEN_LEFT_PAREN) return token; } for (i = 0; i < n_return_vals; i++) { token = plug_in_proc_arg_deserialize (scanner, gimp, procedure, TRUE); if (token != G_TOKEN_LEFT_PAREN) return token; } if (! gimp_scanner_parse_token (scanner, G_TOKEN_RIGHT_PAREN)) return G_TOKEN_RIGHT_PAREN; return G_TOKEN_LEFT_PAREN; }
void gimp_action_history_init (Gimp *gimp) { GimpGuiConfig *config; GFile *file; GScanner *scanner; GTokenType token; gint count = 0; gint n_items = 0; g_return_if_fail (GIMP_IS_GIMP (gimp)); config = GIMP_GUI_CONFIG (gimp->config); if (history.items != NULL) { g_warning ("%s: must be run only once.", G_STRFUNC); return; } file = gimp_directory_file (GIMP_ACTION_HISTORY_FILENAME, NULL); if (gimp->be_verbose) g_print ("Parsing '%s'\n", gimp_file_get_utf8_name (file)); scanner = gimp_scanner_new_gfile (file, NULL); g_object_unref (file); if (! scanner) return; g_scanner_scope_add_symbol (scanner, 0, "history-item", GINT_TO_POINTER (HISTORY_ITEM)); 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 (HISTORY_ITEM)) { gchar *action_name; token = G_TOKEN_STRING; if (g_scanner_peek_next_token (scanner) != token) break; if (! gimp_scanner_parse_string (scanner, &action_name)) break; token = G_TOKEN_INT; if (g_scanner_peek_next_token (scanner) != token || ! gimp_scanner_parse_int (scanner, &count)) { g_free (action_name); break; } history.items = g_list_insert_sorted (history.items, gimp_action_history_item_new (action_name, count), (GCompareFunc) gimp_action_history_init_compare_func); n_items++; g_free (action_name); } token = G_TOKEN_RIGHT_PAREN; break; case G_TOKEN_RIGHT_PAREN: token = G_TOKEN_LEFT_PAREN; if (n_items >= config->action_history_size) goto done; break; default: /* do nothing */ break; } } done: gimp_scanner_destroy (scanner); if (count > 1) { GList *actions; gint i; for (actions = history.items, i = 0; actions && i < config->action_history_size; actions = g_list_next (actions), i++) { GimpActionHistoryItem *action = actions->data; action->count -= count - 1; } } }
GTokenType gimp_session_info_dock_deserialize (GScanner *scanner, gint scope, GimpSessionInfoDock **dock_info, const gchar *dock_type) { GTokenType token; g_return_val_if_fail (scanner != NULL, G_TOKEN_LEFT_PAREN); g_return_val_if_fail (dock_info != NULL, G_TOKEN_LEFT_PAREN); g_scanner_scope_add_symbol (scanner, scope, "side", GINT_TO_POINTER (SESSION_INFO_SIDE)); g_scanner_scope_add_symbol (scanner, scope, "position", GINT_TO_POINTER (SESSION_INFO_POSITION)); g_scanner_scope_add_symbol (scanner, scope, "book", GINT_TO_POINTER (SESSION_INFO_BOOK)); *dock_info = gimp_session_info_dock_new (dock_type); 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)) { GimpSessionInfoBook *book; case SESSION_INFO_SIDE: token = G_TOKEN_IDENTIFIER; if (g_scanner_peek_next_token (scanner) != token) break; g_scanner_get_next_token (scanner); if (strcmp ("left", scanner->value.v_identifier) == 0) (*dock_info)->side = GIMP_ALIGN_LEFT; else (*dock_info)->side = GIMP_ALIGN_RIGHT; break; case SESSION_INFO_POSITION: token = G_TOKEN_INT; if (! gimp_scanner_parse_int (scanner, &((*dock_info)->position))) (*dock_info)->position = 0; break; case SESSION_INFO_BOOK: g_scanner_set_scope (scanner, scope + 1); token = gimp_session_info_book_deserialize (scanner, scope + 1, &book); if (token == G_TOKEN_LEFT_PAREN) { (*dock_info)->books = g_list_append ((*dock_info)->books, book); g_scanner_set_scope (scanner, scope); } else return token; break; default: return token; } token = G_TOKEN_RIGHT_PAREN; break; case G_TOKEN_RIGHT_PAREN: token = G_TOKEN_LEFT_PAREN; break; default: break; } } g_scanner_scope_remove_symbol (scanner, scope, "book"); g_scanner_scope_remove_symbol (scanner, scope, "position"); g_scanner_scope_remove_symbol (scanner, scope, "side"); return token; }
static gboolean gimp_parasite_list_deserialize (GimpConfig *list, GScanner *scanner, gint nest_level, gpointer data) { GTokenType token; g_scanner_scope_add_symbol (scanner, 0, parasite_symbol, (gpointer) parasite_symbol); 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 == parasite_symbol) { gchar *parasite_name = NULL; gint parasite_flags = 0; guint8 *parasite_data = NULL; gint parasite_data_size = 0; GimpParasite *parasite; token = G_TOKEN_STRING; if (g_scanner_peek_next_token (scanner) != token) break; if (! gimp_scanner_parse_string (scanner, ¶site_name)) break; token = G_TOKEN_INT; if (g_scanner_peek_next_token (scanner) != token) goto cleanup; if (! gimp_scanner_parse_int (scanner, ¶site_flags)) goto cleanup; token = G_TOKEN_INT; if (g_scanner_peek_next_token (scanner) != token) { /* old format -- plain string */ gchar *str; if (g_scanner_peek_next_token (scanner) != G_TOKEN_STRING) goto cleanup; if (! gimp_scanner_parse_string (scanner, &str)) goto cleanup; parasite_data_size = strlen (str); parasite_data = (guint8 *) str; } else { /* new format -- properly encoded binary data */ if (! gimp_scanner_parse_int (scanner, ¶site_data_size)) goto cleanup; token = G_TOKEN_STRING; if (g_scanner_peek_next_token (scanner) != token) goto cleanup; if (! gimp_scanner_parse_data (scanner, parasite_data_size, ¶site_data)) goto cleanup; } parasite = gimp_parasite_new (parasite_name, parasite_flags, parasite_data_size, parasite_data); gimp_parasite_list_add (GIMP_PARASITE_LIST (list), parasite); /* adds a copy */ gimp_parasite_free (parasite); token = G_TOKEN_RIGHT_PAREN; g_free (parasite_data); cleanup: g_free (parasite_name); } break; case G_TOKEN_RIGHT_PAREN: token = G_TOKEN_LEFT_PAREN; break; default: /* do nothing */ break; } } return gimp_config_deserialize_return (scanner, token, nest_level); }
void session_init (Gimp *gimp) { gchar *filename; GScanner *scanner; GTokenType token; GError *error = NULL; g_return_if_fail (GIMP_IS_GIMP (gimp)); filename = session_filename (gimp); scanner = gimp_scanner_new_file (filename, &error); if (! scanner && error->code == GIMP_CONFIG_ERROR_OPEN_ENOENT) { g_clear_error (&error); g_free (filename); filename = g_build_filename (gimp_sysconf_directory (), "sessionrc", NULL); scanner = gimp_scanner_new_file (filename, NULL); } if (! scanner) { g_clear_error (&error); g_free (filename); return; } if (gimp->be_verbose) g_print ("Parsing '%s'\n", gimp_filename_to_utf8 (filename)); g_scanner_scope_add_symbol (scanner, 0, "session-info", GINT_TO_POINTER (SESSION_INFO)); g_scanner_scope_add_symbol (scanner, 0, "last-tip-shown", GINT_TO_POINTER (LAST_TIP_SHOWN)); 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 = gimp_session_info_deserialize (scanner, SESSION_INFO); if (token == G_TOKEN_RIGHT_PAREN) g_scanner_set_scope (scanner, 0); else break; } else if (scanner->value.v_symbol == GINT_TO_POINTER (LAST_TIP_SHOWN)) { GimpGuiConfig *config = GIMP_GUI_CONFIG (gimp->config); token = G_TOKEN_INT; if (! gimp_scanner_parse_int (scanner, &config->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); } if (error) { gimp_message (gimp, NULL, GIMP_MESSAGE_ERROR, "%s", error->message); g_clear_error (&error); gimp_config_file_backup_on_error (filename, "sessionrc", NULL); } gimp_scanner_destroy (scanner); g_free (filename); }
static GTokenType plug_in_def_deserialize (Gimp *gimp, GScanner *scanner, GSList **plug_in_defs) { GimpPlugInDef *plug_in_def; GimpPlugInProcedure *proc = NULL; gchar *name; gchar *path; gint mtime; GTokenType token; if (! gimp_scanner_parse_string (scanner, &name)) return G_TOKEN_STRING; path = gimp_config_path_expand (name, TRUE, NULL); g_free (name); plug_in_def = gimp_plug_in_def_new (path); g_free (path); if (! gimp_scanner_parse_int (scanner, &mtime)) { g_object_unref (plug_in_def); return G_TOKEN_INT; } plug_in_def->mtime = mtime; 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 PROC_DEF: token = plug_in_procedure_deserialize (scanner, gimp, plug_in_def->prog, &proc); if (token == G_TOKEN_LEFT_PAREN) gimp_plug_in_def_add_procedure (plug_in_def, proc); if (proc) g_object_unref (proc); break; case LOCALE_DEF: token = plug_in_locale_def_deserialize (scanner, plug_in_def); break; case HELP_DEF: token = plug_in_help_def_deserialize (scanner, plug_in_def); break; case HAS_INIT: token = plug_in_has_init_deserialize (scanner, plug_in_def); break; default: break; } 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 (gimp_scanner_parse_token (scanner, token)) { *plug_in_defs = g_slist_prepend (*plug_in_defs, plug_in_def); return G_TOKEN_LEFT_PAREN; } } g_object_unref (plug_in_def); return token; }
static gboolean gimp_session_info_deserialize (GimpConfig *config, GScanner *scanner, gint nest_level, gpointer data) { GimpSessionInfo *info = GIMP_SESSION_INFO (config); GTokenType token; guint scope_id; guint old_scope_id; scope_id = g_type_qname (G_TYPE_FROM_INSTANCE (config)); old_scope_id = g_scanner_set_scope (scanner, scope_id); g_scanner_scope_add_symbol (scanner, scope_id, "factory-entry", GINT_TO_POINTER (SESSION_INFO_FACTORY_ENTRY)); g_scanner_scope_add_symbol (scanner, scope_id, "position", GINT_TO_POINTER (SESSION_INFO_POSITION)); g_scanner_scope_add_symbol (scanner, scope_id, "size", GINT_TO_POINTER (SESSION_INFO_SIZE)); g_scanner_scope_add_symbol (scanner, scope_id, "monitor", GINT_TO_POINTER (SESSION_INFO_MONITOR)); g_scanner_scope_add_symbol (scanner, scope_id, "open-on-exit", GINT_TO_POINTER (SESSION_INFO_OPEN)); g_scanner_scope_add_symbol (scanner, scope_id, "aux-info", GINT_TO_POINTER (SESSION_INFO_AUX)); g_scanner_scope_add_symbol (scanner, scope_id, "gimp-dock", GINT_TO_POINTER (SESSION_INFO_GIMP_DOCK)); g_scanner_scope_add_symbol (scanner, scope_id, "gimp-toolbox", GINT_TO_POINTER (SESSION_INFO_GIMP_TOOLBOX)); /* For sessionrc files from version <= GIMP 2.6 */ g_scanner_scope_add_symbol (scanner, scope_id, "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) { gint dummy; 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_FACTORY_ENTRY: { gchar *identifier = NULL; GimpDialogFactoryEntry *entry = NULL; token = G_TOKEN_STRING; if (! gimp_scanner_parse_string (scanner, &identifier)) goto error; entry = gimp_dialog_factory_find_entry (gimp_dialog_factory_get_singleton (), identifier); if (! entry) goto error; gimp_session_info_set_factory_entry (info, entry); g_free (identifier); } break; case SESSION_INFO_POSITION: token = G_TOKEN_INT; if (! gimp_session_info_parse_offset (scanner, &info->p->x, &info->p->right_align)) goto error; if (! gimp_session_info_parse_offset (scanner, &info->p->y, &info->p->bottom_align)) goto error; break; case SESSION_INFO_SIZE: token = G_TOKEN_INT; if (! gimp_scanner_parse_int (scanner, &info->p->width)) goto error; if (! gimp_scanner_parse_int (scanner, &info->p->height)) goto error; break; case SESSION_INFO_MONITOR: token = G_TOKEN_INT; if (gimp_scanner_parse_int (scanner, &dummy)) { info->p->monitor = gdk_display_get_monitor (gdk_display_get_default (), dummy); } else goto error; break; case SESSION_INFO_OPEN: info->p->open = TRUE; /* the screen number is optional, and obsolete */ if (g_scanner_peek_next_token (scanner) == G_TOKEN_RIGHT_PAREN) break; token = G_TOKEN_INT; if (! gimp_scanner_parse_int (scanner, &dummy)) goto error; break; case SESSION_INFO_AUX: token = gimp_session_info_aux_deserialize (scanner, &info->p->aux_info); if (token != G_TOKEN_LEFT_PAREN) goto error; break; case SESSION_INFO_GIMP_TOOLBOX: case SESSION_INFO_GIMP_DOCK: case SESSION_INFO_DOCK: { GimpSessionInfoDock *dock_info = NULL; const gchar *dock_type = NULL; /* Handle old sessionrc:s from versions <= GIMP 2.6 */ if (GPOINTER_TO_INT (scanner->value.v_symbol) == SESSION_INFO_DOCK && info->p->factory_entry && info->p->factory_entry->identifier && strcmp ("gimp-toolbox-window", info->p->factory_entry->identifier) == 0) { dock_type = "gimp-toolbox"; } else { dock_type = ((GPOINTER_TO_INT (scanner->value.v_symbol) == SESSION_INFO_GIMP_TOOLBOX) ? "gimp-toolbox" : "gimp-dock"); } g_scanner_set_scope (scanner, scope_id + 1); token = gimp_session_info_dock_deserialize (scanner, scope_id + 1, &dock_info, dock_type); if (token == G_TOKEN_LEFT_PAREN) { g_scanner_set_scope (scanner, scope_id); info->p->docks = g_list_append (info->p->docks, dock_info); } else goto error; } break; default: break; } token = G_TOKEN_RIGHT_PAREN; break; case G_TOKEN_RIGHT_PAREN: token = G_TOKEN_LEFT_PAREN; break; default: break; } } error: /* If we don't have docks, assume it is a toolbox dock window from a * sessionrc file from GIMP <= 2.6 and add a toolbox dock manually */ if (! info->p->docks && info->p->factory_entry && strcmp ("gimp-toolbox-window", info->p->factory_entry->identifier) == 0) { info->p->docks = g_list_append (info->p->docks, gimp_session_info_dock_new ("gimp-toolbox")); } g_scanner_scope_remove_symbol (scanner, scope_id, "factory-entry"); g_scanner_scope_remove_symbol (scanner, scope_id, "position"); g_scanner_scope_remove_symbol (scanner, scope_id, "size"); g_scanner_scope_remove_symbol (scanner, scope_id, "open-on-exit"); g_scanner_scope_remove_symbol (scanner, scope_id, "aux-info"); g_scanner_scope_remove_symbol (scanner, scope_id, "gimp-dock"); g_scanner_scope_remove_symbol (scanner, scope_id, "gimp-toolbox"); g_scanner_scope_remove_symbol (scanner, scope_id, "dock"); g_scanner_set_scope (scanner, old_scope_id); return gimp_config_deserialize_return (scanner, token, nest_level); }