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:
parent
841153b625
commit
77755cf684
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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,
|
||||||
|
Loading…
Reference in New Issue
Block a user