This is an archive of the discontinued LLVM Phabricator instance.

Partial fix for handling backticks in commands and aliases
ClosedPublic

Authored by jingham on Aug 31 2022, 12:57 PM.

Details

Summary

At present, backtick substitution is a "preprocessor" operation, which is not, I think, what people expect. I'm pretty sure you didn't mean to run an expression when you specified a file name that happened to have backticks in it, etc. I think it makes a lot more sense that the substitution should be done when it is encountered as a quote character. There was, in fact, some code in CommandObjectParsed that attempted to treat it this way, but it was defeated by the fact that we unconditionally do PreprocessCommand on the command string before parsing. It was also not quite right since it assumed the quote would still be present in the argument value, when in fact it was just in the quote member of the ArgEntry...

I fixed that, and changed the CommandInterpreter code to only preprocess the whole string for raw commands. I think really that Raw commands should handle their own preprocessing, for instance I don't think doing backtick substitution in the expression passed to expr is really what people expect...

When I did that a bunch of tests failed because we were not correctly preserving the backticks around arguments when we parsed them into a temporary argv array and then back out again, and because we didn't take them into account when stripping elements out of the incoming command when handling command aliases.

I also added a test that explicitly tests command aliases with embedded backticks. The test has a succeeding case and a failing case. The latter shows an extant bug this patch doesn't fix: the CommandAlias::Desugar doesn't correctly handle the case where you alias an alias and the second alias fills in slots of the first alias. It just pastes the second aliases options after the first aliases and then tries to evaluate them, which ends up with unfilled slots. As I say, that's an extant bug so the test for it fails now. I'll fix that one next chance I have to mess with this.

Diff Detail

Event Timeline

jingham created this revision.Aug 31 2022, 12:57 PM
Herald added a project: Restricted Project. · View Herald TranscriptAug 31 2022, 12:57 PM
jingham requested review of this revision.Aug 31 2022, 12:57 PM
Herald added a project: Restricted Project. · View Herald TranscriptAug 31 2022, 12:57 PM

The other bit of this patch was a cleanup I made as I was understanding the alias parsing where we were using specific tokens in the parsed alias, but the tokens were ad hoc strings, so I replaced them with constants.

Sorry if these comments are not helpful! Everything looks great!

lldb/source/Interpreter/Options.cpp
1026

Question: Could we drop the final else if we initialized option_to_insert to CommandInterpreter::g_no_argument? Just curious.

lldb/test/API/commands/command/backticks/TestBackticksInAlias.py
17

Nit: Typo. backtraces => backticks.

jingham marked an inline comment as done.Sep 13 2022, 11:02 AM
jingham added inline comments.
lldb/source/Interpreter/Options.cpp
1026

No, the correct default when there is an option_arg is the empty string. So I'd also have to set the string back to empty after the if (option_arg) { which would look weird.

lldb/test/API/commands/command/backticks/TestBackticksInAlias.py
17

Thanks for spotting that, I'll fix on commit.

This revision was not accepted when it landed; it landed in state Needs Review.Sep 13 2022, 11:02 AM
This revision was automatically updated to reflect the committed changes.
jingham marked an inline comment as done.

This seems to break the build with GCC (tested with the system compiler GCC 9 on Ubuntu 20.04):

ld.lld: error: undefined symbol: lldb_private::CommandInterpreter::g_argument
>>> referenced by CommandAlias.cpp
>>>               CommandAlias.cpp.o:(lldb_private::CommandAlias::GetAliasExpansion(lldb_private::StreamString&) const (.localalias)) in archive lib/liblldbInterpreter.a

(with lots more similar errors)