aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoman Zippel <zippel@linux-m68k.org>2008-02-28 23:10:24 -0500
committerSam Ravnborg <sam@uranus.ravnborg.org>2008-04-28 17:04:57 -0400
commit48981178869bf7d9770f11fc361996ad11217a75 (patch)
tree7e1cc7382f04ac3e724996a9ea13023bdb531f9a
parentdfecbec8b54038ef02835d2f8181e1f44bd080d2 (diff)
kconfig: fix choice dependency check
Properly check the dependency of choices as a group. Also fix that sym_check_deps() correctly terminates the dependency loop error check (otherwise it would continue printing the dependency chain). Signed-off-by: Roman Zippel <zippel@linux-m68k.org> Signed-off-by: Sam Ravnborg <sam@ravnborg.org>
-rw-r--r--scripts/kconfig/symbol.c94
1 files changed, 76 insertions, 18 deletions
diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c
index 4a03191ad176..45f409a8f37f 100644
--- a/scripts/kconfig/symbol.c
+++ b/scripts/kconfig/symbol.c
@@ -762,8 +762,6 @@ struct symbol **sym_re_search(const char *pattern)
762} 762}
763 763
764 764
765struct symbol *sym_check_deps(struct symbol *sym);
766
767static struct symbol *sym_check_expr_deps(struct expr *e) 765static struct symbol *sym_check_expr_deps(struct expr *e)
768{ 766{
769 struct symbol *sym; 767 struct symbol *sym;
@@ -795,40 +793,100 @@ static struct symbol *sym_check_expr_deps(struct expr *e)
795} 793}
796 794
797/* return NULL when dependencies are OK */ 795/* return NULL when dependencies are OK */
798struct symbol *sym_check_deps(struct symbol *sym) 796static struct symbol *sym_check_sym_deps(struct symbol *sym)
799{ 797{
800 struct symbol *sym2; 798 struct symbol *sym2;
801 struct property *prop; 799 struct property *prop;
802 800
803 if (sym->flags & SYMBOL_CHECK) {
804 fprintf(stderr, "%s:%d:error: found recursive dependency: %s",
805 sym->prop->file->name, sym->prop->lineno, sym->name);
806 return sym;
807 }
808 if (sym->flags & SYMBOL_CHECKED)
809 return NULL;
810
811 sym->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED);
812 sym2 = sym_check_expr_deps(sym->rev_dep.expr); 801 sym2 = sym_check_expr_deps(sym->rev_dep.expr);
813 if (sym2) 802 if (sym2)
814 goto out; 803 return sym2;
815 804
816 for (prop = sym->prop; prop; prop = prop->next) { 805 for (prop = sym->prop; prop; prop = prop->next) {
817 if (prop->type == P_CHOICE || prop->type == P_SELECT) 806 if (prop->type == P_CHOICE || prop->type == P_SELECT)
818 continue; 807 continue;
819 sym2 = sym_check_expr_deps(prop->visible.expr); 808 sym2 = sym_check_expr_deps(prop->visible.expr);
820 if (sym2) 809 if (sym2)
821 goto out; 810 break;
822 if (prop->type != P_DEFAULT || sym_is_choice(sym)) 811 if (prop->type != P_DEFAULT || sym_is_choice(sym))
823 continue; 812 continue;
824 sym2 = sym_check_expr_deps(prop->expr); 813 sym2 = sym_check_expr_deps(prop->expr);
825 if (sym2) 814 if (sym2)
826 goto out; 815 break;
827 } 816 }
828out: 817
818 return sym2;
819}
820
821static struct symbol *sym_check_choice_deps(struct symbol *choice)
822{
823 struct symbol *sym, *sym2;
824 struct property *prop;
825 struct expr *e;
826
827 prop = sym_get_choice_prop(choice);
828 expr_list_for_each_sym(prop->expr, e, sym)
829 sym->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED);
830
831 choice->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED);
832 sym2 = sym_check_sym_deps(choice);
833 choice->flags &= ~SYMBOL_CHECK;
829 if (sym2) 834 if (sym2)
830 fprintf(stderr, " -> %s%s", sym->name, sym2 == sym? "\n": ""); 835 goto out;
831 sym->flags &= ~SYMBOL_CHECK; 836
837 expr_list_for_each_sym(prop->expr, e, sym) {
838 sym2 = sym_check_sym_deps(sym);
839 if (sym2) {
840 fprintf(stderr, " -> %s", sym->name);
841 break;
842 }
843 }
844out:
845 expr_list_for_each_sym(prop->expr, e, sym)
846 sym->flags &= ~SYMBOL_CHECK;
847
848 if (sym2 && sym_is_choice_value(sym2) &&
849 prop_get_symbol(sym_get_choice_prop(sym2)) == choice)
850 sym2 = choice;
851
852 return sym2;
853}
854
855struct symbol *sym_check_deps(struct symbol *sym)
856{
857 struct symbol *sym2;
858 struct property *prop;
859
860 if (sym->flags & SYMBOL_CHECK) {
861 fprintf(stderr, "%s:%d:error: found recursive dependency: %s",
862 sym->prop->file->name, sym->prop->lineno,
863 sym->name ? sym->name : "<choice>");
864 return sym;
865 }
866 if (sym->flags & SYMBOL_CHECKED)
867 return NULL;
868
869 if (sym_is_choice_value(sym)) {
870 /* for choice groups start the check with main choice symbol */
871 prop = sym_get_choice_prop(sym);
872 sym2 = sym_check_deps(prop_get_symbol(prop));
873 } else if (sym_is_choice(sym)) {
874 sym2 = sym_check_choice_deps(sym);
875 } else {
876 sym->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED);
877 sym2 = sym_check_sym_deps(sym);
878 sym->flags &= ~SYMBOL_CHECK;
879 }
880
881 if (sym2) {
882 fprintf(stderr, " -> %s", sym->name ? sym->name : "<choice>");
883 if (sym2 == sym) {
884 fprintf(stderr, "\n");
885 zconfnerrs++;
886 sym2 = NULL;
887 }
888 }
889
832 return sym2; 890 return sym2;
833} 891}
834 892