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