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 _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits