teemperor created this revision.
teemperor added a reviewer: LLDB.
Herald added subscribers: lldb-commits, JDevlieghere.
Herald added a project: LLDB.

Repository:
  rLLDB LLDB

https://reviews.llvm.org/D67903

Files:
  lldb/include/lldb/Utility/Log.h
  
lldb/packages/Python/lldbsuite/test/functionalities/completion/TestCompletion.py
  lldb/source/Commands/CommandObjectLog.cpp
  lldb/source/Utility/Log.cpp

Index: lldb/source/Utility/Log.cpp
===================================================================
--- lldb/source/Utility/Log.cpp
+++ lldb/source/Utility/Log.cpp
@@ -9,7 +9,6 @@
 #include "lldb/Utility/Log.h"
 #include "lldb/Utility/VASPrintf.h"
 
-#include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/Twine.h"
 #include "llvm/ADT/iterator.h"
@@ -38,13 +37,21 @@
 
 llvm::ManagedStatic<Log::ChannelMap> Log::g_channel_map;
 
-void Log::ListCategories(llvm::raw_ostream &stream, const ChannelMap::value_type &entry) {
-  stream << llvm::formatv("Logging categories for '{0}':\n", entry.first());
-  stream << "  all - all available logging categories\n";
-  stream << "  default - default set of logging categories\n";
+void Log::ForEachCategory(
+    const Log::ChannelMap::value_type &entry,
+    llvm::function_ref<void(llvm::StringRef, llvm::StringRef)> lambda) {
+  lambda("all", "all available logging categories");
+  lambda("default", "default set of logging categories");
   for (const auto &category : entry.second.m_channel.categories)
-    stream << llvm::formatv("  {0} - {1}\n", category.name,
-                            category.description);
+    lambda(category.name, category.description);
+}
+
+void Log::ListCategories(llvm::raw_ostream &stream,
+                         const ChannelMap::value_type &entry) {
+  ForEachCategory(entry,
+                  [&stream](llvm::StringRef name, llvm::StringRef description) {
+                    stream << llvm::formatv("  {0} - {1}\n", name, description);
+                  });
 }
 
 uint32_t Log::GetFlags(llvm::raw_ostream &stream, const ChannelMap::value_type &entry,
@@ -237,6 +244,23 @@
     entry.second.Disable(UINT32_MAX);
 }
 
+void Log::ForEachChannelCategory(
+    llvm::StringRef channel,
+    llvm::function_ref<void(llvm::StringRef, llvm::StringRef)> lambda) {
+  auto ch = g_channel_map->find(channel);
+  if (ch == g_channel_map->end())
+    return;
+
+  ForEachCategory(*ch, lambda);
+}
+
+std::vector<llvm::StringRef> Log::ListChannels() {
+  std::vector<llvm::StringRef> result;
+  for (const auto &channel : *g_channel_map)
+    result.push_back(channel.first());
+  return result;
+}
+
 void Log::ListAllLogChannels(llvm::raw_ostream &stream) {
   if (g_channel_map->empty()) {
     stream << "No logging channels are currently registered.\n";
Index: lldb/source/Commands/CommandObjectLog.cpp
===================================================================
--- lldb/source/Commands/CommandObjectLog.cpp
+++ lldb/source/Commands/CommandObjectLog.cpp
@@ -34,6 +34,21 @@
 #define LLDB_OPTIONS_log
 #include "CommandOptions.inc"
 
+/// Common completion logic for log enable/disable.
+static void CompleteEnableDisable(CompletionRequest &request) {
+  size_t arg_index = request.GetCursorIndex();
+  if (arg_index == 0) { // We got: log enable/disable x[tab]
+    for (llvm::StringRef channel : Log::ListChannels())
+      request.TryCompleteCurrentArg(channel);
+  } else if (arg_index >= 1) { // We got: log enable/disable channel x[tab]
+    llvm::StringRef channel = request.GetParsedLine().GetArgumentAtIndex(0);
+    Log::ForEachChannelCategory(
+        channel, [&request](llvm::StringRef name, llvm::StringRef desc) {
+          request.TryCompleteCurrentArg(name, desc);
+        });
+  }
+}
+
 class CommandObjectLogEnable : public CommandObjectParsed {
 public:
   // Constructors and Destructors
@@ -134,6 +149,12 @@
     uint32_t log_options;
   };
 
+  void
+  HandleArgumentCompletion(CompletionRequest &request,
+                           OptionElementVector &opt_element_vector) override {
+    CompleteEnableDisable(request);
+  }
+
 protected:
   bool DoExecute(Args &args, CommandReturnObject &result) override {
     if (args.GetArgumentCount() < 2) {
@@ -202,6 +223,12 @@
 
   ~CommandObjectLogDisable() override = default;
 
+  void
+  HandleArgumentCompletion(CompletionRequest &request,
+                           OptionElementVector &opt_element_vector) override {
+    CompleteEnableDisable(request);
+  }
+
 protected:
   bool DoExecute(Args &args, CommandReturnObject &result) override {
     if (args.empty()) {
@@ -254,6 +281,13 @@
 
   ~CommandObjectLogList() override = default;
 
+  void
+  HandleArgumentCompletion(CompletionRequest &request,
+                           OptionElementVector &opt_element_vector) override {
+    for (llvm::StringRef channel : Log::ListChannels())
+      request.TryCompleteCurrentArg(channel);
+  }
+
 protected:
   bool DoExecute(Args &args, CommandReturnObject &result) override {
     std::string output;
Index: lldb/packages/Python/lldbsuite/test/functionalities/completion/TestCompletion.py
===================================================================
--- lldb/packages/Python/lldbsuite/test/functionalities/completion/TestCompletion.py
+++ lldb/packages/Python/lldbsuite/test/functionalities/completion/TestCompletion.py
@@ -101,6 +101,38 @@
     def test_plugin_load(self):
         self.complete_from_to('plugin load ', [])
 
+    @skipIfFreeBSD  # timing out on the FreeBSD buildbot
+    def test_log_enable(self):
+        self.completions_match('log enable ',
+                               ['dwarf',
+                                'gdb-remote',
+                                'kdp-remote',
+                                'lldb'])
+        self.complete_from_to('log enable ll', ['lldb'])
+        self.complete_from_to('log enable lldb al', ['all'])
+        self.complete_from_to('log enable lldb sym', ['symbol'])
+
+    @skipIfFreeBSD  # timing out on the FreeBSD buildbot
+    def test_log_enable(self):
+        self.completions_match('log disable ',
+                               ['dwarf',
+                                'gdb-remote',
+                                'kdp-remote',
+                                'lldb'])
+        self.complete_from_to('log disable ll', ['lldb'])
+        self.complete_from_to('log disable lldb al', ['all'])
+        self.complete_from_to('log disable lldb sym', ['symbol'])
+
+    @skipIfFreeBSD  # timing out on the FreeBSD buildbot
+    def test_log_list(self):
+        self.completions_match('log list ',
+                               ['dwarf',
+                                'gdb-remote',
+                                'kdp-remote',
+                                'lldb'])
+        self.complete_from_to('log list ll', ['lldb'])
+        self.complete_from_to('log list lldb dwa', ['dwarf'])
+
     @skipIfFreeBSD  # timing out on the FreeBSD buildbot
     def test_quoted_command(self):
         self.complete_from_to('"set',
Index: lldb/include/lldb/Utility/Log.h
===================================================================
--- lldb/include/lldb/Utility/Log.h
+++ lldb/include/lldb/Utility/Log.h
@@ -14,6 +14,7 @@
 #include "lldb/lldb-defines.h"
 
 #include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/StringMap.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/Error.h"
@@ -112,6 +113,14 @@
   static bool ListChannelCategories(llvm::StringRef channel,
                                     llvm::raw_ostream &stream);
 
+  /// Returns the list of log channels.
+  static std::vector<llvm::StringRef> ListChannels();
+  /// Calls the given lambda for every category in the given channel.
+  /// If no channel with the given name exists, lambda is never called.
+  static void ForEachChannelCategory(
+      llvm::StringRef channel,
+      llvm::function_ref<void(llvm::StringRef, llvm::StringRef)> lambda);
+
   static void DisableAllLogChannels();
 
   static void ListAllLogChannels(llvm::raw_ostream &stream);
@@ -193,6 +202,10 @@
   typedef llvm::StringMap<Log> ChannelMap;
   static llvm::ManagedStatic<ChannelMap> g_channel_map;
 
+  static void ForEachCategory(
+      const Log::ChannelMap::value_type &entry,
+      llvm::function_ref<void(llvm::StringRef, llvm::StringRef)> lambda);
+
   static void ListCategories(llvm::raw_ostream &stream,
                              const ChannelMap::value_type &entry);
   static uint32_t GetFlags(llvm::raw_ostream &stream, const ChannelMap::value_type &entry,
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to