1 //===-- SBDebugger.cpp ------------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "lldb/API/SBDebugger.h"
11 
12 #include "lldb/lldb-private.h"
13 
14 #include "lldb/API/SBListener.h"
15 #include "lldb/API/SBBroadcaster.h"
16 #include "lldb/API/SBCommandInterpreter.h"
17 #include "lldb/API/SBCommandReturnObject.h"
18 #include "lldb/API/SBEvent.h"
19 #include "lldb/API/SBFrame.h"
20 #include "lldb/API/SBInputReader.h"
21 #include "lldb/API/SBProcess.h"
22 #include "lldb/API/SBSourceManager.h"
23 #include "lldb/API/SBStream.h"
24 #include "lldb/API/SBStringList.h"
25 #include "lldb/API/SBTarget.h"
26 #include "lldb/API/SBThread.h"
27 #include "lldb/Core/Debugger.h"
28 #include "lldb/Core/State.h"
29 #include "lldb/Interpreter/Args.h"
30 #include "lldb/Interpreter/CommandInterpreter.h"
31 #include "lldb/Target/Process.h"
32 #include "lldb/Target/TargetList.h"
33 
34 using namespace lldb;
35 using namespace lldb_private;
36 
37 void
38 SBDebugger::Initialize ()
39 {
40     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
41 
42     if (log)
43         log->Printf ("SBDebugger::Initialize ()");
44 
45     SBCommandInterpreter::InitializeSWIG ();
46 
47     Debugger::Initialize();
48 }
49 
50 void
51 SBDebugger::Terminate ()
52 {
53     Debugger::Terminate();
54 }
55 
56 void
57 SBDebugger::Clear ()
58 {
59     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
60 
61     if (log)
62         log->Printf ("SBDebugger(%p)::Clear ()", m_opaque_sp.get());
63 
64     if (m_opaque_sp)
65         m_opaque_sp->CleanUpInputReaders ();
66 
67     m_opaque_sp.reset();
68 }
69 
70 SBDebugger
71 SBDebugger::Create()
72 {
73     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
74 
75     SBDebugger debugger;
76     debugger.reset(Debugger::CreateInstance());
77 
78     if (log)
79     {
80         SBStream sstr;
81         debugger.GetDescription (sstr);
82         log->Printf ("SBDebugger::Create () => SBDebugger(%p): %s", debugger.m_opaque_sp.get(), sstr.GetData());
83     }
84 
85     return debugger;
86 }
87 
88 void
89 SBDebugger::Destroy (SBDebugger &debugger)
90 {
91     LogSP log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
92 
93     if (log)
94     {
95         SBStream sstr;
96         debugger.GetDescription (sstr);
97         log->Printf ("SBDebugger::Destroy () => SBDebugger(%p): %s", debugger.m_opaque_sp.get(), sstr.GetData());
98     }
99 
100     Debugger::Destroy (debugger.m_opaque_sp);
101 
102     if (debugger.m_opaque_sp.get() != NULL)
103         debugger.m_opaque_sp.reset();
104 }
105 
106 SBDebugger::SBDebugger () :
107     m_opaque_sp ()
108 {
109 }
110 
111 SBDebugger::SBDebugger(const SBDebugger &rhs) :
112     m_opaque_sp (rhs.m_opaque_sp)
113 {
114 }
115 
116 SBDebugger &
117 SBDebugger::operator = (const SBDebugger &rhs)
118 {
119     if (this != &rhs)
120     {
121         m_opaque_sp = rhs.m_opaque_sp;
122     }
123     return *this;
124 }
125 
126 SBDebugger::~SBDebugger ()
127 {
128 }
129 
130 bool
131 SBDebugger::IsValid() const
132 {
133     return m_opaque_sp.get() != NULL;
134 }
135 
136 
137 void
138 SBDebugger::SetAsync (bool b)
139 {
140     if (m_opaque_sp)
141         m_opaque_sp->SetAsyncExecution(b);
142 }
143 
144 void
145 SBDebugger::SkipLLDBInitFiles (bool b)
146 {
147     if (m_opaque_sp)
148         m_opaque_sp->GetCommandInterpreter().SkipLLDBInitFiles (b);
149 }
150 
151 // Shouldn't really be settable after initialization as this could cause lots of problems; don't want users
152 // trying to switch modes in the middle of a debugging session.
153 void
154 SBDebugger::SetInputFileHandle (FILE *fh, bool transfer_ownership)
155 {
156     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
157 
158     if (log)
159         log->Printf ("SBDebugger(%p)::SetInputFileHandle (fh=%p, transfer_ownership=%i)", m_opaque_sp.get(),
160                      fh, transfer_ownership);
161 
162     if (m_opaque_sp)
163         m_opaque_sp->SetInputFileHandle (fh, transfer_ownership);
164 }
165 
166 void
167 SBDebugger::SetOutputFileHandle (FILE *fh, bool transfer_ownership)
168 {
169     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
170 
171 
172     if (log)
173         log->Printf ("SBDebugger(%p)::SetOutputFileHandle (fh=%p, transfer_ownership=%i)", m_opaque_sp.get(),
174                      fh, transfer_ownership);
175 
176     if (m_opaque_sp)
177         m_opaque_sp->SetOutputFileHandle (fh, transfer_ownership);
178 }
179 
180 void
181 SBDebugger::SetErrorFileHandle (FILE *fh, bool transfer_ownership)
182 {
183     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
184 
185 
186     if (log)
187         log->Printf ("SBDebugger(%p)::SetErrorFileHandle (fh=%p, transfer_ownership=%i)", m_opaque_sp.get(),
188                      fh, transfer_ownership);
189 
190     if (m_opaque_sp)
191         m_opaque_sp->SetErrorFileHandle (fh, transfer_ownership);
192 }
193 
194 FILE *
195 SBDebugger::GetInputFileHandle ()
196 {
197     if (m_opaque_sp)
198         return m_opaque_sp->GetInputFile().GetStream();
199     return NULL;
200 }
201 
202 FILE *
203 SBDebugger::GetOutputFileHandle ()
204 {
205     if (m_opaque_sp)
206         return m_opaque_sp->GetOutputFile().GetStream();
207     return NULL;
208 }
209 
210 FILE *
211 SBDebugger::GetErrorFileHandle ()
212 {
213     if (m_opaque_sp)
214         return m_opaque_sp->GetErrorFile().GetStream();
215     return NULL;
216 }
217 
218 SBCommandInterpreter
219 SBDebugger::GetCommandInterpreter ()
220 {
221     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
222 
223     SBCommandInterpreter sb_interpreter;
224     if (m_opaque_sp)
225         sb_interpreter.reset (&m_opaque_sp->GetCommandInterpreter());
226 
227     if (log)
228         log->Printf ("SBDebugger(%p)::GetCommandInterpreter () => SBCommandInterpreter(%p)",
229                      m_opaque_sp.get(), sb_interpreter.get());
230 
231     return sb_interpreter;
232 }
233 
234 void
235 SBDebugger::HandleCommand (const char *command)
236 {
237     if (m_opaque_sp)
238     {
239         TargetSP target_sp (m_opaque_sp->GetSelectedTarget());
240         Mutex::Locker api_locker;
241         if (target_sp)
242             api_locker.Reset(target_sp->GetAPIMutex().GetMutex());
243 
244         SBCommandInterpreter sb_interpreter(GetCommandInterpreter ());
245         SBCommandReturnObject result;
246 
247         sb_interpreter.HandleCommand (command, result, false);
248 
249         if (GetErrorFileHandle() != NULL)
250             result.PutError (GetErrorFileHandle());
251         if (GetOutputFileHandle() != NULL)
252             result.PutOutput (GetOutputFileHandle());
253 
254         if (m_opaque_sp->GetAsyncExecution() == false)
255         {
256             SBProcess process(GetCommandInterpreter().GetProcess ());
257             if (process.IsValid())
258             {
259                 EventSP event_sp;
260                 Listener &lldb_listener = m_opaque_sp->GetListener();
261                 while (lldb_listener.GetNextEventForBroadcaster (process.get(), event_sp))
262                 {
263                     SBEvent event(event_sp);
264                     HandleProcessEvent (process, event, GetOutputFileHandle(), GetErrorFileHandle());
265                 }
266             }
267         }
268     }
269 }
270 
271 SBListener
272 SBDebugger::GetListener ()
273 {
274     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
275 
276     SBListener sb_listener;
277     if (m_opaque_sp)
278         sb_listener.reset(&m_opaque_sp->GetListener(), false);
279 
280     if (log)
281         log->Printf ("SBDebugger(%p)::GetListener () => SBListener(%p)", m_opaque_sp.get(),
282                      sb_listener.get());
283 
284     return sb_listener;
285 }
286 
287 void
288 SBDebugger::HandleProcessEvent (const SBProcess &process, const SBEvent &event, FILE *out, FILE *err)
289 {
290     if (!process.IsValid())
291         return;
292 
293     const uint32_t event_type = event.GetType();
294     char stdio_buffer[1024];
295     size_t len;
296 
297     Mutex::Locker api_locker (process.GetTarget()->GetAPIMutex());
298 
299     if (event_type & (Process::eBroadcastBitSTDOUT | Process::eBroadcastBitStateChanged))
300     {
301         // Drain stdout when we stop just in case we have any bytes
302         while ((len = process.GetSTDOUT (stdio_buffer, sizeof (stdio_buffer))) > 0)
303             if (out != NULL)
304                 ::fwrite (stdio_buffer, 1, len, out);
305     }
306 
307     if (event_type & (Process::eBroadcastBitSTDERR | Process::eBroadcastBitStateChanged))
308     {
309         // Drain stderr when we stop just in case we have any bytes
310         while ((len = process.GetSTDERR (stdio_buffer, sizeof (stdio_buffer))) > 0)
311             if (err != NULL)
312                 ::fwrite (stdio_buffer, 1, len, err);
313     }
314 
315     if (event_type & Process::eBroadcastBitStateChanged)
316     {
317         StateType event_state = SBProcess::GetStateFromEvent (event);
318 
319         if (event_state == eStateInvalid)
320             return;
321 
322         bool is_stopped = StateIsStoppedState (event_state);
323         if (!is_stopped)
324             process.ReportEventState (event, out);
325     }
326 }
327 
328 SBSourceManager &
329 SBDebugger::GetSourceManager ()
330 {
331     static SourceManager g_lldb_source_manager;
332     static SBSourceManager g_sb_source_manager (&g_lldb_source_manager);
333     return g_sb_source_manager;
334 }
335 
336 
337 bool
338 SBDebugger::GetDefaultArchitecture (char *arch_name, size_t arch_name_len)
339 {
340     if (arch_name && arch_name_len)
341     {
342         ArchSpec default_arch = lldb_private::Target::GetDefaultArchitecture ();
343 
344         if (default_arch.IsValid())
345         {
346             ::snprintf (arch_name, arch_name_len, "%s", default_arch.GetArchitectureName());
347             return true;
348         }
349     }
350     if (arch_name && arch_name_len)
351         arch_name[0] = '\0';
352     return false;
353 }
354 
355 
356 bool
357 SBDebugger::SetDefaultArchitecture (const char *arch_name)
358 {
359     if (arch_name)
360     {
361         ArchSpec arch (arch_name, NULL);
362         if (arch.IsValid())
363         {
364             lldb_private::Target::SetDefaultArchitecture (arch);
365             return true;
366         }
367     }
368     return false;
369 }
370 
371 ScriptLanguage
372 SBDebugger::GetScriptingLanguage (const char *script_language_name)
373 {
374 
375     return Args::StringToScriptLanguage (script_language_name,
376                                          eScriptLanguageDefault,
377                                          NULL);
378 }
379 
380 const char *
381 SBDebugger::GetVersionString ()
382 {
383     return lldb_private::GetVersion();
384 }
385 
386 const char *
387 SBDebugger::StateAsCString (lldb::StateType state)
388 {
389     return lldb_private::StateAsCString (state);
390 }
391 
392 bool
393 SBDebugger::StateIsRunningState (lldb::StateType state)
394 {
395     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
396 
397     const bool result = lldb_private::StateIsRunningState (state);
398     if (log)
399         log->Printf ("SBDebugger::StateIsRunningState (state=%s) => %i",
400                      lldb_private::StateAsCString (state), result);
401 
402     return result;
403 }
404 
405 bool
406 SBDebugger::StateIsStoppedState (lldb::StateType state)
407 {
408     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
409 
410     const bool result = lldb_private::StateIsStoppedState (state);
411     if (log)
412         log->Printf ("SBDebugger::StateIsStoppedState (state=%s) => %i",
413                      lldb_private::StateAsCString (state), result);
414 
415     return result;
416 }
417 
418 
419 SBTarget
420 SBDebugger::CreateTargetWithFileAndTargetTriple (const char *filename,
421                                                  const char *target_triple)
422 {
423     SBTarget target;
424     if (m_opaque_sp)
425     {
426         ArchSpec arch;
427         FileSpec file_spec (filename, true);
428         arch.SetTriple (target_triple, m_opaque_sp->GetPlatformList().GetSelectedPlatform().get());
429         TargetSP target_sp;
430         Error error (m_opaque_sp->GetTargetList().CreateTarget (*m_opaque_sp, file_spec, arch, true, target_sp));
431         target.reset (target_sp);
432     }
433 
434     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
435     if (log)
436     {
437         log->Printf ("SBDebugger(%p)::CreateTargetWithFileAndTargetTriple (filename=\"%s\", triple=%s) => SBTarget(%p)",
438                      m_opaque_sp.get(), filename, target_triple, target.get());
439     }
440 
441     return target;
442 }
443 
444 SBTarget
445 SBDebugger::CreateTargetWithFileAndArch (const char *filename, const char *arch_cstr)
446 {
447     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
448 
449     SBTarget target;
450     if (m_opaque_sp)
451     {
452         FileSpec file (filename, true);
453         ArchSpec arch;
454         TargetSP target_sp;
455         Error error;
456 
457         if (arch_cstr)
458             arch.SetTriple (arch_cstr, m_opaque_sp->GetPlatformList().GetSelectedPlatform().get());
459 
460         error = m_opaque_sp->GetTargetList().CreateTarget (*m_opaque_sp, file, arch, true, target_sp);
461 
462         if (error.Success())
463         {
464             m_opaque_sp->GetTargetList().SetSelectedTarget (target_sp.get());
465             target.reset(target_sp);
466         }
467     }
468 
469     if (log)
470     {
471         log->Printf ("SBDebugger(%p)::CreateTargetWithFileAndArch (filename=\"%s\", arch=%s) => SBTarget(%p)",
472                      m_opaque_sp.get(), filename, arch_cstr, target.get());
473     }
474 
475     return target;
476 }
477 
478 SBTarget
479 SBDebugger::CreateTarget (const char *filename)
480 {
481     SBTarget target;
482     if (m_opaque_sp)
483     {
484         FileSpec file (filename, true);
485         ArchSpec arch = lldb_private::Target::GetDefaultArchitecture ();
486         TargetSP target_sp;
487         Error error;
488 
489         error = m_opaque_sp->GetTargetList().CreateTarget (*m_opaque_sp, file, arch, true, target_sp);
490 
491         if (error.Success())
492         {
493             m_opaque_sp->GetTargetList().SetSelectedTarget (target_sp.get());
494             target.reset (target_sp);
495         }
496     }
497     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
498     if (log)
499     {
500         log->Printf ("SBDebugger(%p)::CreateTarget (filename=\"%s\") => SBTarget(%p)",
501                      m_opaque_sp.get(), filename, target.get());
502     }
503     return target;
504 }
505 
506 SBTarget
507 SBDebugger::GetTargetAtIndex (uint32_t idx)
508 {
509     SBTarget sb_target;
510     if (m_opaque_sp)
511     {
512         // No need to lock, the target list is thread safe
513         sb_target.reset(m_opaque_sp->GetTargetList().GetTargetAtIndex (idx));
514     }
515     return sb_target;
516 }
517 
518 SBTarget
519 SBDebugger::FindTargetWithProcessID (pid_t pid)
520 {
521     SBTarget sb_target;
522     if (m_opaque_sp)
523     {
524         // No need to lock, the target list is thread safe
525         sb_target.reset(m_opaque_sp->GetTargetList().FindTargetWithProcessID (pid));
526     }
527     return sb_target;
528 }
529 
530 SBTarget
531 SBDebugger::FindTargetWithFileAndArch (const char *filename, const char *arch_name)
532 {
533     SBTarget sb_target;
534     if (m_opaque_sp && filename && filename[0])
535     {
536         // No need to lock, the target list is thread safe
537         ArchSpec arch (arch_name, m_opaque_sp->GetPlatformList().GetSelectedPlatform().get());
538         TargetSP target_sp (m_opaque_sp->GetTargetList().FindTargetWithExecutableAndArchitecture (FileSpec(filename, false), arch_name ? &arch : NULL));
539         sb_target.reset(target_sp);
540     }
541     return sb_target;
542 }
543 
544 SBTarget
545 SBDebugger::FindTargetWithLLDBProcess (const lldb::ProcessSP &process_sp)
546 {
547     SBTarget sb_target;
548     if (m_opaque_sp)
549     {
550         // No need to lock, the target list is thread safe
551         sb_target.reset(m_opaque_sp->GetTargetList().FindTargetWithProcess (process_sp.get()));
552     }
553     return sb_target;
554 }
555 
556 
557 uint32_t
558 SBDebugger::GetNumTargets ()
559 {
560     if (m_opaque_sp)
561     {
562         // No need to lock, the target list is thread safe
563         return m_opaque_sp->GetTargetList().GetNumTargets ();
564     }
565     return 0;
566 }
567 
568 SBTarget
569 SBDebugger::GetSelectedTarget ()
570 {
571     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
572 
573     SBTarget sb_target;
574     if (m_opaque_sp)
575     {
576         // No need to lock, the target list is thread safe
577         sb_target.reset(m_opaque_sp->GetTargetList().GetSelectedTarget ());
578     }
579 
580     if (log)
581     {
582         SBStream sstr;
583         sb_target.GetDescription (sstr, lldb::eDescriptionLevelBrief);
584         log->Printf ("SBDebugger(%p)::GetSelectedTarget () => SBTarget(%p): %s", m_opaque_sp.get(),
585                      sb_target.get(), sstr.GetData());
586     }
587 
588     return sb_target;
589 }
590 
591 void
592 SBDebugger::DispatchInput (void *baton, const void *data, size_t data_len)
593 {
594     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
595 
596     if (log)
597         log->Printf ("SBDebugger(%p)::DispatchInput (baton=%p, data=\"%.*s\", size_t=%zu)", m_opaque_sp.get(),
598                      baton, (int) data_len, (const char *) data, data_len);
599 
600     if (m_opaque_sp)
601         m_opaque_sp->DispatchInput ((const char *) data, data_len);
602 }
603 
604 void
605 SBDebugger::DispatchInputInterrupt ()
606 {
607     if (m_opaque_sp)
608         m_opaque_sp->DispatchInputInterrupt ();
609 }
610 
611 void
612 SBDebugger::DispatchInputEndOfFile ()
613 {
614     if (m_opaque_sp)
615         m_opaque_sp->DispatchInputEndOfFile ();
616 }
617 
618 void
619 SBDebugger::PushInputReader (SBInputReader &reader)
620 {
621     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
622 
623     if (log)
624         log->Printf ("SBDebugger(%p)::PushInputReader (SBInputReader(%p))", m_opaque_sp.get(), &reader);
625 
626     if (m_opaque_sp && reader.IsValid())
627     {
628         TargetSP target_sp (m_opaque_sp->GetSelectedTarget());
629         Mutex::Locker api_locker;
630         if (target_sp)
631             api_locker.Reset(target_sp->GetAPIMutex().GetMutex());
632         InputReaderSP reader_sp(*reader);
633         m_opaque_sp->PushInputReader (reader_sp);
634     }
635 }
636 
637 void
638 SBDebugger::reset (const lldb::DebuggerSP &debugger_sp)
639 {
640     m_opaque_sp = debugger_sp;
641 }
642 
643 Debugger *
644 SBDebugger::get () const
645 {
646     return m_opaque_sp.get();
647 }
648 
649 Debugger &
650 SBDebugger::ref () const
651 {
652     assert (m_opaque_sp.get());
653     return *m_opaque_sp;
654 }
655 
656 
657 SBDebugger
658 SBDebugger::FindDebuggerWithID (int id)
659 {
660     // No need to lock, the debugger list is thread safe
661     SBDebugger sb_debugger;
662     lldb::DebuggerSP debugger_sp = Debugger::FindDebuggerWithID (id);
663     if (debugger_sp)
664         sb_debugger.reset (debugger_sp);
665     return sb_debugger;
666 }
667 
668 const char *
669 SBDebugger::GetInstanceName()
670 {
671     if (m_opaque_sp)
672         return m_opaque_sp->GetInstanceName().AsCString();
673     else
674         return NULL;
675 }
676 
677 SBError
678 SBDebugger::SetInternalVariable (const char *var_name, const char *value, const char *debugger_instance_name)
679 {
680     lldb::UserSettingsControllerSP root_settings_controller = lldb_private::Debugger::GetSettingsController();
681 
682     Error err = root_settings_controller->SetVariable (var_name,
683                                                        value,
684                                                        eVarSetOperationAssign,
685                                                        true,
686                                                        debugger_instance_name);
687     SBError sb_error;
688     sb_error.SetError (err);
689 
690     return sb_error;
691 }
692 
693 lldb::SBStringList
694 SBDebugger::GetInternalVariableValue (const char *var_name, const char *debugger_instance_name)
695 {
696     SBStringList ret_value;
697     SettableVariableType var_type;
698     lldb_private::Error err;
699 
700     lldb::UserSettingsControllerSP root_settings_controller = lldb_private::Debugger::GetSettingsController();
701 
702     StringList value = root_settings_controller->GetVariable (var_name, var_type, debugger_instance_name, err);
703 
704     if (err.Success())
705     {
706         for (unsigned i = 0; i != value.GetSize(); ++i)
707             ret_value.AppendString (value.GetStringAtIndex(i));
708     }
709     else
710     {
711         ret_value.AppendString (err.AsCString());
712     }
713 
714 
715     return ret_value;
716 }
717 
718 uint32_t
719 SBDebugger::GetTerminalWidth () const
720 {
721     if (m_opaque_sp)
722         return m_opaque_sp->GetTerminalWidth ();
723     return 0;
724 }
725 
726 void
727 SBDebugger::SetTerminalWidth (uint32_t term_width)
728 {
729     if (m_opaque_sp)
730         m_opaque_sp->SetTerminalWidth (term_width);
731 }
732 
733 const char *
734 SBDebugger::GetPrompt() const
735 {
736     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
737 
738     if (log)
739         log->Printf ("SBDebugger(%p)::GetPrompt () => \"%s\"", m_opaque_sp.get(),
740                      (m_opaque_sp ? m_opaque_sp->GetPrompt() : ""));
741 
742     if (m_opaque_sp)
743         return m_opaque_sp->GetPrompt ();
744     return 0;
745 }
746 
747 void
748 SBDebugger::SetPrompt (const char *prompt)
749 {
750     if (m_opaque_sp)
751         m_opaque_sp->SetPrompt (prompt);
752 }
753 
754 
755 lldb::ScriptLanguage
756 SBDebugger::GetScriptLanguage() const
757 {
758     if (m_opaque_sp)
759         return m_opaque_sp->GetScriptLanguage ();
760     return eScriptLanguageNone;
761 }
762 
763 void
764 SBDebugger::SetScriptLanguage (lldb::ScriptLanguage script_lang)
765 {
766     if (m_opaque_sp)
767     {
768         m_opaque_sp->SetScriptLanguage (script_lang);
769     }
770 }
771 
772 bool
773 SBDebugger::SetUseExternalEditor (bool value)
774 {
775     if (m_opaque_sp)
776         return m_opaque_sp->SetUseExternalEditor (value);
777     return false;
778 }
779 
780 bool
781 SBDebugger::GetUseExternalEditor ()
782 {
783     if (m_opaque_sp)
784         return m_opaque_sp->GetUseExternalEditor ();
785     return false;
786 }
787 
788 bool
789 SBDebugger::GetDescription (SBStream &description)
790 {
791     if (m_opaque_sp)
792     {
793         const char *name = m_opaque_sp->GetInstanceName().AsCString();
794         lldb::user_id_t id = m_opaque_sp->GetID();
795         description.Printf ("Debugger (instance: \"%s\", id: %d)", name, id);
796     }
797     else
798         description.Printf ("No value");
799 
800     return true;
801 }
802 
803 lldb::user_id_t
804 SBDebugger::GetID()
805 {
806     if (m_opaque_sp)
807         return m_opaque_sp->GetID();
808     return LLDB_INVALID_UID;
809 }
810