[Lldb-commits] [lldb] r246639 - Fix tab completion for command arguments containing spaces

Tamas Berghammer via lldb-commits lldb-commits at lists.llvm.org
Wed Sep 2 03:35:28 PDT 2015


Author: tberghammer
Date: Wed Sep  2 05:35:27 2015
New Revision: 246639

URL: http://llvm.org/viewvc/llvm-project?rev=246639&view=rev
Log:
Fix tab completion for command arguments containing spaces

If a command argument contains a space then it have to be escaped with
backslash signs so the argument parsing logic can parse it properly.
This CL fixes the tab completion code for the arguments to create
complitions with correctly escaped strings.

Differential revision: http://reviews.llvm.org/D12531

Added:
    lldb/trunk/test/functionalities/completion/Makefile
    lldb/trunk/test/functionalities/completion/main.cpp
Modified:
    lldb/trunk/include/lldb/Interpreter/Args.h
    lldb/trunk/source/Interpreter/Args.cpp
    lldb/trunk/source/Interpreter/CommandInterpreter.cpp
    lldb/trunk/test/functionalities/completion/TestCompletion.py

Modified: lldb/trunk/include/lldb/Interpreter/Args.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Interpreter/Args.h?rev=246639&r1=246638&r2=246639&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Interpreter/Args.h (original)
+++ lldb/trunk/include/lldb/Interpreter/Args.h Wed Sep  2 05:35:27 2015
@@ -424,6 +424,9 @@ public:
     static void
     ExpandEscapedCharacters (const char *src, std::string &dst);
 
+    static std::string
+    EscapeLLDBCommandArgument (const std::string& arg, char quote_char);
+
     // This one isn't really relevant to Arguments per se, but we're using the Args as a
     // general strings container, so...
     void

Modified: lldb/trunk/source/Interpreter/Args.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/Args.cpp?rev=246639&r1=246638&r2=246639&view=diff
==============================================================================
--- lldb/trunk/source/Interpreter/Args.cpp (original)
+++ lldb/trunk/source/Interpreter/Args.cpp Wed Sep  2 05:35:27 2015
@@ -1668,3 +1668,33 @@ Args::ExpandEscapedCharacters (const cha
     }
 }
 
+std::string
+Args::EscapeLLDBCommandArgument (const std::string& arg, char quote_char)
+{
+    const char* chars_to_escape = nullptr;
+    switch (quote_char)
+    {
+        case '\0':
+            chars_to_escape = " \t\\'\"`";
+            break;
+        case '\'':
+            chars_to_escape = "";
+            break;
+        case '"':
+            chars_to_escape = "$\"`\\";
+            break;
+        default:
+            assert(false && "Unhandled quote character");
+    }
+
+    std::string res;
+    res.reserve(arg.size());
+    for (char c : arg)
+    {
+        if (::strchr(chars_to_escape, c))
+            res.push_back('\\');
+        res.push_back(c);
+    }
+    return res;
+}
+

Modified: lldb/trunk/source/Interpreter/CommandInterpreter.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/CommandInterpreter.cpp?rev=246639&r1=246638&r2=246639&view=diff
==============================================================================
--- lldb/trunk/source/Interpreter/CommandInterpreter.cpp (original)
+++ lldb/trunk/source/Interpreter/CommandInterpreter.cpp Wed Sep  2 05:35:27 2015
@@ -2002,7 +2002,7 @@ CommandInterpreter::HandleCompletion (co
                                                    matches);
 
     if (num_command_matches <= 0)
-            return num_command_matches;
+        return num_command_matches;
 
     if (num_args == 0)
     {
@@ -2021,18 +2021,18 @@ CommandInterpreter::HandleCompletion (co
         std::string common_prefix;
         matches.LongestCommonPrefix (common_prefix);
         const size_t partial_name_len = command_partial_str.size();
+        common_prefix.erase (0, partial_name_len);
 
         // If we matched a unique single command, add a space...
         // Only do this if the completer told us this was a complete word, however...
         if (num_command_matches == 1 && word_complete)
         {
             char quote_char = parsed_line.GetArgumentQuoteCharAtIndex(cursor_index);
+            common_prefix = Args::EscapeLLDBCommandArgument(common_prefix, quote_char);
             if (quote_char != '\0')
                 common_prefix.push_back(quote_char);
-
             common_prefix.push_back(' ');
         }
-        common_prefix.erase (0, partial_name_len);
         matches.InsertStringAtIndex(0, common_prefix.c_str());
     }
     return num_command_matches;

Added: lldb/trunk/test/functionalities/completion/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/completion/Makefile?rev=246639&view=auto
==============================================================================
--- lldb/trunk/test/functionalities/completion/Makefile (added)
+++ lldb/trunk/test/functionalities/completion/Makefile Wed Sep  2 05:35:27 2015
@@ -0,0 +1,5 @@
+LEVEL = ../../make
+
+CXX_SOURCES := main.cpp
+
+include $(LEVEL)/Makefile.rules

Modified: lldb/trunk/test/functionalities/completion/TestCompletion.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/completion/TestCompletion.py?rev=246639&r1=246638&r2=246639&view=diff
==============================================================================
--- lldb/trunk/test/functionalities/completion/TestCompletion.py (original)
+++ lldb/trunk/test/functionalities/completion/TestCompletion.py Wed Sep  2 05:35:27 2015
@@ -219,6 +219,23 @@ class CommandLineCompletionTestCase(Test
         """Test that 'target va' completes to 'target variable '."""
         self.complete_from_to('target va', 'target variable ')
 
+    @skipUnlessDarwin
+    @dsym_test
+    def test_symbol_name_dsym(self):
+        self.buildDsym()
+        self.complete_from_to('''file a.out
+                                 breakpoint set -n Fo''',
+                              'breakpoint set -n Foo::Bar(int,\\ int)',
+                              turn_off_re_match=True)
+
+    @dwarf_test
+    def test_symbol_name_dwarf(self):
+        self.buildDwarf()
+        self.complete_from_to('''file a.out
+                                 breakpoint set -n Fo''',
+                              'breakpoint set -n Foo::Bar(int,\\ int)',
+                              turn_off_re_match=True)
+
     def complete_from_to(self, str_input, patterns, turn_off_re_match=False):
         """Test that the completion mechanism completes str_input to patterns,
         where patterns could be a pattern-string or a list of pattern-strings"""

Added: lldb/trunk/test/functionalities/completion/main.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/completion/main.cpp?rev=246639&view=auto
==============================================================================
--- lldb/trunk/test/functionalities/completion/main.cpp (added)
+++ lldb/trunk/test/functionalities/completion/main.cpp Wed Sep  2 05:35:27 2015
@@ -0,0 +1,14 @@
+class Foo
+{
+public:
+    int Bar(int x, int y)
+    {
+        return x + y;
+    }
+};
+
+int main()
+{
+    Foo f;
+    f.Bar(1, 2);
+}




More information about the lldb-commits mailing list