[U-Boot] [PATCH] kconfig: Print reverse dependencies in groups

Eugeniu Rosca erosca at de.adit-jv.com
Tue May 8 17:59:11 UTC 2018


Not sure if partial/limited sync with Linux Kconfig is practiced, but
if yes, then pick below three Linux commits, which are focused around
improving the readability of reverse dependencies in menuconfig UI.

[1] commit 1ccb27143360bd2390a9a970e50709f858b53761
    Author: Petr Vorel <petr.vorel at gmail.com>
    kconfig: make "Selected by:" and "Implied by:" readable

[2] commit 9a47ceec543bfb703fbe2f8d584850b582caf1a6
    Masahiro Yamada <yamada.masahiro at socionext.com>
    kconfig: clean-up reverse dependency help implementation

[3] commit d9119b5925a03b9a3191fa3e93b4091651d8ad25
    Author: Eugeniu Rosca <erosca at de.adit-jv.com>
    kconfig: Print reverse dependencies in groups

Here is an example of re-formatted information about the reverse
dependencies of CONFIG_DM (sandbox_defconfig):

* W/o the imported commits:

Selected by: NIOS2 [=n] && <choice> || SANDBOX [=y] && <choice> || X86
[=n] && <choice> || ARCH_MVEBU [=n] && <choice> || TARGET_STV0991 [=n]
&& <choice> || ARCH_BCM283X [=n] && <choice> || ARCH_EXYNOS [=n] &&
<choice> || ARCH_S5PC1XX [=n] && ...

* With the imported commits:

  Selected by [y]:
  - SANDBOX [=y] && <choice>
  - LOG [=y]
  Selected by [n]:
  - NIOS2 [=n] && <choice>
  - X86 [=n] && <choice>
  - ARCH_MVEBU [=n] && <choice>
  - TARGET_STV0991 [=n] && <choice>
  - ARCH_BCM283X [=n] && <choice>
  - ARCH_EXYNOS [=n] && <choice>
  - ARCH_S5PC1XX [=n] && <choice>
  - ARCH_INTEGRATOR [=n] && <choice>
  - ARCH_MX8M [=n] && <choice>
  - ARCH_QEMU [=n] && <choice>
  - ARCH_RMOBILE [=n] && <choice>
  - ARCH_SNAPDRAGON [=n] && <choice>
  - ARCH_SOCFPGA [=n] && <choice>
  - ARCH_SUNXI [=n] && <choice>
  - ARCH_ZYNQ [=n] && <choice>
  - ARCH_ZYNQMP [=n] && <choice>
  - TARGET_HIKEY [=n] && <choice>
  ...

Signed-off-by: Eugeniu Rosca <erosca at de.adit-jv.com>
---
 scripts/kconfig/expr.c | 34 +++++++++++++++++++++++++++++++++-
 scripts/kconfig/expr.h |  2 ++
 scripts/kconfig/menu.c | 12 ++++++------
 3 files changed, 41 insertions(+), 7 deletions(-)

diff --git a/scripts/kconfig/expr.c b/scripts/kconfig/expr.c
index cbf4996dd9c1..40887d17f1e2 100644
--- a/scripts/kconfig/expr.c
+++ b/scripts/kconfig/expr.c
@@ -1070,7 +1070,9 @@ struct expr *expr_simplify_unmet_dep(struct expr *e1, struct expr *e2)
 	return expr_get_leftmost_symbol(ret);
 }
 
-void expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char *), void *data, int prevtoken)
+void expr_print(struct expr *e,
+		void (*fn)(void *, struct symbol *, const char *),
+		void *data, int prevtoken)
 {
 	if (!e) {
 		fn(data, NULL, "y");
@@ -1204,3 +1206,33 @@ void expr_gstr_print(struct expr *e, struct gstr *gs)
 {
 	expr_print(e, expr_print_gstr_helper, gs, E_NONE);
 }
+
+/*
+ * 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.
+ */
+static void expr_print_revdep(struct expr *e,
+			      void (*fn)(void *, struct symbol *, const char *),
+			      void *data, tristate pr_type, const char **title)
+{
+	if (e->type == E_OR) {
+		expr_print_revdep(e->left.expr, fn, data, pr_type, title);
+		expr_print_revdep(e->right.expr, fn, data, pr_type, title);
+	} else if (expr_calc_value(e) == pr_type) {
+		if (*title) {
+			fn(data, NULL, *title);
+			*title = NULL;
+		}
+
+		fn(data, NULL, "  - ");
+		expr_print(e, fn, data, E_NONE);
+		fn(data, NULL, "\n");
+	}
+}
+
+void expr_gstr_print_revdep(struct expr *e, struct gstr *gs,
+			    tristate pr_type, const char *title)
+{
+	expr_print_revdep(e, expr_print_gstr_helper, gs, pr_type, &title);
+}
diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h
index a73f762c48d6..3a3d334ed554 100644
--- a/scripts/kconfig/expr.h
+++ b/scripts/kconfig/expr.h
@@ -222,6 +222,8 @@ struct expr *expr_simplify_unmet_dep(struct expr *e1, struct expr *e2);
 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,
+			    tristate pr_type, const char *title);
 
 static inline int expr_is_yes(struct expr *e)
 {
diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c
index e9357931b47d..392c1a0a3963 100644
--- a/scripts/kconfig/menu.c
+++ b/scripts/kconfig/menu.c
@@ -675,16 +675,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: "));
-		expr_gstr_print(sym->rev_dep.expr, r);
-		str_append(r, "\n");
+		expr_gstr_print_revdep(sym->rev_dep.expr, r, yes, "  Selected by [y]:\n");
+		expr_gstr_print_revdep(sym->rev_dep.expr, r, mod, "  Selected by [m]:\n");
+		expr_gstr_print_revdep(sym->rev_dep.expr, r, no, "  Selected by [n]:\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");
+		expr_gstr_print_revdep(sym->implied.expr, r, yes, "  Implied by [y]:\n");
+		expr_gstr_print_revdep(sym->implied.expr, r, mod, "  Implied by [m]:\n");
+		expr_gstr_print_revdep(sym->implied.expr, r, no, "  Implied by [n]:\n");
 	}
 
 	str_append(r, "\n\n");
-- 
2.17.0



More information about the U-Boot mailing list