|
@@ -233,6 +233,8 @@ static void sym_check_prop(struct symbol *sym)
|
|
|
{
|
|
|
struct property *prop;
|
|
|
struct symbol *sym2;
|
|
|
+ char *use;
|
|
|
+
|
|
|
for (prop = sym->prop; prop; prop = prop->next) {
|
|
|
switch (prop->type) {
|
|
|
case P_DEFAULT:
|
|
@@ -252,18 +254,20 @@ static void sym_check_prop(struct symbol *sym)
|
|
|
}
|
|
|
break;
|
|
|
case P_SELECT:
|
|
|
+ case P_IMPLY:
|
|
|
+ use = prop->type == P_SELECT ? "select" : "imply";
|
|
|
sym2 = prop_get_symbol(prop);
|
|
|
if (sym->type != S_BOOLEAN && sym->type != S_TRISTATE)
|
|
|
prop_warn(prop,
|
|
|
- "config symbol '%s' uses select, but is "
|
|
|
- "not boolean or tristate", sym->name);
|
|
|
+ "config symbol '%s' uses %s, but is "
|
|
|
+ "not boolean or tristate", sym->name, use);
|
|
|
else if (sym2->type != S_UNKNOWN &&
|
|
|
sym2->type != S_BOOLEAN &&
|
|
|
sym2->type != S_TRISTATE)
|
|
|
prop_warn(prop,
|
|
|
- "'%s' has wrong type. 'select' only "
|
|
|
+ "'%s' has wrong type. '%s' only "
|
|
|
"accept arguments of boolean and "
|
|
|
- "tristate type", sym2->name);
|
|
|
+ "tristate type", sym2->name, use);
|
|
|
break;
|
|
|
case P_RANGE:
|
|
|
if (sym->type != S_INT && sym->type != S_HEX)
|
|
@@ -333,6 +337,10 @@ void menu_finalize(struct menu *parent)
|
|
|
struct symbol *es = prop_get_symbol(prop);
|
|
|
es->rev_dep.expr = expr_alloc_or(es->rev_dep.expr,
|
|
|
expr_alloc_and(expr_alloc_symbol(menu->sym), expr_copy(dep)));
|
|
|
+ } else if (prop->type == P_IMPLY) {
|
|
|
+ struct symbol *es = prop_get_symbol(prop);
|
|
|
+ es->implied.expr = expr_alloc_or(es->implied.expr,
|
|
|
+ expr_alloc_and(expr_alloc_symbol(menu->sym), expr_copy(dep)));
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -612,13 +620,30 @@ static struct property *get_symbol_prop(struct symbol *sym)
|
|
|
return prop;
|
|
|
}
|
|
|
|
|
|
+static void get_symbol_props_str(struct gstr *r, struct symbol *sym,
|
|
|
+ enum prop_type tok, const char *prefix)
|
|
|
+{
|
|
|
+ bool hit = false;
|
|
|
+ struct property *prop;
|
|
|
+
|
|
|
+ for_all_properties(sym, prop, tok) {
|
|
|
+ if (!hit) {
|
|
|
+ str_append(r, prefix);
|
|
|
+ hit = true;
|
|
|
+ } else
|
|
|
+ str_printf(r, " && ");
|
|
|
+ expr_gstr_print(prop->expr, r);
|
|
|
+ }
|
|
|
+ if (hit)
|
|
|
+ str_append(r, "\n");
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* head is optional and may be NULL
|
|
|
*/
|
|
|
static void get_symbol_str(struct gstr *r, struct symbol *sym,
|
|
|
struct list_head *head)
|
|
|
{
|
|
|
- bool hit;
|
|
|
struct property *prop;
|
|
|
|
|
|
if (sym && sym->name) {
|
|
@@ -648,22 +673,20 @@ static void get_symbol_str(struct gstr *r, struct symbol *sym,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- hit = false;
|
|
|
- for_all_properties(sym, prop, P_SELECT) {
|
|
|
- if (!hit) {
|
|
|
- str_append(r, " Selects: ");
|
|
|
- hit = true;
|
|
|
- } else
|
|
|
- str_printf(r, " && ");
|
|
|
- expr_gstr_print(prop->expr, r);
|
|
|
- }
|
|
|
- if (hit)
|
|
|
- str_append(r, "\n");
|
|
|
+ get_symbol_props_str(r, sym, P_SELECT, _(" Selects: "));
|
|
|
if (sym->rev_dep.expr) {
|
|
|
str_append(r, _(" Selected by: "));
|
|
|
expr_gstr_print(sym->rev_dep.expr, r);
|
|
|
str_append(r, "\n");
|
|
|
}
|
|
|
+
|
|
|
+ get_symbol_props_str(r, sym, P_IMPLY, _(" Implies: "));
|
|
|
+ if (sym->implied.expr) {
|
|
|
+ str_append(r, _(" Implied by: "));
|
|
|
+ expr_gstr_print(sym->implied.expr, r);
|
|
|
+ str_append(r, "\n");
|
|
|
+ }
|
|
|
+
|
|
|
str_append(r, "\n\n");
|
|
|
}
|
|
|
|