Add %{expr:...} macro for parsing expressions

Supports the same expressions as spec %if conditions because, well,
it's the same expression parser. Only this returns the result as
a string instead of a boolean.
This commit is contained in:
Panu Matilainen 2019-08-21 13:59:04 +03:00
parent 4fc0370c56
commit 3a6a7cf691
3 changed files with 49 additions and 0 deletions

View File

@ -93,6 +93,7 @@ to perform useful operations. The current list is
%{load:...} load a macro file
%{lua:...} expand using the embedded Lua interpreter
%{expand:...} like eval, expand ... to <body> and (re-)expand <body>
%{expr:...} evaluate an expression
%{shrink:...} trim leading and trailing whitespace, reduce
intermediate whitespace to a single space
%{quote:...} quote a parametric macro argument, needed to pass

View File

@ -539,6 +539,7 @@ static struct builtins_s {
{ STR_AND_LEN("echo"), doOutput, NULL },
{ STR_AND_LEN("error"), doOutput, NULL },
{ STR_AND_LEN("expand"), doFoo, NULL },
{ STR_AND_LEN("expr"), doFoo, NULL },
{ STR_AND_LEN("getconfdir"),doFoo, NULL },
{ STR_AND_LEN("getenv"), doFoo, NULL },
{ STR_AND_LEN("getncpus"), doFoo, NULL },
@ -1101,6 +1102,14 @@ doFoo(MacroBuf mb, int chkexist, int negate, const char * f, size_t fn,
b++;
} else if (STREQ("expand", f, fn) || STREQ("verbose", f, fn)) {
b = buf;
} else if (STREQ("expr", f, fn)) {
char *expr = rpmExprStr(buf);
if (expr) {
free(buf);
b = buf = expr;
} else {
mb->error = 1;
}
} else if (STREQ("url2path", f, fn) || STREQ("u2p", f, fn)) {
(void)urlPath(buf, (const char **)&b);
if (*b == '\0') b = "/";

View File

@ -245,6 +245,45 @@ runroot rpm \
])
AT_CLEANUP
AT_SETUP([expr macro 1])
AT_KEYWORDS([macros])
AT_CHECK([
runroot rpm \
--define "aaa 5" \
--define "bbb 0" \
--eval '%{expr:4*1024}' \
--eval '%{expr:5 < 1}' \
--eval '%{expr:(4 + 5) * 2 == 18}' \
--eval '%{expr:%{aaa} || %{bbb}}' \
--eval '%{expr:%{aaa} && %{bbb}}'
],
[0],
[4096
0
1
1
0
],
[])
AT_CLEANUP
AT_SETUP([expr macro 2])
AT_KEYWORDS([macros])
AT_CHECK([
runroot rpm --eval '%{expr:a*1}'
runroot rpm --eval '%{expr:(5+1)*4)}'
runroot rpm --eval '%{expr:a=!b}'
],
[1],
[],
[error: types must match: a*1
error: syntax error in expression: (5+1)*4)
error: ^
error: syntax error while parsing ==: a=!b
error: ^
])
AT_CLEANUP
AT_SETUP([shell expansion])
AT_KEYWORDS([macros])
AT_CHECK([