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