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