1435933ddSDimitry Andric //===-- CommandObjectApropos.cpp ---------------------------------*- C++
2435933ddSDimitry Andric //-*-===//
3ac7ddfbfSEd Maste //
4ac7ddfbfSEd Maste //                     The LLVM Compiler Infrastructure
5ac7ddfbfSEd Maste //
6ac7ddfbfSEd Maste // This file is distributed under the University of Illinois Open Source
7ac7ddfbfSEd Maste // License. See LICENSE.TXT for details.
8ac7ddfbfSEd Maste //
9ac7ddfbfSEd Maste //===----------------------------------------------------------------------===//
10ac7ddfbfSEd Maste 
114bb0738eSEd Maste #include "CommandObjectApropos.h"
12ac7ddfbfSEd Maste #include "lldb/Interpreter/CommandInterpreter.h"
13ac7ddfbfSEd Maste #include "lldb/Interpreter/CommandReturnObject.h"
14435933ddSDimitry Andric #include "lldb/Interpreter/Options.h"
15435933ddSDimitry Andric #include "lldb/Interpreter/Property.h"
16*4ba319b5SDimitry Andric #include "lldb/Utility/Args.h"
17ac7ddfbfSEd Maste 
18ac7ddfbfSEd Maste using namespace lldb;
19ac7ddfbfSEd Maste using namespace lldb_private;
20ac7ddfbfSEd Maste 
21ac7ddfbfSEd Maste //-------------------------------------------------------------------------
22ac7ddfbfSEd Maste // CommandObjectApropos
23ac7ddfbfSEd Maste //-------------------------------------------------------------------------
24ac7ddfbfSEd Maste 
CommandObjectApropos(CommandInterpreter & interpreter)254bb0738eSEd Maste CommandObjectApropos::CommandObjectApropos(CommandInterpreter &interpreter)
26435933ddSDimitry Andric     : CommandObjectParsed(
27435933ddSDimitry Andric           interpreter, "apropos",
28435933ddSDimitry Andric           "List debugger commands related to a word or subject.", nullptr) {
29ac7ddfbfSEd Maste   CommandArgumentEntry arg;
30ac7ddfbfSEd Maste   CommandArgumentData search_word_arg;
31ac7ddfbfSEd Maste 
32ac7ddfbfSEd Maste   // Define the first (and only) variant of this arg.
33ac7ddfbfSEd Maste   search_word_arg.arg_type = eArgTypeSearchWord;
34ac7ddfbfSEd Maste   search_word_arg.arg_repetition = eArgRepeatPlain;
35ac7ddfbfSEd Maste 
36435933ddSDimitry Andric   // There is only one variant this argument could be; put it into the argument
37435933ddSDimitry Andric   // entry.
38ac7ddfbfSEd Maste   arg.push_back(search_word_arg);
39ac7ddfbfSEd Maste 
40ac7ddfbfSEd Maste   // Push the data for the first argument into the m_arguments vector.
41ac7ddfbfSEd Maste   m_arguments.push_back(arg);
42ac7ddfbfSEd Maste }
43ac7ddfbfSEd Maste 
444bb0738eSEd Maste CommandObjectApropos::~CommandObjectApropos() = default;
45ac7ddfbfSEd Maste 
DoExecute(Args & args,CommandReturnObject & result)46435933ddSDimitry Andric bool CommandObjectApropos::DoExecute(Args &args, CommandReturnObject &result) {
47ac7ddfbfSEd Maste   const size_t argc = args.GetArgumentCount();
48ac7ddfbfSEd Maste 
49435933ddSDimitry Andric   if (argc == 1) {
50435933ddSDimitry Andric     auto search_word = args[0].ref;
51435933ddSDimitry Andric     if (!search_word.empty()) {
52*4ba319b5SDimitry Andric       // The bulk of the work must be done inside the Command Interpreter,
53*4ba319b5SDimitry Andric       // since the command dictionary is private.
54ac7ddfbfSEd Maste       StringList commands_found;
55ac7ddfbfSEd Maste       StringList commands_help;
56ac7ddfbfSEd Maste 
57435933ddSDimitry Andric       m_interpreter.FindCommandsForApropos(search_word, commands_found,
58435933ddSDimitry Andric                                            commands_help, true, true, true);
59ac7ddfbfSEd Maste 
60435933ddSDimitry Andric       if (commands_found.GetSize() == 0) {
61435933ddSDimitry Andric         result.AppendMessageWithFormat("No commands found pertaining to '%s'. "
62435933ddSDimitry Andric                                        "Try 'help' to see a complete list of "
63435933ddSDimitry Andric                                        "debugger commands.\n",
64435933ddSDimitry Andric                                        args[0].c_str());
65435933ddSDimitry Andric       } else {
66435933ddSDimitry Andric         if (commands_found.GetSize() > 0) {
67435933ddSDimitry Andric           result.AppendMessageWithFormat(
68435933ddSDimitry Andric               "The following commands may relate to '%s':\n", args[0].c_str());
69ac7ddfbfSEd Maste           size_t max_len = 0;
70ac7ddfbfSEd Maste 
71435933ddSDimitry Andric           for (size_t i = 0; i < commands_found.GetSize(); ++i) {
72ac7ddfbfSEd Maste             size_t len = strlen(commands_found.GetStringAtIndex(i));
73ac7ddfbfSEd Maste             if (len > max_len)
74ac7ddfbfSEd Maste               max_len = len;
75ac7ddfbfSEd Maste           }
76ac7ddfbfSEd Maste 
77ac7ddfbfSEd Maste           for (size_t i = 0; i < commands_found.GetSize(); ++i)
78435933ddSDimitry Andric             m_interpreter.OutputFormattedHelpText(
79435933ddSDimitry Andric                 result.GetOutputStream(), commands_found.GetStringAtIndex(i),
80435933ddSDimitry Andric                 "--", commands_help.GetStringAtIndex(i), max_len);
81ac7ddfbfSEd Maste         }
82ac7ddfbfSEd Maste       }
83ac7ddfbfSEd Maste 
84ac7ddfbfSEd Maste       std::vector<const Property *> properties;
85435933ddSDimitry Andric       const size_t num_properties =
86435933ddSDimitry Andric           m_interpreter.GetDebugger().Apropos(search_word, properties);
87435933ddSDimitry Andric       if (num_properties) {
88ac7ddfbfSEd Maste         const bool dump_qualified_name = true;
89435933ddSDimitry Andric         result.AppendMessageWithFormatv(
90435933ddSDimitry Andric             "\nThe following settings variables may relate to '{0}': \n\n",
91435933ddSDimitry Andric             args[0].ref);
92ac7ddfbfSEd Maste         for (size_t i = 0; i < num_properties; ++i)
93435933ddSDimitry Andric           properties[i]->DumpDescription(
94435933ddSDimitry Andric               m_interpreter, result.GetOutputStream(), 0, dump_qualified_name);
95ac7ddfbfSEd Maste       }
96ac7ddfbfSEd Maste 
97ac7ddfbfSEd Maste       result.SetStatus(eReturnStatusSuccessFinishNoResult);
98435933ddSDimitry Andric     } else {
99ac7ddfbfSEd Maste       result.AppendError("'' is not a valid search word.\n");
100ac7ddfbfSEd Maste       result.SetStatus(eReturnStatusFailed);
101ac7ddfbfSEd Maste     }
102435933ddSDimitry Andric   } else {
103ac7ddfbfSEd Maste     result.AppendError("'apropos' must be called with exactly one argument.\n");
104ac7ddfbfSEd Maste     result.SetStatus(eReturnStatusFailed);
105ac7ddfbfSEd Maste   }
106ac7ddfbfSEd Maste 
107ac7ddfbfSEd Maste   return result.Succeeded();
108ac7ddfbfSEd Maste }
109