Commit e4922a0b authored by Roman Zippel's avatar Roman Zippel Committed by Ben Collins

[PATCH] support for 'range'

The 'range' keyword allows to define a lower and upper limit for integer
and hex symbols.
parent f3b837df
......@@ -224,6 +224,20 @@ int conf_read(const char *name)
fclose(in);
for_all_symbols(i, sym) {
sym_calc_value(sym);
if (sym_has_value(sym)) {
if (sym->visible == no)
sym->flags |= SYMBOL_NEW;
switch (sym->type) {
case S_STRING:
case S_INT:
case S_HEX:
if (!sym_string_within_range(sym, sym->user.val))
sym->flags |= SYMBOL_NEW;
default:
break;
}
}
if (!sym_is_choice(sym))
continue;
prop = sym_get_choice_prop(sym);
......
......@@ -215,6 +215,7 @@ int expr_eq(struct expr *e1, struct expr *e2)
trans_count = old_count;
return res;
case E_CHOICE:
case E_RANGE:
case E_NONE:
/* panic */;
}
......@@ -917,6 +918,7 @@ struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symb
case E_SYMBOL:
return expr_alloc_comp(type, e->left.sym, sym);
case E_CHOICE:
case E_RANGE:
case E_NONE:
/* panic */;
}
......@@ -1043,6 +1045,13 @@ void expr_print(struct expr *e, void (*fn)(void *, const char *), void *data, in
expr_print(e->left.expr, fn, data, E_CHOICE);
}
break;
case E_RANGE:
fn(data, "[");
fn(data, e->left.sym->name);
fn(data, " ");
fn(data, e->right.sym->name);
fn(data, "]");
break;
default:
{
char buf[32];
......
......@@ -32,7 +32,7 @@ typedef enum tristate {
} tristate;
enum expr_type {
E_NONE, E_OR, E_AND, E_NOT, E_EQUAL, E_UNEQUAL, E_CHOICE, E_SYMBOL
E_NONE, E_OR, E_AND, E_NOT, E_EQUAL, E_UNEQUAL, E_CHOICE, E_SYMBOL, E_RANGE
};
union expr_data {
......@@ -98,7 +98,7 @@ struct symbol {
#define SYMBOL_HASHMASK 0xff
enum prop_type {
P_UNKNOWN, P_PROMPT, P_COMMENT, P_MENU, P_DEFAULT, P_CHOICE, P_SELECT
P_UNKNOWN, P_PROMPT, P_COMMENT, P_MENU, P_DEFAULT, P_CHOICE, P_SELECT, P_RANGE
};
struct property {
......
......@@ -25,6 +25,7 @@ P(sym_tristate_within_range,bool,(struct symbol *sym,tristate tri));
P(sym_set_tristate_value,bool,(struct symbol *sym,tristate tri));
P(sym_toggle_tristate_value,tristate,(struct symbol *sym));
P(sym_string_valid,bool,(struct symbol *sym, const char *newval));
P(sym_string_within_range,bool,(struct symbol *sym, const char *str));
P(sym_set_string_value,bool,(struct symbol *sym, const char *newval));
P(sym_is_changable,bool,(struct symbol *sym));
P(sym_get_choice_prop,struct property *,(struct symbol *sym));
......
......@@ -130,6 +130,18 @@ struct property *sym_get_default_prop(struct symbol *sym)
return NULL;
}
struct property *sym_get_range_prop(struct symbol *sym)
{
struct property *prop;
for_all_properties(sym, prop, P_RANGE) {
prop->visible.tri = expr_calc_value(prop->visible.expr);
if (prop->visible.tri != no)
return prop;
}
return NULL;
}
static void sym_calc_visibility(struct symbol *sym)
{
struct property *prop;
......@@ -432,6 +444,46 @@ bool sym_string_valid(struct symbol *sym, const char *str)
} while ((ch = *str++));
return true;
case S_BOOLEAN:
case S_TRISTATE:
switch (str[0]) {
case 'y': case 'Y':
case 'm': case 'M':
case 'n': case 'N':
return true;
}
return false;
default:
return false;
}
}
bool sym_string_within_range(struct symbol *sym, const char *str)
{
struct property *prop;
int val;
switch (sym->type) {
case S_STRING:
return sym_string_valid(sym, str);
case S_INT:
if (!sym_string_valid(sym, str))
return false;
prop = sym_get_range_prop(sym);
if (!prop)
return true;
val = strtol(str, NULL, 10);
return val >= strtol(prop->expr->left.sym->name, NULL, 10) &&
val <= strtol(prop->expr->right.sym->name, NULL, 10);
case S_HEX:
if (!sym_string_valid(sym, str))
return false;
prop = sym_get_range_prop(sym);
if (!prop)
return true;
val = strtol(str, NULL, 16);
return val >= strtol(prop->expr->left.sym->name, NULL, 16) &&
val <= strtol(prop->expr->right.sym->name, NULL, 16);
case S_BOOLEAN:
case S_TRISTATE:
switch (str[0]) {
case 'y': case 'Y':
......@@ -469,7 +521,7 @@ bool sym_set_string_value(struct symbol *sym, const char *newval)
;
}
if (!sym_string_valid(sym, newval))
if (!sym_string_within_range(sym, newval))
return false;
if (sym->flags & SYMBOL_NEW) {
......@@ -644,6 +696,8 @@ const char *prop_get_type_name(enum prop_type type)
return "choice";
case P_SELECT:
return "select";
case P_RANGE:
return "range";
case P_UNKNOWN:
break;
}
......
......@@ -1414,6 +1414,7 @@ yyreduce:
case 37:
{
menu_add_expr(P_RANGE, expr_alloc_comp(E_RANGE,yyvsp[-3].symbol, yyvsp[-2].symbol), yyvsp[-1].expr);
printd(DEBUG_PARSE, "%s:%d:range\n", zconf_curname(), zconf_lineno());
;}
break;
......
......@@ -221,6 +221,7 @@ config_option: T_SELECT T_WORD if_expr T_EOL
config_option: T_RANGE symbol symbol if_expr T_EOL
{
menu_add_expr(P_RANGE, expr_alloc_comp(E_RANGE,$2, $3), $4);
printd(DEBUG_PARSE, "%s:%d:range\n", zconf_curname(), zconf_lineno());
};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment