diff options
author | Rob Landley <rob@landley.net> | 2016-03-20 20:39:27 -0500 |
---|---|---|
committer | Rob Landley <rob@landley.net> | 2016-03-20 20:39:27 -0500 |
commit | 6aba814b28cddd45c7301c39dccd65b316eb5c82 (patch) | |
tree | b9061ca0c52407c3d8c18f80e521e1dd4db3357c /toys | |
parent | 4de04e83d7ff621062b8b5456a14f2f313a2639c (diff) | |
download | toybox-6aba814b28cddd45c7301c39dccd65b316eb5c82.tar.gz |
Posix requires "" to be false, and 00 should be false, and -0 should be false.
Fix memory leaks in regex. Simplify regex check (if we matched, subexpression
had to match). Don't exit() from a command, set exitval and return.
Diffstat (limited to 'toys')
-rw-r--r-- | toys/pending/expr.c | 28 |
1 files changed, 17 insertions, 11 deletions
diff --git a/toys/pending/expr.c b/toys/pending/expr.c index 25aa3cd6..743a9536 100644 --- a/toys/pending/expr.c +++ b/toys/pending/expr.c @@ -58,6 +58,8 @@ config EXPR GLOBALS( char **tok; // current token, not on the stack since recursive calls mutate it + + char *refree; ) // Scalar value. If s != NULL, it's a string, otherwise it's an int. @@ -97,8 +99,7 @@ void assign_int(struct value *v, long long i) // Check if v is 0 or the empty string. static int is_false(struct value *v) { - if (v->s) return !*v->s || !strcmp(v->s, "0"); // get_int("0") -> 0 - return !v->i; + return get_int(v, &v->i) && !v->i; } // 'ret' is filled with a string capture or int match position. @@ -108,16 +109,19 @@ static void re(char *target, char *pattern, struct value *ret) regmatch_t m[2]; xregcomp(&pat, pattern, 0); - if (!regexec(&pat, target, 2, m, 0) && m[0].rm_so == 0) { // match at pos 0 - regmatch_t *g1 = &m[1]; // group capture 1 - if (pat.re_nsub > 0 && g1->rm_so >= 0) // has capture - ret->s = xmprintf("%.*s", g1->rm_eo - g1->rm_so, target + g1->rm_so); - else assign_int(ret, m[0].rm_eo); - } else { // no match - // has capture - if (pat.re_nsub > 0) ret->s = ""; + // must match at pos 0 + if (!regexec(&pat, target, 2, m, 0) && !m[0].rm_so) { + // Return first parenthesized subexpression as string, or length of match + if (pat.re_nsub>0) { + ret->s = xmprintf("%.*s", m[1].rm_eo-m[1].rm_so, target+m[1].rm_so); + if (TT.refree) free(TT.refree); + TT.refree = ret->s; + } else assign_int(ret, m[0].rm_eo); + } else { + if (pat.re_nsub>0) ret->s = ""; else assign_int(ret, 0); } + regfree(&pat); } // 4 different signatures of operators. S = string, I = int, SI = string or @@ -250,5 +254,7 @@ void expr_main(void) if (ret.s) printf("%s\n", ret.s); else printf("%lld\n", ret.i); - exit(is_false(&ret)); + toys.exitval = is_false(&ret); + + if (TT.refree) free(TT.refree); } |