1
0
mirror of https://github.com/rkd77/elinks.git synced 2024-11-04 08:17:17 -05:00

config: Rewrite "set" to "unset" and vice versa.

Also, replace OPT_WATERMARK with OPT_MUST_SAVE, which has the opposite
meaning.

Watermarking of aliases does not yet work correctly in this version.
Neither does the "include" command.
(cherry picked from commit 7cdbc908d8)
This commit is contained in:
Kalle Olavi Niemitalo 2008-02-03 13:07:43 +02:00 committed by Kalle Olavi Niemitalo
parent 841153b625
commit 77755cf684
3 changed files with 89 additions and 53 deletions

View File

@ -192,8 +192,8 @@ skip_to_unquoted_newline_or_comment(struct conf_parsing_pos *pos)
/* Parse a command. Returns error code. */ /* Parse a command. Returns error code. */
/* If dynamic string credentials are supplied, we will mirror the command at /* If dynamic string credentials are supplied, we will mirror the command at
* the end of the string; however, we won't load the option value to the tree, * the end of the string; however, we won't load the option value to the tree,
* and we will even write option value from the tree to the output string. We * and we will even write option value from the tree to the output string.
* will only possibly set OPT_WATERMARK flag to the option (if enabled). */ * We will only possibly clear OPT_MUST_SAVE flag in the option. */
static enum parse_error static enum parse_error
parse_set(struct option *opt_tree, struct conf_parsing_state *state, parse_set(struct option *opt_tree, struct conf_parsing_state *state,
@ -242,6 +242,24 @@ parse_set(struct option *opt_tree, struct conf_parsing_state *state,
show_parse_error(state, ERROR_OPTION); show_parse_error(state, ERROR_OPTION);
skip_option_value(&state->pos); skip_option_value(&state->pos);
return ERROR_OPTION; return ERROR_OPTION;
/* TODO: Distinguish between two scenarios:
* - A newer version of ELinks has saved an
* option that this version does not recognize.
* The option must be preserved. (This works.)
* - The user has added an option, saved
* elinks.conf, restarted ELinks, deleted the
* option, and is now saving elinks.conf again.
* The option should be rewritten to "unset".
* (This does not work yet.)
* In both cases, ELinks has no struct option
* for that name. Possible fixes:
* - If the tree has OPT_AUTOCREATE, then
* assume the user had created that option,
* and rewrite it to "unset". Otherwise,
* keep it.
* - When the user deletes an option, just mark
* it with OPT_DELETED, and keep it in memory
* as long as OPT_TOUCHED is set. */
} }
if (!option_types[opt->type].read) { if (!option_types[opt->type].read) {
@ -274,21 +292,24 @@ parse_set(struct option *opt_tree, struct conf_parsing_state *state,
} }
} else { } else {
/* rewriting a configuration file */ /* rewriting a configuration file */
if (opt->flags & OPT_DELETED) if (opt->flags & OPT_DELETED) {
opt->flags &= ~OPT_WATERMARK; /* Replace the "set" command with an
else * "unset" command. */
opt->flags |= OPT_WATERMARK; add_to_string(mirror, "unset ");
if (option_types[opt->type].write) { add_bytes_to_string(mirror, optname_orig,
optname_len);
state->mirrored = state->pos.look;
} else if (option_types[opt->type].write) {
add_bytes_to_string(mirror, state->mirrored, add_bytes_to_string(mirror, state->mirrored,
pos_before_value.look pos_before_value.look
- state->mirrored); - state->mirrored);
option_types[opt->type].write(opt, mirror); option_types[opt->type].write(opt, mirror);
state->mirrored = state->pos.look; state->mirrored = state->pos.look;
} }
/* Remember that the option need not be
* written to the end of the file. */
opt->flags &= ~OPT_MUST_SAVE;
} }
/* This is not needed since this will be WATERMARK'd when
* saving it. We won't need to save it as touched. */
/* if (!str) opt->flags |= OPT_TOUCHED; */
mem_free(val); mem_free(val);
} }
@ -303,9 +324,6 @@ parse_unset(struct option *opt_tree, struct conf_parsing_state *state,
size_t optname_len; size_t optname_len;
unsigned char *optname_copy; unsigned char *optname_copy;
/* XXX: This does not handle the autorewriting well and is mostly a
* quick hack than anything now. --pasky */
skip_white(&state->pos); skip_white(&state->pos);
if (!*state->pos.look) return show_parse_error(state, ERROR_PARSE); if (!*state->pos.look) return show_parse_error(state, ERROR_PARSE);
@ -342,10 +360,23 @@ parse_unset(struct option *opt_tree, struct conf_parsing_state *state,
else mark_option_as_deleted(opt); else mark_option_as_deleted(opt);
} else { } else {
/* rewriting a configuration file */ /* rewriting a configuration file */
if (opt->flags & OPT_DELETED) if (opt->flags & OPT_DELETED) {
opt->flags |= OPT_WATERMARK; /* The "unset" command is already in the file,
else * and unlike with "set", there is no value
opt->flags &= ~OPT_WATERMARK; * to be updated. */
} else if (option_types[opt->type].write) {
/* Replace the "unset" command with a
* "set" command. */
add_to_string(mirror, "set ");
add_bytes_to_string(mirror, optname_orig,
optname_len);
add_to_string(mirror, " = ");
option_types[opt->type].write(opt, mirror);
state->mirrored = state->pos.look;
}
/* Remember that the option need not be
* written to the end of the file. */
opt->flags &= ~OPT_MUST_SAVE;
} }
} }
@ -716,7 +747,6 @@ load_config(void)
static int indentation = 2; static int indentation = 2;
/* 0 -> none, 1 -> only option full name+type, 2 -> only desc, 3 -> both */ /* 0 -> none, 1 -> only option full name+type, 2 -> only desc, 3 -> both */
static int comments = 3; static int comments = 3;
static int touching = 0;
static inline unsigned char * static inline unsigned char *
conf_i18n(unsigned char *s, int i18n) conf_i18n(unsigned char *s, int i18n)
@ -743,12 +773,6 @@ smart_config_output_fn(struct string *string, struct option *option,
if (option->type == OPT_ALIAS) if (option->type == OPT_ALIAS)
return; return;
/* XXX: OPT_LANGUAGE shouldn't have any bussiness here, but we're just
* weird in that area. */
if (touching && !(option->flags & OPT_TOUCHED)
&& option->type != OPT_LANGUAGE)
return;
switch (action) { switch (action) {
case 0: case 0:
if (!(comments & 1)) break; if (!(comments & 1)) break;
@ -868,23 +892,18 @@ create_config_string(unsigned char *prefix, unsigned char *name,
if (!init_string(&config)) return NULL; if (!init_string(&config)) return NULL;
if (savestyle == 3) { prepare_mustsave_flags(options->value.tree,
touching = 1; savestyle == 1 || savestyle == 2);
savestyle = 1;
} else {
touching = 0;
}
/* Scaring. */ /* Scaring. */
if (savestyle == 2 if (savestyle == 2
|| (savestyle < 2 || load_config_file(prefix, name, options, &config, 0)
&& (load_config_file(prefix, name, options, &config, 0) || !config.length) {
|| !config.length))) {
/* At first line, and in English, write ELinks version, may be /* At first line, and in English, write ELinks version, may be
* of some help in future. Please keep that format for it. * of some help in future. Please keep that format for it.
* --Zas */ * --Zas */
add_to_string(&config, "## ELinks " VERSION " configuration file\n\n"); add_to_string(&config, "## ELinks " VERSION " configuration file\n\n");
assert(savestyle >= 0 && savestyle <= 2); assert(savestyle >= 0 && savestyle <= 3);
switch (savestyle) { switch (savestyle) {
case 0: case 0:
add_to_string(&config, conf_i18n(N_( add_to_string(&config, conf_i18n(N_(
@ -894,7 +913,7 @@ create_config_string(unsigned char *prefix, unsigned char *name,
"## and all your formatting, own comments etc will be kept as-is.\n"), "## and all your formatting, own comments etc will be kept as-is.\n"),
i18n)); i18n));
break; break;
case 1: case 1: case 3:
add_to_string(&config, conf_i18n(N_( add_to_string(&config, conf_i18n(N_(
"## This is ELinks configuration file. You can edit it manually,\n" "## This is ELinks configuration file. You can edit it manually,\n"
"## if you wish so; this file is edited by ELinks when you save\n" "## if you wish so; this file is edited by ELinks when you save\n"
@ -951,8 +970,6 @@ create_config_string(unsigned char *prefix, unsigned char *name,
done_string(&tmpstring); done_string(&tmpstring);
get_me_out: get_me_out:
unmark_options_tree(options->value.tree);
return config.source; return config.source;
} }

View File

@ -731,14 +731,22 @@ register_change_hooks(struct change_hook_info *change_hooks)
} }
void void
unmark_options_tree(struct list_head *tree) prepare_mustsave_flags(struct list_head *tree, int set_all)
{ {
struct option *option; struct option *option;
foreach (option, *tree) { foreach (option, *tree) {
option->flags &= ~OPT_WATERMARK; /* XXX: OPT_LANGUAGE shouldn't have any bussiness
* here, but we're just weird in that area. */
if (set_all
|| (option->flags & (OPT_TOUCHED | OPT_DELETED))
|| option->type == OPT_LANGUAGE)
option->flags |= OPT_MUST_SAVE;
else
option->flags &= ~OPT_MUST_SAVE;
if (option->type == OPT_TREE) if (option->type == OPT_TREE)
unmark_options_tree(option->value.tree); prepare_mustsave_flags(option->value.tree, set_all);
} }
} }
@ -764,7 +772,7 @@ check_nonempty_tree(struct list_head *options)
if (opt->type == OPT_TREE) { if (opt->type == OPT_TREE) {
if (check_nonempty_tree(opt->value.tree)) if (check_nonempty_tree(opt->value.tree))
return 1; return 1;
} else if (!(opt->flags & OPT_WATERMARK)) { } else if (opt->flags & OPT_MUST_SAVE) {
return 1; return 1;
} }
} }
@ -784,14 +792,14 @@ smart_config_string(struct string *str, int print_comment, int i18n,
int do_print_comment = 1; int do_print_comment = 1;
if (option->flags & OPT_HIDDEN || if (option->flags & OPT_HIDDEN ||
option->flags & OPT_WATERMARK ||
option->type == OPT_ALIAS || option->type == OPT_ALIAS ||
!strcmp(option->name, "_template_")) !strcmp(option->name, "_template_"))
continue; continue;
/* Is there anything to be printed anyway? */ /* Is there anything to be printed anyway? */
if (option->type == OPT_TREE if (option->type == OPT_TREE
&& !check_nonempty_tree(option->value.tree)) ? !check_nonempty_tree(option->value.tree)
: !(option->flags & OPT_MUST_SAVE))
continue; continue;
/* We won't pop out the description when we're in autocreate /* We won't pop out the description when we're in autocreate

View File

@ -24,15 +24,26 @@ enum option_flags {
* this category when adding an option. The 'template' for the added * this category when adding an option. The 'template' for the added
* hiearchy piece (category) is stored as "_template_" category. */ * hiearchy piece (category) is stored as "_template_" category. */
OPT_AUTOCREATE = 2, OPT_AUTOCREATE = 2,
/* This is used just for marking various options for some very dark, /* The option has been modified in some way and must be saved
* nasty and dirty purposes. This watermarking should be kept inside * to elinks.conf. ELinks uses this flag only while it is
* some very closed and clearly bounded piece of ELinks module, not * saving the options. When the config.saving_style option
* spreaded along whole ELinks code, and you should clear it everytime * has value 3, saving works like this:
* when sneaking outside of the module (except some trivial common * - First, ELinks sets OPT_MUST_SAVE in the options that have
* utility functions). Basically, you don't want to use this flag * OPT_TOUCHED or OPT_DELETED, and clears it in the rest.
* normally ;). It doesn't affect how the option is handled by common * - ELinks then parses the old configuration file. If it
* option handling functions in any way. */ * contains a "set" or "unset" command for this option,
OPT_WATERMARK = 4, * ELinks rewrites the command and clears OPT_MUST_SAVE.
* - After ELinks has rewritten the configuration file, it
* appends the options that still have the OPT_MUST_SAVE
* flag.
* Other saving styles are variants of this:
* - 0: ELinks does not append any options to the
* configuration file. So OPT_MUST_SAVE has no effect.
* - 1: ELinks initially sets OPT_MUST_SAVE in all options,
* regardless of OPT_TOUCHED and OPT_DELETED.
* - 2: ELinks initially sets OPT_MUST_SAVE in all options,
* and does not read any configuration files. */
OPT_MUST_SAVE = 4,
/* This is used to mark options modified after the last save. That's /* This is used to mark options modified after the last save. That's
* being useful if you want to save only the options whose value * being useful if you want to save only the options whose value
* changed. */ * changed. */
@ -150,7 +161,7 @@ extern void register_change_hooks(struct change_hook_info *change_hooks);
extern struct list_head *init_options_tree(void); extern struct list_head *init_options_tree(void);
extern void unmark_options_tree(struct list_head *); extern void prepare_mustsave_flags(struct list_head *, int set_all);
extern void untouch_options(struct list_head *); extern void untouch_options(struct list_head *);
extern void smart_config_string(struct string *, int, int, struct list_head *, unsigned char *, int, extern void smart_config_string(struct string *, int, int, struct list_head *, unsigned char *, int,