scripts/findconf provides menuconfig's search functionality as a standalone, non-interactive command, somewhat in the spirit of scripts/config. It is meant to be useful for tasks like getting a quick overview of symbol dependencies or determining which Kconfig file to edit for a given symbol, without having to fire up one of the interactive config programs. It accepts a single command-line flag, '-v', which causes it to also print the help text of each matching result. Signed-off-by: Zev Weiss <zev@xxxxxxxxxxxxxxxxx> --- This works a bit differently from [gmnq]conf in that it accepts (and requires) arguments, but I couldn't see an easy/obvious way of passing command-line args through the makefile infrastructure that invokes those, so the wrapper script passes things to it via environment variables instead. Suggestions welcome if there's a nicer way of achieving that. scripts/findconf | 22 ++++++++++++ scripts/kconfig/.gitignore | 1 + scripts/kconfig/Makefile | 7 +++- scripts/kconfig/findconf.c | 74 ++++++++++++++++++++++++++++++++++++++ scripts/kconfig/lkc.h | 1 + scripts/kconfig/menu.c | 2 +- 6 files changed, 105 insertions(+), 2 deletions(-) create mode 100755 scripts/findconf create mode 100644 scripts/kconfig/findconf.c diff --git a/scripts/findconf b/scripts/findconf new file mode 100755 index 000000000000..c59132548082 --- /dev/null +++ b/scripts/findconf @@ -0,0 +1,22 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +# +# Find Kconfig symbols matching one or more regexen. Pass '-v' to +# also show help text. + +if [ "$1" = "-v" ]; then + export FINDCONF_SHOW_HELP=1 + shift +fi + +if [ $# = 0 ] || [ "$1" = "-h" ] || [ "$1" = "--help" ]; then + echo >&$(($# ? 1 : 2)) "Usage: $(basename $0) [-v] REGEX [REGEX ...]" + exit $((!$#)) +fi + +n=0 +for q in "$@"; do + export FINDCONF_QUERY_$((n++))="$q" +done + +exec make findconfig diff --git a/scripts/kconfig/.gitignore b/scripts/kconfig/.gitignore index 500e7424b3ef..a3ea0600c731 100644 --- a/scripts/kconfig/.gitignore +++ b/scripts/kconfig/.gitignore @@ -1,5 +1,6 @@ # SPDX-License-Identifier: GPL-2.0-only /conf +/findconf /[gmnq]conf /[gmnq]conf-cfg /qconf-moc.cc diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile index b8ef0fb4bbef..99e48b2d8563 100644 --- a/scripts/kconfig/Makefile +++ b/scripts/kconfig/Makefile @@ -35,6 +35,7 @@ menuconfig-prog := mconf nconfig-prog := nconf gconfig-prog := gconf xconfig-prog := qconf +findconfig-prog := findconf define config_rule PHONY += $(1) @@ -45,7 +46,7 @@ PHONY += build_$(1) build_$(1): $(obj)/$($(1)-prog) endef -$(foreach c, config menuconfig nconfig gconfig xconfig, $(eval $(call config_rule,$(c)))) +$(foreach c, config menuconfig nconfig gconfig xconfig findconfig, $(eval $(call config_rule,$(c)))) PHONY += localmodconfig localyesconfig localyesconfig localmodconfig: $(obj)/conf @@ -155,6 +156,10 @@ HOSTCFLAGS_parser.tab.o := -I $(srctree)/$(src) hostprogs += conf conf-objs := conf.o $(common-objs) +# findconf: standalone non-interactive config-symbol search +hostprogs += findconf +findconf-objs := findconf.o $(common-objs) + # nconf: Used for the nconfig target based on ncurses hostprogs += nconf nconf-objs := nconf.o nconf.gui.o $(common-objs) diff --git a/scripts/kconfig/findconf.c b/scripts/kconfig/findconf.c new file mode 100644 index 000000000000..786408c97eab --- /dev/null +++ b/scripts/kconfig/findconf.c @@ -0,0 +1,74 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2022 Zev Weiss <zev@xxxxxxxxxxxxxxxxx> + * + * Kconfig symbol search a la carte. + */ +#include "lkc.h" + +static bool query(const char *q) +{ + unsigned int i; + const char *help; + struct gstr res; + struct symbol **sym_arr, *sym; + struct property *prop; + + sym_arr = sym_re_search(q); + + if (!sym_arr) { + printf("%s: no matches found.\n", q); + return false; + } + + for (i = 0; sym_arr[i]; i++) { + sym = sym_arr[i]; + res = str_new(); + get_symbol_str(&res, sym, NULL); + printf("%s", str_get(&res)); + str_free(&res); + + if (getenv("FINDCONF_SHOW_HELP")) { + for_all_properties(sym, prop, P_SYMBOL) { + if (prop->menu) { + help = menu_get_help(prop->menu); + if (help && *help) + printf("%s\n", help); + } + } + } + } + + free(sym_arr); + + return true; +} + +int main(int argc, char **argv) +{ + unsigned int i = 0; + char qvar[32]; + bool found = false; + + if (argc != 2) { + fprintf(stderr, "Usage: %s KCONFIG\n", argv[0]); + exit(1); + } + + conf_parse(argv[1]); + conf_read(NULL); + + for (;;) { + snprintf(qvar, sizeof(qvar), "FINDCONF_QUERY_%u", i++); + if (!getenv(qvar)) + break; + found = query(getenv(qvar)) || found; + } + + if (i == 1) { + fprintf(stderr, "FINDCONF_QUERY_0 not set\n"); + return 1; + } + + return !found; +} diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h index fa8c010aa683..b4730f580dee 100644 --- a/scripts/kconfig/lkc.h +++ b/scripts/kconfig/lkc.h @@ -102,6 +102,7 @@ struct menu *menu_get_root_menu(struct menu *menu); struct menu *menu_get_parent_menu(struct menu *menu); bool menu_has_help(struct menu *menu); const char *menu_get_help(struct menu *menu); +void get_symbol_str(struct gstr *r, struct symbol *sym, struct list_head *head); struct gstr get_relations_str(struct symbol **sym_arr, struct list_head *head); void menu_get_ext_help(struct menu *menu, struct gstr *help); diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c index 3d6f7cba8846..4b990c73e431 100644 --- a/scripts/kconfig/menu.c +++ b/scripts/kconfig/menu.c @@ -800,7 +800,7 @@ static void get_symbol_props_str(struct gstr *r, struct symbol *sym, /* * head is optional and may be NULL */ -static void get_symbol_str(struct gstr *r, struct symbol *sym, +void get_symbol_str(struct gstr *r, struct symbol *sym, struct list_head *head) { struct property *prop; -- 2.36.1