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