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