1//===-- CommandObjectApropos.cpp ------------------------------------------===// 2// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6// 7//===----------------------------------------------------------------------===// 8 9#include "CommandObjectApropos.h" 10#include "lldb/Interpreter/CommandInterpreter.h" 11#include "lldb/Interpreter/CommandReturnObject.h" 12#include "lldb/Interpreter/Property.h" 13#include "lldb/Utility/Args.h" 14 15using namespace lldb; 16using namespace lldb_private; 17 18// CommandObjectApropos 19 20CommandObjectApropos::CommandObjectApropos(CommandInterpreter &interpreter) 21 : CommandObjectParsed( 22 interpreter, "apropos", 23 "List debugger commands related to a word or subject.", nullptr) { 24 CommandArgumentEntry arg; 25 CommandArgumentData search_word_arg; 26 27 // Define the first (and only) variant of this arg. 28 search_word_arg.arg_type = eArgTypeSearchWord; 29 search_word_arg.arg_repetition = eArgRepeatPlain; 30 31 // There is only one variant this argument could be; put it into the argument 32 // entry. 33 arg.push_back(search_word_arg); 34 35 // Push the data for the first argument into the m_arguments vector. 36 m_arguments.push_back(arg); 37} 38 39CommandObjectApropos::~CommandObjectApropos() = default; 40 41bool CommandObjectApropos::DoExecute(Args &args, CommandReturnObject &result) { 42 const size_t argc = args.GetArgumentCount(); 43 44 if (argc == 1) { 45 auto search_word = args[0].ref(); 46 if (!search_word.empty()) { 47 // The bulk of the work must be done inside the Command Interpreter, 48 // since the command dictionary is private. 49 StringList commands_found; 50 StringList commands_help; 51 52 m_interpreter.FindCommandsForApropos( 53 search_word, commands_found, commands_help, true, true, true, true); 54 55 if (commands_found.GetSize() == 0) { 56 result.AppendMessageWithFormat("No commands found pertaining to '%s'. " 57 "Try 'help' to see a complete list of " 58 "debugger commands.\n", 59 args[0].c_str()); 60 } else { 61 if (commands_found.GetSize() > 0) { 62 result.AppendMessageWithFormat( 63 "The following commands may relate to '%s':\n", args[0].c_str()); 64 const size_t max_len = commands_found.GetMaxStringLength(); 65 66 for (size_t i = 0; i < commands_found.GetSize(); ++i) 67 m_interpreter.OutputFormattedHelpText( 68 result.GetOutputStream(), commands_found.GetStringAtIndex(i), 69 "--", commands_help.GetStringAtIndex(i), max_len); 70 } 71 } 72 73 std::vector<const Property *> properties; 74 const size_t num_properties = 75 GetDebugger().Apropos(search_word, properties); 76 if (num_properties) { 77 const bool dump_qualified_name = true; 78 result.AppendMessageWithFormatv( 79 "\nThe following settings variables may relate to '{0}': \n\n", 80 args[0].ref()); 81 for (size_t i = 0; i < num_properties; ++i) 82 properties[i]->DumpDescription( 83 m_interpreter, result.GetOutputStream(), 0, dump_qualified_name); 84 } 85 86 result.SetStatus(eReturnStatusSuccessFinishNoResult); 87 } else { 88 result.AppendError("'' is not a valid search word.\n"); 89 } 90 } else { 91 result.AppendError("'apropos' must be called with exactly one argument.\n"); 92 } 93 94 return result.Succeeded(); 95} 96