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