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::eDisplayLanguageSpecific;
871             // if this is a V, print the value using the default format
872             else if (*format_name == 'V')
873                 *val_obj_display = ValueObject::eDisplayValue;
874             // if this is an L, print the location of the value
875             else if (*format_name == 'L')
876                 *val_obj_display = ValueObject::eDisplayLocation;
877             // if this is an S, print the summary after all
878             else if (*format_name == 'S')
879                 *val_obj_display = ValueObject::eDisplaySummary;
880             else if (*format_name == '#')
881                 *val_obj_display = ValueObject::eDisplayChildrenCount;
882             else if (*format_name == 'T')
883                 *val_obj_display = ValueObject::eDisplayType;
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::eDisplayValue;
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::eHonorPointers);
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::eDereference : ValueObject::eNothing);
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::eEndOfString;
1139                         ValueObject::ExpressionPathEndResultType final_value_type = ValueObject::ePlain;
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                                     valobj = valobj->GetSyntheticValue(eUseSyntheticFilter).get();
1168                                     var_name_begin++;
1169                                 }
1170 
1171                                 if (log)
1172                                     log->Printf("initial string: %s",var_name_begin);
1173 
1174                                 // should be a 'v' by now
1175                                 if (*var_name_begin != 'v')
1176                                     break;
1177 
1178                                 if (log)
1179                                     log->Printf("initial string: %s",var_name_begin);
1180 
1181                                 ValueObject::ExpressionPathAftermath what_next = (do_deref_pointer ?
1182                                                                                   ValueObject::eDereference : ValueObject::eNothing);
1183                                 ValueObject::GetValueForExpressionPathOptions options;
1184                                 options.DontCheckDotVsArrowSyntax().DoAllowBitfieldSyntax().DoAllowFragileIVar().DoAllowSyntheticChildren();
1185                                 ValueObject::ValueObjectRepresentationStyle val_obj_display = ValueObject::eDisplaySummary;
1186                                 ValueObject* target = NULL;
1187                                 Format custom_format = eFormatInvalid;
1188                                 const char* var_name_final = NULL;
1189                                 const char* var_name_final_if_array_range = NULL;
1190                                 const char* close_bracket_position = NULL;
1191                                 int64_t index_lower = -1;
1192                                 int64_t index_higher = -1;
1193                                 bool is_array_range = false;
1194                                 const char* first_unparsed;
1195                                 bool was_plain_var = false;
1196                                 bool was_var_format = false;
1197 
1198                                 if (!valobj) break;
1199                                 // simplest case ${var}, just print valobj's value
1200                                 if (::strncmp (var_name_begin, "var}", strlen("var}")) == 0)
1201                                 {
1202                                     was_plain_var = true;
1203                                     target = valobj;
1204                                     val_obj_display = ValueObject::eDisplayValue;
1205                                 }
1206                                 else if (::strncmp(var_name_begin,"var%",strlen("var%")) == 0)
1207                                 {
1208                                     was_var_format = true;
1209                                     // this is a variable with some custom format applied to it
1210                                     const char* percent_position;
1211                                     target = valobj;
1212                                     val_obj_display = ValueObject::eDisplayValue;
1213                                     ScanFormatDescriptor (var_name_begin,
1214                                                           var_name_end,
1215                                                           &var_name_final,
1216                                                           &percent_position,
1217                                                           &custom_format,
1218                                                           &val_obj_display);
1219                                 }
1220                                     // this is ${var.something} or multiple .something nested
1221                                 else if (::strncmp (var_name_begin, "var", strlen("var")) == 0)
1222                                 {
1223 
1224                                     const char* percent_position;
1225                                     ScanFormatDescriptor (var_name_begin,
1226                                                           var_name_end,
1227                                                           &var_name_final,
1228                                                           &percent_position,
1229                                                           &custom_format,
1230                                                           &val_obj_display);
1231 
1232                                     const char* open_bracket_position;
1233                                     const char* separator_position;
1234                                     ScanBracketedRange (var_name_begin,
1235                                                         var_name_end,
1236                                                         var_name_final,
1237                                                         &open_bracket_position,
1238                                                         &separator_position,
1239                                                         &close_bracket_position,
1240                                                         &var_name_final_if_array_range,
1241                                                         &index_lower,
1242                                                         &index_higher);
1243 
1244                                     Error error;
1245 
1246                                     std::auto_ptr<char> expr_path(new char[var_name_final-var_name_begin-1]);
1247                                     ::memset(expr_path.get(), 0, var_name_final-var_name_begin-1);
1248                                     memcpy(expr_path.get(), var_name_begin+3,var_name_final-var_name_begin-3);
1249 
1250                                     if (log)
1251                                         log->Printf("symbol to expand: %s",expr_path.get());
1252 
1253                                     target = valobj->GetValueForExpressionPath(expr_path.get(),
1254                                                                              &first_unparsed,
1255                                                                              &reason_to_stop,
1256                                                                              &final_value_type,
1257                                                                              options,
1258                                                                              &what_next).get();
1259 
1260                                     if (!target)
1261                                     {
1262                                         if (log)
1263                                             log->Printf("ERROR: unparsed portion = %s, why stopping = %d,"
1264                                                " final_value_type %d",
1265                                                first_unparsed, reason_to_stop, final_value_type);
1266                                         break;
1267                                     }
1268                                     else
1269                                     {
1270                                         if (log)
1271                                             log->Printf("ALL RIGHT: unparsed portion = %s, why stopping = %d,"
1272                                                " final_value_type %d",
1273                                                first_unparsed, reason_to_stop, final_value_type);
1274                                     }
1275                                 }
1276                                 else
1277                                     break;
1278 
1279                                 is_array_range = (final_value_type == ValueObject::eBoundedRange ||
1280                                                   final_value_type == ValueObject::eUnboundedRange);
1281 
1282                                 do_deref_pointer = (what_next == ValueObject::eDereference);
1283 
1284                                 if (do_deref_pointer && !is_array_range)
1285                                 {
1286                                     // I have not deref-ed yet, let's do it
1287                                     // this happens when we are not going through GetValueForVariableExpressionPath
1288                                     // to get to the target ValueObject
1289                                     Error error;
1290                                     target = target->Dereference(error).get();
1291                                     if (error.Fail())
1292                                     {
1293                                         if (log)
1294                                             log->Printf("ERROR: %s\n", error.AsCString("unknown")); \
1295                                         break;
1296                                     }
1297                                     do_deref_pointer = false;
1298                                 }
1299 
1300                                 // TODO use flags for these
1301                                 bool is_array = ClangASTContext::IsArrayType(target->GetClangType());
1302                                 bool is_pointer = ClangASTContext::IsPointerType(target->GetClangType());
1303                                 bool is_aggregate = ClangASTContext::IsAggregateType(target->GetClangType());
1304 
1305                                 if ((is_array || is_pointer) && (!is_array_range) && val_obj_display == ValueObject::eDisplayValue) // this should be wrong, but there are some exceptions
1306                                 {
1307                                     StreamString str_temp;
1308                                     if (log)
1309                                         log->Printf("I am into array || pointer && !range");
1310 
1311                                     if (target->HasSpecialCasesForPrintableRepresentation(val_obj_display,
1312                                                                                           custom_format))
1313                                     {
1314                                         // try to use the special cases
1315                                         var_success = target->DumpPrintableRepresentation(str_temp,
1316                                                                                           val_obj_display,
1317                                                                                           custom_format);
1318                                         if (log)
1319                                             log->Printf("special cases did%s match", var_success ? "" : "n't");
1320 
1321                                         // should not happen
1322                                         if (!var_success)
1323                                             s << "<invalid usage of pointer value as object>";
1324                                         else
1325                                             s << str_temp.GetData();
1326                                         var_success = true;
1327                                         break;
1328                                     }
1329                                     else
1330                                     {
1331                                         if (was_plain_var) // if ${var}
1332                                         {
1333                                             s << target->GetTypeName() << " @ " << target->GetLocationAsCString();
1334                                         }
1335                                         else if (is_pointer) // if pointer, value is the address stored
1336                                         {
1337                                             var_success = target->GetPrintableRepresentation(s,
1338                                                                                              val_obj_display,
1339                                                                                              custom_format);
1340                                         }
1341                                         else
1342                                         {
1343                                             s << "<invalid usage of pointer value as object>";
1344                                         }
1345                                         var_success = true;
1346                                         break;
1347                                     }
1348                                 }
1349 
1350                                 // if directly trying to print ${var}, and this is an aggregate, display a nice
1351                                 // type @ location message
1352                                 if (is_aggregate && was_plain_var)
1353                                 {
1354                                     s << target->GetTypeName() << " @ " << target->GetLocationAsCString();
1355                                     var_success = true;
1356                                     break;
1357                                 }
1358 
1359                                 // if directly trying to print ${var%V}, and this is an aggregate, do not let the user do it
1360                                 if (is_aggregate && ((was_var_format && val_obj_display == ValueObject::eDisplayValue)))
1361                                 {
1362                                     s << "<invalid use of aggregate type>";
1363                                     var_success = true;
1364                                     break;
1365                                 }
1366 
1367                                 if (!is_array_range)
1368                                 {
1369                                     if (log)
1370                                         log->Printf("dumping ordinary printable output");
1371                                     var_success = target->DumpPrintableRepresentation(s,val_obj_display, custom_format);
1372                                 }
1373                                 else
1374                                 {
1375                                     if (log)
1376                                         log->Printf("checking if I can handle as array");
1377                                     if (!is_array && !is_pointer)
1378                                         break;
1379                                     if (log)
1380                                         log->Printf("handle as array");
1381                                     const char* special_directions = NULL;
1382                                     StreamString special_directions_writer;
1383                                     if (close_bracket_position && (var_name_end-close_bracket_position > 1))
1384                                     {
1385                                         ConstString additional_data;
1386                                         additional_data.SetCStringWithLength(close_bracket_position+1, var_name_end-close_bracket_position-1);
1387                                         special_directions_writer.Printf("${%svar%s}",
1388                                                                          do_deref_pointer ? "*" : "",
1389                                                                          additional_data.GetCString());
1390                                         special_directions = special_directions_writer.GetData();
1391                                     }
1392 
1393                                     // let us display items index_lower thru index_higher of this array
1394                                     s.PutChar('[');
1395                                     var_success = true;
1396 
1397                                     if (index_higher < 0)
1398                                         index_higher = valobj->GetNumChildren() - 1;
1399 
1400                                     uint32_t max_num_children = target->GetTargetSP()->GetMaximumNumberOfChildrenToDisplay();
1401 
1402                                     for (;index_lower<=index_higher;index_lower++)
1403                                     {
1404                                         ValueObject* item = ExpandIndexedExpression (target,
1405                                                                                      index_lower,
1406                                                                                      exe_ctx->GetFramePtr(),
1407                                                                                      false).get();
1408 
1409                                         if (!item)
1410                                         {
1411                                             if (log)
1412                                                 log->Printf("ERROR in getting child item at index %lld", index_lower);
1413                                         }
1414                                         else
1415                                         {
1416                                             if (log)
1417                                                 log->Printf("special_directions for child item: %s",special_directions);
1418                                         }
1419 
1420                                         if (!special_directions)
1421                                             var_success &= item->DumpPrintableRepresentation(s,val_obj_display, custom_format);
1422                                         else
1423                                             var_success &= FormatPrompt(special_directions, sc, exe_ctx, addr, s, NULL, item);
1424 
1425                                         if (--max_num_children == 0)
1426                                         {
1427                                             s.PutCString(", ...");
1428                                             break;
1429                                         }
1430 
1431                                         if (index_lower < index_higher)
1432                                             s.PutChar(',');
1433                                     }
1434                                     s.PutChar(']');
1435                                 }
1436                             }
1437                             break;
1438                         case 'a':
1439                             if (::strncmp (var_name_begin, "addr}", strlen("addr}")) == 0)
1440                             {
1441                                 if (addr && addr->IsValid())
1442                                 {
1443                                     var_success = true;
1444                                     format_addr = *addr;
1445                                 }
1446                             }
1447                             else if (::strncmp (var_name_begin, "ansi.", strlen("ansi.")) == 0)
1448                             {
1449                                 var_success = true;
1450                                 var_name_begin += strlen("ansi."); // Skip the "ansi."
1451                                 if (::strncmp (var_name_begin, "fg.", strlen("fg.")) == 0)
1452                                 {
1453                                     var_name_begin += strlen("fg."); // Skip the "fg."
1454                                     if (::strncmp (var_name_begin, "black}", strlen("black}")) == 0)
1455                                     {
1456                                         s.Printf ("%s%s%s",
1457                                                   lldb_utility::ansi::k_escape_start,
1458                                                   lldb_utility::ansi::k_fg_black,
1459                                                   lldb_utility::ansi::k_escape_end);
1460                                     }
1461                                     else if (::strncmp (var_name_begin, "red}", strlen("red}")) == 0)
1462                                     {
1463                                         s.Printf ("%s%s%s",
1464                                                   lldb_utility::ansi::k_escape_start,
1465                                                   lldb_utility::ansi::k_fg_red,
1466                                                   lldb_utility::ansi::k_escape_end);
1467                                     }
1468                                     else if (::strncmp (var_name_begin, "green}", strlen("green}")) == 0)
1469                                     {
1470                                         s.Printf ("%s%s%s",
1471                                                   lldb_utility::ansi::k_escape_start,
1472                                                   lldb_utility::ansi::k_fg_green,
1473                                                   lldb_utility::ansi::k_escape_end);
1474                                     }
1475                                     else if (::strncmp (var_name_begin, "yellow}", strlen("yellow}")) == 0)
1476                                     {
1477                                         s.Printf ("%s%s%s",
1478                                                   lldb_utility::ansi::k_escape_start,
1479                                                   lldb_utility::ansi::k_fg_yellow,
1480                                                   lldb_utility::ansi::k_escape_end);
1481                                     }
1482                                     else if (::strncmp (var_name_begin, "blue}", strlen("blue}")) == 0)
1483                                     {
1484                                         s.Printf ("%s%s%s",
1485                                                   lldb_utility::ansi::k_escape_start,
1486                                                   lldb_utility::ansi::k_fg_blue,
1487                                                   lldb_utility::ansi::k_escape_end);
1488                                     }
1489                                     else if (::strncmp (var_name_begin, "purple}", strlen("purple}")) == 0)
1490                                     {
1491                                         s.Printf ("%s%s%s",
1492                                                   lldb_utility::ansi::k_escape_start,
1493                                                   lldb_utility::ansi::k_fg_purple,
1494                                                   lldb_utility::ansi::k_escape_end);
1495                                     }
1496                                     else if (::strncmp (var_name_begin, "cyan}", strlen("cyan}")) == 0)
1497                                     {
1498                                         s.Printf ("%s%s%s",
1499                                                   lldb_utility::ansi::k_escape_start,
1500                                                   lldb_utility::ansi::k_fg_cyan,
1501                                                   lldb_utility::ansi::k_escape_end);
1502                                     }
1503                                     else if (::strncmp (var_name_begin, "white}", strlen("white}")) == 0)
1504                                     {
1505                                         s.Printf ("%s%s%s",
1506                                                   lldb_utility::ansi::k_escape_start,
1507                                                   lldb_utility::ansi::k_fg_white,
1508                                                   lldb_utility::ansi::k_escape_end);
1509                                     }
1510                                     else
1511                                     {
1512                                         var_success = false;
1513                                     }
1514                                 }
1515                                 else if (::strncmp (var_name_begin, "bg.", strlen("bg.")) == 0)
1516                                 {
1517                                     var_name_begin += strlen("bg."); // Skip the "bg."
1518                                     if (::strncmp (var_name_begin, "black}", strlen("black}")) == 0)
1519                                     {
1520                                         s.Printf ("%s%s%s",
1521                                                   lldb_utility::ansi::k_escape_start,
1522                                                   lldb_utility::ansi::k_bg_black,
1523                                                   lldb_utility::ansi::k_escape_end);
1524                                     }
1525                                     else if (::strncmp (var_name_begin, "red}", strlen("red}")) == 0)
1526                                     {
1527                                         s.Printf ("%s%s%s",
1528                                                   lldb_utility::ansi::k_escape_start,
1529                                                   lldb_utility::ansi::k_bg_red,
1530                                                   lldb_utility::ansi::k_escape_end);
1531                                     }
1532                                     else if (::strncmp (var_name_begin, "green}", strlen("green}")) == 0)
1533                                     {
1534                                         s.Printf ("%s%s%s",
1535                                                   lldb_utility::ansi::k_escape_start,
1536                                                   lldb_utility::ansi::k_bg_green,
1537                                                   lldb_utility::ansi::k_escape_end);
1538                                     }
1539                                     else if (::strncmp (var_name_begin, "yellow}", strlen("yellow}")) == 0)
1540                                     {
1541                                         s.Printf ("%s%s%s",
1542                                                   lldb_utility::ansi::k_escape_start,
1543                                                   lldb_utility::ansi::k_bg_yellow,
1544                                                   lldb_utility::ansi::k_escape_end);
1545                                     }
1546                                     else if (::strncmp (var_name_begin, "blue}", strlen("blue}")) == 0)
1547                                     {
1548                                         s.Printf ("%s%s%s",
1549                                                   lldb_utility::ansi::k_escape_start,
1550                                                   lldb_utility::ansi::k_bg_blue,
1551                                                   lldb_utility::ansi::k_escape_end);
1552                                     }
1553                                     else if (::strncmp (var_name_begin, "purple}", strlen("purple}")) == 0)
1554                                     {
1555                                         s.Printf ("%s%s%s",
1556                                                   lldb_utility::ansi::k_escape_start,
1557                                                   lldb_utility::ansi::k_bg_purple,
1558                                                   lldb_utility::ansi::k_escape_end);
1559                                     }
1560                                     else if (::strncmp (var_name_begin, "cyan}", strlen("cyan}")) == 0)
1561                                     {
1562                                         s.Printf ("%s%s%s",
1563                                                   lldb_utility::ansi::k_escape_start,
1564                                                   lldb_utility::ansi::k_bg_cyan,
1565                                                   lldb_utility::ansi::k_escape_end);
1566                                     }
1567                                     else if (::strncmp (var_name_begin, "white}", strlen("white}")) == 0)
1568                                     {
1569                                         s.Printf ("%s%s%s",
1570                                                   lldb_utility::ansi::k_escape_start,
1571                                                   lldb_utility::ansi::k_bg_white,
1572                                                   lldb_utility::ansi::k_escape_end);
1573                                     }
1574                                     else
1575                                     {
1576                                         var_success = false;
1577                                     }
1578                                 }
1579                                 else if (::strncmp (var_name_begin, "normal}", strlen ("normal}")) == 0)
1580                                 {
1581                                     s.Printf ("%s%s%s",
1582                                               lldb_utility::ansi::k_escape_start,
1583                                               lldb_utility::ansi::k_ctrl_normal,
1584                                               lldb_utility::ansi::k_escape_end);
1585                                 }
1586                                 else if (::strncmp (var_name_begin, "bold}", strlen("bold}")) == 0)
1587                                 {
1588                                     s.Printf ("%s%s%s",
1589                                               lldb_utility::ansi::k_escape_start,
1590                                               lldb_utility::ansi::k_ctrl_bold,
1591                                               lldb_utility::ansi::k_escape_end);
1592                                 }
1593                                 else if (::strncmp (var_name_begin, "faint}", strlen("faint}")) == 0)
1594                                 {
1595                                     s.Printf ("%s%s%s",
1596                                               lldb_utility::ansi::k_escape_start,
1597                                               lldb_utility::ansi::k_ctrl_faint,
1598                                               lldb_utility::ansi::k_escape_end);
1599                                 }
1600                                 else if (::strncmp (var_name_begin, "italic}", strlen("italic}")) == 0)
1601                                 {
1602                                     s.Printf ("%s%s%s",
1603                                               lldb_utility::ansi::k_escape_start,
1604                                               lldb_utility::ansi::k_ctrl_italic,
1605                                               lldb_utility::ansi::k_escape_end);
1606                                 }
1607                                 else if (::strncmp (var_name_begin, "underline}", strlen("underline}")) == 0)
1608                                 {
1609                                     s.Printf ("%s%s%s",
1610                                               lldb_utility::ansi::k_escape_start,
1611                                               lldb_utility::ansi::k_ctrl_underline,
1612                                               lldb_utility::ansi::k_escape_end);
1613                                 }
1614                                 else if (::strncmp (var_name_begin, "slow-blink}", strlen("slow-blink}")) == 0)
1615                                 {
1616                                     s.Printf ("%s%s%s",
1617                                               lldb_utility::ansi::k_escape_start,
1618                                               lldb_utility::ansi::k_ctrl_slow_blink,
1619                                               lldb_utility::ansi::k_escape_end);
1620                                 }
1621                                 else if (::strncmp (var_name_begin, "fast-blink}", strlen("fast-blink}")) == 0)
1622                                 {
1623                                     s.Printf ("%s%s%s",
1624                                               lldb_utility::ansi::k_escape_start,
1625                                               lldb_utility::ansi::k_ctrl_fast_blink,
1626                                               lldb_utility::ansi::k_escape_end);
1627                                 }
1628                                 else if (::strncmp (var_name_begin, "negative}", strlen("negative}")) == 0)
1629                                 {
1630                                     s.Printf ("%s%s%s",
1631                                               lldb_utility::ansi::k_escape_start,
1632                                               lldb_utility::ansi::k_ctrl_negative,
1633                                               lldb_utility::ansi::k_escape_end);
1634                                 }
1635                                 else if (::strncmp (var_name_begin, "conceal}", strlen("conceal}")) == 0)
1636                                 {
1637                                     s.Printf ("%s%s%s",
1638                                               lldb_utility::ansi::k_escape_start,
1639                                               lldb_utility::ansi::k_ctrl_conceal,
1640                                               lldb_utility::ansi::k_escape_end);
1641 
1642                                 }
1643                                 else if (::strncmp (var_name_begin, "crossed-out}", strlen("crossed-out}")) == 0)
1644                                 {
1645                                     s.Printf ("%s%s%s",
1646                                               lldb_utility::ansi::k_escape_start,
1647                                               lldb_utility::ansi::k_ctrl_crossed_out,
1648                                               lldb_utility::ansi::k_escape_end);
1649                                 }
1650                                 else
1651                                 {
1652                                     var_success = false;
1653                                 }
1654                             }
1655                             break;
1656 
1657                         case 'p':
1658                             if (::strncmp (var_name_begin, "process.", strlen("process.")) == 0)
1659                             {
1660                                 if (exe_ctx)
1661                                 {
1662                                     Process *process = exe_ctx->GetProcessPtr();
1663                                     if (process)
1664                                     {
1665                                         var_name_begin += ::strlen ("process.");
1666                                         if (::strncmp (var_name_begin, "id}", strlen("id}")) == 0)
1667                                         {
1668                                             s.Printf("%llu", process->GetID());
1669                                             var_success = true;
1670                                         }
1671                                         else if ((::strncmp (var_name_begin, "name}", strlen("name}")) == 0) ||
1672                                                  (::strncmp (var_name_begin, "file.basename}", strlen("file.basename}")) == 0) ||
1673                                                  (::strncmp (var_name_begin, "file.fullpath}", strlen("file.fullpath}")) == 0))
1674                                         {
1675                                             Module *exe_module = process->GetTarget().GetExecutableModulePointer();
1676                                             if (exe_module)
1677                                             {
1678                                                 if (var_name_begin[0] == 'n' || var_name_begin[5] == 'f')
1679                                                 {
1680                                                     format_file_spec.GetFilename() = exe_module->GetFileSpec().GetFilename();
1681                                                     var_success = format_file_spec;
1682                                                 }
1683                                                 else
1684                                                 {
1685                                                     format_file_spec = exe_module->GetFileSpec();
1686                                                     var_success = format_file_spec;
1687                                                 }
1688                                             }
1689                                         }
1690                                     }
1691                                 }
1692                             }
1693                             break;
1694 
1695                         case 't':
1696                             if (::strncmp (var_name_begin, "thread.", strlen("thread.")) == 0)
1697                             {
1698                                 if (exe_ctx)
1699                                 {
1700                                     Thread *thread = exe_ctx->GetThreadPtr();
1701                                     if (thread)
1702                                     {
1703                                         var_name_begin += ::strlen ("thread.");
1704                                         if (::strncmp (var_name_begin, "id}", strlen("id}")) == 0)
1705                                         {
1706                                             s.Printf("0x%4.4llx", thread->GetID());
1707                                             var_success = true;
1708                                         }
1709                                         else if (::strncmp (var_name_begin, "index}", strlen("index}")) == 0)
1710                                         {
1711                                             s.Printf("%u", thread->GetIndexID());
1712                                             var_success = true;
1713                                         }
1714                                         else if (::strncmp (var_name_begin, "name}", strlen("name}")) == 0)
1715                                         {
1716                                             cstr = thread->GetName();
1717                                             var_success = cstr && cstr[0];
1718                                             if (var_success)
1719                                                 s.PutCString(cstr);
1720                                         }
1721                                         else if (::strncmp (var_name_begin, "queue}", strlen("queue}")) == 0)
1722                                         {
1723                                             cstr = thread->GetQueueName();
1724                                             var_success = cstr && cstr[0];
1725                                             if (var_success)
1726                                                 s.PutCString(cstr);
1727                                         }
1728                                         else if (::strncmp (var_name_begin, "stop-reason}", strlen("stop-reason}")) == 0)
1729                                         {
1730                                             StopInfoSP stop_info_sp = thread->GetStopInfo ();
1731                                             if (stop_info_sp)
1732                                             {
1733                                                 cstr = stop_info_sp->GetDescription();
1734                                                 if (cstr && cstr[0])
1735                                                 {
1736                                                     s.PutCString(cstr);
1737                                                     var_success = true;
1738                                                 }
1739                                             }
1740                                         }
1741                                         else if (::strncmp (var_name_begin, "return-value}", strlen("return-value}")) == 0)
1742                                         {
1743                                             StopInfoSP stop_info_sp = thread->GetStopInfo ();
1744                                             if (stop_info_sp)
1745                                             {
1746                                                 ValueObjectSP return_valobj_sp = StopInfo::GetReturnValueObject (stop_info_sp);
1747                                                 if (return_valobj_sp)
1748                                                 {
1749                                                     ValueObject::DumpValueObjectOptions dump_options;
1750                                                     ValueObject::DumpValueObject (s, return_valobj_sp.get(), dump_options);
1751                                                     var_success = true;
1752                                                 }
1753                                             }
1754                                         }
1755                                     }
1756                                 }
1757                             }
1758                             else if (::strncmp (var_name_begin, "target.", strlen("target.")) == 0)
1759                             {
1760                                 Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
1761                                 if (target)
1762                                 {
1763                                     var_name_begin += ::strlen ("target.");
1764                                     if (::strncmp (var_name_begin, "arch}", strlen("arch}")) == 0)
1765                                     {
1766                                         ArchSpec arch (target->GetArchitecture ());
1767                                         if (arch.IsValid())
1768                                         {
1769                                             s.PutCString (arch.GetArchitectureName());
1770                                             var_success = true;
1771                                         }
1772                                     }
1773                                 }
1774                             }
1775                             break;
1776 
1777 
1778                         case 'm':
1779                             if (::strncmp (var_name_begin, "module.", strlen("module.")) == 0)
1780                             {
1781                                 if (sc && sc->module_sp.get())
1782                                 {
1783                                     Module *module = sc->module_sp.get();
1784                                     var_name_begin += ::strlen ("module.");
1785 
1786                                     if (::strncmp (var_name_begin, "file.", strlen("file.")) == 0)
1787                                     {
1788                                         if (module->GetFileSpec())
1789                                         {
1790                                             var_name_begin += ::strlen ("file.");
1791 
1792                                             if (::strncmp (var_name_begin, "basename}", strlen("basename}")) == 0)
1793                                             {
1794                                                 format_file_spec.GetFilename() = module->GetFileSpec().GetFilename();
1795                                                 var_success = format_file_spec;
1796                                             }
1797                                             else if (::strncmp (var_name_begin, "fullpath}", strlen("fullpath}")) == 0)
1798                                             {
1799                                                 format_file_spec = module->GetFileSpec();
1800                                                 var_success = format_file_spec;
1801                                             }
1802                                         }
1803                                     }
1804                                 }
1805                             }
1806                             break;
1807 
1808 
1809                         case 'f':
1810                             if (::strncmp (var_name_begin, "file.", strlen("file.")) == 0)
1811                             {
1812                                 if (sc && sc->comp_unit != NULL)
1813                                 {
1814                                     var_name_begin += ::strlen ("file.");
1815 
1816                                     if (::strncmp (var_name_begin, "basename}", strlen("basename}")) == 0)
1817                                     {
1818                                         format_file_spec.GetFilename() = sc->comp_unit->GetFilename();
1819                                         var_success = format_file_spec;
1820                                     }
1821                                     else if (::strncmp (var_name_begin, "fullpath}", strlen("fullpath}")) == 0)
1822                                     {
1823                                         format_file_spec = *sc->comp_unit;
1824                                         var_success = format_file_spec;
1825                                     }
1826                                 }
1827                             }
1828                             else if (::strncmp (var_name_begin, "frame.", strlen("frame.")) == 0)
1829                             {
1830                                 if (exe_ctx)
1831                                 {
1832                                     StackFrame *frame = exe_ctx->GetFramePtr();
1833                                     if (frame)
1834                                     {
1835                                         var_name_begin += ::strlen ("frame.");
1836                                         if (::strncmp (var_name_begin, "index}", strlen("index}")) == 0)
1837                                         {
1838                                             s.Printf("%u", frame->GetFrameIndex());
1839                                             var_success = true;
1840                                         }
1841                                         else if (::strncmp (var_name_begin, "pc}", strlen("pc}")) == 0)
1842                                         {
1843                                             reg_kind = eRegisterKindGeneric;
1844                                             reg_num = LLDB_REGNUM_GENERIC_PC;
1845                                             var_success = true;
1846                                         }
1847                                         else if (::strncmp (var_name_begin, "sp}", strlen("sp}")) == 0)
1848                                         {
1849                                             reg_kind = eRegisterKindGeneric;
1850                                             reg_num = LLDB_REGNUM_GENERIC_SP;
1851                                             var_success = true;
1852                                         }
1853                                         else if (::strncmp (var_name_begin, "fp}", strlen("fp}")) == 0)
1854                                         {
1855                                             reg_kind = eRegisterKindGeneric;
1856                                             reg_num = LLDB_REGNUM_GENERIC_FP;
1857                                             var_success = true;
1858                                         }
1859                                         else if (::strncmp (var_name_begin, "flags}", strlen("flags}")) == 0)
1860                                         {
1861                                             reg_kind = eRegisterKindGeneric;
1862                                             reg_num = LLDB_REGNUM_GENERIC_FLAGS;
1863                                             var_success = true;
1864                                         }
1865                                         else if (::strncmp (var_name_begin, "reg.", strlen ("reg.")) == 0)
1866                                         {
1867                                             reg_ctx = frame->GetRegisterContext().get();
1868                                             if (reg_ctx)
1869                                             {
1870                                                 var_name_begin += ::strlen ("reg.");
1871                                                 if (var_name_begin < var_name_end)
1872                                                 {
1873                                                     std::string reg_name (var_name_begin, var_name_end);
1874                                                     reg_info = reg_ctx->GetRegisterInfoByName (reg_name.c_str());
1875                                                     if (reg_info)
1876                                                         var_success = true;
1877                                                 }
1878                                             }
1879                                         }
1880                                     }
1881                                 }
1882                             }
1883                             else if (::strncmp (var_name_begin, "function.", strlen("function.")) == 0)
1884                             {
1885                                 if (sc && (sc->function != NULL || sc->symbol != NULL))
1886                                 {
1887                                     var_name_begin += ::strlen ("function.");
1888                                     if (::strncmp (var_name_begin, "id}", strlen("id}")) == 0)
1889                                     {
1890                                         if (sc->function)
1891                                             s.Printf("function{0x%8.8llx}", sc->function->GetID());
1892                                         else
1893                                             s.Printf("symbol[%u]", sc->symbol->GetID());
1894 
1895                                         var_success = true;
1896                                     }
1897                                     else if (::strncmp (var_name_begin, "name}", strlen("name}")) == 0)
1898                                     {
1899                                         if (sc->function)
1900                                             cstr = sc->function->GetName().AsCString (NULL);
1901                                         else if (sc->symbol)
1902                                             cstr = sc->symbol->GetName().AsCString (NULL);
1903                                         if (cstr)
1904                                         {
1905                                             s.PutCString(cstr);
1906 
1907                                             if (sc->block)
1908                                             {
1909                                                 Block *inline_block = sc->block->GetContainingInlinedBlock ();
1910                                                 if (inline_block)
1911                                                 {
1912                                                     const InlineFunctionInfo *inline_info = sc->block->GetInlinedFunctionInfo();
1913                                                     if (inline_info)
1914                                                     {
1915                                                         s.PutCString(" [inlined] ");
1916                                                         inline_info->GetName().Dump(&s);
1917                                                     }
1918                                                 }
1919                                             }
1920                                             var_success = true;
1921                                         }
1922                                     }
1923                                     else if (::strncmp (var_name_begin, "name-with-args}", strlen("name-with-args}")) == 0)
1924                                     {
1925                                         // Print the function name with arguments in it
1926 
1927                                         if (sc->function)
1928                                         {
1929                                             var_success = true;
1930                                             ExecutionContextScope *exe_scope = exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL;
1931                                             cstr = sc->function->GetName().AsCString (NULL);
1932                                             if (cstr)
1933                                             {
1934                                                 const InlineFunctionInfo *inline_info = NULL;
1935                                                 VariableListSP variable_list_sp;
1936                                                 bool get_function_vars = true;
1937                                                 if (sc->block)
1938                                                 {
1939                                                     Block *inline_block = sc->block->GetContainingInlinedBlock ();
1940 
1941                                                     if (inline_block)
1942                                                     {
1943                                                         get_function_vars = false;
1944                                                         inline_info = sc->block->GetInlinedFunctionInfo();
1945                                                         if (inline_info)
1946                                                             variable_list_sp = inline_block->GetBlockVariableList (true);
1947                                                     }
1948                                                 }
1949 
1950                                                 if (get_function_vars)
1951                                                 {
1952                                                     variable_list_sp = sc->function->GetBlock(true).GetBlockVariableList (true);
1953                                                 }
1954 
1955                                                 if (inline_info)
1956                                                 {
1957                                                     s.PutCString (cstr);
1958                                                     s.PutCString (" [inlined] ");
1959                                                     cstr = inline_info->GetName().GetCString();
1960                                                 }
1961 
1962                                                 VariableList args;
1963                                                 if (variable_list_sp)
1964                                                 {
1965                                                     const size_t num_variables = variable_list_sp->GetSize();
1966                                                     for (size_t var_idx = 0; var_idx < num_variables; ++var_idx)
1967                                                     {
1968                                                         VariableSP var_sp (variable_list_sp->GetVariableAtIndex(var_idx));
1969                                                         if (var_sp->GetScope() == eValueTypeVariableArgument)
1970                                                             args.AddVariable (var_sp);
1971                                                     }
1972 
1973                                                 }
1974                                                 if (args.GetSize() > 0)
1975                                                 {
1976                                                     const char *open_paren = strchr (cstr, '(');
1977                                                     const char *close_paren = NULL;
1978                                                     if (open_paren)
1979                                                         close_paren = strchr (open_paren, ')');
1980 
1981                                                     if (open_paren)
1982                                                         s.Write(cstr, open_paren - cstr + 1);
1983                                                     else
1984                                                     {
1985                                                         s.PutCString (cstr);
1986                                                         s.PutChar ('(');
1987                                                     }
1988                                                     const size_t num_args = args.GetSize();
1989                                                     for (size_t arg_idx = 0; arg_idx < num_args; ++arg_idx)
1990                                                     {
1991                                                         VariableSP var_sp (args.GetVariableAtIndex (arg_idx));
1992                                                         ValueObjectSP var_value_sp (ValueObjectVariable::Create (exe_scope, var_sp));
1993                                                         const char *var_name = var_value_sp->GetName().GetCString();
1994                                                         const char *var_value = var_value_sp->GetValueAsCString();
1995                                                         if (var_value_sp->GetError().Success())
1996                                                         {
1997                                                             if (arg_idx > 0)
1998                                                                 s.PutCString (", ");
1999                                                             s.Printf ("%s=%s", var_name, var_value);
2000                                                         }
2001                                                     }
2002 
2003                                                     if (close_paren)
2004                                                         s.PutCString (close_paren);
2005                                                     else
2006                                                         s.PutChar(')');
2007 
2008                                                 }
2009                                                 else
2010                                                 {
2011                                                     s.PutCString(cstr);
2012                                                 }
2013                                             }
2014                                         }
2015                                         else if (sc->symbol)
2016                                         {
2017                                             cstr = sc->symbol->GetName().AsCString (NULL);
2018                                             if (cstr)
2019                                             {
2020                                                 s.PutCString(cstr);
2021                                                 var_success = true;
2022                                             }
2023                                         }
2024                                     }
2025                                     else if (::strncmp (var_name_begin, "addr-offset}", strlen("addr-offset}")) == 0)
2026                                     {
2027                                         var_success = addr != NULL;
2028                                         if (var_success)
2029                                         {
2030                                             format_addr = *addr;
2031                                             calculate_format_addr_function_offset = true;
2032                                         }
2033                                     }
2034                                     else if (::strncmp (var_name_begin, "line-offset}", strlen("line-offset}")) == 0)
2035                                     {
2036                                         var_success = sc->line_entry.range.GetBaseAddress().IsValid();
2037                                         if (var_success)
2038                                         {
2039                                             format_addr = sc->line_entry.range.GetBaseAddress();
2040                                             calculate_format_addr_function_offset = true;
2041                                         }
2042                                     }
2043                                     else if (::strncmp (var_name_begin, "pc-offset}", strlen("pc-offset}")) == 0)
2044                                     {
2045                                         StackFrame *frame = exe_ctx->GetFramePtr();
2046                                         var_success = frame != NULL;
2047                                         if (var_success)
2048                                         {
2049                                             format_addr = frame->GetFrameCodeAddress();
2050                                             calculate_format_addr_function_offset = true;
2051                                         }
2052                                     }
2053                                 }
2054                             }
2055                             break;
2056 
2057                         case 'l':
2058                             if (::strncmp (var_name_begin, "line.", strlen("line.")) == 0)
2059                             {
2060                                 if (sc && sc->line_entry.IsValid())
2061                                 {
2062                                     var_name_begin += ::strlen ("line.");
2063                                     if (::strncmp (var_name_begin, "file.", strlen("file.")) == 0)
2064                                     {
2065                                         var_name_begin += ::strlen ("file.");
2066 
2067                                         if (::strncmp (var_name_begin, "basename}", strlen("basename}")) == 0)
2068                                         {
2069                                             format_file_spec.GetFilename() = sc->line_entry.file.GetFilename();
2070                                             var_success = format_file_spec;
2071                                         }
2072                                         else if (::strncmp (var_name_begin, "fullpath}", strlen("fullpath}")) == 0)
2073                                         {
2074                                             format_file_spec = sc->line_entry.file;
2075                                             var_success = format_file_spec;
2076                                         }
2077                                     }
2078                                     else if (::strncmp (var_name_begin, "number}", strlen("number}")) == 0)
2079                                     {
2080                                         var_success = true;
2081                                         s.Printf("%u", sc->line_entry.line);
2082                                     }
2083                                     else if ((::strncmp (var_name_begin, "start-addr}", strlen("start-addr}")) == 0) ||
2084                                              (::strncmp (var_name_begin, "end-addr}", strlen("end-addr}")) == 0))
2085                                     {
2086                                         var_success = sc && sc->line_entry.range.GetBaseAddress().IsValid();
2087                                         if (var_success)
2088                                         {
2089                                             format_addr = sc->line_entry.range.GetBaseAddress();
2090                                             if (var_name_begin[0] == 'e')
2091                                                 format_addr.Slide (sc->line_entry.range.GetByteSize());
2092                                         }
2093                                     }
2094                                 }
2095                             }
2096                             break;
2097                         }
2098 
2099                         if (var_success)
2100                         {
2101                             // If format addr is valid, then we need to print an address
2102                             if (reg_num != LLDB_INVALID_REGNUM)
2103                             {
2104                                 StackFrame *frame = exe_ctx->GetFramePtr();
2105                                 // We have a register value to display...
2106                                 if (reg_num == LLDB_REGNUM_GENERIC_PC && reg_kind == eRegisterKindGeneric)
2107                                 {
2108                                     format_addr = frame->GetFrameCodeAddress();
2109                                 }
2110                                 else
2111                                 {
2112                                     if (reg_ctx == NULL)
2113                                         reg_ctx = frame->GetRegisterContext().get();
2114 
2115                                     if (reg_ctx)
2116                                     {
2117                                         if (reg_kind != kNumRegisterKinds)
2118                                             reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(reg_kind, reg_num);
2119                                         reg_info = reg_ctx->GetRegisterInfoAtIndex (reg_num);
2120                                         var_success = reg_info != NULL;
2121                                     }
2122                                 }
2123                             }
2124 
2125                             if (reg_info != NULL)
2126                             {
2127                                 RegisterValue reg_value;
2128                                 var_success = reg_ctx->ReadRegister (reg_info, reg_value);
2129                                 if (var_success)
2130                                 {
2131                                     reg_value.Dump(&s, reg_info, false, false, eFormatDefault);
2132                                 }
2133                             }
2134 
2135                             if (format_file_spec)
2136                             {
2137                                 s << format_file_spec;
2138                             }
2139 
2140                             // If format addr is valid, then we need to print an address
2141                             if (format_addr.IsValid())
2142                             {
2143                                 var_success = false;
2144 
2145                                 if (calculate_format_addr_function_offset)
2146                                 {
2147                                     Address func_addr;
2148 
2149                                     if (sc)
2150                                     {
2151                                         if (sc->function)
2152                                         {
2153                                             func_addr = sc->function->GetAddressRange().GetBaseAddress();
2154                                             if (sc->block)
2155                                             {
2156                                                 // Check to make sure we aren't in an inline
2157                                                 // function. If we are, use the inline block
2158                                                 // range that contains "format_addr" since
2159                                                 // blocks can be discontiguous.
2160                                                 Block *inline_block = sc->block->GetContainingInlinedBlock ();
2161                                                 AddressRange inline_range;
2162                                                 if (inline_block && inline_block->GetRangeContainingAddress (format_addr, inline_range))
2163                                                     func_addr = inline_range.GetBaseAddress();
2164                                             }
2165                                         }
2166                                         else if (sc->symbol && sc->symbol->ValueIsAddress())
2167                                             func_addr = sc->symbol->GetAddress();
2168                                     }
2169 
2170                                     if (func_addr.IsValid())
2171                                     {
2172                                         if (func_addr.GetSection() == format_addr.GetSection())
2173                                         {
2174                                             addr_t func_file_addr = func_addr.GetFileAddress();
2175                                             addr_t addr_file_addr = format_addr.GetFileAddress();
2176                                             if (addr_file_addr > func_file_addr)
2177                                                 s.Printf(" + %llu", addr_file_addr - func_file_addr);
2178                                             else if (addr_file_addr < func_file_addr)
2179                                                 s.Printf(" - %llu", func_file_addr - addr_file_addr);
2180                                             var_success = true;
2181                                         }
2182                                         else
2183                                         {
2184                                             Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
2185                                             if (target)
2186                                             {
2187                                                 addr_t func_load_addr = func_addr.GetLoadAddress (target);
2188                                                 addr_t addr_load_addr = format_addr.GetLoadAddress (target);
2189                                                 if (addr_load_addr > func_load_addr)
2190                                                     s.Printf(" + %llu", addr_load_addr - func_load_addr);
2191                                                 else if (addr_load_addr < func_load_addr)
2192                                                     s.Printf(" - %llu", func_load_addr - addr_load_addr);
2193                                                 var_success = true;
2194                                             }
2195                                         }
2196                                     }
2197                                 }
2198                                 else
2199                                 {
2200                                     Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
2201                                     addr_t vaddr = LLDB_INVALID_ADDRESS;
2202                                     if (exe_ctx && !target->GetSectionLoadList().IsEmpty())
2203                                         vaddr = format_addr.GetLoadAddress (target);
2204                                     if (vaddr == LLDB_INVALID_ADDRESS)
2205                                         vaddr = format_addr.GetFileAddress ();
2206 
2207                                     if (vaddr != LLDB_INVALID_ADDRESS)
2208                                     {
2209                                         int addr_width = target->GetArchitecture().GetAddressByteSize() * 2;
2210                                         if (addr_width == 0)
2211                                             addr_width = 16;
2212                                         s.Printf("0x%*.*llx", addr_width, addr_width, vaddr);
2213                                         var_success = true;
2214                                     }
2215                                 }
2216                             }
2217                         }
2218 
2219                         if (var_success == false)
2220                             success = false;
2221                     }
2222                     p = var_name_end;
2223                 }
2224                 else
2225                     break;
2226             }
2227             else
2228             {
2229                 // We got a dollar sign with no '{' after it, it must just be a dollar sign
2230                 s.PutChar(*p);
2231             }
2232         }
2233         else if (*p == '\\')
2234         {
2235             ++p; // skip the slash
2236             switch (*p)
2237             {
2238             case 'a': s.PutChar ('\a'); break;
2239             case 'b': s.PutChar ('\b'); break;
2240             case 'f': s.PutChar ('\f'); break;
2241             case 'n': s.PutChar ('\n'); break;
2242             case 'r': s.PutChar ('\r'); break;
2243             case 't': s.PutChar ('\t'); break;
2244             case 'v': s.PutChar ('\v'); break;
2245             case '\'': s.PutChar ('\''); break;
2246             case '\\': s.PutChar ('\\'); break;
2247             case '0':
2248                 // 1 to 3 octal chars
2249                 {
2250                     // Make a string that can hold onto the initial zero char,
2251                     // up to 3 octal digits, and a terminating NULL.
2252                     char oct_str[5] = { 0, 0, 0, 0, 0 };
2253 
2254                     int i;
2255                     for (i=0; (p[i] >= '0' && p[i] <= '7') && i<4; ++i)
2256                         oct_str[i] = p[i];
2257 
2258                     // We don't want to consume the last octal character since
2259                     // the main for loop will do this for us, so we advance p by
2260                     // one less than i (even if i is zero)
2261                     p += i - 1;
2262                     unsigned long octal_value = ::strtoul (oct_str, NULL, 8);
2263                     if (octal_value <= UINT8_MAX)
2264                     {
2265                         char octal_char = octal_value;
2266                         s.Write (&octal_char, 1);
2267                     }
2268                 }
2269                 break;
2270 
2271             case 'x':
2272                 // hex number in the format
2273                 if (isxdigit(p[1]))
2274                 {
2275                     ++p;    // Skip the 'x'
2276 
2277                     // Make a string that can hold onto two hex chars plus a
2278                     // NULL terminator
2279                     char hex_str[3] = { 0,0,0 };
2280                     hex_str[0] = *p;
2281                     if (isxdigit(p[1]))
2282                     {
2283                         ++p; // Skip the first of the two hex chars
2284                         hex_str[1] = *p;
2285                     }
2286 
2287                     unsigned long hex_value = strtoul (hex_str, NULL, 16);
2288                     if (hex_value <= UINT8_MAX)
2289                         s.PutChar (hex_value);
2290                 }
2291                 else
2292                 {
2293                     s.PutChar('x');
2294                 }
2295                 break;
2296 
2297             default:
2298                 // Just desensitize any other character by just printing what
2299                 // came after the '\'
2300                 s << *p;
2301                 break;
2302 
2303             }
2304 
2305         }
2306     }
2307     if (end)
2308         *end = p;
2309     return success;
2310 }
2311 
2312 void
2313 Debugger::SetLoggingCallback (lldb::LogOutputCallback log_callback, void *baton)
2314 {
2315     // For simplicity's sake, I am not going to deal with how to close down any
2316     // open logging streams, I just redirect everything from here on out to the
2317     // callback.
2318     m_log_callback_stream_sp.reset (new StreamCallback (log_callback, baton));
2319 }
2320 
2321 bool
2322 Debugger::EnableLog (const char *channel, const char **categories, const char *log_file, uint32_t log_options, Stream &error_stream)
2323 {
2324     Log::Callbacks log_callbacks;
2325 
2326     StreamSP log_stream_sp;
2327     if (m_log_callback_stream_sp != NULL)
2328     {
2329         log_stream_sp = m_log_callback_stream_sp;
2330         // For now when using the callback mode you always get thread & timestamp.
2331         log_options |= LLDB_LOG_OPTION_PREPEND_TIMESTAMP | LLDB_LOG_OPTION_PREPEND_THREAD_NAME;
2332     }
2333     else if (log_file == NULL || *log_file == '\0')
2334     {
2335         log_stream_sp.reset(new StreamFile(GetOutputFile().GetDescriptor(), false));
2336     }
2337     else
2338     {
2339         LogStreamMap::iterator pos = m_log_streams.find(log_file);
2340         if (pos == m_log_streams.end())
2341         {
2342             log_stream_sp.reset (new StreamFile (log_file));
2343             m_log_streams[log_file] = log_stream_sp;
2344         }
2345         else
2346             log_stream_sp = pos->second;
2347     }
2348     assert (log_stream_sp.get());
2349 
2350     if (log_options == 0)
2351         log_options = LLDB_LOG_OPTION_PREPEND_THREAD_NAME | LLDB_LOG_OPTION_THREADSAFE;
2352 
2353     if (Log::GetLogChannelCallbacks (channel, log_callbacks))
2354     {
2355         log_callbacks.enable (log_stream_sp, log_options, categories, &error_stream);
2356         return true;
2357     }
2358     else
2359     {
2360         LogChannelSP log_channel_sp (LogChannel::FindPlugin (channel));
2361         if (log_channel_sp)
2362         {
2363             if (log_channel_sp->Enable (log_stream_sp, log_options, &error_stream, categories))
2364             {
2365                 return true;
2366             }
2367             else
2368             {
2369                 error_stream.Printf ("Invalid log channel '%s'.\n", channel);
2370                 return false;
2371             }
2372         }
2373         else
2374         {
2375             error_stream.Printf ("Invalid log channel '%s'.\n", channel);
2376             return false;
2377         }
2378     }
2379     return false;
2380 }
2381 
2382 #pragma mark Debugger::SettingsController
2383 
2384 //--------------------------------------------------
2385 // class Debugger::SettingsController
2386 //--------------------------------------------------
2387 
2388 Debugger::SettingsController::SettingsController () :
2389     UserSettingsController ("", UserSettingsControllerSP())
2390 {
2391 }
2392 
2393 Debugger::SettingsController::~SettingsController ()
2394 {
2395 }
2396 
2397 
2398 InstanceSettingsSP
2399 Debugger::SettingsController::CreateInstanceSettings (const char *instance_name)
2400 {
2401     InstanceSettingsSP new_settings_sp (new DebuggerInstanceSettings (GetSettingsController(),
2402                                                                       false,
2403                                                                       instance_name));
2404     return new_settings_sp;
2405 }
2406 
2407 #pragma mark DebuggerInstanceSettings
2408 //--------------------------------------------------
2409 //  class DebuggerInstanceSettings
2410 //--------------------------------------------------
2411 
2412 DebuggerInstanceSettings::DebuggerInstanceSettings
2413 (
2414     const UserSettingsControllerSP &m_owner_sp,
2415     bool live_instance,
2416     const char *name
2417 ) :
2418     InstanceSettings (m_owner_sp, name ? name : InstanceSettings::InvalidName().AsCString(), live_instance),
2419     m_term_width (80),
2420     m_stop_source_before_count (3),
2421     m_stop_source_after_count (3),
2422     m_stop_disassembly_count (4),
2423     m_stop_disassembly_display (eStopDisassemblyTypeNoSource),
2424     m_prompt (),
2425     m_frame_format (),
2426     m_thread_format (),
2427     m_script_lang (),
2428     m_use_external_editor (false),
2429     m_auto_confirm_on (false)
2430 {
2431     // CopyInstanceSettings is a pure virtual function in InstanceSettings; it therefore cannot be called
2432     // until the vtables for DebuggerInstanceSettings are properly set up, i.e. AFTER all the initializers.
2433     // For this reason it has to be called here, rather than in the initializer or in the parent constructor.
2434     // The same is true of CreateInstanceName().
2435 
2436     if (GetInstanceName() == InstanceSettings::InvalidName())
2437     {
2438         ChangeInstanceName (std::string (CreateInstanceName().AsCString()));
2439         m_owner_sp->RegisterInstanceSettings (this);
2440     }
2441 
2442     if (live_instance)
2443     {
2444         const InstanceSettingsSP &pending_settings = m_owner_sp->FindPendingSettings (m_instance_name);
2445         CopyInstanceSettings (pending_settings, false);
2446     }
2447 }
2448 
2449 DebuggerInstanceSettings::DebuggerInstanceSettings (const DebuggerInstanceSettings &rhs) :
2450     InstanceSettings (Debugger::GetSettingsController(), CreateInstanceName ().AsCString()),
2451     m_prompt (rhs.m_prompt),
2452     m_frame_format (rhs.m_frame_format),
2453     m_thread_format (rhs.m_thread_format),
2454     m_script_lang (rhs.m_script_lang),
2455     m_use_external_editor (rhs.m_use_external_editor),
2456     m_auto_confirm_on(rhs.m_auto_confirm_on)
2457 {
2458     UserSettingsControllerSP owner_sp (m_owner_wp.lock());
2459     if (owner_sp)
2460     {
2461         CopyInstanceSettings (owner_sp->FindPendingSettings (m_instance_name), false);
2462         owner_sp->RemovePendingSettings (m_instance_name);
2463     }
2464 }
2465 
2466 DebuggerInstanceSettings::~DebuggerInstanceSettings ()
2467 {
2468 }
2469 
2470 DebuggerInstanceSettings&
2471 DebuggerInstanceSettings::operator= (const DebuggerInstanceSettings &rhs)
2472 {
2473     if (this != &rhs)
2474     {
2475         m_term_width = rhs.m_term_width;
2476         m_prompt = rhs.m_prompt;
2477         m_frame_format = rhs.m_frame_format;
2478         m_thread_format = rhs.m_thread_format;
2479         m_script_lang = rhs.m_script_lang;
2480         m_use_external_editor = rhs.m_use_external_editor;
2481         m_auto_confirm_on = rhs.m_auto_confirm_on;
2482     }
2483 
2484     return *this;
2485 }
2486 
2487 bool
2488 DebuggerInstanceSettings::ValidTermWidthValue (const char *value, Error err)
2489 {
2490     bool valid = false;
2491 
2492     // Verify we have a value string.
2493     if (value == NULL || value[0] == '\0')
2494     {
2495         err.SetErrorString ("missing value, can't set terminal width without a value");
2496     }
2497     else
2498     {
2499         char *end = NULL;
2500         const uint32_t width = ::strtoul (value, &end, 0);
2501 
2502         if (end && end[0] == '\0')
2503         {
2504             if (width >= 10 && width <= 1024)
2505                 valid = true;
2506             else
2507                 err.SetErrorString ("invalid term-width value; value must be between 10 and 1024");
2508         }
2509         else
2510             err.SetErrorStringWithFormat ("'%s' is not a valid unsigned integer string", value);
2511     }
2512 
2513     return valid;
2514 }
2515 
2516 
2517 void
2518 DebuggerInstanceSettings::UpdateInstanceSettingsVariable (const ConstString &var_name,
2519                                                           const char *index_value,
2520                                                           const char *value,
2521                                                           const ConstString &instance_name,
2522                                                           const SettingEntry &entry,
2523                                                           VarSetOperationType op,
2524                                                           Error &err,
2525                                                           bool pending)
2526 {
2527 
2528     if (var_name == TermWidthVarName())
2529     {
2530         if (ValidTermWidthValue (value, err))
2531         {
2532             m_term_width = ::strtoul (value, NULL, 0);
2533         }
2534     }
2535     else if (var_name == PromptVarName())
2536     {
2537         UserSettingsController::UpdateStringVariable (op, m_prompt, value, err);
2538         if (!pending)
2539         {
2540             // 'instance_name' is actually (probably) in the form '[<instance_name>]';  if so, we need to
2541             // strip off the brackets before passing it to BroadcastPromptChange.
2542 
2543             std::string tmp_instance_name (instance_name.AsCString());
2544             if ((tmp_instance_name[0] == '[')
2545                 && (tmp_instance_name[instance_name.GetLength() - 1] == ']'))
2546                 tmp_instance_name = tmp_instance_name.substr (1, instance_name.GetLength() - 2);
2547             ConstString new_name (tmp_instance_name.c_str());
2548 
2549             BroadcastPromptChange (new_name, m_prompt.c_str());
2550         }
2551     }
2552     else if (var_name == GetFrameFormatName())
2553     {
2554         UserSettingsController::UpdateStringVariable (op, m_frame_format, value, err);
2555     }
2556     else if (var_name == GetThreadFormatName())
2557     {
2558         UserSettingsController::UpdateStringVariable (op, m_thread_format, value, err);
2559     }
2560     else if (var_name == ScriptLangVarName())
2561     {
2562         bool success;
2563         m_script_lang = Args::StringToScriptLanguage (value, eScriptLanguageDefault,
2564                                                       &success);
2565     }
2566     else if (var_name == UseExternalEditorVarName ())
2567     {
2568         UserSettingsController::UpdateBooleanVariable (op, m_use_external_editor, value, false, err);
2569     }
2570     else if (var_name == AutoConfirmName ())
2571     {
2572         UserSettingsController::UpdateBooleanVariable (op, m_auto_confirm_on, value, false, err);
2573     }
2574     else if (var_name == StopSourceContextBeforeName ())
2575     {
2576         uint32_t new_value = Args::StringToUInt32(value, UINT32_MAX, 10, NULL);
2577         if (new_value != UINT32_MAX)
2578             m_stop_source_before_count = new_value;
2579         else
2580             err.SetErrorStringWithFormat("invalid unsigned string value '%s' for the '%s' setting", value, StopSourceContextAfterName ().GetCString());
2581     }
2582     else if (var_name == StopSourceContextAfterName ())
2583     {
2584         uint32_t new_value = Args::StringToUInt32(value, UINT32_MAX, 10, NULL);
2585         if (new_value != UINT32_MAX)
2586             m_stop_source_after_count = new_value;
2587         else
2588             err.SetErrorStringWithFormat("invalid unsigned string value '%s' for the '%s' setting", value, StopSourceContextBeforeName ().GetCString());
2589     }
2590     else if (var_name == StopDisassemblyCountName ())
2591     {
2592         uint32_t new_value = Args::StringToUInt32(value, UINT32_MAX, 10, NULL);
2593         if (new_value != UINT32_MAX)
2594             m_stop_disassembly_count = new_value;
2595         else
2596             err.SetErrorStringWithFormat("invalid unsigned string value '%s' for the '%s' setting", value, StopDisassemblyCountName ().GetCString());
2597     }
2598     else if (var_name == StopDisassemblyDisplayName ())
2599     {
2600         int new_value;
2601         UserSettingsController::UpdateEnumVariable (g_show_disassembly_enum_values, &new_value, value, err);
2602         if (err.Success())
2603             m_stop_disassembly_display = (StopDisassemblyType)new_value;
2604     }
2605 }
2606 
2607 bool
2608 DebuggerInstanceSettings::GetInstanceSettingsValue (const SettingEntry &entry,
2609                                                     const ConstString &var_name,
2610                                                     StringList &value,
2611                                                     Error *err)
2612 {
2613     if (var_name == PromptVarName())
2614     {
2615         value.AppendString (m_prompt.c_str(), m_prompt.size());
2616 
2617     }
2618     else if (var_name == ScriptLangVarName())
2619     {
2620         value.AppendString (ScriptInterpreter::LanguageToString (m_script_lang).c_str());
2621     }
2622     else if (var_name == TermWidthVarName())
2623     {
2624         StreamString width_str;
2625         width_str.Printf ("%u", m_term_width);
2626         value.AppendString (width_str.GetData());
2627     }
2628     else if (var_name == GetFrameFormatName ())
2629     {
2630         value.AppendString(m_frame_format.c_str(), m_frame_format.size());
2631     }
2632     else if (var_name == GetThreadFormatName ())
2633     {
2634         value.AppendString(m_thread_format.c_str(), m_thread_format.size());
2635     }
2636     else if (var_name == UseExternalEditorVarName())
2637     {
2638         if (m_use_external_editor)
2639             value.AppendString ("true");
2640         else
2641             value.AppendString ("false");
2642     }
2643     else if (var_name == AutoConfirmName())
2644     {
2645         if (m_auto_confirm_on)
2646             value.AppendString ("true");
2647         else
2648             value.AppendString ("false");
2649     }
2650     else if (var_name == StopSourceContextAfterName ())
2651     {
2652         StreamString strm;
2653         strm.Printf ("%u", m_stop_source_before_count);
2654         value.AppendString (strm.GetData());
2655     }
2656     else if (var_name == StopSourceContextBeforeName ())
2657     {
2658         StreamString strm;
2659         strm.Printf ("%u", m_stop_source_after_count);
2660         value.AppendString (strm.GetData());
2661     }
2662     else if (var_name == StopDisassemblyCountName ())
2663     {
2664         StreamString strm;
2665         strm.Printf ("%u", m_stop_disassembly_count);
2666         value.AppendString (strm.GetData());
2667     }
2668     else if (var_name == StopDisassemblyDisplayName ())
2669     {
2670         if (m_stop_disassembly_display >= eStopDisassemblyTypeNever && m_stop_disassembly_display <= eStopDisassemblyTypeAlways)
2671             value.AppendString (g_show_disassembly_enum_values[m_stop_disassembly_display].string_value);
2672         else
2673             value.AppendString ("<invalid>");
2674     }
2675     else
2676     {
2677         if (err)
2678             err->SetErrorStringWithFormat ("unrecognized variable name '%s'", var_name.AsCString());
2679         return false;
2680     }
2681     return true;
2682 }
2683 
2684 void
2685 DebuggerInstanceSettings::CopyInstanceSettings (const InstanceSettingsSP &new_settings,
2686                                                 bool pending)
2687 {
2688     if (new_settings.get() == NULL)
2689         return;
2690 
2691     DebuggerInstanceSettings *new_debugger_settings = (DebuggerInstanceSettings *) new_settings.get();
2692 
2693     m_prompt = new_debugger_settings->m_prompt;
2694     if (!pending)
2695     {
2696         // 'instance_name' is actually (probably) in the form '[<instance_name>]';  if so, we need to
2697         // strip off the brackets before passing it to BroadcastPromptChange.
2698 
2699         std::string tmp_instance_name (m_instance_name.AsCString());
2700         if ((tmp_instance_name[0] == '[')
2701             && (tmp_instance_name[m_instance_name.GetLength() - 1] == ']'))
2702             tmp_instance_name = tmp_instance_name.substr (1, m_instance_name.GetLength() - 2);
2703         ConstString new_name (tmp_instance_name.c_str());
2704 
2705         BroadcastPromptChange (new_name, m_prompt.c_str());
2706     }
2707     m_frame_format = new_debugger_settings->m_frame_format;
2708     m_thread_format = new_debugger_settings->m_thread_format;
2709     m_term_width = new_debugger_settings->m_term_width;
2710     m_script_lang = new_debugger_settings->m_script_lang;
2711     m_use_external_editor = new_debugger_settings->m_use_external_editor;
2712     m_auto_confirm_on = new_debugger_settings->m_auto_confirm_on;
2713 }
2714 
2715 
2716 bool
2717 DebuggerInstanceSettings::BroadcastPromptChange (const ConstString &instance_name, const char *new_prompt)
2718 {
2719     std::string tmp_prompt;
2720 
2721     if (new_prompt != NULL)
2722     {
2723         tmp_prompt = new_prompt ;
2724         int len = tmp_prompt.size();
2725         if (len > 1
2726             && (tmp_prompt[0] == '\'' || tmp_prompt[0] == '"')
2727             && (tmp_prompt[len-1] == tmp_prompt[0]))
2728         {
2729             tmp_prompt = tmp_prompt.substr(1,len-2);
2730         }
2731         len = tmp_prompt.size();
2732         if (tmp_prompt[len-1] != ' ')
2733             tmp_prompt.append(" ");
2734     }
2735     EventSP new_event_sp;
2736     new_event_sp.reset (new Event(CommandInterpreter::eBroadcastBitResetPrompt,
2737                                   new EventDataBytes (tmp_prompt.c_str())));
2738 
2739     if (instance_name.GetLength() != 0)
2740     {
2741         // Set prompt for a particular instance.
2742         Debugger *dbg = Debugger::FindDebuggerWithInstanceName (instance_name).get();
2743         if (dbg != NULL)
2744         {
2745             dbg->GetCommandInterpreter().BroadcastEvent (new_event_sp);
2746         }
2747     }
2748 
2749     return true;
2750 }
2751 
2752 const ConstString
2753 DebuggerInstanceSettings::CreateInstanceName ()
2754 {
2755     static int instance_count = 1;
2756     StreamString sstr;
2757 
2758     sstr.Printf ("debugger_%d", instance_count);
2759     ++instance_count;
2760 
2761     const ConstString ret_val (sstr.GetData());
2762 
2763     return ret_val;
2764 }
2765 
2766 
2767 //--------------------------------------------------
2768 // SettingsController Variable Tables
2769 //--------------------------------------------------
2770 
2771 
2772 SettingEntry
2773 Debugger::SettingsController::global_settings_table[] =
2774 {
2775   //{ "var-name",    var-type,      "default", enum-table, init'd, hidden, "help-text"},
2776   // The Debugger level global table should always be empty; all Debugger settable variables should be instance
2777   // variables.
2778     {  NULL, eSetVarTypeNone, NULL, NULL, 0, 0, NULL }
2779 };
2780 
2781 #define MODULE_WITH_FUNC "{ ${module.file.basename}{`${function.name}${function.pc-offset}}}"
2782 #define FILE_AND_LINE "{ at ${line.file.basename}:${line.number}}"
2783 
2784 #define DEFAULT_THREAD_FORMAT "thread #${thread.index}: tid = ${thread.id}"\
2785     "{, ${frame.pc}}"\
2786     MODULE_WITH_FUNC\
2787     FILE_AND_LINE\
2788     "{, stop reason = ${thread.stop-reason}}"\
2789     "{\\nReturn value: ${thread.return-value}}"\
2790     "\\n"
2791 
2792 //#define DEFAULT_THREAD_FORMAT "thread #${thread.index}: tid = ${thread.id}"\
2793 //    "{, ${frame.pc}}"\
2794 //    MODULE_WITH_FUNC\
2795 //    FILE_AND_LINE\
2796 //    "{, stop reason = ${thread.stop-reason}}"\
2797 //    "{, name = ${thread.name}}"\
2798 //    "{, queue = ${thread.queue}}"\
2799 //    "\\n"
2800 
2801 #define DEFAULT_FRAME_FORMAT "frame #${frame.index}: ${frame.pc}"\
2802     MODULE_WITH_FUNC\
2803     FILE_AND_LINE\
2804     "\\n"
2805 
2806 SettingEntry
2807 Debugger::SettingsController::instance_settings_table[] =
2808 {
2809 //  NAME                    Setting variable type   Default                 Enum  Init'd Hidden Help
2810 //  ======================= ======================= ======================  ====  ====== ====== ======================
2811 {   "frame-format",         eSetVarTypeString,      DEFAULT_FRAME_FORMAT,   NULL, false, false, "The default frame format string to use when displaying thread information." },
2812 {   "prompt",               eSetVarTypeString,      "(lldb) ",              NULL, false, false, "The debugger command line prompt displayed for the user." },
2813 {   "script-lang",          eSetVarTypeString,      "python",               NULL, false, false, "The script language to be used for evaluating user-written scripts." },
2814 {   "term-width",           eSetVarTypeInt,         "80"    ,               NULL, false, false, "The maximum number of columns to use for displaying text." },
2815 {   "thread-format",        eSetVarTypeString,      DEFAULT_THREAD_FORMAT,  NULL, false, false, "The default thread format string to use when displaying thread information." },
2816 {   "use-external-editor",  eSetVarTypeBoolean,     "false",                NULL, false, false, "Whether to use an external editor or not." },
2817 {   "auto-confirm",         eSetVarTypeBoolean,     "false",                NULL, false, false, "If true all confirmation prompts will receive their default reply." },
2818 {   "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." },
2819 {   "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." },
2820 {   "stop-disassembly-count",  eSetVarTypeInt,      "0",                    NULL, false, false, "The number of disassembly lines to show when displaying a stopped context." },
2821 {   "stop-disassembly-display", eSetVarTypeEnum,    "no-source",           g_show_disassembly_enum_values, false, false, "Control when to display disassembly when displaying a stopped context." },
2822 {   NULL,                   eSetVarTypeNone,        NULL,                   NULL, false, false, NULL }
2823 };
2824