#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"
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);
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,
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',
#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
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) {
~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()) {
~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;
#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"
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,
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";