diff options
Diffstat (limited to 'scripts/kconfig/symbol.c')
-rw-r--r-- | scripts/kconfig/symbol.c | 118 |
1 files changed, 87 insertions, 31 deletions
diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c index 4a03191ad176..18f3e5c33634 100644 --- a/scripts/kconfig/symbol.c +++ b/scripts/kconfig/symbol.c | |||
@@ -40,7 +40,7 @@ void sym_add_default(struct symbol *sym, const char *def) | |||
40 | { | 40 | { |
41 | struct property *prop = prop_alloc(P_DEFAULT, sym); | 41 | struct property *prop = prop_alloc(P_DEFAULT, sym); |
42 | 42 | ||
43 | prop->expr = expr_alloc_symbol(sym_lookup(def, 1)); | 43 | prop->expr = expr_alloc_symbol(sym_lookup(def, SYMBOL_CONST)); |
44 | } | 44 | } |
45 | 45 | ||
46 | void sym_init(void) | 46 | void sym_init(void) |
@@ -350,9 +350,6 @@ void sym_calc_value(struct symbol *sym) | |||
350 | ; | 350 | ; |
351 | } | 351 | } |
352 | 352 | ||
353 | if (sym->flags & SYMBOL_AUTO) | ||
354 | sym->flags &= ~SYMBOL_WRITE; | ||
355 | |||
356 | sym->curr = newval; | 353 | sym->curr = newval; |
357 | if (sym_is_choice(sym) && newval.tri == yes) | 354 | if (sym_is_choice(sym) && newval.tri == yes) |
358 | sym->curr.val = sym_calc_choice(sym); | 355 | sym->curr.val = sym_calc_choice(sym); |
@@ -377,6 +374,9 @@ void sym_calc_value(struct symbol *sym) | |||
377 | sym_set_changed(choice_sym); | 374 | sym_set_changed(choice_sym); |
378 | } | 375 | } |
379 | } | 376 | } |
377 | |||
378 | if (sym->flags & SYMBOL_AUTO) | ||
379 | sym->flags &= ~SYMBOL_WRITE; | ||
380 | } | 380 | } |
381 | 381 | ||
382 | void sym_clear_all_valid(void) | 382 | void sym_clear_all_valid(void) |
@@ -651,7 +651,7 @@ bool sym_is_changable(struct symbol *sym) | |||
651 | return sym->visible > sym->rev_dep.tri; | 651 | return sym->visible > sym->rev_dep.tri; |
652 | } | 652 | } |
653 | 653 | ||
654 | struct symbol *sym_lookup(const char *name, int isconst) | 654 | struct symbol *sym_lookup(const char *name, int flags) |
655 | { | 655 | { |
656 | struct symbol *symbol; | 656 | struct symbol *symbol; |
657 | const char *ptr; | 657 | const char *ptr; |
@@ -671,11 +671,10 @@ struct symbol *sym_lookup(const char *name, int isconst) | |||
671 | hash &= 0xff; | 671 | hash &= 0xff; |
672 | 672 | ||
673 | for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) { | 673 | for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) { |
674 | if (!strcmp(symbol->name, name)) { | 674 | if (!strcmp(symbol->name, name) && |
675 | if ((isconst && symbol->flags & SYMBOL_CONST) || | 675 | (flags ? symbol->flags & flags |
676 | (!isconst && !(symbol->flags & SYMBOL_CONST))) | 676 | : !(symbol->flags & (SYMBOL_CONST|SYMBOL_CHOICE)))) |
677 | return symbol; | 677 | return symbol; |
678 | } | ||
679 | } | 678 | } |
680 | new_name = strdup(name); | 679 | new_name = strdup(name); |
681 | } else { | 680 | } else { |
@@ -687,8 +686,7 @@ struct symbol *sym_lookup(const char *name, int isconst) | |||
687 | memset(symbol, 0, sizeof(*symbol)); | 686 | memset(symbol, 0, sizeof(*symbol)); |
688 | symbol->name = new_name; | 687 | symbol->name = new_name; |
689 | symbol->type = S_UNKNOWN; | 688 | symbol->type = S_UNKNOWN; |
690 | if (isconst) | 689 | symbol->flags |= flags; |
691 | symbol->flags |= SYMBOL_CONST; | ||
692 | 690 | ||
693 | symbol->next = symbol_hash[hash]; | 691 | symbol->next = symbol_hash[hash]; |
694 | symbol_hash[hash] = symbol; | 692 | symbol_hash[hash] = symbol; |
@@ -762,8 +760,6 @@ struct symbol **sym_re_search(const char *pattern) | |||
762 | } | 760 | } |
763 | 761 | ||
764 | 762 | ||
765 | struct symbol *sym_check_deps(struct symbol *sym); | ||
766 | |||
767 | static struct symbol *sym_check_expr_deps(struct expr *e) | 763 | static struct symbol *sym_check_expr_deps(struct expr *e) |
768 | { | 764 | { |
769 | struct symbol *sym; | 765 | struct symbol *sym; |
@@ -795,40 +791,100 @@ static struct symbol *sym_check_expr_deps(struct expr *e) | |||
795 | } | 791 | } |
796 | 792 | ||
797 | /* return NULL when dependencies are OK */ | 793 | /* return NULL when dependencies are OK */ |
798 | struct symbol *sym_check_deps(struct symbol *sym) | 794 | static struct symbol *sym_check_sym_deps(struct symbol *sym) |
799 | { | 795 | { |
800 | struct symbol *sym2; | 796 | struct symbol *sym2; |
801 | struct property *prop; | 797 | struct property *prop; |
802 | 798 | ||
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); | 799 | sym2 = sym_check_expr_deps(sym->rev_dep.expr); |
813 | if (sym2) | 800 | if (sym2) |
814 | goto out; | 801 | return sym2; |
815 | 802 | ||
816 | for (prop = sym->prop; prop; prop = prop->next) { | 803 | for (prop = sym->prop; prop; prop = prop->next) { |
817 | if (prop->type == P_CHOICE || prop->type == P_SELECT) | 804 | if (prop->type == P_CHOICE || prop->type == P_SELECT) |
818 | continue; | 805 | continue; |
819 | sym2 = sym_check_expr_deps(prop->visible.expr); | 806 | sym2 = sym_check_expr_deps(prop->visible.expr); |
820 | if (sym2) | 807 | if (sym2) |
821 | goto out; | 808 | break; |
822 | if (prop->type != P_DEFAULT || sym_is_choice(sym)) | 809 | if (prop->type != P_DEFAULT || sym_is_choice(sym)) |
823 | continue; | 810 | continue; |
824 | sym2 = sym_check_expr_deps(prop->expr); | 811 | sym2 = sym_check_expr_deps(prop->expr); |
825 | if (sym2) | 812 | if (sym2) |
826 | goto out; | 813 | break; |
827 | } | 814 | } |
828 | out: | 815 | |
816 | return sym2; | ||
817 | } | ||
818 | |||
819 | static struct symbol *sym_check_choice_deps(struct symbol *choice) | ||
820 | { | ||
821 | struct symbol *sym, *sym2; | ||
822 | struct property *prop; | ||
823 | struct expr *e; | ||
824 | |||
825 | prop = sym_get_choice_prop(choice); | ||
826 | expr_list_for_each_sym(prop->expr, e, sym) | ||
827 | sym->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED); | ||
828 | |||
829 | choice->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED); | ||
830 | sym2 = sym_check_sym_deps(choice); | ||
831 | choice->flags &= ~SYMBOL_CHECK; | ||
829 | if (sym2) | 832 | if (sym2) |
830 | fprintf(stderr, " -> %s%s", sym->name, sym2 == sym? "\n": ""); | 833 | goto out; |
831 | sym->flags &= ~SYMBOL_CHECK; | 834 | |
835 | expr_list_for_each_sym(prop->expr, e, sym) { | ||
836 | sym2 = sym_check_sym_deps(sym); | ||
837 | if (sym2) { | ||
838 | fprintf(stderr, " -> %s", sym->name); | ||
839 | break; | ||
840 | } | ||
841 | } | ||
842 | out: | ||
843 | expr_list_for_each_sym(prop->expr, e, sym) | ||
844 | sym->flags &= ~SYMBOL_CHECK; | ||
845 | |||
846 | if (sym2 && sym_is_choice_value(sym2) && | ||
847 | prop_get_symbol(sym_get_choice_prop(sym2)) == choice) | ||
848 | sym2 = choice; | ||
849 | |||
850 | return sym2; | ||
851 | } | ||
852 | |||
853 | struct symbol *sym_check_deps(struct symbol *sym) | ||
854 | { | ||
855 | struct symbol *sym2; | ||
856 | struct property *prop; | ||
857 | |||
858 | if (sym->flags & SYMBOL_CHECK) { | ||
859 | fprintf(stderr, "%s:%d:error: found recursive dependency: %s", | ||
860 | sym->prop->file->name, sym->prop->lineno, | ||
861 | sym->name ? sym->name : "<choice>"); | ||
862 | return sym; | ||
863 | } | ||
864 | if (sym->flags & SYMBOL_CHECKED) | ||
865 | return NULL; | ||
866 | |||
867 | if (sym_is_choice_value(sym)) { | ||
868 | /* for choice groups start the check with main choice symbol */ | ||
869 | prop = sym_get_choice_prop(sym); | ||
870 | sym2 = sym_check_deps(prop_get_symbol(prop)); | ||
871 | } else if (sym_is_choice(sym)) { | ||
872 | sym2 = sym_check_choice_deps(sym); | ||
873 | } else { | ||
874 | sym->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED); | ||
875 | sym2 = sym_check_sym_deps(sym); | ||
876 | sym->flags &= ~SYMBOL_CHECK; | ||
877 | } | ||
878 | |||
879 | if (sym2) { | ||
880 | fprintf(stderr, " -> %s", sym->name ? sym->name : "<choice>"); | ||
881 | if (sym2 == sym) { | ||
882 | fprintf(stderr, "\n"); | ||
883 | zconfnerrs++; | ||
884 | sym2 = NULL; | ||
885 | } | ||
886 | } | ||
887 | |||
832 | return sym2; | 888 | return sym2; |
833 | } | 889 | } |
834 | 890 | ||
@@ -904,7 +960,7 @@ void prop_add_env(const char *env) | |||
904 | } | 960 | } |
905 | 961 | ||
906 | prop = prop_alloc(P_ENV, sym); | 962 | prop = prop_alloc(P_ENV, sym); |
907 | prop->expr = expr_alloc_symbol(sym_lookup(env, 1)); | 963 | prop->expr = expr_alloc_symbol(sym_lookup(env, SYMBOL_CONST)); |
908 | 964 | ||
909 | sym_env_list = expr_alloc_one(E_LIST, sym_env_list); | 965 | sym_env_list = expr_alloc_one(E_LIST, sym_env_list); |
910 | sym_env_list->right.sym = sym; | 966 | sym_env_list->right.sym = sym; |