From efb8b7b1ec48caef82f1326f0f81528933d83629 Mon Sep 17 00:00:00 2001 From: Raphael Isemann Date: Wed, 28 Aug 2019 10:17:23 +0000 Subject: [PATCH] [lldb] Fix and test completion for ambiguous long options The refactoring patch for the option completion broke the completion for ambiguous long options. As this feature was also untested (as testing ambiguous options with the current test methods is impossible), I just noticed now. This patch restores the old behavior and adds a test for this feature. llvm-svn: 370185 --- .../functionalities/completion/TestCompletion.py | 7 +++++++ lldb/packages/Python/lldbsuite/test/lldbtest.py | 10 ++++++++++ lldb/source/Interpreter/Options.cpp | 14 ++++---------- 3 files changed, 21 insertions(+), 10 deletions(-) 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;