diff options
| -rw-r--r-- | scripts/kconfig/symbol.c | 94 |
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 | ||
| 765 | struct symbol *sym_check_deps(struct symbol *sym); | ||
| 766 | |||
| 767 | static struct symbol *sym_check_expr_deps(struct expr *e) | 765 | static 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 */ |
| 798 | struct symbol *sym_check_deps(struct symbol *sym) | 796 | static 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 | } |
| 828 | out: | 817 | |
| 818 | return sym2; | ||
| 819 | } | ||
| 820 | |||
| 821 | static 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 | } | ||
| 844 | out: | ||
| 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 | |||
| 855 | struct 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 | ||
