180814287SRaphael Isemann //===-- CommandObject.cpp -------------------------------------------------===//
230fdc8d8SChris Lattner //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
630fdc8d8SChris Lattner //
730fdc8d8SChris Lattner //===----------------------------------------------------------------------===//
830fdc8d8SChris Lattner 
930fdc8d8SChris Lattner #include "lldb/Interpreter/CommandObject.h"
1030fdc8d8SChris Lattner 
1130fdc8d8SChris Lattner #include <map>
12b9c1b51eSKate Stone #include <sstream>
13b9c1b51eSKate Stone #include <string>
1430fdc8d8SChris Lattner 
1576e47d48SRaphael Isemann #include <cctype>
1676e47d48SRaphael Isemann #include <cstdlib>
1730fdc8d8SChris Lattner 
1830fdc8d8SChris Lattner #include "lldb/Core/Address.h"
19*bcae3cdbSJonas Devlieghere #include "lldb/Interpreter/CommandOptionArgumentTable.h"
2040af72e1SJim Ingham #include "lldb/Interpreter/Options.h"
215f19b907SPavel Labath #include "lldb/Utility/ArchSpec.h"
2218bb1f10SRaphael Isemann #include "llvm/ADT/ScopeExit.h"
2330fdc8d8SChris Lattner 
2430fdc8d8SChris Lattner // These are for the Sourcename completers.
2530fdc8d8SChris Lattner // FIXME: Make a separate file for the completers.
2630fdc8d8SChris Lattner #include "lldb/Core/FileSpecList.h"
27a78bd7ffSZachary Turner #include "lldb/DataFormatters/FormatManager.h"
2830fdc8d8SChris Lattner #include "lldb/Target/Process.h"
2930fdc8d8SChris Lattner #include "lldb/Target/Target.h"
305713a05bSZachary Turner #include "lldb/Utility/FileSpec.h"
3130fdc8d8SChris Lattner 
320e0984eeSJim Ingham #include "lldb/Target/Language.h"
330e0984eeSJim Ingham 
3430fdc8d8SChris Lattner #include "lldb/Interpreter/CommandInterpreter.h"
357ced9fffSJonas Devlieghere #include "lldb/Interpreter/CommandOptionArgumentTable.h"
3630fdc8d8SChris Lattner #include "lldb/Interpreter/CommandReturnObject.h"
3730fdc8d8SChris Lattner 
3830fdc8d8SChris Lattner using namespace lldb;
3930fdc8d8SChris Lattner using namespace lldb_private;
4030fdc8d8SChris Lattner 
4130fdc8d8SChris Lattner // CommandObject
4230fdc8d8SChris Lattner 
CommandObject(CommandInterpreter & interpreter,llvm::StringRef name,llvm::StringRef help,llvm::StringRef syntax,uint32_t flags)43adcd0268SBenjamin Kramer CommandObject::CommandObject(CommandInterpreter &interpreter,
44adcd0268SBenjamin Kramer                              llvm::StringRef name, llvm::StringRef help,
45adcd0268SBenjamin Kramer                              llvm::StringRef syntax, uint32_t flags)
46adcd0268SBenjamin Kramer     : m_interpreter(interpreter), m_cmd_name(std::string(name)),
478cdcd41eSTatyana Krasnukha       m_flags(flags), m_deprecated_command_override_callback(nullptr),
48b9c1b51eSKate Stone       m_command_override_callback(nullptr), m_command_override_baton(nullptr) {
49adcd0268SBenjamin Kramer   m_cmd_help_short = std::string(help);
50adcd0268SBenjamin Kramer   m_cmd_syntax = std::string(syntax);
5130fdc8d8SChris Lattner }
5230fdc8d8SChris Lattner 
GetDebugger()532b29b432SJonas Devlieghere Debugger &CommandObject::GetDebugger() { return m_interpreter.GetDebugger(); }
542b29b432SJonas Devlieghere 
GetHelp()55442f6530SZachary Turner llvm::StringRef CommandObject::GetHelp() { return m_cmd_help_short; }
5630fdc8d8SChris Lattner 
GetHelpLong()57442f6530SZachary Turner llvm::StringRef CommandObject::GetHelpLong() { return m_cmd_help_long; }
5830fdc8d8SChris Lattner 
GetSyntax()59442f6530SZachary Turner llvm::StringRef CommandObject::GetSyntax() {
607cff7d46SEugene Zemtsov   if (!m_cmd_syntax.empty())
61442f6530SZachary Turner     return m_cmd_syntax;
62442f6530SZachary Turner 
63e139cf23SCaroline Tice   StreamString syntax_str;
64442f6530SZachary Turner   syntax_str.PutCString(GetCommandName());
65442f6530SZachary Turner 
66bef55ac8SEnrico Granata   if (!IsDashDashCommand() && GetOptions() != nullptr)
67442f6530SZachary Turner     syntax_str.PutCString(" <cmd-options>");
68442f6530SZachary Turner 
69442f6530SZachary Turner   if (!m_arguments.empty()) {
70442f6530SZachary Turner     syntax_str.PutCString(" ");
71442f6530SZachary Turner 
72b9c1b51eSKate Stone     if (!IsDashDashCommand() && WantsRawCommandString() && GetOptions() &&
73b9c1b51eSKate Stone         GetOptions()->NumCommandOptions())
74442f6530SZachary Turner       syntax_str.PutCString("-- ");
75e139cf23SCaroline Tice     GetFormattedCommandArguments(syntax_str);
76e139cf23SCaroline Tice   }
77adcd0268SBenjamin Kramer   m_cmd_syntax = std::string(syntax_str.GetString());
78e139cf23SCaroline Tice 
79442f6530SZachary Turner   return m_cmd_syntax;
8030fdc8d8SChris Lattner }
8130fdc8d8SChris Lattner 
GetCommandName() const82a449698cSZachary Turner llvm::StringRef CommandObject::GetCommandName() const { return m_cmd_name; }
8330fdc8d8SChris Lattner 
SetCommandName(llvm::StringRef name)84adcd0268SBenjamin Kramer void CommandObject::SetCommandName(llvm::StringRef name) {
85adcd0268SBenjamin Kramer   m_cmd_name = std::string(name);
86adcd0268SBenjamin Kramer }
8730fdc8d8SChris Lattner 
SetHelp(llvm::StringRef str)88adcd0268SBenjamin Kramer void CommandObject::SetHelp(llvm::StringRef str) {
89adcd0268SBenjamin Kramer   m_cmd_help_short = std::string(str);
90adcd0268SBenjamin Kramer }
916f79bb2dSEnrico Granata 
SetHelpLong(llvm::StringRef str)92adcd0268SBenjamin Kramer void CommandObject::SetHelpLong(llvm::StringRef str) {
93adcd0268SBenjamin Kramer   m_cmd_help_long = std::string(str);
94adcd0268SBenjamin Kramer }
9599f0b8f9SEnrico Granata 
SetSyntax(llvm::StringRef str)96adcd0268SBenjamin Kramer void CommandObject::SetSyntax(llvm::StringRef str) {
97adcd0268SBenjamin Kramer   m_cmd_syntax = std::string(str);
98adcd0268SBenjamin Kramer }
9930fdc8d8SChris Lattner 
GetOptions()100b9c1b51eSKate Stone Options *CommandObject::GetOptions() {
10105097246SAdrian Prantl   // By default commands don't have options unless this virtual function is
10205097246SAdrian Prantl   // overridden by base classes.
103d78c9576SEd Maste   return nullptr;
10430fdc8d8SChris Lattner }
10530fdc8d8SChris Lattner 
ParseOptions(Args & args,CommandReturnObject & result)106b9c1b51eSKate Stone bool CommandObject::ParseOptions(Args &args, CommandReturnObject &result) {
10730fdc8d8SChris Lattner   // See if the subclass has options?
10830fdc8d8SChris Lattner   Options *options = GetOptions();
109b9c1b51eSKate Stone   if (options != nullptr) {
11097206d57SZachary Turner     Status error;
111e1cfbc79STodd Fiala 
112e1cfbc79STodd Fiala     auto exe_ctx = GetCommandInterpreter().GetExecutionContext();
113e1cfbc79STodd Fiala     options->NotifyOptionParsingStarting(&exe_ctx);
11430fdc8d8SChris Lattner 
115e1cfbc79STodd Fiala     const bool require_validation = true;
1165f56fca4SPavel Labath     llvm::Expected<Args> args_or = options->Parse(
1175f56fca4SPavel Labath         args, &exe_ctx, GetCommandInterpreter().GetPlatform(true),
118e1cfbc79STodd Fiala         require_validation);
11930fdc8d8SChris Lattner 
1205f56fca4SPavel Labath     if (args_or) {
1215f56fca4SPavel Labath       args = std::move(*args_or);
122e1cfbc79STodd Fiala       error = options->NotifyOptionParsingFinished(&exe_ctx);
1235f56fca4SPavel Labath     } else
1245f56fca4SPavel Labath       error = args_or.takeError();
125f6b8b581SGreg Clayton 
126b9c1b51eSKate Stone     if (error.Success()) {
127f6b8b581SGreg Clayton       if (options->VerifyOptions(result))
128f6b8b581SGreg Clayton         return true;
129b9c1b51eSKate Stone     } else {
13030fdc8d8SChris Lattner       const char *error_cstr = error.AsCString();
131b9c1b51eSKate Stone       if (error_cstr) {
13230fdc8d8SChris Lattner         // We got an error string, lets use that
13386edbf41SGreg Clayton         result.AppendError(error_cstr);
134b9c1b51eSKate Stone       } else {
13530fdc8d8SChris Lattner         // No error string, output the usage information into result
136b9c1b51eSKate Stone         options->GenerateOptionUsage(
137e473e79cSDavid Spickett             result.GetErrorStream(), *this,
138b9c1b51eSKate Stone             GetCommandInterpreter().GetDebugger().GetTerminalWidth());
13930fdc8d8SChris Lattner       }
140f6b8b581SGreg Clayton     }
14130fdc8d8SChris Lattner     result.SetStatus(eReturnStatusFailed);
14230fdc8d8SChris Lattner     return false;
14330fdc8d8SChris Lattner   }
14430fdc8d8SChris Lattner   return true;
14530fdc8d8SChris Lattner }
14630fdc8d8SChris Lattner 
CheckRequirements(CommandReturnObject & result)147b9c1b51eSKate Stone bool CommandObject::CheckRequirements(CommandReturnObject &result) {
14805097246SAdrian Prantl   // Nothing should be stored in m_exe_ctx between running commands as
14905097246SAdrian Prantl   // m_exe_ctx has shared pointers to the target, process, thread and frame and
15005097246SAdrian Prantl   // we don't want any CommandObject instances to keep any of these objects
15105097246SAdrian Prantl   // around longer than for a single command. Every command should call
15261f1b70aSAdrian Prantl   // CommandObject::Cleanup() after it has completed.
15361f1b70aSAdrian Prantl   assert(!m_exe_ctx.GetTargetPtr());
15461f1b70aSAdrian Prantl   assert(!m_exe_ctx.GetProcessPtr());
15561f1b70aSAdrian Prantl   assert(!m_exe_ctx.GetThreadPtr());
15661f1b70aSAdrian Prantl   assert(!m_exe_ctx.GetFramePtr());
157f9fc609fSGreg Clayton 
15805097246SAdrian Prantl   // Lock down the interpreter's execution context prior to running the command
15905097246SAdrian Prantl   // so we guarantee the selected target, process, thread and frame can't go
16005097246SAdrian Prantl   // away during the execution
161f9fc609fSGreg Clayton   m_exe_ctx = m_interpreter.GetExecutionContext();
162f9fc609fSGreg Clayton 
163f9fc609fSGreg Clayton   const uint32_t flags = GetFlags().Get();
164b9c1b51eSKate Stone   if (flags & (eCommandRequiresTarget | eCommandRequiresProcess |
165b9c1b51eSKate Stone                eCommandRequiresThread | eCommandRequiresFrame |
166b9c1b51eSKate Stone                eCommandTryTargetAPILock)) {
167f9fc609fSGreg Clayton 
168b9c1b51eSKate Stone     if ((flags & eCommandRequiresTarget) && !m_exe_ctx.HasTargetScope()) {
169f9fc609fSGreg Clayton       result.AppendError(GetInvalidTargetDescription());
170f9fc609fSGreg Clayton       return false;
171f9fc609fSGreg Clayton     }
172f9fc609fSGreg Clayton 
173b9c1b51eSKate Stone     if ((flags & eCommandRequiresProcess) && !m_exe_ctx.HasProcessScope()) {
174e59b0d2cSJason Molenda       if (!m_exe_ctx.HasTargetScope())
175e59b0d2cSJason Molenda         result.AppendError(GetInvalidTargetDescription());
176e59b0d2cSJason Molenda       else
177f9fc609fSGreg Clayton         result.AppendError(GetInvalidProcessDescription());
178f9fc609fSGreg Clayton       return false;
179f9fc609fSGreg Clayton     }
180f9fc609fSGreg Clayton 
181b9c1b51eSKate Stone     if ((flags & eCommandRequiresThread) && !m_exe_ctx.HasThreadScope()) {
182e59b0d2cSJason Molenda       if (!m_exe_ctx.HasTargetScope())
183e59b0d2cSJason Molenda         result.AppendError(GetInvalidTargetDescription());
184e59b0d2cSJason Molenda       else if (!m_exe_ctx.HasProcessScope())
185e59b0d2cSJason Molenda         result.AppendError(GetInvalidProcessDescription());
186e59b0d2cSJason Molenda       else
187f9fc609fSGreg Clayton         result.AppendError(GetInvalidThreadDescription());
188f9fc609fSGreg Clayton       return false;
189f9fc609fSGreg Clayton     }
190f9fc609fSGreg Clayton 
191b9c1b51eSKate Stone     if ((flags & eCommandRequiresFrame) && !m_exe_ctx.HasFrameScope()) {
192e59b0d2cSJason Molenda       if (!m_exe_ctx.HasTargetScope())
193e59b0d2cSJason Molenda         result.AppendError(GetInvalidTargetDescription());
194e59b0d2cSJason Molenda       else if (!m_exe_ctx.HasProcessScope())
195e59b0d2cSJason Molenda         result.AppendError(GetInvalidProcessDescription());
196e59b0d2cSJason Molenda       else if (!m_exe_ctx.HasThreadScope())
197e59b0d2cSJason Molenda         result.AppendError(GetInvalidThreadDescription());
198e59b0d2cSJason Molenda       else
199f9fc609fSGreg Clayton         result.AppendError(GetInvalidFrameDescription());
200f9fc609fSGreg Clayton       return false;
201f9fc609fSGreg Clayton     }
202f9fc609fSGreg Clayton 
203b9c1b51eSKate Stone     if ((flags & eCommandRequiresRegContext) &&
204b9c1b51eSKate Stone         (m_exe_ctx.GetRegisterContext() == nullptr)) {
205f9fc609fSGreg Clayton       result.AppendError(GetInvalidRegContextDescription());
206f9fc609fSGreg Clayton       return false;
207f9fc609fSGreg Clayton     }
208f9fc609fSGreg Clayton 
209b9c1b51eSKate Stone     if (flags & eCommandTryTargetAPILock) {
210f9fc609fSGreg Clayton       Target *target = m_exe_ctx.GetTargetPtr();
211f9fc609fSGreg Clayton       if (target)
212b9c1b51eSKate Stone         m_api_locker =
213b9c1b51eSKate Stone             std::unique_lock<std::recursive_mutex>(target->GetAPIMutex());
214f9fc609fSGreg Clayton     }
215f9fc609fSGreg Clayton   }
216f9fc609fSGreg Clayton 
217b9c1b51eSKate Stone   if (GetFlags().AnySet(eCommandProcessMustBeLaunched |
218b9c1b51eSKate Stone                         eCommandProcessMustBePaused)) {
219c14ee32dSGreg Clayton     Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
220b9c1b51eSKate Stone     if (process == nullptr) {
221b8e8a5f3SJim Ingham       // A process that is not running is considered paused.
222b9c1b51eSKate Stone       if (GetFlags().Test(eCommandProcessMustBeLaunched)) {
22330fdc8d8SChris Lattner         result.AppendError("Process must exist.");
22430fdc8d8SChris Lattner         return false;
22530fdc8d8SChris Lattner       }
226b9c1b51eSKate Stone     } else {
22730fdc8d8SChris Lattner       StateType state = process->GetState();
228b9c1b51eSKate Stone       switch (state) {
2297a5388bfSGreg Clayton       case eStateInvalid:
23030fdc8d8SChris Lattner       case eStateSuspended:
23130fdc8d8SChris Lattner       case eStateCrashed:
23230fdc8d8SChris Lattner       case eStateStopped:
23330fdc8d8SChris Lattner         break;
23430fdc8d8SChris Lattner 
235b766a73dSGreg Clayton       case eStateConnected:
236b766a73dSGreg Clayton       case eStateAttaching:
237b766a73dSGreg Clayton       case eStateLaunching:
23830fdc8d8SChris Lattner       case eStateDetached:
23930fdc8d8SChris Lattner       case eStateExited:
24030fdc8d8SChris Lattner       case eStateUnloaded:
241b9c1b51eSKate Stone         if (GetFlags().Test(eCommandProcessMustBeLaunched)) {
24230fdc8d8SChris Lattner           result.AppendError("Process must be launched.");
24330fdc8d8SChris Lattner           return false;
24430fdc8d8SChris Lattner         }
24530fdc8d8SChris Lattner         break;
24630fdc8d8SChris Lattner 
24730fdc8d8SChris Lattner       case eStateRunning:
24830fdc8d8SChris Lattner       case eStateStepping:
249b9c1b51eSKate Stone         if (GetFlags().Test(eCommandProcessMustBePaused)) {
250b9c1b51eSKate Stone           result.AppendError("Process is running.  Use 'process interrupt' to "
251b9c1b51eSKate Stone                              "pause execution.");
25230fdc8d8SChris Lattner           return false;
25330fdc8d8SChris Lattner         }
25430fdc8d8SChris Lattner       }
25530fdc8d8SChris Lattner     }
256b766a73dSGreg Clayton   }
257fb19f11eSWalter Erquinigo 
258fb19f11eSWalter Erquinigo   if (GetFlags().Test(eCommandProcessMustBeTraced)) {
259fb19f11eSWalter Erquinigo     Target *target = m_exe_ctx.GetTargetPtr();
260fb19f11eSWalter Erquinigo     if (target && !target->GetTrace()) {
2611b1c8e4aSDavid Spickett       result.AppendError("Process is not being traced.");
262fb19f11eSWalter Erquinigo       return false;
263fb19f11eSWalter Erquinigo     }
264fb19f11eSWalter Erquinigo   }
265fb19f11eSWalter Erquinigo 
2665a988416SJim Ingham   return true;
26730fdc8d8SChris Lattner }
26830fdc8d8SChris Lattner 
Cleanup()269b9c1b51eSKate Stone void CommandObject::Cleanup() {
270f9fc609fSGreg Clayton   m_exe_ctx.Clear();
271bb19a13cSSaleem Abdulrasool   if (m_api_locker.owns_lock())
272bb19a13cSSaleem Abdulrasool     m_api_locker.unlock();
273f9fc609fSGreg Clayton }
274f9fc609fSGreg Clayton 
HandleCompletion(CompletionRequest & request)275ae34ed2cSRaphael Isemann void CommandObject::HandleCompletion(CompletionRequest &request) {
276ec31255cSGongyu Deng 
277ec31255cSGongyu Deng   m_exe_ctx = m_interpreter.GetExecutionContext();
27818bb1f10SRaphael Isemann   auto reset_ctx = llvm::make_scope_exit([this]() { Cleanup(); });
279ec31255cSGongyu Deng 
280e171da5cSBruce Mitchener   // Default implementation of WantsCompletion() is !WantsRawCommandString().
28105097246SAdrian Prantl   // Subclasses who want raw command string but desire, for example, argument
28205097246SAdrian Prantl   // completion should override WantsCompletion() to return true, instead.
283b9c1b51eSKate Stone   if (WantsRawCommandString() && !WantsCompletion()) {
284b9c1b51eSKate Stone     // FIXME: Abstract telling the completion to insert the completion
285b9c1b51eSKate Stone     // character.
286ae34ed2cSRaphael Isemann     return;
287b9c1b51eSKate Stone   } else {
28830fdc8d8SChris Lattner     // Can we do anything generic with the options?
28930fdc8d8SChris Lattner     Options *cur_options = GetOptions();
290de019b88SJonas Devlieghere     CommandReturnObject result(m_interpreter.GetDebugger().GetUseColor());
29130fdc8d8SChris Lattner     OptionElementVector opt_element_vector;
29230fdc8d8SChris Lattner 
293b9c1b51eSKate Stone     if (cur_options != nullptr) {
2942443bbd4SRaphael Isemann       opt_element_vector = cur_options->ParseForCompletion(
2952443bbd4SRaphael Isemann           request.GetParsedLine(), request.GetCursorIndex());
29630fdc8d8SChris Lattner 
297a2e76c0bSRaphael Isemann       bool handled_by_options = cur_options->HandleOptionCompletion(
298a2e76c0bSRaphael Isemann           request, opt_element_vector, GetCommandInterpreter());
29930fdc8d8SChris Lattner       if (handled_by_options)
300ae34ed2cSRaphael Isemann         return;
30130fdc8d8SChris Lattner     }
30230fdc8d8SChris Lattner 
30330fdc8d8SChris Lattner     // If we got here, the last word is not an option or an option argument.
304ae34ed2cSRaphael Isemann     HandleArgumentCompletion(request, opt_element_vector);
30530fdc8d8SChris Lattner   }
30630fdc8d8SChris Lattner }
30730fdc8d8SChris Lattner 
HelpTextContainsWord(llvm::StringRef search_word,bool search_short_help,bool search_long_help,bool search_syntax,bool search_options)30898896839SZachary Turner bool CommandObject::HelpTextContainsWord(llvm::StringRef search_word,
309d033e1ceSEnrico Granata                                          bool search_short_help,
310d033e1ceSEnrico Granata                                          bool search_long_help,
311d033e1ceSEnrico Granata                                          bool search_syntax,
312b9c1b51eSKate Stone                                          bool search_options) {
31330fdc8d8SChris Lattner   std::string options_usage_help;
31430fdc8d8SChris Lattner 
31530fdc8d8SChris Lattner   bool found_word = false;
31630fdc8d8SChris Lattner 
317442f6530SZachary Turner   llvm::StringRef short_help = GetHelp();
318442f6530SZachary Turner   llvm::StringRef long_help = GetHelpLong();
319442f6530SZachary Turner   llvm::StringRef syntax_help = GetSyntax();
32030fdc8d8SChris Lattner 
321e50f9c41SMartin Storsjö   if (search_short_help && short_help.contains_insensitive(search_word))
32230fdc8d8SChris Lattner     found_word = true;
323e50f9c41SMartin Storsjö   else if (search_long_help && long_help.contains_insensitive(search_word))
32430fdc8d8SChris Lattner     found_word = true;
325e50f9c41SMartin Storsjö   else if (search_syntax && syntax_help.contains_insensitive(search_word))
32630fdc8d8SChris Lattner     found_word = true;
32730fdc8d8SChris Lattner 
328b9c1b51eSKate Stone   if (!found_word && search_options && GetOptions() != nullptr) {
32930fdc8d8SChris Lattner     StreamString usage_help;
330b9c1b51eSKate Stone     GetOptions()->GenerateOptionUsage(
331e473e79cSDavid Spickett         usage_help, *this,
332b9c1b51eSKate Stone         GetCommandInterpreter().GetDebugger().GetTerminalWidth());
33398896839SZachary Turner     if (!usage_help.Empty()) {
33498896839SZachary Turner       llvm::StringRef usage_text = usage_help.GetString();
335e50f9c41SMartin Storsjö       if (usage_text.contains_insensitive(search_word))
33630fdc8d8SChris Lattner         found_word = true;
33730fdc8d8SChris Lattner     }
33830fdc8d8SChris Lattner   }
33930fdc8d8SChris Lattner 
34030fdc8d8SChris Lattner   return found_word;
34130fdc8d8SChris Lattner }
342e139cf23SCaroline Tice 
ParseOptionsAndNotify(Args & args,CommandReturnObject & result,OptionGroupOptions & group_options,ExecutionContext & exe_ctx)3433a0e1270SRaphael Isemann bool CommandObject::ParseOptionsAndNotify(Args &args,
3443a0e1270SRaphael Isemann                                           CommandReturnObject &result,
3453a0e1270SRaphael Isemann                                           OptionGroupOptions &group_options,
3463a0e1270SRaphael Isemann                                           ExecutionContext &exe_ctx) {
3473a0e1270SRaphael Isemann   if (!ParseOptions(args, result))
3483a0e1270SRaphael Isemann     return false;
3493a0e1270SRaphael Isemann 
3503a0e1270SRaphael Isemann   Status error(group_options.NotifyOptionParsingFinished(&exe_ctx));
3513a0e1270SRaphael Isemann   if (error.Fail()) {
3523a0e1270SRaphael Isemann     result.AppendError(error.AsCString());
3533a0e1270SRaphael Isemann     return false;
3543a0e1270SRaphael Isemann   }
3553a0e1270SRaphael Isemann   return true;
3563a0e1270SRaphael Isemann }
3573a0e1270SRaphael Isemann 
GetNumArgumentEntries()358b9c1b51eSKate Stone int CommandObject::GetNumArgumentEntries() { return m_arguments.size(); }
359e139cf23SCaroline Tice 
360e139cf23SCaroline Tice CommandObject::CommandArgumentEntry *
GetArgumentEntryAtIndex(int idx)361b9c1b51eSKate Stone CommandObject::GetArgumentEntryAtIndex(int idx) {
3623985c8c6SSaleem Abdulrasool   if (static_cast<size_t>(idx) < m_arguments.size())
363e139cf23SCaroline Tice     return &(m_arguments[idx]);
364e139cf23SCaroline Tice 
365d78c9576SEd Maste   return nullptr;
366e139cf23SCaroline Tice }
367e139cf23SCaroline Tice 
368d7e6a4f2SVince Harron const CommandObject::ArgumentTableEntry *
FindArgumentDataByType(CommandArgumentType arg_type)369b9c1b51eSKate Stone CommandObject::FindArgumentDataByType(CommandArgumentType arg_type) {
370e139cf23SCaroline Tice   for (int i = 0; i < eArgTypeLastArg; ++i)
3717ced9fffSJonas Devlieghere     if (g_argument_table[i].arg_type == arg_type)
3727ced9fffSJonas Devlieghere       return &(g_argument_table[i]);
373e139cf23SCaroline Tice 
374d78c9576SEd Maste   return nullptr;
375e139cf23SCaroline Tice }
376e139cf23SCaroline Tice 
GetArgumentHelp(Stream & str,CommandArgumentType arg_type,CommandInterpreter & interpreter)377b9c1b51eSKate Stone void CommandObject::GetArgumentHelp(Stream &str, CommandArgumentType arg_type,
378b9c1b51eSKate Stone                                     CommandInterpreter &interpreter) {
3797ced9fffSJonas Devlieghere   const ArgumentTableEntry *entry = &(g_argument_table[arg_type]);
380e139cf23SCaroline Tice 
381b9c1b51eSKate Stone   // The table is *supposed* to be kept in arg_type order, but someone *could*
382b9c1b51eSKate Stone   // have messed it up...
383e139cf23SCaroline Tice 
384e139cf23SCaroline Tice   if (entry->arg_type != arg_type)
385e139cf23SCaroline Tice     entry = CommandObject::FindArgumentDataByType(arg_type);
386e139cf23SCaroline Tice 
387e139cf23SCaroline Tice   if (!entry)
388e139cf23SCaroline Tice     return;
389e139cf23SCaroline Tice 
390e139cf23SCaroline Tice   StreamString name_str;
391e139cf23SCaroline Tice   name_str.Printf("<%s>", entry->arg_name);
392e139cf23SCaroline Tice 
393b9c1b51eSKate Stone   if (entry->help_function) {
394e0038717SZachary Turner     llvm::StringRef help_text = entry->help_function();
395b9c1b51eSKate Stone     if (!entry->help_function.self_formatting) {
396c156427dSZachary Turner       interpreter.OutputFormattedHelpText(str, name_str.GetString(), "--",
397b9c1b51eSKate Stone                                           help_text, name_str.GetSize());
398b9c1b51eSKate Stone     } else {
399c156427dSZachary Turner       interpreter.OutputHelpText(str, name_str.GetString(), "--", help_text,
40082a7d983SEnrico Granata                                  name_str.GetSize());
40182a7d983SEnrico Granata     }
402*bcae3cdbSJonas Devlieghere   } else {
403c156427dSZachary Turner     interpreter.OutputFormattedHelpText(str, name_str.GetString(), "--",
404b9c1b51eSKate Stone                                         entry->help_text, name_str.GetSize());
405*bcae3cdbSJonas Devlieghere 
406*bcae3cdbSJonas Devlieghere     // Print enum values and their description if any.
407*bcae3cdbSJonas Devlieghere     OptionEnumValues enum_values = g_argument_table[arg_type].enum_values;
408*bcae3cdbSJonas Devlieghere     if (!enum_values.empty()) {
409*bcae3cdbSJonas Devlieghere       str.EOL();
410*bcae3cdbSJonas Devlieghere       size_t longest = 0;
411*bcae3cdbSJonas Devlieghere       for (const OptionEnumValueElement &element : enum_values)
412*bcae3cdbSJonas Devlieghere         longest =
413*bcae3cdbSJonas Devlieghere             std::max(longest, llvm::StringRef(element.string_value).size());
414*bcae3cdbSJonas Devlieghere       str.IndentMore(5);
415*bcae3cdbSJonas Devlieghere       for (const OptionEnumValueElement &element : enum_values) {
416*bcae3cdbSJonas Devlieghere         str.Indent();
417*bcae3cdbSJonas Devlieghere         interpreter.OutputHelpText(str, element.string_value, ":",
418*bcae3cdbSJonas Devlieghere                                    element.usage, longest);
419*bcae3cdbSJonas Devlieghere       }
420*bcae3cdbSJonas Devlieghere       str.IndentLess(5);
421*bcae3cdbSJonas Devlieghere       str.EOL();
422*bcae3cdbSJonas Devlieghere     }
423*bcae3cdbSJonas Devlieghere   }
424e139cf23SCaroline Tice }
425e139cf23SCaroline Tice 
GetArgumentName(CommandArgumentType arg_type)426b9c1b51eSKate Stone const char *CommandObject::GetArgumentName(CommandArgumentType arg_type) {
4277ced9fffSJonas Devlieghere   const ArgumentTableEntry *entry = &(g_argument_table[arg_type]);
428deaab222SCaroline Tice 
429b9c1b51eSKate Stone   // The table is *supposed* to be kept in arg_type order, but someone *could*
430b9c1b51eSKate Stone   // have messed it up...
431deaab222SCaroline Tice 
432deaab222SCaroline Tice   if (entry->arg_type != arg_type)
433deaab222SCaroline Tice     entry = CommandObject::FindArgumentDataByType(arg_type);
434deaab222SCaroline Tice 
435e6acf355SJohnny Chen   if (entry)
436deaab222SCaroline Tice     return entry->arg_name;
437e6acf355SJohnny Chen 
438c156427dSZachary Turner   return nullptr;
439e139cf23SCaroline Tice }
440e139cf23SCaroline Tice 
IsPairType(ArgumentRepetitionType arg_repeat_type)441b9c1b51eSKate Stone bool CommandObject::IsPairType(ArgumentRepetitionType arg_repeat_type) {
442a6682a41SJonas Devlieghere   return (arg_repeat_type == eArgRepeatPairPlain) ||
443b9c1b51eSKate Stone          (arg_repeat_type == eArgRepeatPairOptional) ||
444b9c1b51eSKate Stone          (arg_repeat_type == eArgRepeatPairPlus) ||
445b9c1b51eSKate Stone          (arg_repeat_type == eArgRepeatPairStar) ||
446b9c1b51eSKate Stone          (arg_repeat_type == eArgRepeatPairRange) ||
447a6682a41SJonas Devlieghere          (arg_repeat_type == eArgRepeatPairRangeOptional);
448405fe67fSCaroline Tice }
449405fe67fSCaroline Tice 
45034ddc8dbSJohnny Chen static CommandObject::CommandArgumentEntry
OptSetFiltered(uint32_t opt_set_mask,CommandObject::CommandArgumentEntry & cmd_arg_entry)451b9c1b51eSKate Stone OptSetFiltered(uint32_t opt_set_mask,
452b9c1b51eSKate Stone                CommandObject::CommandArgumentEntry &cmd_arg_entry) {
45334ddc8dbSJohnny Chen   CommandObject::CommandArgumentEntry ret_val;
45434ddc8dbSJohnny Chen   for (unsigned i = 0; i < cmd_arg_entry.size(); ++i)
45534ddc8dbSJohnny Chen     if (opt_set_mask & cmd_arg_entry[i].arg_opt_set_association)
45634ddc8dbSJohnny Chen       ret_val.push_back(cmd_arg_entry[i]);
45734ddc8dbSJohnny Chen   return ret_val;
45834ddc8dbSJohnny Chen }
45934ddc8dbSJohnny Chen 
46005097246SAdrian Prantl // Default parameter value of opt_set_mask is LLDB_OPT_SET_ALL, which means
46105097246SAdrian Prantl // take all the argument data into account.  On rare cases where some argument
46205097246SAdrian Prantl // sticks with certain option sets, this function returns the option set
46305097246SAdrian Prantl // filtered args.
GetFormattedCommandArguments(Stream & str,uint32_t opt_set_mask)464b9c1b51eSKate Stone void CommandObject::GetFormattedCommandArguments(Stream &str,
465b9c1b51eSKate Stone                                                  uint32_t opt_set_mask) {
466e139cf23SCaroline Tice   int num_args = m_arguments.size();
467b9c1b51eSKate Stone   for (int i = 0; i < num_args; ++i) {
468e139cf23SCaroline Tice     if (i > 0)
469e139cf23SCaroline Tice       str.Printf(" ");
47034ddc8dbSJohnny Chen     CommandArgumentEntry arg_entry =
471b9c1b51eSKate Stone         opt_set_mask == LLDB_OPT_SET_ALL
472b9c1b51eSKate Stone             ? m_arguments[i]
47334ddc8dbSJohnny Chen             : OptSetFiltered(opt_set_mask, m_arguments[i]);
47494038c57SVenkata Ramanaiah Nalamothu     // This argument is not associated with the current option set, so skip it.
47594038c57SVenkata Ramanaiah Nalamothu     if (arg_entry.empty())
47694038c57SVenkata Ramanaiah Nalamothu       continue;
477e139cf23SCaroline Tice     int num_alternatives = arg_entry.size();
478405fe67fSCaroline Tice 
479b9c1b51eSKate Stone     if ((num_alternatives == 2) && IsPairType(arg_entry[0].arg_repetition)) {
480405fe67fSCaroline Tice       const char *first_name = GetArgumentName(arg_entry[0].arg_type);
481405fe67fSCaroline Tice       const char *second_name = GetArgumentName(arg_entry[1].arg_type);
482b9c1b51eSKate Stone       switch (arg_entry[0].arg_repetition) {
483405fe67fSCaroline Tice       case eArgRepeatPairPlain:
484405fe67fSCaroline Tice         str.Printf("<%s> <%s>", first_name, second_name);
485405fe67fSCaroline Tice         break;
486405fe67fSCaroline Tice       case eArgRepeatPairOptional:
487405fe67fSCaroline Tice         str.Printf("[<%s> <%s>]", first_name, second_name);
488405fe67fSCaroline Tice         break;
489405fe67fSCaroline Tice       case eArgRepeatPairPlus:
490b9c1b51eSKate Stone         str.Printf("<%s> <%s> [<%s> <%s> [...]]", first_name, second_name,
491b9c1b51eSKate Stone                    first_name, second_name);
492405fe67fSCaroline Tice         break;
493405fe67fSCaroline Tice       case eArgRepeatPairStar:
494b9c1b51eSKate Stone         str.Printf("[<%s> <%s> [<%s> <%s> [...]]]", first_name, second_name,
495b9c1b51eSKate Stone                    first_name, second_name);
496405fe67fSCaroline Tice         break;
497405fe67fSCaroline Tice       case eArgRepeatPairRange:
498b9c1b51eSKate Stone         str.Printf("<%s_1> <%s_1> ... <%s_n> <%s_n>", first_name, second_name,
499b9c1b51eSKate Stone                    first_name, second_name);
500405fe67fSCaroline Tice         break;
501405fe67fSCaroline Tice       case eArgRepeatPairRangeOptional:
502b9c1b51eSKate Stone         str.Printf("[<%s_1> <%s_1> ... <%s_n> <%s_n>]", first_name, second_name,
503b9c1b51eSKate Stone                    first_name, second_name);
504405fe67fSCaroline Tice         break;
505b9c1b51eSKate Stone       // Explicitly test for all the rest of the cases, so if new types get
50605097246SAdrian Prantl       // added we will notice the missing case statement(s).
507ca1176aaSCaroline Tice       case eArgRepeatPlain:
508ca1176aaSCaroline Tice       case eArgRepeatOptional:
509ca1176aaSCaroline Tice       case eArgRepeatPlus:
510ca1176aaSCaroline Tice       case eArgRepeatStar:
511ca1176aaSCaroline Tice       case eArgRepeatRange:
512b9c1b51eSKate Stone         // These should not be reached, as they should fail the IsPairType test
513b9c1b51eSKate Stone         // above.
514ca1176aaSCaroline Tice         break;
515405fe67fSCaroline Tice       }
516b9c1b51eSKate Stone     } else {
517e139cf23SCaroline Tice       StreamString names;
518b9c1b51eSKate Stone       for (int j = 0; j < num_alternatives; ++j) {
519e139cf23SCaroline Tice         if (j > 0)
520e139cf23SCaroline Tice           names.Printf(" | ");
521e139cf23SCaroline Tice         names.Printf("%s", GetArgumentName(arg_entry[j].arg_type));
522e139cf23SCaroline Tice       }
523c156427dSZachary Turner 
524adcd0268SBenjamin Kramer       std::string name_str = std::string(names.GetString());
525b9c1b51eSKate Stone       switch (arg_entry[0].arg_repetition) {
526e139cf23SCaroline Tice       case eArgRepeatPlain:
527c156427dSZachary Turner         str.Printf("<%s>", name_str.c_str());
528e139cf23SCaroline Tice         break;
529e139cf23SCaroline Tice       case eArgRepeatPlus:
530c156427dSZachary Turner         str.Printf("<%s> [<%s> [...]]", name_str.c_str(), name_str.c_str());
531e139cf23SCaroline Tice         break;
532e139cf23SCaroline Tice       case eArgRepeatStar:
533c156427dSZachary Turner         str.Printf("[<%s> [<%s> [...]]]", name_str.c_str(), name_str.c_str());
534e139cf23SCaroline Tice         break;
535e139cf23SCaroline Tice       case eArgRepeatOptional:
536c156427dSZachary Turner         str.Printf("[<%s>]", name_str.c_str());
537e139cf23SCaroline Tice         break;
538405fe67fSCaroline Tice       case eArgRepeatRange:
539c156427dSZachary Turner         str.Printf("<%s_1> .. <%s_n>", name_str.c_str(), name_str.c_str());
540ca1176aaSCaroline Tice         break;
541b9c1b51eSKate Stone       // Explicitly test for all the rest of the cases, so if new types get
54205097246SAdrian Prantl       // added we will notice the missing case statement(s).
543ca1176aaSCaroline Tice       case eArgRepeatPairPlain:
544ca1176aaSCaroline Tice       case eArgRepeatPairOptional:
545ca1176aaSCaroline Tice       case eArgRepeatPairPlus:
546ca1176aaSCaroline Tice       case eArgRepeatPairStar:
547ca1176aaSCaroline Tice       case eArgRepeatPairRange:
548ca1176aaSCaroline Tice       case eArgRepeatPairRangeOptional:
549b9c1b51eSKate Stone         // These should not be hit, as they should pass the IsPairType test
55005097246SAdrian Prantl         // above, and control should have gone into the other branch of the if
55105097246SAdrian Prantl         // statement.
552ca1176aaSCaroline Tice         break;
553405fe67fSCaroline Tice       }
554e139cf23SCaroline Tice     }
555e139cf23SCaroline Tice   }
556e139cf23SCaroline Tice }
557e139cf23SCaroline Tice 
55814f6b2c0SZachary Turner CommandArgumentType
LookupArgumentName(llvm::StringRef arg_name)55914f6b2c0SZachary Turner CommandObject::LookupArgumentName(llvm::StringRef arg_name) {
560e139cf23SCaroline Tice   CommandArgumentType return_type = eArgTypeLastArg;
561e139cf23SCaroline Tice 
56214f6b2c0SZachary Turner   arg_name = arg_name.ltrim('<').rtrim('>');
563e139cf23SCaroline Tice 
564e139cf23SCaroline Tice   for (int i = 0; i < eArgTypeLastArg; ++i)
5657ced9fffSJonas Devlieghere     if (arg_name == g_argument_table[i].arg_name)
5667ced9fffSJonas Devlieghere       return_type = g_argument_table[i].arg_type;
567e139cf23SCaroline Tice 
568e139cf23SCaroline Tice   return return_type;
569e139cf23SCaroline Tice }
570e139cf23SCaroline Tice 
FormatLongHelpText(Stream & output_strm,llvm::StringRef long_help)571b9c1b51eSKate Stone void CommandObject::FormatLongHelpText(Stream &output_strm,
572442f6530SZachary Turner                                        llvm::StringRef long_help) {
573ea671fbdSKate Stone   CommandInterpreter &interpreter = GetCommandInterpreter();
574adcd0268SBenjamin Kramer   std::stringstream lineStream{std::string(long_help)};
575ea671fbdSKate Stone   std::string line;
576ea671fbdSKate Stone   while (std::getline(lineStream, line)) {
577ea671fbdSKate Stone     if (line.empty()) {
578ea671fbdSKate Stone       output_strm << "\n";
579ea671fbdSKate Stone       continue;
580ea671fbdSKate Stone     }
581ea671fbdSKate Stone     size_t result = line.find_first_not_of(" \t");
582ea671fbdSKate Stone     if (result == std::string::npos) {
583ea671fbdSKate Stone       result = 0;
584ea671fbdSKate Stone     }
585ea671fbdSKate Stone     std::string whitespace_prefix = line.substr(0, result);
586ea671fbdSKate Stone     std::string remainder = line.substr(result);
587ff058e73SJonas Devlieghere     interpreter.OutputFormattedHelpText(output_strm, whitespace_prefix,
588ff058e73SJonas Devlieghere                                         remainder);
589ea671fbdSKate Stone   }
590ea671fbdSKate Stone }
591ea671fbdSKate Stone 
GenerateHelpText(CommandReturnObject & result)592b9c1b51eSKate Stone void CommandObject::GenerateHelpText(CommandReturnObject &result) {
5939b62d1d5SEnrico Granata   GenerateHelpText(result.GetOutputStream());
5949b62d1d5SEnrico Granata 
5959b62d1d5SEnrico Granata   result.SetStatus(eReturnStatusSuccessFinishNoResult);
5969b62d1d5SEnrico Granata }
5979b62d1d5SEnrico Granata 
GenerateHelpText(Stream & output_strm)598b9c1b51eSKate Stone void CommandObject::GenerateHelpText(Stream &output_strm) {
5999b62d1d5SEnrico Granata   CommandInterpreter &interpreter = GetCommandInterpreter();
6009b62d1d5SEnrico Granata   std::string help_text(GetHelp());
601d7432360SJonas Devlieghere   if (WantsRawCommandString()) {
6027428a18cSKate Stone     help_text.append("  Expects 'raw' input (see 'help raw-input'.)");
603d7432360SJonas Devlieghere   }
604d7432360SJonas Devlieghere   interpreter.OutputFormattedHelpText(output_strm, "", help_text);
60503c9f364SZachary Turner   output_strm << "\nSyntax: " << GetSyntax() << "\n";
6067428a18cSKate Stone   Options *options = GetOptions();
607b9c1b51eSKate Stone   if (options != nullptr) {
608b9c1b51eSKate Stone     options->GenerateOptionUsage(
609e473e79cSDavid Spickett         output_strm, *this,
610b9c1b51eSKate Stone         GetCommandInterpreter().GetDebugger().GetTerminalWidth());
6117428a18cSKate Stone   }
612442f6530SZachary Turner   llvm::StringRef long_help = GetHelpLong();
613442f6530SZachary Turner   if (!long_help.empty()) {
614ea671fbdSKate Stone     FormatLongHelpText(output_strm, long_help);
6157428a18cSKate Stone   }
616b9c1b51eSKate Stone   if (!IsDashDashCommand() && options && options->NumCommandOptions() > 0) {
617b9c1b51eSKate Stone     if (WantsRawCommandString() && !WantsCompletion()) {
618b9c1b51eSKate Stone       // Emit the message about using ' -- ' between the end of the command
61905097246SAdrian Prantl       // options and the raw input conditionally, i.e., only if the command
62005097246SAdrian Prantl       // object does not want completion.
6217428a18cSKate Stone       interpreter.OutputFormattedHelpText(
6227428a18cSKate Stone           output_strm, "", "",
623b9c1b51eSKate Stone           "\nImportant Note: Because this command takes 'raw' input, if you "
624b9c1b51eSKate Stone           "use any command options"
625b9c1b51eSKate Stone           " you must use ' -- ' between the end of the command options and the "
626b9c1b51eSKate Stone           "beginning of the raw input.",
6277428a18cSKate Stone           1);
628b9c1b51eSKate Stone     } else if (GetNumArgumentEntries() > 0) {
629b9c1b51eSKate Stone       // Also emit a warning about using "--" in case you are using a command
630b9c1b51eSKate Stone       // that takes options and arguments.
6317428a18cSKate Stone       interpreter.OutputFormattedHelpText(
632b9c1b51eSKate Stone           output_strm, "", "",
633b9c1b51eSKate Stone           "\nThis command takes options and free-form arguments.  If your "
634b9c1b51eSKate Stone           "arguments resemble"
635b9c1b51eSKate Stone           " option specifiers (i.e., they start with a - or --), you must use "
636b9c1b51eSKate Stone           "' -- ' between"
6377428a18cSKate Stone           " the end of the command options and the beginning of the arguments.",
6387428a18cSKate Stone           1);
6399b62d1d5SEnrico Granata     }
6409b62d1d5SEnrico Granata   }
641bfb75e9bSEnrico Granata }
6429b62d1d5SEnrico Granata 
AddIDsArgumentData(CommandArgumentEntry & arg,CommandArgumentType ID,CommandArgumentType IDRange)643b9c1b51eSKate Stone void CommandObject::AddIDsArgumentData(CommandArgumentEntry &arg,
644b9c1b51eSKate Stone                                        CommandArgumentType ID,
645b9c1b51eSKate Stone                                        CommandArgumentType IDRange) {
646184d7a72SJohnny Chen   CommandArgumentData id_arg;
647184d7a72SJohnny Chen   CommandArgumentData id_range_arg;
648184d7a72SJohnny Chen 
649b9c1b51eSKate Stone   // Create the first variant for the first (and only) argument for this
650b9c1b51eSKate Stone   // command.
651de753464SJohnny Chen   id_arg.arg_type = ID;
652184d7a72SJohnny Chen   id_arg.arg_repetition = eArgRepeatOptional;
653184d7a72SJohnny Chen 
654b9c1b51eSKate Stone   // Create the second variant for the first (and only) argument for this
655b9c1b51eSKate Stone   // command.
656de753464SJohnny Chen   id_range_arg.arg_type = IDRange;
657184d7a72SJohnny Chen   id_range_arg.arg_repetition = eArgRepeatOptional;
658184d7a72SJohnny Chen 
659b9c1b51eSKate Stone   // The first (and only) argument for this command could be either an id or an
66005097246SAdrian Prantl   // id_range. Push both variants into the entry for the first argument for
66105097246SAdrian Prantl   // this command.
662184d7a72SJohnny Chen   arg.push_back(id_arg);
663184d7a72SJohnny Chen   arg.push_back(id_range_arg);
664184d7a72SJohnny Chen }
665184d7a72SJohnny Chen 
GetArgumentTypeAsCString(const lldb::CommandArgumentType arg_type)666b9c1b51eSKate Stone const char *CommandObject::GetArgumentTypeAsCString(
667b9c1b51eSKate Stone     const lldb::CommandArgumentType arg_type) {
668b9c1b51eSKate Stone   assert(arg_type < eArgTypeLastArg &&
669b9c1b51eSKate Stone          "Invalid argument type passed to GetArgumentTypeAsCString");
6707ced9fffSJonas Devlieghere   return g_argument_table[arg_type].arg_name;
6719d0402b1SGreg Clayton }
6729d0402b1SGreg Clayton 
GetArgumentDescriptionAsCString(const lldb::CommandArgumentType arg_type)673b9c1b51eSKate Stone const char *CommandObject::GetArgumentDescriptionAsCString(
674b9c1b51eSKate Stone     const lldb::CommandArgumentType arg_type) {
675b9c1b51eSKate Stone   assert(arg_type < eArgTypeLastArg &&
676b9c1b51eSKate Stone          "Invalid argument type passed to GetArgumentDescriptionAsCString");
6777ced9fffSJonas Devlieghere   return g_argument_table[arg_type].help_text;
6789d0402b1SGreg Clayton }
6799d0402b1SGreg Clayton 
GetDummyTarget()680cb2380c9SRaphael Isemann Target &CommandObject::GetDummyTarget() {
681b2fa3b92SJonas Devlieghere   return m_interpreter.GetDebugger().GetDummyTarget();
682893c932aSJim Ingham }
683893c932aSJim Ingham 
GetSelectedOrDummyTarget(bool prefer_dummy)684cb2380c9SRaphael Isemann Target &CommandObject::GetSelectedOrDummyTarget(bool prefer_dummy) {
685b2fa3b92SJonas Devlieghere   return m_interpreter.GetDebugger().GetSelectedOrDummyTarget(prefer_dummy);
686893c932aSJim Ingham }
687893c932aSJim Ingham 
GetSelectedTarget()68804a4c091SRaphael Isemann Target &CommandObject::GetSelectedTarget() {
68904a4c091SRaphael Isemann   assert(m_flags.AnySet(eCommandRequiresTarget | eCommandProcessMustBePaused |
69004a4c091SRaphael Isemann                         eCommandProcessMustBeLaunched | eCommandRequiresFrame |
69104a4c091SRaphael Isemann                         eCommandRequiresThread | eCommandRequiresProcess |
69204a4c091SRaphael Isemann                         eCommandRequiresRegContext) &&
69304a4c091SRaphael Isemann          "GetSelectedTarget called from object that may have no target");
69404a4c091SRaphael Isemann   return *m_interpreter.GetDebugger().GetSelectedTarget();
69504a4c091SRaphael Isemann }
69604a4c091SRaphael Isemann 
GetDefaultThread()697b9c1b51eSKate Stone Thread *CommandObject::GetDefaultThread() {
6988d94ba0fSJim Ingham   Thread *thread_to_use = m_exe_ctx.GetThreadPtr();
6998d94ba0fSJim Ingham   if (thread_to_use)
7008d94ba0fSJim Ingham     return thread_to_use;
7018d94ba0fSJim Ingham 
7028d94ba0fSJim Ingham   Process *process = m_exe_ctx.GetProcessPtr();
703b9c1b51eSKate Stone   if (!process) {
7048d94ba0fSJim Ingham     Target *target = m_exe_ctx.GetTargetPtr();
705b9c1b51eSKate Stone     if (!target) {
7068d94ba0fSJim Ingham       target = m_interpreter.GetDebugger().GetSelectedTarget().get();
7078d94ba0fSJim Ingham     }
7088d94ba0fSJim Ingham     if (target)
7098d94ba0fSJim Ingham       process = target->GetProcessSP().get();
7108d94ba0fSJim Ingham   }
7118d94ba0fSJim Ingham 
7128d94ba0fSJim Ingham   if (process)
7138d94ba0fSJim Ingham     return process->GetThreadList().GetSelectedThread().get();
7148d94ba0fSJim Ingham   else
7158d94ba0fSJim Ingham     return nullptr;
7168d94ba0fSJim Ingham }
7178d94ba0fSJim Ingham 
Execute(const char * args_string,CommandReturnObject & result)718b9c1b51eSKate Stone bool CommandObjectParsed::Execute(const char *args_string,
719b9c1b51eSKate Stone                                   CommandReturnObject &result) {
7205a988416SJim Ingham   bool handled = false;
7215a988416SJim Ingham   Args cmd_args(args_string);
722b9c1b51eSKate Stone   if (HasOverrideCallback()) {
7235a988416SJim Ingham     Args full_args(GetCommandName());
7245a988416SJim Ingham     full_args.AppendArguments(cmd_args);
725b9c1b51eSKate Stone     handled =
726b9c1b51eSKate Stone         InvokeOverrideCallback(full_args.GetConstArgumentVector(), result);
7275a988416SJim Ingham   }
728b9c1b51eSKate Stone   if (!handled) {
72997d2c401SZachary Turner     for (auto entry : llvm::enumerate(cmd_args.entries())) {
7300d9a201eSRaphael Isemann       if (!entry.value().ref().empty() && entry.value().ref().front() == '`') {
731b9c1b51eSKate Stone         cmd_args.ReplaceArgumentAtIndex(
7324eb8449dSZachary Turner             entry.index(),
7334eb8449dSZachary Turner             m_interpreter.ProcessEmbeddedScriptCommands(entry.value().c_str()));
73497d2c401SZachary Turner       }
7355a988416SJim Ingham     }
7365a988416SJim Ingham 
737b9c1b51eSKate Stone     if (CheckRequirements(result)) {
738b9c1b51eSKate Stone       if (ParseOptions(cmd_args, result)) {
739b9c1b51eSKate Stone         // Call the command-specific version of 'Execute', passing it the
740b9c1b51eSKate Stone         // already processed arguments.
741c1b07d61SJim Ingham         if (cmd_args.GetArgumentCount() != 0 && m_arguments.empty()) {
742c1b07d61SJim Ingham           result.AppendErrorWithFormatv("'{0}' doesn't take any arguments.",
743c1b07d61SJim Ingham                                         GetCommandName());
744c1b07d61SJim Ingham           return false;
745c1b07d61SJim Ingham         }
7465a988416SJim Ingham         handled = DoExecute(cmd_args, result);
7475a988416SJim Ingham       }
748f9fc609fSGreg Clayton     }
749f9fc609fSGreg Clayton 
750f9fc609fSGreg Clayton     Cleanup();
751f9fc609fSGreg Clayton   }
7525a988416SJim Ingham   return handled;
7535a988416SJim Ingham }
7545a988416SJim Ingham 
Execute(const char * args_string,CommandReturnObject & result)755b9c1b51eSKate Stone bool CommandObjectRaw::Execute(const char *args_string,
756b9c1b51eSKate Stone                                CommandReturnObject &result) {
7575a988416SJim Ingham   bool handled = false;
758b9c1b51eSKate Stone   if (HasOverrideCallback()) {
7595a988416SJim Ingham     std::string full_command(GetCommandName());
7605a988416SJim Ingham     full_command += ' ';
7615a988416SJim Ingham     full_command += args_string;
762d78c9576SEd Maste     const char *argv[2] = {nullptr, nullptr};
7635a988416SJim Ingham     argv[0] = full_command.c_str();
7643b652621SJim Ingham     handled = InvokeOverrideCallback(argv, result);
7655a988416SJim Ingham   }
766b9c1b51eSKate Stone   if (!handled) {
767f9fc609fSGreg Clayton     if (CheckRequirements(result))
7685a988416SJim Ingham       handled = DoExecute(args_string, result);
769f9fc609fSGreg Clayton 
770f9fc609fSGreg Clayton     Cleanup();
7715a988416SJim Ingham   }
7725a988416SJim Ingham   return handled;
7735a988416SJim Ingham }
774