diff options
| -rw-r--r-- | scripts/kconfig/menu.c | 10 | ||||
| -rw-r--r-- | scripts/kconfig/symbol.c | 58 | 
2 files changed, 62 insertions, 6 deletions
diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c index 5cfa6c405cf0..c2a423a1c341 100644 --- a/scripts/kconfig/menu.c +++ b/scripts/kconfig/menu.c  | |||
| @@ -151,6 +151,12 @@ void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep) | |||
| 151 | menu_add_prop(type, NULL, expr_alloc_symbol(sym), dep); | 151 | menu_add_prop(type, NULL, expr_alloc_symbol(sym), dep); | 
| 152 | } | 152 | } | 
| 153 | 153 | ||
| 154 | static int menu_range_valid_sym(struct symbol *sym, struct symbol *sym2) | ||
| 155 | { | ||
| 156 | return sym2->type == S_INT || sym2->type == S_HEX || | ||
| 157 | (sym2->type == S_UNKNOWN && sym_string_valid(sym, sym2->name)); | ||
| 158 | } | ||
| 159 | |||
| 154 | void sym_check_prop(struct symbol *sym) | 160 | void sym_check_prop(struct symbol *sym) | 
| 155 | { | 161 | { | 
| 156 | struct property *prop; | 162 | struct property *prop; | 
| @@ -185,8 +191,8 @@ void sym_check_prop(struct symbol *sym) | |||
| 185 | if (sym->type != S_INT && sym->type != S_HEX) | 191 | if (sym->type != S_INT && sym->type != S_HEX) | 
| 186 | prop_warn(prop, "range is only allowed " | 192 | prop_warn(prop, "range is only allowed " | 
| 187 | "for int or hex symbols"); | 193 | "for int or hex symbols"); | 
| 188 | if (!sym_string_valid(sym, prop->expr->left.sym->name) || | 194 | if (!menu_range_valid_sym(sym, prop->expr->left.sym) || | 
| 189 | !sym_string_valid(sym, prop->expr->right.sym->name)) | 195 | !menu_range_valid_sym(sym, prop->expr->right.sym)) | 
| 190 | prop_warn(prop, "range is invalid"); | 196 | prop_warn(prop, "range is invalid"); | 
| 191 | break; | 197 | break; | 
| 192 | default: | 198 | default: | 
diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c index 29bff43adc5e..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); | 
| @@ -489,8 +539,8 @@ bool sym_string_within_range(struct symbol *sym, const char *str) | |||
| 489 | if (!prop) | 539 | if (!prop) | 
| 490 | return true; | 540 | return true; | 
| 491 | val = strtol(str, NULL, 10); | 541 | val = strtol(str, NULL, 10); | 
| 492 | return val >= strtol(prop->expr->left.sym->name, NULL, 10) && | 542 | return val >= sym_get_range_val(prop->expr->left.sym, 10) && | 
| 493 | val <= strtol(prop->expr->right.sym->name, NULL, 10); | 543 | val <= sym_get_range_val(prop->expr->right.sym, 10); | 
| 494 | case S_HEX: | 544 | case S_HEX: | 
| 495 | if (!sym_string_valid(sym, str)) | 545 | if (!sym_string_valid(sym, str)) | 
| 496 | return false; | 546 | return false; | 
| @@ -498,8 +548,8 @@ bool sym_string_within_range(struct symbol *sym, const char *str) | |||
| 498 | if (!prop) | 548 | if (!prop) | 
| 499 | return true; | 549 | return true; | 
| 500 | val = strtol(str, NULL, 16); | 550 | val = strtol(str, NULL, 16); | 
| 501 | return val >= strtol(prop->expr->left.sym->name, NULL, 16) && | 551 | return val >= sym_get_range_val(prop->expr->left.sym, 16) && | 
| 502 | val <= strtol(prop->expr->right.sym->name, NULL, 16); | 552 | val <= sym_get_range_val(prop->expr->right.sym, 16); | 
| 503 | case S_BOOLEAN: | 553 | case S_BOOLEAN: | 
| 504 | case S_TRISTATE: | 554 | case S_TRISTATE: | 
| 505 | switch (str[0]) { | 555 | switch (str[0]) { | 
