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