rpm icon indicating copy to clipboard operation
rpm copied to clipboard

Add macro '%-x**' containing all occurrences of the flag '-x'

Open rhabacker opened this issue 2 years ago • 21 comments

Fix #546

rhabacker avatar Mar 23 '23 15:03 rhabacker

This pull request required several push forces because the master branch of rpm on openSUSE 15.4 could not be built due to the missing package rpm-sequoia. The patch was therefore developed on rpm-4.14.x and ported to the master branch.

rhabacker avatar Mar 24 '23 15:03 rhabacker

depends on #2455

Dropped that dependency.

rhabacker avatar Mar 30 '23 09:03 rhabacker

Is there anything else that would block the merge? I need this feature to fix a problem I am having on https://build.opensuse.org/project/show/windows:mingw:win32.

rhabacker avatar May 11 '23 20:05 rhabacker

Is there anything else that would block the merge? I need this feature to fix a problem I am having on https://build.opensuse.org/project/show/windows:mingw:win32.

The dbus project has reported a problem in this regard on https://gitlab.freedesktop.org/dbus/dbus/-/issues/455 for which this support is required, since the associated macro mingwxx-cmake must be adapted to filter out all occurrences of -Dxxx and --xxx together with -B and -S.

Alternatively, this functionality would have to be (re)implemented as a lua macro, which in my opinion is a waste of time, since there is already a solution with this merge request.

rhabacker avatar May 24 '23 23:05 rhabacker

Sorry for not responding earlier, we've been busy with 4.19 alpha preparations and stuff.

The question is whether this is the way we want to address this particular issue. Separating the arguments by space introduces a new problem as arguments can legitimately have spaces in them (by using %{quote:...}) and we don't want to introduce a feature that's not compatible with the rest of the system. @mlschroe , thoughts?

pmatilai avatar May 26 '23 08:05 pmatilai

@pmatilai what about quoting each argument separately, or making them available as a Lua array? IMO any macro this complex should probably be written in Lua.

DemiMarie avatar May 27 '23 22:05 DemiMarie

@pmatilai what about quoting each argument separately,

I checked how quotes in strings are handled correctly with the changes from this pull request:

$ ../rpm-build/rpm --define '%foo(D:) %{-D**}' --eval '%foo -D11  -D 22 -D"33" -D"44 55" -D "66 77"    argument'
 -D11 -D 22 -D"33" -D"44 -D "66

The result is that the parameter -D"44 55" and -D "66 77" are not recognized correctly.

But the same issue also happens with the present macros related to returning flags and/or values

$ ../rpm-build/rpm --define '%foo(D:) %{-D}' --eval '%foo -D"44 55"   argument'
-D"44

../rpm-build/rpm --define '%foo(D:) %{-D*}' --eval '%foo -D "44 55"   argument'
"44

so there is no difference here.

rhabacker avatar Jun 05 '23 11:06 rhabacker

Since rpm uses a call to getopt to process the command line, I checked the parameter list with the command line tool getopt.

$ getopt -o "D:" -- -D11 -D 22 -D "33" -D "44 55" -D "66 77"
 -D '11' -D '22' -D '33' -D '44 55' -D '66 77' --

which gave the expected results (apart from adding an extra space between the flag and the value).

Running getopt with gdb and inspecting the argv array

