1 //===-- Debugger.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/Core/Debugger.h"
11 
12 #include <map>
13 
14 #include "clang/AST/DeclCXX.h"
15 #include "clang/AST/Type.h"
16 
17 #include "lldb/lldb-private.h"
18 #include "lldb/Core/ConnectionFileDescriptor.h"
19 #include "lldb/Core/FormatManager.h"
20 #include "lldb/Core/InputReader.h"
21 #include "lldb/Core/RegisterValue.h"
22 #include "lldb/Core/State.h"
23 #include "lldb/Core/StreamAsynchronousIO.h"
24 #include "lldb/Core/StreamCallback.h"
25 #include "lldb/Core/StreamString.h"
26 #include "lldb/Core/Timer.h"
27 #include "lldb/Core/ValueObject.h"
28 #include "lldb/Core/ValueObjectVariable.h"
29 #include "lldb/Host/Terminal.h"
30 #include "lldb/Interpreter/CommandInterpreter.h"
31 #include "lldb/Symbol/VariableList.h"
32 #include "lldb/Target/TargetList.h"
33 #include "lldb/Target/Process.h"
34 #include "lldb/Target/RegisterContext.h"
35 #include "lldb/Target/StopInfo.h"
36 #include "lldb/Target/Thread.h"
37 #include "lldb/Utility/AnsiTerminal.h"
38 
39 using namespace lldb;
40 using namespace lldb_private;
41 
42 
43 static uint32_t g_shared_debugger_refcount = 0;
44 static lldb::user_id_t g_unique_id = 1;
45 
46 #pragma mark Static Functions
47 
48 static Mutex &
49 GetDebuggerListMutex ()
50 {
51     static Mutex g_mutex(Mutex::eMutexTypeRecursive);
52     return g_mutex;
53 }
54 
55 typedef std::vector<DebuggerSP> DebuggerList;
56 
57 static DebuggerList &
58 GetDebuggerList()
59 {
60     // hide the static debugger list inside a singleton accessor to avoid
61     // global init contructors
62     static DebuggerList g_list;
63     return g_list;
64 }
65 
66 
67 static const ConstString &
68 PromptVarName ()
69 {
70     static ConstString g_const_string ("prompt");
71     return g_const_string;
72 }
73 
74 static const ConstString &
75 GetFrameFormatName ()
76 {
77     static ConstString g_const_string ("frame-format");
78     return g_const_string;
79 }
80 
81 static const ConstString &
82 GetThreadFormatName ()
83 {
84     static ConstString g_const_string ("thread-format");
85     return g_const_string;
86 }
87 
88 static const ConstString &
89 ScriptLangVarName ()
90 {
91     static ConstString g_const_string ("script-lang");
92     return g_const_string;
93 }
94 
95 static const ConstString &
96 TermWidthVarName ()
97 {
98     static ConstString g_const_string ("term-width");
99     return g_const_string;
100 }
101 
102 static const ConstString &
103 UseExternalEditorVarName ()
104 {
105     static ConstString g_const_string ("use-external-editor");
106     return g_const_string;
107 }
108 
109 static const ConstString &
110 AutoConfirmName ()
111 {
112     static ConstString g_const_string ("auto-confirm");
113     return g_const_string;
114 }
115 
116 static const ConstString &
117 StopSourceContextBeforeName ()
118 {
119     static ConstString g_const_string ("stop-line-count-before");
120     return g_const_string;
121 }
122 
123 static const ConstString &
124 StopSourceContextAfterName ()
125 {
126     static ConstString g_const_string ("stop-line-count-after");
127     return g_const_string;
128 }
129 
130 static const ConstString &
131 StopDisassemblyCountName ()
132 {
133     static ConstString g_const_string ("stop-disassembly-count");
134     return g_const_string;
135 }
136 
137 static const ConstString &
138 StopDisassemblyDisplayName ()
139 {
140     static ConstString g_const_string ("stop-disassembly-display");
141     return g_const_string;
142 }
143 
144 OptionEnumValueElement
145 DebuggerInstanceSettings::g_show_disassembly_enum_values[] =
146 {
147     { eStopDisassemblyTypeNever,    "never",     "Never show disassembly when displaying a stop context."},
148     { eStopDisassemblyTypeNoSource, "no-source", "Show disassembly when there is no source information, or the source file is missing when displaying a stop context."},
149     { eStopDisassemblyTypeAlways,   "always",    "Always show disassembly when displaying a stop context."},
150     { 0, NULL, NULL }
151 };
152 
153 
154 
155 #pragma mark Debugger
156 
157 UserSettingsControllerSP &
158 Debugger::GetSettingsController ()
159 {
160     static UserSettingsControllerSP g_settings_controller_sp;
161     if (!g_settings_controller_sp)
162     {
163         g_settings_controller_sp.reset (new Debugger::SettingsController);
164 
165         // The first shared pointer to Debugger::SettingsController in
166         // g_settings_controller_sp must be fully created above so that
167         // the DebuggerInstanceSettings can use a weak_ptr to refer back
168         // to the master setttings controller
169         InstanceSettingsSP default_instance_settings_sp (new DebuggerInstanceSettings (g_settings_controller_sp,
170                                                                                        false,
171                                                                                        InstanceSettings::GetDefaultName().AsCString()));
172         g_settings_controller_sp->SetDefaultInstanceSettings (default_instance_settings_sp);
173     }
174     return g_settings_controller_sp;
175 }
176 
177 int
178 Debugger::TestDebuggerRefCount ()
179 {
180     return g_shared_debugger_refcount;
181 }
182 
183 void
184 Debugger::Initialize ()
185 {
186     if (g_shared_debugger_refcount == 0)
187     {
188         lldb_private::Initialize();
189     }
190     g_shared_debugger_refcount++;
191 
192 }
193 
194 void
195 Debugger::Terminate ()
196 {
197     if (g_shared_debugger_refcount > 0)
198     {
199         g_shared_debugger_refcount--;
200         if (g_shared_debugger_refcount == 0)
201         {
202             lldb_private::WillTerminate();
203             lldb_private::Terminate();
204 
205             // Clear our master list of debugger objects
206             Mutex::Locker locker (GetDebuggerListMutex ());
207             GetDebuggerList().clear();
208         }
209     }
210 }
211 
212 void
213 Debugger::SettingsInitialize ()
214 {
215     static bool g_initialized = false;
216 
217     if (!g_initialized)
218     {
219         g_initialized = true;
220         UserSettingsController::InitializeSettingsController (GetSettingsController(),
221                                                               SettingsController::global_settings_table,
222                                                               SettingsController::instance_settings_table);
223         // Now call SettingsInitialize for each settings 'child' of Debugger
224         Target::SettingsInitialize ();
225     }
226 }
227 
228 void
229 Debugger::SettingsTerminate ()
230 {
231 
232     // Must call SettingsTerminate() for each settings 'child' of Debugger, before terminating the Debugger's
233     // Settings.
234 
235     Target::SettingsTerminate ();
236 
237     // Now terminate the Debugger Settings.
238 
239     UserSettingsControllerSP &usc = GetSettingsController();
240     UserSettingsController::FinalizeSettingsController (usc);
241     usc.reset();
242 }
243 
244 DebuggerSP
245 Debugger::CreateInstance (lldb::LogOutputCallback log_callback, void *baton)
246 {
247     DebuggerSP debugger_sp (new Debugger(log_callback, baton));
248     // Scope for locker
249     {
250         Mutex::Locker locker (GetDebuggerListMutex ());
251         GetDebuggerList().push_back(debugger_sp);
252     }
253     return debugger_sp;
254 }
255 
256 void
257 Debugger::Destroy (DebuggerSP &debugger_sp)
258 {
259     if (debugger_sp.get() == NULL)
260         return;
261 
262     debugger_sp->Clear();
263 
264     Mutex::Locker locker (GetDebuggerListMutex ());
265     DebuggerList &debugger_list = GetDebuggerList ();
266     DebuggerList::iterator pos, end = debugger_list.end();
267     for (pos = debugger_list.begin (); pos != end; ++pos)
268     {
269         if ((*pos).get() == debugger_sp.get())
270         {
271             debugger_list.erase (pos);
272             return;
273         }
274     }
275 }
276 
277 DebuggerSP
278 Debugger::FindDebuggerWithInstanceName (const ConstString &instance_name)
279 {
280     DebuggerSP debugger_sp;
281 
282     Mutex::Locker locker (GetDebuggerListMutex ());
283     DebuggerList &debugger_list = GetDebuggerList();
284     DebuggerList::iterator pos, end = debugger_list.end();
285 
286     for (pos = debugger_list.begin(); pos != end; ++pos)
287     {
288         if ((*pos).get()->m_instance_name == instance_name)
289         {
290             debugger_sp = *pos;
291             break;
292         }
293     }
294     return debugger_sp;
295 }
296 
297 TargetSP
298 Debugger::FindTargetWithProcessID (lldb::pid_t pid)
299 {
300     TargetSP target_sp;
301     Mutex::Locker locker (GetDebuggerListMutex ());
302     DebuggerList &debugger_list = GetDebuggerList();
303     DebuggerList::iterator pos, end = debugger_list.end();
304     for (pos = debugger_list.begin(); pos != end; ++pos)
305     {
306         target_sp = (*pos)->GetTargetList().FindTargetWithProcessID (pid);
307         if (target_sp)
308             break;
309     }
310     return target_sp;
311 }
312 
313 TargetSP
314 Debugger::FindTargetWithProcess (Process *process)
315 {
316     TargetSP target_sp;
317     Mutex::Locker locker (GetDebuggerListMutex ());
318     DebuggerList &debugger_list = GetDebuggerList();
319     DebuggerList::iterator pos, end = debugger_list.end();
320     for (pos = debugger_list.begin(); pos != end; ++pos)
321     {
322         target_sp = (*pos)->GetTargetList().FindTargetWithProcess (process);
323         if (target_sp)
324             break;
325     }
326     return target_sp;
327 }
328 
329 
330 Debugger::Debugger (lldb::LogOutputCallback log_callback, void *baton) :
331     UserID (g_unique_id++),
332     DebuggerInstanceSettings (GetSettingsController()),
333     m_input_comm("debugger.input"),
334     m_input_file (),
335     m_output_file (),
336     m_error_file (),
337     m_target_list (*this),
338     m_platform_list (),
339     m_listener ("lldb.Debugger"),
340     m_source_manager(*this),
341     m_source_file_cache(),
342     m_command_interpreter_ap (new CommandInterpreter (*this, eScriptLanguageDefault, false)),
343     m_input_reader_stack (),
344     m_input_reader_data ()
345 {
346     if (log_callback)
347         m_log_callback_stream_sp.reset (new StreamCallback (log_callback, baton));
348     m_command_interpreter_ap->Initialize ();
349     // Always add our default platform to the platform list
350     PlatformSP default_platform_sp (Platform::GetDefaultPlatform());
351     assert (default_platform_sp.get());
352     m_platform_list.Append (default_platform_sp, true);
353 }
354 
355 Debugger::~Debugger ()
356 {
357     Clear();
358 }
359 
360 void
361 Debugger::Clear()
362 {
363     CleanUpInputReaders();
364     m_listener.Clear();
365     int num_targets = m_target_list.GetNumTargets();
366     for (int i = 0; i < num_targets; i++)
367     {
368         TargetSP target_sp (m_target_list.GetTargetAtIndex (i));
369         if (target_sp)
370         {
371             ProcessSP process_sp (target_sp->GetProcessSP());
372             if (process_sp)
373             {
374                 if (process_sp->GetShouldDetach())
375                     process_sp->Detach();
376             }
377             target_sp->Destroy();
378         }
379     }
380     BroadcasterManager::Clear ();
381     DisconnectInput();
382 
383 }
384 
385 bool
386 Debugger::GetCloseInputOnEOF () const
387 {
388     return m_input_comm.GetCloseOnEOF();
389 }
390 
391 void
392 Debugger::SetCloseInputOnEOF (bool b)
393 {
394     m_input_comm.SetCloseOnEOF(b);
395 }
396 
397 bool
398 Debugger::GetAsyncExecution ()
399 {
400     return !m_command_interpreter_ap->GetSynchronous();
401 }
402 
403 void
404 Debugger::SetAsyncExecution (bool async_execution)
405 {
406     m_command_interpreter_ap->SetSynchronous (!async_execution);
407 }
408 
409 
410 void
411 Debugger::SetInputFileHandle (FILE *fh, bool tranfer_ownership)
412 {
413     File &in_file = GetInputFile();
414     in_file.SetStream (fh, tranfer_ownership);
415     if (in_file.IsValid() == false)
416         in_file.SetStream (stdin, true);
417 
418     // Disconnect from any old connection if we had one
419     m_input_comm.Disconnect ();
420     // Pass false as the second argument to ConnectionFileDescriptor below because
421     // our "in_file" above will already take ownership if requested and we don't
422     // want to objects trying to own and close a file descriptor.
423     m_input_comm.SetConnection (new ConnectionFileDescriptor (in_file.GetDescriptor(), false));
424     m_input_comm.SetReadThreadBytesReceivedCallback (Debugger::DispatchInputCallback, this);
425 
426     Error error;
427     if (m_input_comm.StartReadThread (&error) == false)
428     {
429         File &err_file = GetErrorFile();
430 
431         err_file.Printf ("error: failed to main input read thread: %s", error.AsCString() ? error.AsCString() : "unkown error");
432         exit(1);
433     }
434 }
435 
436 void
437 Debugger::SetOutputFileHandle (FILE *fh, bool tranfer_ownership)
438 {
439     File &out_file = GetOutputFile();
440     out_file.SetStream (fh, tranfer_ownership);
441     if (out_file.IsValid() == false)
442         out_file.SetStream (stdout, false);
443 
444     GetCommandInterpreter().GetScriptInterpreter()->ResetOutputFileHandle (fh);
445 }
446 
447 void
448 Debugger::SetErrorFileHandle (FILE *fh, bool tranfer_ownership)
449 {
450     File &err_file = GetErrorFile();
451     err_file.SetStream (fh, tranfer_ownership);
452     if (err_file.IsValid() == false)
453         err_file.SetStream (stderr, false);
454 }
455 
456 ExecutionContext
457 Debugger::GetSelectedExecutionContext ()
458 {
459     ExecutionContext exe_ctx;
460     TargetSP target_sp(GetSelectedTarget());
461     exe_ctx.SetTargetSP (target_sp);
462 
463     if (target_sp)
464     {
465         ProcessSP process_sp (target_sp->GetProcessSP());
466         exe_ctx.SetProcessSP (process_sp);
467         if (process_sp && process_sp->IsRunning() == false)
468         {
469             ThreadSP thread_sp (process_sp->GetThreadList().GetSelectedThread());
470             if (thread_sp)
471             {
472                 exe_ctx.SetThreadSP (thread_sp);
473                 exe_ctx.SetFrameSP (thread_sp->GetSelectedFrame());
474                 if (exe_ctx.GetFramePtr() == NULL)
475                     exe_ctx.SetFrameSP (thread_sp->GetStackFrameAtIndex (0));
476             }
477         }
478     }
479     return exe_ctx;
480 
481 }
482 
483 InputReaderSP
484 Debugger::GetCurrentInputReader ()
485 {
486     InputReaderSP reader_sp;
487 
488     if (!m_input_reader_stack.IsEmpty())
489     {
490         // Clear any finished readers from the stack
491         while (CheckIfTopInputReaderIsDone()) ;
492 
493         if (!m_input_reader_stack.IsEmpty())
494             reader_sp = m_input_reader_stack.Top();
495     }
496 
497     return reader_sp;
498 }
499 
500 void
501 Debugger::DispatchInputCallback (void *baton, const void *bytes, size_t bytes_len)
502 {
503     if (bytes_len > 0)
504         ((Debugger *)baton)->DispatchInput ((char *)bytes, bytes_len);
505     else
506         ((Debugger *)baton)->DispatchInputEndOfFile ();
507 }
508 
509 
510 void
511 Debugger::DispatchInput (const char *bytes, size_t bytes_len)
512 {
513     if (bytes == NULL || bytes_len == 0)
514         return;
515 
516     WriteToDefaultReader (bytes, bytes_len);
517 }
518 
519 void
520 Debugger::DispatchInputInterrupt ()
521 {
522     m_input_reader_data.clear();
523 
524     InputReaderSP reader_sp (GetCurrentInputReader ());
525     if (reader_sp)
526     {
527         reader_sp->Notify (eInputReaderInterrupt);
528 
529         // If notifying the reader of the interrupt finished the reader, we should pop it off the stack.
530         while (CheckIfTopInputReaderIsDone ()) ;
531     }
532 }
533 
534 void
535 Debugger::DispatchInputEndOfFile ()
536 {
537     m_input_reader_data.clear();
538 
539     InputReaderSP reader_sp (GetCurrentInputReader ());
540     if (reader_sp)
541     {
542         reader_sp->Notify (eInputReaderEndOfFile);
543 
544         // If notifying the reader of the end-of-file finished the reader, we should pop it off the stack.
545         while (CheckIfTopInputReaderIsDone ()) ;
546     }
547 }
548 
549 void
550 Debugger::CleanUpInputReaders ()
551 {
552     m_input_reader_data.clear();
553 
554     // The bottom input reader should be the main debugger input reader.  We do not want to close that one here.
555     while (m_input_reader_stack.GetSize() > 1)
556     {
557         InputReaderSP reader_sp (GetCurrentInputReader ());
558         if (reader_sp)
559         {
560             reader_sp->Notify (eInputReaderEndOfFile);
561             reader_sp->SetIsDone (true);
562         }
563     }
564 }
565 
566 void
567 Debugger::NotifyTopInputReader (InputReaderAction notification)
568 {
569     InputReaderSP reader_sp (GetCurrentInputReader());
570     if (reader_sp)
571 	{
572         reader_sp->Notify (notification);
573 
574         // Flush out any input readers that are done.
575         while (CheckIfTopInputReaderIsDone ())
576             /* Do nothing. */;
577     }
578 }
579 
580 bool
581 Debugger::InputReaderIsTopReader (const InputReaderSP& reader_sp)
582 {
583     InputReaderSP top_reader_sp (GetCurrentInputReader());
584 
585     return (reader_sp.get() == top_reader_sp.get());
586 }
587 
588 
589 void
590 Debugger::WriteToDefaultReader (const char *bytes, size_t bytes_len)
591 {
592     if (bytes && bytes_len)
593         m_input_reader_data.append (bytes, bytes_len);
594 
595     if (m_input_reader_data.empty())
596         return;
597 
598     while (!m_input_reader_stack.IsEmpty() && !m_input_reader_data.empty())
599     {
600         // Get the input reader from the top of the stack
601         InputReaderSP reader_sp (GetCurrentInputReader ());
602         if (!reader_sp)
603             break;
604 
605         size_t bytes_handled = reader_sp->HandleRawBytes (m_input_reader_data.c_str(),
606                                                           m_input_reader_data.size());
607         if (bytes_handled)
608         {
609             m_input_reader_data.erase (0, bytes_handled);
610         }
611         else
612         {
613             // No bytes were handled, we might not have reached our
614             // granularity, just return and wait for more data
615             break;
616         }
617     }
618 
619     // Flush out any input readers that are done.
620     while (CheckIfTopInputReaderIsDone ())
621         /* Do nothing. */;
622 
623 }
624 
625 void
626 Debugger::PushInputReader (const InputReaderSP& reader_sp)
627 {
628     if (!reader_sp)
629         return;
630 
631     // Deactivate the old top reader
632     InputReaderSP top_reader_sp (GetCurrentInputReader ());
633 
634     if (top_reader_sp)
635         top_reader_sp->Notify (eInputReaderDeactivate);
636 
637     m_input_reader_stack.Push (reader_sp);
638     reader_sp->Notify (eInputReaderActivate);
639     ActivateInputReader (reader_sp);
640 }
641 
642 bool
643 Debugger::PopInputReader (const InputReaderSP& pop_reader_sp)
644 {
645     bool result = false;
646 
647     // The reader on the stop of the stack is done, so let the next
648     // read on the stack referesh its prompt and if there is one...
649     if (!m_input_reader_stack.IsEmpty())
650     {
651         // Cannot call GetCurrentInputReader here, as that would cause an infinite loop.
652         InputReaderSP reader_sp(m_input_reader_stack.Top());
653 
654         if (!pop_reader_sp || pop_reader_sp.get() == reader_sp.get())
655         {
656             m_input_reader_stack.Pop ();
657             reader_sp->Notify (eInputReaderDeactivate);
658             reader_sp->Notify (eInputReaderDone);
659             result = true;
660 
661             if (!m_input_reader_stack.IsEmpty())
662             {
663                 reader_sp = m_input_reader_stack.Top();
664                 if (reader_sp)
665                 {
666                     ActivateInputReader (reader_sp);
667                     reader_sp->Notify (eInputReaderReactivate);
668                 }
669             }
670         }
671     }
672     return result;
673 }
674 
675 bool
676 Debugger::CheckIfTopInputReaderIsDone ()
677 {
678     bool result = false;
679     if (!m_input_reader_stack.IsEmpty())
680     {
681         // Cannot call GetCurrentInputReader here, as that would cause an infinite loop.
682         InputReaderSP reader_sp(m_input_reader_stack.Top());
683 
684         if (reader_sp && reader_sp->IsDone())
685         {
686             result = true;
687             PopInputReader (reader_sp);
688         }
689     }
690     return result;
691 }
692 
693 void
694 Debugger::ActivateInputReader (const InputReaderSP &reader_sp)
695 {
696     int input_fd = m_input_file.GetFile().GetDescriptor();
697 
698     if (input_fd >= 0)
699     {
700         Terminal tty(input_fd);
701 
702         tty.SetEcho(reader_sp->GetEcho());
703 
704         switch (reader_sp->GetGranularity())
705         {
706         case eInputReaderGranularityByte:
707         case eInputReaderGranularityWord:
708             tty.SetCanonical (false);
709             break;
710 
711         case eInputReaderGranularityLine:
712         case eInputReaderGranularityAll:
713             tty.SetCanonical (true);
714             break;
715 
716         default:
717             break;
718         }
719     }
720 }
721 
722 StreamSP
723 Debugger::GetAsyncOutputStream ()
724 {
725     return StreamSP (new StreamAsynchronousIO (GetCommandInterpreter(),
726                                                CommandInterpreter::eBroadcastBitAsynchronousOutputData));
727 }
728 
729 StreamSP
730 Debugger::GetAsyncErrorStream ()
731 {
732     return StreamSP (new StreamAsynchronousIO (GetCommandInterpreter(),
733                                                CommandInterpreter::eBroadcastBitAsynchronousErrorData));
734 }
735 
736 uint32_t
737 Debugger::GetNumDebuggers()
738 {
739     Mutex::Locker locker (GetDebuggerListMutex ());
740     return GetDebuggerList().size();
741 }
742 
743 lldb::DebuggerSP
744 Debugger::GetDebuggerAtIndex (uint32_t index)
745 {
746     DebuggerSP debugger_sp;
747 
748     Mutex::Locker locker (GetDebuggerListMutex ());
749     DebuggerList &debugger_list = GetDebuggerList();
750 
751     if (index < debugger_list.size())
752         debugger_sp = debugger_list[index];
753 
754     return debugger_sp;
755 }
756 
757 DebuggerSP
758 Debugger::FindDebuggerWithID (lldb::user_id_t id)
759 {
760     DebuggerSP debugger_sp;
761 
762     Mutex::Locker locker (GetDebuggerListMutex ());
763     DebuggerList &debugger_list = GetDebuggerList();
764     DebuggerList::iterator pos, end = debugger_list.end();
765     for (pos = debugger_list.begin(); pos != end; ++pos)
766     {
767         if ((*pos).get()->GetID() == id)
768         {
769             debugger_sp = *pos;
770             break;
771         }
772     }
773     return debugger_sp;
774 }
775 
776 static void
777 TestPromptFormats (StackFrame *frame)
778 {
779     if (frame == NULL)
780         return;
781 
782     StreamString s;
783     const char *prompt_format =
784     "{addr = '${addr}'\n}"
785     "{process.id = '${process.id}'\n}"
786     "{process.name = '${process.name}'\n}"
787     "{process.file.basename = '${process.file.basename}'\n}"
788     "{process.file.fullpath = '${process.file.fullpath}'\n}"
789     "{thread.id = '${thread.id}'\n}"
790     "{thread.index = '${thread.index}'\n}"
791     "{thread.name = '${thread.name}'\n}"
792     "{thread.queue = '${thread.queue}'\n}"
793     "{thread.stop-reason = '${thread.stop-reason}'\n}"
794     "{target.arch = '${target.arch}'\n}"
795     "{module.file.basename = '${module.file.basename}'\n}"
796     "{module.file.fullpath = '${module.file.fullpath}'\n}"
797     "{file.basename = '${file.basename}'\n}"
798     "{file.fullpath = '${file.fullpath}'\n}"
799     "{frame.index = '${frame.index}'\n}"
800     "{frame.pc = '${frame.pc}'\n}"
801     "{frame.sp = '${frame.sp}'\n}"
802     "{frame.fp = '${frame.fp}'\n}"
803     "{frame.flags = '${frame.flags}'\n}"
804     "{frame.reg.rdi = '${frame.reg.rdi}'\n}"
805     "{frame.reg.rip = '${frame.reg.rip}'\n}"
806     "{frame.reg.rsp = '${frame.reg.rsp}'\n}"
807     "{frame.reg.rbp = '${frame.reg.rbp}'\n}"
808     "{frame.reg.rflags = '${frame.reg.rflags}'\n}"
809     "{frame.reg.xmm0 = '${frame.reg.xmm0}'\n}"
810     "{frame.reg.carp = '${frame.reg.carp}'\n}"
811     "{function.id = '${function.id}'\n}"
812     "{function.name = '${function.name}'\n}"
813     "{function.name-with-args = '${function.name-with-args}'\n}"
814     "{function.addr-offset = '${function.addr-offset}'\n}"
815     "{function.line-offset = '${function.line-offset}'\n}"
816     "{function.pc-offset = '${function.pc-offset}'\n}"
817     "{line.file.basename = '${line.file.basename}'\n}"
818     "{line.file.fullpath = '${line.file.fullpath}'\n}"
819     "{line.number = '${line.number}'\n}"
820     "{line.start-addr = '${line.start-addr}'\n}"
821     "{line.end-addr = '${line.end-addr}'\n}"
822 ;
823 
824     SymbolContext sc (frame->GetSymbolContext(eSymbolContextEverything));
825     ExecutionContext exe_ctx;
826     frame->CalculateExecutionContext(exe_ctx);
827     const char *end = NULL;
828     if (Debugger::FormatPrompt (prompt_format, &sc, &exe_ctx, &sc.line_entry.range.GetBaseAddress(), s, &end))
829     {
830         printf("%s\n", s.GetData());
831     }
832     else
833     {
834         printf ("error: at '%s'\n", end);
835         printf ("what we got: %s\n", s.GetData());
836     }
837 }
838 
839 static bool
840 ScanFormatDescriptor (const char* var_name_begin,
841                       const char* var_name_end,
842                       const char** var_name_final,
843                       const char** percent_position,
844                       Format* custom_format,
845                       ValueObject::ValueObjectRepresentationStyle* val_obj_display)
846 {
847     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
848     *percent_position = ::strchr(var_name_begin,'%');
849     if (!*percent_position || *percent_position > var_name_end)
850     {
851         if (log)
852             log->Printf("no format descriptor in string, skipping");
853         *var_name_final = var_name_end;
854     }
855     else
856     {
857         *var_name_final = *percent_position;
858         char* format_name = new char[var_name_end-*var_name_final]; format_name[var_name_end-*var_name_final-1] = '\0';
859         memcpy(format_name, *var_name_final+1, var_name_end-*var_name_final-1);
860         if (log)
861             log->Printf("parsing %s as a format descriptor", format_name);
862         if ( !FormatManager::GetFormatFromCString(format_name,
863                                                   true,
864                                                   *custom_format) )
865         {
866             if (log)
867                 log->Printf("%s is an unknown format", format_name);
868             // if this is an @ sign, print ObjC description
869             if (*format_name == '@')
870                 *val_obj_display = ValueObject::eValueObjectRepresentationStyleLanguageSpecific;
871             // if this is a V, print the value using the default format
872             else if (*format_name == 'V')
873                 *val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
874             // if this is an L, print the location of the value
875             else if (*format_name == 'L')
876                 *val_obj_display = ValueObject::eValueObjectRepresentationStyleLocation;
877             // if this is an S, print the summary after all
878             else if (*format_name == 'S')
879                 *val_obj_display = ValueObject::eValueObjectRepresentationStyleSummary;
880             else if (*format_name == '#')
881                 *val_obj_display = ValueObject::eValueObjectRepresentationStyleChildrenCount;
882             else if (*format_name == 'T')
883                 *val_obj_display = ValueObject::eValueObjectRepresentationStyleType;
884             else if (log)
885                 log->Printf("%s is an error, leaving the previous value alone", format_name);
886         }
887         // a good custom format tells us to print the value using it
888         else
889         {
890             if (log)
891                 log->Printf("will display value for this VO");
892             *val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
893         }
894         delete format_name;
895     }
896     if (log)
897         log->Printf("final format description outcome: custom_format = %d, val_obj_display = %d",
898                     *custom_format,
899                     *val_obj_display);
900     return true;
901 }
902 
903 static bool
904 ScanBracketedRange (const char* var_name_begin,
905                     const char* var_name_end,
906                     const char* var_name_final,
907                     const char** open_bracket_position,
908                     const char** separator_position,
909                     const char** close_bracket_position,
910                     const char** var_name_final_if_array_range,
911                     int64_t* index_lower,
912                     int64_t* index_higher)
913 {
914     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
915     *open_bracket_position = ::strchr(var_name_begin,'[');
916     if (*open_bracket_position && *open_bracket_position < var_name_final)
917     {
918         *separator_position = ::strchr(*open_bracket_position,'-'); // might be NULL if this is a simple var[N] bitfield
919         *close_bracket_position = ::strchr(*open_bracket_position,']');
920         // as usual, we assume that [] will come before %
921         //printf("trying to expand a []\n");
922         *var_name_final_if_array_range = *open_bracket_position;
923         if (*close_bracket_position - *open_bracket_position == 1)
924         {
925             if (log)
926                 log->Printf("[] detected.. going from 0 to end of data");
927             *index_lower = 0;
928         }
929         else if (*separator_position == NULL || *separator_position > var_name_end)
930         {
931             char *end = NULL;
932             *index_lower = ::strtoul (*open_bracket_position+1, &end, 0);
933             *index_higher = *index_lower;
934             if (log)
935                 log->Printf("[%lld] detected, high index is same", *index_lower);
936         }
937         else if (*close_bracket_position && *close_bracket_position < var_name_end)
938         {
939             char *end = NULL;
940             *index_lower = ::strtoul (*open_bracket_position+1, &end, 0);
941             *index_higher = ::strtoul (*separator_position+1, &end, 0);
942             if (log)
943                 log->Printf("[%lld-%lld] detected", *index_lower, *index_higher);
944         }
945         else
946         {
947             if (log)
948                 log->Printf("expression is erroneous, cannot extract indices out of it");
949             return false;
950         }
951         if (*index_lower > *index_higher && *index_higher > 0)
952         {
953             if (log)
954                 log->Printf("swapping indices");
955             int temp = *index_lower;
956             *index_lower = *index_higher;
957             *index_higher = temp;
958         }
959     }
960     else if (log)
961             log->Printf("no bracketed range, skipping entirely");
962     return true;
963 }
964 
965 
966 static ValueObjectSP
967 ExpandExpressionPath (ValueObject* valobj,
968                       StackFrame* frame,
969                       bool* do_deref_pointer,
970                       const char* var_name_begin,
971                       const char* var_name_final,
972                       Error& error)
973 {
974     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
975     StreamString sstring;
976     VariableSP var_sp;
977 
978     if (*do_deref_pointer)
979     {
980         if (log)
981             log->Printf("been told to deref_pointer by caller");
982         sstring.PutChar('*');
983     }
984     else if (valobj->IsDereferenceOfParent() && ClangASTContext::IsPointerType(valobj->GetParent()->GetClangType()) && !valobj->IsArrayItemForPointer())
985     {
986         if (log)
987             log->Printf("decided to deref_pointer myself");
988         sstring.PutChar('*');
989         *do_deref_pointer = true;
990     }
991 
992     valobj->GetExpressionPath(sstring, true, ValueObject::eGetExpressionPathFormatHonorPointers);
993     if (log)
994         log->Printf("expression path to expand in phase 0: %s",sstring.GetData());
995     sstring.PutRawBytes(var_name_begin+3, var_name_final-var_name_begin-3);
996     if (log)
997         log->Printf("expression path to expand in phase 1: %s",sstring.GetData());
998     std::string name = std::string(sstring.GetData());
999     ValueObjectSP target = frame->GetValueForVariableExpressionPath (name.c_str(),
1000                                                                      eNoDynamicValues,
1001                                                                      0,
1002                                                                      var_sp,
1003                                                                      error);
1004     return target;
1005 }
1006 
1007 static ValueObjectSP
1008 ExpandIndexedExpression (ValueObject* valobj,
1009                          uint32_t index,
1010                          StackFrame* frame,
1011                          bool deref_pointer)
1012 {
1013     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
1014     const char* ptr_deref_format = "[%d]";
1015     std::auto_ptr<char> ptr_deref_buffer(new char[10]);
1016     ::sprintf(ptr_deref_buffer.get(), ptr_deref_format, index);
1017     if (log)
1018         log->Printf("name to deref: %s",ptr_deref_buffer.get());
1019     const char* first_unparsed;
1020     ValueObject::GetValueForExpressionPathOptions options;
1021     ValueObject::ExpressionPathEndResultType final_value_type;
1022     ValueObject::ExpressionPathScanEndReason reason_to_stop;
1023     ValueObject::ExpressionPathAftermath what_next = (deref_pointer ? ValueObject::eExpressionPathAftermathDereference : ValueObject::eExpressionPathAftermathNothing);
1024     ValueObjectSP item = valobj->GetValueForExpressionPath (ptr_deref_buffer.get(),
1025                                                           &first_unparsed,
1026                                                           &reason_to_stop,
1027                                                           &final_value_type,
1028                                                           options,
1029                                                           &what_next);
1030     if (!item)
1031     {
1032         if (log)
1033             log->Printf("ERROR: unparsed portion = %s, why stopping = %d,"
1034                " final_value_type %d",
1035                first_unparsed, reason_to_stop, final_value_type);
1036     }
1037     else
1038     {
1039         if (log)
1040             log->Printf("ALL RIGHT: unparsed portion = %s, why stopping = %d,"
1041                " final_value_type %d",
1042                first_unparsed, reason_to_stop, final_value_type);
1043     }
1044     return item;
1045 }
1046 
1047 bool
1048 Debugger::FormatPrompt
1049 (
1050     const char *format,
1051     const SymbolContext *sc,
1052     const ExecutionContext *exe_ctx,
1053     const Address *addr,
1054     Stream &s,
1055     const char **end,
1056     ValueObject* valobj
1057 )
1058 {
1059     ValueObject* realvalobj = NULL; // makes it super-easy to parse pointers
1060     bool success = true;
1061     const char *p;
1062     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
1063     for (p = format; *p != '\0'; ++p)
1064     {
1065         if (realvalobj)
1066         {
1067             valobj = realvalobj;
1068             realvalobj = NULL;
1069         }
1070         size_t non_special_chars = ::strcspn (p, "${}\\");
1071         if (non_special_chars > 0)
1072         {
1073             if (success)
1074                 s.Write (p, non_special_chars);
1075             p += non_special_chars;
1076         }
1077 
1078         if (*p == '\0')
1079         {
1080             break;
1081         }
1082         else if (*p == '{')
1083         {
1084             // Start a new scope that must have everything it needs if it is to
1085             // to make it into the final output stream "s". If you want to make
1086             // a format that only prints out the function or symbol name if there
1087             // is one in the symbol context you can use:
1088             //      "{function =${function.name}}"
1089             // The first '{' starts a new scope that end with the matching '}' at
1090             // the end of the string. The contents "function =${function.name}"
1091             // will then be evaluated and only be output if there is a function
1092             // or symbol with a valid name.
1093             StreamString sub_strm;
1094 
1095             ++p;  // Skip the '{'
1096 
1097             if (FormatPrompt (p, sc, exe_ctx, addr, sub_strm, &p, valobj))
1098             {
1099                 // The stream had all it needed
1100                 s.Write(sub_strm.GetData(), sub_strm.GetSize());
1101             }
1102             if (*p != '}')
1103             {
1104                 success = false;
1105                 break;
1106             }
1107         }
1108         else if (*p == '}')
1109         {
1110             // End of a enclosing scope
1111             break;
1112         }
1113         else if (*p == '$')
1114         {
1115             // We have a prompt variable to print
1116             ++p;
1117             if (*p == '{')
1118             {
1119                 ++p;
1120                 const char *var_name_begin = p;
1121                 const char *var_name_end = ::strchr (p, '}');
1122 
1123                 if (var_name_end && var_name_begin < var_name_end)
1124                 {
1125                     // if we have already failed to parse, skip this variable
1126                     if (success)
1127                     {
1128                         const char *cstr = NULL;
1129                         Address format_addr;
1130                         bool calculate_format_addr_function_offset = false;
1131                         // Set reg_kind and reg_num to invalid values
1132                         RegisterKind reg_kind = kNumRegisterKinds;
1133                         uint32_t reg_num = LLDB_INVALID_REGNUM;
1134                         FileSpec format_file_spec;
1135                         const RegisterInfo *reg_info = NULL;
1136                         RegisterContext *reg_ctx = NULL;
1137                         bool do_deref_pointer = false;
1138                         ValueObject::ExpressionPathScanEndReason reason_to_stop = ValueObject::eExpressionPathScanEndReasonEndOfString;
1139                         ValueObject::ExpressionPathEndResultType final_value_type = ValueObject::eExpressionPathEndResultTypePlain;
1140 
1141                         // Each variable must set success to true below...
1142                         bool var_success = false;
1143                         switch (var_name_begin[0])
1144                         {
1145                         case '*':
1146                         case 'v':
1147                         case 's':
1148                             {
1149                                 if (!valobj)
1150                                     break;
1151 
1152                                 if (log)
1153                                     log->Printf("initial string: %s",var_name_begin);
1154 
1155                                 // check for *var and *svar
1156                                 if (*var_name_begin == '*')
1157                                 {
1158                                     do_deref_pointer = true;
1159                                     var_name_begin++;
1160                                 }
1161 
1162                                 if (log)
1163                                     log->Printf("initial string: %s",var_name_begin);
1164 
1165                                 if (*var_name_begin == 's')
1166                                 {
1167                                     if (!valobj->IsSynthetic())
1168                                         valobj = valobj->GetSyntheticValue().get();
1169                                     if (!valobj)
1170                                         break;
1171                                     var_name_begin++;
1172                                 }
1173 
1174                                 if (log)
1175                                     log->Printf("initial string: %s",var_name_begin);
1176 
1177                                 // should be a 'v' by now
1178                                 if (*var_name_begin != 'v')
1179                                     break;
1180 
1181                                 if (log)
1182                                     log->Printf("initial string: %s",var_name_begin);
1183 
1184                                 ValueObject::ExpressionPathAftermath what_next = (do_deref_pointer ?
1185                                                                                   ValueObject::eExpressionPathAftermathDereference : ValueObject::eExpressionPathAftermathNothing);
1186                                 ValueObject::GetValueForExpressionPathOptions options;
1187                                 options.DontCheckDotVsArrowSyntax().DoAllowBitfieldSyntax().DoAllowFragileIVar().DoAllowSyntheticChildren();
1188                                 ValueObject::ValueObjectRepresentationStyle val_obj_display = ValueObject::eValueObjectRepresentationStyleSummary;
1189                                 ValueObject* target = NULL;
1190                                 Format custom_format = eFormatInvalid;
1191                                 const char* var_name_final = NULL;
1192                                 const char* var_name_final_if_array_range = NULL;
1193                                 const char* close_bracket_position = NULL;
1194                                 int64_t index_lower = -1;
1195                                 int64_t index_higher = -1;
1196                                 bool is_array_range = false;
1197                                 const char* first_unparsed;
1198                                 bool was_plain_var = false;
1199                                 bool was_var_format = false;
1200 
1201                                 if (!valobj) break;
1202                                 // simplest case ${var}, just print valobj's value
1203                                 if (::strncmp (var_name_begin, "var}", strlen("var}")) == 0)
1204                                 {
1205                                     was_plain_var = true;
1206                                     target = valobj;
1207                                     val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
1208                                 }
1209                                 else if (::strncmp(var_name_begin,"var%",strlen("var%")) == 0)
1210                                 {
1211                                     was_var_format = true;
1212                                     // this is a variable with some custom format applied to it
1213                                     const char* percent_position;
1214                                     target = valobj;
1215                                     val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
1216                                     ScanFormatDescriptor (var_name_begin,
1217                                                           var_name_end,
1218                                                           &var_name_final,
1219                                                           &percent_position,
1220                                                           &custom_format,
1221                                                           &val_obj_display);
1222                                 }
1223                                     // this is ${var.something} or multiple .something nested
1224                                 else if (::strncmp (var_name_begin, "var", strlen("var")) == 0)
1225                                 {
1226 
1227                                     const char* percent_position;
1228                                     ScanFormatDescriptor (var_name_begin,
1229                                                           var_name_end,
1230                                                           &var_name_final,
1231                                                           &percent_position,
1232                                                           &custom_format,
1233                                                           &val_obj_display);
1234 
1235                                     const char* open_bracket_position;
1236                                     const char* separator_position;
1237                                     ScanBracketedRange (var_name_begin,
1238                                                         var_name_end,
1239                                                         var_name_final,
1240                                                         &open_bracket_position,
1241                                                         &separator_position,
1242                                                         &close_bracket_position,
1243                                                         &var_name_final_if_array_range,
1244                                                         &index_lower,
1245                                                         &index_higher);
1246 
1247                                     Error error;
1248 
1249                                     std::auto_ptr<char> expr_path(new char[var_name_final-var_name_begin-1]);
1250                                     ::memset(expr_path.get(), 0, var_name_final-var_name_begin-1);
1251                                     memcpy(expr_path.get(), var_name_begin+3,var_name_final-var_name_begin-3);
1252 
1253                                     if (log)
1254                                         log->Printf("symbol to expand: %s",expr_path.get());
1255 
1256                                     target = valobj->GetValueForExpressionPath(expr_path.get(),
1257                                                                              &first_unparsed,
1258                                                                              &reason_to_stop,
1259                                                                              &final_value_type,
1260                                                                              options,
1261                                                                              &what_next).get();
1262 
1263                                     if (!target)
1264                                     {
1265                                         if (log)
1266                                             log->Printf("ERROR: unparsed portion = %s, why stopping = %d,"
1267                                                " final_value_type %d",
1268                                                first_unparsed, reason_to_stop, final_value_type);
1269                                         break;
1270                                     }
1271                                     else
1272                                     {
1273                                         if (log)
1274                                             log->Printf("ALL RIGHT: unparsed portion = %s, why stopping = %d,"
1275                                                " final_value_type %d",
1276                                                first_unparsed, reason_to_stop, final_value_type);
1277                                     }
1278                                 }
1279                                 else
1280                                     break;
1281 
1282                                 is_array_range = (final_value_type == ValueObject::eExpressionPathEndResultTypeBoundedRange ||
1283                                                   final_value_type == ValueObject::eExpressionPathEndResultTypeUnboundedRange);
1284 
1285                                 do_deref_pointer = (what_next == ValueObject::eExpressionPathAftermathDereference);
1286 
1287                                 if (do_deref_pointer && !is_array_range)
1288                                 {
1289                                     // I have not deref-ed yet, let's do it
1290                                     // this happens when we are not going through GetValueForVariableExpressionPath
1291                                     // to get to the target ValueObject
1292                                     Error error;
1293                                     target = target->Dereference(error).get();
1294                                     if (error.Fail())
1295                                     {
1296                                         if (log)
1297                                             log->Printf("ERROR: %s\n", error.AsCString("unknown")); \
1298                                         break;
1299                                     }
1300                                     do_deref_pointer = false;
1301                                 }
1302 
1303                                 // TODO use flags for these
1304                                 bool is_array = ClangASTContext::IsArrayType(target->GetClangType());
1305                                 bool is_pointer = ClangASTContext::IsPointerType(target->GetClangType());
1306                                 bool is_aggregate = ClangASTContext::IsAggregateType(target->GetClangType());
1307 
1308                                 if ((is_array || is_pointer) && (!is_array_range) && val_obj_display == ValueObject::eValueObjectRepresentationStyleValue) // this should be wrong, but there are some exceptions
1309                                 {
1310                                     StreamString str_temp;
1311                                     if (log)
1312                                         log->Printf("I am into array || pointer && !range");
1313 
1314                                     if (target->HasSpecialPrintableRepresentation(val_obj_display,
1315                                                                                   custom_format))
1316                                     {
1317                                         // try to use the special cases
1318                                         var_success = target->DumpPrintableRepresentation(str_temp,
1319                                                                                           val_obj_display,
1320                                                                                           custom_format);
1321                                         if (log)
1322                                             log->Printf("special cases did%s match", var_success ? "" : "n't");
1323 
1324                                         // should not happen
1325                                         if (!var_success)
1326                                             s << "<invalid usage of pointer value as object>";
1327                                         else
1328                                             s << str_temp.GetData();
1329                                         var_success = true;
1330                                         break;
1331                                     }
1332                                     else
1333                                     {
1334                                         if (was_plain_var) // if ${var}
1335                                         {
1336                                             s << target->GetTypeName() << " @ " << target->GetLocationAsCString();
1337                                         }
1338                                         else if (is_pointer) // if pointer, value is the address stored
1339                                         {
1340                                             var_success = target->DumpPrintableRepresentation(s,
1341                                                                                              val_obj_display,
1342                                                                                              custom_format,
1343                                                                                              ValueObject::ePrintableRepresentationSpecialCasesDisable);
1344                                         }
1345                                         else
1346                                         {
1347                                             s << "<invalid usage of pointer value as object>";
1348                                         }
1349                                         var_success = true;
1350                                         break;
1351                                     }
1352                                 }
1353 
1354                                 // if directly trying to print ${var}, and this is an aggregate, display a nice
1355                                 // type @ location message
1356                                 if (is_aggregate && was_plain_var)
1357                                 {
1358                                     s << target->GetTypeName() << " @ " << target->GetLocationAsCString();
1359                                     var_success = true;
1360                                     break;
1361                                 }
1362 
1363                                 // if directly trying to print ${var%V}, and this is an aggregate, do not let the user do it
1364                                 if (is_aggregate && ((was_var_format && val_obj_display == ValueObject::eValueObjectRepresentationStyleValue)))
1365                                 {
1366                                     s << "<invalid use of aggregate type>";
1367                                     var_success = true;
1368                                     break;
1369                                 }
1370 
1371                                 if (!is_array_range)
1372                                 {
1373                                     if (log)
1374                                         log->Printf("dumping ordinary printable output");
1375                                     var_success = target->DumpPrintableRepresentation(s,val_obj_display, custom_format);
1376                                 }
1377                                 else
1378                                 {
1379                                     if (log)
1380                                         log->Printf("checking if I can handle as array");
1381                                     if (!is_array && !is_pointer)
1382                                         break;
1383                                     if (log)
1384                                         log->Printf("handle as array");
1385                                     const char* special_directions = NULL;
1386                                     StreamString special_directions_writer;
1387                                     if (close_bracket_position && (var_name_end-close_bracket_position > 1))
1388                                     {
1389                                         ConstString additional_data;
1390                                         additional_data.SetCStringWithLength(close_bracket_position+1, var_name_end-close_bracket_position-1);
1391                                         special_directions_writer.Printf("${%svar%s}",
1392                                                                          do_deref_pointer ? "*" : "",
1393                                                                          additional_data.GetCString());
1394                                         special_directions = special_directions_writer.GetData();
1395                                     }
1396 
1397                                     // let us display items index_lower thru index_higher of this array
1398                                     s.PutChar('[');
1399                                     var_success = true;
1400 
1401                                     if (index_higher < 0)
1402                                         index_higher = valobj->GetNumChildren() - 1;
1403 
1404                                     uint32_t max_num_children = target->GetTargetSP()->GetMaximumNumberOfChildrenToDisplay();
1405 
1406                                     for (;index_lower<=index_higher;index_lower++)
1407                                     {
1408                                         ValueObject* item = ExpandIndexedExpression (target,
1409                                                                                      index_lower,
1410                                                                                      exe_ctx->GetFramePtr(),
1411                                                                                      false).get();
1412 
1413                                         if (!item)
1414                                         {
1415                                             if (log)
1416                                                 log->Printf("ERROR in getting child item at index %lld", index_lower);
1417                                         }
1418                                         else
1419                                         {
1420                                             if (log)
1421                                                 log->Printf("special_directions for child item: %s",special_directions);
1422                                         }
1423 
1424                                         if (!special_directions)
1425                                             var_success &= item->DumpPrintableRepresentation(s,val_obj_display, custom_format);
1426                                         else
1427                                             var_success &= FormatPrompt(special_directions, sc, exe_ctx, addr, s, NULL, item);
1428 
1429                                         if (--max_num_children == 0)
1430                                         {
1431                                             s.PutCString(", ...");
1432                                             break;
1433                                         }
1434 
1435                                         if (index_lower < index_higher)
1436                                             s.PutChar(',');
1437                                     }
1438                                     s.PutChar(']');
1439                                 }
1440                             }
1441                             break;
1442                         case 'a':
1443                             if (::strncmp (var_name_begin, "addr}", strlen("addr}")) == 0)
1444                             {
1445                                 if (addr && addr->IsValid())
1446                                 {
1447                                     var_success = true;
1448                                     format_addr = *addr;
1449                                 }
1450                             }
1451                             else if (::strncmp (var_name_begin, "ansi.", strlen("ansi.")) == 0)
1452                             {
1453                                 var_success = true;
1454                                 var_name_begin += strlen("ansi."); // Skip the "ansi."
1455                                 if (::strncmp (var_name_begin, "fg.", strlen("fg.")) == 0)
1456                                 {
1457                                     var_name_begin += strlen("fg."); // Skip the "fg."
1458                                     if (::strncmp (var_name_begin, "black}", strlen("black}")) == 0)
1459                                     {
1460                                         s.Printf ("%s%s%s",
1461                                                   lldb_utility::ansi::k_escape_start,
1462                                                   lldb_utility::ansi::k_fg_black,
1463                                                   lldb_utility::ansi::k_escape_end);
1464                                     }
1465                                     else if (::strncmp (var_name_begin, "red}", strlen("red}")) == 0)
1466                                     {
1467                                         s.Printf ("%s%s%s",
1468                                                   lldb_utility::ansi::k_escape_start,
1469                                                   lldb_utility::ansi::k_fg_red,
1470                                                   lldb_utility::ansi::k_escape_end);
1471                                     }
1472                                     else if (::strncmp (var_name_begin, "green}", strlen("green}")) == 0)
1473                                     {
1474                                         s.Printf ("%s%s%s",
1475                                                   lldb_utility::ansi::k_escape_start,
1476                                                   lldb_utility::ansi::k_fg_green,
1477                                                   lldb_utility::ansi::k_escape_end);
1478                                     }
1479                                     else if (::strncmp (var_name_begin, "yellow}", strlen("yellow}")) == 0)
1480                                     {
1481                                         s.Printf ("%s%s%s",
1482                                                   lldb_utility::ansi::k_escape_start,
1483                                                   lldb_utility::ansi::k_fg_yellow,
1484                                                   lldb_utility::ansi::k_escape_end);
1485                                     }
1486                                     else if (::strncmp (var_name_begin, "blue}", strlen("blue}")) == 0)
1487                                     {
1488                                         s.Printf ("%s%s%s",
1489                                                   lldb_utility::ansi::k_escape_start,
1490                                                   lldb_utility::ansi::k_fg_blue,
1491                                                   lldb_utility::ansi::k_escape_end);
1492                                     }
1493                                     else if (::strncmp (var_name_begin, "purple}", strlen("purple}")) == 0)
1494                                     {
1495                                         s.Printf ("%s%s%s",
1496                                                   lldb_utility::ansi::k_escape_start,
1497                                                   lldb_utility::ansi::k_fg_purple,
1498                                                   lldb_utility::ansi::k_escape_end);
1499                                     }
1500                                     else if (::strncmp (var_name_begin, "cyan}", strlen("cyan}")) == 0)
1501                                     {
1502                                         s.Printf ("%s%s%s",
1503                                                   lldb_utility::ansi::k_escape_start,
1504                                                   lldb_utility::ansi::k_fg_cyan,
1505                                                   lldb_utility::ansi::k_escape_end);
1506                                     }
1507                                     else if (::strncmp (var_name_begin, "white}", strlen("white}")) == 0)
1508                                     {
1509                                         s.Printf ("%s%s%s",
1510                                                   lldb_utility::ansi::k_escape_start,
1511                                                   lldb_utility::ansi::k_fg_white,
1512                                                   lldb_utility::ansi::k_escape_end);
1513                                     }
1514                                     else
1515                                     {
1516                                         var_success = false;
1517                                     }
1518                                 }
1519                                 else if (::strncmp (var_name_begin, "bg.", strlen("bg.")) == 0)
1520                                 {
1521                                     var_name_begin += strlen("bg."); // Skip the "bg."
1522                                     if (::strncmp (var_name_begin, "black}", strlen("black}")) == 0)
1523                                     {
1524                                         s.Printf ("%s%s%s",
1525                                                   lldb_utility::ansi::k_escape_start,
1526                                                   lldb_utility::ansi::k_bg_black,
1527                                                   lldb_utility::ansi::k_escape_end);
1528                                     }
1529                                     else if (::strncmp (var_name_begin, "red}", strlen("red}")) == 0)
1530                                     {
1531                                         s.Printf ("%s%s%s",
1532                                                   lldb_utility::ansi::k_escape_start,
1533                                                   lldb_utility::ansi::k_bg_red,
1534                                                   lldb_utility::ansi::k_escape_end);
1535                                     }
1536                                     else if (::strncmp (var_name_begin, "green}", strlen("green}")) == 0)
1537                                     {
1538                                         s.Printf ("%s%s%s",
1539                                                   lldb_utility::ansi::k_escape_start,
1540                                                   lldb_utility::ansi::k_bg_green,
1541                                                   lldb_utility::ansi::k_escape_end);
1542                                     }
1543                                     else if (::strncmp (var_name_begin, "yellow}", strlen("yellow}")) == 0)
1544                                     {
1545                                         s.Printf ("%s%s%s",
1546                                                   lldb_utility::ansi::k_escape_start,
1547                                                   lldb_utility::ansi::k_bg_yellow,
1548                                                   lldb_utility::ansi::k_escape_end);
1549                                     }
1550                                     else if (::strncmp (var_name_begin, "blue}", strlen("blue}")) == 0)
1551                                     {
1552                                         s.Printf ("%s%s%s",
1553                                                   lldb_utility::ansi::k_escape_start,
1554                                                   lldb_utility::ansi::k_bg_blue,
1555                                                   lldb_utility::ansi::k_escape_end);
1556                                     }
1557                                     else if (::strncmp (var_name_begin, "purple}", strlen("purple}")) == 0)
1558                                     {
1559                                         s.Printf ("%s%s%s",
1560                                                   lldb_utility::ansi::k_escape_start,
1561                                                   lldb_utility::ansi::k_bg_purple,
1562                                                   lldb_utility::ansi::k_escape_end);
1563                                     }
1564                                     else if (::strncmp (var_name_begin, "cyan}", strlen("cyan}")) == 0)
1565                                     {
1566                                         s.Printf ("%s%s%s",
1567                                                   lldb_utility::ansi::k_escape_start,
1568                                                   lldb_utility::ansi::k_bg_cyan,
1569                                                   lldb_utility::ansi::k_escape_end);
1570                                     }
1571                                     else if (::strncmp (var_name_begin, "white}", strlen("white}")) == 0)
1572                                     {
1573                                         s.Printf ("%s%s%s",
1574                                                   lldb_utility::ansi::k_escape_start,
1575                                                   lldb_utility::ansi::k_bg_white,
1576                                                   lldb_utility::ansi::k_escape_end);
1577                                     }
1578                                     else
1579                                     {
1580                                         var_success = false;
1581                                     }
1582                                 }
1583                                 else if (::strncmp (var_name_begin, "normal}", strlen ("normal}")) == 0)
1584                                 {
1585                                     s.Printf ("%s%s%s",
1586                                               lldb_utility::ansi::k_escape_start,
1587                                               lldb_utility::ansi::k_ctrl_normal,
1588                                               lldb_utility::ansi::k_escape_end);
1589                                 }
1590                                 else if (::strncmp (var_name_begin, "bold}", strlen("bold}")) == 0)
1591                                 {
1592                                     s.Printf ("%s%s%s",
1593                                               lldb_utility::ansi::k_escape_start,
1594                                               lldb_utility::ansi::k_ctrl_bold,
1595                                               lldb_utility::ansi::k_escape_end);
1596                                 }
1597                                 else if (::strncmp (var_name_begin, "faint}", strlen("faint}")) == 0)
1598                                 {
1599                                     s.Printf ("%s%s%s",
1600                                               lldb_utility::ansi::k_escape_start,
1601                                               lldb_utility::ansi::k_ctrl_faint,
1602                                               lldb_utility::ansi::k_escape_end);
1603                                 }
1604                                 else if (::strncmp (var_name_begin, "italic}", strlen("italic}")) == 0)
1605                                 {
1606                                     s.Printf ("%s%s%s",
1607                                               lldb_utility::ansi::k_escape_start,
1608                                               lldb_utility::ansi::k_ctrl_italic,
1609                                               lldb_utility::ansi::k_escape_end);
1610                                 }
1611                                 else if (::strncmp (var_name_begin, "underline}", strlen("underline}")) == 0)
1612                                 {
1613                                     s.Printf ("%s%s%s",
1614                                               lldb_utility::ansi::k_escape_start,
1615                                               lldb_utility::ansi::k_ctrl_underline,
1616                                               lldb_utility::ansi::k_escape_end);
1617                                 }
1618                                 else if (::strncmp (var_name_begin, "slow-blink}", strlen("slow-blink}")) == 0)
1619                                 {
1620                                     s.Printf ("%s%s%s",
1621                                               lldb_utility::ansi::k_escape_start,
1622                                               lldb_utility::ansi::k_ctrl_slow_blink,
1623                                               lldb_utility::ansi::k_escape_end);
1624                                 }
1625                                 else if (::strncmp (var_name_begin, "fast-blink}", strlen("fast-blink}")) == 0)
1626                                 {
1627                                     s.Printf ("%s%s%s",
1628                                               lldb_utility::ansi::k_escape_start,
1629                                               lldb_utility::ansi::k_ctrl_fast_blink,
1630                                               lldb_utility::ansi::k_escape_end);
1631                                 }
1632                                 else if (::strncmp (var_name_begin, "negative}", strlen("negative}")) == 0)
1633                                 {
1634                                     s.Printf ("%s%s%s",
1635                                               lldb_utility::ansi::k_escape_start,
1636                                               lldb_utility::ansi::k_ctrl_negative,
1637                                               lldb_utility::ansi::k_escape_end);
1638                                 }
1639                                 else if (::strncmp (var_name_begin, "conceal}", strlen("conceal}")) == 0)
1640                                 {
1641                                     s.Printf ("%s%s%s",
1642                                               lldb_utility::ansi::k_escape_start,
1643                                               lldb_utility::ansi::k_ctrl_conceal,
1644                                               lldb_utility::ansi::k_escape_end);
1645 
1646                                 }
1647                                 else if (::strncmp (var_name_begin, "crossed-out}", strlen("crossed-out}")) == 0)
1648                                 {
1649                                     s.Printf ("%s%s%s",
1650                                               lldb_utility::ansi::k_escape_start,
1651                                               lldb_utility::ansi::k_ctrl_crossed_out,
1652                                               lldb_utility::ansi::k_escape_end);
1653                                 }
1654                                 else
1655                                 {
1656                                     var_success = false;
1657                                 }
1658                             }
1659                             break;
1660 
1661                         case 'p':
1662                             if (::strncmp (var_name_begin, "process.", strlen("process.")) == 0)
1663                             {
1664                                 if (exe_ctx)
1665                                 {
1666                                     Process *process = exe_ctx->GetProcessPtr();
1667                                     if (process)
1668                                     {
1669                                         var_name_begin += ::strlen ("process.");
1670                                         if (::strncmp (var_name_begin, "id}", strlen("id}")) == 0)
1671                                         {
1672                                             s.Printf("%llu", process->GetID());
1673                                             var_success = true;
1674                                         }
1675                                         else if ((::strncmp (var_name_begin, "name}", strlen("name}")) == 0) ||
1676                                                  (::strncmp (var_name_begin, "file.basename}", strlen("file.basename}")) == 0) ||
1677                                                  (::strncmp (var_name_begin, "file.fullpath}", strlen("file.fullpath}")) == 0))
1678                                         {
1679                                             Module *exe_module = process->GetTarget().GetExecutableModulePointer();
1680                                             if (exe_module)
1681                                             {
1682                                                 if (var_name_begin[0] == 'n' || var_name_begin[5] == 'f')
1683                                                 {
1684                                                     format_file_spec.GetFilename() = exe_module->GetFileSpec().GetFilename();
1685                                                     var_success = format_file_spec;
1686                                                 }
1687                                                 else
1688                                                 {
1689                                                     format_file_spec = exe_module->GetFileSpec();
1690                                                     var_success = format_file_spec;
1691                                                 }
1692                                             }
1693                                         }
1694                                     }
1695                                 }
1696                             }
1697                             break;
1698 
1699                         case 't':
1700                             if (::strncmp (var_name_begin, "thread.", strlen("thread.")) == 0)
1701                             {
1702                                 if (exe_ctx)
1703                                 {
1704                                     Thread *thread = exe_ctx->GetThreadPtr();
1705                                     if (thread)
1706                                     {
1707                                         var_name_begin += ::strlen ("thread.");
1708                                         if (::strncmp (var_name_begin, "id}", strlen("id}")) == 0)
1709                                         {
1710                                             s.Printf("0x%4.4llx", thread->GetID());
1711                                             var_success = true;
1712                                         }
1713                                         else if (::strncmp (var_name_begin, "index}", strlen("index}")) == 0)
1714                                         {
1715                                             s.Printf("%u", thread->GetIndexID());
1716                                             var_success = true;
1717                                         }
1718                                         else if (::strncmp (var_name_begin, "name}", strlen("name}")) == 0)
1719                                         {
1720                                             cstr = thread->GetName();
1721                                             var_success = cstr && cstr[0];
1722                                             if (var_success)
1723                                                 s.PutCString(cstr);
1724                                         }
1725                                         else if (::strncmp (var_name_begin, "queue}", strlen("queue}")) == 0)
1726                                         {
1727                                             cstr = thread->GetQueueName();
1728                                             var_success = cstr && cstr[0];
1729                                             if (var_success)
1730                                                 s.PutCString(cstr);
1731                                         }
1732                                         else if (::strncmp (var_name_begin, "stop-reason}", strlen("stop-reason}")) == 0)
1733                                         {
1734                                             StopInfoSP stop_info_sp = thread->GetStopInfo ();
1735                                             if (stop_info_sp)
1736                                             {
1737                                                 cstr = stop_info_sp->GetDescription();
1738                                                 if (cstr && cstr[0])
1739                                                 {
1740                                                     s.PutCString(cstr);
1741                                                     var_success = true;
1742                                                 }
1743                                             }
1744                                         }
1745                                         else if (::strncmp (var_name_begin, "return-value}", strlen("return-value}")) == 0)
1746                                         {
1747                                             StopInfoSP stop_info_sp = thread->GetStopInfo ();
1748                                             if (stop_info_sp)
1749                                             {
1750                                                 ValueObjectSP return_valobj_sp = StopInfo::GetReturnValueObject (stop_info_sp);
1751                                                 if (return_valobj_sp)
1752                                                 {
1753                                                     ValueObject::DumpValueObjectOptions dump_options;
1754                                                     ValueObject::DumpValueObject (s, return_valobj_sp.get(), dump_options);
1755                                                     var_success = true;
1756                                                 }
1757                                             }
1758                                         }
1759                                     }
1760                                 }
1761                             }
1762                             else if (::strncmp (var_name_begin, "target.", strlen("target.")) == 0)
1763                             {
1764                                 Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
1765                                 if (target)
1766                                 {
1767                                     var_name_begin += ::strlen ("target.");
1768                                     if (::strncmp (var_name_begin, "arch}", strlen("arch}")) == 0)
1769                                     {
1770                                         ArchSpec arch (target->GetArchitecture ());
1771                                         if (arch.IsValid())
1772                                         {
1773                                             s.PutCString (arch.GetArchitectureName());
1774                                             var_success = true;
1775                                         }
1776                                     }
1777                                 }
1778                             }
1779                             break;
1780 
1781 
1782                         case 'm':
1783                             if (::strncmp (var_name_begin, "module.", strlen("module.")) == 0)
1784                             {
1785                                 if (sc && sc->module_sp.get())
1786                                 {
1787                                     Module *module = sc->module_sp.get();
1788                                     var_name_begin += ::strlen ("module.");
1789 
1790                                     if (::strncmp (var_name_begin, "file.", strlen("file.")) == 0)
1791                                     {
1792                                         if (module->GetFileSpec())
1793                                         {
1794                                             var_name_begin += ::strlen ("file.");
1795 
1796                                             if (::strncmp (var_name_begin, "basename}", strlen("basename}")) == 0)
1797                                             {
1798                                                 format_file_spec.GetFilename() = module->GetFileSpec().GetFilename();
1799                                                 var_success = format_file_spec;
1800                                             }
1801                                             else if (::strncmp (var_name_begin, "fullpath}", strlen("fullpath}")) == 0)
1802                                             {
1803                                                 format_file_spec = module->GetFileSpec();
1804                                                 var_success = format_file_spec;
1805                                             }
1806                                         }
1807                                     }
1808                                 }
1809                             }
1810                             break;
1811 
1812 
1813                         case 'f':
1814                             if (::strncmp (var_name_begin, "file.", strlen("file.")) == 0)
1815                             {
1816                                 if (sc && sc->comp_unit != NULL)
1817                                 {
1818                                     var_name_begin += ::strlen ("file.");
1819 
1820                                     if (::strncmp (var_name_begin, "basename}", strlen("basename}")) == 0)
1821                                     {
1822                                         format_file_spec.GetFilename() = sc->comp_unit->GetFilename();
1823                                         var_success = format_file_spec;
1824                                     }
1825                                     else if (::strncmp (var_name_begin, "fullpath}", strlen("fullpath}")) == 0)
1826                                     {
1827                                         format_file_spec = *sc->comp_unit;
1828                                         var_success = format_file_spec;
1829                                     }
1830                                 }
1831                             }
1832                             else if (::strncmp (var_name_begin, "frame.", strlen("frame.")) == 0)
1833                             {
1834                                 if (exe_ctx)
1835                                 {
1836                                     StackFrame *frame = exe_ctx->GetFramePtr();
1837                                     if (frame)
1838                                     {
1839                                         var_name_begin += ::strlen ("frame.");
1840                                         if (::strncmp (var_name_begin, "index}", strlen("index}")) == 0)
1841                                         {
1842                                             s.Printf("%u", frame->GetFrameIndex());
1843                                             var_success = true;
1844                                         }
1845                                         else if (::strncmp (var_name_begin, "pc}", strlen("pc}")) == 0)
1846                                         {
1847                                             reg_kind = eRegisterKindGeneric;
1848                                             reg_num = LLDB_REGNUM_GENERIC_PC;
1849                                             var_success = true;
1850                                         }
1851                                         else if (::strncmp (var_name_begin, "sp}", strlen("sp}")) == 0)
1852                                         {
1853                                             reg_kind = eRegisterKindGeneric;
1854                                             reg_num = LLDB_REGNUM_GENERIC_SP;
1855                                             var_success = true;
1856                                         }
1857                                         else if (::strncmp (var_name_begin, "fp}", strlen("fp}")) == 0)
1858                                         {
1859                                             reg_kind = eRegisterKindGeneric;
1860                                             reg_num = LLDB_REGNUM_GENERIC_FP;
1861                                             var_success = true;
1862                                         }
1863                                         else if (::strncmp (var_name_begin, "flags}", strlen("flags}")) == 0)
1864                                         {
1865                                             reg_kind = eRegisterKindGeneric;
1866                                             reg_num = LLDB_REGNUM_GENERIC_FLAGS;
1867                                             var_success = true;
1868                                         }
1869                                         else if (::strncmp (var_name_begin, "reg.", strlen ("reg.")) == 0)
1870                                         {
1871                                             reg_ctx = frame->GetRegisterContext().get();
1872                                             if (reg_ctx)
1873                                             {
1874                                                 var_name_begin += ::strlen ("reg.");
1875                                                 if (var_name_begin < var_name_end)
1876                                                 {
1877                                                     std::string reg_name (var_name_begin, var_name_end);
1878                                                     reg_info = reg_ctx->GetRegisterInfoByName (reg_name.c_str());
1879                                                     if (reg_info)
1880                                                         var_success = true;
1881                                                 }
1882                                             }
1883                                         }
1884                                     }
1885                                 }
1886                             }
1887                             else if (::strncmp (var_name_begin, "function.", strlen("function.")) == 0)
1888                             {
1889                                 if (sc && (sc->function != NULL || sc->symbol != NULL))
1890                                 {
1891                                     var_name_begin += ::strlen ("function.");
1892                                     if (::strncmp (var_name_begin, "id}", strlen("id}")) == 0)
1893                                     {
1894                                         if (sc->function)
1895                                             s.Printf("function{0x%8.8llx}", sc->function->GetID());
1896                                         else
1897                                             s.Printf("symbol[%u]", sc->symbol->GetID());
1898 
1899                                         var_success = true;
1900                                     }
1901                                     else if (::strncmp (var_name_begin, "name}", strlen("name}")) == 0)
1902                                     {
1903                                         if (sc->function)
1904                                             cstr = sc->function->GetName().AsCString (NULL);
1905                                         else if (sc->symbol)
1906                                             cstr = sc->symbol->GetName().AsCString (NULL);
1907                                         if (cstr)
1908                                         {
1909                                             s.PutCString(cstr);
1910 
1911                                             if (sc->block)
1912                                             {
1913                                                 Block *inline_block = sc->block->GetContainingInlinedBlock ();
1914                                                 if (inline_block)
1915                                                 {
1916                                                     const InlineFunctionInfo *inline_info = sc->block->GetInlinedFunctionInfo();
1917                                                     if (inline_info)
1918                                                     {
1919                                                         s.PutCString(" [inlined] ");
1920                                                         inline_info->GetName().Dump(&s);
1921                                                     }
1922                                                 }
1923                                             }
1924                                             var_success = true;
1925                                         }
1926                                     }
1927                                     else if (::strncmp (var_name_begin, "name-with-args}", strlen("name-with-args}")) == 0)
1928                                     {
1929                                         // Print the function name with arguments in it
1930 
1931                                         if (sc->function)
1932                                         {
1933                                             var_success = true;
1934                                             ExecutionContextScope *exe_scope = exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL;
1935                                             cstr = sc->function->GetName().AsCString (NULL);
1936                                             if (cstr)
1937                                             {
1938                                                 const InlineFunctionInfo *inline_info = NULL;
1939                                                 VariableListSP variable_list_sp;
1940                                                 bool get_function_vars = true;
1941                                                 if (sc->block)
1942                                                 {
1943                                                     Block *inline_block = sc->block->GetContainingInlinedBlock ();
1944 
1945                                                     if (inline_block)
1946                                                     {
1947                                                         get_function_vars = false;
1948                                                         inline_info = sc->block->GetInlinedFunctionInfo();
1949                                                         if (inline_info)
1950                                                             variable_list_sp = inline_block->GetBlockVariableList (true);
1951                                                     }
1952                                                 }
1953 
1954                                                 if (get_function_vars)
1955                                                 {
1956                                                     variable_list_sp = sc->function->GetBlock(true).GetBlockVariableList (true);
1957                                                 }
1958 
1959                                                 if (inline_info)
1960                                                 {
1961                                                     s.PutCString (cstr);
1962                                                     s.PutCString (" [inlined] ");
1963                                                     cstr = inline_info->GetName().GetCString();
1964                                                 }
1965 
1966                                                 VariableList args;
1967                                                 if (variable_list_sp)
1968                                                 {
1969                                                     const size_t num_variables = variable_list_sp->GetSize();
1970                                                     for (size_t var_idx = 0; var_idx < num_variables; ++var_idx)
1971                                                     {
1972                                                         VariableSP var_sp (variable_list_sp->GetVariableAtIndex(var_idx));
1973                                                         if (var_sp->GetScope() == eValueTypeVariableArgument)
1974                                                             args.AddVariable (var_sp);
1975                                                     }
1976 
1977                                                 }
1978                                                 if (args.GetSize() > 0)
1979                                                 {
1980                                                     const char *open_paren = strchr (cstr, '(');
1981                                                     const char *close_paren = NULL;
1982                                                     if (open_paren)
1983                                                         close_paren = strchr (open_paren, ')');
1984 
1985                                                     if (open_paren)
1986                                                         s.Write(cstr, open_paren - cstr + 1);
1987                                                     else
1988                                                     {
1989                                                         s.PutCString (cstr);
1990                                                         s.PutChar ('(');
1991                                                     }
1992                                                     const size_t num_args = args.GetSize();
1993                                                     for (size_t arg_idx = 0; arg_idx < num_args; ++arg_idx)
1994                                                     {
1995                                                         VariableSP var_sp (args.GetVariableAtIndex (arg_idx));
1996                                                         ValueObjectSP var_value_sp (ValueObjectVariable::Create (exe_scope, var_sp));
1997                                                         const char *var_name = var_value_sp->GetName().GetCString();
1998                                                         const char *var_value = var_value_sp->GetValueAsCString();
1999                                                         if (var_value_sp->GetError().Success())
2000                                                         {
2001                                                             if (arg_idx > 0)
2002                                                                 s.PutCString (", ");
2003                                                             s.Printf ("%s=%s", var_name, var_value);
2004                                                         }
2005                                                     }
2006 
2007                                                     if (close_paren)
2008                                                         s.PutCString (close_paren);
2009                                                     else
2010                                                         s.PutChar(')');
2011 
2012                                                 }
2013                                                 else
2014                                                 {
2015                                                     s.PutCString(cstr);
2016                                                 }
2017                                             }
2018                                         }
2019                                         else if (sc->symbol)
2020                                         {
2021                                             cstr = sc->symbol->GetName().AsCString (NULL);
2022                                             if (cstr)
2023                                             {
2024                                                 s.PutCString(cstr);
2025                                                 var_success = true;
2026                                             }
2027                                         }
2028                                     }
2029                                     else if (::strncmp (var_name_begin, "addr-offset}", strlen("addr-offset}")) == 0)
2030                                     {
2031                                         var_success = addr != NULL;
2032                                         if (var_success)
2033                                         {
2034                                             format_addr = *addr;
2035                                             calculate_format_addr_function_offset = true;
2036                                         }
2037                                     }
2038                                     else if (::strncmp (var_name_begin, "line-offset}", strlen("line-offset}")) == 0)
2039                                     {
2040                                         var_success = sc->line_entry.range.GetBaseAddress().IsValid();
2041                                         if (var_success)
2042                                         {
2043                                             format_addr = sc->line_entry.range.GetBaseAddress();
2044                                             calculate_format_addr_function_offset = true;
2045                                         }
2046                                     }
2047                                     else if (::strncmp (var_name_begin, "pc-offset}", strlen("pc-offset}")) == 0)
2048                                     {
2049                                         StackFrame *frame = exe_ctx->GetFramePtr();
2050                                         var_success = frame != NULL;
2051                                         if (var_success)
2052                                         {
2053                                             format_addr = frame->GetFrameCodeAddress();
2054                                             calculate_format_addr_function_offset = true;
2055                                         }
2056                                     }
2057                                 }
2058                             }
2059                             break;
2060 
2061                         case 'l':
2062                             if (::strncmp (var_name_begin, "line.", strlen("line.")) == 0)
2063                             {
2064                                 if (sc && sc->line_entry.IsValid())
2065                                 {
2066                                     var_name_begin += ::strlen ("line.");
2067                                     if (::strncmp (var_name_begin, "file.", strlen("file.")) == 0)
2068                                     {
2069                                         var_name_begin += ::strlen ("file.");
2070 
2071                                         if (::strncmp (var_name_begin, "basename}", strlen("basename}")) == 0)
2072                                         {
2073                                             format_file_spec.GetFilename() = sc->line_entry.file.GetFilename();
2074                                             var_success = format_file_spec;
2075                                         }
2076                                         else if (::strncmp (var_name_begin, "fullpath}", strlen("fullpath}")) == 0)
2077                                         {
2078                                             format_file_spec = sc->line_entry.file;
2079                                             var_success = format_file_spec;
2080                                         }
2081                                     }
2082                                     else if (::strncmp (var_name_begin, "number}", strlen("number}")) == 0)
2083                                     {
2084                                         var_success = true;
2085                                         s.Printf("%u", sc->line_entry.line);
2086                                     }
2087                                     else if ((::strncmp (var_name_begin, "start-addr}", strlen("start-addr}")) == 0) ||
2088                                              (::strncmp (var_name_begin, "end-addr}", strlen("end-addr}")) == 0))
2089                                     {
2090                                         var_success = sc && sc->line_entry.range.GetBaseAddress().IsValid();
2091                                         if (var_success)
2092                                         {
2093                                             format_addr = sc->line_entry.range.GetBaseAddress();
2094                                             if (var_name_begin[0] == 'e')
2095                                                 format_addr.Slide (sc->line_entry.range.GetByteSize());
2096                                         }
2097                                     }
2098                                 }
2099                             }
2100                             break;
2101                         }
2102 
2103                         if (var_success)
2104                         {
2105                             // If format addr is valid, then we need to print an address
2106                             if (reg_num != LLDB_INVALID_REGNUM)
2107                             {
2108                                 StackFrame *frame = exe_ctx->GetFramePtr();
2109                                 // We have a register value to display...
2110                                 if (reg_num == LLDB_REGNUM_GENERIC_PC && reg_kind == eRegisterKindGeneric)
2111                                 {
2112                                     format_addr = frame->GetFrameCodeAddress();
2113                                 }
2114                                 else
2115                                 {
2116                                     if (reg_ctx == NULL)
2117                                         reg_ctx = frame->GetRegisterContext().get();
2118 
2119                                     if (reg_ctx)
2120                                     {
2121                                         if (reg_kind != kNumRegisterKinds)
2122                                             reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(reg_kind, reg_num);
2123                                         reg_info = reg_ctx->GetRegisterInfoAtIndex (reg_num);
2124                                         var_success = reg_info != NULL;
2125                                     }
2126                                 }
2127                             }
2128 
2129                             if (reg_info != NULL)
2130                             {
2131                                 RegisterValue reg_value;
2132                                 var_success = reg_ctx->ReadRegister (reg_info, reg_value);
2133                                 if (var_success)
2134                                 {
2135                                     reg_value.Dump(&s, reg_info, false, false, eFormatDefault);
2136                                 }
2137                             }
2138 
2139                             if (format_file_spec)
2140                             {
2141                                 s << format_file_spec;
2142                             }
2143 
2144                             // If format addr is valid, then we need to print an address
2145                             if (format_addr.IsValid())
2146                             {
2147                                 var_success = false;
2148 
2149                                 if (calculate_format_addr_function_offset)
2150                                 {
2151                                     Address func_addr;
2152 
2153                                     if (sc)
2154                                     {
2155                                         if (sc->function)
2156                                         {
2157                                             func_addr = sc->function->GetAddressRange().GetBaseAddress();
2158                                             if (sc->block)
2159                                             {
2160                                                 // Check to make sure we aren't in an inline
2161                                                 // function. If we are, use the inline block
2162                                                 // range that contains "format_addr" since
2163                                                 // blocks can be discontiguous.
2164                                                 Block *inline_block = sc->block->GetContainingInlinedBlock ();
2165                                                 AddressRange inline_range;
2166                                                 if (inline_block && inline_block->GetRangeContainingAddress (format_addr, inline_range))
2167                                                     func_addr = inline_range.GetBaseAddress();
2168                                             }
2169                                         }
2170                                         else if (sc->symbol && sc->symbol->ValueIsAddress())
2171                                             func_addr = sc->symbol->GetAddress();
2172                                     }
2173 
2174                                     if (func_addr.IsValid())
2175                                     {
2176                                         if (func_addr.GetSection() == format_addr.GetSection())
2177                                         {
2178                                             addr_t func_file_addr = func_addr.GetFileAddress();
2179                                             addr_t addr_file_addr = format_addr.GetFileAddress();
2180                                             if (addr_file_addr > func_file_addr)
2181                                                 s.Printf(" + %llu", addr_file_addr - func_file_addr);
2182                                             else if (addr_file_addr < func_file_addr)
2183                                                 s.Printf(" - %llu", func_file_addr - addr_file_addr);
2184                                             var_success = true;
2185                                         }
2186                                         else
2187                                         {
2188                                             Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
2189                                             if (target)
2190                                             {
2191                                                 addr_t func_load_addr = func_addr.GetLoadAddress (target);
2192                                                 addr_t addr_load_addr = format_addr.GetLoadAddress (target);
2193                                                 if (addr_load_addr > func_load_addr)
2194                                                     s.Printf(" + %llu", addr_load_addr - func_load_addr);
2195                                                 else if (addr_load_addr < func_load_addr)
2196                                                     s.Printf(" - %llu", func_load_addr - addr_load_addr);
2197                                                 var_success = true;
2198                                             }
2199                                         }
2200                                     }
2201                                 }
2202                                 else
2203                                 {
2204                                     Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
2205                                     addr_t vaddr = LLDB_INVALID_ADDRESS;
2206                                     if (exe_ctx && !target->GetSectionLoadList().IsEmpty())
2207                                         vaddr = format_addr.GetLoadAddress (target);
2208                                     if (vaddr == LLDB_INVALID_ADDRESS)
2209                                         vaddr = format_addr.GetFileAddress ();
2210 
2211                                     if (vaddr != LLDB_INVALID_ADDRESS)
2212                                     {
2213                                         int addr_width = target->GetArchitecture().GetAddressByteSize() * 2;
2214                                         if (addr_width == 0)
2215                                             addr_width = 16;
2216                                         s.Printf("0x%*.*llx", addr_width, addr_width, vaddr);
2217                                         var_success = true;
2218                                     }
2219                                 }
2220                             }
2221                         }
2222 
2223                         if (var_success == false)
2224                             success = false;
2225                     }
2226                     p = var_name_end;
2227                 }
2228                 else
2229                     break;
2230             }
2231             else
2232             {
2233                 // We got a dollar sign with no '{' after it, it must just be a dollar sign
2234                 s.PutChar(*p);
2235             }
2236         }
2237         else if (*p == '\\')
2238         {
2239             ++p; // skip the slash
2240             switch (*p)
2241             {
2242             case 'a': s.PutChar ('\a'); break;
2243             case 'b': s.PutChar ('\b'); break;
2244             case 'f': s.PutChar ('\f'); break;
2245             case 'n': s.PutChar ('\n'); break;
2246             case 'r': s.PutChar ('\r'); break;
2247             case 't': s.PutChar ('\t'); break;
2248             case 'v': s.PutChar ('\v'); break;
2249             case '\'': s.PutChar ('\''); break;
2250             case '\\': s.PutChar ('\\'); break;
2251             case '0':
2252                 // 1 to 3 octal chars
2253                 {
2254                     // Make a string that can hold onto the initial zero char,
2255                     // up to 3 octal digits, and a terminating NULL.
2256                     char oct_str[5] = { 0, 0, 0, 0, 0 };
2257 
2258                     int i;
2259                     for (i=0; (p[i] >= '0' && p[i] <= '7') && i<4; ++i)
2260                         oct_str[i] = p[i];
2261 
2262                     // We don't want to consume the last octal character since
2263                     // the main for loop will do this for us, so we advance p by
2264                     // one less than i (even if i is zero)
2265                     p += i - 1;
2266                     unsigned long octal_value = ::strtoul (oct_str, NULL, 8);
2267                     if (octal_value <= UINT8_MAX)
2268                     {
2269                         char octal_char = octal_value;
2270                         s.Write (&octal_char, 1);
2271                     }
2272                 }
2273                 break;
2274 
2275             case 'x':
2276                 // hex number in the format
2277                 if (isxdigit(p[1]))
2278                 {
2279                     ++p;    // Skip the 'x'
2280 
2281                     // Make a string that can hold onto two hex chars plus a
2282                     // NULL terminator
2283                     char hex_str[3] = { 0,0,0 };
2284                     hex_str[0] = *p;
2285                     if (isxdigit(p[1]))
2286                     {
2287                         ++p; // Skip the first of the two hex chars
2288                         hex_str[1] = *p;
2289                     }
2290 
2291                     unsigned long hex_value = strtoul (hex_str, NULL, 16);
2292                     if (hex_value <= UINT8_MAX)
2293                         s.PutChar (hex_value);
2294                 }
2295                 else
2296                 {
2297                     s.PutChar('x');
2298                 }
2299                 break;
2300 
2301             default:
2302                 // Just desensitize any other character by just printing what
2303                 // came after the '\'
2304                 s << *p;
2305                 break;
2306 
2307             }
2308 
2309         }
2310     }
2311     if (end)
2312         *end = p;
2313     return success;
2314 }
2315 
2316 void
2317 Debugger::SetLoggingCallback (lldb::LogOutputCallback log_callback, void *baton)
2318 {
2319     // For simplicity's sake, I am not going to deal with how to close down any
2320     // open logging streams, I just redirect everything from here on out to the
2321     // callback.
2322     m_log_callback_stream_sp.reset (new StreamCallback (log_callback, baton));
2323 }
2324 
2325 bool
2326 Debugger::EnableLog (const char *channel, const char **categories, const char *log_file, uint32_t log_options, Stream &error_stream)
2327 {
2328     Log::Callbacks log_callbacks;
2329 
2330     StreamSP log_stream_sp;
2331     if (m_log_callback_stream_sp != NULL)
2332     {
2333         log_stream_sp = m_log_callback_stream_sp;
2334         // For now when using the callback mode you always get thread & timestamp.
2335         log_options |= LLDB_LOG_OPTION_PREPEND_TIMESTAMP | LLDB_LOG_OPTION_PREPEND_THREAD_NAME;
2336     }
2337     else if (log_file == NULL || *log_file == '\0')
2338     {
2339         log_stream_sp.reset(new StreamFile(GetOutputFile().GetDescriptor(), false));
2340     }
2341     else
2342     {
2343         LogStreamMap::iterator pos = m_log_streams.find(log_file);
2344         if (pos == m_log_streams.end())
2345         {
2346             log_stream_sp.reset (new StreamFile (log_file));
2347             m_log_streams[log_file] = log_stream_sp;
2348         }
2349         else
2350             log_stream_sp = pos->second;
2351     }
2352     assert (log_stream_sp.get());
2353 
2354     if (log_options == 0)
2355         log_options = LLDB_LOG_OPTION_PREPEND_THREAD_NAME | LLDB_LOG_OPTION_THREADSAFE;
2356 
2357     if (Log::GetLogChannelCallbacks (channel, log_callbacks))
2358     {
2359         log_callbacks.enable (log_stream_sp, log_options, categories, &error_stream);
2360         return true;
2361     }
2362     else
2363     {
2364         LogChannelSP log_channel_sp (LogChannel::FindPlugin (channel));
2365         if (log_channel_sp)
2366         {
2367             if (log_channel_sp->Enable (log_stream_sp, log_options, &error_stream, categories))
2368             {
2369                 return true;
2370             }
2371             else
2372             {
2373                 error_stream.Printf ("Invalid log channel '%s'.\n", channel);
2374                 return false;
2375             }
2376         }
2377         else
2378         {
2379             error_stream.Printf ("Invalid log channel '%s'.\n", channel);
2380             return false;
2381         }
2382     }
2383     return false;
2384 }
2385 
2386 #pragma mark Debugger::SettingsController
2387 
2388 //--------------------------------------------------
2389 // class Debugger::SettingsController
2390 //--------------------------------------------------
2391 
2392 Debugger::SettingsController::SettingsController () :
2393     UserSettingsController ("", UserSettingsControllerSP())
2394 {
2395 }
2396 
2397 Debugger::SettingsController::~SettingsController ()
2398 {
2399 }
2400 
2401 
2402 InstanceSettingsSP
2403 Debugger::SettingsController::CreateInstanceSettings (const char *instance_name)
2404 {
2405     InstanceSettingsSP new_settings_sp (new DebuggerInstanceSettings (GetSettingsController(),
2406                                                                       false,
2407                                                                       instance_name));
2408     return new_settings_sp;
2409 }
2410 
2411 #pragma mark DebuggerInstanceSettings
2412 //--------------------------------------------------
2413 //  class DebuggerInstanceSettings
2414 //--------------------------------------------------
2415 
2416 DebuggerInstanceSettings::DebuggerInstanceSettings
2417 (
2418     const UserSettingsControllerSP &m_owner_sp,
2419     bool live_instance,
2420     const char *name
2421 ) :
2422     InstanceSettings (m_owner_sp, name ? name : InstanceSettings::InvalidName().AsCString(), live_instance),
2423     m_term_width (80),
2424     m_stop_source_before_count (3),
2425     m_stop_source_after_count (3),
2426     m_stop_disassembly_count (4),
2427     m_stop_disassembly_display (eStopDisassemblyTypeNoSource),
2428     m_prompt (),
2429     m_frame_format (),
2430     m_thread_format (),
2431     m_script_lang (),
2432     m_use_external_editor (false),
2433     m_auto_confirm_on (false)
2434 {
2435     // CopyInstanceSettings is a pure virtual function in InstanceSettings; it therefore cannot be called
2436     // until the vtables for DebuggerInstanceSettings are properly set up, i.e. AFTER all the initializers.
2437     // For this reason it has to be called here, rather than in the initializer or in the parent constructor.
2438     // The same is true of CreateInstanceName().
2439 
2440     if (GetInstanceName() == InstanceSettings::InvalidName())
2441     {
2442         ChangeInstanceName (std::string (CreateInstanceName().AsCString()));
2443         m_owner_sp->RegisterInstanceSettings (this);
2444     }
2445 
2446     if (live_instance)
2447     {
2448         const InstanceSettingsSP &pending_settings = m_owner_sp->FindPendingSettings (m_instance_name);
2449         CopyInstanceSettings (pending_settings, false);
2450     }
2451 }
2452 
2453 DebuggerInstanceSettings::DebuggerInstanceSettings (const DebuggerInstanceSettings &rhs) :
2454     InstanceSettings (Debugger::GetSettingsController(), CreateInstanceName ().AsCString()),
2455     m_prompt (rhs.m_prompt),
2456     m_frame_format (rhs.m_frame_format),
2457     m_thread_format (rhs.m_thread_format),
2458     m_script_lang (rhs.m_script_lang),
2459     m_use_external_editor (rhs.m_use_external_editor),
2460     m_auto_confirm_on(rhs.m_auto_confirm_on)
2461 {
2462     UserSettingsControllerSP owner_sp (m_owner_wp.lock());
2463     if (owner_sp)
2464     {
2465         CopyInstanceSettings (owner_sp->FindPendingSettings (m_instance_name), false);
2466         owner_sp->RemovePendingSettings (m_instance_name);
2467     }
2468 }
2469 
2470 DebuggerInstanceSettings::~DebuggerInstanceSettings ()
2471 {
2472 }
2473 
2474 DebuggerInstanceSettings&
2475 DebuggerInstanceSettings::operator= (const DebuggerInstanceSettings &rhs)
2476 {
2477     if (this != &rhs)
2478     {
2479         m_term_width = rhs.m_term_width;
2480         m_prompt = rhs.m_prompt;
2481         m_frame_format = rhs.m_frame_format;
2482         m_thread_format = rhs.m_thread_format;
2483         m_script_lang = rhs.m_script_lang;
2484         m_use_external_editor = rhs.m_use_external_editor;
2485         m_auto_confirm_on = rhs.m_auto_confirm_on;
2486     }
2487 
2488     return *this;
2489 }
2490 
2491 bool
2492 DebuggerInstanceSettings::ValidTermWidthValue (const char *value, Error err)
2493 {
2494     bool valid = false;
2495 
2496     // Verify we have a value string.
2497     if (value == NULL || value[0] == '\0')
2498     {
2499         err.SetErrorString ("missing value, can't set terminal width without a value");
2500     }
2501     else
2502     {
2503         char *end = NULL;
2504         const uint32_t width = ::strtoul (value, &end, 0);
2505 
2506         if (end && end[0] == '\0')
2507         {
2508             if (width >= 10 && width <= 1024)
2509                 valid = true;
2510             else
2511                 err.SetErrorString ("invalid term-width value; value must be between 10 and 1024");
2512         }
2513         else
2514             err.SetErrorStringWithFormat ("'%s' is not a valid unsigned integer string", value);
2515     }
2516 
2517     return valid;
2518 }
2519 
2520 
2521 void
2522 DebuggerInstanceSettings::UpdateInstanceSettingsVariable (const ConstString &var_name,
2523                                                           const char *index_value,
2524                                                           const char *value,
2525                                                           const ConstString &instance_name,
2526                                                           const SettingEntry &entry,
2527                                                           VarSetOperationType op,
2528                                                           Error &err,
2529                                                           bool pending)
2530 {
2531 
2532     if (var_name == TermWidthVarName())
2533     {
2534         if (ValidTermWidthValue (value, err))
2535         {
2536             m_term_width = ::strtoul (value, NULL, 0);
2537         }
2538     }
2539     else if (var_name == PromptVarName())
2540     {
2541         UserSettingsController::UpdateStringVariable (op, m_prompt, value, err);
2542         if (!pending)
2543         {
2544             // 'instance_name' is actually (probably) in the form '[<instance_name>]';  if so, we need to
2545             // strip off the brackets before passing it to BroadcastPromptChange.
2546 
2547             std::string tmp_instance_name (instance_name.AsCString());
2548             if ((tmp_instance_name[0] == '[')
2549                 && (tmp_instance_name[instance_name.GetLength() - 1] == ']'))
2550                 tmp_instance_name = tmp_instance_name.substr (1, instance_name.GetLength() - 2);
2551             ConstString new_name (tmp_instance_name.c_str());
2552 
2553             BroadcastPromptChange (new_name, m_prompt.c_str());
2554         }
2555     }
2556     else if (var_name == GetFrameFormatName())
2557     {
2558         UserSettingsController::UpdateStringVariable (op, m_frame_format, value, err);
2559     }
2560     else if (var_name == GetThreadFormatName())
2561     {
2562         UserSettingsController::UpdateStringVariable (op, m_thread_format, value, err);
2563     }
2564     else if (var_name == ScriptLangVarName())
2565     {
2566         bool success;
2567         m_script_lang = Args::StringToScriptLanguage (value, eScriptLanguageDefault,
2568                                                       &success);
2569     }
2570     else if (var_name == UseExternalEditorVarName ())
2571     {
2572         UserSettingsController::UpdateBooleanVariable (op, m_use_external_editor, value, false, err);
2573     }
2574     else if (var_name == AutoConfirmName ())
2575     {
2576         UserSettingsController::UpdateBooleanVariable (op, m_auto_confirm_on, value, false, err);
2577     }
2578     else if (var_name == StopSourceContextBeforeName ())
2579     {
2580         uint32_t new_value = Args::StringToUInt32(value, UINT32_MAX, 10, NULL);
2581         if (new_value != UINT32_MAX)
2582             m_stop_source_before_count = new_value;
2583         else
2584             err.SetErrorStringWithFormat("invalid unsigned string value '%s' for the '%s' setting", value, StopSourceContextAfterName ().GetCString());
2585     }
2586     else if (var_name == StopSourceContextAfterName ())
2587     {
2588         uint32_t new_value = Args::StringToUInt32(value, UINT32_MAX, 10, NULL);
2589         if (new_value != UINT32_MAX)
2590             m_stop_source_after_count = new_value;
2591         else
2592             err.SetErrorStringWithFormat("invalid unsigned string value '%s' for the '%s' setting", value, StopSourceContextBeforeName ().GetCString());
2593     }
2594     else if (var_name == StopDisassemblyCountName ())
2595     {
2596         uint32_t new_value = Args::StringToUInt32(value, UINT32_MAX, 10, NULL);
2597         if (new_value != UINT32_MAX)
2598             m_stop_disassembly_count = new_value;
2599         else
2600             err.SetErrorStringWithFormat("invalid unsigned string value '%s' for the '%s' setting", value, StopDisassemblyCountName ().GetCString());
2601     }
2602     else if (var_name == StopDisassemblyDisplayName ())
2603     {
2604         int new_value;
2605         UserSettingsController::UpdateEnumVariable (g_show_disassembly_enum_values, &new_value, value, err);
2606         if (err.Success())
2607             m_stop_disassembly_display = (StopDisassemblyType)new_value;
2608     }
2609 }
2610 
2611 bool
2612 DebuggerInstanceSettings::GetInstanceSettingsValue (const SettingEntry &entry,
2613                                                     const ConstString &var_name,
2614                                                     StringList &value,
2615                                                     Error *err)
2616 {
2617     if (var_name == PromptVarName())
2618     {
2619         value.AppendString (m_prompt.c_str(), m_prompt.size());
2620 
2621     }
2622     else if (var_name == ScriptLangVarName())
2623     {
2624         value.AppendString (ScriptInterpreter::LanguageToString (m_script_lang).c_str());
2625     }
2626     else if (var_name == TermWidthVarName())
2627     {
2628         StreamString width_str;
2629         width_str.Printf ("%u", m_term_width);
2630         value.AppendString (width_str.GetData());
2631     }
2632     else if (var_name == GetFrameFormatName ())
2633     {
2634         value.AppendString(m_frame_format.c_str(), m_frame_format.size());
2635     }
2636     else if (var_name == GetThreadFormatName ())
2637     {
2638         value.AppendString(m_thread_format.c_str(), m_thread_format.size());
2639     }
2640     else if (var_name == UseExternalEditorVarName())
2641     {
2642         if (m_use_external_editor)
2643             value.AppendString ("true");
2644         else
2645             value.AppendString ("false");
2646     }
2647     else if (var_name == AutoConfirmName())
2648     {
2649         if (m_auto_confirm_on)
2650             value.AppendString ("true");
2651         else
2652             value.AppendString ("false");
2653     }
2654     else if (var_name == StopSourceContextAfterName ())
2655     {
2656         StreamString strm;
2657         strm.Printf ("%u", m_stop_source_before_count);
2658         value.AppendString (strm.GetData());
2659     }
2660     else if (var_name == StopSourceContextBeforeName ())
2661     {
2662         StreamString strm;
2663         strm.Printf ("%u", m_stop_source_after_count);
2664         value.AppendString (strm.GetData());
2665     }
2666     else if (var_name == StopDisassemblyCountName ())
2667     {
2668         StreamString strm;
2669         strm.Printf ("%u", m_stop_disassembly_count);
2670         value.AppendString (strm.GetData());
2671     }
2672     else if (var_name == StopDisassemblyDisplayName ())
2673     {
2674         if (m_stop_disassembly_display >= eStopDisassemblyTypeNever && m_stop_disassembly_display <= eStopDisassemblyTypeAlways)
2675             value.AppendString (g_show_disassembly_enum_values[m_stop_disassembly_display].string_value);
2676         else
2677             value.AppendString ("<invalid>");
2678     }
2679     else
2680     {
2681         if (err)
2682             err->SetErrorStringWithFormat ("unrecognized variable name '%s'", var_name.AsCString());
2683         return false;
2684     }
2685     return true;
2686 }
2687 
2688 void
2689 DebuggerInstanceSettings::CopyInstanceSettings (const InstanceSettingsSP &new_settings,
2690                                                 bool pending)
2691 {
2692     if (new_settings.get() == NULL)
2693         return;
2694 
2695     DebuggerInstanceSettings *new_debugger_settings = (DebuggerInstanceSettings *) new_settings.get();
2696 
2697     m_prompt = new_debugger_settings->m_prompt;
2698     if (!pending)
2699     {
2700         // 'instance_name' is actually (probably) in the form '[<instance_name>]';  if so, we need to
2701         // strip off the brackets before passing it to BroadcastPromptChange.
2702 
2703         std::string tmp_instance_name (m_instance_name.AsCString());
2704         if ((tmp_instance_name[0] == '[')
2705             && (tmp_instance_name[m_instance_name.GetLength() - 1] == ']'))
2706             tmp_instance_name = tmp_instance_name.substr (1, m_instance_name.GetLength() - 2);
2707         ConstString new_name (tmp_instance_name.c_str());
2708 
2709         BroadcastPromptChange (new_name, m_prompt.c_str());
2710     }
2711     m_frame_format = new_debugger_settings->m_frame_format;
2712     m_thread_format = new_debugger_settings->m_thread_format;
2713     m_term_width = new_debugger_settings->m_term_width;
2714     m_script_lang = new_debugger_settings->m_script_lang;
2715     m_use_external_editor = new_debugger_settings->m_use_external_editor;
2716     m_auto_confirm_on = new_debugger_settings->m_auto_confirm_on;
2717 }
2718 
2719 
2720 bool
2721 DebuggerInstanceSettings::BroadcastPromptChange (const ConstString &instance_name, const char *new_prompt)
2722 {
2723     std::string tmp_prompt;
2724 
2725     if (new_prompt != NULL)
2726     {
2727         tmp_prompt = new_prompt ;
2728         int len = tmp_prompt.size();
2729         if (len > 1
2730             && (tmp_prompt[0] == '\'' || tmp_prompt[0] == '"')
2731             && (tmp_prompt[len-1] == tmp_prompt[0]))
2732         {
2733             tmp_prompt = tmp_prompt.substr(1,len-2);
2734         }
2735         len = tmp_prompt.size();
2736         if (tmp_prompt[len-1] != ' ')
2737             tmp_prompt.append(" ");
2738     }
2739     EventSP new_event_sp;
2740     new_event_sp.reset (new Event(CommandInterpreter::eBroadcastBitResetPrompt,
2741                                   new EventDataBytes (tmp_prompt.c_str())));
2742 
2743     if (instance_name.GetLength() != 0)
2744     {
2745         // Set prompt for a particular instance.
2746         Debugger *dbg = Debugger::FindDebuggerWithInstanceName (instance_name).get();
2747         if (dbg != NULL)
2748         {
2749             dbg->GetCommandInterpreter().BroadcastEvent (new_event_sp);
2750         }
2751     }
2752 
2753     return true;
2754 }
2755 
2756 const ConstString
2757 DebuggerInstanceSettings::CreateInstanceName ()
2758 {
2759     static int instance_count = 1;
2760     StreamString sstr;
2761 
2762     sstr.Printf ("debugger_%d", instance_count);
2763     ++instance_count;
2764 
2765     const ConstString ret_val (sstr.GetData());
2766 
2767     return ret_val;
2768 }
2769 
2770 
2771 //--------------------------------------------------
2772 // SettingsController Variable Tables
2773 //--------------------------------------------------
2774 
2775 
2776 SettingEntry
2777 Debugger::SettingsController::global_settings_table[] =
2778 {
2779   //{ "var-name",    var-type,      "default", enum-table, init'd, hidden, "help-text"},
2780   // The Debugger level global table should always be empty; all Debugger settable variables should be instance
2781   // variables.
2782     {  NULL, eSetVarTypeNone, NULL, NULL, 0, 0, NULL }
2783 };
2784 
2785 #define MODULE_WITH_FUNC "{ ${module.file.basename}{`${function.name}${function.pc-offset}}}"
2786 #define FILE_AND_LINE "{ at ${line.file.basename}:${line.number}}"
2787 
2788 #define DEFAULT_THREAD_FORMAT "thread #${thread.index}: tid = ${thread.id}"\
2789     "{, ${frame.pc}}"\
2790     MODULE_WITH_FUNC\
2791     FILE_AND_LINE\
2792     "{, stop reason = ${thread.stop-reason}}"\
2793     "{\\nReturn value: ${thread.return-value}}"\
2794     "\\n"
2795 
2796 //#define DEFAULT_THREAD_FORMAT "thread #${thread.index}: tid = ${thread.id}"\
2797 //    "{, ${frame.pc}}"\
2798 //    MODULE_WITH_FUNC\
2799 //    FILE_AND_LINE\
2800 //    "{, stop reason = ${thread.stop-reason}}"\
2801 //    "{, name = ${thread.name}}"\
2802 //    "{, queue = ${thread.queue}}"\
2803 //    "\\n"
2804 
2805 #define DEFAULT_FRAME_FORMAT "frame #${frame.index}: ${frame.pc}"\
2806     MODULE_WITH_FUNC\
2807     FILE_AND_LINE\
2808     "\\n"
2809 
2810 SettingEntry
2811 Debugger::SettingsController::instance_settings_table[] =
2812 {
2813 //  NAME                    Setting variable type   Default                 Enum  Init'd Hidden Help
2814 //  ======================= ======================= ======================  ====  ====== ====== ======================
2815 {   "frame-format",         eSetVarTypeString,      DEFAULT_FRAME_FORMAT,   NULL, false, false, "The default frame format string to use when displaying thread information." },
2816 {   "prompt",               eSetVarTypeString,      "(lldb) ",              NULL, false, false, "The debugger command line prompt displayed for the user." },
2817 {   "script-lang",          eSetVarTypeString,      "python",               NULL, false, false, "The script language to be used for evaluating user-written scripts." },
2818 {   "term-width",           eSetVarTypeInt,         "80"    ,               NULL, false, false, "The maximum number of columns to use for displaying text." },
2819 {   "thread-format",        eSetVarTypeString,      DEFAULT_THREAD_FORMAT,  NULL, false, false, "The default thread format string to use when displaying thread information." },
2820 {   "use-external-editor",  eSetVarTypeBoolean,     "false",                NULL, false, false, "Whether to use an external editor or not." },
2821 {   "auto-confirm",         eSetVarTypeBoolean,     "false",                NULL, false, false, "If true all confirmation prompts will receive their default reply." },
2822 {   "stop-line-count-before",eSetVarTypeInt,        "3",                    NULL, false, false, "The number of sources lines to display that come before the current source line when displaying a stopped context." },
2823 {   "stop-line-count-after", eSetVarTypeInt,        "3",                    NULL, false, false, "The number of sources lines to display that come after the current source line when displaying a stopped context." },
2824 {   "stop-disassembly-count",  eSetVarTypeInt,      "0",                    NULL, false, false, "The number of disassembly lines to show when displaying a stopped context." },
2825 {   "stop-disassembly-display", eSetVarTypeEnum,    "no-source",           g_show_disassembly_enum_values, false, false, "Control when to display disassembly when displaying a stopped context." },
2826 {   NULL,                   eSetVarTypeNone,        NULL,                   NULL, false, false, NULL }
2827 };
2828