diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/completion/TestCompletion.py b/lldb/packages/Python/lldbsuite/test/functionalities/completion/TestCompletion.py index 2df341e572d04..969a7b543e09f 100644 --- a/lldb/packages/Python/lldbsuite/test/functionalities/completion/TestCompletion.py +++ b/lldb/packages/Python/lldbsuite/test/functionalities/completion/TestCompletion.py @@ -90,6 +90,13 @@ def test_process_launch_arch(self): ['mips', 'arm64']) + @skipIfFreeBSD # timing out on the FreeBSD buildbot + def test_ambiguous_long_opt(self): + self.completions_match('breakpoint modify --th', + ['--thread-id', + '--thread-index', + '--thread-name']) + @skipIfFreeBSD # timing out on the FreeBSD buildbot def test_plugin_load(self): self.complete_from_to('plugin load ', []) diff --git a/lldb/packages/Python/lldbsuite/test/lldbtest.py b/lldb/packages/Python/lldbsuite/test/lldbtest.py index 9d38909d679ff..6c00350167d0e 100644 --- a/lldb/packages/Python/lldbsuite/test/lldbtest.py +++ b/lldb/packages/Python/lldbsuite/test/lldbtest.py @@ -2194,6 +2194,16 @@ def complete_from_to(self, str_input, patterns, turn_off_re_match=False): compare_string, msg=COMPLETION_MSG( str_input, p, match_strings), exe=False, patterns=[p]) + def completions_match(self, command, completions): + """Checks that the completions for the given command are equal to the + given list of completions""" + interp = self.dbg.GetCommandInterpreter() + match_strings = lldb.SBStringList() + interp.HandleCompletion(command, len(command), 0, -1, match_strings) + # match_strings is a 1-indexed list, so we have to slice... + self.assertItemsEqual(completions, list(match_strings)[1:], + "List of returned completion is wrong") + def filecheck( self, command, diff --git a/lldb/source/Interpreter/Options.cpp b/lldb/source/Interpreter/Options.cpp index 2829a22b7e497..1a713ed7fbb54 100644 --- a/lldb/source/Interpreter/Options.cpp +++ b/lldb/source/Interpreter/Options.cpp @@ -706,17 +706,11 @@ bool Options::HandleOptionCompletion(CompletionRequest &request, // elements // that are not unique up to this point. getopt_long_only does // shortest unique match for long options already. - - if (cur_opt_str.startswith("--")) { + if (cur_opt_str.consume_front("--")) { for (auto &def : opt_defs) { - if (!def.long_option) - continue; - - if (cur_opt_str.startswith(def.long_option)) { - std::string full_name("--"); - full_name.append(def.long_option); - request.AddCompletion(full_name); - } + llvm::StringRef long_option(def.long_option); + if (long_option.startswith(cur_opt_str)) + request.AddCompletion("--" + long_option.str()); } } return true;