1
0
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:
Miciah Dashiel Butler Masters 2007-08-28 17:11:52 +00:00 committed by Miciah Dashiel Butler Masters
parent ea372bd0cd
commit fd22173b29
4 changed files with 64 additions and 9 deletions

View File

@ -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)
{

View File

@ -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 *);

View File

@ -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");

View File

@ -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;
};