diff options
Diffstat (limited to 'scripts/kconfig/symbol.c')
-rw-r--r-- | scripts/kconfig/symbol.c | 347 |
1 files changed, 314 insertions, 33 deletions
diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c index 2e7a048e0cfc..a796c95fe8a0 100644 --- a/scripts/kconfig/symbol.c +++ b/scripts/kconfig/symbol.c | |||
@@ -205,6 +205,16 @@ static void sym_calc_visibility(struct symbol *sym) | |||
205 | } | 205 | } |
206 | if (sym_is_choice_value(sym)) | 206 | if (sym_is_choice_value(sym)) |
207 | return; | 207 | return; |
208 | /* defaulting to "yes" if no explicit "depends on" are given */ | ||
209 | tri = yes; | ||
210 | if (sym->dir_dep.expr) | ||
211 | tri = expr_calc_value(sym->dir_dep.expr); | ||
212 | if (tri == mod) | ||
213 | tri = yes; | ||
214 | if (sym->dir_dep.tri != tri) { | ||
215 | sym->dir_dep.tri = tri; | ||
216 | sym_set_changed(sym); | ||
217 | } | ||
208 | tri = no; | 218 | tri = no; |
209 | if (sym->rev_dep.expr) | 219 | if (sym->rev_dep.expr) |
210 | tri = expr_calc_value(sym->rev_dep.expr); | 220 | tri = expr_calc_value(sym->rev_dep.expr); |
@@ -216,44 +226,63 @@ static void sym_calc_visibility(struct symbol *sym) | |||
216 | } | 226 | } |
217 | } | 227 | } |
218 | 228 | ||
219 | static struct symbol *sym_calc_choice(struct symbol *sym) | 229 | /* |
230 | * Find the default symbol for a choice. | ||
231 | * First try the default values for the choice symbol | ||
232 | * Next locate the first visible choice value | ||
233 | * Return NULL if none was found | ||
234 | */ | ||
235 | struct symbol *sym_choice_default(struct symbol *sym) | ||
220 | { | 236 | { |
221 | struct symbol *def_sym; | 237 | struct symbol *def_sym; |
222 | struct property *prop; | 238 | struct property *prop; |
223 | struct expr *e; | 239 | struct expr *e; |
224 | 240 | ||
225 | /* is the user choice visible? */ | ||
226 | def_sym = sym->def[S_DEF_USER].val; | ||
227 | if (def_sym) { | ||
228 | sym_calc_visibility(def_sym); | ||
229 | if (def_sym->visible != no) | ||
230 | return def_sym; | ||
231 | } | ||
232 | |||
233 | /* any of the defaults visible? */ | 241 | /* any of the defaults visible? */ |
234 | for_all_defaults(sym, prop) { | 242 | for_all_defaults(sym, prop) { |
235 | prop->visible.tri = expr_calc_value(prop->visible.expr); | 243 | prop->visible.tri = expr_calc_value(prop->visible.expr); |
236 | if (prop->visible.tri == no) | 244 | if (prop->visible.tri == no) |
237 | continue; | 245 | continue; |
238 | def_sym = prop_get_symbol(prop); | 246 | def_sym = prop_get_symbol(prop); |
239 | sym_calc_visibility(def_sym); | ||
240 | if (def_sym->visible != no) | 247 | if (def_sym->visible != no) |
241 | return def_sym; | 248 | return def_sym; |
242 | } | 249 | } |
243 | 250 | ||
244 | /* just get the first visible value */ | 251 | /* just get the first visible value */ |
245 | prop = sym_get_choice_prop(sym); | 252 | prop = sym_get_choice_prop(sym); |
246 | expr_list_for_each_sym(prop->expr, e, def_sym) { | 253 | expr_list_for_each_sym(prop->expr, e, def_sym) |
247 | sym_calc_visibility(def_sym); | ||
248 | if (def_sym->visible != no) | 254 | if (def_sym->visible != no) |
249 | return def_sym; | 255 | return def_sym; |
250 | } | ||
251 | 256 | ||
252 | /* no choice? reset tristate value */ | 257 | /* failed to locate any defaults */ |
253 | sym->curr.tri = no; | ||
254 | return NULL; | 258 | return NULL; |
255 | } | 259 | } |
256 | 260 | ||
261 | static struct symbol *sym_calc_choice(struct symbol *sym) | ||
262 | { | ||
263 | struct symbol *def_sym; | ||
264 | struct property *prop; | ||
265 | struct expr *e; | ||
266 | |||
267 | /* first calculate all choice values' visibilities */ | ||
268 | prop = sym_get_choice_prop(sym); | ||
269 | expr_list_for_each_sym(prop->expr, e, def_sym) | ||
270 | sym_calc_visibility(def_sym); | ||
271 | |||
272 | /* is the user choice visible? */ | ||
273 | def_sym = sym->def[S_DEF_USER].val; | ||
274 | if (def_sym && def_sym->visible != no) | ||
275 | return def_sym; | ||
276 | |||
277 | def_sym = sym_choice_default(sym); | ||
278 | |||
279 | if (def_sym == NULL) | ||
280 | /* no choice? reset tristate value */ | ||
281 | sym->curr.tri = no; | ||
282 | |||
283 | return def_sym; | ||
284 | } | ||
285 | |||
257 | void sym_calc_value(struct symbol *sym) | 286 | void sym_calc_value(struct symbol *sym) |
258 | { | 287 | { |
259 | struct symbol_value newval, oldval; | 288 | struct symbol_value newval, oldval; |
@@ -321,6 +350,18 @@ void sym_calc_value(struct symbol *sym) | |||
321 | } | 350 | } |
322 | } | 351 | } |
323 | calc_newval: | 352 | calc_newval: |
353 | if (sym->dir_dep.tri == no && sym->rev_dep.tri != no) { | ||
354 | struct expr *e; | ||
355 | e = expr_simplify_unmet_dep(sym->rev_dep.expr, | ||
356 | sym->dir_dep.expr); | ||
357 | fprintf(stderr, "warning: ("); | ||
358 | expr_fprint(e, stderr); | ||
359 | fprintf(stderr, ") selects %s which has unmet direct dependencies (", | ||
360 | sym->name); | ||
361 | expr_fprint(sym->dir_dep.expr, stderr); | ||
362 | fprintf(stderr, ")\n"); | ||
363 | expr_free(e); | ||
364 | } | ||
324 | newval.tri = EXPR_OR(newval.tri, sym->rev_dep.tri); | 365 | newval.tri = EXPR_OR(newval.tri, sym->rev_dep.tri); |
325 | } | 366 | } |
326 | if (newval.tri == mod && sym_get_type(sym) == S_BOOLEAN) | 367 | if (newval.tri == mod && sym_get_type(sym) == S_BOOLEAN) |
@@ -365,12 +406,13 @@ void sym_calc_value(struct symbol *sym) | |||
365 | 406 | ||
366 | if (sym_is_choice(sym)) { | 407 | if (sym_is_choice(sym)) { |
367 | struct symbol *choice_sym; | 408 | struct symbol *choice_sym; |
368 | int flags = sym->flags & (SYMBOL_CHANGED | SYMBOL_WRITE); | ||
369 | 409 | ||
370 | prop = sym_get_choice_prop(sym); | 410 | prop = sym_get_choice_prop(sym); |
371 | expr_list_for_each_sym(prop->expr, e, choice_sym) { | 411 | expr_list_for_each_sym(prop->expr, e, choice_sym) { |
372 | choice_sym->flags |= flags; | 412 | if ((sym->flags & SYMBOL_WRITE) && |
373 | if (flags & SYMBOL_CHANGED) | 413 | choice_sym->visible != no) |
414 | choice_sym->flags |= SYMBOL_WRITE; | ||
415 | if (sym->flags & SYMBOL_CHANGED) | ||
374 | sym_set_changed(choice_sym); | 416 | sym_set_changed(choice_sym); |
375 | } | 417 | } |
376 | } | 418 | } |
@@ -623,6 +665,80 @@ bool sym_set_string_value(struct symbol *sym, const char *newval) | |||
623 | return true; | 665 | return true; |
624 | } | 666 | } |
625 | 667 | ||
668 | /* | ||
669 | * Find the default value associated to a symbol. | ||
670 | * For tristate symbol handle the modules=n case | ||
671 | * in which case "m" becomes "y". | ||
672 | * If the symbol does not have any default then fallback | ||
673 | * to the fixed default values. | ||
674 | */ | ||
675 | const char *sym_get_string_default(struct symbol *sym) | ||
676 | { | ||
677 | struct property *prop; | ||
678 | struct symbol *ds; | ||
679 | const char *str; | ||
680 | tristate val; | ||
681 | |||
682 | sym_calc_visibility(sym); | ||
683 | sym_calc_value(modules_sym); | ||
684 | val = symbol_no.curr.tri; | ||
685 | str = symbol_empty.curr.val; | ||
686 | |||
687 | /* If symbol has a default value look it up */ | ||
688 | prop = sym_get_default_prop(sym); | ||
689 | if (prop != NULL) { | ||
690 | switch (sym->type) { | ||
691 | case S_BOOLEAN: | ||
692 | case S_TRISTATE: | ||
693 | /* The visibility may limit the value from yes => mod */ | ||
694 | val = EXPR_AND(expr_calc_value(prop->expr), prop->visible.tri); | ||
695 | break; | ||
696 | default: | ||
697 | /* | ||
698 | * The following fails to handle the situation | ||
699 | * where a default value is further limited by | ||
700 | * the valid range. | ||
701 | */ | ||
702 | ds = prop_get_symbol(prop); | ||
703 | if (ds != NULL) { | ||
704 | sym_calc_value(ds); | ||
705 | str = (const char *)ds->curr.val; | ||
706 | } | ||
707 | } | ||
708 | } | ||
709 | |||
710 | /* Handle select statements */ | ||
711 | val = EXPR_OR(val, sym->rev_dep.tri); | ||
712 | |||
713 | /* transpose mod to yes if modules are not enabled */ | ||
714 | if (val == mod) | ||
715 | if (!sym_is_choice_value(sym) && modules_sym->curr.tri == no) | ||
716 | val = yes; | ||
717 | |||
718 | /* transpose mod to yes if type is bool */ | ||
719 | if (sym->type == S_BOOLEAN && val == mod) | ||
720 | val = yes; | ||
721 | |||
722 | switch (sym->type) { | ||
723 | case S_BOOLEAN: | ||
724 | case S_TRISTATE: | ||
725 | switch (val) { | ||
726 | case no: return "n"; | ||
727 | case mod: return "m"; | ||
728 | case yes: return "y"; | ||
729 | } | ||
730 | case S_INT: | ||
731 | case S_HEX: | ||
732 | return str; | ||
733 | case S_STRING: | ||
734 | return str; | ||
735 | case S_OTHER: | ||
736 | case S_UNKNOWN: | ||
737 | break; | ||
738 | } | ||
739 | return ""; | ||
740 | } | ||
741 | |||
626 | const char *sym_get_string_value(struct symbol *sym) | 742 | const char *sym_get_string_value(struct symbol *sym) |
627 | { | 743 | { |
628 | tristate val; | 744 | tristate val; |
@@ -728,6 +844,55 @@ struct symbol *sym_find(const char *name) | |||
728 | return symbol; | 844 | return symbol; |
729 | } | 845 | } |
730 | 846 | ||
847 | /* | ||
848 | * Expand symbol's names embedded in the string given in argument. Symbols' | ||
849 | * name to be expanded shall be prefixed by a '$'. Unknown symbol expands to | ||
850 | * the empty string. | ||
851 | */ | ||
852 | const char *sym_expand_string_value(const char *in) | ||
853 | { | ||
854 | const char *src; | ||
855 | char *res; | ||
856 | size_t reslen; | ||
857 | |||
858 | reslen = strlen(in) + 1; | ||
859 | res = malloc(reslen); | ||
860 | res[0] = '\0'; | ||
861 | |||
862 | while ((src = strchr(in, '$'))) { | ||
863 | char *p, name[SYMBOL_MAXLENGTH]; | ||
864 | const char *symval = ""; | ||
865 | struct symbol *sym; | ||
866 | size_t newlen; | ||
867 | |||
868 | strncat(res, in, src - in); | ||
869 | src++; | ||
870 | |||
871 | p = name; | ||
872 | while (isalnum(*src) || *src == '_') | ||
873 | *p++ = *src++; | ||
874 | *p = '\0'; | ||
875 | |||
876 | sym = sym_find(name); | ||
877 | if (sym != NULL) { | ||
878 | sym_calc_value(sym); | ||
879 | symval = sym_get_string_value(sym); | ||
880 | } | ||
881 | |||
882 | newlen = strlen(res) + strlen(symval) + strlen(src) + 1; | ||
883 | if (newlen > reslen) { | ||
884 | reslen = newlen; | ||
885 | res = realloc(res, reslen); | ||
886 | } | ||
887 | |||
888 | strcat(res, symval); | ||
889 | in = src; | ||
890 | } | ||
891 | strcat(res, in); | ||
892 | |||
893 | return res; | ||
894 | } | ||
895 | |||
731 | struct symbol **sym_re_search(const char *pattern) | 896 | struct symbol **sym_re_search(const char *pattern) |
732 | { | 897 | { |
733 | struct symbol *sym, **sym_arr = NULL; | 898 | struct symbol *sym, **sym_arr = NULL; |
@@ -765,6 +930,112 @@ struct symbol **sym_re_search(const char *pattern) | |||
765 | return sym_arr; | 930 | return sym_arr; |
766 | } | 931 | } |
767 | 932 | ||
933 | /* | ||
934 | * When we check for recursive dependencies we use a stack to save | ||
935 | * current state so we can print out relevant info to user. | ||
936 | * The entries are located on the call stack so no need to free memory. | ||
937 | * Note inser() remove() must always match to properly clear the stack. | ||
938 | */ | ||
939 | static struct dep_stack { | ||
940 | struct dep_stack *prev, *next; | ||
941 | struct symbol *sym; | ||
942 | struct property *prop; | ||
943 | struct expr *expr; | ||
944 | } *check_top; | ||
945 | |||
946 | static void dep_stack_insert(struct dep_stack *stack, struct symbol *sym) | ||
947 | { | ||
948 | memset(stack, 0, sizeof(*stack)); | ||
949 | if (check_top) | ||
950 | check_top->next = stack; | ||
951 | stack->prev = check_top; | ||
952 | stack->sym = sym; | ||
953 | check_top = stack; | ||
954 | } | ||
955 | |||
956 | static void dep_stack_remove(void) | ||
957 | { | ||
958 | check_top = check_top->prev; | ||
959 | if (check_top) | ||
960 | check_top->next = NULL; | ||
961 | } | ||
962 | |||
963 | /* | ||
964 | * Called when we have detected a recursive dependency. | ||
965 | * check_top point to the top of the stact so we use | ||
966 | * the ->prev pointer to locate the bottom of the stack. | ||
967 | */ | ||
968 | static void sym_check_print_recursive(struct symbol *last_sym) | ||
969 | { | ||
970 | struct dep_stack *stack; | ||
971 | struct symbol *sym, *next_sym; | ||
972 | struct menu *menu = NULL; | ||
973 | struct property *prop; | ||
974 | struct dep_stack cv_stack; | ||
975 | |||
976 | if (sym_is_choice_value(last_sym)) { | ||
977 | dep_stack_insert(&cv_stack, last_sym); | ||
978 | last_sym = prop_get_symbol(sym_get_choice_prop(last_sym)); | ||
979 | } | ||
980 | |||
981 | for (stack = check_top; stack != NULL; stack = stack->prev) | ||
982 | if (stack->sym == last_sym) | ||
983 | break; | ||
984 | if (!stack) { | ||
985 | fprintf(stderr, "unexpected recursive dependency error\n"); | ||
986 | return; | ||
987 | } | ||
988 | |||
989 | for (; stack; stack = stack->next) { | ||
990 | sym = stack->sym; | ||
991 | next_sym = stack->next ? stack->next->sym : last_sym; | ||
992 | prop = stack->prop; | ||
993 | if (prop == NULL) | ||
994 | prop = stack->sym->prop; | ||
995 | |||
996 | /* for choice values find the menu entry (used below) */ | ||
997 | if (sym_is_choice(sym) || sym_is_choice_value(sym)) { | ||
998 | for (prop = sym->prop; prop; prop = prop->next) { | ||
999 | menu = prop->menu; | ||
1000 | if (prop->menu) | ||
1001 | break; | ||
1002 | } | ||
1003 | } | ||
1004 | if (stack->sym == last_sym) | ||
1005 | fprintf(stderr, "%s:%d:error: recursive dependency detected!\n", | ||
1006 | prop->file->name, prop->lineno); | ||
1007 | if (stack->expr) { | ||
1008 | fprintf(stderr, "%s:%d:\tsymbol %s %s value contains %s\n", | ||
1009 | prop->file->name, prop->lineno, | ||
1010 | sym->name ? sym->name : "<choice>", | ||
1011 | prop_get_type_name(prop->type), | ||
1012 | next_sym->name ? next_sym->name : "<choice>"); | ||
1013 | } else if (stack->prop) { | ||
1014 | fprintf(stderr, "%s:%d:\tsymbol %s depends on %s\n", | ||
1015 | prop->file->name, prop->lineno, | ||
1016 | sym->name ? sym->name : "<choice>", | ||
1017 | next_sym->name ? next_sym->name : "<choice>"); | ||
1018 | } else if (sym_is_choice(sym)) { | ||
1019 | fprintf(stderr, "%s:%d:\tchoice %s contains symbol %s\n", | ||
1020 | menu->file->name, menu->lineno, | ||
1021 | sym->name ? sym->name : "<choice>", | ||
1022 | next_sym->name ? next_sym->name : "<choice>"); | ||
1023 | } else if (sym_is_choice_value(sym)) { | ||
1024 | fprintf(stderr, "%s:%d:\tsymbol %s is part of choice %s\n", | ||
1025 | menu->file->name, menu->lineno, | ||
1026 | sym->name ? sym->name : "<choice>", | ||
1027 | next_sym->name ? next_sym->name : "<choice>"); | ||
1028 | } else { | ||
1029 | fprintf(stderr, "%s:%d:\tsymbol %s is selected by %s\n", | ||
1030 | prop->file->name, prop->lineno, | ||
1031 | sym->name ? sym->name : "<choice>", | ||
1032 | next_sym->name ? next_sym->name : "<choice>"); | ||
1033 | } | ||
1034 | } | ||
1035 | |||
1036 | if (check_top == &cv_stack) | ||
1037 | dep_stack_remove(); | ||
1038 | } | ||
768 | 1039 | ||
769 | static struct symbol *sym_check_expr_deps(struct expr *e) | 1040 | static struct symbol *sym_check_expr_deps(struct expr *e) |
770 | { | 1041 | { |
@@ -801,24 +1072,33 @@ static struct symbol *sym_check_sym_deps(struct symbol *sym) | |||
801 | { | 1072 | { |
802 | struct symbol *sym2; | 1073 | struct symbol *sym2; |
803 | struct property *prop; | 1074 | struct property *prop; |
1075 | struct dep_stack stack; | ||
1076 | |||
1077 | dep_stack_insert(&stack, sym); | ||
804 | 1078 | ||
805 | sym2 = sym_check_expr_deps(sym->rev_dep.expr); | 1079 | sym2 = sym_check_expr_deps(sym->rev_dep.expr); |
806 | if (sym2) | 1080 | if (sym2) |
807 | return sym2; | 1081 | goto out; |
808 | 1082 | ||
809 | for (prop = sym->prop; prop; prop = prop->next) { | 1083 | for (prop = sym->prop; prop; prop = prop->next) { |
810 | if (prop->type == P_CHOICE || prop->type == P_SELECT) | 1084 | if (prop->type == P_CHOICE || prop->type == P_SELECT) |
811 | continue; | 1085 | continue; |
1086 | stack.prop = prop; | ||
812 | sym2 = sym_check_expr_deps(prop->visible.expr); | 1087 | sym2 = sym_check_expr_deps(prop->visible.expr); |
813 | if (sym2) | 1088 | if (sym2) |
814 | break; | 1089 | break; |
815 | if (prop->type != P_DEFAULT || sym_is_choice(sym)) | 1090 | if (prop->type != P_DEFAULT || sym_is_choice(sym)) |
816 | continue; | 1091 | continue; |
1092 | stack.expr = prop->expr; | ||
817 | sym2 = sym_check_expr_deps(prop->expr); | 1093 | sym2 = sym_check_expr_deps(prop->expr); |
818 | if (sym2) | 1094 | if (sym2) |
819 | break; | 1095 | break; |
1096 | stack.expr = NULL; | ||
820 | } | 1097 | } |
821 | 1098 | ||
1099 | out: | ||
1100 | dep_stack_remove(); | ||
1101 | |||
822 | return sym2; | 1102 | return sym2; |
823 | } | 1103 | } |
824 | 1104 | ||
@@ -827,6 +1107,9 @@ static struct symbol *sym_check_choice_deps(struct symbol *choice) | |||
827 | struct symbol *sym, *sym2; | 1107 | struct symbol *sym, *sym2; |
828 | struct property *prop; | 1108 | struct property *prop; |
829 | struct expr *e; | 1109 | struct expr *e; |
1110 | struct dep_stack stack; | ||
1111 | |||
1112 | dep_stack_insert(&stack, choice); | ||
830 | 1113 | ||
831 | prop = sym_get_choice_prop(choice); | 1114 | prop = sym_get_choice_prop(choice); |
832 | expr_list_for_each_sym(prop->expr, e, sym) | 1115 | expr_list_for_each_sym(prop->expr, e, sym) |
@@ -840,10 +1123,8 @@ static struct symbol *sym_check_choice_deps(struct symbol *choice) | |||
840 | 1123 | ||
841 | expr_list_for_each_sym(prop->expr, e, sym) { | 1124 | expr_list_for_each_sym(prop->expr, e, sym) { |
842 | sym2 = sym_check_sym_deps(sym); | 1125 | sym2 = sym_check_sym_deps(sym); |
843 | if (sym2) { | 1126 | if (sym2) |
844 | fprintf(stderr, " -> %s", sym->name); | ||
845 | break; | 1127 | break; |
846 | } | ||
847 | } | 1128 | } |
848 | out: | 1129 | out: |
849 | expr_list_for_each_sym(prop->expr, e, sym) | 1130 | expr_list_for_each_sym(prop->expr, e, sym) |
@@ -853,6 +1134,8 @@ out: | |||
853 | prop_get_symbol(sym_get_choice_prop(sym2)) == choice) | 1134 | prop_get_symbol(sym_get_choice_prop(sym2)) == choice) |
854 | sym2 = choice; | 1135 | sym2 = choice; |
855 | 1136 | ||
1137 | dep_stack_remove(); | ||
1138 | |||
856 | return sym2; | 1139 | return sym2; |
857 | } | 1140 | } |
858 | 1141 | ||
@@ -862,18 +1145,20 @@ struct symbol *sym_check_deps(struct symbol *sym) | |||
862 | struct property *prop; | 1145 | struct property *prop; |
863 | 1146 | ||
864 | if (sym->flags & SYMBOL_CHECK) { | 1147 | if (sym->flags & SYMBOL_CHECK) { |
865 | fprintf(stderr, "%s:%d:error: found recursive dependency: %s", | 1148 | sym_check_print_recursive(sym); |
866 | sym->prop->file->name, sym->prop->lineno, | ||
867 | sym->name ? sym->name : "<choice>"); | ||
868 | return sym; | 1149 | return sym; |
869 | } | 1150 | } |
870 | if (sym->flags & SYMBOL_CHECKED) | 1151 | if (sym->flags & SYMBOL_CHECKED) |
871 | return NULL; | 1152 | return NULL; |
872 | 1153 | ||
873 | if (sym_is_choice_value(sym)) { | 1154 | if (sym_is_choice_value(sym)) { |
1155 | struct dep_stack stack; | ||
1156 | |||
874 | /* for choice groups start the check with main choice symbol */ | 1157 | /* for choice groups start the check with main choice symbol */ |
1158 | dep_stack_insert(&stack, sym); | ||
875 | prop = sym_get_choice_prop(sym); | 1159 | prop = sym_get_choice_prop(sym); |
876 | sym2 = sym_check_deps(prop_get_symbol(prop)); | 1160 | sym2 = sym_check_deps(prop_get_symbol(prop)); |
1161 | dep_stack_remove(); | ||
877 | } else if (sym_is_choice(sym)) { | 1162 | } else if (sym_is_choice(sym)) { |
878 | sym2 = sym_check_choice_deps(sym); | 1163 | sym2 = sym_check_choice_deps(sym); |
879 | } else { | 1164 | } else { |
@@ -882,14 +1167,8 @@ struct symbol *sym_check_deps(struct symbol *sym) | |||
882 | sym->flags &= ~SYMBOL_CHECK; | 1167 | sym->flags &= ~SYMBOL_CHECK; |
883 | } | 1168 | } |
884 | 1169 | ||
885 | if (sym2) { | 1170 | if (sym2 && sym2 == sym) |
886 | fprintf(stderr, " -> %s", sym->name ? sym->name : "<choice>"); | 1171 | sym2 = NULL; |
887 | if (sym2 == sym) { | ||
888 | fprintf(stderr, "\n"); | ||
889 | zconfnerrs++; | ||
890 | sym2 = NULL; | ||
891 | } | ||
892 | } | ||
893 | 1172 | ||
894 | return sym2; | 1173 | return sym2; |
895 | } | 1174 | } |
@@ -943,6 +1222,8 @@ const char *prop_get_type_name(enum prop_type type) | |||
943 | return "select"; | 1222 | return "select"; |
944 | case P_RANGE: | 1223 | case P_RANGE: |
945 | return "range"; | 1224 | return "range"; |
1225 | case P_SYMBOL: | ||
1226 | return "symbol"; | ||
946 | case P_UNKNOWN: | 1227 | case P_UNKNOWN: |
947 | break; | 1228 | break; |
948 | } | 1229 | } |