diff options
Diffstat (limited to 'package/config/menu.c')
| -rw-r--r-- | package/config/menu.c | 74 | 
1 files changed, 48 insertions, 26 deletions
diff --git a/package/config/menu.c b/package/config/menu.c index f9d0d91a3..07ff8d105 100644 --- a/package/config/menu.c +++ b/package/config/menu.c @@ -15,7 +15,7 @@ static struct menu **last_entry_ptr;  struct file *file_list;  struct file *current_file; -static void menu_warn(struct menu *menu, const char *fmt, ...) +void menu_warn(struct menu *menu, const char *fmt, ...)  {  	va_list ap;  	va_start(ap, fmt); @@ -172,6 +172,9 @@ void menu_add_option(int token, char *arg)  		else if (sym_defconfig_list != current_entry->sym)  			zconf_error("trying to redefine defconfig symbol");  		break; +	case T_OPT_ENV: +		prop_add_env(arg); +		break;  	}  } @@ -200,12 +203,9 @@ void sym_check_prop(struct symbol *sym)  				prop_warn(prop,  				    "config symbol '%s' uses select, but is "  				    "not boolean or tristate", sym->name); -			else if (sym2->type == S_UNKNOWN) -				prop_warn(prop, -				    "'select' used by config symbol '%s' " -				    "refers to undefined symbol '%s'", -				    sym->name, sym2->name); -			else if (sym2->type != S_BOOLEAN && sym2->type != S_TRISTATE) +			else if (sym2->type != S_UNKNOWN && +			         sym2->type != S_BOOLEAN && +			         sym2->type != S_TRISTATE)  				prop_warn(prop,  				    "'%s' has wrong type. 'select' only "  				    "accept arguments of boolean and " @@ -235,15 +235,21 @@ void menu_finalize(struct menu *parent)  	sym = parent->sym;  	if (parent->list) {  		if (sym && sym_is_choice(sym)) { -			/* find the first choice value and find out choice type */ +			if (sym->type == S_UNKNOWN) { +				/* find the first choice value to find out choice type */ +				current_entry = parent; +				for (menu = parent->list; menu; menu = menu->next) { +					if (menu->sym && menu->sym->type != S_UNKNOWN) { +						menu_set_type(menu->sym->type); +						break; +					} +				} +			} +			/* set the type of the remaining choice values */  			for (menu = parent->list; menu; menu = menu->next) { -				if (menu->sym) { -					current_entry = parent; -					menu_set_type(menu->sym->type); -					current_entry = menu; +				current_entry = menu; +				if (menu->sym && menu->sym->type == S_UNKNOWN)  					menu_set_type(sym->type); -					break; -				}  			}  			parentdep = expr_alloc_symbol(sym);  		} else if (parent->prompt) @@ -311,27 +317,43 @@ void menu_finalize(struct menu *parent)  		}  	}  	for (menu = parent->list; menu; menu = menu->next) { -		if (sym && sym_is_choice(sym) && menu->sym) { +		if (sym && sym_is_choice(sym) && +		    menu->sym && !sym_is_choice_value(menu->sym)) { +			current_entry = menu;  			menu->sym->flags |= SYMBOL_CHOICEVAL;  			if (!menu->prompt)  				menu_warn(menu, "choice value must have a prompt");  			for (prop = menu->sym->prop; prop; prop = prop->next) { -				if (prop->type == P_PROMPT && prop->menu != menu) { -					prop_warn(prop, "choice values " -					    "currently only support a " -					    "single prompt"); -				}  				if (prop->type == P_DEFAULT)  					prop_warn(prop, "defaults for choice " -					    "values not supported"); +						  "values not supported"); +				if (prop->menu == menu) +					continue; +				if (prop->type == P_PROMPT && +				    prop->menu->parent->sym != sym) +					prop_warn(prop, "choice value used outside its choice group"); +			} +			/* Non-tristate choice values of tristate choices must +			 * depend on the choice being set to Y. The choice +			 * values' dependencies were propagated to their +			 * properties above, so the change here must be re- +			 * propagated. +			 */ +			if (sym->type == S_TRISTATE && menu->sym->type != S_TRISTATE) { +				basedep = expr_alloc_comp(E_EQUAL, sym, &symbol_yes); +				menu->dep = expr_alloc_and(basedep, menu->dep); +				for (prop = menu->sym->prop; prop; prop = prop->next) { +					if (prop->menu != menu) +						continue; +					prop->visible.expr = expr_alloc_and(expr_copy(basedep), +									    prop->visible.expr); +				}  			} -			current_entry = menu; -			menu_set_type(sym->type);  			menu_add_symbol(P_CHOICE, sym, NULL);  			prop = sym_get_choice_prop(sym);  			for (ep = &prop->expr; *ep; ep = &(*ep)->left.expr)  				; -			*ep = expr_alloc_one(E_CHOICE, NULL); +			*ep = expr_alloc_one(E_LIST, NULL);  			(*ep)->right.sym = menu->sym;  		}  		if (menu->list && (!menu->prompt || !menu->prompt->text)) { @@ -394,9 +416,9 @@ bool menu_is_visible(struct menu *menu)  const char *menu_get_prompt(struct menu *menu)  {  	if (menu->prompt) -		return _(menu->prompt->text); +		return menu->prompt->text;  	else if (menu->sym) -		return _(menu->sym->name); +		return menu->sym->name;  	return NULL;  }  | 
