diff options
Diffstat (limited to 'scripts/kconfig/symbol.c')
-rw-r--r-- | scripts/kconfig/symbol.c | 80 |
1 files changed, 73 insertions, 7 deletions
diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c index affa52f5c651..69c2549c0baa 100644 --- a/scripts/kconfig/symbol.c +++ b/scripts/kconfig/symbol.c | |||
@@ -141,6 +141,55 @@ struct property *sym_get_range_prop(struct symbol *sym) | |||
141 | return NULL; | 141 | return NULL; |
142 | } | 142 | } |
143 | 143 | ||
144 | static int sym_get_range_val(struct symbol *sym, int base) | ||
145 | { | ||
146 | sym_calc_value(sym); | ||
147 | switch (sym->type) { | ||
148 | case S_INT: | ||
149 | base = 10; | ||
150 | break; | ||
151 | case S_HEX: | ||
152 | base = 16; | ||
153 | break; | ||
154 | default: | ||
155 | break; | ||
156 | } | ||
157 | return strtol(sym->curr.val, NULL, base); | ||
158 | } | ||
159 | |||
160 | static void sym_validate_range(struct symbol *sym) | ||
161 | { | ||
162 | struct property *prop; | ||
163 | int base, val, val2; | ||
164 | char str[64]; | ||
165 | |||
166 | switch (sym->type) { | ||
167 | case S_INT: | ||
168 | base = 10; | ||
169 | break; | ||
170 | case S_HEX: | ||
171 | base = 16; | ||
172 | break; | ||
173 | default: | ||
174 | return; | ||
175 | } | ||
176 | prop = sym_get_range_prop(sym); | ||
177 | if (!prop) | ||
178 | return; | ||
179 | val = strtol(sym->curr.val, NULL, base); | ||
180 | val2 = sym_get_range_val(prop->expr->left.sym, base); | ||
181 | if (val >= val2) { | ||
182 | val2 = sym_get_range_val(prop->expr->right.sym, base); | ||
183 | if (val <= val2) | ||
184 | return; | ||
185 | } | ||
186 | if (sym->type == S_INT) | ||
187 | sprintf(str, "%d", val2); | ||
188 | else | ||
189 | sprintf(str, "0x%x", val2); | ||
190 | sym->curr.val = strdup(str); | ||
191 | } | ||
192 | |||
144 | static void sym_calc_visibility(struct symbol *sym) | 193 | static void sym_calc_visibility(struct symbol *sym) |
145 | { | 194 | { |
146 | struct property *prop; | 195 | struct property *prop; |
@@ -301,6 +350,7 @@ void sym_calc_value(struct symbol *sym) | |||
301 | sym->curr = newval; | 350 | sym->curr = newval; |
302 | if (sym_is_choice(sym) && newval.tri == yes) | 351 | if (sym_is_choice(sym) && newval.tri == yes) |
303 | sym->curr.val = sym_calc_choice(sym); | 352 | sym->curr.val = sym_calc_choice(sym); |
353 | sym_validate_range(sym); | ||
304 | 354 | ||
305 | if (memcmp(&oldval, &sym->curr, sizeof(oldval))) | 355 | if (memcmp(&oldval, &sym->curr, sizeof(oldval))) |
306 | sym_set_changed(sym); | 356 | sym_set_changed(sym); |
@@ -380,11 +430,22 @@ bool sym_set_tristate_value(struct symbol *sym, tristate val) | |||
380 | sym->flags &= ~SYMBOL_NEW; | 430 | sym->flags &= ~SYMBOL_NEW; |
381 | sym_set_changed(sym); | 431 | sym_set_changed(sym); |
382 | } | 432 | } |
433 | /* | ||
434 | * setting a choice value also resets the new flag of the choice | ||
435 | * symbol and all other choice values. | ||
436 | */ | ||
383 | if (sym_is_choice_value(sym) && val == yes) { | 437 | if (sym_is_choice_value(sym) && val == yes) { |
384 | struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym)); | 438 | struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym)); |
439 | struct property *prop; | ||
440 | struct expr *e; | ||
385 | 441 | ||
386 | cs->user.val = sym; | 442 | cs->user.val = sym; |
387 | cs->flags &= ~SYMBOL_NEW; | 443 | cs->flags &= ~SYMBOL_NEW; |
444 | prop = sym_get_choice_prop(cs); | ||
445 | for (e = prop->expr; e; e = e->left.expr) { | ||
446 | if (e->right.sym->visible != no) | ||
447 | e->right.sym->flags &= ~SYMBOL_NEW; | ||
448 | } | ||
388 | } | 449 | } |
389 | 450 | ||
390 | sym->user.tri = val; | 451 | sym->user.tri = val; |
@@ -478,8 +539,8 @@ bool sym_string_within_range(struct symbol *sym, const char *str) | |||
478 | if (!prop) | 539 | if (!prop) |
479 | return true; | 540 | return true; |
480 | val = strtol(str, NULL, 10); | 541 | val = strtol(str, NULL, 10); |
481 | return val >= strtol(prop->expr->left.sym->name, NULL, 10) && | 542 | return val >= sym_get_range_val(prop->expr->left.sym, 10) && |
482 | val <= strtol(prop->expr->right.sym->name, NULL, 10); | 543 | val <= sym_get_range_val(prop->expr->right.sym, 10); |
483 | case S_HEX: | 544 | case S_HEX: |
484 | if (!sym_string_valid(sym, str)) | 545 | if (!sym_string_valid(sym, str)) |
485 | return false; | 546 | return false; |
@@ -487,8 +548,8 @@ bool sym_string_within_range(struct symbol *sym, const char *str) | |||
487 | if (!prop) | 548 | if (!prop) |
488 | return true; | 549 | return true; |
489 | val = strtol(str, NULL, 16); | 550 | val = strtol(str, NULL, 16); |
490 | return val >= strtol(prop->expr->left.sym->name, NULL, 16) && | 551 | return val >= sym_get_range_val(prop->expr->left.sym, 16) && |
491 | val <= strtol(prop->expr->right.sym->name, NULL, 16); | 552 | val <= sym_get_range_val(prop->expr->right.sym, 16); |
492 | case S_BOOLEAN: | 553 | case S_BOOLEAN: |
493 | case S_TRISTATE: | 554 | case S_TRISTATE: |
494 | switch (str[0]) { | 555 | switch (str[0]) { |
@@ -731,12 +792,12 @@ struct symbol *sym_check_deps(struct symbol *sym) | |||
731 | struct symbol *sym2; | 792 | struct symbol *sym2; |
732 | struct property *prop; | 793 | struct property *prop; |
733 | 794 | ||
734 | if (sym->flags & SYMBOL_CHECK_DONE) | ||
735 | return NULL; | ||
736 | if (sym->flags & SYMBOL_CHECK) { | 795 | if (sym->flags & SYMBOL_CHECK) { |
737 | printf("Warning! Found recursive dependency: %s", sym->name); | 796 | printf("Warning! Found recursive dependency: %s", sym->name); |
738 | return sym; | 797 | return sym; |
739 | } | 798 | } |
799 | if (sym->flags & SYMBOL_CHECKED) | ||
800 | return NULL; | ||
740 | 801 | ||
741 | sym->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED); | 802 | sym->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED); |
742 | sym2 = sym_check_expr_deps(sym->rev_dep.expr); | 803 | sym2 = sym_check_expr_deps(sym->rev_dep.expr); |
@@ -756,8 +817,13 @@ struct symbol *sym_check_deps(struct symbol *sym) | |||
756 | goto out; | 817 | goto out; |
757 | } | 818 | } |
758 | out: | 819 | out: |
759 | if (sym2) | 820 | if (sym2) { |
760 | printf(" %s", sym->name); | 821 | printf(" %s", sym->name); |
822 | if (sym2 == sym) { | ||
823 | printf("\n"); | ||
824 | sym2 = NULL; | ||
825 | } | ||
826 | } | ||
761 | sym->flags &= ~SYMBOL_CHECK; | 827 | sym->flags &= ~SYMBOL_CHECK; |
762 | return sym2; | 828 | return sym2; |
763 | } | 829 | } |