diff --git a/src/core/settings.c b/src/core/settings.c index 1ddc6fa6..5c8d17d2 100644 --- a/src/core/settings.c +++ b/src/core/settings.c @@ -33,6 +33,7 @@ CONFIG_REC *mainconfig; static GString *last_errors; static char *last_config_error_msg; +static GSList *last_invalid_modules; static int fe_initialized; static int config_changed; /* FIXME: remove after .98 (unless needed again) */ @@ -269,7 +270,7 @@ static void sig_init_finished(void) { fe_initialized = TRUE; if (last_errors != NULL) { - signal_emit("gui dialog", 2, "error", last_errors->str); + signal_emit("settings errors", 1, last_errors->str); g_string_free(last_errors, TRUE); } @@ -299,6 +300,43 @@ static void settings_move(SETTINGS_REC *rec, char *value) config_changed = TRUE; } +static void settings_clean_invalid_module(const char *module) +{ + CONFIG_NODE *node; + SETTINGS_REC *set; + GSList *tmp, *next; + + node = iconfig_node_traverse("settings", FALSE); + if (node == NULL) return; + + node = config_node_section(node, module, -1); + if (node == NULL) return; + + for (tmp = node->value; tmp != NULL; tmp = next) { + CONFIG_NODE *subnode = tmp->data; + next = tmp->next; + + set = g_hash_table_lookup(settings, subnode->key); + if (set == NULL || strcmp(set->module, module) != 0) + iconfig_node_remove(node, subnode); + } +} + +/* remove all invalid settings from config file. works only with the + modules that have already called settings_check() */ +void settings_clean_invalid(void) +{ + while (last_invalid_modules != NULL) { + char *module = last_invalid_modules->data; + + settings_clean_invalid_module(module); + + g_free(module); + last_invalid_modules = + g_slist_remove(last_invalid_modules, module); + } +} + /* verify that all settings in config file for `module' are actually found from /SET list */ void settings_check_module(const char *module) @@ -311,7 +349,7 @@ void settings_check_module(const char *module) g_return_if_fail(module != NULL); - node = iconfig_node_traverse("settings", TRUE); + node = iconfig_node_traverse("settings", FALSE); if (node != NULL) { /* FIXME: remove after 0.7.98 */ for (tmp = node->value; tmp != NULL; tmp = next) { @@ -329,8 +367,8 @@ void settings_check_module(const char *module) if (node == NULL) return; errors = g_string_new(NULL); - g_string_sprintf(errors, "Unknown settings in configuration " - "file for module %s:", module); + g_string_sprintf(errors, _("Unknown settings in configuration " + "file for module %s:"), module); count = 0; for (tmp = node->value; tmp != NULL; tmp = tmp->next) { @@ -343,8 +381,15 @@ void settings_check_module(const char *module) } } if (count > 0) { + if (gslist_find_icase_string(last_invalid_modules, + module) == NULL) { + /* mark this module having invalid settings */ + last_invalid_modules = + g_slist_append(last_invalid_modules, + g_strdup(module)); + } if (fe_initialized) - signal_emit("gui dialog", 2, "error", errors->str); + signal_emit("settings errors", 1, errors->str); else { if (last_errors == NULL) last_errors = g_string_new(NULL); @@ -466,7 +511,7 @@ static CONFIG_REC *parse_configfile(const char *fname) config = config_open(path, -1); if (config == NULL) { last_config_error_msg = - g_strdup_printf("Error opening configuration file %s: %s", + g_strdup_printf(_("Error opening configuration file %s: %s"), path, g_strerror(errno)); config = config_open(NULL, -1); } @@ -602,7 +647,8 @@ void settings_init(void) (GCompareFunc) g_str_equal); last_errors = NULL; - last_config_error_msg = NULL; + last_config_error_msg = NULL; + last_invalid_modules = NULL; fe_initialized = FALSE; config_changed = FALSE; @@ -627,6 +673,9 @@ void settings_deinit(void) signal_remove("irssi init finished", (SIGNAL_FUNC) sig_init_finished); signal_remove("gui exit", (SIGNAL_FUNC) sig_autosave); + g_slist_foreach(last_invalid_modules, (GFunc) g_free, NULL); + g_slist_free(last_invalid_modules); + g_hash_table_foreach(settings, (GHFunc) settings_hash_free, NULL); g_hash_table_destroy(settings); diff --git a/src/core/settings.h b/src/core/settings.h index 72cf6193..cea8c4d0 100644 --- a/src/core/settings.h +++ b/src/core/settings.h @@ -74,6 +74,10 @@ SETTINGS_REC *settings_get_record(const char *key); void settings_check_module(const char *module); #define settings_check() settings_check_module(MODULE_NAME) +/* remove all invalid settings from config file. works only with the + modules that have already called settings_check() */ +void settings_clean_invalid(void); + /* if `fname' is NULL, the default is used */ int settings_reread(const char *fname); int settings_save(const char *fname); diff --git a/src/fe-common/core/fe-settings.c b/src/fe-common/core/fe-settings.c index 694318f6..92f1d99a 100644 --- a/src/fe-common/core/fe-settings.c +++ b/src/fe-common/core/fe-settings.c @@ -285,6 +285,20 @@ static void cmd_save(const char *data) 0, g_strdup(data)); } +static void settings_clean_confirm(const char *line) +{ + if (g_strncasecmp(line, _("Y"), 1) == 0) + settings_clean_invalid(); +} + +static void sig_settings_errors(const char *msg) +{ + printtext(NULL, NULL, MSGLEVEL_CLIENTERROR, "%s", msg); + keyboard_entry_redirect((SIGNAL_FUNC) settings_clean_confirm, + _("Remove unknown settings from config file (Y/n)?"), + 0, NULL); +} + void fe_settings_init(void) { command_bind("set", NULL, (SIGNAL_FUNC) cmd_set); @@ -293,8 +307,9 @@ void fe_settings_init(void) command_bind("unalias", NULL, (SIGNAL_FUNC) cmd_unalias); command_bind("reload", NULL, (SIGNAL_FUNC) cmd_reload); command_bind("save", NULL, (SIGNAL_FUNC) cmd_save); - command_set_options("set", "clear"); + + signal_add("settings errors", (SIGNAL_FUNC) sig_settings_errors); } void fe_settings_deinit(void) @@ -305,4 +320,6 @@ void fe_settings_deinit(void) command_unbind("unalias", (SIGNAL_FUNC) cmd_unalias); command_unbind("reload", (SIGNAL_FUNC) cmd_reload); command_unbind("save", (SIGNAL_FUNC) cmd_save); + + signal_remove("settings errors", (SIGNAL_FUNC) sig_settings_errors); }