Add shorthand macros for some conventient Lua string operations

Despite all the Lua magic we already do, it's annoyingly often the case
that shelling out is easier (or at least shorter) than doing the same in
Lua (substrings, length etc)

Add shorthand macros %gsub, %len, %lower, %rep, %reverse, %sub and
%upper which simply wrap the corresponding Lua string.* functions for
convenience.
This commit is contained in:
Panu Matilainen 2022-09-12 10:53:00 +03:00
parent f78be76a00
commit cad5affacd
7 changed files with 81 additions and 8 deletions

View File

@ -84,6 +84,15 @@ to perform useful operations. The current list is
%{macrobody:...} literal body of a macro %{macrobody:...} literal body of a macro
%{gsub:...} replace occurences of pattern in a string
(see Lua `string.gsub()`)
%{len:...} string length
%{lower:...} lowercase a string
%{rep:...} repeat a string (see Lua `string.rep()`)
%{reverse:...} reverse a string
%{sub:...} expand to substring (see Lua `string.sub()`)
%{upper:...} uppercase a string
%{basename:...} basename(1) macro analogue %{basename:...} basename(1) macro analogue
%{dirname:...} dirname(1) macro analogue %{dirname:...} dirname(1) macro analogue
%{exists:...} test file existence, expands to 1/0 %{exists:...} test file existence, expands to 1/0

View File