Breakpoint 1, main (argc=11, argv=0x7fffffd7d8) at misc-utils/getopt.c:369
369 struct getopt_control ctl = {
(gdb) p argv[8]
$10 = 0x7fffffdd66 "-D44 55"
(gdb) p argv[9]
$11 = 0x7fffffdd6e "-D"
(gdb) p argv[10]
$12 = 0x7fffffdd71 "66 77"
(gdb)

shows that the quoting is done by the shell and not by getopt itself. The conclusion is that something similar must be done before calling getopt in rpm to process macro parameters with quotes.

rhabacker avatar Jun 05 '23 12:06 rhabacker

... The conclusion is that something similar must be done before calling getopt in rpm to process macro parameters with quotes.

There is already a function named splitQuoted(), which splits the arguments, currently only separated by space and tabs.

It looks like a candidate for processing quotes.

rhabacker avatar Jun 06 '23 10:06 rhabacker

@rhabacker

shows that the quoting is done by the shell and not by getopt itself. The conclusion is that something similar must be done before calling getopt in rpm to process macro parameters with quotes.

Isn't that %quote, like @pmatilai mentioned? Going back to your experiments (braces added to output for clarity):

$ rpm --define '%foo(D:) [%{-D}]' --eval '%foo -D%{quote:44 55} argument' 
[-D 44 55]
$ rpm --define '%foo(D:) [%{-D*}]' --eval '%foo -D%{quote:44 55} argument'
[44 55]

ferdnyc avatar Jan 22 '24 09:01 ferdnyc

With the new ME_QUOTED support added end of last year we could make this work correctly. So the question is if we want %-x** or not.

mlschroe avatar Jan 22 '24 10:01 mlschroe

I don't think %-x** should repeat the option name, though. It should just be the arguments, i.e. just like %-x* but with multiple values.

mlschroe avatar Jan 22 '24 11:01 mlschroe

Like I said before, I'm not convinced this is the way we want to represent the multivalue case.

Assuming we can technically do this now, is there a reason not to put those values into the normal -x* macro? It seems to me we can't really break any significant existing users as we just haven't supported multiple flags before, so macros can't have been using them much.

And, I concur with @DemiMarie here - I tend to think this would be better left to Lua where an array of values can be properly dealt with.

pmatilai avatar Jan 22 '24 11:01 pmatilai

Historically it has always been just the last occurrence, so I don't think we can change this.

Regarding the array of values part: we now can deal properly with it because of ME_QUOTED. But I'm fine if the functionality is only available to lua (but it currently is not).

mlschroe avatar Jan 22 '24 11:01 mlschroe

(We might be able to change the behavior of %-f so that it includes all occurrences, but even that makes me a bit uneasy.)

mlschroe avatar Jan 22 '24 12:01 mlschroe

I know its that way historically, just doubtful of people actually relying on multivalues being handled that way. But then, I wouldn't know. There's some risk involved for sure.

Yet another possibility could be letting macros declare the way they want their arguments, ie "I can handle multiple values, bring em on", just like we have a way to disable all pre-processing.

pmatilai avatar Jan 22 '24 12:01 pmatilai

Just realized %{-f} and %{-f*} explictly documented as being the last occurence. So yep, we can't change that.

pmatilai avatar Jan 22 '24 12:01 pmatilai

But the change that documented it was commit a5bd7571358c7974da1c909e331525b13dce1264 by Ralf done March 2023....

mlschroe avatar Jan 22 '24 12:01 mlschroe

Actually, there is a kind of a way to access the values from Lua even now.

%-f* macro has the last definition of the macro. If you pop (ie undefine) it, you get the one underneath. And with that, you can walk all the values. It wont work on normal macros as "%undefine -f*" is not permitted, but rpm.undefine() in Lua bypasses that check.

Not that this is something I'd recommend for use.

pmatilai avatar Jan 22 '24 12:01 pmatilai

With the new ME_QUOTED support added end of last year we could make this work correctly. So the question is if we want %-x** or not.

Speaking of ME_QUOTED: On a somewhat related note, am I doing something wrong or does %{quote} seem to not play nicely with %{**}?

$ rpm --define '%foo(D:) %{**}' --eval '%foo -D"33 44"  argument' 
-D"33 44" argument

$ rpm --define '%foo(D:) %{**}' --eval '%foo -D%{quote:33 44}  argument'
-D33 44 argument

ferdnyc avatar Jan 25 '24 21:01 ferdnyc

That looks like the correct output to me. Why do you think it doesn't work? Note that %quote does not add any quotes, the effect is purely internal. Here's how to make it visible:

$ rpm --define '%foo(D:) %{shescape %{**}}' --eval '%foo -D"33 44"  argument' 
'-D"33' '44"' 'argument'
$ rpm --define '%foo(D:) %{shescape %{**}}' --eval '%foo -D%{quote:33 44}  argument'
'-D33 44' 'argument'

mlschroe avatar Jan 26 '24 13:01 mlschroe