conf: improve simple integer math expressions - brackets

Add brackets to the simple math expressions like:

  $[($a+($val+100))/2]

Signed-off-by: Jaroslav Kysela <perex@perex.cz>
This commit is contained in:
Jaroslav Kysela 2021-11-30 14:32:58 +01:00
parent 7b6da9ee6d
commit 9b53b1f0fb
2 changed files with 19 additions and 9 deletions

View file

@ -40,13 +40,13 @@
typedef long long value_type_t; typedef long long value_type_t;
static const char *_find_end_of_expression(const char *s) static const char *_find_end_of_expression(const char *s, char begin, char end)
{ {
int count = 1; int count = 1;
while (*s) { while (*s) {
if (*s == '[') { if (*s == begin) {
count++; count++;
} else if (*s == ']') { } else if (*s == end) {
count--; count--;
if (count == 0) if (count == 0)
return s + 1; return s + 1;
@ -126,7 +126,7 @@ int _snd_eval_string(snd_config_t **dst, const char *s,
const char *save, *e; const char *save, *e;
char *m; char *m;
value_type_t left, right; value_type_t left, right;
int err, c, op; int err, c, op, off;
enum { enum {
LEFT, LEFT,
OP, OP,
@ -164,16 +164,22 @@ int _snd_eval_string(snd_config_t **dst, const char *s,
s++; s++;
continue; continue;
} }
if (c == '$') { if (c == '(') {
e = _find_end_of_expression(s + 1, '(', ')');
off = 1;
goto _expr;
} else if (c == '$') {
if (s[1] == '[') { if (s[1] == '[') {
e = _find_end_of_expression(s + 2); e = _find_end_of_expression(s + 2, '[', ']');
off = 2;
_expr:
if (e == NULL) if (e == NULL)
return -EINVAL; return -EINVAL;
m = malloc(e - s - 1); m = malloc(e - s - (off - 1));
if (m == NULL) if (m == NULL)
return -ENOMEM; return -ENOMEM;
memcpy(m, s + 2, e - s - 2); memcpy(m, s + off, e - s - off);
m[e - s - 3] = '\0'; m[e - s - (off + 1)] = '\0';
err = _snd_eval_string(&tmp, m, fcn, private_data); err = _snd_eval_string(&tmp, m, fcn, private_data);
free(m); free(m);
if (err < 0) if (err < 0)
@ -203,6 +209,8 @@ int _snd_eval_string(snd_config_t **dst, const char *s,
snd_config_delete(tmp); snd_config_delete(tmp);
} else if (c == '-' || (c >= '0' && c <= '9')) { } else if (c == '-' || (c >= '0' && c <= '9')) {
err = _parse_integer(op == LEFT ? &left : &right, &s); err = _parse_integer(op == LEFT ? &left : &right, &s);
} else {
return -EINVAL;
} }
if (err < 0) if (err < 0)
return err; return err;

View file

@ -574,8 +574,10 @@ static void test_evaluate_string(void)
{ .expr = "$[0xff&0xfc]", .result = 0xfc }, { .expr = "$[0xff&0xfc]", .result = 0xfc },
{ .expr = "$[4294967296+10]", .result = 4294967306LL }, { .expr = "$[4294967296+10]", .result = 4294967306LL },
{ .expr = "$[$var10+1]", .result = 11 }, { .expr = "$[$var10+1]", .result = 11 },
{ .expr = "$[1+1+1]", .result = 11 },
{ .expr = "$[$var10 + $var50]", .result = 60 }, { .expr = "$[$var10 + $var50]", .result = 60 },
{ .expr = "$[ $var10 + $[ $var50 + 10 ] ]", .result = 70 }, { .expr = "$[ $var10 + $[ $var50 + 10 ] ]", .result = 70 },
{ .expr = "$[ ( $var10 + ( $var50 + 112 ) ) + 5 ]", .result = 177 },
{ .expr = NULL, .result = 0 }, { .expr = NULL, .result = 0 },
}; };
snd_config_t *dst; snd_config_t *dst;