[Lldb-commits] [lldb] [lldb/Interpreter] Fix ambiguous partial command resolution (PR #101934)
via lldb-commits
lldb-commits at lists.llvm.org
Mon Aug 5 01:03:48 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-lldb
Author: Med Ismail Bennani (medismailben)
<details>
<summary>Changes</summary>
This patch is a follow-up to #<!-- -->97263 that fix ambigous abbreviated command resolution.
When multiple commands are resolved, instead of failing to pick a command to run, this patch changes to resolution logic to check if there is either a single user command match or a single alias match and if so, it will run that command instead of the others.
This has as a side-effect that we don't need to make aliases for every substring of aliases to support abbrivated alias resolution.
---
Full diff: https://github.com/llvm/llvm-project/pull/101934.diff
2 Files Affected:
- (modified) lldb/include/lldb/Interpreter/CommandInterpreter.h (+4)
- (modified) lldb/source/Interpreter/CommandInterpreter.cpp (+68-19)
``````````diff
diff --git a/lldb/include/lldb/Interpreter/CommandInterpreter.h b/lldb/include/lldb/Interpreter/CommandInterpreter.h
index 48f6618ab0e39..2bafc30cc8e23 100644
--- a/lldb/include/lldb/Interpreter/CommandInterpreter.h
+++ b/lldb/include/lldb/Interpreter/CommandInterpreter.h
@@ -295,6 +295,10 @@ class CommandInterpreter : public Broadcaster,
StringList *matches = nullptr,
StringList *descriptions = nullptr) const;
+ CommandObject *
+ GetAliasCommandObject(llvm::StringRef cmd, StringList *matches = nullptr,
+ StringList *descriptions = nullptr) const;
+
/// Determine whether a root level, built-in command with this name exists.
bool CommandExists(llvm::StringRef cmd) const;
diff --git a/lldb/source/Interpreter/CommandInterpreter.cpp b/lldb/source/Interpreter/CommandInterpreter.cpp
index fc07168b6c0ac..0fd3dfcb73ed1 100644
--- a/lldb/source/Interpreter/CommandInterpreter.cpp
+++ b/lldb/source/Interpreter/CommandInterpreter.cpp
@@ -520,10 +520,6 @@ void CommandInterpreter::Initialize() {
cmd_obj_sp = GetCommandSPExact("scripting run");
if (cmd_obj_sp) {
- AddAlias("sc", cmd_obj_sp);
- AddAlias("scr", cmd_obj_sp);
- AddAlias("scri", cmd_obj_sp);
- AddAlias("scrip", cmd_obj_sp);
AddAlias("script", cmd_obj_sp);
}
@@ -1302,6 +1298,36 @@ CommandObject *CommandInterpreter::GetUserCommandObject(
return {};
}
+CommandObject *CommandInterpreter::GetAliasCommandObject(
+ llvm::StringRef cmd, StringList *matches, StringList *descriptions) const {
+ std::string cmd_str(cmd);
+ auto find_exact = [&](const CommandObject::CommandMap &map) {
+ auto found_elem = map.find(std::string(cmd));
+ if (found_elem == map.end())
+ return (CommandObject *)nullptr;
+ CommandObject *exact_cmd = found_elem->second.get();
+ if (exact_cmd) {
+ if (matches)
+ matches->AppendString(exact_cmd->GetCommandName());
+ if (descriptions)
+ descriptions->AppendString(exact_cmd->GetHelp());
+ return exact_cmd;
+ }
+ return (CommandObject *)nullptr;
+ };
+
+ CommandObject *exact_cmd = find_exact(GetAliases());
+ if (exact_cmd)
+ return exact_cmd;
+
+ // We didn't have an exact command, so now look for partial matches.
+ StringList tmp_list;
+ StringList *matches_ptr = matches ? matches : &tmp_list;
+ AddNamesMatchingPartialString(GetAliases(), cmd_str, *matches_ptr);
+
+ return {};
+}
+
bool CommandInterpreter::CommandExists(llvm::StringRef cmd) const {
return m_command_dict.find(std::string(cmd)) != m_command_dict.end();
}
@@ -3421,6 +3447,19 @@ CommandInterpreter::ResolveCommandImpl(std::string &command_line,
std::string next_word;
StringList matches;
bool done = false;
+
+ auto build_alias_cmd = [&](std::string &full_name) {
+ revised_command_line.Clear();
+ matches.Clear();
+ std::string alias_result;
+ cmd_obj =
+ BuildAliasResult(full_name, scratch_command, alias_result, result);
+ revised_command_line.Printf("%s", alias_result.c_str());
+ if (cmd_obj) {
+ wants_raw_input = cmd_obj->WantsRawCommandString();
+ }
+ };
+
while (!done) {
char quote_char = '\0';
std::string suffix;
@@ -3432,14 +3471,7 @@ CommandInterpreter::ResolveCommandImpl(std::string &command_line,
bool is_real_command =
(!is_alias) || (cmd_obj != nullptr && !cmd_obj->IsAlias());
if (!is_real_command) {
- matches.Clear();
- std::string alias_result;
- cmd_obj =
- BuildAliasResult(full_name, scratch_command, alias_result, result);
- revised_command_line.Printf("%s", alias_result.c_str());
- if (cmd_obj) {
- wants_raw_input = cmd_obj->WantsRawCommandString();
- }
+ build_alias_cmd(full_name);
} else {
if (cmd_obj) {
llvm::StringRef cmd_name = cmd_obj->GetCommandName();
@@ -3486,21 +3518,38 @@ CommandInterpreter::ResolveCommandImpl(std::string &command_line,
if (cmd_obj == nullptr) {
const size_t num_matches = matches.GetSize();
if (matches.GetSize() > 1) {
- StreamString error_msg;
- error_msg.Printf("Ambiguous command '%s'. Possible matches:\n",
- next_word.c_str());
+ StringList user_cmd_matches;
+ GetUserCommandObject(next_word, &user_cmd_matches);
+
+ StringList alias_matches;
+ GetAliasCommandObject(next_word, &alias_matches);
+
+ if (user_cmd_matches.GetSize() == 1) {
+ cmd_obj = GetCommandObject(user_cmd_matches.GetStringAtIndex(0));
+ done = static_cast<bool>(cmd_obj);
+ } else if (alias_matches.GetSize() == 1) {
+ std::string full_name;
+ GetAliasFullName(alias_matches.GetStringAtIndex(0), full_name);
+ build_alias_cmd(full_name);
+ done = static_cast<bool>(cmd_obj);
+ } else {
+ StreamString error_msg;
+ error_msg.Printf("Ambiguous command '%s'. Possible matches:\n",
+ next_word.c_str());
- for (uint32_t i = 0; i < num_matches; ++i) {
- error_msg.Printf("\t%s\n", matches.GetStringAtIndex(i));
+ for (uint32_t i = 0; i < num_matches; ++i) {
+ error_msg.Printf("\t%s\n", matches.GetStringAtIndex(i));
+ }
+ result.AppendRawError(error_msg.GetString());
}
- result.AppendRawError(error_msg.GetString());
} else {
// We didn't have only one match, otherwise we wouldn't get here.
lldbassert(num_matches == 0);
result.AppendErrorWithFormat("'%s' is not a valid command.\n",
next_word.c_str());
}
- return nullptr;
+ if (!done)
+ return nullptr;
}
if (cmd_obj->IsMultiwordObject()) {
``````````
</details>
https://github.com/llvm/llvm-project/pull/101934
More information about the lldb-commits
mailing list