]> git.alsa-project.org Git - alsa-lib.git/commitdiff
conf: improve simple integer math expressions - brackets
authorJaroslav Kysela <perex@perex.cz>
Tue, 30 Nov 2021 13:32:58 +0000 (14:32 +0100)
committerJaroslav Kysela <perex@perex.cz>
Tue, 30 Nov 2021 13:35:58 +0000 (14:35 +0100)
Add brackets to the simple math expressions like:

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

Signed-off-by: Jaroslav Kysela <perex@perex.cz>
src/confeval.c
test/lsb/config.c

index c8d36f1ef35952f260ef862156ac47b75d4ee721..180310f5e46ab99b7d1d5357a2a97e36c4ba1e93 100644 (file)
 
 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;
        while (*s) {
-               if (*s == '[') {
+               if (*s == begin) {
                        count++;
-               } else if (*s == ']') {
+               } else if (*s == end) {
                        count--;
                        if (count == 0)
                                return s + 1;
@@ -126,7 +126,7 @@ int _snd_eval_string(snd_config_t **dst, const char *s,
        const char *save, *e;
        char *m;
        value_type_t left, right;
-       int err, c, op;
+       int err, c, op, off;
        enum {
                LEFT,
                OP,
@@ -164,16 +164,22 @@ int _snd_eval_string(snd_config_t **dst, const char *s,
                        s++;
                        continue;
                }
-               if (c == '$') {
+               if (c == '(') {
+                       e = _find_end_of_expression(s + 1, '(', ')');
+                       off = 1;
+                       goto _expr;
+               } else if (c == '$') {
                        if (s[1] == '[') {
-                               e = _find_end_of_expression(s + 2);
+                               e = _find_end_of_expression(s + 2, '[', ']');
+                               off = 2;
+  _expr:
                                if (e == NULL)
                                        return -EINVAL;
-                               m = malloc(e - s - 1);
+                               m = malloc(e - s - (off - 1));
                                if (m == NULL)
                                        return -ENOMEM;
-                               memcpy(m, s + 2, e - s - 2);
-                               m[e - s - 3] = '\0';
+                               memcpy(m, s + off, e - s - off);
+                               m[e - s - (off + 1)] = '\0';
                                err = _snd_eval_string(&tmp, m, fcn, private_data);
                                free(m);
                                if (err < 0)
@@ -203,6 +209,8 @@ int _snd_eval_string(snd_config_t **dst, const char *s,
                        snd_config_delete(tmp);
                } else if (c == '-' || (c >= '0' && c <= '9')) {
                        err = _parse_integer(op == LEFT ? &left : &right, &s);
+               } else {
+                       return -EINVAL;
                }
                if (err < 0)
                        return err;
index c57f441d33b26bf6bc958ac6f7d715dfcc0325f5..0ff1d9f81c71d01e1347d3cccbbadcebaddd4275 100644 (file)
@@ -574,8 +574,10 @@ static void test_evaluate_string(void)
                { .expr = "$[0xff&0xfc]", .result = 0xfc },
                { .expr = "$[4294967296+10]", .result = 4294967306LL },
                { .expr = "$[$var10+1]", .result = 11 },
+               { .expr = "$[1+1+1]", .result = 11 },
                { .expr = "$[$var10 + $var50]", .result = 60 },
                { .expr = "$[ $var10 + $[ $var50 + 10 ] ]", .result = 70 },
+               { .expr = "$[ ( $var10 + ( $var50 + 112 ) ) + 5 ]", .result = 177 },
                { .expr = NULL, .result = 0 },
        };
        snd_config_t *dst;