xref: /llvm-project/lldb/source/Commands/CommandObjectApropos.cpp (revision c8ecc2a9fa3c100ae1c8c3e9ce4a5db452a69206)
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,
30                         "apropos",
31                         "Find a list of debugger commands related to a particular word/subject.",
32                         nullptr)
33 {
34     CommandArgumentEntry arg;
35     CommandArgumentData search_word_arg;
36 
37     // Define the first (and only) variant of this arg.
38     search_word_arg.arg_type = eArgTypeSearchWord;
39     search_word_arg.arg_repetition = eArgRepeatPlain;
40 
41     // There is only one variant this argument could be; put it into the argument 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
51 CommandObjectApropos::DoExecute (Args& args, CommandReturnObject &result)
52 {
53     const size_t argc = args.GetArgumentCount ();
54 
55     if (argc == 1)
56     {
57         const char *search_word = args.GetArgumentAtIndex(0);
58         if ((search_word != nullptr)
59             && (strlen (search_word) > 0))
60         {
61             // The bulk of the work must be done inside the Command Interpreter, since the command dictionary
62             // is private.
63             StringList commands_found;
64             StringList commands_help;
65             StringList user_commands_found;
66             StringList user_commands_help;
67 
68             m_interpreter.FindCommandsForApropos (search_word, commands_found, commands_help, true, false);
69             m_interpreter.FindCommandsForApropos (search_word, user_commands_found, user_commands_help, false, true);
70 
71             if (commands_found.GetSize() == 0 && user_commands_found.GetSize() == 0)
72             {
73                 result.AppendMessageWithFormat ("No commands found pertaining to '%s'. Try 'help' to see a complete list of debugger commands.\n", search_word);
74             }
75             else
76             {
77                 if (commands_found.GetSize() > 0)
78                 {
79                     result.AppendMessageWithFormat ("The following built-in commands may relate to '%s':\n", search_word);
80                     size_t max_len = 0;
81 
82                     for (size_t i = 0; i < commands_found.GetSize(); ++i)
83                     {
84                         size_t len = strlen (commands_found.GetStringAtIndex (i));
85                         if (len > max_len)
86                             max_len = len;
87                     }
88 
89                     for (size_t i = 0; i < commands_found.GetSize(); ++i)
90                         m_interpreter.OutputFormattedHelpText (result.GetOutputStream(),
91                                                                commands_found.GetStringAtIndex(i),
92                                                                "--",
93                                                                commands_help.GetStringAtIndex(i),
94                                                                max_len);
95                     if (user_commands_found.GetSize() > 0)
96                         result.AppendMessage("");
97                 }
98 
99                 if (user_commands_found.GetSize() > 0)
100                 {
101                     result.AppendMessageWithFormat ("The following user commands may relate to '%s':\n", search_word);
102                     size_t max_len = 0;
103 
104                     for (size_t i = 0; i < user_commands_found.GetSize(); ++i)
105                     {
106                         size_t len = strlen (user_commands_found.GetStringAtIndex (i));
107                         if (len > max_len)
108                             max_len = len;
109                     }
110 
111                     for (size_t i = 0; i < user_commands_found.GetSize(); ++i)
112                         m_interpreter.OutputFormattedHelpText (result.GetOutputStream(),
113                                                                user_commands_found.GetStringAtIndex(i),
114                                                                "--",
115                                                                user_commands_help.GetStringAtIndex(i),
116                                                                max_len);
117                 }
118             }
119 
120             std::vector<const Property *> properties;
121             const size_t num_properties = m_interpreter.GetDebugger().Apropos(search_word, properties);
122             if (num_properties)
123             {
124                 const bool dump_qualified_name = true;
125                 result.AppendMessageWithFormat ("\nThe following settings variables may relate to '%s': \n\n", search_word);
126                 for (size_t i=0; i<num_properties; ++i)
127                     properties[i]->DumpDescription (m_interpreter, result.GetOutputStream(), 0, dump_qualified_name);
128 
129             }
130 
131             result.SetStatus (eReturnStatusSuccessFinishNoResult);
132         }
133         else
134         {
135             result.AppendError ("'' is not a valid search word.\n");
136             result.SetStatus (eReturnStatusFailed);
137         }
138     }
139     else
140     {
141         result.AppendError ("'apropos' must be called with exactly one argument.\n");
142         result.SetStatus (eReturnStatusFailed);
143     }
144 
145     return result.Succeeded();
146 }
147