summaryrefslogtreecommitdiff
path: root/kconfig
diff options
context:
space:
mode:
authorChris Packham <judge.packham@gmail.com>2020-12-09 08:03:27 (GMT)
committerChris Packham <judge.packham@gmail.com>2021-02-02 07:06:32 (GMT)
commit689dc60f212db105243b60290480f29475578e0d (patch)
tree3e4a6332013209dd63809f4e719f1add8fe9b21a /kconfig
parent07ae8dd48dfb19a7b89bc4c208bc5778c79ce446 (diff)
kconfig: Sync with upstream v4.17
This commit introduces the following upstream changes: 17baab68d337 kconfig: extend output of 'listnewconfig' b23d1a241f4e kbuild: add %.lex.c and %.tab.[ch] to 'targets' automatically 9a8dfb394c04 kbuild: clean up *.lex.c and *.tab.[ch] patterns from top-level Makefile 598893002745 .gitignore: move *.lex.c *.tab.[ch] patterns to the top-level .gitignore 18492685e479 kconfig: use yylineno option instead of manual lineno increments 379a8eb8eb1a kconfig: detect recursive inclusion earlier 32a94b8b0c3e kconfig: remove duplicated file name and lineno of recursive inclusion 26561514cc9d kconfig: do not include both curses.h and ncurses.h for nconfig f8f69dc0b4e0 kconfig: make unmet dependency warnings readable f622f8279581 kconfig: warn unmet direct dependency of tristate symbols selected by y e2c75e7667c7 kconfig: tests: test if recursive inclusion is detected 29c434f367ea kconfig: tests: test if recursive dependencies are detected 3e4888c2e3d7 kconfig: tests: test randconfig for choice in choice beaaddb62540 kconfig: tests: test defconfig when two choices interact ee236610653e kconfig: tests: check visibility of tristate choice values in y choice 930c429a656f kconfig: tests: check unneeded "is not set" with unmet dependency b76960c0f6b2 kconfig: tests: test if new symbols in choice are asked 49ac3c0c3aa3 kconfig: tests: test automatic submenu creation 1903c5119059 kconfig: tests: add basic choice tests 022a4bf6b59d kconfig: tests: add framework for Kconfig unit testing 2a61625835c7 kconfig: remove redundant streamline_config.pl prerequisite 911a91c39cab kconfig: rename silentoldconfig to syncconfig 81d2bc227305 kconfig: invoke oldconfig instead of silentoldconfig from local*config 2aad9b896213 kconfig: hide irrelevant sub-menus for oldconfig 99f0b6578bab kconfig: remove redundant input_mode test for check_conf() loop 4bb3a5b085cd kconfig: remove unneeded input_mode test in conf() 59a80b5e892d kconfig: do not call check_conf() for olddefconfig f467c5640c29 kconfig: only write '# CONFIG_FOO is not set' for visible symbols d9119b5925a0 kconfig: Print reverse dependencies in groups 9a47ceec543b kconfig: clean-up reverse dependency help implementation 07a422bb213a kbuild: restore autoksyms.h touch to the top Makefile Signed-off-by: Chris Packham <judge.packham@gmail.com>
Diffstat (limited to 'kconfig')
-rw-r--r--kconfig/.gitignore3
-rw-r--r--kconfig/conf.c51
-rw-r--r--kconfig/expr.c86
-rw-r--r--kconfig/expr.h4
-rw-r--r--kconfig/lkc.h1
-rw-r--r--kconfig/menu.c12
-rw-r--r--kconfig/nconf.h4
-rw-r--r--kconfig/symbol.c40
-rw-r--r--kconfig/zconf.l41
9 files changed, 115 insertions, 127 deletions
diff --git a/kconfig/.gitignore b/kconfig/.gitignore
index 0c8d3a2..1908525 100644
--- a/kconfig/.gitignore
+++ b/kconfig/.gitignore
@@ -1,9 +1,6 @@
#
# Generated files
#
-*.lex.c
-*.tab.c
-*.tab.h
.deps
Makefile
diff --git a/kconfig/conf.c b/kconfig/conf.c
index 55e4f7c..5141be2 100644
--- a/kconfig/conf.c
+++ b/kconfig/conf.c
@@ -23,7 +23,7 @@ static void check_conf(struct menu *menu);
enum input_mode {
oldaskconfig,
- silentoldconfig,
+ syncconfig,
oldconfig,
allnoconfig,
allyesconfig,
@@ -100,7 +100,7 @@ static int conf_askvalue(struct symbol *sym, const char *def)
switch (input_mode) {
case oldconfig:
- case silentoldconfig:
+ case syncconfig:
if (sym_has_value(sym)) {
printf("%s\n", def);
return 0;
@@ -293,7 +293,7 @@ static int conf_choice(struct menu *menu)
printf("[1-%d?]: ", cnt);
switch (input_mode) {
case oldconfig:
- case silentoldconfig:
+ case syncconfig:
if (!is_new) {
cnt = def;
printf("%d\n", cnt);
@@ -358,10 +358,11 @@ static void conf(struct menu *menu)
switch (prop->type) {
case P_MENU:
- if ((input_mode == silentoldconfig ||
- input_mode == listnewconfig ||
- input_mode == olddefconfig) &&
- rootEntry != menu) {
+ /*
+ * Except in oldaskconfig mode, we show only menus that
+ * contain new symbols.
+ */
+ if (input_mode != oldaskconfig && rootEntry != menu) {
check_conf(menu);
return;
}
@@ -421,10 +422,20 @@ static void check_conf(struct menu *menu)
if (sym_is_changable(sym) ||
(sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)) {
if (input_mode == listnewconfig) {
- if (sym->name && !sym_is_choice_value(sym)) {
- printf("%s%s\n", CONFIG_, sym->name);
+ if (sym->name) {
+ const char *str;
+
+ if (sym->type == S_STRING) {
+ str = sym_get_string_value(sym);
+ str = sym_escape_string_value(str);
+ printf("%s%s=%s\n", CONFIG_, sym->name, str);
+ free((void *)str);
+ } else {
+ str = sym_get_string_value(sym);
+ printf("%s%s=%s\n", CONFIG_, sym->name, str);
+ }
}
- } else if (input_mode != olddefconfig) {
+ } else {
if (!conf_cnt++)
printf(_("*\n* Restart config...\n*\n"));
rootEntry = menu_get_parent_menu(menu);
@@ -440,7 +451,7 @@ static void check_conf(struct menu *menu)
static struct option long_opts[] = {
{"oldaskconfig", no_argument, NULL, oldaskconfig},
{"oldconfig", no_argument, NULL, oldconfig},
- {"silentoldconfig", no_argument, NULL, silentoldconfig},
+ {"syncconfig", no_argument, NULL, syncconfig},
{"defconfig", optional_argument, NULL, defconfig},
{"savedefconfig", required_argument, NULL, savedefconfig},
{"allnoconfig", no_argument, NULL, allnoconfig},
@@ -479,7 +490,7 @@ int main(int ac, char **av)
}
input_mode = (enum input_mode)opt;
switch (opt) {
- case silentoldconfig:
+ case syncconfig:
sync_kconfig = 1;
break;
case defconfig:
@@ -561,7 +572,7 @@ int main(int ac, char **av)
}
break;
case savedefconfig:
- case silentoldconfig:
+ case syncconfig:
case oldaskconfig:
case oldconfig:
case listnewconfig:
@@ -641,24 +652,24 @@ int main(int ac, char **av)
case oldaskconfig:
rootEntry = &rootmenu;
conf(&rootmenu);
- input_mode = silentoldconfig;
+ input_mode = oldconfig;
/* fall through */
case oldconfig:
case listnewconfig:
- case olddefconfig:
- case silentoldconfig:
+ case syncconfig:
/* Update until a loop caused no more changes */
do {
conf_cnt = 0;
check_conf(&rootmenu);
- } while (conf_cnt &&
- (input_mode != listnewconfig &&
- input_mode != olddefconfig));
+ } while (conf_cnt);
+ break;
+ case olddefconfig:
+ default:
break;
}
if (sync_kconfig) {
- /* silentoldconfig is used during the build so we shall update autoconf.
+ /* syncconfig is used during the build so we shall update autoconf.
* All other commands are only used to generate a config.
*/
if (conf_get_changed() && conf_write(NULL)) {
diff --git a/kconfig/expr.c b/kconfig/expr.c
index d453819..e1a39e9 100644
--- a/kconfig/expr.c
+++ b/kconfig/expr.c
@@ -1137,49 +1137,9 @@ static int expr_compare_type(enum expr_type t1, enum expr_type t2)
return 0;
}
-static inline struct expr *
-expr_get_leftmost_symbol(const struct expr *e)
-{
-
- if (e == NULL)
- return NULL;
-
- while (e->type != E_SYMBOL)
- e = e->left.expr;
-
- return expr_copy(e);
-}
-
-/*
- * Given expression `e1' and `e2', returns the leaf of the longest
- * sub-expression of `e1' not containing 'e2.
- */
-struct expr *expr_simplify_unmet_dep(struct expr *e1, struct expr *e2)
-{
- struct expr *ret;
-
- switch (e1->type) {
- case E_OR:
- return expr_alloc_and(
- expr_simplify_unmet_dep(e1->left.expr, e2),
- expr_simplify_unmet_dep(e1->right.expr, e2));
- case E_AND: {
- struct expr *e;
- e = expr_alloc_and(expr_copy(e1), expr_copy(e2));
- e = expr_eliminate_dups(e);
- ret = (!expr_eq(e, e1)) ? e1 : NULL;
- expr_free(e);
- break;
- }
- default:
- ret = e1;
- break;
- }
-
- 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)
+void expr_print(struct expr *e,
+ void (*fn)(void *, struct symbol *, const char *),
+ void *data, int prevtoken)
{
if (!e) {
fn(data, NULL, "y");
@@ -1234,14 +1194,9 @@ 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
- fn(data, NULL, " || ");
- __expr_print(e->right.expr, fn, data, E_OR, revdep);
+ expr_print(e->left.expr, fn, data, E_OR);
+ fn(data, NULL, " || ");
+ expr_print(e->right.expr, fn, data, E_OR);
break;
case E_AND:
expr_print(e->left.expr, fn, data, E_AND);
@@ -1274,11 +1229,6 @@ static void __expr_print(struct expr *e, void (*fn)(void *, struct symbol *, con
fn(data, NULL, ")");
}
-void expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char *), void *data, int prevtoken)
-{
- __expr_print(e, fn, data, prevtoken, false);
-}
-
static void expr_print_file_helper(void *data, struct symbol *sym, const char *str)
{
xfwrite(str, strlen(str), 1, data);
@@ -1329,7 +1279,27 @@ void expr_gstr_print(struct expr *e, struct gstr *gs)
* line with a minus. This makes expressions much easier to read.
* Suitable for reverse dependency expressions.
*/
-void expr_gstr_print_revdep(struct expr *e, struct gstr *gs)
+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(e, expr_print_gstr_helper, gs, E_NONE, true);
+ expr_print_revdep(e, expr_print_gstr_helper, gs, pr_type, &title);
}
diff --git a/kconfig/expr.h b/kconfig/expr.h
index c16e82e..94a383b 100644
--- a/kconfig/expr.h
+++ b/kconfig/expr.h
@@ -305,12 +305,12 @@ struct expr *expr_transform(struct expr *e);
int expr_contains_symbol(struct expr *dep, struct symbol *sym);
bool expr_depends_symbol(struct expr *dep, struct symbol *sym);
struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym);
-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);
+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/kconfig/lkc.h b/kconfig/lkc.h
index 2d5ec2d..f4394af 100644
--- a/kconfig/lkc.h
+++ b/kconfig/lkc.h
@@ -68,6 +68,7 @@ struct kconf_id {
enum symbol_type stype;
};
+extern int yylineno;
void zconfdump(FILE *out);
void zconf_starthelp(void);
FILE *zconf_fopen(const char *name);
diff --git a/kconfig/menu.c b/kconfig/menu.c
index d5a3322..53e7ad4 100644
--- a/kconfig/menu.c
+++ b/kconfig/menu.c
@@ -834,16 +834,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_revdep(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_revdep(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");
diff --git a/kconfig/nconf.h b/kconfig/nconf.h
index 0d52617..9f6f21d 100644
--- a/kconfig/nconf.h
+++ b/kconfig/nconf.h
@@ -15,7 +15,7 @@
#include <string.h>
#include <unistd.h>
#include <locale.h>
-#include <curses.h>
+#include <ncurses.h>
#include <menu.h>
#include <panel.h>
#include <form.h>
@@ -24,8 +24,6 @@
#include <time.h>
#include <sys/time.h>
-#include "ncurses.h"
-
#define max(a, b) ({\
typeof(a) _a = a;\
typeof(b) _b = b;\
diff --git a/kconfig/symbol.c b/kconfig/symbol.c
index 2220bc4..f0b2e3b 100644
--- a/kconfig/symbol.c
+++ b/kconfig/symbol.c
@@ -243,7 +243,7 @@ static void sym_calc_visibility(struct symbol *sym)
tri = yes;
if (sym->dir_dep.expr)
tri = expr_calc_value(sym->dir_dep.expr);
- if (tri == mod)
+ if (tri == mod && sym_get_type(sym) == S_BOOLEAN)
tri = yes;
if (sym->dir_dep.tri != tri) {
sym->dir_dep.tri = tri;
@@ -333,6 +333,27 @@ static struct symbol *sym_calc_choice(struct symbol *sym)
return def_sym;
}
+static void sym_warn_unmet_dep(struct symbol *sym)
+{
+ struct gstr gs = str_new();
+
+ str_printf(&gs,
+ "\nWARNING: unmet direct dependencies detected for %s\n",
+ sym->name);
+ str_printf(&gs,
+ " Depends on [%c]: ",
+ sym->dir_dep.tri == mod ? 'm' : 'n');
+ expr_gstr_print(sym->dir_dep.expr, &gs);
+ str_printf(&gs, "\n");
+
+ expr_gstr_print_revdep(sym->rev_dep.expr, &gs, yes,
+ " Selected by [y]:\n");
+ expr_gstr_print_revdep(sym->rev_dep.expr, &gs, mod,
+ " Selected by [m]:\n");
+
+ fputs(str_get(&gs), stderr);
+}
+
void sym_calc_value(struct symbol *sym)
{
struct symbol_value newval, oldval;
@@ -403,9 +424,10 @@ void sym_calc_value(struct symbol *sym)
if (!sym_is_choice(sym)) {
prop = sym_get_default_prop(sym);
if (prop) {
- sym->flags |= SYMBOL_WRITE;
newval.tri = EXPR_AND(expr_calc_value(prop->expr),
prop->visible.tri);
+ if (newval.tri != no)
+ sym->flags |= SYMBOL_WRITE;
}
if (sym->implied.tri != no) {
sym->flags |= SYMBOL_WRITE;
@@ -413,18 +435,8 @@ void sym_calc_value(struct symbol *sym)
}
}
calc_newval:
- if (sym->dir_dep.tri == no && sym->rev_dep.tri != no) {
- struct expr *e;
- e = expr_simplify_unmet_dep(sym->rev_dep.expr,
- sym->dir_dep.expr);
- fprintf(stderr, "warning: (");
- expr_fprint(e, stderr);
- fprintf(stderr, ") selects %s which has unmet direct dependencies (",
- sym->name);
- expr_fprint(sym->dir_dep.expr, stderr);
- fprintf(stderr, ")\n");
- expr_free(e);
- }
+ if (sym->dir_dep.tri < sym->rev_dep.tri)
+ sym_warn_unmet_dep(sym);
newval.tri = EXPR_OR(newval.tri, sym->rev_dep.tri);
}
if (newval.tri == mod &&
diff --git a/kconfig/zconf.l b/kconfig/zconf.l
index 88b650e..045093d 100644
--- a/kconfig/zconf.l
+++ b/kconfig/zconf.l
@@ -1,5 +1,5 @@
%option nostdinit noyywrap never-interactive full ecs
-%option 8bit nodefault perf-report perf-report
+%option 8bit nodefault yylineno
%option noinput
%x COMMAND HELP STRING PARAM
%{
@@ -83,7 +83,6 @@ n [A-Za-z0-9_-]
[ \t]*#.*\n |
[ \t]*\n {
- current_file->lineno++;
return T_EOL;
}
[ \t]*#.*
@@ -104,7 +103,7 @@ n [A-Za-z0-9_-]
const struct kconf_id *id = kconf_id_lookup(yytext, yyleng);
BEGIN(PARAM);
current_pos.file = current_file;
- current_pos.lineno = current_file->lineno;
+ current_pos.lineno = yylineno;
if (id && id->flags & TF_COMMAND) {
yylval.id = id;
return id->token;
@@ -116,7 +115,6 @@ n [A-Za-z0-9_-]
. warn_ignored_character(*yytext);
\n {
BEGIN(INITIAL);
- current_file->lineno++;
return T_EOL;
}
}
@@ -138,7 +136,7 @@ n [A-Za-z0-9_-]
new_string();
BEGIN(STRING);
}
- \n BEGIN(INITIAL); current_file->lineno++; return T_EOL;
+ \n BEGIN(INITIAL); return T_EOL;
({n}|[/.])+ {
const struct kconf_id *id = kconf_id_lookup(yytext, yyleng);
if (id && id->flags & TF_PARAM) {
@@ -150,7 +148,7 @@ n [A-Za-z0-9_-]
return T_WORD;
}
#.* /* comment */
- \\\n current_file->lineno++;
+ \\\n ;
[[:blank:]]+
. warn_ignored_character(*yytext);
<<EOF>> {
@@ -187,7 +185,6 @@ n [A-Za-z0-9_-]
fprintf(stderr,
"%s:%d:warning: multi-line strings not supported\n",
zconf_curname(), zconf_lineno());
- current_file->lineno++;
BEGIN(INITIAL);
return T_EOL;
}
@@ -220,12 +217,10 @@ n [A-Za-z0-9_-]
}
}
[ \t]*\n/[^ \t\n] {
- current_file->lineno++;
zconf_endhelp();
return T_HELPTEXT;
}
[ \t]*\n {
- current_file->lineno++;
append_string("\n", 1);
}
[^ \t\n].* {
@@ -304,7 +299,7 @@ void zconf_initscan(const char *name)
memset(current_buf, 0, sizeof(*current_buf));
current_file = file_lookup(name);
- current_file->lineno = 1;
+ yylineno = 1;
}
void zconf_nextfile(const char *name)
@@ -325,24 +320,26 @@ void zconf_nextfile(const char *name)
buf->parent = current_buf;
current_buf = buf;
- for (iter = current_file->parent; iter; iter = iter->parent ) {
- if (!strcmp(current_file->name,iter->name) ) {
+ current_file->lineno = yylineno;
+ file->parent = current_file;
+
+ for (iter = current_file; iter; iter = iter->parent) {
+ if (!strcmp(iter->name, file->name)) {
fprintf(stderr,
- "%s:%d: recursive inclusion detected. "
- "Inclusion path:\n current file : '%s'\n",
- zconf_curname(), zconf_lineno(),
- zconf_curname());
- iter = current_file;
+ "Recursive inclusion detected.\n"
+ "Inclusion path:\n"
+ " current file : %s\n", file->name);
+ iter = file;
do {
iter = iter->parent;
- fprintf(stderr, " included from: '%s:%d'\n",
+ fprintf(stderr, " included from: %s:%d\n",
iter->name, iter->lineno - 1);
- } while (strcmp(iter->name, current_file->name));
+ } while (strcmp(iter->name, file->name));
exit(1);
}
}
- file->lineno = 1;
- file->parent = current_file;
+
+ yylineno = 1;
current_file = file;
}
@@ -351,6 +348,8 @@ static void zconf_endfile(void)
struct buffer *parent;
current_file = current_file->parent;
+ if (current_file)
+ yylineno = current_file->lineno;
parent = current_buf->parent;
if (parent) {