130fdc8d8SChris Lattner //===-- Debugger.cpp --------------------------------------------*- C++ -*-===//
230fdc8d8SChris Lattner //
330fdc8d8SChris Lattner //                     The LLVM Compiler Infrastructure
430fdc8d8SChris Lattner //
530fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source
630fdc8d8SChris Lattner // License. See LICENSE.TXT for details.
730fdc8d8SChris Lattner //
830fdc8d8SChris Lattner //===----------------------------------------------------------------------===//
930fdc8d8SChris Lattner 
1093a64300SDaniel Malea #include "lldb/lldb-python.h"
1193a64300SDaniel Malea 
1221dfcd9dSEnrico Granata #include "lldb/API/SBDebugger.h"
1321dfcd9dSEnrico Granata 
144a33d318SGreg Clayton #include "lldb/Core/Debugger.h"
154a33d318SGreg Clayton 
164a33d318SGreg Clayton #include <map>
174a33d318SGreg Clayton 
184becb37eSEnrico Granata #include "clang/AST/DeclCXX.h"
194becb37eSEnrico Granata #include "clang/AST/Type.h"
204becb37eSEnrico Granata 
2130fdc8d8SChris Lattner #include "lldb/lldb-private.h"
2230fdc8d8SChris Lattner #include "lldb/Core/ConnectionFileDescriptor.h"
23a777dc2aSEnrico Granata #include "lldb/Core/DataVisualization.h"
244a33d318SGreg Clayton #include "lldb/Core/FormatManager.h"
2530fdc8d8SChris Lattner #include "lldb/Core/InputReader.h"
261f746071SGreg Clayton #include "lldb/Core/Module.h"
27e8cd0c98SGreg Clayton #include "lldb/Core/PluginManager.h"
287349bd90SGreg Clayton #include "lldb/Core/RegisterValue.h"
2930fdc8d8SChris Lattner #include "lldb/Core/State.h"
305b52f0c7SJim Ingham #include "lldb/Core/StreamAsynchronousIO.h"
31228063cdSJim Ingham #include "lldb/Core/StreamCallback.h"
321b654882SGreg Clayton #include "lldb/Core/StreamString.h"
3330fdc8d8SChris Lattner #include "lldb/Core/Timer.h"
344becb37eSEnrico Granata #include "lldb/Core/ValueObject.h"
356d3dbf51SGreg Clayton #include "lldb/Core/ValueObjectVariable.h"
3621dfcd9dSEnrico Granata #include "lldb/Host/DynamicLibrary.h"
37a3406614SGreg Clayton #include "lldb/Host/Terminal.h"
386611103cSGreg Clayton #include "lldb/Interpreter/CommandInterpreter.h"
3967cc0636SGreg Clayton #include "lldb/Interpreter/OptionValueSInt64.h"
4067cc0636SGreg Clayton #include "lldb/Interpreter/OptionValueString.h"
411f746071SGreg Clayton #include "lldb/Symbol/ClangASTContext.h"
421f746071SGreg Clayton #include "lldb/Symbol/CompileUnit.h"
431f746071SGreg Clayton #include "lldb/Symbol/Function.h"
441f746071SGreg Clayton #include "lldb/Symbol/Symbol.h"
456d3dbf51SGreg Clayton #include "lldb/Symbol/VariableList.h"
4630fdc8d8SChris Lattner #include "lldb/Target/TargetList.h"
4730fdc8d8SChris Lattner #include "lldb/Target/Process.h"
481b654882SGreg Clayton #include "lldb/Target/RegisterContext.h"
491b654882SGreg Clayton #include "lldb/Target/StopInfo.h"
5030fdc8d8SChris Lattner #include "lldb/Target/Thread.h"
515a31471eSGreg Clayton #include "lldb/Utility/AnsiTerminal.h"
5230fdc8d8SChris Lattner 
5330fdc8d8SChris Lattner using namespace lldb;
5430fdc8d8SChris Lattner using namespace lldb_private;
5530fdc8d8SChris Lattner 
5630fdc8d8SChris Lattner 
571b654882SGreg Clayton static uint32_t g_shared_debugger_refcount = 0;
58ebc1bb27SCaroline Tice static lldb::user_id_t g_unique_id = 1;
59ebc1bb27SCaroline Tice 
601b654882SGreg Clayton #pragma mark Static Functions
611b654882SGreg Clayton 
621b654882SGreg Clayton static Mutex &
631b654882SGreg Clayton GetDebuggerListMutex ()
641b654882SGreg Clayton {
651b654882SGreg Clayton     static Mutex g_mutex(Mutex::eMutexTypeRecursive);
661b654882SGreg Clayton     return g_mutex;
671b654882SGreg Clayton }
681b654882SGreg Clayton 
691b654882SGreg Clayton typedef std::vector<DebuggerSP> DebuggerList;
701b654882SGreg Clayton 
711b654882SGreg Clayton static DebuggerList &
721b654882SGreg Clayton GetDebuggerList()
731b654882SGreg Clayton {
741b654882SGreg Clayton     // hide the static debugger list inside a singleton accessor to avoid
751b654882SGreg Clayton     // global init contructors
761b654882SGreg Clayton     static DebuggerList g_list;
771b654882SGreg Clayton     return g_list;
781b654882SGreg Clayton }
79e372b98dSGreg Clayton 
80e372b98dSGreg Clayton OptionEnumValueElement
8167cc0636SGreg Clayton g_show_disassembly_enum_values[] =
82e372b98dSGreg Clayton {
8367cc0636SGreg Clayton     { Debugger::eStopDisassemblyTypeNever,    "never",     "Never show disassembly when displaying a stop context."},
8467cc0636SGreg Clayton     { Debugger::eStopDisassemblyTypeNoSource, "no-source", "Show disassembly when there is no source information, or the source file is missing when displaying a stop context."},
8567cc0636SGreg Clayton     { Debugger::eStopDisassemblyTypeAlways,   "always",    "Always show disassembly when displaying a stop context."},
86e372b98dSGreg Clayton     { 0, NULL, NULL }
87e372b98dSGreg Clayton };
88e372b98dSGreg Clayton 
8967cc0636SGreg Clayton OptionEnumValueElement
9067cc0636SGreg Clayton g_language_enumerators[] =
9167cc0636SGreg Clayton {
9267cc0636SGreg Clayton     { eScriptLanguageNone,      "none",     "Disable scripting languages."},
9367cc0636SGreg Clayton     { eScriptLanguagePython,    "python",   "Select python as the default scripting language."},
9467cc0636SGreg Clayton     { eScriptLanguageDefault,   "default",  "Select the lldb default as the default scripting language."},
95a12993c9SGreg Clayton     { 0, NULL, NULL }
9667cc0636SGreg Clayton };
97e372b98dSGreg Clayton 
9867cc0636SGreg Clayton #define MODULE_WITH_FUNC "{ ${module.file.basename}{`${function.name-with-args}${function.pc-offset}}}"
9967cc0636SGreg Clayton #define FILE_AND_LINE "{ at ${line.file.basename}:${line.number}}"
10067cc0636SGreg Clayton 
10167cc0636SGreg Clayton #define DEFAULT_THREAD_FORMAT "thread #${thread.index}: tid = ${thread.id}"\
10267cc0636SGreg Clayton     "{, ${frame.pc}}"\
10367cc0636SGreg Clayton     MODULE_WITH_FUNC\
10467cc0636SGreg Clayton     FILE_AND_LINE\
10567cc0636SGreg Clayton     "{, stop reason = ${thread.stop-reason}}"\
10667cc0636SGreg Clayton     "{\\nReturn value: ${thread.return-value}}"\
10767cc0636SGreg Clayton     "\\n"
10867cc0636SGreg Clayton 
10967cc0636SGreg Clayton #define DEFAULT_FRAME_FORMAT "frame #${frame.index}: ${frame.pc}"\
11067cc0636SGreg Clayton     MODULE_WITH_FUNC\
11167cc0636SGreg Clayton     FILE_AND_LINE\
11267cc0636SGreg Clayton     "\\n"
11367cc0636SGreg Clayton 
11467cc0636SGreg Clayton 
11567cc0636SGreg Clayton 
116754a9369SGreg Clayton static PropertyDefinition
117754a9369SGreg Clayton g_properties[] =
11867cc0636SGreg Clayton {
11967cc0636SGreg Clayton {   "auto-confirm",             OptionValue::eTypeBoolean, true, false, NULL, NULL, "If true all confirmation prompts will receive their default reply." },
12067cc0636SGreg Clayton {   "frame-format",             OptionValue::eTypeString , true, 0    , DEFAULT_FRAME_FORMAT, NULL, "The default frame format string to use when displaying stack frame information for threads." },
12167cc0636SGreg Clayton {   "notify-void",              OptionValue::eTypeBoolean, true, false, NULL, NULL, "Notify the user explicitly if an expression returns void (default: false)." },
1224c05410fSGreg Clayton {   "prompt",                   OptionValue::eTypeString , true, OptionValueString::eOptionEncodeCharacterEscapeSequences, "(lldb) ", NULL, "The debugger command line prompt displayed for the user." },
12367cc0636SGreg Clayton {   "script-lang",              OptionValue::eTypeEnum   , true, eScriptLanguagePython, NULL, g_language_enumerators, "The script language to be used for evaluating user-written scripts." },
12467cc0636SGreg Clayton {   "stop-disassembly-count",   OptionValue::eTypeSInt64 , true, 4    , NULL, NULL, "The number of disassembly lines to show when displaying a stopped context." },
12567cc0636SGreg Clayton {   "stop-disassembly-display", OptionValue::eTypeEnum   , true, Debugger::eStopDisassemblyTypeNoSource, NULL, g_show_disassembly_enum_values, "Control when to display disassembly when displaying a stopped context." },
12667cc0636SGreg Clayton {   "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." },
12767cc0636SGreg Clayton {   "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." },
12867cc0636SGreg Clayton {   "term-width",               OptionValue::eTypeSInt64 , true, 80   , NULL, NULL, "The maximum number of columns to use for displaying text." },
12967cc0636SGreg Clayton {   "thread-format",            OptionValue::eTypeString , true, 0    , DEFAULT_THREAD_FORMAT, NULL, "The default thread format string to use when displaying thread information." },
13067cc0636SGreg Clayton {   "use-external-editor",      OptionValue::eTypeBoolean, true, false, NULL, NULL, "Whether to use an external editor or not." },
131e8cd0c98SGreg Clayton 
13267cc0636SGreg Clayton     {   NULL,                       OptionValue::eTypeInvalid, true, 0    , NULL, NULL, NULL }
13367cc0636SGreg Clayton };
13467cc0636SGreg Clayton 
13567cc0636SGreg Clayton enum
13667cc0636SGreg Clayton {
13767cc0636SGreg Clayton     ePropertyAutoConfirm = 0,
13867cc0636SGreg Clayton     ePropertyFrameFormat,
13967cc0636SGreg Clayton     ePropertyNotiftVoid,
14067cc0636SGreg Clayton     ePropertyPrompt,
14167cc0636SGreg Clayton     ePropertyScriptLanguage,
14267cc0636SGreg Clayton     ePropertyStopDisassemblyCount,
14367cc0636SGreg Clayton     ePropertyStopDisassemblyDisplay,
14467cc0636SGreg Clayton     ePropertyStopLineCountAfter,
14567cc0636SGreg Clayton     ePropertyStopLineCountBefore,
14667cc0636SGreg Clayton     ePropertyTerminalWidth,
14767cc0636SGreg Clayton     ePropertyThreadFormat,
14867cc0636SGreg Clayton     ePropertyUseExternalEditor
14967cc0636SGreg Clayton };
15067cc0636SGreg Clayton 
15167cc0636SGreg Clayton //
15267cc0636SGreg Clayton //const char *
15367cc0636SGreg Clayton //Debugger::GetFrameFormat() const
15467cc0636SGreg Clayton //{
15567cc0636SGreg Clayton //    return m_properties_sp->GetFrameFormat();
15667cc0636SGreg Clayton //}
15767cc0636SGreg Clayton //const char *
15867cc0636SGreg Clayton //Debugger::GetThreadFormat() const
15967cc0636SGreg Clayton //{
16067cc0636SGreg Clayton //    return m_properties_sp->GetThreadFormat();
16167cc0636SGreg Clayton //}
16267cc0636SGreg Clayton //
1634c05410fSGreg Clayton 
1644c05410fSGreg Clayton 
1654c05410fSGreg Clayton Error
1664c05410fSGreg Clayton Debugger::SetPropertyValue (const ExecutionContext *exe_ctx,
1674c05410fSGreg Clayton                             VarSetOperationType op,
1684c05410fSGreg Clayton                             const char *property_path,
1694c05410fSGreg Clayton                             const char *value)
1704c05410fSGreg Clayton {
1714c05410fSGreg Clayton     Error error (Properties::SetPropertyValue (exe_ctx, op, property_path, value));
1724c05410fSGreg Clayton     if (error.Success())
1734c05410fSGreg Clayton     {
1744c05410fSGreg Clayton         if (strcmp(property_path, g_properties[ePropertyPrompt].name) == 0)
1754c05410fSGreg Clayton         {
1764c05410fSGreg Clayton             const char *new_prompt = GetPrompt();
1774c05410fSGreg Clayton             EventSP prompt_change_event_sp (new Event(CommandInterpreter::eBroadcastBitResetPrompt, new EventDataBytes (new_prompt)));
1784c05410fSGreg Clayton             GetCommandInterpreter().BroadcastEvent (prompt_change_event_sp);
1794c05410fSGreg Clayton         }
1804c05410fSGreg Clayton     }
1814c05410fSGreg Clayton     return error;
1824c05410fSGreg Clayton }
1834c05410fSGreg Clayton 
18467cc0636SGreg Clayton bool
18567cc0636SGreg Clayton Debugger::GetAutoConfirm () const
18667cc0636SGreg Clayton {
18767cc0636SGreg Clayton     const uint32_t idx = ePropertyAutoConfirm;
188754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
18967cc0636SGreg Clayton }
19067cc0636SGreg Clayton 
19167cc0636SGreg Clayton const char *
19267cc0636SGreg Clayton Debugger::GetFrameFormat() const
19367cc0636SGreg Clayton {
19467cc0636SGreg Clayton     const uint32_t idx = ePropertyFrameFormat;
195754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsString (NULL, idx, g_properties[idx].default_cstr_value);
19667cc0636SGreg Clayton }
19767cc0636SGreg Clayton 
19867cc0636SGreg Clayton bool
19967cc0636SGreg Clayton Debugger::GetNotifyVoid () const
20067cc0636SGreg Clayton {
20167cc0636SGreg Clayton     const uint32_t idx = ePropertyNotiftVoid;
202754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
20367cc0636SGreg Clayton }
20467cc0636SGreg Clayton 
20567cc0636SGreg Clayton const char *
20667cc0636SGreg Clayton Debugger::GetPrompt() const
20767cc0636SGreg Clayton {
20867cc0636SGreg Clayton     const uint32_t idx = ePropertyPrompt;
209754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsString (NULL, idx, g_properties[idx].default_cstr_value);
21067cc0636SGreg Clayton }
21167cc0636SGreg Clayton 
21267cc0636SGreg Clayton void
21367cc0636SGreg Clayton Debugger::SetPrompt(const char *p)
21467cc0636SGreg Clayton {
21567cc0636SGreg Clayton     const uint32_t idx = ePropertyPrompt;
21667cc0636SGreg Clayton     m_collection_sp->SetPropertyAtIndexAsString (NULL, idx, p);
21767cc0636SGreg Clayton     const char *new_prompt = GetPrompt();
21867cc0636SGreg Clayton     EventSP prompt_change_event_sp (new Event(CommandInterpreter::eBroadcastBitResetPrompt, new EventDataBytes (new_prompt)));;
21967cc0636SGreg Clayton     GetCommandInterpreter().BroadcastEvent (prompt_change_event_sp);
22067cc0636SGreg Clayton }
22167cc0636SGreg Clayton 
22267cc0636SGreg Clayton const char *
22367cc0636SGreg Clayton Debugger::GetThreadFormat() const
22467cc0636SGreg Clayton {
22567cc0636SGreg Clayton     const uint32_t idx = ePropertyThreadFormat;
226754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsString (NULL, idx, g_properties[idx].default_cstr_value);
22767cc0636SGreg Clayton }
22867cc0636SGreg Clayton 
22967cc0636SGreg Clayton lldb::ScriptLanguage
23067cc0636SGreg Clayton Debugger::GetScriptLanguage() const
23167cc0636SGreg Clayton {
23267cc0636SGreg Clayton     const uint32_t idx = ePropertyScriptLanguage;
233754a9369SGreg Clayton     return (lldb::ScriptLanguage)m_collection_sp->GetPropertyAtIndexAsEnumeration (NULL, idx, g_properties[idx].default_uint_value);
23467cc0636SGreg Clayton }
23567cc0636SGreg Clayton 
23667cc0636SGreg Clayton bool
23767cc0636SGreg Clayton Debugger::SetScriptLanguage (lldb::ScriptLanguage script_lang)
23867cc0636SGreg Clayton {
23967cc0636SGreg Clayton     const uint32_t idx = ePropertyScriptLanguage;
24067cc0636SGreg Clayton     return m_collection_sp->SetPropertyAtIndexAsEnumeration (NULL, idx, script_lang);
24167cc0636SGreg Clayton }
24267cc0636SGreg Clayton 
24367cc0636SGreg Clayton uint32_t
24467cc0636SGreg Clayton Debugger::GetTerminalWidth () const
24567cc0636SGreg Clayton {
24667cc0636SGreg Clayton     const uint32_t idx = ePropertyTerminalWidth;
247754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsSInt64 (NULL, idx, g_properties[idx].default_uint_value);
24867cc0636SGreg Clayton }
24967cc0636SGreg Clayton 
25067cc0636SGreg Clayton bool
25167cc0636SGreg Clayton Debugger::SetTerminalWidth (uint32_t term_width)
25267cc0636SGreg Clayton {
25367cc0636SGreg Clayton     const uint32_t idx = ePropertyTerminalWidth;
25467cc0636SGreg Clayton     return m_collection_sp->SetPropertyAtIndexAsSInt64 (NULL, idx, term_width);
25567cc0636SGreg Clayton }
25667cc0636SGreg Clayton 
25767cc0636SGreg Clayton bool
25867cc0636SGreg Clayton Debugger::GetUseExternalEditor () const
25967cc0636SGreg Clayton {
26067cc0636SGreg Clayton     const uint32_t idx = ePropertyUseExternalEditor;
261754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
26267cc0636SGreg Clayton }
26367cc0636SGreg Clayton 
26467cc0636SGreg Clayton bool
26567cc0636SGreg Clayton Debugger::SetUseExternalEditor (bool b)
26667cc0636SGreg Clayton {
26767cc0636SGreg Clayton     const uint32_t idx = ePropertyUseExternalEditor;
26867cc0636SGreg Clayton     return m_collection_sp->SetPropertyAtIndexAsBoolean (NULL, idx, b);
26967cc0636SGreg Clayton }
27067cc0636SGreg Clayton 
27167cc0636SGreg Clayton uint32_t
27267cc0636SGreg Clayton Debugger::GetStopSourceLineCount (bool before) const
27367cc0636SGreg Clayton {
27467cc0636SGreg Clayton     const uint32_t idx = before ? ePropertyStopLineCountBefore : ePropertyStopLineCountAfter;
275754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsSInt64 (NULL, idx, g_properties[idx].default_uint_value);
27667cc0636SGreg Clayton }
27767cc0636SGreg Clayton 
27867cc0636SGreg Clayton Debugger::StopDisassemblyType
27967cc0636SGreg Clayton Debugger::GetStopDisassemblyDisplay () const
28067cc0636SGreg Clayton {
28167cc0636SGreg Clayton     const uint32_t idx = ePropertyStopDisassemblyDisplay;
282754a9369SGreg Clayton     return (Debugger::StopDisassemblyType)m_collection_sp->GetPropertyAtIndexAsEnumeration (NULL, idx, g_properties[idx].default_uint_value);
28367cc0636SGreg Clayton }
28467cc0636SGreg Clayton 
28567cc0636SGreg Clayton uint32_t
28667cc0636SGreg Clayton Debugger::GetDisassemblyLineCount () const
28767cc0636SGreg Clayton {
28867cc0636SGreg Clayton     const uint32_t idx = ePropertyStopDisassemblyCount;
289754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsSInt64 (NULL, idx, g_properties[idx].default_uint_value);
29067cc0636SGreg Clayton }
291e372b98dSGreg Clayton 
2921b654882SGreg Clayton #pragma mark Debugger
2931b654882SGreg Clayton 
29467cc0636SGreg Clayton //const DebuggerPropertiesSP &
29567cc0636SGreg Clayton //Debugger::GetSettings() const
29667cc0636SGreg Clayton //{
29767cc0636SGreg Clayton //    return m_properties_sp;
29867cc0636SGreg Clayton //}
29967cc0636SGreg Clayton //
30099d0faf2SGreg Clayton 
3012f88aadfSCaroline Tice int
3022f88aadfSCaroline Tice Debugger::TestDebuggerRefCount ()
3032f88aadfSCaroline Tice {
3042f88aadfSCaroline Tice     return g_shared_debugger_refcount;
3052f88aadfSCaroline Tice }
3062f88aadfSCaroline Tice 
30730fdc8d8SChris Lattner void
30830fdc8d8SChris Lattner Debugger::Initialize ()
30930fdc8d8SChris Lattner {
310c15f55e2SGreg Clayton     if (g_shared_debugger_refcount++ == 0)
311dbe54508SGreg Clayton         lldb_private::Initialize();
31299d0faf2SGreg Clayton }
31330fdc8d8SChris Lattner 
31430fdc8d8SChris Lattner void
31530fdc8d8SChris Lattner Debugger::Terminate ()
31630fdc8d8SChris Lattner {
3176611103cSGreg Clayton     if (g_shared_debugger_refcount > 0)
3186611103cSGreg Clayton     {
31930fdc8d8SChris Lattner         g_shared_debugger_refcount--;
32030fdc8d8SChris Lattner         if (g_shared_debugger_refcount == 0)
32130fdc8d8SChris Lattner         {
322dbe54508SGreg Clayton             lldb_private::WillTerminate();
323dbe54508SGreg Clayton             lldb_private::Terminate();
3246760a517SCaroline Tice 
32599d0faf2SGreg Clayton             // Clear our master list of debugger objects
32699d0faf2SGreg Clayton             Mutex::Locker locker (GetDebuggerListMutex ());
32799d0faf2SGreg Clayton             GetDebuggerList().clear();
32830fdc8d8SChris Lattner         }
3296760a517SCaroline Tice     }
3306760a517SCaroline Tice }
33130fdc8d8SChris Lattner 
33220bd37f7SCaroline Tice void
33320bd37f7SCaroline Tice Debugger::SettingsInitialize ()
33420bd37f7SCaroline Tice {
3356920b52bSGreg Clayton     Target::SettingsInitialize ();
33620bd37f7SCaroline Tice }
33720bd37f7SCaroline Tice 
33820bd37f7SCaroline Tice void
33920bd37f7SCaroline Tice Debugger::SettingsTerminate ()
34020bd37f7SCaroline Tice {
3416920b52bSGreg Clayton     Target::SettingsTerminate ();
34220bd37f7SCaroline Tice }
34320bd37f7SCaroline Tice 
34421dfcd9dSEnrico Granata bool
34521dfcd9dSEnrico Granata Debugger::LoadPlugin (const FileSpec& spec)
34621dfcd9dSEnrico Granata {
34721dfcd9dSEnrico Granata     lldb::DynamicLibrarySP dynlib_sp(new lldb_private::DynamicLibrary(spec));
34821dfcd9dSEnrico Granata     lldb::DebuggerSP debugger_sp(shared_from_this());
34921dfcd9dSEnrico Granata     lldb::SBDebugger debugger_sb(debugger_sp);
35021dfcd9dSEnrico Granata     // TODO: mangle this differently for your system - on OSX, the first underscore needs to be removed and the second one stays
35121dfcd9dSEnrico Granata     LLDBCommandPluginInit init_func = dynlib_sp->GetSymbol<LLDBCommandPluginInit>("_ZN4lldb16PluginInitializeENS_10SBDebuggerE");
35221dfcd9dSEnrico Granata     if (!init_func)
35321dfcd9dSEnrico Granata         return false;
35421dfcd9dSEnrico Granata     if (init_func(debugger_sb))
35521dfcd9dSEnrico Granata     {
35621dfcd9dSEnrico Granata         m_loaded_plugins.push_back(dynlib_sp);
35721dfcd9dSEnrico Granata         return true;
35821dfcd9dSEnrico Granata     }
35921dfcd9dSEnrico Granata     return false;
36021dfcd9dSEnrico Granata }
36121dfcd9dSEnrico Granata 
36221dfcd9dSEnrico Granata static FileSpec::EnumerateDirectoryResult
36321dfcd9dSEnrico Granata LoadPluginCallback
36421dfcd9dSEnrico Granata (
36521dfcd9dSEnrico Granata  void *baton,
36621dfcd9dSEnrico Granata  FileSpec::FileType file_type,
36721dfcd9dSEnrico Granata  const FileSpec &file_spec
36821dfcd9dSEnrico Granata  )
36921dfcd9dSEnrico Granata {
37021dfcd9dSEnrico Granata     Error error;
37121dfcd9dSEnrico Granata 
37221dfcd9dSEnrico Granata     static ConstString g_dylibext("dylib");
37321dfcd9dSEnrico Granata 
37421dfcd9dSEnrico Granata     if (!baton)
37521dfcd9dSEnrico Granata         return FileSpec::eEnumerateDirectoryResultQuit;
37621dfcd9dSEnrico Granata 
37721dfcd9dSEnrico Granata     Debugger *debugger = (Debugger*)baton;
37821dfcd9dSEnrico Granata 
37921dfcd9dSEnrico Granata     // If we have a regular file, a symbolic link or unknown file type, try
38021dfcd9dSEnrico Granata     // and process the file. We must handle unknown as sometimes the directory
38121dfcd9dSEnrico Granata     // enumeration might be enumerating a file system that doesn't have correct
38221dfcd9dSEnrico Granata     // file type information.
38321dfcd9dSEnrico Granata     if (file_type == FileSpec::eFileTypeRegular         ||
38421dfcd9dSEnrico Granata         file_type == FileSpec::eFileTypeSymbolicLink    ||
38521dfcd9dSEnrico Granata         file_type == FileSpec::eFileTypeUnknown          )
38621dfcd9dSEnrico Granata     {
38721dfcd9dSEnrico Granata         FileSpec plugin_file_spec (file_spec);
38821dfcd9dSEnrico Granata         plugin_file_spec.ResolvePath ();
38921dfcd9dSEnrico Granata 
39021dfcd9dSEnrico Granata         if (plugin_file_spec.GetFileNameExtension() != g_dylibext)
39121dfcd9dSEnrico Granata             return FileSpec::eEnumerateDirectoryResultNext;
39221dfcd9dSEnrico Granata 
39321dfcd9dSEnrico Granata         debugger->LoadPlugin (plugin_file_spec);
39421dfcd9dSEnrico Granata 
39521dfcd9dSEnrico Granata         return FileSpec::eEnumerateDirectoryResultNext;
39621dfcd9dSEnrico Granata     }
39721dfcd9dSEnrico Granata 
39821dfcd9dSEnrico Granata     else if (file_type == FileSpec::eFileTypeUnknown     ||
39921dfcd9dSEnrico Granata         file_type == FileSpec::eFileTypeDirectory   ||
40021dfcd9dSEnrico Granata         file_type == FileSpec::eFileTypeSymbolicLink )
40121dfcd9dSEnrico Granata     {
40221dfcd9dSEnrico Granata         // Try and recurse into anything that a directory or symbolic link.
40321dfcd9dSEnrico Granata         // We must also do this for unknown as sometimes the directory enumeration
40421dfcd9dSEnrico Granata         // might be enurating a file system that doesn't have correct file type
40521dfcd9dSEnrico Granata         // information.
40621dfcd9dSEnrico Granata         return FileSpec::eEnumerateDirectoryResultEnter;
40721dfcd9dSEnrico Granata     }
40821dfcd9dSEnrico Granata 
40921dfcd9dSEnrico Granata     return FileSpec::eEnumerateDirectoryResultNext;
41021dfcd9dSEnrico Granata }
41121dfcd9dSEnrico Granata 
41221dfcd9dSEnrico Granata void
41321dfcd9dSEnrico Granata Debugger::InstanceInitialize ()
41421dfcd9dSEnrico Granata {
41521dfcd9dSEnrico Granata     FileSpec dir_spec;
41621dfcd9dSEnrico Granata     const bool find_directories = true;
41721dfcd9dSEnrico Granata     const bool find_files = true;
41821dfcd9dSEnrico Granata     const bool find_other = true;
41921dfcd9dSEnrico Granata     char dir_path[PATH_MAX];
42021dfcd9dSEnrico Granata     if (Host::GetLLDBPath (ePathTypeLLDBSystemPlugins, dir_spec))
42121dfcd9dSEnrico Granata     {
42221dfcd9dSEnrico Granata         if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path)))
42321dfcd9dSEnrico Granata         {
42421dfcd9dSEnrico Granata             FileSpec::EnumerateDirectory (dir_path,
42521dfcd9dSEnrico Granata                                           find_directories,
42621dfcd9dSEnrico Granata                                           find_files,
42721dfcd9dSEnrico Granata                                           find_other,
42821dfcd9dSEnrico Granata                                           LoadPluginCallback,
42921dfcd9dSEnrico Granata                                           this);
43021dfcd9dSEnrico Granata         }
43121dfcd9dSEnrico Granata     }
43221dfcd9dSEnrico Granata 
43321dfcd9dSEnrico Granata     if (Host::GetLLDBPath (ePathTypeLLDBUserPlugins, dir_spec))
43421dfcd9dSEnrico Granata     {
43521dfcd9dSEnrico Granata         if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path)))
43621dfcd9dSEnrico Granata         {
43721dfcd9dSEnrico Granata             FileSpec::EnumerateDirectory (dir_path,
43821dfcd9dSEnrico Granata                                           find_directories,
43921dfcd9dSEnrico Granata                                           find_files,
44021dfcd9dSEnrico Granata                                           find_other,
44121dfcd9dSEnrico Granata                                           LoadPluginCallback,
44221dfcd9dSEnrico Granata                                           this);
44321dfcd9dSEnrico Granata         }
44421dfcd9dSEnrico Granata     }
445e8cd0c98SGreg Clayton 
446e8cd0c98SGreg Clayton     PluginManager::DebuggerInitialize (*this);
44721dfcd9dSEnrico Granata }
44821dfcd9dSEnrico Granata 
4496611103cSGreg Clayton DebuggerSP
450228063cdSJim Ingham Debugger::CreateInstance (lldb::LogOutputCallback log_callback, void *baton)
4516611103cSGreg Clayton {
452228063cdSJim Ingham     DebuggerSP debugger_sp (new Debugger(log_callback, baton));
453c15f55e2SGreg Clayton     if (g_shared_debugger_refcount > 0)
4546611103cSGreg Clayton     {
4556611103cSGreg Clayton         Mutex::Locker locker (GetDebuggerListMutex ());
4566611103cSGreg Clayton         GetDebuggerList().push_back(debugger_sp);
4576611103cSGreg Clayton     }
45821dfcd9dSEnrico Granata     debugger_sp->InstanceInitialize ();
4596611103cSGreg Clayton     return debugger_sp;
4606611103cSGreg Clayton }
4616611103cSGreg Clayton 
462e02657b1SCaroline Tice void
4634d122c40SGreg Clayton Debugger::Destroy (DebuggerSP &debugger_sp)
464e02657b1SCaroline Tice {
465e02657b1SCaroline Tice     if (debugger_sp.get() == NULL)
466e02657b1SCaroline Tice         return;
467e02657b1SCaroline Tice 
4688314c525SJim Ingham     debugger_sp->Clear();
4698314c525SJim Ingham 
470c15f55e2SGreg Clayton     if (g_shared_debugger_refcount > 0)
471c15f55e2SGreg Clayton     {
472e02657b1SCaroline Tice         Mutex::Locker locker (GetDebuggerListMutex ());
473e02657b1SCaroline Tice         DebuggerList &debugger_list = GetDebuggerList ();
474e02657b1SCaroline Tice         DebuggerList::iterator pos, end = debugger_list.end();
475e02657b1SCaroline Tice         for (pos = debugger_list.begin (); pos != end; ++pos)
476e02657b1SCaroline Tice         {
477e02657b1SCaroline Tice             if ((*pos).get() == debugger_sp.get())
478e02657b1SCaroline Tice             {
479e02657b1SCaroline Tice                 debugger_list.erase (pos);
480e02657b1SCaroline Tice                 return;
481e02657b1SCaroline Tice             }
482e02657b1SCaroline Tice         }
483e02657b1SCaroline Tice     }
484c15f55e2SGreg Clayton }
485e02657b1SCaroline Tice 
4864d122c40SGreg Clayton DebuggerSP
4873df9a8dfSCaroline Tice Debugger::FindDebuggerWithInstanceName (const ConstString &instance_name)
4883df9a8dfSCaroline Tice {
4894d122c40SGreg Clayton     DebuggerSP debugger_sp;
4906920b52bSGreg Clayton     if (g_shared_debugger_refcount > 0)
4916920b52bSGreg Clayton     {
4926920b52bSGreg Clayton         Mutex::Locker locker (GetDebuggerListMutex ());
4936920b52bSGreg Clayton         DebuggerList &debugger_list = GetDebuggerList();
4946920b52bSGreg Clayton         DebuggerList::iterator pos, end = debugger_list.end();
4956920b52bSGreg Clayton 
4966920b52bSGreg Clayton         for (pos = debugger_list.begin(); pos != end; ++pos)
4976920b52bSGreg Clayton         {
4986920b52bSGreg Clayton             if ((*pos).get()->m_instance_name == instance_name)
4996920b52bSGreg Clayton             {
5006920b52bSGreg Clayton                 debugger_sp = *pos;
5016920b52bSGreg Clayton                 break;
5026920b52bSGreg Clayton             }
5036920b52bSGreg Clayton         }
5046920b52bSGreg Clayton     }
5053df9a8dfSCaroline Tice     return debugger_sp;
5063df9a8dfSCaroline Tice }
5076611103cSGreg Clayton 
5086611103cSGreg Clayton TargetSP
5096611103cSGreg Clayton Debugger::FindTargetWithProcessID (lldb::pid_t pid)
5106611103cSGreg Clayton {
5114d122c40SGreg Clayton     TargetSP target_sp;
512c15f55e2SGreg Clayton     if (g_shared_debugger_refcount > 0)
513c15f55e2SGreg Clayton     {
5146611103cSGreg Clayton         Mutex::Locker locker (GetDebuggerListMutex ());
5156611103cSGreg Clayton         DebuggerList &debugger_list = GetDebuggerList();
5166611103cSGreg Clayton         DebuggerList::iterator pos, end = debugger_list.end();
5176611103cSGreg Clayton         for (pos = debugger_list.begin(); pos != end; ++pos)
5186611103cSGreg Clayton         {
5196611103cSGreg Clayton             target_sp = (*pos)->GetTargetList().FindTargetWithProcessID (pid);
5206611103cSGreg Clayton             if (target_sp)
5216611103cSGreg Clayton                 break;
5226611103cSGreg Clayton         }
523c15f55e2SGreg Clayton     }
5246611103cSGreg Clayton     return target_sp;
5256611103cSGreg Clayton }
5266611103cSGreg Clayton 
527e4e45924SGreg Clayton TargetSP
528e4e45924SGreg Clayton Debugger::FindTargetWithProcess (Process *process)
529e4e45924SGreg Clayton {
530e4e45924SGreg Clayton     TargetSP target_sp;
531c15f55e2SGreg Clayton     if (g_shared_debugger_refcount > 0)
532c15f55e2SGreg Clayton     {
533e4e45924SGreg Clayton         Mutex::Locker locker (GetDebuggerListMutex ());
534e4e45924SGreg Clayton         DebuggerList &debugger_list = GetDebuggerList();
535e4e45924SGreg Clayton         DebuggerList::iterator pos, end = debugger_list.end();
536e4e45924SGreg Clayton         for (pos = debugger_list.begin(); pos != end; ++pos)
537e4e45924SGreg Clayton         {
538e4e45924SGreg Clayton             target_sp = (*pos)->GetTargetList().FindTargetWithProcess (process);
539e4e45924SGreg Clayton             if (target_sp)
540e4e45924SGreg Clayton                 break;
541e4e45924SGreg Clayton         }
542c15f55e2SGreg Clayton     }
543e4e45924SGreg Clayton     return target_sp;
544e4e45924SGreg Clayton }
545e4e45924SGreg Clayton 
546228063cdSJim Ingham Debugger::Debugger (lldb::LogOutputCallback log_callback, void *baton) :
547ebc1bb27SCaroline Tice     UserID (g_unique_id++),
54867cc0636SGreg Clayton     Properties(OptionValuePropertiesSP(new OptionValueProperties())),
549d46c87a1SGreg Clayton     m_input_comm("debugger.input"),
55030fdc8d8SChris Lattner     m_input_file (),
55130fdc8d8SChris Lattner     m_output_file (),
55230fdc8d8SChris Lattner     m_error_file (),
553c5917d9aSJim Ingham     m_terminal_state (),
5544bddaeb5SJim Ingham     m_target_list (*this),
555ded470d3SGreg Clayton     m_platform_list (),
55630fdc8d8SChris Lattner     m_listener ("lldb.Debugger"),
557e37d605eSJim Ingham     m_source_manager(*this),
558e37d605eSJim Ingham     m_source_file_cache(),
5596611103cSGreg Clayton     m_command_interpreter_ap (new CommandInterpreter (*this, eScriptLanguageDefault, false)),
560d5a0a01bSCaroline Tice     m_input_reader_stack (),
56167cc0636SGreg Clayton     m_input_reader_data (),
56267cc0636SGreg Clayton     m_instance_name()
56330fdc8d8SChris Lattner {
56467cc0636SGreg Clayton     char instance_cstr[256];
56567cc0636SGreg Clayton     snprintf(instance_cstr, sizeof(instance_cstr), "debugger_%d", (int)GetID());
56667cc0636SGreg Clayton     m_instance_name.SetCString(instance_cstr);
567228063cdSJim Ingham     if (log_callback)
568228063cdSJim Ingham         m_log_callback_stream_sp.reset (new StreamCallback (log_callback, baton));
5696611103cSGreg Clayton     m_command_interpreter_ap->Initialize ();
570ded470d3SGreg Clayton     // Always add our default platform to the platform list
571ded470d3SGreg Clayton     PlatformSP default_platform_sp (Platform::GetDefaultPlatform());
572ded470d3SGreg Clayton     assert (default_platform_sp.get());
573ded470d3SGreg Clayton     m_platform_list.Append (default_platform_sp, true);
57467cc0636SGreg Clayton 
575754a9369SGreg Clayton     m_collection_sp->Initialize (g_properties);
57667cc0636SGreg Clayton     m_collection_sp->AppendProperty (ConstString("target"),
57767cc0636SGreg Clayton                                      ConstString("Settings specify to debugging targets."),
57867cc0636SGreg Clayton                                      true,
57967cc0636SGreg Clayton                                      Target::GetGlobalProperties()->GetValueProperties());
580754a9369SGreg Clayton     if (m_command_interpreter_ap.get())
581754a9369SGreg Clayton     {
582754a9369SGreg Clayton         m_collection_sp->AppendProperty (ConstString("interpreter"),
583754a9369SGreg Clayton                                          ConstString("Settings specify to the debugger's command interpreter."),
584754a9369SGreg Clayton                                          true,
585754a9369SGreg Clayton                                          m_command_interpreter_ap->GetValueProperties());
586754a9369SGreg Clayton     }
58767cc0636SGreg Clayton     OptionValueSInt64 *term_width = m_collection_sp->GetPropertyAtIndexAsOptionValueSInt64 (NULL, ePropertyTerminalWidth);
58867cc0636SGreg Clayton     term_width->SetMinimumValue(10);
58967cc0636SGreg Clayton     term_width->SetMaximumValue(1024);
59030fdc8d8SChris Lattner }
59130fdc8d8SChris Lattner 
59230fdc8d8SChris Lattner Debugger::~Debugger ()
59330fdc8d8SChris Lattner {
5948314c525SJim Ingham     Clear();
5958314c525SJim Ingham }
5968314c525SJim Ingham 
5978314c525SJim Ingham void
5988314c525SJim Ingham Debugger::Clear()
5998314c525SJim Ingham {
6003d6086f6SCaroline Tice     CleanUpInputReaders();
6011ed54f50SGreg Clayton     m_listener.Clear();
6026611103cSGreg Clayton     int num_targets = m_target_list.GetNumTargets();
6036611103cSGreg Clayton     for (int i = 0; i < num_targets; i++)
6046611103cSGreg Clayton     {
605ccbc08e6SGreg Clayton         TargetSP target_sp (m_target_list.GetTargetAtIndex (i));
606ccbc08e6SGreg Clayton         if (target_sp)
607ccbc08e6SGreg Clayton         {
608ccbc08e6SGreg Clayton             ProcessSP process_sp (target_sp->GetProcessSP());
6096611103cSGreg Clayton             if (process_sp)
6108314c525SJim Ingham             {
611e24c4acfSGreg Clayton                 if (process_sp->GetShouldDetach())
6128314c525SJim Ingham                     process_sp->Detach();
613ccbc08e6SGreg Clayton             }
614ccbc08e6SGreg Clayton             target_sp->Destroy();
6156611103cSGreg Clayton         }
61630fdc8d8SChris Lattner     }
6174bddaeb5SJim Ingham     BroadcasterManager::Clear ();
61830fdc8d8SChris Lattner 
6190d69a3a4SGreg Clayton     // Close the input file _before_ we close the input read communications class
6200d69a3a4SGreg Clayton     // as it does NOT own the input file, our m_input_file does.
621c5917d9aSJim Ingham     m_terminal_state.Clear();
6220d69a3a4SGreg Clayton     GetInputFile().Close ();
6230d69a3a4SGreg Clayton     // Now that we have closed m_input_file, we can now tell our input communication
6240d69a3a4SGreg Clayton     // class to close down. Its read thread should quickly exit after we close
6250d69a3a4SGreg Clayton     // the input file handle above.
6260d69a3a4SGreg Clayton     m_input_comm.Clear ();
6278314c525SJim Ingham }
62830fdc8d8SChris Lattner 
62930fdc8d8SChris Lattner bool
630fc3f027dSGreg Clayton Debugger::GetCloseInputOnEOF () const
631fc3f027dSGreg Clayton {
632fc3f027dSGreg Clayton     return m_input_comm.GetCloseOnEOF();
633fc3f027dSGreg Clayton }
634fc3f027dSGreg Clayton 
635fc3f027dSGreg Clayton void
636fc3f027dSGreg Clayton Debugger::SetCloseInputOnEOF (bool b)
637fc3f027dSGreg Clayton {
638fc3f027dSGreg Clayton     m_input_comm.SetCloseOnEOF(b);
639fc3f027dSGreg Clayton }
640fc3f027dSGreg Clayton 
641fc3f027dSGreg Clayton bool
64230fdc8d8SChris Lattner Debugger::GetAsyncExecution ()
64330fdc8d8SChris Lattner {
6446611103cSGreg Clayton     return !m_command_interpreter_ap->GetSynchronous();
64530fdc8d8SChris Lattner }
64630fdc8d8SChris Lattner 
64730fdc8d8SChris Lattner void
64830fdc8d8SChris Lattner Debugger::SetAsyncExecution (bool async_execution)
64930fdc8d8SChris Lattner {
6506611103cSGreg Clayton     m_command_interpreter_ap->SetSynchronous (!async_execution);
65130fdc8d8SChris Lattner }
65230fdc8d8SChris Lattner 
65330fdc8d8SChris Lattner 
65430fdc8d8SChris Lattner void
65530fdc8d8SChris Lattner Debugger::SetInputFileHandle (FILE *fh, bool tranfer_ownership)
65630fdc8d8SChris Lattner {
65751b1e2d2SGreg Clayton     File &in_file = GetInputFile();
65851b1e2d2SGreg Clayton     in_file.SetStream (fh, tranfer_ownership);
65951b1e2d2SGreg Clayton     if (in_file.IsValid() == false)
66051b1e2d2SGreg Clayton         in_file.SetStream (stdin, true);
66130fdc8d8SChris Lattner 
66230fdc8d8SChris Lattner     // Disconnect from any old connection if we had one
66330fdc8d8SChris Lattner     m_input_comm.Disconnect ();
66432720b51SGreg Clayton     // Pass false as the second argument to ConnectionFileDescriptor below because
66532720b51SGreg Clayton     // our "in_file" above will already take ownership if requested and we don't
66632720b51SGreg Clayton     // want to objects trying to own and close a file descriptor.
66732720b51SGreg Clayton     m_input_comm.SetConnection (new ConnectionFileDescriptor (in_file.GetDescriptor(), false));
66830fdc8d8SChris Lattner     m_input_comm.SetReadThreadBytesReceivedCallback (Debugger::DispatchInputCallback, this);
66930fdc8d8SChris Lattner 
670c5917d9aSJim Ingham     // Save away the terminal state if that is relevant, so that we can restore it in RestoreInputState.
671c5917d9aSJim Ingham     SaveInputTerminalState ();
672c5917d9aSJim Ingham 
67330fdc8d8SChris Lattner     Error error;
67430fdc8d8SChris Lattner     if (m_input_comm.StartReadThread (&error) == false)
67530fdc8d8SChris Lattner     {
67651b1e2d2SGreg Clayton         File &err_file = GetErrorFile();
67751b1e2d2SGreg Clayton 
67851b1e2d2SGreg Clayton         err_file.Printf ("error: failed to main input read thread: %s", error.AsCString() ? error.AsCString() : "unkown error");
67930fdc8d8SChris Lattner         exit(1);
68030fdc8d8SChris Lattner     }
68130fdc8d8SChris Lattner }
68230fdc8d8SChris Lattner 
68330fdc8d8SChris Lattner void
68430fdc8d8SChris Lattner Debugger::SetOutputFileHandle (FILE *fh, bool tranfer_ownership)
68530fdc8d8SChris Lattner {
68651b1e2d2SGreg Clayton     File &out_file = GetOutputFile();
68751b1e2d2SGreg Clayton     out_file.SetStream (fh, tranfer_ownership);
68851b1e2d2SGreg Clayton     if (out_file.IsValid() == false)
68951b1e2d2SGreg Clayton         out_file.SetStream (stdout, false);
6902f88aadfSCaroline Tice 
691b588726eSEnrico Granata     // do not create the ScriptInterpreter just for setting the output file handle
692b588726eSEnrico Granata     // as the constructor will know how to do the right thing on its own
693b588726eSEnrico Granata     const bool can_create = false;
694b588726eSEnrico Granata     ScriptInterpreter* script_interpreter = GetCommandInterpreter().GetScriptInterpreter(can_create);
695b588726eSEnrico Granata     if (script_interpreter)
696b588726eSEnrico Granata         script_interpreter->ResetOutputFileHandle (fh);
69730fdc8d8SChris Lattner }
69830fdc8d8SChris Lattner 
69930fdc8d8SChris Lattner void
70030fdc8d8SChris Lattner Debugger::SetErrorFileHandle (FILE *fh, bool tranfer_ownership)
70130fdc8d8SChris Lattner {
70251b1e2d2SGreg Clayton     File &err_file = GetErrorFile();
70351b1e2d2SGreg Clayton     err_file.SetStream (fh, tranfer_ownership);
70451b1e2d2SGreg Clayton     if (err_file.IsValid() == false)
70551b1e2d2SGreg Clayton         err_file.SetStream (stderr, false);
70630fdc8d8SChris Lattner }
70730fdc8d8SChris Lattner 
708c5917d9aSJim Ingham void
709c5917d9aSJim Ingham Debugger::SaveInputTerminalState ()
710c5917d9aSJim Ingham {
711c5917d9aSJim Ingham     File &in_file = GetInputFile();
712c5917d9aSJim Ingham     if (in_file.GetDescriptor() != File::kInvalidDescriptor)
713c5917d9aSJim Ingham         m_terminal_state.Save(in_file.GetDescriptor(), true);
714c5917d9aSJim Ingham }
715c5917d9aSJim Ingham 
716c5917d9aSJim Ingham void
717c5917d9aSJim Ingham Debugger::RestoreInputTerminalState ()
718c5917d9aSJim Ingham {
719c5917d9aSJim Ingham     m_terminal_state.Restore();
720c5917d9aSJim Ingham }
721c5917d9aSJim Ingham 
72230fdc8d8SChris Lattner ExecutionContext
7232976d00aSJim Ingham Debugger::GetSelectedExecutionContext ()
72430fdc8d8SChris Lattner {
72530fdc8d8SChris Lattner     ExecutionContext exe_ctx;
726c14ee32dSGreg Clayton     TargetSP target_sp(GetSelectedTarget());
727c14ee32dSGreg Clayton     exe_ctx.SetTargetSP (target_sp);
72830fdc8d8SChris Lattner 
72930fdc8d8SChris Lattner     if (target_sp)
73030fdc8d8SChris Lattner     {
731c14ee32dSGreg Clayton         ProcessSP process_sp (target_sp->GetProcessSP());
732c14ee32dSGreg Clayton         exe_ctx.SetProcessSP (process_sp);
733c14ee32dSGreg Clayton         if (process_sp && process_sp->IsRunning() == false)
73430fdc8d8SChris Lattner         {
735c14ee32dSGreg Clayton             ThreadSP thread_sp (process_sp->GetThreadList().GetSelectedThread());
736c14ee32dSGreg Clayton             if (thread_sp)
73730fdc8d8SChris Lattner             {
738c14ee32dSGreg Clayton                 exe_ctx.SetThreadSP (thread_sp);
739c14ee32dSGreg Clayton                 exe_ctx.SetFrameSP (thread_sp->GetSelectedFrame());
740c14ee32dSGreg Clayton                 if (exe_ctx.GetFramePtr() == NULL)
741c14ee32dSGreg Clayton                     exe_ctx.SetFrameSP (thread_sp->GetStackFrameAtIndex (0));
74230fdc8d8SChris Lattner             }
74330fdc8d8SChris Lattner         }
74430fdc8d8SChris Lattner     }
74530fdc8d8SChris Lattner     return exe_ctx;
74630fdc8d8SChris Lattner 
74730fdc8d8SChris Lattner }
74830fdc8d8SChris Lattner 
749b44880caSCaroline Tice InputReaderSP
750b44880caSCaroline Tice Debugger::GetCurrentInputReader ()
751b44880caSCaroline Tice {
752b44880caSCaroline Tice     InputReaderSP reader_sp;
753b44880caSCaroline Tice 
754d5a0a01bSCaroline Tice     if (!m_input_reader_stack.IsEmpty())
755b44880caSCaroline Tice     {
756b44880caSCaroline Tice         // Clear any finished readers from the stack
757b44880caSCaroline Tice         while (CheckIfTopInputReaderIsDone()) ;
758b44880caSCaroline Tice 
759d5a0a01bSCaroline Tice         if (!m_input_reader_stack.IsEmpty())
760d5a0a01bSCaroline Tice             reader_sp = m_input_reader_stack.Top();
761b44880caSCaroline Tice     }
762b44880caSCaroline Tice 
763b44880caSCaroline Tice     return reader_sp;
764b44880caSCaroline Tice }
765b44880caSCaroline Tice 
76630fdc8d8SChris Lattner void
76730fdc8d8SChris Lattner Debugger::DispatchInputCallback (void *baton, const void *bytes, size_t bytes_len)
76830fdc8d8SChris Lattner {
769efed6131SCaroline Tice     if (bytes_len > 0)
77030fdc8d8SChris Lattner         ((Debugger *)baton)->DispatchInput ((char *)bytes, bytes_len);
771efed6131SCaroline Tice     else
772efed6131SCaroline Tice         ((Debugger *)baton)->DispatchInputEndOfFile ();
77330fdc8d8SChris Lattner }
77430fdc8d8SChris Lattner 
77530fdc8d8SChris Lattner 
77630fdc8d8SChris Lattner void
77730fdc8d8SChris Lattner Debugger::DispatchInput (const char *bytes, size_t bytes_len)
77830fdc8d8SChris Lattner {
779efed6131SCaroline Tice     if (bytes == NULL || bytes_len == 0)
780efed6131SCaroline Tice         return;
78130fdc8d8SChris Lattner 
78230fdc8d8SChris Lattner     WriteToDefaultReader (bytes, bytes_len);
78330fdc8d8SChris Lattner }
78430fdc8d8SChris Lattner 
78530fdc8d8SChris Lattner void
786efed6131SCaroline Tice Debugger::DispatchInputInterrupt ()
787efed6131SCaroline Tice {
788efed6131SCaroline Tice     m_input_reader_data.clear();
789efed6131SCaroline Tice 
790b44880caSCaroline Tice     InputReaderSP reader_sp (GetCurrentInputReader ());
791efed6131SCaroline Tice     if (reader_sp)
792b44880caSCaroline Tice     {
793efed6131SCaroline Tice         reader_sp->Notify (eInputReaderInterrupt);
794efed6131SCaroline Tice 
795b44880caSCaroline Tice         // If notifying the reader of the interrupt finished the reader, we should pop it off the stack.
796efed6131SCaroline Tice         while (CheckIfTopInputReaderIsDone ()) ;
797efed6131SCaroline Tice     }
798efed6131SCaroline Tice }
799efed6131SCaroline Tice 
800efed6131SCaroline Tice void
801efed6131SCaroline Tice Debugger::DispatchInputEndOfFile ()
802efed6131SCaroline Tice {
803efed6131SCaroline Tice     m_input_reader_data.clear();
804efed6131SCaroline Tice 
805b44880caSCaroline Tice     InputReaderSP reader_sp (GetCurrentInputReader ());
806efed6131SCaroline Tice     if (reader_sp)
807b44880caSCaroline Tice     {
808efed6131SCaroline Tice         reader_sp->Notify (eInputReaderEndOfFile);
809efed6131SCaroline Tice 
810b44880caSCaroline Tice         // If notifying the reader of the end-of-file finished the reader, we should pop it off the stack.
811efed6131SCaroline Tice         while (CheckIfTopInputReaderIsDone ()) ;
812efed6131SCaroline Tice     }
813efed6131SCaroline Tice }
814efed6131SCaroline Tice 
815efed6131SCaroline Tice void
8163d6086f6SCaroline Tice Debugger::CleanUpInputReaders ()
8173d6086f6SCaroline Tice {
8183d6086f6SCaroline Tice     m_input_reader_data.clear();
8193d6086f6SCaroline Tice 
820b44880caSCaroline Tice     // The bottom input reader should be the main debugger input reader.  We do not want to close that one here.
821d5a0a01bSCaroline Tice     while (m_input_reader_stack.GetSize() > 1)
8223d6086f6SCaroline Tice     {
823b44880caSCaroline Tice         InputReaderSP reader_sp (GetCurrentInputReader ());
8243d6086f6SCaroline Tice         if (reader_sp)
8253d6086f6SCaroline Tice         {
8263d6086f6SCaroline Tice             reader_sp->Notify (eInputReaderEndOfFile);
8273d6086f6SCaroline Tice             reader_sp->SetIsDone (true);
8283d6086f6SCaroline Tice         }
8293d6086f6SCaroline Tice     }
8303d6086f6SCaroline Tice }
8313d6086f6SCaroline Tice 
8323d6086f6SCaroline Tice void
833969ed3d1SCaroline Tice Debugger::NotifyTopInputReader (InputReaderAction notification)
834969ed3d1SCaroline Tice {
835969ed3d1SCaroline Tice     InputReaderSP reader_sp (GetCurrentInputReader());
836969ed3d1SCaroline Tice     if (reader_sp)
837969ed3d1SCaroline Tice 	{
838969ed3d1SCaroline Tice         reader_sp->Notify (notification);
839969ed3d1SCaroline Tice 
840969ed3d1SCaroline Tice         // Flush out any input readers that are done.
841969ed3d1SCaroline Tice         while (CheckIfTopInputReaderIsDone ())
842969ed3d1SCaroline Tice             /* Do nothing. */;
843969ed3d1SCaroline Tice     }
844969ed3d1SCaroline Tice }
845969ed3d1SCaroline Tice 
8469088b068SCaroline Tice bool
8474d122c40SGreg Clayton Debugger::InputReaderIsTopReader (const InputReaderSP& reader_sp)
8489088b068SCaroline Tice {
8499088b068SCaroline Tice     InputReaderSP top_reader_sp (GetCurrentInputReader());
8509088b068SCaroline Tice 
851d61c10bcSCaroline Tice     return (reader_sp.get() == top_reader_sp.get());
8529088b068SCaroline Tice }
8539088b068SCaroline Tice 
8549088b068SCaroline Tice 
855969ed3d1SCaroline Tice void
85630fdc8d8SChris Lattner Debugger::WriteToDefaultReader (const char *bytes, size_t bytes_len)
85730fdc8d8SChris Lattner {
85830fdc8d8SChris Lattner     if (bytes && bytes_len)
85930fdc8d8SChris Lattner         m_input_reader_data.append (bytes, bytes_len);
86030fdc8d8SChris Lattner 
86130fdc8d8SChris Lattner     if (m_input_reader_data.empty())
86230fdc8d8SChris Lattner         return;
86330fdc8d8SChris Lattner 
864d5a0a01bSCaroline Tice     while (!m_input_reader_stack.IsEmpty() && !m_input_reader_data.empty())
86530fdc8d8SChris Lattner     {
86630fdc8d8SChris Lattner         // Get the input reader from the top of the stack
867b44880caSCaroline Tice         InputReaderSP reader_sp (GetCurrentInputReader ());
86830fdc8d8SChris Lattner         if (!reader_sp)
86930fdc8d8SChris Lattner             break;
87030fdc8d8SChris Lattner 
871471b31ceSGreg Clayton         size_t bytes_handled = reader_sp->HandleRawBytes (m_input_reader_data.c_str(),
87230fdc8d8SChris Lattner                                                           m_input_reader_data.size());
87330fdc8d8SChris Lattner         if (bytes_handled)
87430fdc8d8SChris Lattner         {
87530fdc8d8SChris Lattner             m_input_reader_data.erase (0, bytes_handled);
87630fdc8d8SChris Lattner         }
87730fdc8d8SChris Lattner         else
87830fdc8d8SChris Lattner         {
87930fdc8d8SChris Lattner             // No bytes were handled, we might not have reached our
88030fdc8d8SChris Lattner             // granularity, just return and wait for more data
88130fdc8d8SChris Lattner             break;
88230fdc8d8SChris Lattner         }
88330fdc8d8SChris Lattner     }
88430fdc8d8SChris Lattner 
885b44880caSCaroline Tice     // Flush out any input readers that are done.
88630fdc8d8SChris Lattner     while (CheckIfTopInputReaderIsDone ())
88730fdc8d8SChris Lattner         /* Do nothing. */;
88830fdc8d8SChris Lattner 
88930fdc8d8SChris Lattner }
89030fdc8d8SChris Lattner 
89130fdc8d8SChris Lattner void
89230fdc8d8SChris Lattner Debugger::PushInputReader (const InputReaderSP& reader_sp)
89330fdc8d8SChris Lattner {
89430fdc8d8SChris Lattner     if (!reader_sp)
89530fdc8d8SChris Lattner         return;
896b44880caSCaroline Tice 
89730fdc8d8SChris Lattner     // Deactivate the old top reader
898b44880caSCaroline Tice     InputReaderSP top_reader_sp (GetCurrentInputReader ());
899b44880caSCaroline Tice 
90030fdc8d8SChris Lattner     if (top_reader_sp)
90130fdc8d8SChris Lattner         top_reader_sp->Notify (eInputReaderDeactivate);
902b44880caSCaroline Tice 
903d5a0a01bSCaroline Tice     m_input_reader_stack.Push (reader_sp);
90430fdc8d8SChris Lattner     reader_sp->Notify (eInputReaderActivate);
90530fdc8d8SChris Lattner     ActivateInputReader (reader_sp);
90630fdc8d8SChris Lattner }
90730fdc8d8SChris Lattner 
90830fdc8d8SChris Lattner bool
9094d122c40SGreg Clayton Debugger::PopInputReader (const InputReaderSP& pop_reader_sp)
91030fdc8d8SChris Lattner {
91130fdc8d8SChris Lattner     bool result = false;
91230fdc8d8SChris Lattner 
91330fdc8d8SChris Lattner     // The reader on the stop of the stack is done, so let the next
91430fdc8d8SChris Lattner     // read on the stack referesh its prompt and if there is one...
915d5a0a01bSCaroline Tice     if (!m_input_reader_stack.IsEmpty())
91630fdc8d8SChris Lattner     {
917b44880caSCaroline Tice         // Cannot call GetCurrentInputReader here, as that would cause an infinite loop.
918d5a0a01bSCaroline Tice         InputReaderSP reader_sp(m_input_reader_stack.Top());
91930fdc8d8SChris Lattner 
92030fdc8d8SChris Lattner         if (!pop_reader_sp || pop_reader_sp.get() == reader_sp.get())
92130fdc8d8SChris Lattner         {
922d5a0a01bSCaroline Tice             m_input_reader_stack.Pop ();
92330fdc8d8SChris Lattner             reader_sp->Notify (eInputReaderDeactivate);
92430fdc8d8SChris Lattner             reader_sp->Notify (eInputReaderDone);
92530fdc8d8SChris Lattner             result = true;
92630fdc8d8SChris Lattner 
927d5a0a01bSCaroline Tice             if (!m_input_reader_stack.IsEmpty())
92830fdc8d8SChris Lattner             {
929d5a0a01bSCaroline Tice                 reader_sp = m_input_reader_stack.Top();
93030fdc8d8SChris Lattner                 if (reader_sp)
93130fdc8d8SChris Lattner                 {
93230fdc8d8SChris Lattner                     ActivateInputReader (reader_sp);
93330fdc8d8SChris Lattner                     reader_sp->Notify (eInputReaderReactivate);
93430fdc8d8SChris Lattner                 }
93530fdc8d8SChris Lattner             }
93630fdc8d8SChris Lattner         }
93730fdc8d8SChris Lattner     }
93830fdc8d8SChris Lattner     return result;
93930fdc8d8SChris Lattner }
94030fdc8d8SChris Lattner 
94130fdc8d8SChris Lattner bool
94230fdc8d8SChris Lattner Debugger::CheckIfTopInputReaderIsDone ()
94330fdc8d8SChris Lattner {
94430fdc8d8SChris Lattner     bool result = false;
945d5a0a01bSCaroline Tice     if (!m_input_reader_stack.IsEmpty())
94630fdc8d8SChris Lattner     {
947b44880caSCaroline Tice         // Cannot call GetCurrentInputReader here, as that would cause an infinite loop.
948d5a0a01bSCaroline Tice         InputReaderSP reader_sp(m_input_reader_stack.Top());
94930fdc8d8SChris Lattner 
95030fdc8d8SChris Lattner         if (reader_sp && reader_sp->IsDone())
95130fdc8d8SChris Lattner         {
95230fdc8d8SChris Lattner             result = true;
95330fdc8d8SChris Lattner             PopInputReader (reader_sp);
95430fdc8d8SChris Lattner         }
95530fdc8d8SChris Lattner     }
95630fdc8d8SChris Lattner     return result;
95730fdc8d8SChris Lattner }
95830fdc8d8SChris Lattner 
95930fdc8d8SChris Lattner void
96030fdc8d8SChris Lattner Debugger::ActivateInputReader (const InputReaderSP &reader_sp)
96130fdc8d8SChris Lattner {
96251b1e2d2SGreg Clayton     int input_fd = m_input_file.GetFile().GetDescriptor();
96330fdc8d8SChris Lattner 
96451b1e2d2SGreg Clayton     if (input_fd >= 0)
96530fdc8d8SChris Lattner     {
96651b1e2d2SGreg Clayton         Terminal tty(input_fd);
967a3406614SGreg Clayton 
968a3406614SGreg Clayton         tty.SetEcho(reader_sp->GetEcho());
96930fdc8d8SChris Lattner 
97030fdc8d8SChris Lattner         switch (reader_sp->GetGranularity())
97130fdc8d8SChris Lattner         {
97230fdc8d8SChris Lattner         case eInputReaderGranularityByte:
97330fdc8d8SChris Lattner         case eInputReaderGranularityWord:
974a3406614SGreg Clayton             tty.SetCanonical (false);
97530fdc8d8SChris Lattner             break;
97630fdc8d8SChris Lattner 
97730fdc8d8SChris Lattner         case eInputReaderGranularityLine:
97830fdc8d8SChris Lattner         case eInputReaderGranularityAll:
979a3406614SGreg Clayton             tty.SetCanonical (true);
98030fdc8d8SChris Lattner             break;
98130fdc8d8SChris Lattner 
98230fdc8d8SChris Lattner         default:
98330fdc8d8SChris Lattner             break;
98430fdc8d8SChris Lattner         }
98530fdc8d8SChris Lattner     }
98630fdc8d8SChris Lattner }
9876611103cSGreg Clayton 
9885b52f0c7SJim Ingham StreamSP
9895b52f0c7SJim Ingham Debugger::GetAsyncOutputStream ()
9905b52f0c7SJim Ingham {
9915b52f0c7SJim Ingham     return StreamSP (new StreamAsynchronousIO (GetCommandInterpreter(),
9925b52f0c7SJim Ingham                                                CommandInterpreter::eBroadcastBitAsynchronousOutputData));
9935b52f0c7SJim Ingham }
9945b52f0c7SJim Ingham 
9955b52f0c7SJim Ingham StreamSP
9965b52f0c7SJim Ingham Debugger::GetAsyncErrorStream ()
9975b52f0c7SJim Ingham {
9985b52f0c7SJim Ingham     return StreamSP (new StreamAsynchronousIO (GetCommandInterpreter(),
9995b52f0c7SJim Ingham                                                CommandInterpreter::eBroadcastBitAsynchronousErrorData));
10005b52f0c7SJim Ingham }
10015b52f0c7SJim Ingham 
1002061858ceSEnrico Granata uint32_t
1003061858ceSEnrico Granata Debugger::GetNumDebuggers()
1004061858ceSEnrico Granata {
1005c15f55e2SGreg Clayton     if (g_shared_debugger_refcount > 0)
1006c15f55e2SGreg Clayton     {
1007061858ceSEnrico Granata         Mutex::Locker locker (GetDebuggerListMutex ());
1008061858ceSEnrico Granata         return GetDebuggerList().size();
1009061858ceSEnrico Granata     }
1010c15f55e2SGreg Clayton     return 0;
1011c15f55e2SGreg Clayton }
1012061858ceSEnrico Granata 
1013061858ceSEnrico Granata lldb::DebuggerSP
1014061858ceSEnrico Granata Debugger::GetDebuggerAtIndex (uint32_t index)
1015061858ceSEnrico Granata {
1016061858ceSEnrico Granata     DebuggerSP debugger_sp;
1017061858ceSEnrico Granata 
1018c15f55e2SGreg Clayton     if (g_shared_debugger_refcount > 0)
1019c15f55e2SGreg Clayton     {
1020061858ceSEnrico Granata         Mutex::Locker locker (GetDebuggerListMutex ());
1021061858ceSEnrico Granata         DebuggerList &debugger_list = GetDebuggerList();
1022061858ceSEnrico Granata 
1023061858ceSEnrico Granata         if (index < debugger_list.size())
1024061858ceSEnrico Granata             debugger_sp = debugger_list[index];
1025c15f55e2SGreg Clayton     }
1026061858ceSEnrico Granata 
1027061858ceSEnrico Granata     return debugger_sp;
1028061858ceSEnrico Granata }
1029061858ceSEnrico Granata 
1030ebc1bb27SCaroline Tice DebuggerSP
1031ebc1bb27SCaroline Tice Debugger::FindDebuggerWithID (lldb::user_id_t id)
1032ebc1bb27SCaroline Tice {
10334d122c40SGreg Clayton     DebuggerSP debugger_sp;
1034ebc1bb27SCaroline Tice 
1035c15f55e2SGreg Clayton     if (g_shared_debugger_refcount > 0)
1036c15f55e2SGreg Clayton     {
1037ebc1bb27SCaroline Tice         Mutex::Locker locker (GetDebuggerListMutex ());
1038ebc1bb27SCaroline Tice         DebuggerList &debugger_list = GetDebuggerList();
1039ebc1bb27SCaroline Tice         DebuggerList::iterator pos, end = debugger_list.end();
1040ebc1bb27SCaroline Tice         for (pos = debugger_list.begin(); pos != end; ++pos)
1041ebc1bb27SCaroline Tice         {
1042ebc1bb27SCaroline Tice             if ((*pos).get()->GetID() == id)
1043ebc1bb27SCaroline Tice             {
1044ebc1bb27SCaroline Tice                 debugger_sp = *pos;
1045ebc1bb27SCaroline Tice                 break;
1046ebc1bb27SCaroline Tice             }
1047ebc1bb27SCaroline Tice         }
1048c15f55e2SGreg Clayton     }
1049ebc1bb27SCaroline Tice     return debugger_sp;
1050ebc1bb27SCaroline Tice }
10513df9a8dfSCaroline Tice 
10521b654882SGreg Clayton static void
10531b654882SGreg Clayton TestPromptFormats (StackFrame *frame)
10541b654882SGreg Clayton {
10551b654882SGreg Clayton     if (frame == NULL)
10561b654882SGreg Clayton         return;
10571b654882SGreg Clayton 
10581b654882SGreg Clayton     StreamString s;
10591b654882SGreg Clayton     const char *prompt_format =
10601b654882SGreg Clayton     "{addr = '${addr}'\n}"
10611b654882SGreg Clayton     "{process.id = '${process.id}'\n}"
10621b654882SGreg Clayton     "{process.name = '${process.name}'\n}"
10631b654882SGreg Clayton     "{process.file.basename = '${process.file.basename}'\n}"
10641b654882SGreg Clayton     "{process.file.fullpath = '${process.file.fullpath}'\n}"
10651b654882SGreg Clayton     "{thread.id = '${thread.id}'\n}"
10661b654882SGreg Clayton     "{thread.index = '${thread.index}'\n}"
10671b654882SGreg Clayton     "{thread.name = '${thread.name}'\n}"
10681b654882SGreg Clayton     "{thread.queue = '${thread.queue}'\n}"
10691b654882SGreg Clayton     "{thread.stop-reason = '${thread.stop-reason}'\n}"
10701b654882SGreg Clayton     "{target.arch = '${target.arch}'\n}"
10711b654882SGreg Clayton     "{module.file.basename = '${module.file.basename}'\n}"
10721b654882SGreg Clayton     "{module.file.fullpath = '${module.file.fullpath}'\n}"
10731b654882SGreg Clayton     "{file.basename = '${file.basename}'\n}"
10741b654882SGreg Clayton     "{file.fullpath = '${file.fullpath}'\n}"
10751b654882SGreg Clayton     "{frame.index = '${frame.index}'\n}"
10761b654882SGreg Clayton     "{frame.pc = '${frame.pc}'\n}"
10771b654882SGreg Clayton     "{frame.sp = '${frame.sp}'\n}"
10781b654882SGreg Clayton     "{frame.fp = '${frame.fp}'\n}"
10791b654882SGreg Clayton     "{frame.flags = '${frame.flags}'\n}"
10801b654882SGreg Clayton     "{frame.reg.rdi = '${frame.reg.rdi}'\n}"
10811b654882SGreg Clayton     "{frame.reg.rip = '${frame.reg.rip}'\n}"
10821b654882SGreg Clayton     "{frame.reg.rsp = '${frame.reg.rsp}'\n}"
10831b654882SGreg Clayton     "{frame.reg.rbp = '${frame.reg.rbp}'\n}"
10841b654882SGreg Clayton     "{frame.reg.rflags = '${frame.reg.rflags}'\n}"
10851b654882SGreg Clayton     "{frame.reg.xmm0 = '${frame.reg.xmm0}'\n}"
10861b654882SGreg Clayton     "{frame.reg.carp = '${frame.reg.carp}'\n}"
10871b654882SGreg Clayton     "{function.id = '${function.id}'\n}"
10881b654882SGreg Clayton     "{function.name = '${function.name}'\n}"
1089ccbc08e6SGreg Clayton     "{function.name-with-args = '${function.name-with-args}'\n}"
10901b654882SGreg Clayton     "{function.addr-offset = '${function.addr-offset}'\n}"
10911b654882SGreg Clayton     "{function.line-offset = '${function.line-offset}'\n}"
10921b654882SGreg Clayton     "{function.pc-offset = '${function.pc-offset}'\n}"
10931b654882SGreg Clayton     "{line.file.basename = '${line.file.basename}'\n}"
10941b654882SGreg Clayton     "{line.file.fullpath = '${line.file.fullpath}'\n}"
10951b654882SGreg Clayton     "{line.number = '${line.number}'\n}"
10961b654882SGreg Clayton     "{line.start-addr = '${line.start-addr}'\n}"
10971b654882SGreg Clayton     "{line.end-addr = '${line.end-addr}'\n}"
10981b654882SGreg Clayton ;
10991b654882SGreg Clayton 
11001b654882SGreg Clayton     SymbolContext sc (frame->GetSymbolContext(eSymbolContextEverything));
11011b654882SGreg Clayton     ExecutionContext exe_ctx;
11020603aa9dSGreg Clayton     frame->CalculateExecutionContext(exe_ctx);
11031b654882SGreg Clayton     const char *end = NULL;
11041b654882SGreg Clayton     if (Debugger::FormatPrompt (prompt_format, &sc, &exe_ctx, &sc.line_entry.range.GetBaseAddress(), s, &end))
11051b654882SGreg Clayton     {
11061b654882SGreg Clayton         printf("%s\n", s.GetData());
11071b654882SGreg Clayton     }
11081b654882SGreg Clayton     else
11091b654882SGreg Clayton     {
11101b654882SGreg Clayton         printf ("error: at '%s'\n", end);
11111b654882SGreg Clayton         printf ("what we got: %s\n", s.GetData());
11121b654882SGreg Clayton     }
11131b654882SGreg Clayton }
11141b654882SGreg Clayton 
11159fc1944eSEnrico Granata static bool
11169fc1944eSEnrico Granata ScanFormatDescriptor (const char* var_name_begin,
11179fc1944eSEnrico Granata                       const char* var_name_end,
11189fc1944eSEnrico Granata                       const char** var_name_final,
11199fc1944eSEnrico Granata                       const char** percent_position,
11204d122c40SGreg Clayton                       Format* custom_format,
11219fc1944eSEnrico Granata                       ValueObject::ValueObjectRepresentationStyle* val_obj_display)
11229fc1944eSEnrico Granata {
1123e992a089SEnrico Granata     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
11249fc1944eSEnrico Granata     *percent_position = ::strchr(var_name_begin,'%');
11259fc1944eSEnrico Granata     if (!*percent_position || *percent_position > var_name_end)
1126e992a089SEnrico Granata     {
1127e992a089SEnrico Granata         if (log)
1128d228483dSEnrico Granata             log->Printf("[ScanFormatDescriptor] no format descriptor in string, skipping");
11299fc1944eSEnrico Granata         *var_name_final = var_name_end;
1130e992a089SEnrico Granata     }
11319fc1944eSEnrico Granata     else
11329fc1944eSEnrico Granata     {
11339fc1944eSEnrico Granata         *var_name_final = *percent_position;
11349fc1944eSEnrico Granata         char* format_name = new char[var_name_end-*var_name_final]; format_name[var_name_end-*var_name_final-1] = '\0';
11359fc1944eSEnrico Granata         memcpy(format_name, *var_name_final+1, var_name_end-*var_name_final-1);
1136e992a089SEnrico Granata         if (log)
1137d228483dSEnrico Granata             log->Printf("ScanFormatDescriptor] parsing %s as a format descriptor", format_name);
11389fc1944eSEnrico Granata         if ( !FormatManager::GetFormatFromCString(format_name,
11399fc1944eSEnrico Granata                                                   true,
11409fc1944eSEnrico Granata                                                   *custom_format) )
11419fc1944eSEnrico Granata         {
1142e992a089SEnrico Granata             if (log)
1143d228483dSEnrico Granata                 log->Printf("ScanFormatDescriptor] %s is an unknown format", format_name);
11449fc1944eSEnrico Granata             // if this is an @ sign, print ObjC description
11459fc1944eSEnrico Granata             if (*format_name == '@')
114686cc9829SEnrico Granata                 *val_obj_display = ValueObject::eValueObjectRepresentationStyleLanguageSpecific;
11479fc1944eSEnrico Granata             // if this is a V, print the value using the default format
1148e992a089SEnrico Granata             else if (*format_name == 'V')
114986cc9829SEnrico Granata                 *val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
1150d55546b2SEnrico Granata             // if this is an L, print the location of the value
1151e992a089SEnrico Granata             else if (*format_name == 'L')
115286cc9829SEnrico Granata                 *val_obj_display = ValueObject::eValueObjectRepresentationStyleLocation;
1153d55546b2SEnrico Granata             // if this is an S, print the summary after all
1154e992a089SEnrico Granata             else if (*format_name == 'S')
115586cc9829SEnrico Granata                 *val_obj_display = ValueObject::eValueObjectRepresentationStyleSummary;
11565dfd49ccSEnrico Granata             else if (*format_name == '#')
115786cc9829SEnrico Granata                 *val_obj_display = ValueObject::eValueObjectRepresentationStyleChildrenCount;
1158d64d0bc0SEnrico Granata             else if (*format_name == 'T')
115986cc9829SEnrico Granata                 *val_obj_display = ValueObject::eValueObjectRepresentationStyleType;
1160e992a089SEnrico Granata             else if (log)
1161d228483dSEnrico Granata                 log->Printf("ScanFormatDescriptor] %s is an error, leaving the previous value alone", format_name);
11629fc1944eSEnrico Granata         }
11639fc1944eSEnrico Granata         // a good custom format tells us to print the value using it
11649fc1944eSEnrico Granata         else
1165e992a089SEnrico Granata         {
1166e992a089SEnrico Granata             if (log)
1167d228483dSEnrico Granata                 log->Printf("ScanFormatDescriptor] will display value for this VO");
116886cc9829SEnrico Granata             *val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
1169e992a089SEnrico Granata         }
11709fc1944eSEnrico Granata         delete format_name;
11719fc1944eSEnrico Granata     }
1172e992a089SEnrico Granata     if (log)
1173d228483dSEnrico Granata         log->Printf("ScanFormatDescriptor] final format description outcome: custom_format = %d, val_obj_display = %d",
1174e992a089SEnrico Granata                     *custom_format,
1175e992a089SEnrico Granata                     *val_obj_display);
11769fc1944eSEnrico Granata     return true;
11779fc1944eSEnrico Granata }
11789fc1944eSEnrico Granata 
11799fc1944eSEnrico Granata static bool
11809fc1944eSEnrico Granata ScanBracketedRange (const char* var_name_begin,
11819fc1944eSEnrico Granata                     const char* var_name_end,
11829fc1944eSEnrico Granata                     const char* var_name_final,
11839fc1944eSEnrico Granata                     const char** open_bracket_position,
11849fc1944eSEnrico Granata                     const char** separator_position,
11859fc1944eSEnrico Granata                     const char** close_bracket_position,
11869fc1944eSEnrico Granata                     const char** var_name_final_if_array_range,
11879fc1944eSEnrico Granata                     int64_t* index_lower,
11889fc1944eSEnrico Granata                     int64_t* index_higher)
11899fc1944eSEnrico Granata {
1190e992a089SEnrico Granata     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
11919fc1944eSEnrico Granata     *open_bracket_position = ::strchr(var_name_begin,'[');
11929fc1944eSEnrico Granata     if (*open_bracket_position && *open_bracket_position < var_name_final)
11939fc1944eSEnrico Granata     {
11949fc1944eSEnrico Granata         *separator_position = ::strchr(*open_bracket_position,'-'); // might be NULL if this is a simple var[N] bitfield
11959fc1944eSEnrico Granata         *close_bracket_position = ::strchr(*open_bracket_position,']');
11969fc1944eSEnrico Granata         // as usual, we assume that [] will come before %
11979fc1944eSEnrico Granata         //printf("trying to expand a []\n");
11989fc1944eSEnrico Granata         *var_name_final_if_array_range = *open_bracket_position;
11999fc1944eSEnrico Granata         if (*close_bracket_position - *open_bracket_position == 1)
12009fc1944eSEnrico Granata         {
1201e992a089SEnrico Granata             if (log)
1202d228483dSEnrico Granata                 log->Printf("[ScanBracketedRange] '[]' detected.. going from 0 to end of data");
12039fc1944eSEnrico Granata             *index_lower = 0;
12049fc1944eSEnrico Granata         }
12059fc1944eSEnrico Granata         else if (*separator_position == NULL || *separator_position > var_name_end)
12069fc1944eSEnrico Granata         {
12079fc1944eSEnrico Granata             char *end = NULL;
12089fc1944eSEnrico Granata             *index_lower = ::strtoul (*open_bracket_position+1, &end, 0);
12099fc1944eSEnrico Granata             *index_higher = *index_lower;
1210e992a089SEnrico Granata             if (log)
1211d01b2953SDaniel Malea                 log->Printf("[ScanBracketedRange] [%" PRId64 "] detected, high index is same", *index_lower);
12129fc1944eSEnrico Granata         }
12139fc1944eSEnrico Granata         else if (*close_bracket_position && *close_bracket_position < var_name_end)
12149fc1944eSEnrico Granata         {
12159fc1944eSEnrico Granata             char *end = NULL;
12169fc1944eSEnrico Granata             *index_lower = ::strtoul (*open_bracket_position+1, &end, 0);
12179fc1944eSEnrico Granata             *index_higher = ::strtoul (*separator_position+1, &end, 0);
1218e992a089SEnrico Granata             if (log)
1219d01b2953SDaniel Malea                 log->Printf("[ScanBracketedRange] [%" PRId64 "-%" PRId64 "] detected", *index_lower, *index_higher);
12209fc1944eSEnrico Granata         }
12219fc1944eSEnrico Granata         else
1222e992a089SEnrico Granata         {
1223e992a089SEnrico Granata             if (log)
1224d228483dSEnrico Granata                 log->Printf("[ScanBracketedRange] expression is erroneous, cannot extract indices out of it");
12259fc1944eSEnrico Granata             return false;
1226e992a089SEnrico Granata         }
12279fc1944eSEnrico Granata         if (*index_lower > *index_higher && *index_higher > 0)
12289fc1944eSEnrico Granata         {
1229e992a089SEnrico Granata             if (log)
1230d228483dSEnrico Granata                 log->Printf("[ScanBracketedRange] swapping indices");
12319fc1944eSEnrico Granata             int temp = *index_lower;
12329fc1944eSEnrico Granata             *index_lower = *index_higher;
12339fc1944eSEnrico Granata             *index_higher = temp;
12349fc1944eSEnrico Granata         }
12359fc1944eSEnrico Granata     }
1236e992a089SEnrico Granata     else if (log)
1237d228483dSEnrico Granata             log->Printf("[ScanBracketedRange] no bracketed range, skipping entirely");
12389fc1944eSEnrico Granata     return true;
12399fc1944eSEnrico Granata }
12409fc1944eSEnrico Granata 
12419fc1944eSEnrico Granata static ValueObjectSP
1242c482a192SEnrico Granata ExpandIndexedExpression (ValueObject* valobj,
12439fc1944eSEnrico Granata                          uint32_t index,
12449fc1944eSEnrico Granata                          StackFrame* frame,
1245fc7a7f3bSEnrico Granata                          bool deref_pointer)
12469fc1944eSEnrico Granata {
1247e992a089SEnrico Granata     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
1248fc7a7f3bSEnrico Granata     const char* ptr_deref_format = "[%d]";
1249fc7a7f3bSEnrico Granata     std::auto_ptr<char> ptr_deref_buffer(new char[10]);
1250fc7a7f3bSEnrico Granata     ::sprintf(ptr_deref_buffer.get(), ptr_deref_format, index);
1251e992a089SEnrico Granata     if (log)
1252d228483dSEnrico Granata         log->Printf("[ExpandIndexedExpression] name to deref: %s",ptr_deref_buffer.get());
1253fc7a7f3bSEnrico Granata     const char* first_unparsed;
1254fc7a7f3bSEnrico Granata     ValueObject::GetValueForExpressionPathOptions options;
1255fc7a7f3bSEnrico Granata     ValueObject::ExpressionPathEndResultType final_value_type;
1256fc7a7f3bSEnrico Granata     ValueObject::ExpressionPathScanEndReason reason_to_stop;
125786cc9829SEnrico Granata     ValueObject::ExpressionPathAftermath what_next = (deref_pointer ? ValueObject::eExpressionPathAftermathDereference : ValueObject::eExpressionPathAftermathNothing);
1258c482a192SEnrico Granata     ValueObjectSP item = valobj->GetValueForExpressionPath (ptr_deref_buffer.get(),
1259fc7a7f3bSEnrico Granata                                                           &first_unparsed,
1260fc7a7f3bSEnrico Granata                                                           &reason_to_stop,
1261fc7a7f3bSEnrico Granata                                                           &final_value_type,
1262fc7a7f3bSEnrico Granata                                                           options,
1263fc7a7f3bSEnrico Granata                                                           &what_next);
1264fc7a7f3bSEnrico Granata     if (!item)
1265fc7a7f3bSEnrico Granata     {
1266e992a089SEnrico Granata         if (log)
1267d228483dSEnrico Granata             log->Printf("[ExpandIndexedExpression] ERROR: unparsed portion = %s, why stopping = %d,"
1268e992a089SEnrico Granata                " final_value_type %d",
1269fc7a7f3bSEnrico Granata                first_unparsed, reason_to_stop, final_value_type);
1270fc7a7f3bSEnrico Granata     }
12719fc1944eSEnrico Granata     else
12729fc1944eSEnrico Granata     {
1273e992a089SEnrico Granata         if (log)
1274d228483dSEnrico Granata             log->Printf("[ExpandIndexedExpression] ALL RIGHT: unparsed portion = %s, why stopping = %d,"
1275e992a089SEnrico Granata                " final_value_type %d",
1276fc7a7f3bSEnrico Granata                first_unparsed, reason_to_stop, final_value_type);
12779fc1944eSEnrico Granata     }
12789fc1944eSEnrico Granata     return item;
12799fc1944eSEnrico Granata }
12809fc1944eSEnrico Granata 
12811b654882SGreg Clayton bool
12821b654882SGreg Clayton Debugger::FormatPrompt
12831b654882SGreg Clayton (
12841b654882SGreg Clayton     const char *format,
12851b654882SGreg Clayton     const SymbolContext *sc,
12861b654882SGreg Clayton     const ExecutionContext *exe_ctx,
12871b654882SGreg Clayton     const Address *addr,
12881b654882SGreg Clayton     Stream &s,
12894becb37eSEnrico Granata     const char **end,
1290c482a192SEnrico Granata     ValueObject* valobj
12911b654882SGreg Clayton )
12921b654882SGreg Clayton {
1293c482a192SEnrico Granata     ValueObject* realvalobj = NULL; // makes it super-easy to parse pointers
12941b654882SGreg Clayton     bool success = true;
12951b654882SGreg Clayton     const char *p;
1296e992a089SEnrico Granata     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
12971b654882SGreg Clayton     for (p = format; *p != '\0'; ++p)
12981b654882SGreg Clayton     {
1299c482a192SEnrico Granata         if (realvalobj)
13004becb37eSEnrico Granata         {
1301c482a192SEnrico Granata             valobj = realvalobj;
1302c482a192SEnrico Granata             realvalobj = NULL;
13034becb37eSEnrico Granata         }
13041b654882SGreg Clayton         size_t non_special_chars = ::strcspn (p, "${}\\");
13051b654882SGreg Clayton         if (non_special_chars > 0)
13061b654882SGreg Clayton         {
13071b654882SGreg Clayton             if (success)
13081b654882SGreg Clayton                 s.Write (p, non_special_chars);
13091b654882SGreg Clayton             p += non_special_chars;
13101b654882SGreg Clayton         }
13111b654882SGreg Clayton 
13121b654882SGreg Clayton         if (*p == '\0')
13131b654882SGreg Clayton         {
13141b654882SGreg Clayton             break;
13151b654882SGreg Clayton         }
13161b654882SGreg Clayton         else if (*p == '{')
13171b654882SGreg Clayton         {
13181b654882SGreg Clayton             // Start a new scope that must have everything it needs if it is to
13191b654882SGreg Clayton             // to make it into the final output stream "s". If you want to make
13201b654882SGreg Clayton             // a format that only prints out the function or symbol name if there
13211b654882SGreg Clayton             // is one in the symbol context you can use:
13221b654882SGreg Clayton             //      "{function =${function.name}}"
13231b654882SGreg Clayton             // The first '{' starts a new scope that end with the matching '}' at
13241b654882SGreg Clayton             // the end of the string. The contents "function =${function.name}"
13251b654882SGreg Clayton             // will then be evaluated and only be output if there is a function
13261b654882SGreg Clayton             // or symbol with a valid name.
13271b654882SGreg Clayton             StreamString sub_strm;
13281b654882SGreg Clayton 
13291b654882SGreg Clayton             ++p;  // Skip the '{'
13301b654882SGreg Clayton 
1331c482a192SEnrico Granata             if (FormatPrompt (p, sc, exe_ctx, addr, sub_strm, &p, valobj))
13321b654882SGreg Clayton             {
13331b654882SGreg Clayton                 // The stream had all it needed
13341b654882SGreg Clayton                 s.Write(sub_strm.GetData(), sub_strm.GetSize());
13351b654882SGreg Clayton             }
13361b654882SGreg Clayton             if (*p != '}')
13371b654882SGreg Clayton             {
13381b654882SGreg Clayton                 success = false;
13391b654882SGreg Clayton                 break;
13401b654882SGreg Clayton             }
13411b654882SGreg Clayton         }
13421b654882SGreg Clayton         else if (*p == '}')
13431b654882SGreg Clayton         {
13441b654882SGreg Clayton             // End of a enclosing scope
13451b654882SGreg Clayton             break;
13461b654882SGreg Clayton         }
13471b654882SGreg Clayton         else if (*p == '$')
13481b654882SGreg Clayton         {
13491b654882SGreg Clayton             // We have a prompt variable to print
13501b654882SGreg Clayton             ++p;
13511b654882SGreg Clayton             if (*p == '{')
13521b654882SGreg Clayton             {
13531b654882SGreg Clayton                 ++p;
13541b654882SGreg Clayton                 const char *var_name_begin = p;
13551b654882SGreg Clayton                 const char *var_name_end = ::strchr (p, '}');
13561b654882SGreg Clayton 
13571b654882SGreg Clayton                 if (var_name_end && var_name_begin < var_name_end)
13581b654882SGreg Clayton                 {
13591b654882SGreg Clayton                     // if we have already failed to parse, skip this variable
13601b654882SGreg Clayton                     if (success)
13611b654882SGreg Clayton                     {
13621b654882SGreg Clayton                         const char *cstr = NULL;
13631b654882SGreg Clayton                         Address format_addr;
13641b654882SGreg Clayton                         bool calculate_format_addr_function_offset = false;
13651b654882SGreg Clayton                         // Set reg_kind and reg_num to invalid values
13661b654882SGreg Clayton                         RegisterKind reg_kind = kNumRegisterKinds;
13671b654882SGreg Clayton                         uint32_t reg_num = LLDB_INVALID_REGNUM;
13681b654882SGreg Clayton                         FileSpec format_file_spec;
1369e0d378b3SGreg Clayton                         const RegisterInfo *reg_info = NULL;
13701b654882SGreg Clayton                         RegisterContext *reg_ctx = NULL;
13719fc1944eSEnrico Granata                         bool do_deref_pointer = false;
137286cc9829SEnrico Granata                         ValueObject::ExpressionPathScanEndReason reason_to_stop = ValueObject::eExpressionPathScanEndReasonEndOfString;
137386cc9829SEnrico Granata                         ValueObject::ExpressionPathEndResultType final_value_type = ValueObject::eExpressionPathEndResultTypePlain;
13741b654882SGreg Clayton 
13751b654882SGreg Clayton                         // Each variable must set success to true below...
13761b654882SGreg Clayton                         bool var_success = false;
13771b654882SGreg Clayton                         switch (var_name_begin[0])
13781b654882SGreg Clayton                         {
13794becb37eSEnrico Granata                         case '*':
13806f3533fbSEnrico Granata                         case 'v':
13816f3533fbSEnrico Granata                         case 's':
13824becb37eSEnrico Granata                             {
1383c482a192SEnrico Granata                                 if (!valobj)
138434132754SGreg Clayton                                     break;
13856f3533fbSEnrico Granata 
1386c3e320a7SEnrico Granata                                 if (log)
1387d228483dSEnrico Granata                                     log->Printf("[Debugger::FormatPrompt] initial string: %s",var_name_begin);
1388c3e320a7SEnrico Granata 
13896f3533fbSEnrico Granata                                 // check for *var and *svar
13906f3533fbSEnrico Granata                                 if (*var_name_begin == '*')
13916f3533fbSEnrico Granata                                 {
13929fc1944eSEnrico Granata                                     do_deref_pointer = true;
13939fc1944eSEnrico Granata                                     var_name_begin++;
13949fc1944eSEnrico Granata                                 }
1395c3e320a7SEnrico Granata 
1396c3e320a7SEnrico Granata                                 if (log)
1397d228483dSEnrico Granata                                     log->Printf("[Debugger::FormatPrompt] initial string: %s",var_name_begin);
1398c3e320a7SEnrico Granata 
13996f3533fbSEnrico Granata                                 if (*var_name_begin == 's')
14004becb37eSEnrico Granata                                 {
1401c5bc412cSEnrico Granata                                     if (!valobj->IsSynthetic())
140286cc9829SEnrico Granata                                         valobj = valobj->GetSyntheticValue().get();
140386cc9829SEnrico Granata                                     if (!valobj)
140486cc9829SEnrico Granata                                         break;
14056f3533fbSEnrico Granata                                     var_name_begin++;
14066f3533fbSEnrico Granata                                 }
14076f3533fbSEnrico Granata 
1408c3e320a7SEnrico Granata                                 if (log)
1409d228483dSEnrico Granata                                     log->Printf("[Debugger::FormatPrompt] initial string: %s",var_name_begin);
1410c3e320a7SEnrico Granata 
14116f3533fbSEnrico Granata                                 // should be a 'v' by now
14126f3533fbSEnrico Granata                                 if (*var_name_begin != 'v')
14136f3533fbSEnrico Granata                                     break;
14146f3533fbSEnrico Granata 
1415c3e320a7SEnrico Granata                                 if (log)
1416d228483dSEnrico Granata                                     log->Printf("[Debugger::FormatPrompt] initial string: %s",var_name_begin);
1417c3e320a7SEnrico Granata 
1418fc7a7f3bSEnrico Granata                                 ValueObject::ExpressionPathAftermath what_next = (do_deref_pointer ?
141986cc9829SEnrico Granata                                                                                   ValueObject::eExpressionPathAftermathDereference : ValueObject::eExpressionPathAftermathNothing);
1420fc7a7f3bSEnrico Granata                                 ValueObject::GetValueForExpressionPathOptions options;
14218c9d3560SEnrico Granata                                 options.DontCheckDotVsArrowSyntax().DoAllowBitfieldSyntax().DoAllowFragileIVar().DoAllowSyntheticChildren();
142286cc9829SEnrico Granata                                 ValueObject::ValueObjectRepresentationStyle val_obj_display = ValueObject::eValueObjectRepresentationStyleSummary;
142334132754SGreg Clayton                                 ValueObject* target = NULL;
14244d122c40SGreg Clayton                                 Format custom_format = eFormatInvalid;
142534132754SGreg Clayton                                 const char* var_name_final = NULL;
14269fc1944eSEnrico Granata                                 const char* var_name_final_if_array_range = NULL;
142734132754SGreg Clayton                                 const char* close_bracket_position = NULL;
142834132754SGreg Clayton                                 int64_t index_lower = -1;
142934132754SGreg Clayton                                 int64_t index_higher = -1;
14309fc1944eSEnrico Granata                                 bool is_array_range = false;
1431fc7a7f3bSEnrico Granata                                 const char* first_unparsed;
143285933ed4SEnrico Granata                                 bool was_plain_var = false;
143385933ed4SEnrico Granata                                 bool was_var_format = false;
1434a777dc2aSEnrico Granata                                 bool was_var_indexed = false;
1435fc7a7f3bSEnrico Granata 
1436c482a192SEnrico Granata                                 if (!valobj) break;
1437c482a192SEnrico Granata                                 // simplest case ${var}, just print valobj's value
14389fc1944eSEnrico Granata                                 if (::strncmp (var_name_begin, "var}", strlen("var}")) == 0)
14390a3958e0SEnrico Granata                                 {
144085933ed4SEnrico Granata                                     was_plain_var = true;
1441c482a192SEnrico Granata                                     target = valobj;
144286cc9829SEnrico Granata                                     val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
14430a3958e0SEnrico Granata                                 }
14449fc1944eSEnrico Granata                                 else if (::strncmp(var_name_begin,"var%",strlen("var%")) == 0)
14459fc1944eSEnrico Granata                                 {
144685933ed4SEnrico Granata                                     was_var_format = true;
14479fc1944eSEnrico Granata                                     // this is a variable with some custom format applied to it
14489fc1944eSEnrico Granata                                     const char* percent_position;
1449c482a192SEnrico Granata                                     target = valobj;
145086cc9829SEnrico Granata                                     val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
14519fc1944eSEnrico Granata                                     ScanFormatDescriptor (var_name_begin,
14529fc1944eSEnrico Granata                                                           var_name_end,
14539fc1944eSEnrico Granata                                                           &var_name_final,
14549fc1944eSEnrico Granata                                                           &percent_position,
14559fc1944eSEnrico Granata                                                           &custom_format,
14569fc1944eSEnrico Granata                                                           &val_obj_display);
14570a3958e0SEnrico Granata                                 }
14589fc1944eSEnrico Granata                                     // this is ${var.something} or multiple .something nested
14599fc1944eSEnrico Granata                                 else if (::strncmp (var_name_begin, "var", strlen("var")) == 0)
14609fc1944eSEnrico Granata                                 {
1461a777dc2aSEnrico Granata                                     if (::strncmp(var_name_begin, "var[", strlen("var[")) == 0)
1462a777dc2aSEnrico Granata                                         was_var_indexed = true;
14639fc1944eSEnrico Granata                                     const char* percent_position;
14649fc1944eSEnrico Granata                                     ScanFormatDescriptor (var_name_begin,
14659fc1944eSEnrico Granata                                                           var_name_end,
14669fc1944eSEnrico Granata                                                           &var_name_final,
14679fc1944eSEnrico Granata                                                           &percent_position,
14689fc1944eSEnrico Granata                                                           &custom_format,
14699fc1944eSEnrico Granata                                                           &val_obj_display);
14709fc1944eSEnrico Granata 
14719fc1944eSEnrico Granata                                     const char* open_bracket_position;
14729fc1944eSEnrico Granata                                     const char* separator_position;
14739fc1944eSEnrico Granata                                     ScanBracketedRange (var_name_begin,
14749fc1944eSEnrico Granata                                                         var_name_end,
14759fc1944eSEnrico Granata                                                         var_name_final,
14769fc1944eSEnrico Granata                                                         &open_bracket_position,
14779fc1944eSEnrico Granata                                                         &separator_position,
14789fc1944eSEnrico Granata                                                         &close_bracket_position,
14799fc1944eSEnrico Granata                                                         &var_name_final_if_array_range,
14809fc1944eSEnrico Granata                                                         &index_lower,
14819fc1944eSEnrico Granata                                                         &index_higher);
14829fc1944eSEnrico Granata 
14839fc1944eSEnrico Granata                                     Error error;
14849fc1944eSEnrico Granata 
1485fc7a7f3bSEnrico Granata                                     std::auto_ptr<char> expr_path(new char[var_name_final-var_name_begin-1]);
1486fc7a7f3bSEnrico Granata                                     ::memset(expr_path.get(), 0, var_name_final-var_name_begin-1);
1487fc7a7f3bSEnrico Granata                                     memcpy(expr_path.get(), var_name_begin+3,var_name_final-var_name_begin-3);
1488fc7a7f3bSEnrico Granata 
1489e992a089SEnrico Granata                                     if (log)
1490d228483dSEnrico Granata                                         log->Printf("[Debugger::FormatPrompt] symbol to expand: %s",expr_path.get());
1491fc7a7f3bSEnrico Granata 
1492c482a192SEnrico Granata                                     target = valobj->GetValueForExpressionPath(expr_path.get(),
1493fc7a7f3bSEnrico Granata                                                                              &first_unparsed,
1494fc7a7f3bSEnrico Granata                                                                              &reason_to_stop,
1495fc7a7f3bSEnrico Granata                                                                              &final_value_type,
1496fc7a7f3bSEnrico Granata                                                                              options,
1497fc7a7f3bSEnrico Granata                                                                              &what_next).get();
1498fc7a7f3bSEnrico Granata 
1499fc7a7f3bSEnrico Granata                                     if (!target)
15009fc1944eSEnrico Granata                                     {
1501e992a089SEnrico Granata                                         if (log)
1502d228483dSEnrico Granata                                             log->Printf("[Debugger::FormatPrompt] ERROR: unparsed portion = %s, why stopping = %d,"
1503e992a089SEnrico Granata                                                " final_value_type %d",
1504fc7a7f3bSEnrico Granata                                                first_unparsed, reason_to_stop, final_value_type);
1505fc7a7f3bSEnrico Granata                                         break;
15060a3958e0SEnrico Granata                                     }
1507a7187d00SEnrico Granata                                     else
1508fc7a7f3bSEnrico Granata                                     {
1509e992a089SEnrico Granata                                         if (log)
1510d228483dSEnrico Granata                                             log->Printf("[Debugger::FormatPrompt] ALL RIGHT: unparsed portion = %s, why stopping = %d,"
1511e992a089SEnrico Granata                                                " final_value_type %d",
1512fc7a7f3bSEnrico Granata                                                first_unparsed, reason_to_stop, final_value_type);
1513a7187d00SEnrico Granata                                     }
15140a3958e0SEnrico Granata                                 }
15150a3958e0SEnrico Granata                                 else
15160a3958e0SEnrico Granata                                     break;
15179fc1944eSEnrico Granata 
151886cc9829SEnrico Granata                                 is_array_range = (final_value_type == ValueObject::eExpressionPathEndResultTypeBoundedRange ||
151986cc9829SEnrico Granata                                                   final_value_type == ValueObject::eExpressionPathEndResultTypeUnboundedRange);
1520fc7a7f3bSEnrico Granata 
152186cc9829SEnrico Granata                                 do_deref_pointer = (what_next == ValueObject::eExpressionPathAftermathDereference);
1522fc7a7f3bSEnrico Granata 
1523a7187d00SEnrico Granata                                 if (do_deref_pointer && !is_array_range)
15240a3958e0SEnrico Granata                                 {
15259fc1944eSEnrico Granata                                     // I have not deref-ed yet, let's do it
15269fc1944eSEnrico Granata                                     // this happens when we are not going through GetValueForVariableExpressionPath
15279fc1944eSEnrico Granata                                     // to get to the target ValueObject
15289fc1944eSEnrico Granata                                     Error error;
15299fc1944eSEnrico Granata                                     target = target->Dereference(error).get();
1530dc940730SEnrico Granata                                     if (error.Fail())
1531dc940730SEnrico Granata                                     {
1532dc940730SEnrico Granata                                         if (log)
1533d228483dSEnrico Granata                                             log->Printf("[Debugger::FormatPrompt] ERROR: %s\n", error.AsCString("unknown")); \
1534dc940730SEnrico Granata                                         break;
1535dc940730SEnrico Granata                                     }
15369fc1944eSEnrico Granata                                     do_deref_pointer = false;
15370a3958e0SEnrico Granata                                 }
15380a3958e0SEnrico Granata 
1539a777dc2aSEnrico Granata                                 // <rdar://problem/11338654>
1540a777dc2aSEnrico Granata                                 // we do not want to use the summary for a bitfield of type T:n
1541a777dc2aSEnrico Granata                                 // if we were originally dealing with just a T - that would get
1542a777dc2aSEnrico Granata                                 // us into an endless recursion
1543a777dc2aSEnrico Granata                                 if (target->IsBitfield() && was_var_indexed)
1544a777dc2aSEnrico Granata                                 {
1545a777dc2aSEnrico Granata                                     // TODO: check for a (T:n)-specific summary - we should still obey that
1546a777dc2aSEnrico Granata                                     StreamString bitfield_name;
1547a777dc2aSEnrico Granata                                     bitfield_name.Printf("%s:%d", target->GetTypeName().AsCString(), target->GetBitfieldBitSize());
1548a777dc2aSEnrico Granata                                     lldb::TypeNameSpecifierImplSP type_sp(new TypeNameSpecifierImpl(bitfield_name.GetData(),false));
1549a777dc2aSEnrico Granata                                     if (!DataVisualization::GetSummaryForType(type_sp))
1550a777dc2aSEnrico Granata                                         val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
1551a777dc2aSEnrico Granata                                 }
1552a777dc2aSEnrico Granata 
155385933ed4SEnrico Granata                                 // TODO use flags for these
15544ef877f5SGreg Clayton                                 bool is_array = ClangASTContext::IsArrayType(target->GetClangType(), NULL, NULL, NULL);
1555f4efecd9SEnrico Granata                                 bool is_pointer = ClangASTContext::IsPointerType(target->GetClangType());
155685933ed4SEnrico Granata                                 bool is_aggregate = ClangASTContext::IsAggregateType(target->GetClangType());
1557f4efecd9SEnrico Granata 
155886cc9829SEnrico Granata                                 if ((is_array || is_pointer) && (!is_array_range) && val_obj_display == ValueObject::eValueObjectRepresentationStyleValue) // this should be wrong, but there are some exceptions
1559f4efecd9SEnrico Granata                                 {
156085933ed4SEnrico Granata                                     StreamString str_temp;
1561e992a089SEnrico Granata                                     if (log)
1562d228483dSEnrico Granata                                         log->Printf("[Debugger::FormatPrompt] I am into array || pointer && !range");
1563d64d0bc0SEnrico Granata 
156486cc9829SEnrico Granata                                     if (target->HasSpecialPrintableRepresentation(val_obj_display,
1565d64d0bc0SEnrico Granata                                                                                   custom_format))
1566d64d0bc0SEnrico Granata                                     {
1567f4efecd9SEnrico Granata                                         // try to use the special cases
156885933ed4SEnrico Granata                                         var_success = target->DumpPrintableRepresentation(str_temp,
156985933ed4SEnrico Granata                                                                                           val_obj_display,
157085933ed4SEnrico Granata                                                                                           custom_format);
1571e992a089SEnrico Granata                                         if (log)
1572d228483dSEnrico Granata                                             log->Printf("[Debugger::FormatPrompt] special cases did%s match", var_success ? "" : "n't");
1573d64d0bc0SEnrico Granata 
1574d64d0bc0SEnrico Granata                                         // should not happen
157585933ed4SEnrico Granata                                         if (!var_success)
157685933ed4SEnrico Granata                                             s << "<invalid usage of pointer value as object>";
157785933ed4SEnrico Granata                                         else
157885933ed4SEnrico Granata                                             s << str_temp.GetData();
1579d64d0bc0SEnrico Granata                                         var_success = true;
1580d64d0bc0SEnrico Granata                                         break;
1581d64d0bc0SEnrico Granata                                     }
1582d64d0bc0SEnrico Granata                                     else
1583d64d0bc0SEnrico Granata                                     {
158488da35f8SEnrico Granata                                         if (was_plain_var) // if ${var}
1585d64d0bc0SEnrico Granata                                         {
1586d64d0bc0SEnrico Granata                                             s << target->GetTypeName() << " @ " << target->GetLocationAsCString();
1587d64d0bc0SEnrico Granata                                         }
158888da35f8SEnrico Granata                                         else if (is_pointer) // if pointer, value is the address stored
158988da35f8SEnrico Granata                                         {
159023f59509SGreg Clayton                                             target->DumpPrintableRepresentation (s,
159188da35f8SEnrico Granata                                                                                  val_obj_display,
159286cc9829SEnrico Granata                                                                                  custom_format,
159386cc9829SEnrico Granata                                                                                  ValueObject::ePrintableRepresentationSpecialCasesDisable);
159488da35f8SEnrico Granata                                         }
1595d64d0bc0SEnrico Granata                                         else
1596d64d0bc0SEnrico Granata                                         {
1597d64d0bc0SEnrico Granata                                             s << "<invalid usage of pointer value as object>";
1598d64d0bc0SEnrico Granata                                         }
1599d64d0bc0SEnrico Granata                                         var_success = true;
1600d64d0bc0SEnrico Granata                                         break;
1601d64d0bc0SEnrico Granata                                     }
1602d64d0bc0SEnrico Granata                                 }
1603d64d0bc0SEnrico Granata 
1604d64d0bc0SEnrico Granata                                 // if directly trying to print ${var}, and this is an aggregate, display a nice
1605d64d0bc0SEnrico Granata                                 // type @ location message
1606d64d0bc0SEnrico Granata                                 if (is_aggregate && was_plain_var)
1607d64d0bc0SEnrico Granata                                 {
1608d64d0bc0SEnrico Granata                                     s << target->GetTypeName() << " @ " << target->GetLocationAsCString();
1609d64d0bc0SEnrico Granata                                     var_success = true;
161085933ed4SEnrico Granata                                     break;
161185933ed4SEnrico Granata                                 }
161285933ed4SEnrico Granata 
1613d64d0bc0SEnrico Granata                                 // if directly trying to print ${var%V}, and this is an aggregate, do not let the user do it
161486cc9829SEnrico Granata                                 if (is_aggregate && ((was_var_format && val_obj_display == ValueObject::eValueObjectRepresentationStyleValue)))
161585933ed4SEnrico Granata                                 {
161685933ed4SEnrico Granata                                     s << "<invalid use of aggregate type>";
161785933ed4SEnrico Granata                                     var_success = true;
1618f4efecd9SEnrico Granata                                     break;
1619f4efecd9SEnrico Granata                                 }
1620f4efecd9SEnrico Granata 
16219fc1944eSEnrico Granata                                 if (!is_array_range)
1622e992a089SEnrico Granata                                 {
1623e992a089SEnrico Granata                                     if (log)
1624d228483dSEnrico Granata                                         log->Printf("[Debugger::FormatPrompt] dumping ordinary printable output");
16259fc1944eSEnrico Granata                                     var_success = target->DumpPrintableRepresentation(s,val_obj_display, custom_format);
1626e992a089SEnrico Granata                                 }
16279fc1944eSEnrico Granata                                 else
16289fc1944eSEnrico Granata                                 {
1629e992a089SEnrico Granata                                     if (log)
1630d228483dSEnrico Granata                                         log->Printf("[Debugger::FormatPrompt] checking if I can handle as array");
16319fc1944eSEnrico Granata                                     if (!is_array && !is_pointer)
16329fc1944eSEnrico Granata                                         break;
1633e992a089SEnrico Granata                                     if (log)
1634d228483dSEnrico Granata                                         log->Printf("[Debugger::FormatPrompt] handle as array");
1635fc7a7f3bSEnrico Granata                                     const char* special_directions = NULL;
1636fc7a7f3bSEnrico Granata                                     StreamString special_directions_writer;
16370a3958e0SEnrico Granata                                     if (close_bracket_position && (var_name_end-close_bracket_position > 1))
16380a3958e0SEnrico Granata                                     {
1639fc7a7f3bSEnrico Granata                                         ConstString additional_data;
1640fc7a7f3bSEnrico Granata                                         additional_data.SetCStringWithLength(close_bracket_position+1, var_name_end-close_bracket_position-1);
1641fc7a7f3bSEnrico Granata                                         special_directions_writer.Printf("${%svar%s}",
1642fc7a7f3bSEnrico Granata                                                                          do_deref_pointer ? "*" : "",
1643fc7a7f3bSEnrico Granata                                                                          additional_data.GetCString());
1644fc7a7f3bSEnrico Granata                                         special_directions = special_directions_writer.GetData();
16450a3958e0SEnrico Granata                                     }
16460a3958e0SEnrico Granata 
16470a3958e0SEnrico Granata                                     // let us display items index_lower thru index_higher of this array
16480a3958e0SEnrico Granata                                     s.PutChar('[');
16490a3958e0SEnrico Granata                                     var_success = true;
16500a3958e0SEnrico Granata 
16519fc1944eSEnrico Granata                                     if (index_higher < 0)
1652c482a192SEnrico Granata                                         index_higher = valobj->GetNumChildren() - 1;
16530a3958e0SEnrico Granata 
1654cc4d0146SGreg Clayton                                     uint32_t max_num_children = target->GetTargetSP()->GetMaximumNumberOfChildrenToDisplay();
165522c55d18SEnrico Granata 
16560a3958e0SEnrico Granata                                     for (;index_lower<=index_higher;index_lower++)
16570a3958e0SEnrico Granata                                     {
1658fc7a7f3bSEnrico Granata                                         ValueObject* item = ExpandIndexedExpression (target,
16599fc1944eSEnrico Granata                                                                                      index_lower,
1660c14ee32dSGreg Clayton                                                                                      exe_ctx->GetFramePtr(),
1661fc7a7f3bSEnrico Granata                                                                                      false).get();
16620a3958e0SEnrico Granata 
1663fc7a7f3bSEnrico Granata                                         if (!item)
1664fc7a7f3bSEnrico Granata                                         {
1665e992a089SEnrico Granata                                             if (log)
1666d01b2953SDaniel Malea                                                 log->Printf("[Debugger::FormatPrompt] ERROR in getting child item at index %" PRId64, index_lower);
1667fc7a7f3bSEnrico Granata                                         }
1668fc7a7f3bSEnrico Granata                                         else
1669fc7a7f3bSEnrico Granata                                         {
1670e992a089SEnrico Granata                                             if (log)
1671d228483dSEnrico Granata                                                 log->Printf("[Debugger::FormatPrompt] special_directions for child item: %s",special_directions);
1672fc7a7f3bSEnrico Granata                                         }
1673fc7a7f3bSEnrico Granata 
16740a3958e0SEnrico Granata                                         if (!special_directions)
16759fc1944eSEnrico Granata                                             var_success &= item->DumpPrintableRepresentation(s,val_obj_display, custom_format);
16760a3958e0SEnrico Granata                                         else
16770a3958e0SEnrico Granata                                             var_success &= FormatPrompt(special_directions, sc, exe_ctx, addr, s, NULL, item);
16780a3958e0SEnrico Granata 
167922c55d18SEnrico Granata                                         if (--max_num_children == 0)
168022c55d18SEnrico Granata                                         {
168122c55d18SEnrico Granata                                             s.PutCString(", ...");
168222c55d18SEnrico Granata                                             break;
168322c55d18SEnrico Granata                                         }
168422c55d18SEnrico Granata 
16850a3958e0SEnrico Granata                                         if (index_lower < index_higher)
16860a3958e0SEnrico Granata                                             s.PutChar(',');
16870a3958e0SEnrico Granata                                     }
16880a3958e0SEnrico Granata                                     s.PutChar(']');
16894becb37eSEnrico Granata                                 }
16904becb37eSEnrico Granata                             }
169134132754SGreg Clayton                             break;
16921b654882SGreg Clayton                         case 'a':
16931b654882SGreg Clayton                             if (::strncmp (var_name_begin, "addr}", strlen("addr}")) == 0)
16941b654882SGreg Clayton                             {
16951b654882SGreg Clayton                                 if (addr && addr->IsValid())
16961b654882SGreg Clayton                                 {
16971b654882SGreg Clayton                                     var_success = true;
16981b654882SGreg Clayton                                     format_addr = *addr;
16991b654882SGreg Clayton                                 }
17001b654882SGreg Clayton                             }
17015a31471eSGreg Clayton                             else if (::strncmp (var_name_begin, "ansi.", strlen("ansi.")) == 0)
17025a31471eSGreg Clayton                             {
17035a31471eSGreg Clayton                                 var_success = true;
17045a31471eSGreg Clayton                                 var_name_begin += strlen("ansi."); // Skip the "ansi."
17055a31471eSGreg Clayton                                 if (::strncmp (var_name_begin, "fg.", strlen("fg.")) == 0)
17065a31471eSGreg Clayton                                 {
17075a31471eSGreg Clayton                                     var_name_begin += strlen("fg."); // Skip the "fg."
17085a31471eSGreg Clayton                                     if (::strncmp (var_name_begin, "black}", strlen("black}")) == 0)
17095a31471eSGreg Clayton                                     {
17105a31471eSGreg Clayton                                         s.Printf ("%s%s%s",
17115a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_start,
17125a31471eSGreg Clayton                                                   lldb_utility::ansi::k_fg_black,
17135a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_end);
17145a31471eSGreg Clayton                                     }
17155a31471eSGreg Clayton                                     else if (::strncmp (var_name_begin, "red}", strlen("red}")) == 0)
17165a31471eSGreg Clayton                                     {
17175a31471eSGreg Clayton                                         s.Printf ("%s%s%s",
17185a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_start,
17195a31471eSGreg Clayton                                                   lldb_utility::ansi::k_fg_red,
17205a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_end);
17215a31471eSGreg Clayton                                     }
17225a31471eSGreg Clayton                                     else if (::strncmp (var_name_begin, "green}", strlen("green}")) == 0)
17235a31471eSGreg Clayton                                     {
17245a31471eSGreg Clayton                                         s.Printf ("%s%s%s",
17255a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_start,
17265a31471eSGreg Clayton                                                   lldb_utility::ansi::k_fg_green,
17275a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_end);
17285a31471eSGreg Clayton                                     }
17295a31471eSGreg Clayton                                     else if (::strncmp (var_name_begin, "yellow}", strlen("yellow}")) == 0)
17305a31471eSGreg Clayton                                     {
17315a31471eSGreg Clayton                                         s.Printf ("%s%s%s",
17325a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_start,
17335a31471eSGreg Clayton                                                   lldb_utility::ansi::k_fg_yellow,
17345a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_end);
17355a31471eSGreg Clayton                                     }
17365a31471eSGreg Clayton                                     else if (::strncmp (var_name_begin, "blue}", strlen("blue}")) == 0)
17375a31471eSGreg Clayton                                     {
17385a31471eSGreg Clayton                                         s.Printf ("%s%s%s",
17395a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_start,
17405a31471eSGreg Clayton                                                   lldb_utility::ansi::k_fg_blue,
17415a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_end);
17425a31471eSGreg Clayton                                     }
17435a31471eSGreg Clayton                                     else if (::strncmp (var_name_begin, "purple}", strlen("purple}")) == 0)
17445a31471eSGreg Clayton                                     {
17455a31471eSGreg Clayton                                         s.Printf ("%s%s%s",
17465a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_start,
17475a31471eSGreg Clayton                                                   lldb_utility::ansi::k_fg_purple,
17485a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_end);
17495a31471eSGreg Clayton                                     }
17505a31471eSGreg Clayton                                     else if (::strncmp (var_name_begin, "cyan}", strlen("cyan}")) == 0)
17515a31471eSGreg Clayton                                     {
17525a31471eSGreg Clayton                                         s.Printf ("%s%s%s",
17535a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_start,
17545a31471eSGreg Clayton                                                   lldb_utility::ansi::k_fg_cyan,
17555a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_end);
17565a31471eSGreg Clayton                                     }
17575a31471eSGreg Clayton                                     else if (::strncmp (var_name_begin, "white}", strlen("white}")) == 0)
17585a31471eSGreg Clayton                                     {
17595a31471eSGreg Clayton                                         s.Printf ("%s%s%s",
17605a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_start,
17615a31471eSGreg Clayton                                                   lldb_utility::ansi::k_fg_white,
17625a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_end);
17635a31471eSGreg Clayton                                     }
17645a31471eSGreg Clayton                                     else
17655a31471eSGreg Clayton                                     {
17665a31471eSGreg Clayton                                         var_success = false;
17675a31471eSGreg Clayton                                     }
17685a31471eSGreg Clayton                                 }
17695a31471eSGreg Clayton                                 else if (::strncmp (var_name_begin, "bg.", strlen("bg.")) == 0)
17705a31471eSGreg Clayton                                 {
17715a31471eSGreg Clayton                                     var_name_begin += strlen("bg."); // Skip the "bg."
17725a31471eSGreg Clayton                                     if (::strncmp (var_name_begin, "black}", strlen("black}")) == 0)
17735a31471eSGreg Clayton                                     {
17745a31471eSGreg Clayton                                         s.Printf ("%s%s%s",
17755a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_start,
17765a31471eSGreg Clayton                                                   lldb_utility::ansi::k_bg_black,
17775a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_end);
17785a31471eSGreg Clayton                                     }
17795a31471eSGreg Clayton                                     else if (::strncmp (var_name_begin, "red}", strlen("red}")) == 0)
17805a31471eSGreg Clayton                                     {
17815a31471eSGreg Clayton                                         s.Printf ("%s%s%s",
17825a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_start,
17835a31471eSGreg Clayton                                                   lldb_utility::ansi::k_bg_red,
17845a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_end);
17855a31471eSGreg Clayton                                     }
17865a31471eSGreg Clayton                                     else if (::strncmp (var_name_begin, "green}", strlen("green}")) == 0)
17875a31471eSGreg Clayton                                     {
17885a31471eSGreg Clayton                                         s.Printf ("%s%s%s",
17895a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_start,
17905a31471eSGreg Clayton                                                   lldb_utility::ansi::k_bg_green,
17915a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_end);
17925a31471eSGreg Clayton                                     }
17935a31471eSGreg Clayton                                     else if (::strncmp (var_name_begin, "yellow}", strlen("yellow}")) == 0)
17945a31471eSGreg Clayton                                     {
17955a31471eSGreg Clayton                                         s.Printf ("%s%s%s",
17965a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_start,
17975a31471eSGreg Clayton                                                   lldb_utility::ansi::k_bg_yellow,
17985a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_end);
17995a31471eSGreg Clayton                                     }
18005a31471eSGreg Clayton                                     else if (::strncmp (var_name_begin, "blue}", strlen("blue}")) == 0)
18015a31471eSGreg Clayton                                     {
18025a31471eSGreg Clayton                                         s.Printf ("%s%s%s",
18035a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_start,
18045a31471eSGreg Clayton                                                   lldb_utility::ansi::k_bg_blue,
18055a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_end);
18065a31471eSGreg Clayton                                     }
18075a31471eSGreg Clayton                                     else if (::strncmp (var_name_begin, "purple}", strlen("purple}")) == 0)
18085a31471eSGreg Clayton                                     {
18095a31471eSGreg Clayton                                         s.Printf ("%s%s%s",
18105a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_start,
18115a31471eSGreg Clayton                                                   lldb_utility::ansi::k_bg_purple,
18125a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_end);
18135a31471eSGreg Clayton                                     }
18145a31471eSGreg Clayton                                     else if (::strncmp (var_name_begin, "cyan}", strlen("cyan}")) == 0)
18155a31471eSGreg Clayton                                     {
18165a31471eSGreg Clayton                                         s.Printf ("%s%s%s",
18175a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_start,
18185a31471eSGreg Clayton                                                   lldb_utility::ansi::k_bg_cyan,
18195a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_end);
18205a31471eSGreg Clayton                                     }
18215a31471eSGreg Clayton                                     else if (::strncmp (var_name_begin, "white}", strlen("white}")) == 0)
18225a31471eSGreg Clayton                                     {
18235a31471eSGreg Clayton                                         s.Printf ("%s%s%s",
18245a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_start,
18255a31471eSGreg Clayton                                                   lldb_utility::ansi::k_bg_white,
18265a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_end);
18275a31471eSGreg Clayton                                     }
18285a31471eSGreg Clayton                                     else
18295a31471eSGreg Clayton                                     {
18305a31471eSGreg Clayton                                         var_success = false;
18315a31471eSGreg Clayton                                     }
18325a31471eSGreg Clayton                                 }
18335a31471eSGreg Clayton                                 else if (::strncmp (var_name_begin, "normal}", strlen ("normal}")) == 0)
18345a31471eSGreg Clayton                                 {
18355a31471eSGreg Clayton                                     s.Printf ("%s%s%s",
18365a31471eSGreg Clayton                                               lldb_utility::ansi::k_escape_start,
18375a31471eSGreg Clayton                                               lldb_utility::ansi::k_ctrl_normal,
18385a31471eSGreg Clayton                                               lldb_utility::ansi::k_escape_end);
18395a31471eSGreg Clayton                                 }
18405a31471eSGreg Clayton                                 else if (::strncmp (var_name_begin, "bold}", strlen("bold}")) == 0)
18415a31471eSGreg Clayton                                 {
18425a31471eSGreg Clayton                                     s.Printf ("%s%s%s",
18435a31471eSGreg Clayton                                               lldb_utility::ansi::k_escape_start,
18445a31471eSGreg Clayton                                               lldb_utility::ansi::k_ctrl_bold,
18455a31471eSGreg Clayton                                               lldb_utility::ansi::k_escape_end);
18465a31471eSGreg Clayton                                 }
18475a31471eSGreg Clayton                                 else if (::strncmp (var_name_begin, "faint}", strlen("faint}")) == 0)
18485a31471eSGreg Clayton                                 {
18495a31471eSGreg Clayton                                     s.Printf ("%s%s%s",
18505a31471eSGreg Clayton                                               lldb_utility::ansi::k_escape_start,
18515a31471eSGreg Clayton                                               lldb_utility::ansi::k_ctrl_faint,
18525a31471eSGreg Clayton                                               lldb_utility::ansi::k_escape_end);
18535a31471eSGreg Clayton                                 }
18545a31471eSGreg Clayton                                 else if (::strncmp (var_name_begin, "italic}", strlen("italic}")) == 0)
18555a31471eSGreg Clayton                                 {
18565a31471eSGreg Clayton                                     s.Printf ("%s%s%s",
18575a31471eSGreg Clayton                                               lldb_utility::ansi::k_escape_start,
18585a31471eSGreg Clayton                                               lldb_utility::ansi::k_ctrl_italic,
18595a31471eSGreg Clayton                                               lldb_utility::ansi::k_escape_end);
18605a31471eSGreg Clayton                                 }
18615a31471eSGreg Clayton                                 else if (::strncmp (var_name_begin, "underline}", strlen("underline}")) == 0)
18625a31471eSGreg Clayton                                 {
18635a31471eSGreg Clayton                                     s.Printf ("%s%s%s",
18645a31471eSGreg Clayton                                               lldb_utility::ansi::k_escape_start,
18655a31471eSGreg Clayton                                               lldb_utility::ansi::k_ctrl_underline,
18665a31471eSGreg Clayton                                               lldb_utility::ansi::k_escape_end);
18675a31471eSGreg Clayton                                 }
18685a31471eSGreg Clayton                                 else if (::strncmp (var_name_begin, "slow-blink}", strlen("slow-blink}")) == 0)
18695a31471eSGreg Clayton                                 {
18705a31471eSGreg Clayton                                     s.Printf ("%s%s%s",
18715a31471eSGreg Clayton                                               lldb_utility::ansi::k_escape_start,
18725a31471eSGreg Clayton                                               lldb_utility::ansi::k_ctrl_slow_blink,
18735a31471eSGreg Clayton                                               lldb_utility::ansi::k_escape_end);
18745a31471eSGreg Clayton                                 }
18755a31471eSGreg Clayton                                 else if (::strncmp (var_name_begin, "fast-blink}", strlen("fast-blink}")) == 0)
18765a31471eSGreg Clayton                                 {
18775a31471eSGreg Clayton                                     s.Printf ("%s%s%s",
18785a31471eSGreg Clayton                                               lldb_utility::ansi::k_escape_start,
18795a31471eSGreg Clayton                                               lldb_utility::ansi::k_ctrl_fast_blink,
18805a31471eSGreg Clayton                                               lldb_utility::ansi::k_escape_end);
18815a31471eSGreg Clayton                                 }
18825a31471eSGreg Clayton                                 else if (::strncmp (var_name_begin, "negative}", strlen("negative}")) == 0)
18835a31471eSGreg Clayton                                 {
18845a31471eSGreg Clayton                                     s.Printf ("%s%s%s",
18855a31471eSGreg Clayton                                               lldb_utility::ansi::k_escape_start,
18865a31471eSGreg Clayton                                               lldb_utility::ansi::k_ctrl_negative,
18875a31471eSGreg Clayton                                               lldb_utility::ansi::k_escape_end);
18885a31471eSGreg Clayton                                 }
18895a31471eSGreg Clayton                                 else if (::strncmp (var_name_begin, "conceal}", strlen("conceal}")) == 0)
18905a31471eSGreg Clayton                                 {
18915a31471eSGreg Clayton                                     s.Printf ("%s%s%s",
18925a31471eSGreg Clayton                                               lldb_utility::ansi::k_escape_start,
18935a31471eSGreg Clayton                                               lldb_utility::ansi::k_ctrl_conceal,
18945a31471eSGreg Clayton                                               lldb_utility::ansi::k_escape_end);
18955a31471eSGreg Clayton 
18965a31471eSGreg Clayton                                 }
18975a31471eSGreg Clayton                                 else if (::strncmp (var_name_begin, "crossed-out}", strlen("crossed-out}")) == 0)
18985a31471eSGreg Clayton                                 {
18995a31471eSGreg Clayton                                     s.Printf ("%s%s%s",
19005a31471eSGreg Clayton                                               lldb_utility::ansi::k_escape_start,
19015a31471eSGreg Clayton                                               lldb_utility::ansi::k_ctrl_crossed_out,
19025a31471eSGreg Clayton                                               lldb_utility::ansi::k_escape_end);
19035a31471eSGreg Clayton                                 }
19045a31471eSGreg Clayton                                 else
19055a31471eSGreg Clayton                                 {
19065a31471eSGreg Clayton                                     var_success = false;
19075a31471eSGreg Clayton                                 }
19085a31471eSGreg Clayton                             }
19091b654882SGreg Clayton                             break;
19101b654882SGreg Clayton 
19111b654882SGreg Clayton                         case 'p':
19121b654882SGreg Clayton                             if (::strncmp (var_name_begin, "process.", strlen("process.")) == 0)
19131b654882SGreg Clayton                             {
1914c14ee32dSGreg Clayton                                 if (exe_ctx)
1915c14ee32dSGreg Clayton                                 {
1916c14ee32dSGreg Clayton                                     Process *process = exe_ctx->GetProcessPtr();
1917c14ee32dSGreg Clayton                                     if (process)
19181b654882SGreg Clayton                                     {
19191b654882SGreg Clayton                                         var_name_begin += ::strlen ("process.");
19201b654882SGreg Clayton                                         if (::strncmp (var_name_begin, "id}", strlen("id}")) == 0)
19211b654882SGreg Clayton                                         {
1922d01b2953SDaniel Malea                                             s.Printf("%" PRIu64, process->GetID());
19231b654882SGreg Clayton                                             var_success = true;
19241b654882SGreg Clayton                                         }
19251b654882SGreg Clayton                                         else if ((::strncmp (var_name_begin, "name}", strlen("name}")) == 0) ||
19261b654882SGreg Clayton                                                  (::strncmp (var_name_begin, "file.basename}", strlen("file.basename}")) == 0) ||
19271b654882SGreg Clayton                                                  (::strncmp (var_name_begin, "file.fullpath}", strlen("file.fullpath}")) == 0))
19281b654882SGreg Clayton                                         {
1929c14ee32dSGreg Clayton                                             Module *exe_module = process->GetTarget().GetExecutableModulePointer();
1930aa149cbdSGreg Clayton                                             if (exe_module)
19311b654882SGreg Clayton                                             {
19321b654882SGreg Clayton                                                 if (var_name_begin[0] == 'n' || var_name_begin[5] == 'f')
19331b654882SGreg Clayton                                                 {
1934aa149cbdSGreg Clayton                                                     format_file_spec.GetFilename() = exe_module->GetFileSpec().GetFilename();
19351b654882SGreg Clayton                                                     var_success = format_file_spec;
19361b654882SGreg Clayton                                                 }
19371b654882SGreg Clayton                                                 else
19381b654882SGreg Clayton                                                 {
1939aa149cbdSGreg Clayton                                                     format_file_spec = exe_module->GetFileSpec();
19401b654882SGreg Clayton                                                     var_success = format_file_spec;
19411b654882SGreg Clayton                                                 }
19421b654882SGreg Clayton                                             }
19431b654882SGreg Clayton                                         }
19441b654882SGreg Clayton                                     }
19451b654882SGreg Clayton                                 }
1946c14ee32dSGreg Clayton                             }
19471b654882SGreg Clayton                             break;
19481b654882SGreg Clayton 
19491b654882SGreg Clayton                         case 't':
19501b654882SGreg Clayton                             if (::strncmp (var_name_begin, "thread.", strlen("thread.")) == 0)
19511b654882SGreg Clayton                             {
1952c14ee32dSGreg Clayton                                 if (exe_ctx)
1953c14ee32dSGreg Clayton                                 {
1954c14ee32dSGreg Clayton                                     Thread *thread = exe_ctx->GetThreadPtr();
1955c14ee32dSGreg Clayton                                     if (thread)
19561b654882SGreg Clayton                                     {
19571b654882SGreg Clayton                                         var_name_begin += ::strlen ("thread.");
19581b654882SGreg Clayton                                         if (::strncmp (var_name_begin, "id}", strlen("id}")) == 0)
19591b654882SGreg Clayton                                         {
1960d01b2953SDaniel Malea                                             s.Printf("0x%4.4" PRIx64, thread->GetID());
19611b654882SGreg Clayton                                             var_success = true;
19621b654882SGreg Clayton                                         }
19631b654882SGreg Clayton                                         else if (::strncmp (var_name_begin, "index}", strlen("index}")) == 0)
19641b654882SGreg Clayton                                         {
1965c14ee32dSGreg Clayton                                             s.Printf("%u", thread->GetIndexID());
19661b654882SGreg Clayton                                             var_success = true;
19671b654882SGreg Clayton                                         }
19681b654882SGreg Clayton                                         else if (::strncmp (var_name_begin, "name}", strlen("name}")) == 0)
19691b654882SGreg Clayton                                         {
1970c14ee32dSGreg Clayton                                             cstr = thread->GetName();
19711b654882SGreg Clayton                                             var_success = cstr && cstr[0];
19721b654882SGreg Clayton                                             if (var_success)
19731b654882SGreg Clayton                                                 s.PutCString(cstr);
19741b654882SGreg Clayton                                         }
19751b654882SGreg Clayton                                         else if (::strncmp (var_name_begin, "queue}", strlen("queue}")) == 0)
19761b654882SGreg Clayton                                         {
1977c14ee32dSGreg Clayton                                             cstr = thread->GetQueueName();
19781b654882SGreg Clayton                                             var_success = cstr && cstr[0];
19791b654882SGreg Clayton                                             if (var_success)
19801b654882SGreg Clayton                                                 s.PutCString(cstr);
19811b654882SGreg Clayton                                         }
19821b654882SGreg Clayton                                         else if (::strncmp (var_name_begin, "stop-reason}", strlen("stop-reason}")) == 0)
19831b654882SGreg Clayton                                         {
1984c14ee32dSGreg Clayton                                             StopInfoSP stop_info_sp = thread->GetStopInfo ();
19855d88a068SJim Ingham                                             if (stop_info_sp && stop_info_sp->IsValid())
19861b654882SGreg Clayton                                             {
1987b15bfc75SJim Ingham                                                 cstr = stop_info_sp->GetDescription();
19881b654882SGreg Clayton                                                 if (cstr && cstr[0])
19891b654882SGreg Clayton                                                 {
19901b654882SGreg Clayton                                                     s.PutCString(cstr);
19911b654882SGreg Clayton                                                     var_success = true;
19921b654882SGreg Clayton                                                 }
19931b654882SGreg Clayton                                             }
19941b654882SGreg Clayton                                         }
199573ca05a2SJim Ingham                                         else if (::strncmp (var_name_begin, "return-value}", strlen("return-value}")) == 0)
199673ca05a2SJim Ingham                                         {
199773ca05a2SJim Ingham                                             StopInfoSP stop_info_sp = thread->GetStopInfo ();
19985d88a068SJim Ingham                                             if (stop_info_sp && stop_info_sp->IsValid())
199973ca05a2SJim Ingham                                             {
200073ca05a2SJim Ingham                                                 ValueObjectSP return_valobj_sp = StopInfo::GetReturnValueObject (stop_info_sp);
200173ca05a2SJim Ingham                                                 if (return_valobj_sp)
200273ca05a2SJim Ingham                                                 {
2003ef651600SJim Ingham                                                     ValueObject::DumpValueObjectOptions dump_options;
2004ef651600SJim Ingham                                                     ValueObject::DumpValueObject (s, return_valobj_sp.get(), dump_options);
200573ca05a2SJim Ingham                                                     var_success = true;
200673ca05a2SJim Ingham                                                 }
200773ca05a2SJim Ingham                                             }
200873ca05a2SJim Ingham                                         }
200973ca05a2SJim Ingham                                     }
20101b654882SGreg Clayton                                 }
20111b654882SGreg Clayton                             }
20121b654882SGreg Clayton                             else if (::strncmp (var_name_begin, "target.", strlen("target.")) == 0)
20131b654882SGreg Clayton                             {
201467cc0636SGreg Clayton                                 // TODO: hookup properties
201567cc0636SGreg Clayton //                                if (!target_properties_sp)
201667cc0636SGreg Clayton //                                {
201767cc0636SGreg Clayton //                                    Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
201867cc0636SGreg Clayton //                                    if (target)
201967cc0636SGreg Clayton //                                        target_properties_sp = target->GetProperties();
202067cc0636SGreg Clayton //                                }
202167cc0636SGreg Clayton //
202267cc0636SGreg Clayton //                                if (target_properties_sp)
202367cc0636SGreg Clayton //                                {
202467cc0636SGreg Clayton //                                    var_name_begin += ::strlen ("target.");
202567cc0636SGreg Clayton //                                    const char *end_property = strchr(var_name_begin, '}');
202667cc0636SGreg Clayton //                                    if (end_property)
202767cc0636SGreg Clayton //                                    {
202867cc0636SGreg Clayton //                                        ConstString property_name(var_name_begin, end_property - var_name_begin);
202967cc0636SGreg Clayton //                                        std::string property_value (target_properties_sp->GetPropertyValue(property_name));
203067cc0636SGreg Clayton //                                        if (!property_value.empty())
203167cc0636SGreg Clayton //                                        {
203267cc0636SGreg Clayton //                                            s.PutCString (property_value.c_str());
203367cc0636SGreg Clayton //                                            var_success = true;
203467cc0636SGreg Clayton //                                        }
203567cc0636SGreg Clayton //                                    }
203667cc0636SGreg Clayton //                                }
20370603aa9dSGreg Clayton                                 Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
20380603aa9dSGreg Clayton                                 if (target)
20391b654882SGreg Clayton                                 {
20401b654882SGreg Clayton                                     var_name_begin += ::strlen ("target.");
20411b654882SGreg Clayton                                     if (::strncmp (var_name_begin, "arch}", strlen("arch}")) == 0)
20421b654882SGreg Clayton                                     {
20431b654882SGreg Clayton                                         ArchSpec arch (target->GetArchitecture ());
20441b654882SGreg Clayton                                         if (arch.IsValid())
20451b654882SGreg Clayton                                         {
204664195a2cSGreg Clayton                                             s.PutCString (arch.GetArchitectureName());
20471b654882SGreg Clayton                                             var_success = true;
20481b654882SGreg Clayton                                         }
20491b654882SGreg Clayton                                     }
20501b654882SGreg Clayton                                 }
20511b654882SGreg Clayton                             }
20521b654882SGreg Clayton                             break;
20531b654882SGreg Clayton 
20541b654882SGreg Clayton 
20551b654882SGreg Clayton                         case 'm':
20561b654882SGreg Clayton                             if (::strncmp (var_name_begin, "module.", strlen("module.")) == 0)
20571b654882SGreg Clayton                             {
20580603aa9dSGreg Clayton                                 if (sc && sc->module_sp.get())
20591b654882SGreg Clayton                                 {
20600603aa9dSGreg Clayton                                     Module *module = sc->module_sp.get();
20611b654882SGreg Clayton                                     var_name_begin += ::strlen ("module.");
20621b654882SGreg Clayton 
20631b654882SGreg Clayton                                     if (::strncmp (var_name_begin, "file.", strlen("file.")) == 0)
20641b654882SGreg Clayton                                     {
20651b654882SGreg Clayton                                         if (module->GetFileSpec())
20661b654882SGreg Clayton                                         {
20671b654882SGreg Clayton                                             var_name_begin += ::strlen ("file.");
20681b654882SGreg Clayton 
20691b654882SGreg Clayton                                             if (::strncmp (var_name_begin, "basename}", strlen("basename}")) == 0)
20701b654882SGreg Clayton                                             {
20711b654882SGreg Clayton                                                 format_file_spec.GetFilename() = module->GetFileSpec().GetFilename();
20721b654882SGreg Clayton                                                 var_success = format_file_spec;
20731b654882SGreg Clayton                                             }
20741b654882SGreg Clayton                                             else if (::strncmp (var_name_begin, "fullpath}", strlen("fullpath}")) == 0)
20751b654882SGreg Clayton                                             {
20761b654882SGreg Clayton                                                 format_file_spec = module->GetFileSpec();
20771b654882SGreg Clayton                                                 var_success = format_file_spec;
20781b654882SGreg Clayton                                             }
20791b654882SGreg Clayton                                         }
20801b654882SGreg Clayton                                     }
20811b654882SGreg Clayton                                 }
20821b654882SGreg Clayton                             }
20831b654882SGreg Clayton                             break;
20841b654882SGreg Clayton 
20851b654882SGreg Clayton 
20861b654882SGreg Clayton                         case 'f':
20871b654882SGreg Clayton                             if (::strncmp (var_name_begin, "file.", strlen("file.")) == 0)
20881b654882SGreg Clayton                             {
20891b654882SGreg Clayton                                 if (sc && sc->comp_unit != NULL)
20901b654882SGreg Clayton                                 {
20911b654882SGreg Clayton                                     var_name_begin += ::strlen ("file.");
20921b654882SGreg Clayton 
20931b654882SGreg Clayton                                     if (::strncmp (var_name_begin, "basename}", strlen("basename}")) == 0)
20941b654882SGreg Clayton                                     {
20951b654882SGreg Clayton                                         format_file_spec.GetFilename() = sc->comp_unit->GetFilename();
20961b654882SGreg Clayton                                         var_success = format_file_spec;
20971b654882SGreg Clayton                                     }
20981b654882SGreg Clayton                                     else if (::strncmp (var_name_begin, "fullpath}", strlen("fullpath}")) == 0)
20991b654882SGreg Clayton                                     {
21001b654882SGreg Clayton                                         format_file_spec = *sc->comp_unit;
21011b654882SGreg Clayton                                         var_success = format_file_spec;
21021b654882SGreg Clayton                                     }
21031b654882SGreg Clayton                                 }
21041b654882SGreg Clayton                             }
21051b654882SGreg Clayton                             else if (::strncmp (var_name_begin, "frame.", strlen("frame.")) == 0)
21061b654882SGreg Clayton                             {
2107c14ee32dSGreg Clayton                                 if (exe_ctx)
2108c14ee32dSGreg Clayton                                 {
2109c14ee32dSGreg Clayton                                     StackFrame *frame = exe_ctx->GetFramePtr();
2110c14ee32dSGreg Clayton                                     if (frame)
21111b654882SGreg Clayton                                     {
21121b654882SGreg Clayton                                         var_name_begin += ::strlen ("frame.");
21131b654882SGreg Clayton                                         if (::strncmp (var_name_begin, "index}", strlen("index}")) == 0)
21141b654882SGreg Clayton                                         {
2115c14ee32dSGreg Clayton                                             s.Printf("%u", frame->GetFrameIndex());
21161b654882SGreg Clayton                                             var_success = true;
21171b654882SGreg Clayton                                         }
21181b654882SGreg Clayton                                         else if (::strncmp (var_name_begin, "pc}", strlen("pc}")) == 0)
21191b654882SGreg Clayton                                         {
21201b654882SGreg Clayton                                             reg_kind = eRegisterKindGeneric;
21211b654882SGreg Clayton                                             reg_num = LLDB_REGNUM_GENERIC_PC;
21221b654882SGreg Clayton                                             var_success = true;
21231b654882SGreg Clayton                                         }
21241b654882SGreg Clayton                                         else if (::strncmp (var_name_begin, "sp}", strlen("sp}")) == 0)
21251b654882SGreg Clayton                                         {
21261b654882SGreg Clayton                                             reg_kind = eRegisterKindGeneric;
21271b654882SGreg Clayton                                             reg_num = LLDB_REGNUM_GENERIC_SP;
21281b654882SGreg Clayton                                             var_success = true;
21291b654882SGreg Clayton                                         }
21301b654882SGreg Clayton                                         else if (::strncmp (var_name_begin, "fp}", strlen("fp}")) == 0)
21311b654882SGreg Clayton                                         {
21321b654882SGreg Clayton                                             reg_kind = eRegisterKindGeneric;
21331b654882SGreg Clayton                                             reg_num = LLDB_REGNUM_GENERIC_FP;
21341b654882SGreg Clayton                                             var_success = true;
21351b654882SGreg Clayton                                         }
21361b654882SGreg Clayton                                         else if (::strncmp (var_name_begin, "flags}", strlen("flags}")) == 0)
21371b654882SGreg Clayton                                         {
21381b654882SGreg Clayton                                             reg_kind = eRegisterKindGeneric;
21391b654882SGreg Clayton                                             reg_num = LLDB_REGNUM_GENERIC_FLAGS;
21401b654882SGreg Clayton                                             var_success = true;
21411b654882SGreg Clayton                                         }
21421b654882SGreg Clayton                                         else if (::strncmp (var_name_begin, "reg.", strlen ("reg.")) == 0)
21431b654882SGreg Clayton                                         {
2144c14ee32dSGreg Clayton                                             reg_ctx = frame->GetRegisterContext().get();
21451b654882SGreg Clayton                                             if (reg_ctx)
21461b654882SGreg Clayton                                             {
21471b654882SGreg Clayton                                                 var_name_begin += ::strlen ("reg.");
21481b654882SGreg Clayton                                                 if (var_name_begin < var_name_end)
21491b654882SGreg Clayton                                                 {
21501b654882SGreg Clayton                                                     std::string reg_name (var_name_begin, var_name_end);
21511b654882SGreg Clayton                                                     reg_info = reg_ctx->GetRegisterInfoByName (reg_name.c_str());
21521b654882SGreg Clayton                                                     if (reg_info)
21531b654882SGreg Clayton                                                         var_success = true;
21541b654882SGreg Clayton                                                 }
21551b654882SGreg Clayton                                             }
21561b654882SGreg Clayton                                         }
21571b654882SGreg Clayton                                     }
21581b654882SGreg Clayton                                 }
2159c14ee32dSGreg Clayton                             }
21601b654882SGreg Clayton                             else if (::strncmp (var_name_begin, "function.", strlen("function.")) == 0)
21611b654882SGreg Clayton                             {
21621b654882SGreg Clayton                                 if (sc && (sc->function != NULL || sc->symbol != NULL))
21631b654882SGreg Clayton                                 {
21641b654882SGreg Clayton                                     var_name_begin += ::strlen ("function.");
21651b654882SGreg Clayton                                     if (::strncmp (var_name_begin, "id}", strlen("id}")) == 0)
21661b654882SGreg Clayton                                     {
21671b654882SGreg Clayton                                         if (sc->function)
2168d01b2953SDaniel Malea                                             s.Printf("function{0x%8.8" PRIx64 "}", sc->function->GetID());
21691b654882SGreg Clayton                                         else
21701b654882SGreg Clayton                                             s.Printf("symbol[%u]", sc->symbol->GetID());
21711b654882SGreg Clayton 
21721b654882SGreg Clayton                                         var_success = true;
21731b654882SGreg Clayton                                     }
21741b654882SGreg Clayton                                     else if (::strncmp (var_name_begin, "name}", strlen("name}")) == 0)
21751b654882SGreg Clayton                                     {
21761b654882SGreg Clayton                                         if (sc->function)
21771b654882SGreg Clayton                                             cstr = sc->function->GetName().AsCString (NULL);
21781b654882SGreg Clayton                                         else if (sc->symbol)
21791b654882SGreg Clayton                                             cstr = sc->symbol->GetName().AsCString (NULL);
21801b654882SGreg Clayton                                         if (cstr)
21811b654882SGreg Clayton                                         {
21821b654882SGreg Clayton                                             s.PutCString(cstr);
21830d9c9934SGreg Clayton 
21840d9c9934SGreg Clayton                                             if (sc->block)
21850d9c9934SGreg Clayton                                             {
21860d9c9934SGreg Clayton                                                 Block *inline_block = sc->block->GetContainingInlinedBlock ();
21870d9c9934SGreg Clayton                                                 if (inline_block)
21880d9c9934SGreg Clayton                                                 {
21890d9c9934SGreg Clayton                                                     const InlineFunctionInfo *inline_info = sc->block->GetInlinedFunctionInfo();
21900d9c9934SGreg Clayton                                                     if (inline_info)
21910d9c9934SGreg Clayton                                                     {
21920d9c9934SGreg Clayton                                                         s.PutCString(" [inlined] ");
21930d9c9934SGreg Clayton                                                         inline_info->GetName().Dump(&s);
21940d9c9934SGreg Clayton                                                     }
21950d9c9934SGreg Clayton                                                 }
21960d9c9934SGreg Clayton                                             }
21971b654882SGreg Clayton                                             var_success = true;
21981b654882SGreg Clayton                                         }
21991b654882SGreg Clayton                                     }
22006d3dbf51SGreg Clayton                                     else if (::strncmp (var_name_begin, "name-with-args}", strlen("name-with-args}")) == 0)
22016d3dbf51SGreg Clayton                                     {
22026d3dbf51SGreg Clayton                                         // Print the function name with arguments in it
22036d3dbf51SGreg Clayton 
22046d3dbf51SGreg Clayton                                         if (sc->function)
22056d3dbf51SGreg Clayton                                         {
22066d3dbf51SGreg Clayton                                             var_success = true;
22076d3dbf51SGreg Clayton                                             ExecutionContextScope *exe_scope = exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL;
22086d3dbf51SGreg Clayton                                             cstr = sc->function->GetName().AsCString (NULL);
22096d3dbf51SGreg Clayton                                             if (cstr)
22106d3dbf51SGreg Clayton                                             {
22116d3dbf51SGreg Clayton                                                 const InlineFunctionInfo *inline_info = NULL;
22126d3dbf51SGreg Clayton                                                 VariableListSP variable_list_sp;
22136d3dbf51SGreg Clayton                                                 bool get_function_vars = true;
22146d3dbf51SGreg Clayton                                                 if (sc->block)
22156d3dbf51SGreg Clayton                                                 {
22166d3dbf51SGreg Clayton                                                     Block *inline_block = sc->block->GetContainingInlinedBlock ();
22176d3dbf51SGreg Clayton 
22186d3dbf51SGreg Clayton                                                     if (inline_block)
22196d3dbf51SGreg Clayton                                                     {
22206d3dbf51SGreg Clayton                                                         get_function_vars = false;
22216d3dbf51SGreg Clayton                                                         inline_info = sc->block->GetInlinedFunctionInfo();
22226d3dbf51SGreg Clayton                                                         if (inline_info)
22236d3dbf51SGreg Clayton                                                             variable_list_sp = inline_block->GetBlockVariableList (true);
22246d3dbf51SGreg Clayton                                                     }
22256d3dbf51SGreg Clayton                                                 }
22266d3dbf51SGreg Clayton 
22276d3dbf51SGreg Clayton                                                 if (get_function_vars)
22286d3dbf51SGreg Clayton                                                 {
22296d3dbf51SGreg Clayton                                                     variable_list_sp = sc->function->GetBlock(true).GetBlockVariableList (true);
22306d3dbf51SGreg Clayton                                                 }
22316d3dbf51SGreg Clayton 
22326d3dbf51SGreg Clayton                                                 if (inline_info)
22336d3dbf51SGreg Clayton                                                 {
22346d3dbf51SGreg Clayton                                                     s.PutCString (cstr);
22356d3dbf51SGreg Clayton                                                     s.PutCString (" [inlined] ");
22366d3dbf51SGreg Clayton                                                     cstr = inline_info->GetName().GetCString();
22376d3dbf51SGreg Clayton                                                 }
22386d3dbf51SGreg Clayton 
22396d3dbf51SGreg Clayton                                                 VariableList args;
22406d3dbf51SGreg Clayton                                                 if (variable_list_sp)
22416d3dbf51SGreg Clayton                                                 {
22426d3dbf51SGreg Clayton                                                     const size_t num_variables = variable_list_sp->GetSize();
22436d3dbf51SGreg Clayton                                                     for (size_t var_idx = 0; var_idx < num_variables; ++var_idx)
22446d3dbf51SGreg Clayton                                                     {
22456d3dbf51SGreg Clayton                                                         VariableSP var_sp (variable_list_sp->GetVariableAtIndex(var_idx));
22466d3dbf51SGreg Clayton                                                         if (var_sp->GetScope() == eValueTypeVariableArgument)
22476d3dbf51SGreg Clayton                                                             args.AddVariable (var_sp);
22486d3dbf51SGreg Clayton                                                     }
22496d3dbf51SGreg Clayton 
22506d3dbf51SGreg Clayton                                                 }
22516d3dbf51SGreg Clayton                                                 if (args.GetSize() > 0)
22526d3dbf51SGreg Clayton                                                 {
22536d3dbf51SGreg Clayton                                                     const char *open_paren = strchr (cstr, '(');
22546d3dbf51SGreg Clayton                                                     const char *close_paren = NULL;
22556d3dbf51SGreg Clayton                                                     if (open_paren)
22566d3dbf51SGreg Clayton                                                         close_paren = strchr (open_paren, ')');
22576d3dbf51SGreg Clayton 
22586d3dbf51SGreg Clayton                                                     if (open_paren)
22596d3dbf51SGreg Clayton                                                         s.Write(cstr, open_paren - cstr + 1);
22606d3dbf51SGreg Clayton                                                     else
22616d3dbf51SGreg Clayton                                                     {
22626d3dbf51SGreg Clayton                                                         s.PutCString (cstr);
22636d3dbf51SGreg Clayton                                                         s.PutChar ('(');
22646d3dbf51SGreg Clayton                                                     }
22655b6889b1SGreg Clayton                                                     const size_t num_args = args.GetSize();
22666d3dbf51SGreg Clayton                                                     for (size_t arg_idx = 0; arg_idx < num_args; ++arg_idx)
22676d3dbf51SGreg Clayton                                                     {
22686d3dbf51SGreg Clayton                                                         VariableSP var_sp (args.GetVariableAtIndex (arg_idx));
22696d3dbf51SGreg Clayton                                                         ValueObjectSP var_value_sp (ValueObjectVariable::Create (exe_scope, var_sp));
22706d3dbf51SGreg Clayton                                                         const char *var_name = var_value_sp->GetName().GetCString();
22716d3dbf51SGreg Clayton                                                         const char *var_value = var_value_sp->GetValueAsCString();
22726d3dbf51SGreg Clayton                                                         if (arg_idx > 0)
22736d3dbf51SGreg Clayton                                                             s.PutCString (", ");
22743b188b17SGreg Clayton                                                         if (var_value_sp->GetError().Success())
22756d3dbf51SGreg Clayton                                                             s.Printf ("%s=%s", var_name, var_value);
22763b188b17SGreg Clayton                                                         else
22773b188b17SGreg Clayton                                                             s.Printf ("%s=<unavailable>", var_name);
22786d3dbf51SGreg Clayton                                                     }
22796d3dbf51SGreg Clayton 
22806d3dbf51SGreg Clayton                                                     if (close_paren)
22816d3dbf51SGreg Clayton                                                         s.PutCString (close_paren);
22826d3dbf51SGreg Clayton                                                     else
22836d3dbf51SGreg Clayton                                                         s.PutChar(')');
22846d3dbf51SGreg Clayton 
22856d3dbf51SGreg Clayton                                                 }
22866d3dbf51SGreg Clayton                                                 else
22876d3dbf51SGreg Clayton                                                 {
22886d3dbf51SGreg Clayton                                                     s.PutCString(cstr);
22896d3dbf51SGreg Clayton                                                 }
22906d3dbf51SGreg Clayton                                             }
22916d3dbf51SGreg Clayton                                         }
22926d3dbf51SGreg Clayton                                         else if (sc->symbol)
22936d3dbf51SGreg Clayton                                         {
22946d3dbf51SGreg Clayton                                             cstr = sc->symbol->GetName().AsCString (NULL);
22956d3dbf51SGreg Clayton                                             if (cstr)
22966d3dbf51SGreg Clayton                                             {
22976d3dbf51SGreg Clayton                                                 s.PutCString(cstr);
22986d3dbf51SGreg Clayton                                                 var_success = true;
22996d3dbf51SGreg Clayton                                             }
23006d3dbf51SGreg Clayton                                         }
23016d3dbf51SGreg Clayton                                     }
23021b654882SGreg Clayton                                     else if (::strncmp (var_name_begin, "addr-offset}", strlen("addr-offset}")) == 0)
23031b654882SGreg Clayton                                     {
23041b654882SGreg Clayton                                         var_success = addr != NULL;
23051b654882SGreg Clayton                                         if (var_success)
23061b654882SGreg Clayton                                         {
23071b654882SGreg Clayton                                             format_addr = *addr;
23081b654882SGreg Clayton                                             calculate_format_addr_function_offset = true;
23091b654882SGreg Clayton                                         }
23101b654882SGreg Clayton                                     }
23111b654882SGreg Clayton                                     else if (::strncmp (var_name_begin, "line-offset}", strlen("line-offset}")) == 0)
23121b654882SGreg Clayton                                     {
23131b654882SGreg Clayton                                         var_success = sc->line_entry.range.GetBaseAddress().IsValid();
23141b654882SGreg Clayton                                         if (var_success)
23151b654882SGreg Clayton                                         {
23161b654882SGreg Clayton                                             format_addr = sc->line_entry.range.GetBaseAddress();
23171b654882SGreg Clayton                                             calculate_format_addr_function_offset = true;
23181b654882SGreg Clayton                                         }
23191b654882SGreg Clayton                                     }
23201b654882SGreg Clayton                                     else if (::strncmp (var_name_begin, "pc-offset}", strlen("pc-offset}")) == 0)
23211b654882SGreg Clayton                                     {
2322c14ee32dSGreg Clayton                                         StackFrame *frame = exe_ctx->GetFramePtr();
2323c14ee32dSGreg Clayton                                         var_success = frame != NULL;
23241b654882SGreg Clayton                                         if (var_success)
23251b654882SGreg Clayton                                         {
2326c14ee32dSGreg Clayton                                             format_addr = frame->GetFrameCodeAddress();
23271b654882SGreg Clayton                                             calculate_format_addr_function_offset = true;
23281b654882SGreg Clayton                                         }
23291b654882SGreg Clayton                                     }
23301b654882SGreg Clayton                                 }
23311b654882SGreg Clayton                             }
23321b654882SGreg Clayton                             break;
23331b654882SGreg Clayton 
23341b654882SGreg Clayton                         case 'l':
23351b654882SGreg Clayton                             if (::strncmp (var_name_begin, "line.", strlen("line.")) == 0)
23361b654882SGreg Clayton                             {
23371b654882SGreg Clayton                                 if (sc && sc->line_entry.IsValid())
23381b654882SGreg Clayton                                 {
23391b654882SGreg Clayton                                     var_name_begin += ::strlen ("line.");
23401b654882SGreg Clayton                                     if (::strncmp (var_name_begin, "file.", strlen("file.")) == 0)
23411b654882SGreg Clayton                                     {
23421b654882SGreg Clayton                                         var_name_begin += ::strlen ("file.");
23431b654882SGreg Clayton 
23441b654882SGreg Clayton                                         if (::strncmp (var_name_begin, "basename}", strlen("basename}")) == 0)
23451b654882SGreg Clayton                                         {
23461b654882SGreg Clayton                                             format_file_spec.GetFilename() = sc->line_entry.file.GetFilename();
23471b654882SGreg Clayton                                             var_success = format_file_spec;
23481b654882SGreg Clayton                                         }
23491b654882SGreg Clayton                                         else if (::strncmp (var_name_begin, "fullpath}", strlen("fullpath}")) == 0)
23501b654882SGreg Clayton                                         {
23511b654882SGreg Clayton                                             format_file_spec = sc->line_entry.file;
23521b654882SGreg Clayton                                             var_success = format_file_spec;
23531b654882SGreg Clayton                                         }
23541b654882SGreg Clayton                                     }
23551b654882SGreg Clayton                                     else if (::strncmp (var_name_begin, "number}", strlen("number}")) == 0)
23561b654882SGreg Clayton                                     {
23571b654882SGreg Clayton                                         var_success = true;
23581b654882SGreg Clayton                                         s.Printf("%u", sc->line_entry.line);
23591b654882SGreg Clayton                                     }
23601b654882SGreg Clayton                                     else if ((::strncmp (var_name_begin, "start-addr}", strlen("start-addr}")) == 0) ||
23611b654882SGreg Clayton                                              (::strncmp (var_name_begin, "end-addr}", strlen("end-addr}")) == 0))
23621b654882SGreg Clayton                                     {
23631b654882SGreg Clayton                                         var_success = sc && sc->line_entry.range.GetBaseAddress().IsValid();
23641b654882SGreg Clayton                                         if (var_success)
23651b654882SGreg Clayton                                         {
23661b654882SGreg Clayton                                             format_addr = sc->line_entry.range.GetBaseAddress();
23671b654882SGreg Clayton                                             if (var_name_begin[0] == 'e')
23681b654882SGreg Clayton                                                 format_addr.Slide (sc->line_entry.range.GetByteSize());
23691b654882SGreg Clayton                                         }
23701b654882SGreg Clayton                                     }
23711b654882SGreg Clayton                                 }
23721b654882SGreg Clayton                             }
23731b654882SGreg Clayton                             break;
23741b654882SGreg Clayton                         }
23751b654882SGreg Clayton 
23761b654882SGreg Clayton                         if (var_success)
23771b654882SGreg Clayton                         {
23781b654882SGreg Clayton                             // If format addr is valid, then we need to print an address
23791b654882SGreg Clayton                             if (reg_num != LLDB_INVALID_REGNUM)
23801b654882SGreg Clayton                             {
2381c14ee32dSGreg Clayton                                 StackFrame *frame = exe_ctx->GetFramePtr();
23821b654882SGreg Clayton                                 // We have a register value to display...
23831b654882SGreg Clayton                                 if (reg_num == LLDB_REGNUM_GENERIC_PC && reg_kind == eRegisterKindGeneric)
23841b654882SGreg Clayton                                 {
2385c14ee32dSGreg Clayton                                     format_addr = frame->GetFrameCodeAddress();
23861b654882SGreg Clayton                                 }
23871b654882SGreg Clayton                                 else
23881b654882SGreg Clayton                                 {
23891b654882SGreg Clayton                                     if (reg_ctx == NULL)
2390c14ee32dSGreg Clayton                                         reg_ctx = frame->GetRegisterContext().get();
23911b654882SGreg Clayton 
23921b654882SGreg Clayton                                     if (reg_ctx)
23931b654882SGreg Clayton                                     {
23941b654882SGreg Clayton                                         if (reg_kind != kNumRegisterKinds)
23951b654882SGreg Clayton                                             reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(reg_kind, reg_num);
23961b654882SGreg Clayton                                         reg_info = reg_ctx->GetRegisterInfoAtIndex (reg_num);
23971b654882SGreg Clayton                                         var_success = reg_info != NULL;
23981b654882SGreg Clayton                                     }
23991b654882SGreg Clayton                                 }
24001b654882SGreg Clayton                             }
24011b654882SGreg Clayton 
24021b654882SGreg Clayton                             if (reg_info != NULL)
24031b654882SGreg Clayton                             {
24047349bd90SGreg Clayton                                 RegisterValue reg_value;
24057349bd90SGreg Clayton                                 var_success = reg_ctx->ReadRegister (reg_info, reg_value);
24067349bd90SGreg Clayton                                 if (var_success)
24071b654882SGreg Clayton                                 {
24089a8fa916SGreg Clayton                                     reg_value.Dump(&s, reg_info, false, false, eFormatDefault);
24091b654882SGreg Clayton                                 }
24101b654882SGreg Clayton                             }
24111b654882SGreg Clayton 
24121b654882SGreg Clayton                             if (format_file_spec)
24131b654882SGreg Clayton                             {
24141b654882SGreg Clayton                                 s << format_file_spec;
24151b654882SGreg Clayton                             }
24161b654882SGreg Clayton 
24171b654882SGreg Clayton                             // If format addr is valid, then we need to print an address
24181b654882SGreg Clayton                             if (format_addr.IsValid())
24191b654882SGreg Clayton                             {
24200603aa9dSGreg Clayton                                 var_success = false;
24210603aa9dSGreg Clayton 
24221b654882SGreg Clayton                                 if (calculate_format_addr_function_offset)
24231b654882SGreg Clayton                                 {
24241b654882SGreg Clayton                                     Address func_addr;
24250603aa9dSGreg Clayton 
24260603aa9dSGreg Clayton                                     if (sc)
24270603aa9dSGreg Clayton                                     {
24281b654882SGreg Clayton                                         if (sc->function)
24290d9c9934SGreg Clayton                                         {
24301b654882SGreg Clayton                                             func_addr = sc->function->GetAddressRange().GetBaseAddress();
24310d9c9934SGreg Clayton                                             if (sc->block)
24320d9c9934SGreg Clayton                                             {
24330d9c9934SGreg Clayton                                                 // Check to make sure we aren't in an inline
24340d9c9934SGreg Clayton                                                 // function. If we are, use the inline block
24350d9c9934SGreg Clayton                                                 // range that contains "format_addr" since
24360d9c9934SGreg Clayton                                                 // blocks can be discontiguous.
24370d9c9934SGreg Clayton                                                 Block *inline_block = sc->block->GetContainingInlinedBlock ();
24380d9c9934SGreg Clayton                                                 AddressRange inline_range;
24390d9c9934SGreg Clayton                                                 if (inline_block && inline_block->GetRangeContainingAddress (format_addr, inline_range))
24400d9c9934SGreg Clayton                                                     func_addr = inline_range.GetBaseAddress();
24410d9c9934SGreg Clayton                                             }
24420d9c9934SGreg Clayton                                         }
2443e7612134SGreg Clayton                                         else if (sc->symbol && sc->symbol->ValueIsAddress())
2444e7612134SGreg Clayton                                             func_addr = sc->symbol->GetAddress();
24450603aa9dSGreg Clayton                                     }
24461b654882SGreg Clayton 
24470603aa9dSGreg Clayton                                     if (func_addr.IsValid())
24481b654882SGreg Clayton                                     {
24491b654882SGreg Clayton                                         if (func_addr.GetSection() == format_addr.GetSection())
24501b654882SGreg Clayton                                         {
24511b654882SGreg Clayton                                             addr_t func_file_addr = func_addr.GetFileAddress();
24521b654882SGreg Clayton                                             addr_t addr_file_addr = format_addr.GetFileAddress();
24531b654882SGreg Clayton                                             if (addr_file_addr > func_file_addr)
2454d01b2953SDaniel Malea                                                 s.Printf(" + %" PRIu64, addr_file_addr - func_file_addr);
24551b654882SGreg Clayton                                             else if (addr_file_addr < func_file_addr)
2456d01b2953SDaniel Malea                                                 s.Printf(" - %" PRIu64, func_file_addr - addr_file_addr);
24570603aa9dSGreg Clayton                                             var_success = true;
24581b654882SGreg Clayton                                         }
24591b654882SGreg Clayton                                         else
24600603aa9dSGreg Clayton                                         {
24610603aa9dSGreg Clayton                                             Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
24620603aa9dSGreg Clayton                                             if (target)
24630603aa9dSGreg Clayton                                             {
24640603aa9dSGreg Clayton                                                 addr_t func_load_addr = func_addr.GetLoadAddress (target);
24650603aa9dSGreg Clayton                                                 addr_t addr_load_addr = format_addr.GetLoadAddress (target);
24660603aa9dSGreg Clayton                                                 if (addr_load_addr > func_load_addr)
2467d01b2953SDaniel Malea                                                     s.Printf(" + %" PRIu64, addr_load_addr - func_load_addr);
24680603aa9dSGreg Clayton                                                 else if (addr_load_addr < func_load_addr)
2469d01b2953SDaniel Malea                                                     s.Printf(" - %" PRIu64, func_load_addr - addr_load_addr);
24700603aa9dSGreg Clayton                                                 var_success = true;
24710603aa9dSGreg Clayton                                             }
24720603aa9dSGreg Clayton                                         }
24731b654882SGreg Clayton                                     }
24741b654882SGreg Clayton                                 }
24751b654882SGreg Clayton                                 else
24761b654882SGreg Clayton                                 {
24770603aa9dSGreg Clayton                                     Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
24781b654882SGreg Clayton                                     addr_t vaddr = LLDB_INVALID_ADDRESS;
24790603aa9dSGreg Clayton                                     if (exe_ctx && !target->GetSectionLoadList().IsEmpty())
24800603aa9dSGreg Clayton                                         vaddr = format_addr.GetLoadAddress (target);
24811b654882SGreg Clayton                                     if (vaddr == LLDB_INVALID_ADDRESS)
24821b654882SGreg Clayton                                         vaddr = format_addr.GetFileAddress ();
24831b654882SGreg Clayton 
24841b654882SGreg Clayton                                     if (vaddr != LLDB_INVALID_ADDRESS)
24850603aa9dSGreg Clayton                                     {
2486514487e8SGreg Clayton                                         int addr_width = target->GetArchitecture().GetAddressByteSize() * 2;
248735f1a0d5SGreg Clayton                                         if (addr_width == 0)
248835f1a0d5SGreg Clayton                                             addr_width = 16;
2489d01b2953SDaniel Malea                                         s.Printf("0x%*.*" PRIx64, addr_width, addr_width, vaddr);
24900603aa9dSGreg Clayton                                         var_success = true;
24910603aa9dSGreg Clayton                                     }
24921b654882SGreg Clayton                                 }
24931b654882SGreg Clayton                             }
24941b654882SGreg Clayton                         }
24951b654882SGreg Clayton 
24961b654882SGreg Clayton                         if (var_success == false)
24971b654882SGreg Clayton                             success = false;
24981b654882SGreg Clayton                     }
24991b654882SGreg Clayton                     p = var_name_end;
25001b654882SGreg Clayton                 }
25011b654882SGreg Clayton                 else
25021b654882SGreg Clayton                     break;
25031b654882SGreg Clayton             }
25041b654882SGreg Clayton             else
25051b654882SGreg Clayton             {
25061b654882SGreg Clayton                 // We got a dollar sign with no '{' after it, it must just be a dollar sign
25071b654882SGreg Clayton                 s.PutChar(*p);
25081b654882SGreg Clayton             }
25091b654882SGreg Clayton         }
25101b654882SGreg Clayton         else if (*p == '\\')
25111b654882SGreg Clayton         {
25121b654882SGreg Clayton             ++p; // skip the slash
25131b654882SGreg Clayton             switch (*p)
25141b654882SGreg Clayton             {
25151b654882SGreg Clayton             case 'a': s.PutChar ('\a'); break;
25161b654882SGreg Clayton             case 'b': s.PutChar ('\b'); break;
25171b654882SGreg Clayton             case 'f': s.PutChar ('\f'); break;
25181b654882SGreg Clayton             case 'n': s.PutChar ('\n'); break;
25191b654882SGreg Clayton             case 'r': s.PutChar ('\r'); break;
25201b654882SGreg Clayton             case 't': s.PutChar ('\t'); break;
25211b654882SGreg Clayton             case 'v': s.PutChar ('\v'); break;
25221b654882SGreg Clayton             case '\'': s.PutChar ('\''); break;
25231b654882SGreg Clayton             case '\\': s.PutChar ('\\'); break;
25241b654882SGreg Clayton             case '0':
25251b654882SGreg Clayton                 // 1 to 3 octal chars
25261b654882SGreg Clayton                 {
25270603aa9dSGreg Clayton                     // Make a string that can hold onto the initial zero char,
25280603aa9dSGreg Clayton                     // up to 3 octal digits, and a terminating NULL.
25290603aa9dSGreg Clayton                     char oct_str[5] = { 0, 0, 0, 0, 0 };
25300603aa9dSGreg Clayton 
25310603aa9dSGreg Clayton                     int i;
25320603aa9dSGreg Clayton                     for (i=0; (p[i] >= '0' && p[i] <= '7') && i<4; ++i)
25330603aa9dSGreg Clayton                         oct_str[i] = p[i];
25340603aa9dSGreg Clayton 
25350603aa9dSGreg Clayton                     // We don't want to consume the last octal character since
25360603aa9dSGreg Clayton                     // the main for loop will do this for us, so we advance p by
25370603aa9dSGreg Clayton                     // one less than i (even if i is zero)
25380603aa9dSGreg Clayton                     p += i - 1;
25390603aa9dSGreg Clayton                     unsigned long octal_value = ::strtoul (oct_str, NULL, 8);
25400603aa9dSGreg Clayton                     if (octal_value <= UINT8_MAX)
25411b654882SGreg Clayton                     {
25420603aa9dSGreg Clayton                         char octal_char = octal_value;
25430603aa9dSGreg Clayton                         s.Write (&octal_char, 1);
25441b654882SGreg Clayton                     }
25451b654882SGreg Clayton                 }
25461b654882SGreg Clayton                 break;
25471b654882SGreg Clayton 
25481b654882SGreg Clayton             case 'x':
25491b654882SGreg Clayton                 // hex number in the format
25500603aa9dSGreg Clayton                 if (isxdigit(p[1]))
25511b654882SGreg Clayton                 {
25520603aa9dSGreg Clayton                     ++p;    // Skip the 'x'
25531b654882SGreg Clayton 
25540603aa9dSGreg Clayton                     // Make a string that can hold onto two hex chars plus a
25550603aa9dSGreg Clayton                     // NULL terminator
25561b654882SGreg Clayton                     char hex_str[3] = { 0,0,0 };
25571b654882SGreg Clayton                     hex_str[0] = *p;
25580603aa9dSGreg Clayton                     if (isxdigit(p[1]))
25590603aa9dSGreg Clayton                     {
25600603aa9dSGreg Clayton                         ++p; // Skip the first of the two hex chars
25611b654882SGreg Clayton                         hex_str[1] = *p;
25620603aa9dSGreg Clayton                     }
25630603aa9dSGreg Clayton 
25641b654882SGreg Clayton                     unsigned long hex_value = strtoul (hex_str, NULL, 16);
25650603aa9dSGreg Clayton                     if (hex_value <= UINT8_MAX)
25661b654882SGreg Clayton                         s.PutChar (hex_value);
25671b654882SGreg Clayton                 }
25681b654882SGreg Clayton                 else
25691b654882SGreg Clayton                 {
25700603aa9dSGreg Clayton                     s.PutChar('x');
25711b654882SGreg Clayton                 }
25721b654882SGreg Clayton                 break;
25731b654882SGreg Clayton 
25741b654882SGreg Clayton             default:
25750603aa9dSGreg Clayton                 // Just desensitize any other character by just printing what
25760603aa9dSGreg Clayton                 // came after the '\'
25770603aa9dSGreg Clayton                 s << *p;
25781b654882SGreg Clayton                 break;
25791b654882SGreg Clayton 
25801b654882SGreg Clayton             }
25811b654882SGreg Clayton 
25821b654882SGreg Clayton         }
25831b654882SGreg Clayton     }
25841b654882SGreg Clayton     if (end)
25851b654882SGreg Clayton         *end = p;
25861b654882SGreg Clayton     return success;
25871b654882SGreg Clayton }
25881b654882SGreg Clayton 
2589228063cdSJim Ingham void
2590228063cdSJim Ingham Debugger::SetLoggingCallback (lldb::LogOutputCallback log_callback, void *baton)
2591228063cdSJim Ingham {
25924f02b22dSJim Ingham     // For simplicity's sake, I am not going to deal with how to close down any
25934f02b22dSJim Ingham     // open logging streams, I just redirect everything from here on out to the
25944f02b22dSJim Ingham     // callback.
2595228063cdSJim Ingham     m_log_callback_stream_sp.reset (new StreamCallback (log_callback, baton));
2596228063cdSJim Ingham }
2597228063cdSJim Ingham 
2598228063cdSJim Ingham bool
2599228063cdSJim Ingham Debugger::EnableLog (const char *channel, const char **categories, const char *log_file, uint32_t log_options, Stream &error_stream)
2600228063cdSJim Ingham {
2601228063cdSJim Ingham     Log::Callbacks log_callbacks;
2602228063cdSJim Ingham 
2603228063cdSJim Ingham     StreamSP log_stream_sp;
26049a028519SSean Callanan     if (m_log_callback_stream_sp)
2605228063cdSJim Ingham     {
2606228063cdSJim Ingham         log_stream_sp = m_log_callback_stream_sp;
2607228063cdSJim Ingham         // For now when using the callback mode you always get thread & timestamp.
2608228063cdSJim Ingham         log_options |= LLDB_LOG_OPTION_PREPEND_TIMESTAMP | LLDB_LOG_OPTION_PREPEND_THREAD_NAME;
2609228063cdSJim Ingham     }
2610228063cdSJim Ingham     else if (log_file == NULL || *log_file == '\0')
2611228063cdSJim Ingham     {
2612228063cdSJim Ingham         log_stream_sp.reset(new StreamFile(GetOutputFile().GetDescriptor(), false));
2613228063cdSJim Ingham     }
2614228063cdSJim Ingham     else
2615228063cdSJim Ingham     {
2616228063cdSJim Ingham         LogStreamMap::iterator pos = m_log_streams.find(log_file);
2617*c1b2ccfdSGreg Clayton         if (pos != m_log_streams.end())
2618*c1b2ccfdSGreg Clayton             log_stream_sp = pos->second.lock();
2619*c1b2ccfdSGreg Clayton         if (!log_stream_sp)
2620228063cdSJim Ingham         {
2621228063cdSJim Ingham             log_stream_sp.reset (new StreamFile (log_file));
2622228063cdSJim Ingham             m_log_streams[log_file] = log_stream_sp;
2623228063cdSJim Ingham         }
2624228063cdSJim Ingham     }
2625228063cdSJim Ingham     assert (log_stream_sp.get());
2626228063cdSJim Ingham 
2627228063cdSJim Ingham     if (log_options == 0)
2628228063cdSJim Ingham         log_options = LLDB_LOG_OPTION_PREPEND_THREAD_NAME | LLDB_LOG_OPTION_THREADSAFE;
2629228063cdSJim Ingham 
2630228063cdSJim Ingham     if (Log::GetLogChannelCallbacks (channel, log_callbacks))
2631228063cdSJim Ingham     {
2632228063cdSJim Ingham         log_callbacks.enable (log_stream_sp, log_options, categories, &error_stream);
2633228063cdSJim Ingham         return true;
2634228063cdSJim Ingham     }
2635228063cdSJim Ingham     else
2636228063cdSJim Ingham     {
2637228063cdSJim Ingham         LogChannelSP log_channel_sp (LogChannel::FindPlugin (channel));
2638228063cdSJim Ingham         if (log_channel_sp)
2639228063cdSJim Ingham         {
2640228063cdSJim Ingham             if (log_channel_sp->Enable (log_stream_sp, log_options, &error_stream, categories))
2641228063cdSJim Ingham             {
2642228063cdSJim Ingham                 return true;
2643228063cdSJim Ingham             }
2644228063cdSJim Ingham             else
2645228063cdSJim Ingham             {
2646228063cdSJim Ingham                 error_stream.Printf ("Invalid log channel '%s'.\n", channel);
2647228063cdSJim Ingham                 return false;
2648228063cdSJim Ingham             }
2649228063cdSJim Ingham         }
2650228063cdSJim Ingham         else
2651228063cdSJim Ingham         {
2652228063cdSJim Ingham             error_stream.Printf ("Invalid log channel '%s'.\n", channel);
2653228063cdSJim Ingham             return false;
2654228063cdSJim Ingham         }
2655228063cdSJim Ingham     }
2656228063cdSJim Ingham     return false;
2657228063cdSJim Ingham }
2658228063cdSJim Ingham 
2659