This revision was automatically updated to reflect the committed changes.
Closed by commit rL246639: Fix tab completion for command arguments containing 
spaces (authored by tberghammer).

Changed prior to commit:
  http://reviews.llvm.org/D12531?vs=33702&id=33794#toc

Repository:
  rL LLVM

http://reviews.llvm.org/D12531

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

Index: lldb/trunk/test/functionalities/completion/Makefile
===================================================================
--- lldb/trunk/test/functionalities/completion/Makefile
+++ lldb/trunk/test/functionalities/completion/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../make
+
+CXX_SOURCES := main.cpp
+
+include $(LEVEL)/Makefile.rules
Index: lldb/trunk/test/functionalities/completion/main.cpp
===================================================================
--- lldb/trunk/test/functionalities/completion/main.cpp
+++ lldb/trunk/test/functionalities/completion/main.cpp
@@ -0,0 +1,14 @@
+class Foo
+{
+public:
+    int Bar(int x, int y)
+    {
+        return x + y;
+    }
+};
+
+int main()
+{
+    Foo f;
+    f.Bar(1, 2);
+}
Index: lldb/trunk/test/functionalities/completion/TestCompletion.py
===================================================================
--- lldb/trunk/test/functionalities/completion/TestCompletion.py
+++ lldb/trunk/test/functionalities/completion/TestCompletion.py
@@ -219,6 +219,23 @@
         """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"""
Index: lldb/trunk/source/Interpreter/CommandInterpreter.cpp
===================================================================
--- lldb/trunk/source/Interpreter/CommandInterpreter.cpp
+++ lldb/trunk/source/Interpreter/CommandInterpreter.cpp
@@ -2002,7 +2002,7 @@
                                                    matches);
 
     if (num_command_matches <= 0)
-            return num_command_matches;
+        return num_command_matches;
 
     if (num_args == 0)
     {
@@ -2021,18 +2021,18 @@
         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;
Index: lldb/trunk/source/Interpreter/Args.cpp
===================================================================
--- lldb/trunk/source/Interpreter/Args.cpp
+++ lldb/trunk/source/Interpreter/Args.cpp
@@ -1668,3 +1668,33 @@
     }
 }
 
+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;
+}
+
Index: lldb/trunk/include/lldb/Interpreter/Args.h
===================================================================
--- lldb/trunk/include/lldb/Interpreter/Args.h
+++ lldb/trunk/include/lldb/Interpreter/Args.h
@@ -424,6 +424,9 @@
     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
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to