diff options
author | Jim Ingham <jingham@apple.com> | 2022-09-14 12:45:26 -0700 |
---|---|---|
committer | Jim Ingham <jingham@apple.com> | 2022-09-14 14:49:51 -0700 |
commit | f3d0bda5344e8429121cb50aba5502c1b399e5cd (patch) | |
tree | b3b95abbc50b4bf612d5df07b19922e4c69df3fe /lldb/source/Interpreter/CommandInterpreter.cpp | |
parent | e395915ac01ffd9b6cf743f361df7265f319a8c7 (diff) | |
download | llvm-f3d0bda5344e8429121cb50aba5502c1b399e5cd.zip llvm-f3d0bda5344e8429121cb50aba5502c1b399e5cd.tar.gz llvm-f3d0bda5344e8429121cb50aba5502c1b399e5cd.tar.bz2 |
Revert "Revert "Be more careful to maintain quoting information when parsing commands.""
This reverts commit ac05bc0524c66c74278b26742896a4c634c034cf.
I had incorrectly removed one set of checks in the option handling in
Options::ParseAlias because I couldn't see what it is for. It was a
bit obscure, but it handled the case where you pass "-something=other --"
as the input_line, which caused the built-in "run" alias not to return
the right value for IsDashDashCommand, causing TestHelp.py to fail.
Diffstat (limited to 'lldb/source/Interpreter/CommandInterpreter.cpp')
-rw-r--r-- | lldb/source/Interpreter/CommandInterpreter.cpp | 62 |
1 files changed, 48 insertions, 14 deletions
diff --git a/lldb/source/Interpreter/CommandInterpreter.cpp b/lldb/source/Interpreter/CommandInterpreter.cpp index 0596d85..0efc0fa 100644 --- a/lldb/source/Interpreter/CommandInterpreter.cpp +++ b/lldb/source/Interpreter/CommandInterpreter.cpp @@ -105,6 +105,11 @@ static constexpr const char *InitFileWarning = "and\n" "accept the security risk."; +const char *CommandInterpreter::g_no_argument = "<no-argument>"; +const char *CommandInterpreter::g_need_argument = "<need-argument>"; +const char *CommandInterpreter::g_argument = "<argument>"; + + #define LLDB_PROPERTIES_interpreter #include "InterpreterProperties.inc" @@ -1634,7 +1639,7 @@ CommandObject *CommandInterpreter::BuildAliasResult( std::string value; for (const auto &entry : *option_arg_vector) { std::tie(option, value_type, value) = entry; - if (option == "<argument>") { + if (option == g_argument) { result_str.Printf(" %s", value.c_str()); continue; } @@ -1656,11 +1661,33 @@ CommandObject *CommandInterpreter::BuildAliasResult( index); return nullptr; } else { - size_t strpos = raw_input_string.find(cmd_args.GetArgumentAtIndex(index)); - if (strpos != std::string::npos) + const Args::ArgEntry &entry = cmd_args[index]; + size_t strpos = raw_input_string.find(entry.c_str()); + const char quote_char = entry.GetQuoteChar(); + if (strpos != std::string::npos) { + const size_t start_fudge = quote_char == '\0' ? 0 : 1; + const size_t len_fudge = quote_char == '\0' ? 0 : 2; + + // Make sure we aren't going outside the bounds of the cmd string: + if (strpos < start_fudge) { + result.AppendError("Unmatched quote at command beginning."); + return nullptr; + } + llvm::StringRef arg_text = entry.ref(); + if (strpos - start_fudge + arg_text.size() + len_fudge + > raw_input_string.size()) { + result.AppendError("Unmatched quote at command end."); + return nullptr; + } raw_input_string = raw_input_string.erase( - strpos, strlen(cmd_args.GetArgumentAtIndex(index))); - result_str.Printf("%s", cmd_args.GetArgumentAtIndex(index)); + strpos - start_fudge, + strlen(cmd_args.GetArgumentAtIndex(index)) + len_fudge); + } + if (quote_char == '\0') + result_str.Printf("%s", cmd_args.GetArgumentAtIndex(index)); + else + result_str.Printf("%c%s%c", quote_char, + entry.c_str(), quote_char); } } @@ -1911,13 +1938,6 @@ bool CommandInterpreter::HandleCommand(const char *command_line, return true; } - Status error(PreprocessCommand(command_string)); - - if (error.Fail()) { - result.AppendError(error.AsCString()); - return false; - } - // Phase 1. // Before we do ANY kind of argument processing, we need to figure out what @@ -1935,6 +1955,20 @@ bool CommandInterpreter::HandleCommand(const char *command_line, CommandObject *cmd_obj = ResolveCommandImpl(command_string, result); + // We have to preprocess the whole command string for Raw commands, since we + // don't know the structure of the command. For parsed commands, we only + // treat backticks as quote characters specially. + // FIXME: We probably want to have raw commands do their own preprocessing. + // For instance, I don't think people expect substitution in expr expressions. + if (cmd_obj && cmd_obj->WantsRawCommandString()) { + Status error(PreprocessCommand(command_string)); + + if (error.Fail()) { + result.AppendError(error.AsCString()); + return false; + } + } + // Although the user may have abbreviated the command, the command_string now // has the command expanded to the full name. For example, if the input was // "br s -n main", command_string is now "breakpoint set -n main". @@ -2163,7 +2197,7 @@ void CommandInterpreter::BuildAliasCommandArgs(CommandObject *alias_cmd_obj, std::string value; for (const auto &option_entry : *option_arg_vector) { std::tie(option, value_type, value) = option_entry; - if (option == "<argument>") { + if (option == g_argument) { if (!wants_raw_input || (value != "--")) { // Since we inserted this above, make sure we don't insert it twice new_args.AppendArgument(value); @@ -2174,7 +2208,7 @@ void CommandInterpreter::BuildAliasCommandArgs(CommandObject *alias_cmd_obj, if (value_type != OptionParser::eOptionalArgument) new_args.AppendArgument(option); - if (value == "<no-argument>") + if (value == g_no_argument) continue; int index = GetOptionArgumentPosition(value.c_str()); |