@ -1096,6 +1096,30 @@ static void doLua(MacroBuf mb, rpmMacroEntry me, ARGV_t argv, size_t *parsed)
} }
} }
/*
* Wrap a call to Lua string functions.
* Note extra parentheses to force only one result returned, multi-value
* returns such as from string.gsub() make no sense in this context.
*/
static void doString(MacroBuf mb, rpmMacroEntry me, ARGV_t argv, size_t *parsed)
{
rpmlua lua = NULL; /* Global state. */
char *printbuf = NULL;
char *s = rstrscat(NULL,
"return (string.", argv[0], "(table.unpack(arg)))", NULL);
rpmluaPushPrintBuffer(lua);
if (rpmluaRunScript(lua, s, argv[0], NULL, argv+1) == -1)
mb->error = 1;
printbuf = rpmluaPopPrintBuffer(lua);
if (printbuf) {
mbAppendStr(mb, printbuf);
free(printbuf);
}
free(s);
}
static void doSP(MacroBuf mb, rpmMacroEntry me, ARGV_t argv, size_t *parsed) static void doSP(MacroBuf mb, rpmMacroEntry me, ARGV_t argv, size_t *parsed)
{ {
char *s = NULL; char *s = NULL;
@ -1245,17 +1269,24 @@ static struct builtins_s {
{ "getenv", doFoo, 1, 0 }, { "getenv", doFoo, 1, 0 },
{ "getncpus", doFoo, 0, 0 }, { "getncpus", doFoo, 0, 0 },
{ "global", doGlobal, 1, ME_PARSE }, { "global", doGlobal, 1, ME_PARSE },
{ "gsub", doString, 1, 0 },
{ "len", doString, 1, 0 },
{ "load", doLoad, 1, 0 }, { "load", doLoad, 1, 0 },
{ "lower", doString, 1, 0 },
{ "lua", doLua, 1, ME_PARSE }, { "lua", doLua, 1, ME_PARSE },
{ "macrobody", doBody, 1, 0 }, { "macrobody", doBody, 1, 0 },
{ "quote", doFoo, 1, 0 }, { "quote", doFoo, 1, 0 },
{ "rep", doString, 1, 0 },
{ "reverse", doString, 1, 0 },
{ "shrink", doFoo, 1, 0 }, { "shrink", doFoo, 1, 0 },
{ "sub", doString, 1, 0 },
{ "suffix", doFoo, 1, 0 }, { "suffix", doFoo, 1, 0 },
{ "trace", doTrace, 0, 0 }, { "trace", doTrace, 0, 0 },
{ "u2p", doFoo, 1, 0 }, { "u2p", doFoo, 1, 0 },
{ "shescape", doShescape, 1, 0 }, { "shescape", doShescape, 1, 0 },
{ "uncompress", doUncompress, 1, 0 }, { "uncompress", doUncompress, 1, 0 },
{ "undefine", doUndefine, 1, 0 }, { "undefine", doUndefine, 1, 0 },
{ "upper", doString, 1, 0 },
{ "url2path", doFoo, 1, 0 }, { "url2path", doFoo, 1, 0 },
{ "verbose", doVerbose, -1, ME_PARSE }, { "verbose", doVerbose, -1, ME_PARSE },
{ "warn", doOutput, 1, 0 }, { "warn", doOutput, 1, 0 },

View File

@ -3,7 +3,7 @@
%{!?filetype: %global filetype file} %{!?filetype: %global filetype file}
Name: configtest%{?sub:-%{sub}} Name: configtest%{?subpkg:-%{subpkg}}
Version: %{ver} Version: %{ver}
Release: 1 Release: 1
Summary: Testing config file behavior Summary: Testing config file behavior

View File

@ -3,7 +3,7 @@
%{!?user: %global user root} %{!?user: %global user root}
%{!?grp: %global grp root} %{!?grp: %global grp root}
Name: replacetest%{?sub:-%{sub}} Name: replacetest%{?subpkg:-%{subpkg}}
Version: %{ver} Version: %{ver}
Release: 1 Release: 1
Summary: Testing file replacement behavior Summary: Testing file replacement behavior

View File

@ -402,7 +402,7 @@ RPMDB_INIT
for s in "A" "B"; do for s in "A" "B"; do
for v in "1.0" "2.0"; do for v in "1.0" "2.0"; do
runroot rpmbuild --quiet -bb \ runroot rpmbuild --quiet -bb \
--define "sub $s" \ --define "subpkg $s" \
--define "ver $v" \ --define "ver $v" \
--define "filedata foo" \ --define "filedata foo" \
/data/SPECS/configtest.spec /data/SPECS/configtest.spec
@ -462,7 +462,7 @@ RPMDB_INIT
for s in "A" "B"; do for s in "A" "B"; do
for v in "1.0" "2.0"; do for v in "1.0" "2.0"; do
runroot rpmbuild --quiet -bb \ runroot rpmbuild --quiet -bb \
--define "sub $s" \ --define "subpkg $s" \
--define "ver $v" \ --define "ver $v" \
--define "filedata foo-$v" \ --define "filedata foo-$v" \
/data/SPECS/configtest.spec /data/SPECS/configtest.spec
@ -552,7 +552,7 @@ RPMDB_INIT
for s in "A" "B"; do for s in "A" "B"; do
for v in "1.0" "2.0"; do for v in "1.0" "2.0"; do
runroot rpmbuild --quiet -bb \ runroot rpmbuild --quiet -bb \
--define "sub $s" \ --define "subpkg $s" \
--define "ver $v" \ --define "ver $v" \
--define "filedata foo-$v" \ --define "filedata foo-$v" \
--define "noreplace 1" \ --define "noreplace 1" \

View File

@ -352,7 +352,7 @@ RPMDB_INIT
for s in "A" "B"; do for s in "A" "B"; do
for v in "1.0" "2.0"; do for v in "1.0" "2.0"; do
runroot rpmbuild --quiet -bb \ runroot rpmbuild --quiet -bb \
--define "sub $s" \ --define "subpkg $s" \
--define "ver $v" \ --define "ver $v" \
--define "filedata foo" \ --define "filedata foo" \
--define "filetype link" \ --define "filetype link" \
@ -414,7 +414,7 @@ RPMDB_INIT
for s in "A" "B"; do for s in "A" "B"; do
for v in "1.0" "2.0"; do for v in "1.0" "2.0"; do
runroot rpmbuild --quiet -bb \ runroot rpmbuild --quiet -bb \
--define "sub $s" \ --define "subpkg $s" \
--define "ver $v" \ --define "ver $v" \
--define "filedata foo-$v" \ --define "filedata foo-$v" \
--define "filetype link" \ --define "filetype link" \
@ -504,7 +504,7 @@ RPMDB_INIT
for s in "A" "B"; do for s in "A" "B"; do
for v in "1.0" "2.0"; do for v in "1.0" "2.0"; do
runroot rpmbuild --quiet -bb \ runroot rpmbuild --quiet -bb \
--define "sub $s" \ --define "subpkg $s" \
--define "ver $v" \ --define "ver $v" \
--define "filedata foo-$v" \ --define "filedata foo-$v" \
--define "filetype link" \ --define "filetype link" \

View File

@ -387,6 +387,39 @@ runroot rpm \
]) ])
AT_CLEANUP AT_CLEANUP
AT_SETUP([string functions])
AT_KEYWORDS([macros])
AT_CHECK([
runroot rpm \
--eval "%sub cd6317ba61e6c27b92d6bbdf2702094ff3c0c732 1 7" \
--eval "%sub cd6317ba61e6c27b92d6bbdf2702094ff3c0c732 7 -7" \
--eval "%sub cd6317ba61e6c27b92d6bbdf2702094ff3c0c732 -7" \
--eval "%len cd6317ba61e6c27b92d6bbdf2702094ff3c0c732" \
--eval "%upper abba" \
--eval "%lower Beatles" \
--eval "%rep ai 2" \
--eval "%reverse live" \
--eval "%reverse a'b" \
--eval "%reverse a\"b" \
--eval "%gsub aaa a b 2"
],
[0],
[cd6317b
ba61e6c27b92d6bbdf2702094ff3
3c0c732
40
ABBA
beatles
aiai
evil
b'a
b"a
bba
],
[])
AT_CLEANUP
AT_SETUP([expr macro 1]) AT_SETUP([expr macro 1])
AT_KEYWORDS([macros]) AT_KEYWORDS([macros])
AT_CHECK([ AT_CHECK([