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