mirror of
https://github.com/rkd77/elinks.git
synced 2025-02-02 15:09:23 -05:00
Introduce option tree shadowing
Introduce get_option_shadow. This routine takes an option, the tree under which that option resides, and another tree. It returns a corresponding option with parallel ancestry in the second tree, creating that option and ancestry if it does not already exist. Add enum copy_option_flags. Add the CO_NO_LISTBOX_ITEM flag, which is used to suppress listbox creation for shadowed trees. Add the CO_SHALLOW flag, which is used to suppress the duplication of unwanted children for shadowed trees. Add a flags parameter to copy_option and tree_dup (and out of necessity, struct option_type_info and str_dup).
This commit is contained in:
parent
ea372bd0cd
commit
fd22173b29
@ -210,7 +210,7 @@ get_opt_rec(struct option *tree, const unsigned char *name_)
|
||||
* option. By having _template_ OPT_AUTOCREATE and _template_
|
||||
* inside, you can have even multi-level autocreating. */
|
||||
|
||||
option = copy_option(template);
|
||||
option = copy_option(template, 0);
|
||||
if (!option) {
|
||||
mem_free(aname);
|
||||
return NULL;
|
||||
@ -618,7 +618,7 @@ delete_option(struct option *option)
|
||||
}
|
||||
|
||||
struct option *
|
||||
copy_option(struct option *template)
|
||||
copy_option(struct option *template, int flags)
|
||||
{
|
||||
struct option *option = mem_calloc(1, sizeof(*option));
|
||||
|
||||
@ -633,7 +633,8 @@ copy_option(struct option *template)
|
||||
option->desc = template->desc;
|
||||
option->change_hook = template->change_hook;
|
||||
|
||||
option->box_item = init_option_listbox_item(option);
|
||||
if (!(flags & CO_NO_LISTBOX_ITEM))
|
||||
option->box_item = init_option_listbox_item(option);
|
||||
if (option->box_item) {
|
||||
if (template->box_item) {
|
||||
option->box_item->type = template->box_item->type;
|
||||
@ -642,7 +643,7 @@ copy_option(struct option *template)
|
||||
}
|
||||
|
||||
if (option_types[template->type].dup) {
|
||||
option_types[template->type].dup(option, template);
|
||||
option_types[template->type].dup(option, template, flags);
|
||||
} else {
|
||||
option->value = template->value;
|
||||
}
|
||||
@ -650,6 +651,48 @@ copy_option(struct option *template)
|
||||
return option;
|
||||
}
|
||||
|
||||
/* Return the shadow option in @shadow_tree of @option in @tree. If @option
|
||||
* isn't yet shadowed in @shadow_tree, shadow it (i.e. create a copy
|
||||
* in @shadow_tree) along with any ancestors that aren't shadowed. */
|
||||
struct option *
|
||||
get_option_shadow(struct option *option, struct option *tree,
|
||||
struct option *shadow_tree)
|
||||
{
|
||||
|
||||
struct option *shadow_option = NULL;
|
||||
|
||||
assert(option);
|
||||
assert(tree);
|
||||
assert(shadow_tree);
|
||||
|
||||
if (option == tree) {
|
||||
shadow_option = shadow_tree;
|
||||
} else if (option->root && option->name) {
|
||||
struct option *shadow_root;
|
||||
|
||||
shadow_root = get_option_shadow(option->root, tree,
|
||||
shadow_tree);
|
||||
if (!shadow_root) return NULL;
|
||||
|
||||
shadow_option = get_opt_rec_real(shadow_root, option->name);
|
||||
if (!shadow_option) {
|
||||
shadow_option = copy_option(option,
|
||||
CO_SHALLOW
|
||||
| CO_NO_LISTBOX_ITEM);
|
||||
if (shadow_option) {
|
||||
shadow_option->root = shadow_root;
|
||||
/* No need to sort, is there? It isn't shown
|
||||
* in the options manager. -- Miciah */
|
||||
add_to_list_end(*shadow_root->value.tree,
|
||||
shadow_option);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return shadow_option;
|
||||
}
|
||||
|
||||
LIST_OF(struct option) *
|
||||
init_options_tree(void)
|
||||
{
|
||||
|
@ -169,7 +169,17 @@ extern void smart_config_string(struct string *, int, int,
|
||||
void (*)(struct string *, struct option *,
|
||||
unsigned char *, int, int, int, int));
|
||||
|
||||
extern struct option *copy_option(struct option *);
|
||||
enum copy_option_flags {
|
||||
/* Do not create a listbox option for the new option. */
|
||||
CO_NO_LISTBOX_ITEM = (1 << 0),
|
||||
|
||||
/* Do not copy children. */
|
||||
CO_SHALLOW = (1 << 1),
|
||||
};
|
||||
|
||||
extern struct option *copy_option(struct option *, int);
|
||||
struct option *get_option_shadow(struct option *, struct option *,
|
||||
struct option *);
|
||||
extern void delete_option(struct option *);
|
||||
void mark_option_as_deleted(struct option *);
|
||||
|
||||
|
@ -295,7 +295,7 @@ str_wr(struct option *o, struct string *s)
|
||||
}
|
||||
|
||||
static void
|
||||
str_dup(struct option *opt, struct option *template)
|
||||
str_dup(struct option *opt, struct option *template, int flags)
|
||||
{
|
||||
unsigned char *new = mem_alloc(MAX_STR_LEN);
|
||||
|
||||
@ -366,7 +366,7 @@ color_wr(struct option *opt, struct string *str)
|
||||
}
|
||||
|
||||
static void
|
||||
tree_dup(struct option *opt, struct option *template)
|
||||
tree_dup(struct option *opt, struct option *template, int flags)
|
||||
{
|
||||
LIST_OF(struct option) *new = init_options_tree();
|
||||
LIST_OF(struct option) *tree = template->value.tree;
|
||||
@ -375,8 +375,10 @@ tree_dup(struct option *opt, struct option *template)
|
||||
if (!new) return;
|
||||
opt->value.tree = new;
|
||||
|
||||
if (flags & CO_SHALLOW) return;
|
||||
|
||||
foreachback (option, *tree) {
|
||||
struct option *new_opt = copy_option(option);
|
||||
struct option *new_opt = copy_option(option, flags);
|
||||
|
||||
if (!new_opt) continue;
|
||||
object_nolock(new_opt, "option");
|
||||
|
@ -9,7 +9,7 @@ struct option_type_info {
|
||||
unsigned char *(*cmdline)(struct option *, unsigned char ***, int *);
|
||||
unsigned char *(*read)(struct option *, unsigned char **, int *);
|
||||
void (*write)(struct option *, struct string *);
|
||||
void (*dup)(struct option *, struct option *);
|
||||
void (*dup)(struct option *, struct option *, int);
|
||||
int (*set)(struct option *, unsigned char *);
|
||||
unsigned char *help_str;
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user