From 8d3e34dbf4eb11f492519464031cd610ad866b53 Mon Sep 17 00:00:00 2001
From: Ulf Magnusson <ulfalizer@gmail.com>
Date: Sun, 4 Feb 2018 18:52:40 +0100
Subject: [PATCH] Readable rev. dep WIP
---
scripts/kconfig/expr.c | 97 +++++++++++++++++++++++++++++++++++++++++---------
scripts/kconfig/expr.h | 1 +
scripts/kconfig/menu.c | 11 +++++-
3 files changed, 92 insertions(+), 17 deletions(-)
@@ -1179,7 +1179,33 @@ struct expr *expr_simplify_unmet_dep(struct expr *e1, struct expr *e2)
return expr_get_leftmost_symbol(ret);
}
-static void __expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char *), void *data, int prevtoken, bool revdep)
+enum expr_print_mode {
+ PRINT_NORMAL,
+
+ /* Print reverse dependencies with selects on separate lines */
+ PRINT_ALL_SELECTS,
+
+ /* Like PRINT_ALL_SELECTS, but skip 'n'-valued selects */
+ PRINT_ACTIVE_SELECTS
+};
+
+/* Helper for pretty-printing reverse dependencies with one select per line */
+static void print_select(struct expr *e,
+ void (*fn)(void *, struct symbol *, const char *),
+ void *data,
+ enum expr_print_mode mode)
+{
+ if (mode == PRINT_ALL_SELECTS || expr_calc_value(e) != no) {
+ fn(data, NULL, "\n - ");
+ expr_print(e, fn, data, E_OR);
+ }
+}
+
+static void __expr_print(struct expr *e,
+ void (*fn)(void *, struct symbol *, const char *),
+ void *data,
+ int prevtoken,
+ enum expr_print_mode mode)
{
if (!e) {
fn(data, NULL, "y");
@@ -1190,10 +1216,18 @@ static void __expr_print(struct expr *e, void (*fn)(void *, struct symbol *, con
fn(data, NULL, "(");
switch (e->type) {
case E_SYMBOL:
- if (e->left.sym->name)
- fn(data, e->left.sym, e->left.sym->name);
- else
+ if (e->left.sym->name) {
+ if (mode == PRINT_NORMAL)
+ fn(data, e->left.sym, e->left.sym->name);
+ else
+ /*
+ * PRINT_*_SELECTS, with a final select that
+ * has no condition
+ */
+ print_select(e, fn, data, mode);
+ } else {
fn(data, NULL, "<choice>");
+ }
break;
case E_NOT:
fn(data, NULL, "!");
@@ -1234,19 +1268,42 @@ static void __expr_print(struct expr *e, void (*fn)(void *, struct symbol *, con
fn(data, e->right.sym, e->right.sym->name);
break;
case E_OR:
- if (revdep && e->left.expr->type != E_OR)
- fn(data, NULL, "\n - ");
- __expr_print(e->left.expr, fn, data, E_OR, revdep);
- if (revdep)
- fn(data, NULL, "\n - ");
- else
+ if (mode == PRINT_NORMAL) {
+ expr_print(e->left.expr, fn, data, E_OR);
fn(data, NULL, " || ");
- __expr_print(e->right.expr, fn, data, E_OR, revdep);
+ expr_print(e->right.expr, fn, data, E_OR);
+ } else {
+ /*
+ * PRINT_*_SELECTS
+ *
+ * Support both (OR, <select 1>, (OR, <select 2>)) and
+ * (OR, (OR, <select 1>), <select 2>) format for
+ * selects. I think you always get the second one in
+ * practice as of writing.
+ */
+ if (e->right.expr->type != E_OR) {
+ print_select(e->right.expr, fn, data, mode);
+ /* Move on to next select */
+ __expr_print(e->left.expr, fn, data, E_OR, mode);
+ } else {
+ print_select(e->left.expr, fn, data, mode);
+ /* Move on to next select */
+ __expr_print(e->right.expr, fn, data, E_OR, mode);
+ }
+ }
break;
case E_AND:
- expr_print(e->left.expr, fn, data, E_AND);
- fn(data, NULL, " && ");
- expr_print(e->right.expr, fn, data, E_AND);
+ if (mode == PRINT_NORMAL) {
+ expr_print(e->left.expr, fn, data, E_AND);
+ fn(data, NULL, " && ");
+ expr_print(e->right.expr, fn, data, E_AND);
+ } else {
+ /*
+ * PRINT_*_SELECTS, with a final select that has a
+ * condition
+ */
+ print_select(e, fn, data, mode);
+ }
break;
case E_LIST:
fn(data, e->right.sym, e->right.sym->name);
@@ -1276,7 +1333,7 @@ static void __expr_print(struct expr *e, void (*fn)(void *, struct symbol *, con
void expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char *), void *data, int prevtoken)
{
- __expr_print(e, fn, data, prevtoken, false);
+ __expr_print(e, fn, data, prevtoken, PRINT_NORMAL);
}
static void expr_print_file_helper(void *data, struct symbol *sym, const char *str)
@@ -1331,5 +1388,13 @@ void expr_gstr_print(struct expr *e, struct gstr *gs)
*/
void expr_gstr_print_revdep(struct expr *e, struct gstr *gs)
{
- __expr_print(e, expr_print_gstr_helper, gs, E_NONE, true);
+ __expr_print(e, expr_print_gstr_helper, gs, E_NONE, PRINT_ALL_SELECTS);
+}
+
+/*
+ * Like expr_gstr_print_revdep(), but do not print 'n'-valued selects
+ */
+void expr_gstr_print_active_revdep(struct expr *e, struct gstr *gs)
+{
+ __expr_print(e, expr_print_gstr_helper, gs, E_NONE, PRINT_ACTIVE_SELECTS);
}
@@ -311,6 +311,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);
+void expr_gstr_print_active_revdep(struct expr *e, struct gstr *gs);
static inline int expr_is_yes(struct expr *e)
{
@@ -827,7 +827,16 @@ 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: "));
+ str_append(r, _(" Currently selected by:"));
+ if (expr_calc_value(sym->rev_dep.expr) == no) {
+ str_append(r, "\n");
+ str_append(r, _(" No symbols"));
+ } else {
+ expr_gstr_print_active_revdep(sym->rev_dep.expr, r);
+ }
+ str_append(r, "\n");
+
+ str_append(r, _(" All selecting symbols:"));
expr_gstr_print_revdep(sym->rev_dep.expr, r);
str_append(r, "\n");
}
--
2.14.1