diff options
author | Masahiro Yamada <yamada.masahiro@socionext.com> | 2018-08-15 01:59:45 -0400 |
---|---|---|
committer | Masahiro Yamada <yamada.masahiro@socionext.com> | 2018-08-22 10:21:39 -0400 |
commit | f498926c47aa7d4f1b6d08af2ba16f3cf8fcb151 (patch) | |
tree | 6309ef2c804936b4d4735b3c2070c9ee7754c968 | |
parent | 5e8c5299d31519e0327be1020f309fa62dc53036 (diff) |
kconfig: improve the recursive dependency report
This commit improves the messages of the recursive dependency.
Currently, sym->dir_dep.expr is not checked. Hence, any dependency
in property visibility is regarded as the dependency of the symbol.
[Test Code 1]
config A
bool "a"
depends on B
config B
bool "b"
depends on A
[Test Code 2]
config A
bool "a" if B
config B
bool "b"
depends on A
For both cases above, the same message is displayed:
symbol B depends on A
symbol A depends on B
This commit changes the message for the latter, like this:
symbol B depends on A
symbol A prompt is visible depending on B
Also, 'select' and 'imply' are distinguished.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Tested-by: Dirk Gouders <dirk@gouders.net>
-rw-r--r-- | scripts/kconfig/symbol.c | 48 | ||||
-rw-r--r-- | scripts/kconfig/tests/err_recursive_dep/expected_stderr | 6 |
2 files changed, 37 insertions, 17 deletions
diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c index 90e706096af8..703b9b899ee9 100644 --- a/scripts/kconfig/symbol.c +++ b/scripts/kconfig/symbol.c | |||
@@ -1011,7 +1011,7 @@ static struct dep_stack { | |||
1011 | struct dep_stack *prev, *next; | 1011 | struct dep_stack *prev, *next; |
1012 | struct symbol *sym; | 1012 | struct symbol *sym; |
1013 | struct property *prop; | 1013 | struct property *prop; |
1014 | struct expr *expr; | 1014 | struct expr **expr; |
1015 | } *check_top; | 1015 | } *check_top; |
1016 | 1016 | ||
1017 | static void dep_stack_insert(struct dep_stack *stack, struct symbol *sym) | 1017 | static void dep_stack_insert(struct dep_stack *stack, struct symbol *sym) |
@@ -1076,31 +1076,42 @@ static void sym_check_print_recursive(struct symbol *last_sym) | |||
1076 | fprintf(stderr, "%s:%d:error: recursive dependency detected!\n", | 1076 | fprintf(stderr, "%s:%d:error: recursive dependency detected!\n", |
1077 | prop->file->name, prop->lineno); | 1077 | prop->file->name, prop->lineno); |
1078 | 1078 | ||
1079 | if (stack->expr) { | 1079 | if (sym_is_choice(sym)) { |
1080 | fprintf(stderr, "%s:%d:\tsymbol %s %s value contains %s\n", | 1080 | fprintf(stderr, "%s:%d:\tchoice %s contains symbol %s\n", |
1081 | prop->file->name, prop->lineno, | 1081 | menu->file->name, menu->lineno, |
1082 | sym->name ? sym->name : "<choice>", | ||
1083 | next_sym->name ? next_sym->name : "<choice>"); | ||
1084 | } else if (sym_is_choice_value(sym)) { | ||
1085 | fprintf(stderr, "%s:%d:\tsymbol %s is part of choice %s\n", | ||
1086 | menu->file->name, menu->lineno, | ||
1082 | sym->name ? sym->name : "<choice>", | 1087 | sym->name ? sym->name : "<choice>", |
1083 | prop_get_type_name(prop->type), | ||
1084 | next_sym->name ? next_sym->name : "<choice>"); | 1088 | next_sym->name ? next_sym->name : "<choice>"); |
1085 | } else if (stack->prop) { | 1089 | } else if (stack->expr == &sym->dir_dep.expr) { |
1086 | fprintf(stderr, "%s:%d:\tsymbol %s depends on %s\n", | 1090 | fprintf(stderr, "%s:%d:\tsymbol %s depends on %s\n", |
1087 | prop->file->name, prop->lineno, | 1091 | prop->file->name, prop->lineno, |
1088 | sym->name ? sym->name : "<choice>", | 1092 | sym->name ? sym->name : "<choice>", |
1089 | next_sym->name ? next_sym->name : "<choice>"); | 1093 | next_sym->name ? next_sym->name : "<choice>"); |
1090 | } else if (sym_is_choice(sym)) { | 1094 | } else if (stack->expr == &sym->rev_dep.expr) { |
1091 | fprintf(stderr, "%s:%d:\tchoice %s contains symbol %s\n", | 1095 | fprintf(stderr, "%s:%d:\tsymbol %s is selected by %s\n", |
1092 | menu->file->name, menu->lineno, | 1096 | prop->file->name, prop->lineno, |
1093 | sym->name ? sym->name : "<choice>", | 1097 | sym->name ? sym->name : "<choice>", |
1094 | next_sym->name ? next_sym->name : "<choice>"); | 1098 | next_sym->name ? next_sym->name : "<choice>"); |
1095 | } else if (sym_is_choice_value(sym)) { | 1099 | } else if (stack->expr == &sym->implied.expr) { |
1096 | fprintf(stderr, "%s:%d:\tsymbol %s is part of choice %s\n", | 1100 | fprintf(stderr, "%s:%d:\tsymbol %s is implied by %s\n", |
1097 | menu->file->name, menu->lineno, | 1101 | prop->file->name, prop->lineno, |
1098 | sym->name ? sym->name : "<choice>", | 1102 | sym->name ? sym->name : "<choice>", |
1099 | next_sym->name ? next_sym->name : "<choice>"); | 1103 | next_sym->name ? next_sym->name : "<choice>"); |
1104 | } else if (stack->expr) { | ||
1105 | fprintf(stderr, "%s:%d:\tsymbol %s %s value contains %s\n", | ||
1106 | prop->file->name, prop->lineno, | ||
1107 | sym->name ? sym->name : "<choice>", | ||
1108 | prop_get_type_name(prop->type), | ||
1109 | next_sym->name ? next_sym->name : "<choice>"); | ||
1100 | } else { | 1110 | } else { |
1101 | fprintf(stderr, "%s:%d:\tsymbol %s is selected or implied by %s\n", | 1111 | fprintf(stderr, "%s:%d:\tsymbol %s %s is visible depending on %s\n", |
1102 | prop->file->name, prop->lineno, | 1112 | prop->file->name, prop->lineno, |
1103 | sym->name ? sym->name : "<choice>", | 1113 | sym->name ? sym->name : "<choice>", |
1114 | prop_get_type_name(prop->type), | ||
1104 | next_sym->name ? next_sym->name : "<choice>"); | 1115 | next_sym->name ? next_sym->name : "<choice>"); |
1105 | } | 1116 | } |
1106 | } | 1117 | } |
@@ -1157,14 +1168,23 @@ static struct symbol *sym_check_sym_deps(struct symbol *sym) | |||
1157 | 1168 | ||
1158 | dep_stack_insert(&stack, sym); | 1169 | dep_stack_insert(&stack, sym); |
1159 | 1170 | ||
1171 | stack.expr = &sym->dir_dep.expr; | ||
1172 | sym2 = sym_check_expr_deps(sym->dir_dep.expr); | ||
1173 | if (sym2) | ||
1174 | goto out; | ||
1175 | |||
1176 | stack.expr = &sym->rev_dep.expr; | ||
1160 | sym2 = sym_check_expr_deps(sym->rev_dep.expr); | 1177 | sym2 = sym_check_expr_deps(sym->rev_dep.expr); |
1161 | if (sym2) | 1178 | if (sym2) |
1162 | goto out; | 1179 | goto out; |
1163 | 1180 | ||
1181 | stack.expr = &sym->implied.expr; | ||
1164 | sym2 = sym_check_expr_deps(sym->implied.expr); | 1182 | sym2 = sym_check_expr_deps(sym->implied.expr); |
1165 | if (sym2) | 1183 | if (sym2) |
1166 | goto out; | 1184 | goto out; |
1167 | 1185 | ||
1186 | stack.expr = NULL; | ||
1187 | |||
1168 | for (prop = sym->prop; prop; prop = prop->next) { | 1188 | for (prop = sym->prop; prop; prop = prop->next) { |
1169 | if (prop->type == P_CHOICE || prop->type == P_SELECT || | 1189 | if (prop->type == P_CHOICE || prop->type == P_SELECT || |
1170 | prop->type == P_IMPLY) | 1190 | prop->type == P_IMPLY) |
@@ -1175,7 +1195,7 @@ static struct symbol *sym_check_sym_deps(struct symbol *sym) | |||
1175 | break; | 1195 | break; |
1176 | if (prop->type != P_DEFAULT || sym_is_choice(sym)) | 1196 | if (prop->type != P_DEFAULT || sym_is_choice(sym)) |
1177 | continue; | 1197 | continue; |
1178 | stack.expr = prop->expr; | 1198 | stack.expr = &prop->expr; |
1179 | sym2 = sym_check_expr_deps(prop->expr); | 1199 | sym2 = sym_check_expr_deps(prop->expr); |
1180 | if (sym2) | 1200 | if (sym2) |
1181 | break; | 1201 | break; |
diff --git a/scripts/kconfig/tests/err_recursive_dep/expected_stderr b/scripts/kconfig/tests/err_recursive_dep/expected_stderr index 2eb25288db8c..84679b104655 100644 --- a/scripts/kconfig/tests/err_recursive_dep/expected_stderr +++ b/scripts/kconfig/tests/err_recursive_dep/expected_stderr | |||
@@ -1,5 +1,5 @@ | |||
1 | Kconfig:11:error: recursive dependency detected! | 1 | Kconfig:11:error: recursive dependency detected! |
2 | Kconfig:11: symbol B is selected or implied by B | 2 | Kconfig:11: symbol B is selected by B |
3 | For a resolution refer to Documentation/kbuild/kconfig-language.txt | 3 | For a resolution refer to Documentation/kbuild/kconfig-language.txt |
4 | subsection "Kconfig recursive dependency limitations" | 4 | subsection "Kconfig recursive dependency limitations" |
5 | 5 | ||
@@ -15,14 +15,14 @@ For a resolution refer to Documentation/kbuild/kconfig-language.txt | |||
15 | subsection "Kconfig recursive dependency limitations" | 15 | subsection "Kconfig recursive dependency limitations" |
16 | 16 | ||
17 | Kconfig:32:error: recursive dependency detected! | 17 | Kconfig:32:error: recursive dependency detected! |
18 | Kconfig:32: symbol D2 is selected or implied by D1 | 18 | Kconfig:32: symbol D2 is selected by D1 |
19 | Kconfig:27: symbol D1 depends on D2 | 19 | Kconfig:27: symbol D1 depends on D2 |
20 | For a resolution refer to Documentation/kbuild/kconfig-language.txt | 20 | For a resolution refer to Documentation/kbuild/kconfig-language.txt |
21 | subsection "Kconfig recursive dependency limitations" | 21 | subsection "Kconfig recursive dependency limitations" |
22 | 22 | ||
23 | Kconfig:37:error: recursive dependency detected! | 23 | Kconfig:37:error: recursive dependency detected! |
24 | Kconfig:37: symbol E1 depends on E2 | 24 | Kconfig:37: symbol E1 depends on E2 |
25 | Kconfig:42: symbol E2 is selected or implied by E1 | 25 | Kconfig:42: symbol E2 is implied by E1 |
26 | For a resolution refer to Documentation/kbuild/kconfig-language.txt | 26 | For a resolution refer to Documentation/kbuild/kconfig-language.txt |
27 | subsection "Kconfig recursive dependency limitations" | 27 | subsection "Kconfig recursive dependency limitations" |
28 | 28 | ||