mirror of
https://github.com/rkd77/elinks.git
synced 2024-12-04 14:46:47 -05:00
config: Fix the "include" command.
Previously, it only pretended to rewrite the configuration file, so it set or cleared OPT_MUST_SAVE but never changed or output any options. Now, it actually sets the options when ELinks is loading the configuration file. Also, when ELinks is rewriting the configuration file, it now compares the values in the included file to the current values of the options, and sets or clears OPT_MUST_SAVE accordingly.
This commit is contained in:
parent
92b430f3dc
commit
054852ae23
@ -193,7 +193,7 @@ skip_to_unquoted_newline_or_comment(struct conf_parsing_pos *pos)
|
|||||||
/* 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.
|
* and we will even write option value from the tree to the output string.
|
||||||
* We will only possibly clear OPT_MUST_SAVE flag in the option. */
|
* We will only possibly set or 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,
|
||||||
@ -290,6 +290,16 @@ parse_set(struct option *opt_tree, struct conf_parsing_state *state,
|
|||||||
mem_free(val);
|
mem_free(val);
|
||||||
return show_parse_error(state, ERROR_VALUE);
|
return show_parse_error(state, ERROR_VALUE);
|
||||||
}
|
}
|
||||||
|
} else if (is_system_conf) {
|
||||||
|
/* scanning a file that will not be rewritten */
|
||||||
|
struct option *flagsite = indirect_option(opt);
|
||||||
|
|
||||||
|
if (!(flagsite->flags & OPT_DELETED)
|
||||||
|
&& option_types[opt->type].equals
|
||||||
|
&& option_types[opt->type].equals(opt, val))
|
||||||
|
flagsite->flags &= ~OPT_MUST_SAVE;
|
||||||
|
else
|
||||||
|
flagsite->flags |= OPT_MUST_SAVE;
|
||||||
} else {
|
} else {
|
||||||
/* rewriting a configuration file */
|
/* rewriting a configuration file */
|
||||||
struct option *flagsite = indirect_option(opt);
|
struct option *flagsite = indirect_option(opt);
|
||||||
@ -360,6 +370,14 @@ parse_unset(struct option *opt_tree, struct conf_parsing_state *state,
|
|||||||
/* loading a configuration file */
|
/* loading a configuration file */
|
||||||
if (opt->flags & OPT_ALLOC) delete_option(opt);
|
if (opt->flags & OPT_ALLOC) delete_option(opt);
|
||||||
else mark_option_as_deleted(opt);
|
else mark_option_as_deleted(opt);
|
||||||
|
} else if (is_system_conf) {
|
||||||
|
/* scanning a file that will not be rewritten */
|
||||||
|
struct option *flagsite = indirect_option(opt);
|
||||||
|
|
||||||
|
if (flagsite->flags & OPT_DELETED)
|
||||||
|
flagsite->flags &= ~OPT_MUST_SAVE;
|
||||||
|
else
|
||||||
|
flagsite->flags |= OPT_MUST_SAVE;
|
||||||
} else {
|
} else {
|
||||||
/* rewriting a configuration file */
|
/* rewriting a configuration file */
|
||||||
struct option *flagsite = indirect_option(opt);
|
struct option *flagsite = indirect_option(opt);
|
||||||
@ -453,6 +471,9 @@ parse_bind(struct option *opt_tree, struct conf_parsing_state *state,
|
|||||||
} else {
|
} else {
|
||||||
err = ERROR_NONE;
|
err = ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
} else if (is_system_conf) {
|
||||||
|
/* scanning a file that will not be rewritten */
|
||||||
|
/* TODO */
|
||||||
} else {
|
} else {
|
||||||
/* rewriting a configuration file */
|
/* rewriting a configuration file */
|
||||||
/* Mirror what we already have. If the keystroke has
|
/* Mirror what we already have. If the keystroke has
|
||||||
@ -513,7 +534,8 @@ parse_include(struct option *opt_tree, struct conf_parsing_state *state,
|
|||||||
* CONFDIR/<otherfile> ;). --pasky */
|
* CONFDIR/<otherfile> ;). --pasky */
|
||||||
if (load_config_file(fname[0] == '/' ? (unsigned char *) ""
|
if (load_config_file(fname[0] == '/' ? (unsigned char *) ""
|
||||||
: elinks_home,
|
: elinks_home,
|
||||||
fname, opt_tree, &dumbstring, is_system_conf)) {
|
fname, opt_tree,
|
||||||
|
mirror ? &dumbstring : NULL, 1)) {
|
||||||
done_string(&dumbstring);
|
done_string(&dumbstring);
|
||||||
mem_free(fname);
|
mem_free(fname);
|
||||||
return show_parse_error(state, ERROR_VALUE);
|
return show_parse_error(state, ERROR_VALUE);
|
||||||
|
@ -30,12 +30,19 @@ enum option_flags {
|
|||||||
* has value 3, saving works like this:
|
* has value 3, saving works like this:
|
||||||
* - First, ELinks sets OPT_MUST_SAVE in the options that have
|
* - First, ELinks sets OPT_MUST_SAVE in the options that have
|
||||||
* OPT_TOUCHED or OPT_DELETED, and clears it in the rest.
|
* OPT_TOUCHED or OPT_DELETED, and clears it in the rest.
|
||||||
* - ELinks then parses the old configuration file. If it
|
* - ELinks then parses the old configuration file and any
|
||||||
* contains a "set" or "unset" command for this option,
|
* files named in "include" commands.
|
||||||
* ELinks rewrites the command and clears OPT_MUST_SAVE.
|
* - If the old configuration file contains a "set" or "unset"
|
||||||
* - After ELinks has rewritten the configuration file, it
|
* command for this option, ELinks rewrites the command and
|
||||||
* appends the options that still have the OPT_MUST_SAVE
|
* clears OPT_MUST_SAVE.
|
||||||
* flag.
|
* - If an included file contains a "set" or "unset" command
|
||||||
|
* for this option, ELinks compares the value of the option
|
||||||
|
* to the value given in the command. ELinks clears
|
||||||
|
* OPT_MUST_SAVE if the values match, or sets it if they
|
||||||
|
* differ.
|
||||||
|
* - After ELinks has rewritten the configuration file and
|
||||||
|
* parsed the included files, it appends the options that
|
||||||
|
* still have the OPT_MUST_SAVE flag.
|
||||||
* Other saving styles are variants of this:
|
* Other saving styles are variants of this:
|
||||||
* - 0: ELinks does not append any options to the
|
* - 0: ELinks does not append any options to the
|
||||||
* configuration file. So OPT_MUST_SAVE has no effect.
|
* configuration file. So OPT_MUST_SAVE has no effect.
|
||||||
|
@ -162,6 +162,28 @@ redir_set(struct option *opt, unsigned char *str)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
redir_eq(struct option *opt, const unsigned char *str)
|
||||||
|
{
|
||||||
|
struct option *real = get_opt_rec(config_options, opt->value.string);
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
assertm(real != NULL, "%s aliased to unknown option %s!", opt->name, opt->value.string);
|
||||||
|
if_assert_failed { return ret; }
|
||||||
|
|
||||||
|
if (option_types[real->type].equals) {
|
||||||
|
long negated;
|
||||||
|
|
||||||
|
if ((opt->flags & OPT_ALIAS_NEGATE) && real->type == OPT_BOOL) {
|
||||||
|
negated = !*(const long *) str;
|
||||||
|
str = (unsigned char *) &negated;
|
||||||
|
}
|
||||||
|
ret = option_types[real->type].equals(real, str);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Support functions for config file parsing. */
|
/* Support functions for config file parsing. */
|
||||||
@ -207,6 +229,12 @@ num_set(struct option *opt, unsigned char *str)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
num_eq(struct option *opt, const unsigned char *str)
|
||||||
|
{
|
||||||
|
return str && opt->value.number == *(const long *) str;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
num_wr(struct option *option, struct string *string)
|
num_wr(struct option *option, struct string *string)
|
||||||
{
|
{
|
||||||
@ -221,6 +249,12 @@ long_set(struct option *opt, unsigned char *str)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
long_eq(struct option *opt, const unsigned char *str)
|
||||||
|
{
|
||||||
|
return str && opt->value.big_number == *(const long *) str;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
long_wr(struct option *option, struct string *string)
|
long_wr(struct option *option, struct string *string)
|
||||||
{
|
{
|
||||||
@ -290,6 +324,12 @@ str_set(struct option *opt, unsigned char *str)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
str_eq(struct option *opt, const unsigned char *str)
|
||||||
|
{
|
||||||
|
return str && strcmp(opt->value.string, str) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
str_wr(struct option *o, struct string *s)
|
str_wr(struct option *o, struct string *s)
|
||||||
{
|
{
|
||||||
@ -320,6 +360,12 @@ cp_set(struct option *opt, unsigned char *str)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
cp_eq(struct option *opt, const unsigned char *str)
|
||||||
|
{
|
||||||
|
return str && get_cp_index(str) == opt->value.number;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
cp_wr(struct option *o, struct string *s)
|
cp_wr(struct option *o, struct string *s)
|
||||||
{
|
{
|
||||||
@ -339,6 +385,16 @@ lang_set(struct option *opt, unsigned char *str)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
lang_eq(struct option *opt, const unsigned char *str)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_NLS
|
||||||
|
return str && name_to_language(str) == opt->value.number;
|
||||||
|
#else
|
||||||
|
return 1; /* All languages are the same. */
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
lang_wr(struct option *o, struct string *s)
|
lang_wr(struct option *o, struct string *s)
|
||||||
{
|
{
|
||||||
@ -360,6 +416,15 @@ color_set(struct option *opt, unsigned char *str)
|
|||||||
return !decode_color(str, strlen(str), &opt->value.color);
|
return !decode_color(str, strlen(str), &opt->value.color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
color_eq(struct option *opt, const unsigned char *str)
|
||||||
|
{
|
||||||
|
color_T color;
|
||||||
|
|
||||||
|
return str && !decode_color(str, strlen(str), &color)
|
||||||
|
&& color == opt->value.color;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
color_wr(struct option *opt, struct string *str)
|
color_wr(struct option *opt, struct string *str)
|
||||||
{
|
{
|
||||||
@ -404,29 +469,29 @@ const struct option_type_info option_types[] = {
|
|||||||
/* The OPT_ comments below are here to be found by grep. */
|
/* The OPT_ comments below are here to be found by grep. */
|
||||||
|
|
||||||
/* OPT_BOOL */
|
/* OPT_BOOL */
|
||||||
{ N_("Boolean"), bool_cmd, num_rd, num_wr, NULL, num_set, N_("[0|1]") },
|
{ N_("Boolean"), bool_cmd, num_rd, num_wr, NULL, num_set, num_eq, N_("[0|1]") },
|
||||||
/* OPT_INT */
|
/* OPT_INT */
|
||||||
{ N_("Integer"), gen_cmd, num_rd, num_wr, NULL, num_set, N_("<num>") },
|
{ N_("Integer"), gen_cmd, num_rd, num_wr, NULL, num_set, num_eq, N_("<num>") },
|
||||||
/* OPT_LONG */
|
/* OPT_LONG */
|
||||||
{ N_("Longint"), gen_cmd, num_rd, long_wr, NULL, long_set, N_("<num>") },
|
{ N_("Longint"), gen_cmd, num_rd, long_wr, NULL, long_set, long_eq, N_("<num>") },
|
||||||
/* OPT_STRING */
|
/* OPT_STRING */
|
||||||
{ N_("String"), gen_cmd, str_rd, str_wr, str_dup, str_set, N_("<str>") },
|
{ N_("String"), gen_cmd, str_rd, str_wr, str_dup, str_set, str_eq, N_("<str>") },
|
||||||
|
|
||||||
/* OPT_CODEPAGE */
|
/* OPT_CODEPAGE */
|
||||||
{ N_("Codepage"), gen_cmd, str_rd, cp_wr, NULL, cp_set, N_("<codepage>") },
|
{ N_("Codepage"), gen_cmd, str_rd, cp_wr, NULL, cp_set, cp_eq, N_("<codepage>") },
|
||||||
/* OPT_LANGUAGE */
|
/* OPT_LANGUAGE */
|
||||||
{ N_("Language"), gen_cmd, str_rd, lang_wr, NULL, lang_set, N_("<language>") },
|
{ N_("Language"), gen_cmd, str_rd, lang_wr, NULL, lang_set, lang_eq, N_("<language>") },
|
||||||
/* OPT_COLOR */
|
/* OPT_COLOR */
|
||||||
{ N_("Color"), gen_cmd, str_rd, color_wr, NULL, color_set, N_("<color|#rrggbb>") },
|
{ N_("Color"), gen_cmd, str_rd, color_wr, NULL, color_set, color_eq, N_("<color|#rrggbb>") },
|
||||||
|
|
||||||
/* OPT_COMMAND */
|
/* OPT_COMMAND */
|
||||||
{ N_("Special"), exec_cmd, NULL, NULL, NULL, NULL, "" },
|
{ N_("Special"), exec_cmd, NULL, NULL, NULL, NULL, NULL, "" },
|
||||||
|
|
||||||
/* OPT_ALIAS */
|
/* OPT_ALIAS */
|
||||||
{ N_("Alias"), redir_cmd, redir_rd, redir_wr, NULL, redir_set, "" },
|
{ N_("Alias"), redir_cmd, redir_rd, redir_wr, NULL, redir_set, redir_eq, "" },
|
||||||
|
|
||||||
/* OPT_TREE */
|
/* OPT_TREE */
|
||||||
{ N_("Folder"), NULL, NULL, NULL, tree_dup, NULL, "" },
|
{ N_("Folder"), NULL, NULL, NULL, tree_dup, NULL, NULL, "" },
|
||||||
};
|
};
|
||||||
|
|
||||||
unsigned char *
|
unsigned char *
|
||||||
|
@ -11,6 +11,7 @@ struct option_type_info {
|
|||||||
void (*write)(struct option *, struct string *);
|
void (*write)(struct option *, struct string *);
|
||||||
void (*dup)(struct option *, struct option *);
|
void (*dup)(struct option *, struct option *);
|
||||||
int (*set)(struct option *, unsigned char *);
|
int (*set)(struct option *, unsigned char *);
|
||||||
|
int (*equals)(struct option *, const unsigned char *);
|
||||||
unsigned char *help_str;
|
unsigned char *help_str;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user