@@ -1180,13 +1180,19 @@ struct expr *expr_simplify_unmet_dep(struct expr *e1, struct expr *e2)
}
static void
-expr_print_newline(struct expr *e,
- void (*fn)(void *, struct symbol *, const char *),
- void *data,
- int prevtoken)
+expr_print_revdep(struct expr *e,
+ void (*fn)(void *, struct symbol *, const char *),
+ void *data,
+ int prevtoken,
+ enum print_type type)
{
- fn(data, NULL, "\n - ");
- expr_print(e, fn, data, prevtoken);
+ if (type == PRINT_REVDEP_ALL ||
+ type == PRINT_REVDEP_YES && expr_calc_value(e) == yes ||
+ type == PRINT_REVDEP_MOD && expr_calc_value(e) == mod ||
+ type == PRINT_REVDEP_NO && expr_calc_value(e) == no) {
+ fn(data, NULL, "\n - ");
+ expr_print(e, fn, data, prevtoken);
+ }
}
static void
@@ -1211,7 +1217,10 @@ __expr_print(struct expr *e,
fn(data, e->left.sym, e->left.sym->name);
break;
case PRINT_REVDEP_ALL:
- expr_print_newline(e, fn, data, E_OR);
+ case PRINT_REVDEP_YES:
+ case PRINT_REVDEP_MOD:
+ case PRINT_REVDEP_NO:
+ expr_print_revdep(e, fn, data, E_OR, type);
break;
}
else
@@ -1269,7 +1278,10 @@ __expr_print(struct expr *e,
expr_print(e->right.expr, fn, data, E_AND);
break;
case PRINT_REVDEP_ALL:
- expr_print_newline(e, fn, data, E_OR);
+ case PRINT_REVDEP_YES:
+ case PRINT_REVDEP_MOD:
+ case PRINT_REVDEP_NO:
+ expr_print_revdep(e, fn, data, E_OR, type);
break;
}
break;
@@ -1349,10 +1361,43 @@ void expr_gstr_print(struct expr *e, struct gstr *gs)
expr_print(e, expr_print_gstr_helper, gs, E_NONE);
}
+/*
+ * Allow front ends to check if a specific reverse dependency expression
+ * has at least one top level "||" member which evaluates to "val". This,
+ * will allow front ends to, as example, avoid printing "Selected by [y]:"
+ * line when there are actually no top level "||" sub-expressions which
+ * evaluate to =y.
+ */
+bool expr_revdep_contains(struct expr *e, tristate val)
+{
+ bool ret = false;
+
+ if (!e)
+ return ret;
+
+ switch (e->type) {
+ case E_SYMBOL:
+ case E_AND:
+ if (expr_calc_value(e) == val)
+ ret = true;
+ break;
+ case E_OR:
+ if (expr_revdep_contains(e->left.expr, val))
+ ret = true;
+ else if (expr_revdep_contains(e->right.expr, val))
+ ret = true;
+ break;
+ default:
+ break;
+ }
+ return ret;
+}
+
/*
* Transform the top level "||" tokens into newlines and prepend each
* line with a minus. This makes expressions much easier to read.
- * Suitable for reverse dependency expressions.
+ * Suitable for reverse dependency expressions. In addition, allow
+ * selective printing of tokens/sub-expressions by their tristate value.
*/
void expr_gstr_print_revdep(struct expr *e, struct gstr *gs, enum print_type t)
{
@@ -37,6 +37,9 @@ enum expr_type {
enum print_type {
PRINT_NORMAL,
PRINT_REVDEP_ALL,
+ PRINT_REVDEP_YES,
+ PRINT_REVDEP_MOD,
+ PRINT_REVDEP_NO,
};
union expr_data {
@@ -316,6 +319,7 @@ void expr_fprint(struct expr *e, FILE *out);
struct gstr; /* forward */
void expr_gstr_print(struct expr *e, struct gstr *gs);
void expr_gstr_print_revdep(struct expr *e, struct gstr *gs, enum print_type t);
+bool expr_revdep_contains(struct expr *e, tristate val);
static inline int expr_is_yes(struct expr *e)
{
@@ -25,6 +25,7 @@ bool menu_has_help(struct menu *menu);
const char * menu_get_help(struct menu *menu);
struct gstr get_relations_str(struct symbol **sym_arr, struct list_head *head);
void menu_get_ext_help(struct menu *menu, struct gstr *help);
+void get_revdep_by_type(struct expr *e, char *s, struct gstr *r);
/* symbol.c */
extern struct symbol * symbol_hash[SYMBOL_HASHSIZE];
@@ -790,6 +790,31 @@ static void get_symbol_props_str(struct gstr *r, struct symbol *sym,
str_append(r, "\n");
}
+void get_revdep_by_type(struct expr *e, char *s, struct gstr *r)
+{
+ if (!e)
+ return;
+
+ if (expr_revdep_contains(e, yes)) {
+ str_append(r, s);
+ str_append(r, " [y]:");
+ expr_gstr_print_revdep(e, r, PRINT_REVDEP_YES);
+ str_append(r, "\n");
+ }
+ if (expr_revdep_contains(e, mod)) {
+ str_append(r, s);
+ str_append(r, " [m]:");
+ expr_gstr_print_revdep(e, r, PRINT_REVDEP_MOD);
+ str_append(r, "\n");
+ }
+ if (expr_revdep_contains(e, no)) {
+ str_append(r, s);
+ str_append(r, " [n]:");
+ expr_gstr_print_revdep(e, r, PRINT_REVDEP_NO);
+ str_append(r, "\n");
+ }
+}
+
/*
* head is optional and may be NULL
*/
@@ -826,18 +851,10 @@ static void get_symbol_str(struct gstr *r, struct symbol *sym,
}
get_symbol_props_str(r, sym, P_SELECT, _(" Selects: "));
- if (sym->rev_dep.expr) {
- str_append(r, _(" Selected by: "));
- expr_gstr_print_revdep(sym->rev_dep.expr, r, PRINT_REVDEP_ALL);
- str_append(r, "\n");
- }
+ get_revdep_by_type(sym->rev_dep.expr, " Selected by", r);
get_symbol_props_str(r, sym, P_IMPLY, _(" Implies: "));
- if (sym->implied.expr) {
- str_append(r, _(" Implied by: "));
- expr_gstr_print_revdep(sym->implied.expr, r, PRINT_REVDEP_ALL);
- str_append(r, "\n");
- }
+ get_revdep_by_type(sym->implied.expr, " Implied by", r);
str_append(r, "\n\n");
}