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