aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/kconfig/symbol.c
diff options
context:
space:
mode:
authorRoman Zippel <zippel@linux-m68k.org>2010-07-31 17:35:30 -0400
committerMichal Marek <mmarek@suse.cz>2010-08-03 07:49:31 -0400
commitd595cea62403db4e65b98a8bb96ff2b5205c7b82 (patch)
tree8adee034859b15daf560ab0b72ba5816e6088885 /scripts/kconfig/symbol.c
parent59e89e3ddf8523be39a8e0a66bacbbdd6a72d069 (diff)
kconfig: print more info when we see a recursive dependency
Consider following kconfig file: config TEST1 bool "test 1" depends on TEST2 config TEST2 bool "test 2" depends on TEST1 Previously kconfig would report: foo:6:error: found recursive dependency: TEST2 -> TEST1 -> TEST2 With the following patch kconfig reports: foo:5:error: recursive dependency detected! foo:5: symbol TEST2 depends on TEST1 foo:1: symbol TEST1 depends on TEST2 Note that we now report where the offending symbols are defined. This can be a great help for complex situations involving several files. Patch is originally from Roman Zippel with a few adjustments by Sam. Signed-off-by: Sam Ravnborg <sam@ravnborg.org> Cc: Roman Zippel <zippel@linux-m68k.org> Signed-off-by: Michal Marek <mmarek@suse.cz>
Diffstat (limited to 'scripts/kconfig/symbol.c')
-rw-r--r--scripts/kconfig/symbol.c142
1 files changed, 127 insertions, 15 deletions
diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c
index 9f180ab7698d..bc1e1584e2da 100644
--- a/scripts/kconfig/symbol.c
+++ b/scripts/kconfig/symbol.c
@@ -783,6 +783,110 @@ struct symbol **sym_re_search(const char *pattern)
783 return sym_arr; 783 return sym_arr;
784} 784}
785 785
786/*
787 * When we check for recursive dependencies we use a stack to save
788 * current state so we can print out relevant info to user.
789 * The entries are located on the call stack so no need to free memory.
790 * Note inser() remove() must always match to properly clear the stack.
791 */
792static struct dep_stack {
793 struct dep_stack *prev, *next;
794 struct symbol *sym;
795 struct property *prop;
796 struct expr *expr;
797} *check_top;
798
799static void dep_stack_insert(struct dep_stack *stack, struct symbol *sym)
800{
801 memset(stack, 0, sizeof(*stack));
802 if (check_top)
803 check_top->next = stack;
804 stack->prev = check_top;
805 stack->sym = sym;
806 check_top = stack;
807}
808
809static void dep_stack_remove(void)
810{
811 check_top = check_top->prev;
812 if (check_top)
813 check_top->next = NULL;
814}
815
816/*
817 * Called when we have detected a recursive dependency.
818 * check_top point to the top of the stact so we use
819 * the ->prev pointer to locate the bottom of the stack.
820 */
821static void sym_check_print_recursive(struct symbol *last_sym)
822{
823 struct dep_stack *stack;
824 struct symbol *sym, *next_sym;
825 struct menu *menu = NULL;
826 struct property *prop;
827 struct dep_stack cv_stack;
828
829 if (sym_is_choice_value(last_sym)) {
830 dep_stack_insert(&cv_stack, last_sym);
831 last_sym = prop_get_symbol(sym_get_choice_prop(last_sym));
832 }
833
834 for (stack = check_top; stack != NULL; stack = stack->prev)
835 if (stack->sym == last_sym)
836 break;
837 if (!stack) {
838 fprintf(stderr, "unexpected recursive dependency error\n");
839 return;
840 }
841
842 for (; stack; stack = stack->next) {
843 sym = stack->sym;
844 next_sym = stack->next ? stack->next->sym : last_sym;
845 prop = stack->prop;
846
847 /* for choice values find the menu entry (used below) */
848 if (sym_is_choice(sym) || sym_is_choice_value(sym)) {
849 for (prop = sym->prop; prop; prop = prop->next) {
850 menu = prop->menu;
851 if (prop->menu)
852 break;
853 }
854 }
855 if (stack->sym == last_sym)
856 fprintf(stderr, "%s:%d:error: recursive dependency detected!\n",
857 prop->file->name, prop->lineno);
858 if (stack->expr) {
859 fprintf(stderr, "%s:%d:\tsymbol %s %s value contains %s\n",
860 prop->file->name, prop->lineno,
861 sym->name ? sym->name : "<choice>",
862 prop_get_type_name(prop->type),
863 next_sym->name ? next_sym->name : "<choice>");
864 } else if (stack->prop) {
865 fprintf(stderr, "%s:%d:\tsymbol %s depends on %s\n",
866 prop->file->name, prop->lineno,
867 sym->name ? sym->name : "<choice>",
868 next_sym->name ? next_sym->name : "<choice>");
869 } else if (sym_is_choice(sym)) {
870 fprintf(stderr, "%s:%d:\tchoice %s contains symbol %s\n",
871 menu->file->name, menu->lineno,
872 sym->name ? sym->name : "<choice>",
873 next_sym->name ? next_sym->name : "<choice>");
874 } else if (sym_is_choice_value(sym)) {
875 fprintf(stderr, "%s:%d:\tsymbol %s is part of choice %s\n",
876 menu->file->name, menu->lineno,
877 sym->name ? sym->name : "<choice>",
878 next_sym->name ? next_sym->name : "<choice>");
879 } else {
880 fprintf(stderr, "%s:%d:\tsymbol %s is selected by %s\n",
881 prop->file->name, prop->lineno,
882 sym->name ? sym->name : "<choice>",
883 next_sym->name ? next_sym->name : "<choice>");
884 }
885 }
886
887 if (check_top == &cv_stack)
888 dep_stack_remove();
889}
786 890
787static struct symbol *sym_check_expr_deps(struct expr *e) 891static struct symbol *sym_check_expr_deps(struct expr *e)
788{ 892{
@@ -819,24 +923,33 @@ static struct symbol *sym_check_sym_deps(struct symbol *sym)
819{ 923{
820 struct symbol *sym2; 924 struct symbol *sym2;
821 struct property *prop; 925 struct property *prop;
926 struct dep_stack stack;
927
928 dep_stack_insert(&stack, sym);
822 929
823 sym2 = sym_check_expr_deps(sym->rev_dep.expr); 930 sym2 = sym_check_expr_deps(sym->rev_dep.expr);
824 if (sym2) 931 if (sym2)
825 return sym2; 932 goto out;
826 933
827 for (prop = sym->prop; prop; prop = prop->next) { 934 for (prop = sym->prop; prop; prop = prop->next) {
828 if (prop->type == P_CHOICE || prop->type == P_SELECT) 935 if (prop->type == P_CHOICE || prop->type == P_SELECT)
829 continue; 936 continue;
937 stack.prop = prop;
830 sym2 = sym_check_expr_deps(prop->visible.expr); 938 sym2 = sym_check_expr_deps(prop->visible.expr);
831 if (sym2) 939 if (sym2)
832 break; 940 break;
833 if (prop->type != P_DEFAULT || sym_is_choice(sym)) 941 if (prop->type != P_DEFAULT || sym_is_choice(sym))
834 continue; 942 continue;
943 stack.expr = prop->expr;
835 sym2 = sym_check_expr_deps(prop->expr); 944 sym2 = sym_check_expr_deps(prop->expr);
836 if (sym2) 945 if (sym2)
837 break; 946 break;
947 stack.expr = NULL;
838 } 948 }
839 949
950out:
951 dep_stack_remove();
952
840 return sym2; 953 return sym2;
841} 954}
842 955
@@ -845,6 +958,9 @@ static struct symbol *sym_check_choice_deps(struct symbol *choice)
845 struct symbol *sym, *sym2; 958 struct symbol *sym, *sym2;
846 struct property *prop; 959 struct property *prop;
847 struct expr *e; 960 struct expr *e;
961 struct dep_stack stack;
962
963 dep_stack_insert(&stack, choice);
848 964
849 prop = sym_get_choice_prop(choice); 965 prop = sym_get_choice_prop(choice);
850 expr_list_for_each_sym(prop->expr, e, sym) 966 expr_list_for_each_sym(prop->expr, e, sym)
@@ -858,10 +974,8 @@ static struct symbol *sym_check_choice_deps(struct symbol *choice)
858 974
859 expr_list_for_each_sym(prop->expr, e, sym) { 975 expr_list_for_each_sym(prop->expr, e, sym) {
860 sym2 = sym_check_sym_deps(sym); 976 sym2 = sym_check_sym_deps(sym);
861 if (sym2) { 977 if (sym2)
862 fprintf(stderr, " -> %s", sym->name);
863 break; 978 break;
864 }
865 } 979 }
866out: 980out:
867 expr_list_for_each_sym(prop->expr, e, sym) 981 expr_list_for_each_sym(prop->expr, e, sym)
@@ -871,6 +985,8 @@ out:
871 prop_get_symbol(sym_get_choice_prop(sym2)) == choice) 985 prop_get_symbol(sym_get_choice_prop(sym2)) == choice)
872 sym2 = choice; 986 sym2 = choice;
873 987
988 dep_stack_remove();
989
874 return sym2; 990 return sym2;
875} 991}
876 992
@@ -880,18 +996,20 @@ struct symbol *sym_check_deps(struct symbol *sym)
880 struct property *prop; 996 struct property *prop;
881 997
882 if (sym->flags & SYMBOL_CHECK) { 998 if (sym->flags & SYMBOL_CHECK) {
883 fprintf(stderr, "%s:%d:error: found recursive dependency: %s", 999 sym_check_print_recursive(sym);
884 sym->prop->file->name, sym->prop->lineno,
885 sym->name ? sym->name : "<choice>");
886 return sym; 1000 return sym;
887 } 1001 }
888 if (sym->flags & SYMBOL_CHECKED) 1002 if (sym->flags & SYMBOL_CHECKED)
889 return NULL; 1003 return NULL;
890 1004
891 if (sym_is_choice_value(sym)) { 1005 if (sym_is_choice_value(sym)) {
1006 struct dep_stack stack;
1007
892 /* for choice groups start the check with main choice symbol */ 1008 /* for choice groups start the check with main choice symbol */
1009 dep_stack_insert(&stack, sym);
893 prop = sym_get_choice_prop(sym); 1010 prop = sym_get_choice_prop(sym);
894 sym2 = sym_check_deps(prop_get_symbol(prop)); 1011 sym2 = sym_check_deps(prop_get_symbol(prop));
1012 dep_stack_remove();
895 } else if (sym_is_choice(sym)) { 1013 } else if (sym_is_choice(sym)) {
896 sym2 = sym_check_choice_deps(sym); 1014 sym2 = sym_check_choice_deps(sym);
897 } else { 1015 } else {
@@ -900,14 +1018,8 @@ struct symbol *sym_check_deps(struct symbol *sym)
900 sym->flags &= ~SYMBOL_CHECK; 1018 sym->flags &= ~SYMBOL_CHECK;
901 } 1019 }
902 1020
903 if (sym2) { 1021 if (sym2 && sym2 == sym)
904 fprintf(stderr, " -> %s", sym->name ? sym->name : "<choice>"); 1022 sym2 = NULL;
905 if (sym2 == sym) {
906 fprintf(stderr, "\n");
907 zconfnerrs++;
908 sym2 = NULL;
909 }
910 }
911 1023
912 return sym2; 1024 return sym2;
913} 1025}