1 //===-- SBCommandInterpreter.cpp --------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
12 // Other libraries and framework includes
14 #include "lldb/lldb-types.h"
16 #include "lldb/Core/Listener.h"
17 #include "lldb/Interpreter/CommandInterpreter.h"
18 #include "lldb/Interpreter/CommandObjectMultiword.h"
19 #include "lldb/Interpreter/CommandReturnObject.h"
20 #include "lldb/Target/Target.h"
22 #include "lldb/API/SBBroadcaster.h"
23 #include "lldb/API/SBCommandReturnObject.h"
24 #include "lldb/API/SBCommandInterpreter.h"
25 #include "lldb/API/SBEvent.h"
26 #include "lldb/API/SBExecutionContext.h"
27 #include "lldb/API/SBProcess.h"
28 #include "lldb/API/SBTarget.h"
29 #include "lldb/API/SBListener.h"
30 #include "lldb/API/SBStream.h"
31 #include "lldb/API/SBStringList.h"
34 using namespace lldb_private;
36 SBCommandInterpreterRunOptions::SBCommandInterpreterRunOptions()
38 m_opaque_up.reset(new CommandInterpreterRunOptions());
41 SBCommandInterpreterRunOptions::~SBCommandInterpreterRunOptions() = default;
44 SBCommandInterpreterRunOptions::GetStopOnContinue () const
46 return m_opaque_up->GetStopOnContinue();
50 SBCommandInterpreterRunOptions::SetStopOnContinue (bool stop_on_continue)
52 m_opaque_up->SetStopOnContinue(stop_on_continue);
56 SBCommandInterpreterRunOptions::GetStopOnError () const
58 return m_opaque_up->GetStopOnError();
62 SBCommandInterpreterRunOptions::SetStopOnError (bool stop_on_error)
64 m_opaque_up->SetStopOnError(stop_on_error);
68 SBCommandInterpreterRunOptions::GetStopOnCrash () const
70 return m_opaque_up->GetStopOnCrash();
74 SBCommandInterpreterRunOptions::SetStopOnCrash (bool stop_on_crash)
76 m_opaque_up->SetStopOnCrash(stop_on_crash);
80 SBCommandInterpreterRunOptions::GetEchoCommands () const
82 return m_opaque_up->GetEchoCommands();
86 SBCommandInterpreterRunOptions::SetEchoCommands (bool echo_commands)
88 m_opaque_up->SetEchoCommands(echo_commands);
92 SBCommandInterpreterRunOptions::GetPrintResults () const
94 return m_opaque_up->GetPrintResults();
98 SBCommandInterpreterRunOptions::SetPrintResults (bool print_results)
100 m_opaque_up->SetPrintResults(print_results);
104 SBCommandInterpreterRunOptions::GetAddToHistory () const
106 return m_opaque_up->GetAddToHistory();
110 SBCommandInterpreterRunOptions::SetAddToHistory (bool add_to_history)
112 m_opaque_up->SetAddToHistory(add_to_history);
115 lldb_private::CommandInterpreterRunOptions *
116 SBCommandInterpreterRunOptions::get () const
118 return m_opaque_up.get();
121 lldb_private::CommandInterpreterRunOptions &
122 SBCommandInterpreterRunOptions::ref () const
124 return *m_opaque_up.get();
127 class CommandPluginInterfaceImplementation : public CommandObjectParsed
130 CommandPluginInterfaceImplementation(CommandInterpreter &interpreter,
132 lldb::SBCommandPluginInterface* backend,
133 const char *help = nullptr,
134 const char *syntax = nullptr,
135 uint32_t flags = 0) :
136 CommandObjectParsed (interpreter, name, help, syntax, flags),
137 m_backend(backend) {}
140 IsRemovable() const override
147 DoExecute(Args& command, CommandReturnObject &result) override
149 SBCommandReturnObject sb_return(&result);
150 SBCommandInterpreter sb_interpreter(&m_interpreter);
151 SBDebugger debugger_sb(m_interpreter.GetDebugger().shared_from_this());
152 bool ret = m_backend->DoExecute (debugger_sb,(char**)command.GetArgumentVector(), sb_return);
156 lldb::SBCommandPluginInterface* m_backend;
159 SBCommandInterpreter::SBCommandInterpreter (CommandInterpreter *interpreter) :
160 m_opaque_ptr (interpreter)
162 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
165 log->Printf ("SBCommandInterpreter::SBCommandInterpreter (interpreter=%p)"
166 " => SBCommandInterpreter(%p)",
167 static_cast<void*>(interpreter),
168 static_cast<void*>(m_opaque_ptr));
171 SBCommandInterpreter::SBCommandInterpreter(const SBCommandInterpreter &rhs) :
172 m_opaque_ptr (rhs.m_opaque_ptr)
176 SBCommandInterpreter::~SBCommandInterpreter() = default;
178 const SBCommandInterpreter &
179 SBCommandInterpreter::operator = (const SBCommandInterpreter &rhs)
181 m_opaque_ptr = rhs.m_opaque_ptr;
186 SBCommandInterpreter::IsValid() const
188 return m_opaque_ptr != nullptr;
192 SBCommandInterpreter::CommandExists(const char *cmd)
194 return (((cmd != nullptr) && IsValid()) ? m_opaque_ptr->CommandExists(cmd) : false);
198 SBCommandInterpreter::AliasExists (const char *cmd)
200 return (((cmd != nullptr) && IsValid()) ? m_opaque_ptr->AliasExists(cmd) : false);
204 SBCommandInterpreter::IsActive()
206 return (IsValid() ? m_opaque_ptr->IsActive() : false);
210 SBCommandInterpreter::GetIOHandlerControlSequence(char ch)
212 return (IsValid() ? m_opaque_ptr->GetDebugger().GetTopIOHandlerControlSequence(ch).GetCString() : nullptr);
216 SBCommandInterpreter::HandleCommand (const char *command_line, SBCommandReturnObject &result, bool add_to_history)
218 SBExecutionContext sb_exe_ctx;
219 return HandleCommand (command_line, sb_exe_ctx, result, add_to_history);
223 SBCommandInterpreter::HandleCommand (const char *command_line, SBExecutionContext &override_context, SBCommandReturnObject &result, bool add_to_history)
225 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
228 log->Printf ("SBCommandInterpreter(%p)::HandleCommand (command=\"%s\", SBCommandReturnObject(%p), add_to_history=%i)",
229 static_cast<void*>(m_opaque_ptr), command_line,
230 static_cast<void*>(result.get()), add_to_history);
232 ExecutionContext ctx, *ctx_ptr;
233 if (override_context.get())
235 ctx = override_context.get()->Lock(true);
243 if (command_line && IsValid())
245 result.ref().SetInteractive(false);
246 m_opaque_ptr->HandleCommand (command_line, add_to_history ? eLazyBoolYes : eLazyBoolNo, result.ref(), ctx_ptr);
250 result->AppendError ("SBCommandInterpreter or the command line is not valid");
251 result->SetStatus (eReturnStatusFailed);
254 // We need to get the value again, in case the command disabled the log!
255 log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API);
259 result.GetDescription (sstr);
260 log->Printf ("SBCommandInterpreter(%p)::HandleCommand (command=\"%s\", SBCommandReturnObject(%p): %s, add_to_history=%i) => %i",
261 static_cast<void*>(m_opaque_ptr), command_line,
262 static_cast<void*>(result.get()), sstr.GetData(),
263 add_to_history, result.GetStatus());
266 return result.GetStatus();
270 SBCommandInterpreter::HandleCommandsFromFile (lldb::SBFileSpec &file,
271 lldb::SBExecutionContext &override_context,
272 lldb::SBCommandInterpreterRunOptions &options,
273 lldb::SBCommandReturnObject result)
275 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
280 file.GetDescription (s);
281 log->Printf ("SBCommandInterpreter(%p)::HandleCommandsFromFile (file=\"%s\", SBCommandReturnObject(%p))",
282 static_cast<void*>(m_opaque_ptr), s.GetData(),
283 static_cast<void*>(result.get()));
288 result->AppendError ("SBCommandInterpreter is not valid.");
289 result->SetStatus (eReturnStatusFailed);
296 file.GetDescription (s);
297 result->AppendErrorWithFormat ("File is not valid: %s.", s.GetData());
298 result->SetStatus (eReturnStatusFailed);
301 FileSpec tmp_spec = file.ref();
302 ExecutionContext ctx, *ctx_ptr;
303 if (override_context.get())
305 ctx = override_context.get()->Lock(true);
311 m_opaque_ptr->HandleCommandsFromFile (tmp_spec, ctx_ptr, options.ref(), result.ref());
315 SBCommandInterpreter::HandleCompletion (const char *current_line,
317 const char *last_char,
318 int match_start_point,
319 int max_return_elements,
320 SBStringList &matches)
322 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
323 int num_completions = 0;
325 // Sanity check the arguments that are passed in:
326 // cursor & last_char have to be within the current_line.
327 if (current_line == nullptr || cursor == nullptr || last_char == nullptr)
330 if (cursor < current_line || last_char < current_line)
333 size_t current_line_size = strlen (current_line);
334 if (cursor - current_line > static_cast<ptrdiff_t>(current_line_size) ||
335 last_char - current_line > static_cast<ptrdiff_t>(current_line_size))
339 log->Printf ("SBCommandInterpreter(%p)::HandleCompletion (current_line=\"%s\", cursor at: %" PRId64 ", last char at: %" PRId64 ", match_start_point: %d, max_return_elements: %d)",
340 static_cast<void*>(m_opaque_ptr), current_line,
341 static_cast<uint64_t>(cursor - current_line),
342 static_cast<uint64_t>(last_char - current_line),
343 match_start_point, max_return_elements);
347 lldb_private::StringList lldb_matches;
348 num_completions = m_opaque_ptr->HandleCompletion(current_line, cursor, last_char, match_start_point,
349 max_return_elements, lldb_matches);
351 SBStringList temp_list (&lldb_matches);
352 matches.AppendList (temp_list);
355 log->Printf ("SBCommandInterpreter(%p)::HandleCompletion - Found %d completions.",
356 static_cast<void*>(m_opaque_ptr), num_completions);
358 return num_completions;
362 SBCommandInterpreter::HandleCompletion (const char *current_line,
364 int match_start_point,
365 int max_return_elements,
366 lldb::SBStringList &matches)
368 const char *cursor = current_line + cursor_pos;
369 const char *last_char = current_line + strlen (current_line);
370 return HandleCompletion (current_line, cursor, last_char, match_start_point, max_return_elements, matches);
374 SBCommandInterpreter::HasCommands()
376 return (IsValid() ? m_opaque_ptr->HasCommands() : false);
380 SBCommandInterpreter::HasAliases()
382 return (IsValid() ? m_opaque_ptr->HasAliases() : false);
386 SBCommandInterpreter::HasAliasOptions()
388 return (IsValid() ? m_opaque_ptr->HasAliasOptions() : false);
392 SBCommandInterpreter::GetProcess ()
394 SBProcess sb_process;
395 ProcessSP process_sp;
398 TargetSP target_sp(m_opaque_ptr->GetDebugger().GetSelectedTarget());
401 std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
402 process_sp = target_sp->GetProcessSP();
403 sb_process.SetSP(process_sp);
406 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
409 log->Printf ("SBCommandInterpreter(%p)::GetProcess () => SBProcess(%p)",
410 static_cast<void*>(m_opaque_ptr),
411 static_cast<void*>(process_sp.get()));
417 SBCommandInterpreter::GetDebugger ()
419 SBDebugger sb_debugger;
421 sb_debugger.reset(m_opaque_ptr->GetDebugger().shared_from_this());
422 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
425 log->Printf ("SBCommandInterpreter(%p)::GetDebugger () => SBDebugger(%p)",
426 static_cast<void*>(m_opaque_ptr),
427 static_cast<void*>(sb_debugger.get()));
433 SBCommandInterpreter::GetPromptOnQuit()
435 return (IsValid() ? m_opaque_ptr->GetPromptOnQuit() : false);
439 SBCommandInterpreter::SetPromptOnQuit (bool b)
442 m_opaque_ptr->SetPromptOnQuit(b);
446 SBCommandInterpreter::ResolveCommand(const char *command_line, SBCommandReturnObject &result)
449 if (command_line && IsValid())
451 m_opaque_ptr->ResolveCommand(command_line, result.ref());
455 result->AppendError("SBCommandInterpreter or the command line is not valid");
456 result->SetStatus(eReturnStatusFailed);
461 SBCommandInterpreter::get ()
467 SBCommandInterpreter::ref ()
469 assert (m_opaque_ptr);
470 return *m_opaque_ptr;
474 SBCommandInterpreter::reset (lldb_private::CommandInterpreter *interpreter)
476 m_opaque_ptr = interpreter;
480 SBCommandInterpreter::SourceInitFileInHomeDirectory (SBCommandReturnObject &result)
485 TargetSP target_sp(m_opaque_ptr->GetDebugger().GetSelectedTarget());
486 std::unique_lock<std::recursive_mutex> lock;
488 lock = std::unique_lock<std::recursive_mutex>(target_sp->GetAPIMutex());
489 m_opaque_ptr->SourceInitFile (false, result.ref());
493 result->AppendError ("SBCommandInterpreter is not valid");
494 result->SetStatus (eReturnStatusFailed);
496 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
499 log->Printf ("SBCommandInterpreter(%p)::SourceInitFileInHomeDirectory (&SBCommandReturnObject(%p))",
500 static_cast<void*>(m_opaque_ptr),
501 static_cast<void*>(result.get()));
505 SBCommandInterpreter::SourceInitFileInCurrentWorkingDirectory (SBCommandReturnObject &result)
510 TargetSP target_sp(m_opaque_ptr->GetDebugger().GetSelectedTarget());
511 std::unique_lock<std::recursive_mutex> lock;
513 lock = std::unique_lock<std::recursive_mutex>(target_sp->GetAPIMutex());
514 m_opaque_ptr->SourceInitFile (true, result.ref());
518 result->AppendError ("SBCommandInterpreter is not valid");
519 result->SetStatus (eReturnStatusFailed);
521 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
524 log->Printf ("SBCommandInterpreter(%p)::SourceInitFileInCurrentWorkingDirectory (&SBCommandReturnObject(%p))",
525 static_cast<void*>(m_opaque_ptr),
526 static_cast<void*>(result.get()));
530 SBCommandInterpreter::GetBroadcaster ()
532 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
534 SBBroadcaster broadcaster (m_opaque_ptr, false);
537 log->Printf ("SBCommandInterpreter(%p)::GetBroadcaster() => SBBroadcaster(%p)",
538 static_cast<void*>(m_opaque_ptr), static_cast<void*>(broadcaster.get()));
544 SBCommandInterpreter::GetBroadcasterClass ()
546 return CommandInterpreter::GetStaticBroadcasterClass().AsCString();
550 SBCommandInterpreter::GetArgumentTypeAsCString (const lldb::CommandArgumentType arg_type)
552 return CommandObject::GetArgumentTypeAsCString (arg_type);
556 SBCommandInterpreter::GetArgumentDescriptionAsCString (const lldb::CommandArgumentType arg_type)
558 return CommandObject::GetArgumentDescriptionAsCString (arg_type);
562 SBCommandInterpreter::EventIsCommandInterpreterEvent (const lldb::SBEvent &event)
564 return event.GetBroadcasterClass() == SBCommandInterpreter::GetBroadcasterClass();
568 SBCommandInterpreter::SetCommandOverrideCallback (const char *command_name,
569 lldb::CommandOverrideCallback callback,
572 if (command_name && command_name[0] && IsValid())
574 std::string command_name_str (command_name);
575 CommandObject *cmd_obj = m_opaque_ptr->GetCommandObjectForCommand(command_name_str);
578 assert(command_name_str.empty());
579 cmd_obj->SetOverrideCallback (callback, baton);
587 SBCommandInterpreter::AddMultiwordCommand (const char* name, const char* help)
589 CommandObjectMultiword *new_command = new CommandObjectMultiword(*m_opaque_ptr, name, help);
590 new_command->SetRemovable (true);
591 lldb::CommandObjectSP new_command_sp(new_command);
592 if (new_command_sp && m_opaque_ptr->AddUserCommand(name, new_command_sp, true))
593 return lldb::SBCommand(new_command_sp);
594 return lldb::SBCommand();
598 SBCommandInterpreter::AddCommand (const char* name, lldb::SBCommandPluginInterface* impl, const char* help)
600 lldb::CommandObjectSP new_command_sp;
601 new_command_sp.reset(new CommandPluginInterfaceImplementation(*m_opaque_ptr,name, impl, help));
603 if (new_command_sp && m_opaque_ptr->AddUserCommand(name, new_command_sp, true))
604 return lldb::SBCommand(new_command_sp);
605 return lldb::SBCommand();
608 SBCommand::SBCommand() = default;
610 SBCommand::SBCommand (lldb::CommandObjectSP cmd_sp) : m_opaque_sp (cmd_sp)
616 return m_opaque_sp.get() != nullptr;
622 return (IsValid() ? m_opaque_sp->GetCommandName() : nullptr);
628 return (IsValid() ? m_opaque_sp->GetHelp() : nullptr);
632 SBCommand::GetHelpLong()
634 return (IsValid() ? m_opaque_sp->GetHelpLong() : nullptr);
638 SBCommand::SetHelp (const char* help)
641 m_opaque_sp->SetHelp(help);
645 SBCommand::SetHelpLong (const char* help)
648 m_opaque_sp->SetHelpLong(help);
652 SBCommand::AddMultiwordCommand (const char* name, const char* help)
655 return lldb::SBCommand();
656 if (!m_opaque_sp->IsMultiwordObject())
657 return lldb::SBCommand();
658 CommandObjectMultiword *new_command = new CommandObjectMultiword(m_opaque_sp->GetCommandInterpreter(),name,help);
659 new_command->SetRemovable (true);
660 lldb::CommandObjectSP new_command_sp(new_command);
661 if (new_command_sp && m_opaque_sp->LoadSubCommand(name,new_command_sp))
662 return lldb::SBCommand(new_command_sp);
663 return lldb::SBCommand();
667 SBCommand::AddCommand (const char* name, lldb::SBCommandPluginInterface *impl, const char* help)
670 return lldb::SBCommand();
671 if (!m_opaque_sp->IsMultiwordObject())
672 return lldb::SBCommand();
673 lldb::CommandObjectSP new_command_sp;
674 new_command_sp.reset(new CommandPluginInterfaceImplementation(m_opaque_sp->GetCommandInterpreter(),name,impl,help));
675 if (new_command_sp && m_opaque_sp->LoadSubCommand(name,new_command_sp))
676 return lldb::SBCommand(new_command_sp);
677 return lldb::SBCommand();
681 SBCommand::GetFlags ()
683 return (IsValid() ? m_opaque_sp->GetFlags().Get() : 0);
687 SBCommand::SetFlags (uint32_t flags)
690 m_opaque_sp->GetFlags().Set(flags);