No functional changes here, but going forward this gives us more
flexibility than the ME_HAVEARG. We could also extend this to support
mandatory arguments to user defined macros too.
Now that both types use identical function signature, we can trivially
unify the calling code for both, simplifying things somewhat, make
the non-braced syntax for built-in macros work, and regain type safety.
No functional changes here and not sure if/how these would ever take
multiple arguments, but there's another treasure at the end of
this particular rainbow...
Accept both %{foo:arg} and %{foo arg} notation for both builtins
and user-defined parametric macros, the former only ever has one
argument whereas the latter can have multiple.
"parse" type builtins such as %define are trickier and only work with
traditional syntax for now.
Only define builtin %{lua:...} if actually compiled with the support.
This loses the "informative" error message about the situation but
I think ability to test feature presence is more useful and important.
%{load:...} supported strange conditional syntaxes that conflict
with general macro syntax. Drop support for these undocumented
variants, people can use %{exists:...} to test for file existence
before trying to load a macro file.
%{verbose:...} supported a special syntax of negation with %{!verbose}
but this conflicts with general macro syntax. Now that we have
expressions we can easily handle arbitrary conditions using generic
syntax but %verbose semantics need to change for that: lose the argument
and just return a simple boolean reflecting whether rpm is in verbose
mode or not.
This is obviously an incompatible change, but few things outside rpm itself
should care about this anyhow.
Update the sole user (build scriptlets) to use an expression instead
(whee, the first actual in-tree user!), documentation and testcases
accordingly.
No intended functional changes, but it's one argument less to pass
around, brings builtins one step closer to how user defined
macros are called and is a step towards supporting options to
builtins as well.
Add the necessary infra to pass and carry a function pointer in the macro
entry, define builtins as part of macro initialization and switch
the main expansion loop to use the macro entry info instead of special
builtin lookup.
This has various nice benefits, such as allowing simple testing whether
rpm supports a given primitive by testing whether said macro is defined
and a small performance boost as an extra lookup for the builtins is
eliminated from all macro expansion cycles.
It also paves way for later implementing various spec constructs as
actual macros instead of the confusing pseudo-macros they are now.
Apart from builtins showing up as defined and macro initialization now
being mandatory, this is not supposed to change any concrete behavior.
Even if macrofiles is NULL we (may) have other initialization tasks
to do, always grab the context lock and mind segfaulting when loading
files if macrofiles is NULL.
Compacts things a bit and allows for more flexibility later on,
unfortunately at the price of losing type safety. No functinal changes,
just paving way for next steps.
Add a mbInit() function that allocates the buffer, increases the
expansion depth and stashes some values into a MacroExpansionData area.
Add a mbFini() function that decreases the depth again,
restores the values and optionally prints the expansion result.
As of Doxygen >= 1.8.20 it started complaining about anything marked
as @retval being undocumented. As this is widely used in rpm...
Mass-replace all @retval uses with @param[out] to silence. Some of
these are actually in/out parameters but combing through all of them
is a bit too much...
Also escape <CR><LF> in rpmpgp.h to shut up yet another new warning.
If there was a \ at the end of the buffer, the code would
return a pointer after the trailing \0 leading to unallocated
memory access and weird results in some cases.
See commit 817959609b.
macro.c: In function ‘mbopt’:
macro.c:895:19: warning: unused variable ‘me’ [-Wunused-variable]
895 | rpmMacroEntry me = mb->me;
| ^~
rpmlua.c: In function ‘fd_seek’:
rpmlua.c:985:22: warning: unused variable ‘mode’ [-Wunused-variable]
985 | static const int mode[] = {SEEK_SET, SEEK_CUR, SEEK_END};
| ^~~~
The former is actually unused, the latter should be used.
Avoids code duplication (glibc quirks and whatnot) between macro and lua
option parsing, isolate the global opt* variable accesses to one spot.
Makes it easier to ensure identical behavior between the users if/when
something changes.
No behavior changes intended.
This seems to be the intention of the code but it did
not work because macro parsing was resumed at the wrong
point of the input string. Without this commit, "%{}"
expanded to "%" instead of "%{}".
We already have the macro arguments in an ARGV that's suitable for
passing to Lua, just store it in the macro buffer for passing around.
As macros can nest arbitrarily, we need to store and restore the mb
args which is a bit hacky, but much less trouble than changing all the
related functions to pass argound an argv which only one function
ever uses. Ditto with the macro entry itself, which is needed to pass
around the options (and name, and maybe something else too later).
Besides all the normal rpm defined macros for arguments and options,
parametric Lua macros now get pre-processed options and arguments
in native local tables "opt" and "arg" for much more pleasant access.
"opt" and "arg" tables are always there even if no options or arguments
were passed, this avoids having to deal with multiple cases and test
for nil's all over the place.
Fixes: #1092
Add support for passing getopt options and arguments to natively to Lua
scriptlets via the internal API. The processed opts and args are stored
in two chunk local two tables, options keyed by the letter and arguments
by their numeric index.
Update call sites accordingly, but no actual functionality changes here,
just pre-requisites for next steps.
Commit cb4e5e755a added flags arguments
to rpmExprBool() and rpmExprStr(), but unfortunately rpm 4.15 sailed
with flagless versions them. It's extremely unlikely that anything out
there is actually using these, but then you never really know.
Rpm soname bumps are so inconvenient that we really do not want to do
that just for these two, so preserve binary compatibility and restore
flagless variants of both, adjust internal code to use flagged versions
always. If only we had symbol versioning, sigh.
Whether a macro is defined can be tested with eg rpmExpandNumeric()
but this is somewhat cumbersome and expensive for such a simple thing.
Prior to this, there was no way to find out whether a macro is
parametric (aka parameterized) or not.
%{expand:...} is a rather special built-in as its *purpose* is to
double-expand its argument, so it makes sense to separate it from
the others.
No functional changes intended here.
%{uncompress:...} is fairly complicated as far as builtin macros go:
it needs to first expand its argument to discover the actual file
its supposed to look at, then determine whether the file exists and
what sort of compression to use, then determine the macro to use
for decompressing that kind of file, expand said macro and finally
catenate the expanded argument to the lot. That's a lot of goo to
do inline doFoo(), so refactor it into a separate function.
Up to now the last step was implemented by re-expanding the argument
too, which makes it impossible to reliably handle paths with percent
signs. Just expand the command, and catenate the argument as deity
intended.
Additionally make behavior with empty argument consistent with other
builtins: %{uncompress:} expands to nothing instead of printing out
an error message with an empty filename.