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"
2330fdc8d8SChris Lattner #include "lldb/Core/InputReader.h"
241f746071SGreg Clayton #include "lldb/Core/Module.h"
25e8cd0c98SGreg Clayton #include "lldb/Core/PluginManager.h"
267349bd90SGreg Clayton #include "lldb/Core/RegisterValue.h"
2730fdc8d8SChris Lattner #include "lldb/Core/State.h"
285b52f0c7SJim Ingham #include "lldb/Core/StreamAsynchronousIO.h"
29228063cdSJim Ingham #include "lldb/Core/StreamCallback.h"
301b654882SGreg Clayton #include "lldb/Core/StreamString.h"
3130fdc8d8SChris Lattner #include "lldb/Core/Timer.h"
324becb37eSEnrico Granata #include "lldb/Core/ValueObject.h"
336d3dbf51SGreg Clayton #include "lldb/Core/ValueObjectVariable.h"
345548cb50SEnrico Granata #include "lldb/DataFormatters/DataVisualization.h"
355548cb50SEnrico Granata #include "lldb/DataFormatters/FormatManager.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\
10585d0c57bSGreg Clayton     "{, name = '${thread.name}}"\
10685d0c57bSGreg Clayton     "{, queue = '${thread.queue}}"\
10767cc0636SGreg Clayton     "{, stop reason = ${thread.stop-reason}}"\
10867cc0636SGreg Clayton     "{\\nReturn value: ${thread.return-value}}"\
10967cc0636SGreg Clayton     "\\n"
11067cc0636SGreg Clayton 
11167cc0636SGreg Clayton #define DEFAULT_FRAME_FORMAT "frame #${frame.index}: ${frame.pc}"\
11267cc0636SGreg Clayton     MODULE_WITH_FUNC\
11367cc0636SGreg Clayton     FILE_AND_LINE\
11467cc0636SGreg Clayton     "\\n"
11567cc0636SGreg Clayton 
11667cc0636SGreg Clayton 
11767cc0636SGreg Clayton 
118754a9369SGreg Clayton static PropertyDefinition
119754a9369SGreg Clayton g_properties[] =
12067cc0636SGreg Clayton {
12167cc0636SGreg Clayton {   "auto-confirm",             OptionValue::eTypeBoolean, true, false, NULL, NULL, "If true all confirmation prompts will receive their default reply." },
12267cc0636SGreg 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." },
12367cc0636SGreg Clayton {   "notify-void",              OptionValue::eTypeBoolean, true, false, NULL, NULL, "Notify the user explicitly if an expression returns void (default: false)." },
1244c05410fSGreg Clayton {   "prompt",                   OptionValue::eTypeString , true, OptionValueString::eOptionEncodeCharacterEscapeSequences, "(lldb) ", NULL, "The debugger command line prompt displayed for the user." },
12567cc0636SGreg Clayton {   "script-lang",              OptionValue::eTypeEnum   , true, eScriptLanguagePython, NULL, g_language_enumerators, "The script language to be used for evaluating user-written scripts." },
12667cc0636SGreg Clayton {   "stop-disassembly-count",   OptionValue::eTypeSInt64 , true, 4    , NULL, NULL, "The number of disassembly lines to show when displaying a stopped context." },
12767cc0636SGreg 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." },
12867cc0636SGreg 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." },
12967cc0636SGreg 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." },
13067cc0636SGreg Clayton {   "term-width",               OptionValue::eTypeSInt64 , true, 80   , NULL, NULL, "The maximum number of columns to use for displaying text." },
13167cc0636SGreg Clayton {   "thread-format",            OptionValue::eTypeString , true, 0    , DEFAULT_THREAD_FORMAT, NULL, "The default thread format string to use when displaying thread information." },
13267cc0636SGreg Clayton {   "use-external-editor",      OptionValue::eTypeBoolean, true, false, NULL, NULL, "Whether to use an external editor or not." },
133e8cd0c98SGreg Clayton 
13467cc0636SGreg Clayton     {   NULL,                       OptionValue::eTypeInvalid, true, 0    , NULL, NULL, NULL }
13567cc0636SGreg Clayton };
13667cc0636SGreg Clayton 
13767cc0636SGreg Clayton enum
13867cc0636SGreg Clayton {
13967cc0636SGreg Clayton     ePropertyAutoConfirm = 0,
14067cc0636SGreg Clayton     ePropertyFrameFormat,
14167cc0636SGreg Clayton     ePropertyNotiftVoid,
14267cc0636SGreg Clayton     ePropertyPrompt,
14367cc0636SGreg Clayton     ePropertyScriptLanguage,
14467cc0636SGreg Clayton     ePropertyStopDisassemblyCount,
14567cc0636SGreg Clayton     ePropertyStopDisassemblyDisplay,
14667cc0636SGreg Clayton     ePropertyStopLineCountAfter,
14767cc0636SGreg Clayton     ePropertyStopLineCountBefore,
14867cc0636SGreg Clayton     ePropertyTerminalWidth,
14967cc0636SGreg Clayton     ePropertyThreadFormat,
15067cc0636SGreg Clayton     ePropertyUseExternalEditor
15167cc0636SGreg Clayton };
15267cc0636SGreg Clayton 
15367cc0636SGreg Clayton //
15467cc0636SGreg Clayton //const char *
15567cc0636SGreg Clayton //Debugger::GetFrameFormat() const
15667cc0636SGreg Clayton //{
15767cc0636SGreg Clayton //    return m_properties_sp->GetFrameFormat();
15867cc0636SGreg Clayton //}
15967cc0636SGreg Clayton //const char *
16067cc0636SGreg Clayton //Debugger::GetThreadFormat() const
16167cc0636SGreg Clayton //{
16267cc0636SGreg Clayton //    return m_properties_sp->GetThreadFormat();
16367cc0636SGreg Clayton //}
16467cc0636SGreg Clayton //
1654c05410fSGreg Clayton 
1664c05410fSGreg Clayton 
1674c05410fSGreg Clayton Error
1684c05410fSGreg Clayton Debugger::SetPropertyValue (const ExecutionContext *exe_ctx,
1694c05410fSGreg Clayton                             VarSetOperationType op,
1704c05410fSGreg Clayton                             const char *property_path,
1714c05410fSGreg Clayton                             const char *value)
1724c05410fSGreg Clayton {
1734c05410fSGreg Clayton     Error error (Properties::SetPropertyValue (exe_ctx, op, property_path, value));
1744c05410fSGreg Clayton     if (error.Success())
1754c05410fSGreg Clayton     {
1764c05410fSGreg Clayton         if (strcmp(property_path, g_properties[ePropertyPrompt].name) == 0)
1774c05410fSGreg Clayton         {
1784c05410fSGreg Clayton             const char *new_prompt = GetPrompt();
1794c05410fSGreg Clayton             EventSP prompt_change_event_sp (new Event(CommandInterpreter::eBroadcastBitResetPrompt, new EventDataBytes (new_prompt)));
1804c05410fSGreg Clayton             GetCommandInterpreter().BroadcastEvent (prompt_change_event_sp);
1814c05410fSGreg Clayton         }
1824c05410fSGreg Clayton     }
1834c05410fSGreg Clayton     return error;
1844c05410fSGreg Clayton }
1854c05410fSGreg Clayton 
18667cc0636SGreg Clayton bool
18767cc0636SGreg Clayton Debugger::GetAutoConfirm () const
18867cc0636SGreg Clayton {
18967cc0636SGreg Clayton     const uint32_t idx = ePropertyAutoConfirm;
190754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
19167cc0636SGreg Clayton }
19267cc0636SGreg Clayton 
19367cc0636SGreg Clayton const char *
19467cc0636SGreg Clayton Debugger::GetFrameFormat() const
19567cc0636SGreg Clayton {
19667cc0636SGreg Clayton     const uint32_t idx = ePropertyFrameFormat;
197754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsString (NULL, idx, g_properties[idx].default_cstr_value);
19867cc0636SGreg Clayton }
19967cc0636SGreg Clayton 
20067cc0636SGreg Clayton bool
20167cc0636SGreg Clayton Debugger::GetNotifyVoid () const
20267cc0636SGreg Clayton {
20367cc0636SGreg Clayton     const uint32_t idx = ePropertyNotiftVoid;
204754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
20567cc0636SGreg Clayton }
20667cc0636SGreg Clayton 
20767cc0636SGreg Clayton const char *
20867cc0636SGreg Clayton Debugger::GetPrompt() const
20967cc0636SGreg Clayton {
21067cc0636SGreg Clayton     const uint32_t idx = ePropertyPrompt;
211754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsString (NULL, idx, g_properties[idx].default_cstr_value);
21267cc0636SGreg Clayton }
21367cc0636SGreg Clayton 
21467cc0636SGreg Clayton void
21567cc0636SGreg Clayton Debugger::SetPrompt(const char *p)
21667cc0636SGreg Clayton {
21767cc0636SGreg Clayton     const uint32_t idx = ePropertyPrompt;
21867cc0636SGreg Clayton     m_collection_sp->SetPropertyAtIndexAsString (NULL, idx, p);
21967cc0636SGreg Clayton     const char *new_prompt = GetPrompt();
22067cc0636SGreg Clayton     EventSP prompt_change_event_sp (new Event(CommandInterpreter::eBroadcastBitResetPrompt, new EventDataBytes (new_prompt)));;
22167cc0636SGreg Clayton     GetCommandInterpreter().BroadcastEvent (prompt_change_event_sp);
22267cc0636SGreg Clayton }
22367cc0636SGreg Clayton 
22467cc0636SGreg Clayton const char *
22567cc0636SGreg Clayton Debugger::GetThreadFormat() const
22667cc0636SGreg Clayton {
22767cc0636SGreg Clayton     const uint32_t idx = ePropertyThreadFormat;
228754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsString (NULL, idx, g_properties[idx].default_cstr_value);
22967cc0636SGreg Clayton }
23067cc0636SGreg Clayton 
23167cc0636SGreg Clayton lldb::ScriptLanguage
23267cc0636SGreg Clayton Debugger::GetScriptLanguage() const
23367cc0636SGreg Clayton {
23467cc0636SGreg Clayton     const uint32_t idx = ePropertyScriptLanguage;
235754a9369SGreg Clayton     return (lldb::ScriptLanguage)m_collection_sp->GetPropertyAtIndexAsEnumeration (NULL, idx, g_properties[idx].default_uint_value);
23667cc0636SGreg Clayton }
23767cc0636SGreg Clayton 
23867cc0636SGreg Clayton bool
23967cc0636SGreg Clayton Debugger::SetScriptLanguage (lldb::ScriptLanguage script_lang)
24067cc0636SGreg Clayton {
24167cc0636SGreg Clayton     const uint32_t idx = ePropertyScriptLanguage;
24267cc0636SGreg Clayton     return m_collection_sp->SetPropertyAtIndexAsEnumeration (NULL, idx, script_lang);
24367cc0636SGreg Clayton }
24467cc0636SGreg Clayton 
24567cc0636SGreg Clayton uint32_t
24667cc0636SGreg Clayton Debugger::GetTerminalWidth () const
24767cc0636SGreg Clayton {
24867cc0636SGreg Clayton     const uint32_t idx = ePropertyTerminalWidth;
249754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsSInt64 (NULL, idx, g_properties[idx].default_uint_value);
25067cc0636SGreg Clayton }
25167cc0636SGreg Clayton 
25267cc0636SGreg Clayton bool
25367cc0636SGreg Clayton Debugger::SetTerminalWidth (uint32_t term_width)
25467cc0636SGreg Clayton {
25567cc0636SGreg Clayton     const uint32_t idx = ePropertyTerminalWidth;
25667cc0636SGreg Clayton     return m_collection_sp->SetPropertyAtIndexAsSInt64 (NULL, idx, term_width);
25767cc0636SGreg Clayton }
25867cc0636SGreg Clayton 
25967cc0636SGreg Clayton bool
26067cc0636SGreg Clayton Debugger::GetUseExternalEditor () const
26167cc0636SGreg Clayton {
26267cc0636SGreg Clayton     const uint32_t idx = ePropertyUseExternalEditor;
263754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
26467cc0636SGreg Clayton }
26567cc0636SGreg Clayton 
26667cc0636SGreg Clayton bool
26767cc0636SGreg Clayton Debugger::SetUseExternalEditor (bool b)
26867cc0636SGreg Clayton {
26967cc0636SGreg Clayton     const uint32_t idx = ePropertyUseExternalEditor;
27067cc0636SGreg Clayton     return m_collection_sp->SetPropertyAtIndexAsBoolean (NULL, idx, b);
27167cc0636SGreg Clayton }
27267cc0636SGreg Clayton 
27367cc0636SGreg Clayton uint32_t
27467cc0636SGreg Clayton Debugger::GetStopSourceLineCount (bool before) const
27567cc0636SGreg Clayton {
27667cc0636SGreg Clayton     const uint32_t idx = before ? ePropertyStopLineCountBefore : ePropertyStopLineCountAfter;
277754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsSInt64 (NULL, idx, g_properties[idx].default_uint_value);
27867cc0636SGreg Clayton }
27967cc0636SGreg Clayton 
28067cc0636SGreg Clayton Debugger::StopDisassemblyType
28167cc0636SGreg Clayton Debugger::GetStopDisassemblyDisplay () const
28267cc0636SGreg Clayton {
28367cc0636SGreg Clayton     const uint32_t idx = ePropertyStopDisassemblyDisplay;
284754a9369SGreg Clayton     return (Debugger::StopDisassemblyType)m_collection_sp->GetPropertyAtIndexAsEnumeration (NULL, idx, g_properties[idx].default_uint_value);
28567cc0636SGreg Clayton }
28667cc0636SGreg Clayton 
28767cc0636SGreg Clayton uint32_t
28867cc0636SGreg Clayton Debugger::GetDisassemblyLineCount () const
28967cc0636SGreg Clayton {
29067cc0636SGreg Clayton     const uint32_t idx = ePropertyStopDisassemblyCount;
291754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsSInt64 (NULL, idx, g_properties[idx].default_uint_value);
29267cc0636SGreg Clayton }
293e372b98dSGreg Clayton 
2941b654882SGreg Clayton #pragma mark Debugger
2951b654882SGreg Clayton 
29667cc0636SGreg Clayton //const DebuggerPropertiesSP &
29767cc0636SGreg Clayton //Debugger::GetSettings() const
29867cc0636SGreg Clayton //{
29967cc0636SGreg Clayton //    return m_properties_sp;
30067cc0636SGreg Clayton //}
30167cc0636SGreg Clayton //
30299d0faf2SGreg Clayton 
3032f88aadfSCaroline Tice int
3042f88aadfSCaroline Tice Debugger::TestDebuggerRefCount ()
3052f88aadfSCaroline Tice {
3062f88aadfSCaroline Tice     return g_shared_debugger_refcount;
3072f88aadfSCaroline Tice }
3082f88aadfSCaroline Tice 
30930fdc8d8SChris Lattner void
31030fdc8d8SChris Lattner Debugger::Initialize ()
31130fdc8d8SChris Lattner {
312c15f55e2SGreg Clayton     if (g_shared_debugger_refcount++ == 0)
313dbe54508SGreg Clayton         lldb_private::Initialize();
31499d0faf2SGreg Clayton }
31530fdc8d8SChris Lattner 
31630fdc8d8SChris Lattner void
31730fdc8d8SChris Lattner Debugger::Terminate ()
31830fdc8d8SChris Lattner {
3196611103cSGreg Clayton     if (g_shared_debugger_refcount > 0)
3206611103cSGreg Clayton     {
32130fdc8d8SChris Lattner         g_shared_debugger_refcount--;
32230fdc8d8SChris Lattner         if (g_shared_debugger_refcount == 0)
32330fdc8d8SChris Lattner         {
324dbe54508SGreg Clayton             lldb_private::WillTerminate();
325dbe54508SGreg Clayton             lldb_private::Terminate();
3266760a517SCaroline Tice 
32799d0faf2SGreg Clayton             // Clear our master list of debugger objects
32899d0faf2SGreg Clayton             Mutex::Locker locker (GetDebuggerListMutex ());
32999d0faf2SGreg Clayton             GetDebuggerList().clear();
33030fdc8d8SChris Lattner         }
3316760a517SCaroline Tice     }
3326760a517SCaroline Tice }
33330fdc8d8SChris Lattner 
33420bd37f7SCaroline Tice void
33520bd37f7SCaroline Tice Debugger::SettingsInitialize ()
33620bd37f7SCaroline Tice {
3376920b52bSGreg Clayton     Target::SettingsInitialize ();
33820bd37f7SCaroline Tice }
33920bd37f7SCaroline Tice 
34020bd37f7SCaroline Tice void
34120bd37f7SCaroline Tice Debugger::SettingsTerminate ()
34220bd37f7SCaroline Tice {
3436920b52bSGreg Clayton     Target::SettingsTerminate ();
34420bd37f7SCaroline Tice }
34520bd37f7SCaroline Tice 
34621dfcd9dSEnrico Granata bool
347e743c782SEnrico Granata Debugger::LoadPlugin (const FileSpec& spec, Error& error)
34821dfcd9dSEnrico Granata {
34921dfcd9dSEnrico Granata     lldb::DynamicLibrarySP dynlib_sp(new lldb_private::DynamicLibrary(spec));
350e743c782SEnrico Granata     if (!dynlib_sp || dynlib_sp->IsValid() == false)
351e743c782SEnrico Granata     {
352e743c782SEnrico Granata         if (spec.Exists())
353e743c782SEnrico Granata             error.SetErrorString("this file does not represent a loadable dylib");
354e743c782SEnrico Granata         else
355e743c782SEnrico Granata             error.SetErrorString("no such file");
356e743c782SEnrico Granata         return false;
357e743c782SEnrico Granata     }
35821dfcd9dSEnrico Granata     lldb::DebuggerSP debugger_sp(shared_from_this());
35921dfcd9dSEnrico Granata     lldb::SBDebugger debugger_sb(debugger_sp);
36021dfcd9dSEnrico Granata     // TODO: mangle this differently for your system - on OSX, the first underscore needs to be removed and the second one stays
36121dfcd9dSEnrico Granata     LLDBCommandPluginInit init_func = dynlib_sp->GetSymbol<LLDBCommandPluginInit>("_ZN4lldb16PluginInitializeENS_10SBDebuggerE");
36221dfcd9dSEnrico Granata     if (!init_func)
363e743c782SEnrico Granata     {
364e743c782SEnrico Granata         error.SetErrorString("cannot find the initialization function lldb::PluginInitialize(lldb::SBDebugger)");
36521dfcd9dSEnrico Granata         return false;
366e743c782SEnrico Granata     }
36721dfcd9dSEnrico Granata     if (init_func(debugger_sb))
36821dfcd9dSEnrico Granata     {
36921dfcd9dSEnrico Granata         m_loaded_plugins.push_back(dynlib_sp);
37021dfcd9dSEnrico Granata         return true;
37121dfcd9dSEnrico Granata     }
372e743c782SEnrico Granata     error.SetErrorString("dylib refused to be loaded");
37321dfcd9dSEnrico Granata     return false;
37421dfcd9dSEnrico Granata }
37521dfcd9dSEnrico Granata 
37621dfcd9dSEnrico Granata static FileSpec::EnumerateDirectoryResult
37721dfcd9dSEnrico Granata LoadPluginCallback
37821dfcd9dSEnrico Granata (
37921dfcd9dSEnrico Granata  void *baton,
38021dfcd9dSEnrico Granata  FileSpec::FileType file_type,
38121dfcd9dSEnrico Granata  const FileSpec &file_spec
38221dfcd9dSEnrico Granata  )
38321dfcd9dSEnrico Granata {
38421dfcd9dSEnrico Granata     Error error;
38521dfcd9dSEnrico Granata 
38621dfcd9dSEnrico Granata     static ConstString g_dylibext("dylib");
38721dfcd9dSEnrico Granata 
38821dfcd9dSEnrico Granata     if (!baton)
38921dfcd9dSEnrico Granata         return FileSpec::eEnumerateDirectoryResultQuit;
39021dfcd9dSEnrico Granata 
39121dfcd9dSEnrico Granata     Debugger *debugger = (Debugger*)baton;
39221dfcd9dSEnrico Granata 
39321dfcd9dSEnrico Granata     // If we have a regular file, a symbolic link or unknown file type, try
39421dfcd9dSEnrico Granata     // and process the file. We must handle unknown as sometimes the directory
39521dfcd9dSEnrico Granata     // enumeration might be enumerating a file system that doesn't have correct
39621dfcd9dSEnrico Granata     // file type information.
39721dfcd9dSEnrico Granata     if (file_type == FileSpec::eFileTypeRegular         ||
39821dfcd9dSEnrico Granata         file_type == FileSpec::eFileTypeSymbolicLink    ||
39921dfcd9dSEnrico Granata         file_type == FileSpec::eFileTypeUnknown          )
40021dfcd9dSEnrico Granata     {
40121dfcd9dSEnrico Granata         FileSpec plugin_file_spec (file_spec);
40221dfcd9dSEnrico Granata         plugin_file_spec.ResolvePath ();
40321dfcd9dSEnrico Granata 
40421dfcd9dSEnrico Granata         if (plugin_file_spec.GetFileNameExtension() != g_dylibext)
40521dfcd9dSEnrico Granata             return FileSpec::eEnumerateDirectoryResultNext;
40621dfcd9dSEnrico Granata 
407e743c782SEnrico Granata         Error plugin_load_error;
408e743c782SEnrico Granata         debugger->LoadPlugin (plugin_file_spec, plugin_load_error);
40921dfcd9dSEnrico Granata 
41021dfcd9dSEnrico Granata         return FileSpec::eEnumerateDirectoryResultNext;
41121dfcd9dSEnrico Granata     }
41221dfcd9dSEnrico Granata 
41321dfcd9dSEnrico Granata     else if (file_type == FileSpec::eFileTypeUnknown     ||
41421dfcd9dSEnrico Granata         file_type == FileSpec::eFileTypeDirectory   ||
41521dfcd9dSEnrico Granata         file_type == FileSpec::eFileTypeSymbolicLink )
41621dfcd9dSEnrico Granata     {
41721dfcd9dSEnrico Granata         // Try and recurse into anything that a directory or symbolic link.
41821dfcd9dSEnrico Granata         // We must also do this for unknown as sometimes the directory enumeration
41921dfcd9dSEnrico Granata         // might be enurating a file system that doesn't have correct file type
42021dfcd9dSEnrico Granata         // information.
42121dfcd9dSEnrico Granata         return FileSpec::eEnumerateDirectoryResultEnter;
42221dfcd9dSEnrico Granata     }
42321dfcd9dSEnrico Granata 
42421dfcd9dSEnrico Granata     return FileSpec::eEnumerateDirectoryResultNext;
42521dfcd9dSEnrico Granata }
42621dfcd9dSEnrico Granata 
42721dfcd9dSEnrico Granata void
42821dfcd9dSEnrico Granata Debugger::InstanceInitialize ()
42921dfcd9dSEnrico Granata {
43021dfcd9dSEnrico Granata     FileSpec dir_spec;
43121dfcd9dSEnrico Granata     const bool find_directories = true;
43221dfcd9dSEnrico Granata     const bool find_files = true;
43321dfcd9dSEnrico Granata     const bool find_other = true;
43421dfcd9dSEnrico Granata     char dir_path[PATH_MAX];
43521dfcd9dSEnrico Granata     if (Host::GetLLDBPath (ePathTypeLLDBSystemPlugins, dir_spec))
43621dfcd9dSEnrico Granata     {
43721dfcd9dSEnrico Granata         if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path)))
43821dfcd9dSEnrico Granata         {
43921dfcd9dSEnrico Granata             FileSpec::EnumerateDirectory (dir_path,
44021dfcd9dSEnrico Granata                                           find_directories,
44121dfcd9dSEnrico Granata                                           find_files,
44221dfcd9dSEnrico Granata                                           find_other,
44321dfcd9dSEnrico Granata                                           LoadPluginCallback,
44421dfcd9dSEnrico Granata                                           this);
44521dfcd9dSEnrico Granata         }
44621dfcd9dSEnrico Granata     }
44721dfcd9dSEnrico Granata 
44821dfcd9dSEnrico Granata     if (Host::GetLLDBPath (ePathTypeLLDBUserPlugins, dir_spec))
44921dfcd9dSEnrico Granata     {
45021dfcd9dSEnrico Granata         if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path)))
45121dfcd9dSEnrico Granata         {
45221dfcd9dSEnrico Granata             FileSpec::EnumerateDirectory (dir_path,
45321dfcd9dSEnrico Granata                                           find_directories,
45421dfcd9dSEnrico Granata                                           find_files,
45521dfcd9dSEnrico Granata                                           find_other,
45621dfcd9dSEnrico Granata                                           LoadPluginCallback,
45721dfcd9dSEnrico Granata                                           this);
45821dfcd9dSEnrico Granata         }
45921dfcd9dSEnrico Granata     }
460e8cd0c98SGreg Clayton 
461e8cd0c98SGreg Clayton     PluginManager::DebuggerInitialize (*this);
46221dfcd9dSEnrico Granata }
46321dfcd9dSEnrico Granata 
4646611103cSGreg Clayton DebuggerSP
465228063cdSJim Ingham Debugger::CreateInstance (lldb::LogOutputCallback log_callback, void *baton)
4666611103cSGreg Clayton {
467228063cdSJim Ingham     DebuggerSP debugger_sp (new Debugger(log_callback, baton));
468c15f55e2SGreg Clayton     if (g_shared_debugger_refcount > 0)
4696611103cSGreg Clayton     {
4706611103cSGreg Clayton         Mutex::Locker locker (GetDebuggerListMutex ());
4716611103cSGreg Clayton         GetDebuggerList().push_back(debugger_sp);
4726611103cSGreg Clayton     }
47321dfcd9dSEnrico Granata     debugger_sp->InstanceInitialize ();
4746611103cSGreg Clayton     return debugger_sp;
4756611103cSGreg Clayton }
4766611103cSGreg Clayton 
477e02657b1SCaroline Tice void
4784d122c40SGreg Clayton Debugger::Destroy (DebuggerSP &debugger_sp)
479e02657b1SCaroline Tice {
480e02657b1SCaroline Tice     if (debugger_sp.get() == NULL)
481e02657b1SCaroline Tice         return;
482e02657b1SCaroline Tice 
4838314c525SJim Ingham     debugger_sp->Clear();
4848314c525SJim Ingham 
485c15f55e2SGreg Clayton     if (g_shared_debugger_refcount > 0)
486c15f55e2SGreg Clayton     {
487e02657b1SCaroline Tice         Mutex::Locker locker (GetDebuggerListMutex ());
488e02657b1SCaroline Tice         DebuggerList &debugger_list = GetDebuggerList ();
489e02657b1SCaroline Tice         DebuggerList::iterator pos, end = debugger_list.end();
490e02657b1SCaroline Tice         for (pos = debugger_list.begin (); pos != end; ++pos)
491e02657b1SCaroline Tice         {
492e02657b1SCaroline Tice             if ((*pos).get() == debugger_sp.get())
493e02657b1SCaroline Tice             {
494e02657b1SCaroline Tice                 debugger_list.erase (pos);
495e02657b1SCaroline Tice                 return;
496e02657b1SCaroline Tice             }
497e02657b1SCaroline Tice         }
498e02657b1SCaroline Tice     }
499c15f55e2SGreg Clayton }
500e02657b1SCaroline Tice 
5014d122c40SGreg Clayton DebuggerSP
5023df9a8dfSCaroline Tice Debugger::FindDebuggerWithInstanceName (const ConstString &instance_name)
5033df9a8dfSCaroline Tice {
5044d122c40SGreg Clayton     DebuggerSP debugger_sp;
5056920b52bSGreg Clayton     if (g_shared_debugger_refcount > 0)
5066920b52bSGreg Clayton     {
5076920b52bSGreg Clayton         Mutex::Locker locker (GetDebuggerListMutex ());
5086920b52bSGreg Clayton         DebuggerList &debugger_list = GetDebuggerList();
5096920b52bSGreg Clayton         DebuggerList::iterator pos, end = debugger_list.end();
5106920b52bSGreg Clayton 
5116920b52bSGreg Clayton         for (pos = debugger_list.begin(); pos != end; ++pos)
5126920b52bSGreg Clayton         {
5136920b52bSGreg Clayton             if ((*pos).get()->m_instance_name == instance_name)
5146920b52bSGreg Clayton             {
5156920b52bSGreg Clayton                 debugger_sp = *pos;
5166920b52bSGreg Clayton                 break;
5176920b52bSGreg Clayton             }
5186920b52bSGreg Clayton         }
5196920b52bSGreg Clayton     }
5203df9a8dfSCaroline Tice     return debugger_sp;
5213df9a8dfSCaroline Tice }
5226611103cSGreg Clayton 
5236611103cSGreg Clayton TargetSP
5246611103cSGreg Clayton Debugger::FindTargetWithProcessID (lldb::pid_t pid)
5256611103cSGreg Clayton {
5264d122c40SGreg Clayton     TargetSP target_sp;
527c15f55e2SGreg Clayton     if (g_shared_debugger_refcount > 0)
528c15f55e2SGreg Clayton     {
5296611103cSGreg Clayton         Mutex::Locker locker (GetDebuggerListMutex ());
5306611103cSGreg Clayton         DebuggerList &debugger_list = GetDebuggerList();
5316611103cSGreg Clayton         DebuggerList::iterator pos, end = debugger_list.end();
5326611103cSGreg Clayton         for (pos = debugger_list.begin(); pos != end; ++pos)
5336611103cSGreg Clayton         {
5346611103cSGreg Clayton             target_sp = (*pos)->GetTargetList().FindTargetWithProcessID (pid);
5356611103cSGreg Clayton             if (target_sp)
5366611103cSGreg Clayton                 break;
5376611103cSGreg Clayton         }
538c15f55e2SGreg Clayton     }
5396611103cSGreg Clayton     return target_sp;
5406611103cSGreg Clayton }
5416611103cSGreg Clayton 
542e4e45924SGreg Clayton TargetSP
543e4e45924SGreg Clayton Debugger::FindTargetWithProcess (Process *process)
544e4e45924SGreg Clayton {
545e4e45924SGreg Clayton     TargetSP target_sp;
546c15f55e2SGreg Clayton     if (g_shared_debugger_refcount > 0)
547c15f55e2SGreg Clayton     {
548e4e45924SGreg Clayton         Mutex::Locker locker (GetDebuggerListMutex ());
549e4e45924SGreg Clayton         DebuggerList &debugger_list = GetDebuggerList();
550e4e45924SGreg Clayton         DebuggerList::iterator pos, end = debugger_list.end();
551e4e45924SGreg Clayton         for (pos = debugger_list.begin(); pos != end; ++pos)
552e4e45924SGreg Clayton         {
553e4e45924SGreg Clayton             target_sp = (*pos)->GetTargetList().FindTargetWithProcess (process);
554e4e45924SGreg Clayton             if (target_sp)
555e4e45924SGreg Clayton                 break;
556e4e45924SGreg Clayton         }
557c15f55e2SGreg Clayton     }
558e4e45924SGreg Clayton     return target_sp;
559e4e45924SGreg Clayton }
560e4e45924SGreg Clayton 
561228063cdSJim Ingham Debugger::Debugger (lldb::LogOutputCallback log_callback, void *baton) :
562ebc1bb27SCaroline Tice     UserID (g_unique_id++),
56367cc0636SGreg Clayton     Properties(OptionValuePropertiesSP(new OptionValueProperties())),
564d46c87a1SGreg Clayton     m_input_comm("debugger.input"),
56530fdc8d8SChris Lattner     m_input_file (),
56630fdc8d8SChris Lattner     m_output_file (),
56730fdc8d8SChris Lattner     m_error_file (),
568c5917d9aSJim Ingham     m_terminal_state (),
5694bddaeb5SJim Ingham     m_target_list (*this),
570ded470d3SGreg Clayton     m_platform_list (),
57130fdc8d8SChris Lattner     m_listener ("lldb.Debugger"),
5729585fbfcSGreg Clayton     m_source_manager_ap(),
573e37d605eSJim Ingham     m_source_file_cache(),
5746611103cSGreg Clayton     m_command_interpreter_ap (new CommandInterpreter (*this, eScriptLanguageDefault, false)),
575d5a0a01bSCaroline Tice     m_input_reader_stack (),
57667cc0636SGreg Clayton     m_input_reader_data (),
57767cc0636SGreg Clayton     m_instance_name()
57830fdc8d8SChris Lattner {
57967cc0636SGreg Clayton     char instance_cstr[256];
58067cc0636SGreg Clayton     snprintf(instance_cstr, sizeof(instance_cstr), "debugger_%d", (int)GetID());
58167cc0636SGreg Clayton     m_instance_name.SetCString(instance_cstr);
582228063cdSJim Ingham     if (log_callback)
583228063cdSJim Ingham         m_log_callback_stream_sp.reset (new StreamCallback (log_callback, baton));
5846611103cSGreg Clayton     m_command_interpreter_ap->Initialize ();
585ded470d3SGreg Clayton     // Always add our default platform to the platform list
586ded470d3SGreg Clayton     PlatformSP default_platform_sp (Platform::GetDefaultPlatform());
587ded470d3SGreg Clayton     assert (default_platform_sp.get());
588ded470d3SGreg Clayton     m_platform_list.Append (default_platform_sp, true);
58967cc0636SGreg Clayton 
590754a9369SGreg Clayton     m_collection_sp->Initialize (g_properties);
59167cc0636SGreg Clayton     m_collection_sp->AppendProperty (ConstString("target"),
59267cc0636SGreg Clayton                                      ConstString("Settings specify to debugging targets."),
59367cc0636SGreg Clayton                                      true,
59467cc0636SGreg Clayton                                      Target::GetGlobalProperties()->GetValueProperties());
595754a9369SGreg Clayton     if (m_command_interpreter_ap.get())
596754a9369SGreg Clayton     {
597754a9369SGreg Clayton         m_collection_sp->AppendProperty (ConstString("interpreter"),
598754a9369SGreg Clayton                                          ConstString("Settings specify to the debugger's command interpreter."),
599754a9369SGreg Clayton                                          true,
600754a9369SGreg Clayton                                          m_command_interpreter_ap->GetValueProperties());
601754a9369SGreg Clayton     }
60267cc0636SGreg Clayton     OptionValueSInt64 *term_width = m_collection_sp->GetPropertyAtIndexAsOptionValueSInt64 (NULL, ePropertyTerminalWidth);
60367cc0636SGreg Clayton     term_width->SetMinimumValue(10);
60467cc0636SGreg Clayton     term_width->SetMaximumValue(1024);
60530fdc8d8SChris Lattner }
60630fdc8d8SChris Lattner 
60730fdc8d8SChris Lattner Debugger::~Debugger ()
60830fdc8d8SChris Lattner {
6098314c525SJim Ingham     Clear();
6108314c525SJim Ingham }
6118314c525SJim Ingham 
6128314c525SJim Ingham void
6138314c525SJim Ingham Debugger::Clear()
6148314c525SJim Ingham {
6153d6086f6SCaroline Tice     CleanUpInputReaders();
6161ed54f50SGreg Clayton     m_listener.Clear();
6176611103cSGreg Clayton     int num_targets = m_target_list.GetNumTargets();
6186611103cSGreg Clayton     for (int i = 0; i < num_targets; i++)
6196611103cSGreg Clayton     {
620ccbc08e6SGreg Clayton         TargetSP target_sp (m_target_list.GetTargetAtIndex (i));
621ccbc08e6SGreg Clayton         if (target_sp)
622ccbc08e6SGreg Clayton         {
623ccbc08e6SGreg Clayton             ProcessSP process_sp (target_sp->GetProcessSP());
6246611103cSGreg Clayton             if (process_sp)
6251fd07059SJim Ingham                 process_sp->Finalize();
626ccbc08e6SGreg Clayton             target_sp->Destroy();
6276611103cSGreg Clayton         }
62830fdc8d8SChris Lattner     }
6294bddaeb5SJim Ingham     BroadcasterManager::Clear ();
63030fdc8d8SChris Lattner 
6310d69a3a4SGreg Clayton     // Close the input file _before_ we close the input read communications class
6320d69a3a4SGreg Clayton     // as it does NOT own the input file, our m_input_file does.
633c5917d9aSJim Ingham     m_terminal_state.Clear();
6340d69a3a4SGreg Clayton     GetInputFile().Close ();
6350d69a3a4SGreg Clayton     // Now that we have closed m_input_file, we can now tell our input communication
6360d69a3a4SGreg Clayton     // class to close down. Its read thread should quickly exit after we close
6370d69a3a4SGreg Clayton     // the input file handle above.
6380d69a3a4SGreg Clayton     m_input_comm.Clear ();
6398314c525SJim Ingham }
64030fdc8d8SChris Lattner 
64130fdc8d8SChris Lattner bool
642fc3f027dSGreg Clayton Debugger::GetCloseInputOnEOF () const
643fc3f027dSGreg Clayton {
644fc3f027dSGreg Clayton     return m_input_comm.GetCloseOnEOF();
645fc3f027dSGreg Clayton }
646fc3f027dSGreg Clayton 
647fc3f027dSGreg Clayton void
648fc3f027dSGreg Clayton Debugger::SetCloseInputOnEOF (bool b)
649fc3f027dSGreg Clayton {
650fc3f027dSGreg Clayton     m_input_comm.SetCloseOnEOF(b);
651fc3f027dSGreg Clayton }
652fc3f027dSGreg Clayton 
653fc3f027dSGreg Clayton bool
65430fdc8d8SChris Lattner Debugger::GetAsyncExecution ()
65530fdc8d8SChris Lattner {
6566611103cSGreg Clayton     return !m_command_interpreter_ap->GetSynchronous();
65730fdc8d8SChris Lattner }
65830fdc8d8SChris Lattner 
65930fdc8d8SChris Lattner void
66030fdc8d8SChris Lattner Debugger::SetAsyncExecution (bool async_execution)
66130fdc8d8SChris Lattner {
6626611103cSGreg Clayton     m_command_interpreter_ap->SetSynchronous (!async_execution);
66330fdc8d8SChris Lattner }
66430fdc8d8SChris Lattner 
66530fdc8d8SChris Lattner 
66630fdc8d8SChris Lattner void
66730fdc8d8SChris Lattner Debugger::SetInputFileHandle (FILE *fh, bool tranfer_ownership)
66830fdc8d8SChris Lattner {
66951b1e2d2SGreg Clayton     File &in_file = GetInputFile();
67051b1e2d2SGreg Clayton     in_file.SetStream (fh, tranfer_ownership);
67151b1e2d2SGreg Clayton     if (in_file.IsValid() == false)
67251b1e2d2SGreg Clayton         in_file.SetStream (stdin, true);
67330fdc8d8SChris Lattner 
67430fdc8d8SChris Lattner     // Disconnect from any old connection if we had one
67530fdc8d8SChris Lattner     m_input_comm.Disconnect ();
67632720b51SGreg Clayton     // Pass false as the second argument to ConnectionFileDescriptor below because
67732720b51SGreg Clayton     // our "in_file" above will already take ownership if requested and we don't
67832720b51SGreg Clayton     // want to objects trying to own and close a file descriptor.
67932720b51SGreg Clayton     m_input_comm.SetConnection (new ConnectionFileDescriptor (in_file.GetDescriptor(), false));
68030fdc8d8SChris Lattner     m_input_comm.SetReadThreadBytesReceivedCallback (Debugger::DispatchInputCallback, this);
68130fdc8d8SChris Lattner 
682c5917d9aSJim Ingham     // Save away the terminal state if that is relevant, so that we can restore it in RestoreInputState.
683c5917d9aSJim Ingham     SaveInputTerminalState ();
684c5917d9aSJim Ingham 
68530fdc8d8SChris Lattner     Error error;
68630fdc8d8SChris Lattner     if (m_input_comm.StartReadThread (&error) == false)
68730fdc8d8SChris Lattner     {
68851b1e2d2SGreg Clayton         File &err_file = GetErrorFile();
68951b1e2d2SGreg Clayton 
69051b1e2d2SGreg Clayton         err_file.Printf ("error: failed to main input read thread: %s", error.AsCString() ? error.AsCString() : "unkown error");
69130fdc8d8SChris Lattner         exit(1);
69230fdc8d8SChris Lattner     }
69330fdc8d8SChris Lattner }
69430fdc8d8SChris Lattner 
69530fdc8d8SChris Lattner void
69630fdc8d8SChris Lattner Debugger::SetOutputFileHandle (FILE *fh, bool tranfer_ownership)
69730fdc8d8SChris Lattner {
69851b1e2d2SGreg Clayton     File &out_file = GetOutputFile();
69951b1e2d2SGreg Clayton     out_file.SetStream (fh, tranfer_ownership);
70051b1e2d2SGreg Clayton     if (out_file.IsValid() == false)
70151b1e2d2SGreg Clayton         out_file.SetStream (stdout, false);
7022f88aadfSCaroline Tice 
703b588726eSEnrico Granata     // do not create the ScriptInterpreter just for setting the output file handle
704b588726eSEnrico Granata     // as the constructor will know how to do the right thing on its own
705b588726eSEnrico Granata     const bool can_create = false;
706b588726eSEnrico Granata     ScriptInterpreter* script_interpreter = GetCommandInterpreter().GetScriptInterpreter(can_create);
707b588726eSEnrico Granata     if (script_interpreter)
708b588726eSEnrico Granata         script_interpreter->ResetOutputFileHandle (fh);
70930fdc8d8SChris Lattner }
71030fdc8d8SChris Lattner 
71130fdc8d8SChris Lattner void
71230fdc8d8SChris Lattner Debugger::SetErrorFileHandle (FILE *fh, bool tranfer_ownership)
71330fdc8d8SChris Lattner {
71451b1e2d2SGreg Clayton     File &err_file = GetErrorFile();
71551b1e2d2SGreg Clayton     err_file.SetStream (fh, tranfer_ownership);
71651b1e2d2SGreg Clayton     if (err_file.IsValid() == false)
71751b1e2d2SGreg Clayton         err_file.SetStream (stderr, false);
71830fdc8d8SChris Lattner }
71930fdc8d8SChris Lattner 
720c5917d9aSJim Ingham void
721c5917d9aSJim Ingham Debugger::SaveInputTerminalState ()
722c5917d9aSJim Ingham {
723c5917d9aSJim Ingham     File &in_file = GetInputFile();
724c5917d9aSJim Ingham     if (in_file.GetDescriptor() != File::kInvalidDescriptor)
725c5917d9aSJim Ingham         m_terminal_state.Save(in_file.GetDescriptor(), true);
726c5917d9aSJim Ingham }
727c5917d9aSJim Ingham 
728c5917d9aSJim Ingham void
729c5917d9aSJim Ingham Debugger::RestoreInputTerminalState ()
730c5917d9aSJim Ingham {
731c5917d9aSJim Ingham     m_terminal_state.Restore();
732c5917d9aSJim Ingham }
733c5917d9aSJim Ingham 
73430fdc8d8SChris Lattner ExecutionContext
7352976d00aSJim Ingham Debugger::GetSelectedExecutionContext ()
73630fdc8d8SChris Lattner {
73730fdc8d8SChris Lattner     ExecutionContext exe_ctx;
738c14ee32dSGreg Clayton     TargetSP target_sp(GetSelectedTarget());
739c14ee32dSGreg Clayton     exe_ctx.SetTargetSP (target_sp);
74030fdc8d8SChris Lattner 
74130fdc8d8SChris Lattner     if (target_sp)
74230fdc8d8SChris Lattner     {
743c14ee32dSGreg Clayton         ProcessSP process_sp (target_sp->GetProcessSP());
744c14ee32dSGreg Clayton         exe_ctx.SetProcessSP (process_sp);
745c14ee32dSGreg Clayton         if (process_sp && process_sp->IsRunning() == false)
74630fdc8d8SChris Lattner         {
747c14ee32dSGreg Clayton             ThreadSP thread_sp (process_sp->GetThreadList().GetSelectedThread());
748c14ee32dSGreg Clayton             if (thread_sp)
74930fdc8d8SChris Lattner             {
750c14ee32dSGreg Clayton                 exe_ctx.SetThreadSP (thread_sp);
751c14ee32dSGreg Clayton                 exe_ctx.SetFrameSP (thread_sp->GetSelectedFrame());
752c14ee32dSGreg Clayton                 if (exe_ctx.GetFramePtr() == NULL)
753c14ee32dSGreg Clayton                     exe_ctx.SetFrameSP (thread_sp->GetStackFrameAtIndex (0));
75430fdc8d8SChris Lattner             }
75530fdc8d8SChris Lattner         }
75630fdc8d8SChris Lattner     }
75730fdc8d8SChris Lattner     return exe_ctx;
75830fdc8d8SChris Lattner 
75930fdc8d8SChris Lattner }
76030fdc8d8SChris Lattner 
761b44880caSCaroline Tice InputReaderSP
762b44880caSCaroline Tice Debugger::GetCurrentInputReader ()
763b44880caSCaroline Tice {
764b44880caSCaroline Tice     InputReaderSP reader_sp;
765b44880caSCaroline Tice 
766d5a0a01bSCaroline Tice     if (!m_input_reader_stack.IsEmpty())
767b44880caSCaroline Tice     {
768b44880caSCaroline Tice         // Clear any finished readers from the stack
769b44880caSCaroline Tice         while (CheckIfTopInputReaderIsDone()) ;
770b44880caSCaroline Tice 
771d5a0a01bSCaroline Tice         if (!m_input_reader_stack.IsEmpty())
772d5a0a01bSCaroline Tice             reader_sp = m_input_reader_stack.Top();
773b44880caSCaroline Tice     }
774b44880caSCaroline Tice 
775b44880caSCaroline Tice     return reader_sp;
776b44880caSCaroline Tice }
777b44880caSCaroline Tice 
77830fdc8d8SChris Lattner void
77930fdc8d8SChris Lattner Debugger::DispatchInputCallback (void *baton, const void *bytes, size_t bytes_len)
78030fdc8d8SChris Lattner {
781efed6131SCaroline Tice     if (bytes_len > 0)
78230fdc8d8SChris Lattner         ((Debugger *)baton)->DispatchInput ((char *)bytes, bytes_len);
783efed6131SCaroline Tice     else
784efed6131SCaroline Tice         ((Debugger *)baton)->DispatchInputEndOfFile ();
78530fdc8d8SChris Lattner }
78630fdc8d8SChris Lattner 
78730fdc8d8SChris Lattner 
78830fdc8d8SChris Lattner void
78930fdc8d8SChris Lattner Debugger::DispatchInput (const char *bytes, size_t bytes_len)
79030fdc8d8SChris Lattner {
791efed6131SCaroline Tice     if (bytes == NULL || bytes_len == 0)
792efed6131SCaroline Tice         return;
79330fdc8d8SChris Lattner 
79430fdc8d8SChris Lattner     WriteToDefaultReader (bytes, bytes_len);
79530fdc8d8SChris Lattner }
79630fdc8d8SChris Lattner 
79730fdc8d8SChris Lattner void
798efed6131SCaroline Tice Debugger::DispatchInputInterrupt ()
799efed6131SCaroline Tice {
800efed6131SCaroline Tice     m_input_reader_data.clear();
801efed6131SCaroline Tice 
802b44880caSCaroline Tice     InputReaderSP reader_sp (GetCurrentInputReader ());
803efed6131SCaroline Tice     if (reader_sp)
804b44880caSCaroline Tice     {
805efed6131SCaroline Tice         reader_sp->Notify (eInputReaderInterrupt);
806efed6131SCaroline Tice 
807b44880caSCaroline Tice         // If notifying the reader of the interrupt finished the reader, we should pop it off the stack.
808efed6131SCaroline Tice         while (CheckIfTopInputReaderIsDone ()) ;
809efed6131SCaroline Tice     }
810efed6131SCaroline Tice }
811efed6131SCaroline Tice 
812efed6131SCaroline Tice void
813efed6131SCaroline Tice Debugger::DispatchInputEndOfFile ()
814efed6131SCaroline Tice {
815efed6131SCaroline Tice     m_input_reader_data.clear();
816efed6131SCaroline Tice 
817b44880caSCaroline Tice     InputReaderSP reader_sp (GetCurrentInputReader ());
818efed6131SCaroline Tice     if (reader_sp)
819b44880caSCaroline Tice     {
820efed6131SCaroline Tice         reader_sp->Notify (eInputReaderEndOfFile);
821efed6131SCaroline Tice 
822b44880caSCaroline Tice         // If notifying the reader of the end-of-file finished the reader, we should pop it off the stack.
823efed6131SCaroline Tice         while (CheckIfTopInputReaderIsDone ()) ;
824efed6131SCaroline Tice     }
825efed6131SCaroline Tice }
826efed6131SCaroline Tice 
827efed6131SCaroline Tice void
8283d6086f6SCaroline Tice Debugger::CleanUpInputReaders ()
8293d6086f6SCaroline Tice {
8303d6086f6SCaroline Tice     m_input_reader_data.clear();
8313d6086f6SCaroline Tice 
832b44880caSCaroline Tice     // The bottom input reader should be the main debugger input reader.  We do not want to close that one here.
833d5a0a01bSCaroline Tice     while (m_input_reader_stack.GetSize() > 1)
8343d6086f6SCaroline Tice     {
835b44880caSCaroline Tice         InputReaderSP reader_sp (GetCurrentInputReader ());
8363d6086f6SCaroline Tice         if (reader_sp)
8373d6086f6SCaroline Tice         {
8383d6086f6SCaroline Tice             reader_sp->Notify (eInputReaderEndOfFile);
8393d6086f6SCaroline Tice             reader_sp->SetIsDone (true);
8403d6086f6SCaroline Tice         }
8413d6086f6SCaroline Tice     }
8423d6086f6SCaroline Tice }
8433d6086f6SCaroline Tice 
8443d6086f6SCaroline Tice void
845969ed3d1SCaroline Tice Debugger::NotifyTopInputReader (InputReaderAction notification)
846969ed3d1SCaroline Tice {
847969ed3d1SCaroline Tice     InputReaderSP reader_sp (GetCurrentInputReader());
848969ed3d1SCaroline Tice     if (reader_sp)
849969ed3d1SCaroline Tice 	{
850969ed3d1SCaroline Tice         reader_sp->Notify (notification);
851969ed3d1SCaroline Tice 
852969ed3d1SCaroline Tice         // Flush out any input readers that are done.
853969ed3d1SCaroline Tice         while (CheckIfTopInputReaderIsDone ())
854969ed3d1SCaroline Tice             /* Do nothing. */;
855969ed3d1SCaroline Tice     }
856969ed3d1SCaroline Tice }
857969ed3d1SCaroline Tice 
8589088b068SCaroline Tice bool
8594d122c40SGreg Clayton Debugger::InputReaderIsTopReader (const InputReaderSP& reader_sp)
8609088b068SCaroline Tice {
8619088b068SCaroline Tice     InputReaderSP top_reader_sp (GetCurrentInputReader());
8629088b068SCaroline Tice 
863d61c10bcSCaroline Tice     return (reader_sp.get() == top_reader_sp.get());
8649088b068SCaroline Tice }
8659088b068SCaroline Tice 
8669088b068SCaroline Tice 
867969ed3d1SCaroline Tice void
86830fdc8d8SChris Lattner Debugger::WriteToDefaultReader (const char *bytes, size_t bytes_len)
86930fdc8d8SChris Lattner {
87030fdc8d8SChris Lattner     if (bytes && bytes_len)
87130fdc8d8SChris Lattner         m_input_reader_data.append (bytes, bytes_len);
87230fdc8d8SChris Lattner 
87330fdc8d8SChris Lattner     if (m_input_reader_data.empty())
87430fdc8d8SChris Lattner         return;
87530fdc8d8SChris Lattner 
876d5a0a01bSCaroline Tice     while (!m_input_reader_stack.IsEmpty() && !m_input_reader_data.empty())
87730fdc8d8SChris Lattner     {
87830fdc8d8SChris Lattner         // Get the input reader from the top of the stack
879b44880caSCaroline Tice         InputReaderSP reader_sp (GetCurrentInputReader ());
88030fdc8d8SChris Lattner         if (!reader_sp)
88130fdc8d8SChris Lattner             break;
88230fdc8d8SChris Lattner 
883471b31ceSGreg Clayton         size_t bytes_handled = reader_sp->HandleRawBytes (m_input_reader_data.c_str(),
88430fdc8d8SChris Lattner                                                           m_input_reader_data.size());
88530fdc8d8SChris Lattner         if (bytes_handled)
88630fdc8d8SChris Lattner         {
88730fdc8d8SChris Lattner             m_input_reader_data.erase (0, bytes_handled);
88830fdc8d8SChris Lattner         }
88930fdc8d8SChris Lattner         else
89030fdc8d8SChris Lattner         {
89130fdc8d8SChris Lattner             // No bytes were handled, we might not have reached our
89230fdc8d8SChris Lattner             // granularity, just return and wait for more data
89330fdc8d8SChris Lattner             break;
89430fdc8d8SChris Lattner         }
89530fdc8d8SChris Lattner     }
89630fdc8d8SChris Lattner 
897b44880caSCaroline Tice     // Flush out any input readers that are done.
89830fdc8d8SChris Lattner     while (CheckIfTopInputReaderIsDone ())
89930fdc8d8SChris Lattner         /* Do nothing. */;
90030fdc8d8SChris Lattner 
90130fdc8d8SChris Lattner }
90230fdc8d8SChris Lattner 
90330fdc8d8SChris Lattner void
90430fdc8d8SChris Lattner Debugger::PushInputReader (const InputReaderSP& reader_sp)
90530fdc8d8SChris Lattner {
90630fdc8d8SChris Lattner     if (!reader_sp)
90730fdc8d8SChris Lattner         return;
908b44880caSCaroline Tice 
90930fdc8d8SChris Lattner     // Deactivate the old top reader
910b44880caSCaroline Tice     InputReaderSP top_reader_sp (GetCurrentInputReader ());
911b44880caSCaroline Tice 
91230fdc8d8SChris Lattner     if (top_reader_sp)
91330fdc8d8SChris Lattner         top_reader_sp->Notify (eInputReaderDeactivate);
914b44880caSCaroline Tice 
915d5a0a01bSCaroline Tice     m_input_reader_stack.Push (reader_sp);
91630fdc8d8SChris Lattner     reader_sp->Notify (eInputReaderActivate);
91730fdc8d8SChris Lattner     ActivateInputReader (reader_sp);
91830fdc8d8SChris Lattner }
91930fdc8d8SChris Lattner 
92030fdc8d8SChris Lattner bool
9214d122c40SGreg Clayton Debugger::PopInputReader (const InputReaderSP& pop_reader_sp)
92230fdc8d8SChris Lattner {
92330fdc8d8SChris Lattner     bool result = false;
92430fdc8d8SChris Lattner 
92530fdc8d8SChris Lattner     // The reader on the stop of the stack is done, so let the next
92630fdc8d8SChris Lattner     // read on the stack referesh its prompt and if there is one...
927d5a0a01bSCaroline Tice     if (!m_input_reader_stack.IsEmpty())
92830fdc8d8SChris Lattner     {
929b44880caSCaroline Tice         // Cannot call GetCurrentInputReader here, as that would cause an infinite loop.
930d5a0a01bSCaroline Tice         InputReaderSP reader_sp(m_input_reader_stack.Top());
93130fdc8d8SChris Lattner 
93230fdc8d8SChris Lattner         if (!pop_reader_sp || pop_reader_sp.get() == reader_sp.get())
93330fdc8d8SChris Lattner         {
934d5a0a01bSCaroline Tice             m_input_reader_stack.Pop ();
93530fdc8d8SChris Lattner             reader_sp->Notify (eInputReaderDeactivate);
93630fdc8d8SChris Lattner             reader_sp->Notify (eInputReaderDone);
93730fdc8d8SChris Lattner             result = true;
93830fdc8d8SChris Lattner 
939d5a0a01bSCaroline Tice             if (!m_input_reader_stack.IsEmpty())
94030fdc8d8SChris Lattner             {
941d5a0a01bSCaroline Tice                 reader_sp = m_input_reader_stack.Top();
94230fdc8d8SChris Lattner                 if (reader_sp)
94330fdc8d8SChris Lattner                 {
94430fdc8d8SChris Lattner                     ActivateInputReader (reader_sp);
94530fdc8d8SChris Lattner                     reader_sp->Notify (eInputReaderReactivate);
94630fdc8d8SChris Lattner                 }
94730fdc8d8SChris Lattner             }
94830fdc8d8SChris Lattner         }
94930fdc8d8SChris Lattner     }
95030fdc8d8SChris Lattner     return result;
95130fdc8d8SChris Lattner }
95230fdc8d8SChris Lattner 
95330fdc8d8SChris Lattner bool
95430fdc8d8SChris Lattner Debugger::CheckIfTopInputReaderIsDone ()
95530fdc8d8SChris Lattner {
95630fdc8d8SChris Lattner     bool result = false;
957d5a0a01bSCaroline Tice     if (!m_input_reader_stack.IsEmpty())
95830fdc8d8SChris Lattner     {
959b44880caSCaroline Tice         // Cannot call GetCurrentInputReader here, as that would cause an infinite loop.
960d5a0a01bSCaroline Tice         InputReaderSP reader_sp(m_input_reader_stack.Top());
96130fdc8d8SChris Lattner 
96230fdc8d8SChris Lattner         if (reader_sp && reader_sp->IsDone())
96330fdc8d8SChris Lattner         {
96430fdc8d8SChris Lattner             result = true;
96530fdc8d8SChris Lattner             PopInputReader (reader_sp);
96630fdc8d8SChris Lattner         }
96730fdc8d8SChris Lattner     }
96830fdc8d8SChris Lattner     return result;
96930fdc8d8SChris Lattner }
97030fdc8d8SChris Lattner 
97130fdc8d8SChris Lattner void
97230fdc8d8SChris Lattner Debugger::ActivateInputReader (const InputReaderSP &reader_sp)
97330fdc8d8SChris Lattner {
97451b1e2d2SGreg Clayton     int input_fd = m_input_file.GetFile().GetDescriptor();
97530fdc8d8SChris Lattner 
97651b1e2d2SGreg Clayton     if (input_fd >= 0)
97730fdc8d8SChris Lattner     {
97851b1e2d2SGreg Clayton         Terminal tty(input_fd);
979a3406614SGreg Clayton 
980a3406614SGreg Clayton         tty.SetEcho(reader_sp->GetEcho());
98130fdc8d8SChris Lattner 
98230fdc8d8SChris Lattner         switch (reader_sp->GetGranularity())
98330fdc8d8SChris Lattner         {
98430fdc8d8SChris Lattner         case eInputReaderGranularityByte:
98530fdc8d8SChris Lattner         case eInputReaderGranularityWord:
986a3406614SGreg Clayton             tty.SetCanonical (false);
98730fdc8d8SChris Lattner             break;
98830fdc8d8SChris Lattner 
98930fdc8d8SChris Lattner         case eInputReaderGranularityLine:
99030fdc8d8SChris Lattner         case eInputReaderGranularityAll:
991a3406614SGreg Clayton             tty.SetCanonical (true);
99230fdc8d8SChris Lattner             break;
99330fdc8d8SChris Lattner 
99430fdc8d8SChris Lattner         default:
99530fdc8d8SChris Lattner             break;
99630fdc8d8SChris Lattner         }
99730fdc8d8SChris Lattner     }
99830fdc8d8SChris Lattner }
9996611103cSGreg Clayton 
10005b52f0c7SJim Ingham StreamSP
10015b52f0c7SJim Ingham Debugger::GetAsyncOutputStream ()
10025b52f0c7SJim Ingham {
10035b52f0c7SJim Ingham     return StreamSP (new StreamAsynchronousIO (GetCommandInterpreter(),
10045b52f0c7SJim Ingham                                                CommandInterpreter::eBroadcastBitAsynchronousOutputData));
10055b52f0c7SJim Ingham }
10065b52f0c7SJim Ingham 
10075b52f0c7SJim Ingham StreamSP
10085b52f0c7SJim Ingham Debugger::GetAsyncErrorStream ()
10095b52f0c7SJim Ingham {
10105b52f0c7SJim Ingham     return StreamSP (new StreamAsynchronousIO (GetCommandInterpreter(),
10115b52f0c7SJim Ingham                                                CommandInterpreter::eBroadcastBitAsynchronousErrorData));
10125b52f0c7SJim Ingham }
10135b52f0c7SJim Ingham 
1014c7bece56SGreg Clayton size_t
1015061858ceSEnrico Granata Debugger::GetNumDebuggers()
1016061858ceSEnrico Granata {
1017c15f55e2SGreg Clayton     if (g_shared_debugger_refcount > 0)
1018c15f55e2SGreg Clayton     {
1019061858ceSEnrico Granata         Mutex::Locker locker (GetDebuggerListMutex ());
1020061858ceSEnrico Granata         return GetDebuggerList().size();
1021061858ceSEnrico Granata     }
1022c15f55e2SGreg Clayton     return 0;
1023c15f55e2SGreg Clayton }
1024061858ceSEnrico Granata 
1025061858ceSEnrico Granata lldb::DebuggerSP
1026c7bece56SGreg Clayton Debugger::GetDebuggerAtIndex (size_t index)
1027061858ceSEnrico Granata {
1028061858ceSEnrico Granata     DebuggerSP debugger_sp;
1029061858ceSEnrico Granata 
1030c15f55e2SGreg Clayton     if (g_shared_debugger_refcount > 0)
1031c15f55e2SGreg Clayton     {
1032061858ceSEnrico Granata         Mutex::Locker locker (GetDebuggerListMutex ());
1033061858ceSEnrico Granata         DebuggerList &debugger_list = GetDebuggerList();
1034061858ceSEnrico Granata 
1035061858ceSEnrico Granata         if (index < debugger_list.size())
1036061858ceSEnrico Granata             debugger_sp = debugger_list[index];
1037c15f55e2SGreg Clayton     }
1038061858ceSEnrico Granata 
1039061858ceSEnrico Granata     return debugger_sp;
1040061858ceSEnrico Granata }
1041061858ceSEnrico Granata 
1042ebc1bb27SCaroline Tice DebuggerSP
1043ebc1bb27SCaroline Tice Debugger::FindDebuggerWithID (lldb::user_id_t id)
1044ebc1bb27SCaroline Tice {
10454d122c40SGreg Clayton     DebuggerSP debugger_sp;
1046ebc1bb27SCaroline Tice 
1047c15f55e2SGreg Clayton     if (g_shared_debugger_refcount > 0)
1048c15f55e2SGreg Clayton     {
1049ebc1bb27SCaroline Tice         Mutex::Locker locker (GetDebuggerListMutex ());
1050ebc1bb27SCaroline Tice         DebuggerList &debugger_list = GetDebuggerList();
1051ebc1bb27SCaroline Tice         DebuggerList::iterator pos, end = debugger_list.end();
1052ebc1bb27SCaroline Tice         for (pos = debugger_list.begin(); pos != end; ++pos)
1053ebc1bb27SCaroline Tice         {
1054ebc1bb27SCaroline Tice             if ((*pos).get()->GetID() == id)
1055ebc1bb27SCaroline Tice             {
1056ebc1bb27SCaroline Tice                 debugger_sp = *pos;
1057ebc1bb27SCaroline Tice                 break;
1058ebc1bb27SCaroline Tice             }
1059ebc1bb27SCaroline Tice         }
1060c15f55e2SGreg Clayton     }
1061ebc1bb27SCaroline Tice     return debugger_sp;
1062ebc1bb27SCaroline Tice }
10633df9a8dfSCaroline Tice 
10641b654882SGreg Clayton static void
10651b654882SGreg Clayton TestPromptFormats (StackFrame *frame)
10661b654882SGreg Clayton {
10671b654882SGreg Clayton     if (frame == NULL)
10681b654882SGreg Clayton         return;
10691b654882SGreg Clayton 
10701b654882SGreg Clayton     StreamString s;
10711b654882SGreg Clayton     const char *prompt_format =
10721b654882SGreg Clayton     "{addr = '${addr}'\n}"
10731b654882SGreg Clayton     "{process.id = '${process.id}'\n}"
10741b654882SGreg Clayton     "{process.name = '${process.name}'\n}"
10751b654882SGreg Clayton     "{process.file.basename = '${process.file.basename}'\n}"
10761b654882SGreg Clayton     "{process.file.fullpath = '${process.file.fullpath}'\n}"
10771b654882SGreg Clayton     "{thread.id = '${thread.id}'\n}"
10781b654882SGreg Clayton     "{thread.index = '${thread.index}'\n}"
10791b654882SGreg Clayton     "{thread.name = '${thread.name}'\n}"
10801b654882SGreg Clayton     "{thread.queue = '${thread.queue}'\n}"
10811b654882SGreg Clayton     "{thread.stop-reason = '${thread.stop-reason}'\n}"
10821b654882SGreg Clayton     "{target.arch = '${target.arch}'\n}"
10831b654882SGreg Clayton     "{module.file.basename = '${module.file.basename}'\n}"
10841b654882SGreg Clayton     "{module.file.fullpath = '${module.file.fullpath}'\n}"
10851b654882SGreg Clayton     "{file.basename = '${file.basename}'\n}"
10861b654882SGreg Clayton     "{file.fullpath = '${file.fullpath}'\n}"
10871b654882SGreg Clayton     "{frame.index = '${frame.index}'\n}"
10881b654882SGreg Clayton     "{frame.pc = '${frame.pc}'\n}"
10891b654882SGreg Clayton     "{frame.sp = '${frame.sp}'\n}"
10901b654882SGreg Clayton     "{frame.fp = '${frame.fp}'\n}"
10911b654882SGreg Clayton     "{frame.flags = '${frame.flags}'\n}"
10921b654882SGreg Clayton     "{frame.reg.rdi = '${frame.reg.rdi}'\n}"
10931b654882SGreg Clayton     "{frame.reg.rip = '${frame.reg.rip}'\n}"
10941b654882SGreg Clayton     "{frame.reg.rsp = '${frame.reg.rsp}'\n}"
10951b654882SGreg Clayton     "{frame.reg.rbp = '${frame.reg.rbp}'\n}"
10961b654882SGreg Clayton     "{frame.reg.rflags = '${frame.reg.rflags}'\n}"
10971b654882SGreg Clayton     "{frame.reg.xmm0 = '${frame.reg.xmm0}'\n}"
10981b654882SGreg Clayton     "{frame.reg.carp = '${frame.reg.carp}'\n}"
10991b654882SGreg Clayton     "{function.id = '${function.id}'\n}"
11001b654882SGreg Clayton     "{function.name = '${function.name}'\n}"
1101ccbc08e6SGreg Clayton     "{function.name-with-args = '${function.name-with-args}'\n}"
11021b654882SGreg Clayton     "{function.addr-offset = '${function.addr-offset}'\n}"
11031b654882SGreg Clayton     "{function.line-offset = '${function.line-offset}'\n}"
11041b654882SGreg Clayton     "{function.pc-offset = '${function.pc-offset}'\n}"
11051b654882SGreg Clayton     "{line.file.basename = '${line.file.basename}'\n}"
11061b654882SGreg Clayton     "{line.file.fullpath = '${line.file.fullpath}'\n}"
11071b654882SGreg Clayton     "{line.number = '${line.number}'\n}"
11081b654882SGreg Clayton     "{line.start-addr = '${line.start-addr}'\n}"
11091b654882SGreg Clayton     "{line.end-addr = '${line.end-addr}'\n}"
11101b654882SGreg Clayton ;
11111b654882SGreg Clayton 
11121b654882SGreg Clayton     SymbolContext sc (frame->GetSymbolContext(eSymbolContextEverything));
11131b654882SGreg Clayton     ExecutionContext exe_ctx;
11140603aa9dSGreg Clayton     frame->CalculateExecutionContext(exe_ctx);
11151b654882SGreg Clayton     const char *end = NULL;
11161b654882SGreg Clayton     if (Debugger::FormatPrompt (prompt_format, &sc, &exe_ctx, &sc.line_entry.range.GetBaseAddress(), s, &end))
11171b654882SGreg Clayton     {
11181b654882SGreg Clayton         printf("%s\n", s.GetData());
11191b654882SGreg Clayton     }
11201b654882SGreg Clayton     else
11211b654882SGreg Clayton     {
11221b654882SGreg Clayton         printf ("error: at '%s'\n", end);
11231b654882SGreg Clayton         printf ("what we got: %s\n", s.GetData());
11241b654882SGreg Clayton     }
11251b654882SGreg Clayton }
11261b654882SGreg Clayton 
11279fc1944eSEnrico Granata static bool
11289fc1944eSEnrico Granata ScanFormatDescriptor (const char* var_name_begin,
11299fc1944eSEnrico Granata                       const char* var_name_end,
11309fc1944eSEnrico Granata                       const char** var_name_final,
11319fc1944eSEnrico Granata                       const char** percent_position,
11324d122c40SGreg Clayton                       Format* custom_format,
11339fc1944eSEnrico Granata                       ValueObject::ValueObjectRepresentationStyle* val_obj_display)
11349fc1944eSEnrico Granata {
11355160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
11369fc1944eSEnrico Granata     *percent_position = ::strchr(var_name_begin,'%');
11379fc1944eSEnrico Granata     if (!*percent_position || *percent_position > var_name_end)
1138e992a089SEnrico Granata     {
1139e992a089SEnrico Granata         if (log)
1140d228483dSEnrico Granata             log->Printf("[ScanFormatDescriptor] no format descriptor in string, skipping");
11419fc1944eSEnrico Granata         *var_name_final = var_name_end;
1142e992a089SEnrico Granata     }
11439fc1944eSEnrico Granata     else
11449fc1944eSEnrico Granata     {
11459fc1944eSEnrico Granata         *var_name_final = *percent_position;
114636aa5ae6SEnrico Granata         std::string format_name(*var_name_final+1, var_name_end-*var_name_final-1);
1147e992a089SEnrico Granata         if (log)
114836aa5ae6SEnrico Granata             log->Printf("ScanFormatDescriptor] parsing %s as a format descriptor", format_name.c_str());
114936aa5ae6SEnrico Granata         if ( !FormatManager::GetFormatFromCString(format_name.c_str(),
11509fc1944eSEnrico Granata                                                   true,
11519fc1944eSEnrico Granata                                                   *custom_format) )
11529fc1944eSEnrico Granata         {
1153e992a089SEnrico Granata             if (log)
115436aa5ae6SEnrico Granata                 log->Printf("ScanFormatDescriptor] %s is an unknown format", format_name.c_str());
115536aa5ae6SEnrico Granata 
115636aa5ae6SEnrico Granata             switch (format_name.front())
115736aa5ae6SEnrico Granata             {
115836aa5ae6SEnrico Granata                 case '@':             // if this is an @ sign, print ObjC description
115986cc9829SEnrico Granata                     *val_obj_display = ValueObject::eValueObjectRepresentationStyleLanguageSpecific;
116036aa5ae6SEnrico Granata                     break;
116136aa5ae6SEnrico Granata                 case 'V': // if this is a V, print the value using the default format
116286cc9829SEnrico Granata                     *val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
116336aa5ae6SEnrico Granata                     break;
116436aa5ae6SEnrico Granata                 case 'L': // if this is an L, print the location of the value
116586cc9829SEnrico Granata                     *val_obj_display = ValueObject::eValueObjectRepresentationStyleLocation;
116636aa5ae6SEnrico Granata                     break;
116736aa5ae6SEnrico Granata                 case 'S': // if this is an S, print the summary after all
116886cc9829SEnrico Granata                     *val_obj_display = ValueObject::eValueObjectRepresentationStyleSummary;
116936aa5ae6SEnrico Granata                     break;
117036aa5ae6SEnrico Granata                 case '#': // if this is a '#', print the number of children
117186cc9829SEnrico Granata                     *val_obj_display = ValueObject::eValueObjectRepresentationStyleChildrenCount;
117236aa5ae6SEnrico Granata                     break;
117336aa5ae6SEnrico Granata                 case 'T': // if this is a 'T', print the type
117486cc9829SEnrico Granata                     *val_obj_display = ValueObject::eValueObjectRepresentationStyleType;
117536aa5ae6SEnrico Granata                     break;
117636aa5ae6SEnrico Granata                 default:
117736aa5ae6SEnrico Granata                     log->Printf("ScanFormatDescriptor] %s is an error, leaving the previous value alone", format_name.c_str());
117836aa5ae6SEnrico Granata                     break;
117936aa5ae6SEnrico Granata             }
11809fc1944eSEnrico Granata         }
11819fc1944eSEnrico Granata         // a good custom format tells us to print the value using it
11829fc1944eSEnrico Granata         else
1183e992a089SEnrico Granata         {
1184e992a089SEnrico Granata             if (log)
1185d228483dSEnrico Granata                 log->Printf("ScanFormatDescriptor] will display value for this VO");
118686cc9829SEnrico Granata             *val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
1187e992a089SEnrico Granata         }
11889fc1944eSEnrico Granata     }
1189e992a089SEnrico Granata     if (log)
1190d228483dSEnrico Granata         log->Printf("ScanFormatDescriptor] final format description outcome: custom_format = %d, val_obj_display = %d",
1191e992a089SEnrico Granata                     *custom_format,
1192e992a089SEnrico Granata                     *val_obj_display);
11939fc1944eSEnrico Granata     return true;
11949fc1944eSEnrico Granata }
11959fc1944eSEnrico Granata 
11969fc1944eSEnrico Granata static bool
11979fc1944eSEnrico Granata ScanBracketedRange (const char* var_name_begin,
11989fc1944eSEnrico Granata                     const char* var_name_end,
11999fc1944eSEnrico Granata                     const char* var_name_final,
12009fc1944eSEnrico Granata                     const char** open_bracket_position,
12019fc1944eSEnrico Granata                     const char** separator_position,
12029fc1944eSEnrico Granata                     const char** close_bracket_position,
12039fc1944eSEnrico Granata                     const char** var_name_final_if_array_range,
12049fc1944eSEnrico Granata                     int64_t* index_lower,
12059fc1944eSEnrico Granata                     int64_t* index_higher)
12069fc1944eSEnrico Granata {
12075160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
12089fc1944eSEnrico Granata     *open_bracket_position = ::strchr(var_name_begin,'[');
12099fc1944eSEnrico Granata     if (*open_bracket_position && *open_bracket_position < var_name_final)
12109fc1944eSEnrico Granata     {
12119fc1944eSEnrico Granata         *separator_position = ::strchr(*open_bracket_position,'-'); // might be NULL if this is a simple var[N] bitfield
12129fc1944eSEnrico Granata         *close_bracket_position = ::strchr(*open_bracket_position,']');
12139fc1944eSEnrico Granata         // as usual, we assume that [] will come before %
12149fc1944eSEnrico Granata         //printf("trying to expand a []\n");
12159fc1944eSEnrico Granata         *var_name_final_if_array_range = *open_bracket_position;
12169fc1944eSEnrico Granata         if (*close_bracket_position - *open_bracket_position == 1)
12179fc1944eSEnrico Granata         {
1218e992a089SEnrico Granata             if (log)
1219d228483dSEnrico Granata                 log->Printf("[ScanBracketedRange] '[]' detected.. going from 0 to end of data");
12209fc1944eSEnrico Granata             *index_lower = 0;
12219fc1944eSEnrico Granata         }
12229fc1944eSEnrico Granata         else if (*separator_position == NULL || *separator_position > var_name_end)
12239fc1944eSEnrico Granata         {
12249fc1944eSEnrico Granata             char *end = NULL;
12259fc1944eSEnrico Granata             *index_lower = ::strtoul (*open_bracket_position+1, &end, 0);
12269fc1944eSEnrico Granata             *index_higher = *index_lower;
1227e992a089SEnrico Granata             if (log)
1228d01b2953SDaniel Malea                 log->Printf("[ScanBracketedRange] [%" PRId64 "] detected, high index is same", *index_lower);
12299fc1944eSEnrico Granata         }
12309fc1944eSEnrico Granata         else if (*close_bracket_position && *close_bracket_position < var_name_end)
12319fc1944eSEnrico Granata         {
12329fc1944eSEnrico Granata             char *end = NULL;
12339fc1944eSEnrico Granata             *index_lower = ::strtoul (*open_bracket_position+1, &end, 0);
12349fc1944eSEnrico Granata             *index_higher = ::strtoul (*separator_position+1, &end, 0);
1235e992a089SEnrico Granata             if (log)
1236d01b2953SDaniel Malea                 log->Printf("[ScanBracketedRange] [%" PRId64 "-%" PRId64 "] detected", *index_lower, *index_higher);
12379fc1944eSEnrico Granata         }
12389fc1944eSEnrico Granata         else
1239e992a089SEnrico Granata         {
1240e992a089SEnrico Granata             if (log)
1241d228483dSEnrico Granata                 log->Printf("[ScanBracketedRange] expression is erroneous, cannot extract indices out of it");
12429fc1944eSEnrico Granata             return false;
1243e992a089SEnrico Granata         }
12449fc1944eSEnrico Granata         if (*index_lower > *index_higher && *index_higher > 0)
12459fc1944eSEnrico Granata         {
1246e992a089SEnrico Granata             if (log)
1247d228483dSEnrico Granata                 log->Printf("[ScanBracketedRange] swapping indices");
1248c7bece56SGreg Clayton             int64_t temp = *index_lower;
12499fc1944eSEnrico Granata             *index_lower = *index_higher;
12509fc1944eSEnrico Granata             *index_higher = temp;
12519fc1944eSEnrico Granata         }
12529fc1944eSEnrico Granata     }
1253e992a089SEnrico Granata     else if (log)
1254d228483dSEnrico Granata             log->Printf("[ScanBracketedRange] no bracketed range, skipping entirely");
12559fc1944eSEnrico Granata     return true;
12569fc1944eSEnrico Granata }
12579fc1944eSEnrico Granata 
12589fc1944eSEnrico Granata static ValueObjectSP
1259c482a192SEnrico Granata ExpandIndexedExpression (ValueObject* valobj,
1260c7bece56SGreg Clayton                          size_t index,
12619fc1944eSEnrico Granata                          StackFrame* frame,
1262fc7a7f3bSEnrico Granata                          bool deref_pointer)
12639fc1944eSEnrico Granata {
12645160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
1265fc7a7f3bSEnrico Granata     const char* ptr_deref_format = "[%d]";
1266599171adSEnrico Granata     std::string ptr_deref_buffer(10,0);
1267599171adSEnrico Granata     ::sprintf(&ptr_deref_buffer[0], ptr_deref_format, index);
1268e992a089SEnrico Granata     if (log)
1269599171adSEnrico Granata         log->Printf("[ExpandIndexedExpression] name to deref: %s",ptr_deref_buffer.c_str());
1270fc7a7f3bSEnrico Granata     const char* first_unparsed;
1271fc7a7f3bSEnrico Granata     ValueObject::GetValueForExpressionPathOptions options;
1272fc7a7f3bSEnrico Granata     ValueObject::ExpressionPathEndResultType final_value_type;
1273fc7a7f3bSEnrico Granata     ValueObject::ExpressionPathScanEndReason reason_to_stop;
127486cc9829SEnrico Granata     ValueObject::ExpressionPathAftermath what_next = (deref_pointer ? ValueObject::eExpressionPathAftermathDereference : ValueObject::eExpressionPathAftermathNothing);
1275599171adSEnrico Granata     ValueObjectSP item = valobj->GetValueForExpressionPath (ptr_deref_buffer.c_str(),
1276fc7a7f3bSEnrico Granata                                                           &first_unparsed,
1277fc7a7f3bSEnrico Granata                                                           &reason_to_stop,
1278fc7a7f3bSEnrico Granata                                                           &final_value_type,
1279fc7a7f3bSEnrico Granata                                                           options,
1280fc7a7f3bSEnrico Granata                                                           &what_next);
1281fc7a7f3bSEnrico Granata     if (!item)
1282fc7a7f3bSEnrico Granata     {
1283e992a089SEnrico Granata         if (log)
1284d228483dSEnrico Granata             log->Printf("[ExpandIndexedExpression] ERROR: unparsed portion = %s, why stopping = %d,"
1285e992a089SEnrico Granata                " final_value_type %d",
1286fc7a7f3bSEnrico Granata                first_unparsed, reason_to_stop, final_value_type);
1287fc7a7f3bSEnrico Granata     }
12889fc1944eSEnrico Granata     else
12899fc1944eSEnrico Granata     {
1290e992a089SEnrico Granata         if (log)
1291d228483dSEnrico Granata             log->Printf("[ExpandIndexedExpression] ALL RIGHT: unparsed portion = %s, why stopping = %d,"
1292e992a089SEnrico Granata                " final_value_type %d",
1293fc7a7f3bSEnrico Granata                first_unparsed, reason_to_stop, final_value_type);
12949fc1944eSEnrico Granata     }
12959fc1944eSEnrico Granata     return item;
12969fc1944eSEnrico Granata }
12979fc1944eSEnrico Granata 
12981b654882SGreg Clayton bool
12991b654882SGreg Clayton Debugger::FormatPrompt
13001b654882SGreg Clayton (
13011b654882SGreg Clayton     const char *format,
13021b654882SGreg Clayton     const SymbolContext *sc,
13031b654882SGreg Clayton     const ExecutionContext *exe_ctx,
13041b654882SGreg Clayton     const Address *addr,
13051b654882SGreg Clayton     Stream &s,
13064becb37eSEnrico Granata     const char **end,
1307c482a192SEnrico Granata     ValueObject* valobj
13081b654882SGreg Clayton )
13091b654882SGreg Clayton {
1310c482a192SEnrico Granata     ValueObject* realvalobj = NULL; // makes it super-easy to parse pointers
13111b654882SGreg Clayton     bool success = true;
13121b654882SGreg Clayton     const char *p;
13135160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
13141b654882SGreg Clayton     for (p = format; *p != '\0'; ++p)
13151b654882SGreg Clayton     {
1316c482a192SEnrico Granata         if (realvalobj)
13174becb37eSEnrico Granata         {
1318c482a192SEnrico Granata             valobj = realvalobj;
1319c482a192SEnrico Granata             realvalobj = NULL;
13204becb37eSEnrico Granata         }
13211b654882SGreg Clayton         size_t non_special_chars = ::strcspn (p, "${}\\");
13221b654882SGreg Clayton         if (non_special_chars > 0)
13231b654882SGreg Clayton         {
13241b654882SGreg Clayton             if (success)
13251b654882SGreg Clayton                 s.Write (p, non_special_chars);
13261b654882SGreg Clayton             p += non_special_chars;
13271b654882SGreg Clayton         }
13281b654882SGreg Clayton 
13291b654882SGreg Clayton         if (*p == '\0')
13301b654882SGreg Clayton         {
13311b654882SGreg Clayton             break;
13321b654882SGreg Clayton         }
13331b654882SGreg Clayton         else if (*p == '{')
13341b654882SGreg Clayton         {
13351b654882SGreg Clayton             // Start a new scope that must have everything it needs if it is to
13361b654882SGreg Clayton             // to make it into the final output stream "s". If you want to make
13371b654882SGreg Clayton             // a format that only prints out the function or symbol name if there
13381b654882SGreg Clayton             // is one in the symbol context you can use:
13391b654882SGreg Clayton             //      "{function =${function.name}}"
13401b654882SGreg Clayton             // The first '{' starts a new scope that end with the matching '}' at
13411b654882SGreg Clayton             // the end of the string. The contents "function =${function.name}"
13421b654882SGreg Clayton             // will then be evaluated and only be output if there is a function
13431b654882SGreg Clayton             // or symbol with a valid name.
13441b654882SGreg Clayton             StreamString sub_strm;
13451b654882SGreg Clayton 
13461b654882SGreg Clayton             ++p;  // Skip the '{'
13471b654882SGreg Clayton 
1348c482a192SEnrico Granata             if (FormatPrompt (p, sc, exe_ctx, addr, sub_strm, &p, valobj))
13491b654882SGreg Clayton             {
13501b654882SGreg Clayton                 // The stream had all it needed
13511b654882SGreg Clayton                 s.Write(sub_strm.GetData(), sub_strm.GetSize());
13521b654882SGreg Clayton             }
13531b654882SGreg Clayton             if (*p != '}')
13541b654882SGreg Clayton             {
13551b654882SGreg Clayton                 success = false;
13561b654882SGreg Clayton                 break;
13571b654882SGreg Clayton             }
13581b654882SGreg Clayton         }
13591b654882SGreg Clayton         else if (*p == '}')
13601b654882SGreg Clayton         {
13611b654882SGreg Clayton             // End of a enclosing scope
13621b654882SGreg Clayton             break;
13631b654882SGreg Clayton         }
13641b654882SGreg Clayton         else if (*p == '$')
13651b654882SGreg Clayton         {
13661b654882SGreg Clayton             // We have a prompt variable to print
13671b654882SGreg Clayton             ++p;
13681b654882SGreg Clayton             if (*p == '{')
13691b654882SGreg Clayton             {
13701b654882SGreg Clayton                 ++p;
13711b654882SGreg Clayton                 const char *var_name_begin = p;
13721b654882SGreg Clayton                 const char *var_name_end = ::strchr (p, '}');
13731b654882SGreg Clayton 
13741b654882SGreg Clayton                 if (var_name_end && var_name_begin < var_name_end)
13751b654882SGreg Clayton                 {
13761b654882SGreg Clayton                     // if we have already failed to parse, skip this variable
13771b654882SGreg Clayton                     if (success)
13781b654882SGreg Clayton                     {
13791b654882SGreg Clayton                         const char *cstr = NULL;
13801b654882SGreg Clayton                         Address format_addr;
13811b654882SGreg Clayton                         bool calculate_format_addr_function_offset = false;
13821b654882SGreg Clayton                         // Set reg_kind and reg_num to invalid values
13831b654882SGreg Clayton                         RegisterKind reg_kind = kNumRegisterKinds;
13841b654882SGreg Clayton                         uint32_t reg_num = LLDB_INVALID_REGNUM;
13851b654882SGreg Clayton                         FileSpec format_file_spec;
1386e0d378b3SGreg Clayton                         const RegisterInfo *reg_info = NULL;
13871b654882SGreg Clayton                         RegisterContext *reg_ctx = NULL;
13889fc1944eSEnrico Granata                         bool do_deref_pointer = false;
138986cc9829SEnrico Granata                         ValueObject::ExpressionPathScanEndReason reason_to_stop = ValueObject::eExpressionPathScanEndReasonEndOfString;
139086cc9829SEnrico Granata                         ValueObject::ExpressionPathEndResultType final_value_type = ValueObject::eExpressionPathEndResultTypePlain;
13911b654882SGreg Clayton 
13921b654882SGreg Clayton                         // Each variable must set success to true below...
13931b654882SGreg Clayton                         bool var_success = false;
13941b654882SGreg Clayton                         switch (var_name_begin[0])
13951b654882SGreg Clayton                         {
13964becb37eSEnrico Granata                         case '*':
13976f3533fbSEnrico Granata                         case 'v':
13986f3533fbSEnrico Granata                         case 's':
13994becb37eSEnrico Granata                             {
1400c482a192SEnrico Granata                                 if (!valobj)
140134132754SGreg Clayton                                     break;
14026f3533fbSEnrico Granata 
1403c3e320a7SEnrico Granata                                 if (log)
1404d228483dSEnrico Granata                                     log->Printf("[Debugger::FormatPrompt] initial string: %s",var_name_begin);
1405c3e320a7SEnrico Granata 
14066f3533fbSEnrico Granata                                 // check for *var and *svar
14076f3533fbSEnrico Granata                                 if (*var_name_begin == '*')
14086f3533fbSEnrico Granata                                 {
14099fc1944eSEnrico Granata                                     do_deref_pointer = true;
14109fc1944eSEnrico Granata                                     var_name_begin++;
14119fc1944eSEnrico Granata                                 }
1412c3e320a7SEnrico Granata 
1413c3e320a7SEnrico Granata                                 if (log)
1414d228483dSEnrico Granata                                     log->Printf("[Debugger::FormatPrompt] initial string: %s",var_name_begin);
1415c3e320a7SEnrico Granata 
14166f3533fbSEnrico Granata                                 if (*var_name_begin == 's')
14174becb37eSEnrico Granata                                 {
1418c5bc412cSEnrico Granata                                     if (!valobj->IsSynthetic())
141986cc9829SEnrico Granata                                         valobj = valobj->GetSyntheticValue().get();
142086cc9829SEnrico Granata                                     if (!valobj)
142186cc9829SEnrico Granata                                         break;
14226f3533fbSEnrico Granata                                     var_name_begin++;
14236f3533fbSEnrico Granata                                 }
14246f3533fbSEnrico Granata 
1425c3e320a7SEnrico Granata                                 if (log)
1426d228483dSEnrico Granata                                     log->Printf("[Debugger::FormatPrompt] initial string: %s",var_name_begin);
1427c3e320a7SEnrico Granata 
14286f3533fbSEnrico Granata                                 // should be a 'v' by now
14296f3533fbSEnrico Granata                                 if (*var_name_begin != 'v')
14306f3533fbSEnrico Granata                                     break;
14316f3533fbSEnrico Granata 
1432c3e320a7SEnrico Granata                                 if (log)
1433d228483dSEnrico Granata                                     log->Printf("[Debugger::FormatPrompt] initial string: %s",var_name_begin);
1434c3e320a7SEnrico Granata 
1435fc7a7f3bSEnrico Granata                                 ValueObject::ExpressionPathAftermath what_next = (do_deref_pointer ?
143686cc9829SEnrico Granata                                                                                   ValueObject::eExpressionPathAftermathDereference : ValueObject::eExpressionPathAftermathNothing);
1437fc7a7f3bSEnrico Granata                                 ValueObject::GetValueForExpressionPathOptions options;
14388c9d3560SEnrico Granata                                 options.DontCheckDotVsArrowSyntax().DoAllowBitfieldSyntax().DoAllowFragileIVar().DoAllowSyntheticChildren();
143986cc9829SEnrico Granata                                 ValueObject::ValueObjectRepresentationStyle val_obj_display = ValueObject::eValueObjectRepresentationStyleSummary;
144034132754SGreg Clayton                                 ValueObject* target = NULL;
14414d122c40SGreg Clayton                                 Format custom_format = eFormatInvalid;
144234132754SGreg Clayton                                 const char* var_name_final = NULL;
14439fc1944eSEnrico Granata                                 const char* var_name_final_if_array_range = NULL;
144434132754SGreg Clayton                                 const char* close_bracket_position = NULL;
144534132754SGreg Clayton                                 int64_t index_lower = -1;
144634132754SGreg Clayton                                 int64_t index_higher = -1;
14479fc1944eSEnrico Granata                                 bool is_array_range = false;
1448fc7a7f3bSEnrico Granata                                 const char* first_unparsed;
144985933ed4SEnrico Granata                                 bool was_plain_var = false;
145085933ed4SEnrico Granata                                 bool was_var_format = false;
1451a777dc2aSEnrico Granata                                 bool was_var_indexed = false;
1452fc7a7f3bSEnrico Granata 
1453c482a192SEnrico Granata                                 if (!valobj) break;
1454c482a192SEnrico Granata                                 // simplest case ${var}, just print valobj's value
14559fc1944eSEnrico Granata                                 if (::strncmp (var_name_begin, "var}", strlen("var}")) == 0)
14560a3958e0SEnrico Granata                                 {
145785933ed4SEnrico Granata                                     was_plain_var = true;
1458c482a192SEnrico Granata                                     target = valobj;
145986cc9829SEnrico Granata                                     val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
14600a3958e0SEnrico Granata                                 }
14619fc1944eSEnrico Granata                                 else if (::strncmp(var_name_begin,"var%",strlen("var%")) == 0)
14629fc1944eSEnrico Granata                                 {
146385933ed4SEnrico Granata                                     was_var_format = true;
14649fc1944eSEnrico Granata                                     // this is a variable with some custom format applied to it
14659fc1944eSEnrico Granata                                     const char* percent_position;
1466c482a192SEnrico Granata                                     target = valobj;
146786cc9829SEnrico Granata                                     val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
14689fc1944eSEnrico Granata                                     ScanFormatDescriptor (var_name_begin,
14699fc1944eSEnrico Granata                                                           var_name_end,
14709fc1944eSEnrico Granata                                                           &var_name_final,
14719fc1944eSEnrico Granata                                                           &percent_position,
14729fc1944eSEnrico Granata                                                           &custom_format,
14739fc1944eSEnrico Granata                                                           &val_obj_display);
14740a3958e0SEnrico Granata                                 }
14759fc1944eSEnrico Granata                                     // this is ${var.something} or multiple .something nested
14769fc1944eSEnrico Granata                                 else if (::strncmp (var_name_begin, "var", strlen("var")) == 0)
14779fc1944eSEnrico Granata                                 {
1478a777dc2aSEnrico Granata                                     if (::strncmp(var_name_begin, "var[", strlen("var[")) == 0)
1479a777dc2aSEnrico Granata                                         was_var_indexed = true;
14809fc1944eSEnrico Granata                                     const char* percent_position;
14819fc1944eSEnrico Granata                                     ScanFormatDescriptor (var_name_begin,
14829fc1944eSEnrico Granata                                                           var_name_end,
14839fc1944eSEnrico Granata                                                           &var_name_final,
14849fc1944eSEnrico Granata                                                           &percent_position,
14859fc1944eSEnrico Granata                                                           &custom_format,
14869fc1944eSEnrico Granata                                                           &val_obj_display);
14879fc1944eSEnrico Granata 
14889fc1944eSEnrico Granata                                     const char* open_bracket_position;
14899fc1944eSEnrico Granata                                     const char* separator_position;
14909fc1944eSEnrico Granata                                     ScanBracketedRange (var_name_begin,
14919fc1944eSEnrico Granata                                                         var_name_end,
14929fc1944eSEnrico Granata                                                         var_name_final,
14939fc1944eSEnrico Granata                                                         &open_bracket_position,
14949fc1944eSEnrico Granata                                                         &separator_position,
14959fc1944eSEnrico Granata                                                         &close_bracket_position,
14969fc1944eSEnrico Granata                                                         &var_name_final_if_array_range,
14979fc1944eSEnrico Granata                                                         &index_lower,
14989fc1944eSEnrico Granata                                                         &index_higher);
14999fc1944eSEnrico Granata 
15009fc1944eSEnrico Granata                                     Error error;
15019fc1944eSEnrico Granata 
1502599171adSEnrico Granata                                     std::string expr_path(var_name_final-var_name_begin-1,0);
1503599171adSEnrico Granata                                     memcpy(&expr_path[0], var_name_begin+3,var_name_final-var_name_begin-3);
1504fc7a7f3bSEnrico Granata 
1505e992a089SEnrico Granata                                     if (log)
1506599171adSEnrico Granata                                         log->Printf("[Debugger::FormatPrompt] symbol to expand: %s",expr_path.c_str());
1507fc7a7f3bSEnrico Granata 
1508599171adSEnrico Granata                                     target = valobj->GetValueForExpressionPath(expr_path.c_str(),
1509fc7a7f3bSEnrico Granata                                                                              &first_unparsed,
1510fc7a7f3bSEnrico Granata                                                                              &reason_to_stop,
1511fc7a7f3bSEnrico Granata                                                                              &final_value_type,
1512fc7a7f3bSEnrico Granata                                                                              options,
1513fc7a7f3bSEnrico Granata                                                                              &what_next).get();
1514fc7a7f3bSEnrico Granata 
1515fc7a7f3bSEnrico Granata                                     if (!target)
15169fc1944eSEnrico Granata                                     {
1517e992a089SEnrico Granata                                         if (log)
1518d228483dSEnrico Granata                                             log->Printf("[Debugger::FormatPrompt] ERROR: unparsed portion = %s, why stopping = %d,"
1519e992a089SEnrico Granata                                                " final_value_type %d",
1520fc7a7f3bSEnrico Granata                                                first_unparsed, reason_to_stop, final_value_type);
1521fc7a7f3bSEnrico Granata                                         break;
15220a3958e0SEnrico Granata                                     }
1523a7187d00SEnrico Granata                                     else
1524fc7a7f3bSEnrico Granata                                     {
1525e992a089SEnrico Granata                                         if (log)
1526d228483dSEnrico Granata                                             log->Printf("[Debugger::FormatPrompt] ALL RIGHT: unparsed portion = %s, why stopping = %d,"
1527e992a089SEnrico Granata                                                " final_value_type %d",
1528fc7a7f3bSEnrico Granata                                                first_unparsed, reason_to_stop, final_value_type);
1529a7187d00SEnrico Granata                                     }
15300a3958e0SEnrico Granata                                 }
15310a3958e0SEnrico Granata                                 else
15320a3958e0SEnrico Granata                                     break;
15339fc1944eSEnrico Granata 
153486cc9829SEnrico Granata                                 is_array_range = (final_value_type == ValueObject::eExpressionPathEndResultTypeBoundedRange ||
153586cc9829SEnrico Granata                                                   final_value_type == ValueObject::eExpressionPathEndResultTypeUnboundedRange);
1536fc7a7f3bSEnrico Granata 
153786cc9829SEnrico Granata                                 do_deref_pointer = (what_next == ValueObject::eExpressionPathAftermathDereference);
1538fc7a7f3bSEnrico Granata 
1539a7187d00SEnrico Granata                                 if (do_deref_pointer && !is_array_range)
15400a3958e0SEnrico Granata                                 {
15419fc1944eSEnrico Granata                                     // I have not deref-ed yet, let's do it
15429fc1944eSEnrico Granata                                     // this happens when we are not going through GetValueForVariableExpressionPath
15439fc1944eSEnrico Granata                                     // to get to the target ValueObject
15449fc1944eSEnrico Granata                                     Error error;
15459fc1944eSEnrico Granata                                     target = target->Dereference(error).get();
1546dc940730SEnrico Granata                                     if (error.Fail())
1547dc940730SEnrico Granata                                     {
1548dc940730SEnrico Granata                                         if (log)
1549d228483dSEnrico Granata                                             log->Printf("[Debugger::FormatPrompt] ERROR: %s\n", error.AsCString("unknown")); \
1550dc940730SEnrico Granata                                         break;
1551dc940730SEnrico Granata                                     }
15529fc1944eSEnrico Granata                                     do_deref_pointer = false;
15530a3958e0SEnrico Granata                                 }
15540a3958e0SEnrico Granata 
1555a777dc2aSEnrico Granata                                 // <rdar://problem/11338654>
1556a777dc2aSEnrico Granata                                 // we do not want to use the summary for a bitfield of type T:n
1557a777dc2aSEnrico Granata                                 // if we were originally dealing with just a T - that would get
1558a777dc2aSEnrico Granata                                 // us into an endless recursion
1559a777dc2aSEnrico Granata                                 if (target->IsBitfield() && was_var_indexed)
1560a777dc2aSEnrico Granata                                 {
1561a777dc2aSEnrico Granata                                     // TODO: check for a (T:n)-specific summary - we should still obey that
1562a777dc2aSEnrico Granata                                     StreamString bitfield_name;
1563a777dc2aSEnrico Granata                                     bitfield_name.Printf("%s:%d", target->GetTypeName().AsCString(), target->GetBitfieldBitSize());
1564a777dc2aSEnrico Granata                                     lldb::TypeNameSpecifierImplSP type_sp(new TypeNameSpecifierImpl(bitfield_name.GetData(),false));
1565a777dc2aSEnrico Granata                                     if (!DataVisualization::GetSummaryForType(type_sp))
1566a777dc2aSEnrico Granata                                         val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
1567a777dc2aSEnrico Granata                                 }
1568a777dc2aSEnrico Granata 
156985933ed4SEnrico Granata                                 // TODO use flags for these
15704ef877f5SGreg Clayton                                 bool is_array = ClangASTContext::IsArrayType(target->GetClangType(), NULL, NULL, NULL);
1571f4efecd9SEnrico Granata                                 bool is_pointer = ClangASTContext::IsPointerType(target->GetClangType());
157285933ed4SEnrico Granata                                 bool is_aggregate = ClangASTContext::IsAggregateType(target->GetClangType());
1573f4efecd9SEnrico Granata 
157486cc9829SEnrico Granata                                 if ((is_array || is_pointer) && (!is_array_range) && val_obj_display == ValueObject::eValueObjectRepresentationStyleValue) // this should be wrong, but there are some exceptions
1575f4efecd9SEnrico Granata                                 {
157685933ed4SEnrico Granata                                     StreamString str_temp;
1577e992a089SEnrico Granata                                     if (log)
1578d228483dSEnrico Granata                                         log->Printf("[Debugger::FormatPrompt] I am into array || pointer && !range");
1579d64d0bc0SEnrico Granata 
15805088c486SGreg Clayton                                     if (target->HasSpecialPrintableRepresentation(val_obj_display, custom_format))
1581d64d0bc0SEnrico Granata                                     {
1582f4efecd9SEnrico Granata                                         // try to use the special cases
158385933ed4SEnrico Granata                                         var_success = target->DumpPrintableRepresentation(str_temp,
158485933ed4SEnrico Granata                                                                                           val_obj_display,
158585933ed4SEnrico Granata                                                                                           custom_format);
1586e992a089SEnrico Granata                                         if (log)
1587d228483dSEnrico Granata                                             log->Printf("[Debugger::FormatPrompt] special cases did%s match", var_success ? "" : "n't");
1588d64d0bc0SEnrico Granata 
1589d64d0bc0SEnrico Granata                                         // should not happen
15905088c486SGreg Clayton                                         if (var_success)
159185933ed4SEnrico Granata                                             s << str_temp.GetData();
1592d64d0bc0SEnrico Granata                                         var_success = true;
1593d64d0bc0SEnrico Granata                                         break;
1594d64d0bc0SEnrico Granata                                     }
1595d64d0bc0SEnrico Granata                                     else
1596d64d0bc0SEnrico Granata                                     {
159788da35f8SEnrico Granata                                         if (was_plain_var) // if ${var}
1598d64d0bc0SEnrico Granata                                         {
1599d64d0bc0SEnrico Granata                                             s << target->GetTypeName() << " @ " << target->GetLocationAsCString();
1600d64d0bc0SEnrico Granata                                         }
160188da35f8SEnrico Granata                                         else if (is_pointer) // if pointer, value is the address stored
160288da35f8SEnrico Granata                                         {
160323f59509SGreg Clayton                                             target->DumpPrintableRepresentation (s,
160488da35f8SEnrico Granata                                                                                  val_obj_display,
160586cc9829SEnrico Granata                                                                                  custom_format,
160686cc9829SEnrico Granata                                                                                  ValueObject::ePrintableRepresentationSpecialCasesDisable);
160788da35f8SEnrico Granata                                         }
1608d64d0bc0SEnrico Granata                                         var_success = true;
1609d64d0bc0SEnrico Granata                                         break;
1610d64d0bc0SEnrico Granata                                     }
1611d64d0bc0SEnrico Granata                                 }
1612d64d0bc0SEnrico Granata 
1613d64d0bc0SEnrico Granata                                 // if directly trying to print ${var}, and this is an aggregate, display a nice
1614d64d0bc0SEnrico Granata                                 // type @ location message
1615d64d0bc0SEnrico Granata                                 if (is_aggregate && was_plain_var)
1616d64d0bc0SEnrico Granata                                 {
1617d64d0bc0SEnrico Granata                                     s << target->GetTypeName() << " @ " << target->GetLocationAsCString();
1618d64d0bc0SEnrico Granata                                     var_success = true;
161985933ed4SEnrico Granata                                     break;
162085933ed4SEnrico Granata                                 }
162185933ed4SEnrico Granata 
1622d64d0bc0SEnrico Granata                                 // if directly trying to print ${var%V}, and this is an aggregate, do not let the user do it
162386cc9829SEnrico Granata                                 if (is_aggregate && ((was_var_format && val_obj_display == ValueObject::eValueObjectRepresentationStyleValue)))
162485933ed4SEnrico Granata                                 {
162585933ed4SEnrico Granata                                     s << "<invalid use of aggregate type>";
162685933ed4SEnrico Granata                                     var_success = true;
1627f4efecd9SEnrico Granata                                     break;
1628f4efecd9SEnrico Granata                                 }
1629f4efecd9SEnrico Granata 
16309fc1944eSEnrico Granata                                 if (!is_array_range)
1631e992a089SEnrico Granata                                 {
1632e992a089SEnrico Granata                                     if (log)
1633d228483dSEnrico Granata                                         log->Printf("[Debugger::FormatPrompt] dumping ordinary printable output");
16349fc1944eSEnrico Granata                                     var_success = target->DumpPrintableRepresentation(s,val_obj_display, custom_format);
1635e992a089SEnrico Granata                                 }
16369fc1944eSEnrico Granata                                 else
16379fc1944eSEnrico Granata                                 {
1638e992a089SEnrico Granata                                     if (log)
1639d228483dSEnrico Granata                                         log->Printf("[Debugger::FormatPrompt] checking if I can handle as array");
16409fc1944eSEnrico Granata                                     if (!is_array && !is_pointer)
16419fc1944eSEnrico Granata                                         break;
1642e992a089SEnrico Granata                                     if (log)
1643d228483dSEnrico Granata                                         log->Printf("[Debugger::FormatPrompt] handle as array");
1644fc7a7f3bSEnrico Granata                                     const char* special_directions = NULL;
1645fc7a7f3bSEnrico Granata                                     StreamString special_directions_writer;
16460a3958e0SEnrico Granata                                     if (close_bracket_position && (var_name_end-close_bracket_position > 1))
16470a3958e0SEnrico Granata                                     {
1648fc7a7f3bSEnrico Granata                                         ConstString additional_data;
1649fc7a7f3bSEnrico Granata                                         additional_data.SetCStringWithLength(close_bracket_position+1, var_name_end-close_bracket_position-1);
1650fc7a7f3bSEnrico Granata                                         special_directions_writer.Printf("${%svar%s}",
1651fc7a7f3bSEnrico Granata                                                                          do_deref_pointer ? "*" : "",
1652fc7a7f3bSEnrico Granata                                                                          additional_data.GetCString());
1653fc7a7f3bSEnrico Granata                                         special_directions = special_directions_writer.GetData();
16540a3958e0SEnrico Granata                                     }
16550a3958e0SEnrico Granata 
16560a3958e0SEnrico Granata                                     // let us display items index_lower thru index_higher of this array
16570a3958e0SEnrico Granata                                     s.PutChar('[');
16580a3958e0SEnrico Granata                                     var_success = true;
16590a3958e0SEnrico Granata 
16609fc1944eSEnrico Granata                                     if (index_higher < 0)
1661c482a192SEnrico Granata                                         index_higher = valobj->GetNumChildren() - 1;
16620a3958e0SEnrico Granata 
1663cc4d0146SGreg Clayton                                     uint32_t max_num_children = target->GetTargetSP()->GetMaximumNumberOfChildrenToDisplay();
166422c55d18SEnrico Granata 
16650a3958e0SEnrico Granata                                     for (;index_lower<=index_higher;index_lower++)
16660a3958e0SEnrico Granata                                     {
1667fc7a7f3bSEnrico Granata                                         ValueObject* item = ExpandIndexedExpression (target,
16689fc1944eSEnrico Granata                                                                                      index_lower,
1669c14ee32dSGreg Clayton                                                                                      exe_ctx->GetFramePtr(),
1670fc7a7f3bSEnrico Granata                                                                                      false).get();
16710a3958e0SEnrico Granata 
1672fc7a7f3bSEnrico Granata                                         if (!item)
1673fc7a7f3bSEnrico Granata                                         {
1674e992a089SEnrico Granata                                             if (log)
1675d01b2953SDaniel Malea                                                 log->Printf("[Debugger::FormatPrompt] ERROR in getting child item at index %" PRId64, index_lower);
1676fc7a7f3bSEnrico Granata                                         }
1677fc7a7f3bSEnrico Granata                                         else
1678fc7a7f3bSEnrico Granata                                         {
1679e992a089SEnrico Granata                                             if (log)
1680d228483dSEnrico Granata                                                 log->Printf("[Debugger::FormatPrompt] special_directions for child item: %s",special_directions);
1681fc7a7f3bSEnrico Granata                                         }
1682fc7a7f3bSEnrico Granata 
16830a3958e0SEnrico Granata                                         if (!special_directions)
16849fc1944eSEnrico Granata                                             var_success &= item->DumpPrintableRepresentation(s,val_obj_display, custom_format);
16850a3958e0SEnrico Granata                                         else
16860a3958e0SEnrico Granata                                             var_success &= FormatPrompt(special_directions, sc, exe_ctx, addr, s, NULL, item);
16870a3958e0SEnrico Granata 
168822c55d18SEnrico Granata                                         if (--max_num_children == 0)
168922c55d18SEnrico Granata                                         {
169022c55d18SEnrico Granata                                             s.PutCString(", ...");
169122c55d18SEnrico Granata                                             break;
169222c55d18SEnrico Granata                                         }
169322c55d18SEnrico Granata 
16940a3958e0SEnrico Granata                                         if (index_lower < index_higher)
16950a3958e0SEnrico Granata                                             s.PutChar(',');
16960a3958e0SEnrico Granata                                     }
16970a3958e0SEnrico Granata                                     s.PutChar(']');
16984becb37eSEnrico Granata                                 }
16994becb37eSEnrico Granata                             }
170034132754SGreg Clayton                             break;
17011b654882SGreg Clayton                         case 'a':
17021b654882SGreg Clayton                             if (::strncmp (var_name_begin, "addr}", strlen("addr}")) == 0)
17031b654882SGreg Clayton                             {
17041b654882SGreg Clayton                                 if (addr && addr->IsValid())
17051b654882SGreg Clayton                                 {
17061b654882SGreg Clayton                                     var_success = true;
17071b654882SGreg Clayton                                     format_addr = *addr;
17081b654882SGreg Clayton                                 }
17091b654882SGreg Clayton                             }
17105a31471eSGreg Clayton                             else if (::strncmp (var_name_begin, "ansi.", strlen("ansi.")) == 0)
17115a31471eSGreg Clayton                             {
17125a31471eSGreg Clayton                                 var_success = true;
17135a31471eSGreg Clayton                                 var_name_begin += strlen("ansi."); // Skip the "ansi."
17145a31471eSGreg Clayton                                 if (::strncmp (var_name_begin, "fg.", strlen("fg.")) == 0)
17155a31471eSGreg Clayton                                 {
17165a31471eSGreg Clayton                                     var_name_begin += strlen("fg."); // Skip the "fg."
17175a31471eSGreg Clayton                                     if (::strncmp (var_name_begin, "black}", strlen("black}")) == 0)
17185a31471eSGreg Clayton                                     {
17195a31471eSGreg Clayton                                         s.Printf ("%s%s%s",
17205a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_start,
17215a31471eSGreg Clayton                                                   lldb_utility::ansi::k_fg_black,
17225a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_end);
17235a31471eSGreg Clayton                                     }
17245a31471eSGreg Clayton                                     else if (::strncmp (var_name_begin, "red}", strlen("red}")) == 0)
17255a31471eSGreg Clayton                                     {
17265a31471eSGreg Clayton                                         s.Printf ("%s%s%s",
17275a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_start,
17285a31471eSGreg Clayton                                                   lldb_utility::ansi::k_fg_red,
17295a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_end);
17305a31471eSGreg Clayton                                     }
17315a31471eSGreg Clayton                                     else if (::strncmp (var_name_begin, "green}", strlen("green}")) == 0)
17325a31471eSGreg Clayton                                     {
17335a31471eSGreg Clayton                                         s.Printf ("%s%s%s",
17345a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_start,
17355a31471eSGreg Clayton                                                   lldb_utility::ansi::k_fg_green,
17365a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_end);
17375a31471eSGreg Clayton                                     }
17385a31471eSGreg Clayton                                     else if (::strncmp (var_name_begin, "yellow}", strlen("yellow}")) == 0)
17395a31471eSGreg Clayton                                     {
17405a31471eSGreg Clayton                                         s.Printf ("%s%s%s",
17415a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_start,
17425a31471eSGreg Clayton                                                   lldb_utility::ansi::k_fg_yellow,
17435a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_end);
17445a31471eSGreg Clayton                                     }
17455a31471eSGreg Clayton                                     else if (::strncmp (var_name_begin, "blue}", strlen("blue}")) == 0)
17465a31471eSGreg Clayton                                     {
17475a31471eSGreg Clayton                                         s.Printf ("%s%s%s",
17485a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_start,
17495a31471eSGreg Clayton                                                   lldb_utility::ansi::k_fg_blue,
17505a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_end);
17515a31471eSGreg Clayton                                     }
17525a31471eSGreg Clayton                                     else if (::strncmp (var_name_begin, "purple}", strlen("purple}")) == 0)
17535a31471eSGreg Clayton                                     {
17545a31471eSGreg Clayton                                         s.Printf ("%s%s%s",
17555a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_start,
17565a31471eSGreg Clayton                                                   lldb_utility::ansi::k_fg_purple,
17575a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_end);
17585a31471eSGreg Clayton                                     }
17595a31471eSGreg Clayton                                     else if (::strncmp (var_name_begin, "cyan}", strlen("cyan}")) == 0)
17605a31471eSGreg Clayton                                     {
17615a31471eSGreg Clayton                                         s.Printf ("%s%s%s",
17625a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_start,
17635a31471eSGreg Clayton                                                   lldb_utility::ansi::k_fg_cyan,
17645a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_end);
17655a31471eSGreg Clayton                                     }
17665a31471eSGreg Clayton                                     else if (::strncmp (var_name_begin, "white}", strlen("white}")) == 0)
17675a31471eSGreg Clayton                                     {
17685a31471eSGreg Clayton                                         s.Printf ("%s%s%s",
17695a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_start,
17705a31471eSGreg Clayton                                                   lldb_utility::ansi::k_fg_white,
17715a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_end);
17725a31471eSGreg Clayton                                     }
17735a31471eSGreg Clayton                                     else
17745a31471eSGreg Clayton                                     {
17755a31471eSGreg Clayton                                         var_success = false;
17765a31471eSGreg Clayton                                     }
17775a31471eSGreg Clayton                                 }
17785a31471eSGreg Clayton                                 else if (::strncmp (var_name_begin, "bg.", strlen("bg.")) == 0)
17795a31471eSGreg Clayton                                 {
17805a31471eSGreg Clayton                                     var_name_begin += strlen("bg."); // Skip the "bg."
17815a31471eSGreg Clayton                                     if (::strncmp (var_name_begin, "black}", strlen("black}")) == 0)
17825a31471eSGreg Clayton                                     {
17835a31471eSGreg Clayton                                         s.Printf ("%s%s%s",
17845a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_start,
17855a31471eSGreg Clayton                                                   lldb_utility::ansi::k_bg_black,
17865a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_end);
17875a31471eSGreg Clayton                                     }
17885a31471eSGreg Clayton                                     else if (::strncmp (var_name_begin, "red}", strlen("red}")) == 0)
17895a31471eSGreg Clayton                                     {
17905a31471eSGreg Clayton                                         s.Printf ("%s%s%s",
17915a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_start,
17925a31471eSGreg Clayton                                                   lldb_utility::ansi::k_bg_red,
17935a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_end);
17945a31471eSGreg Clayton                                     }
17955a31471eSGreg Clayton                                     else if (::strncmp (var_name_begin, "green}", strlen("green}")) == 0)
17965a31471eSGreg Clayton                                     {
17975a31471eSGreg Clayton                                         s.Printf ("%s%s%s",
17985a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_start,
17995a31471eSGreg Clayton                                                   lldb_utility::ansi::k_bg_green,
18005a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_end);
18015a31471eSGreg Clayton                                     }
18025a31471eSGreg Clayton                                     else if (::strncmp (var_name_begin, "yellow}", strlen("yellow}")) == 0)
18035a31471eSGreg Clayton                                     {
18045a31471eSGreg Clayton                                         s.Printf ("%s%s%s",
18055a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_start,
18065a31471eSGreg Clayton                                                   lldb_utility::ansi::k_bg_yellow,
18075a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_end);
18085a31471eSGreg Clayton                                     }
18095a31471eSGreg Clayton                                     else if (::strncmp (var_name_begin, "blue}", strlen("blue}")) == 0)
18105a31471eSGreg Clayton                                     {
18115a31471eSGreg Clayton                                         s.Printf ("%s%s%s",
18125a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_start,
18135a31471eSGreg Clayton                                                   lldb_utility::ansi::k_bg_blue,
18145a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_end);
18155a31471eSGreg Clayton                                     }
18165a31471eSGreg Clayton                                     else if (::strncmp (var_name_begin, "purple}", strlen("purple}")) == 0)
18175a31471eSGreg Clayton                                     {
18185a31471eSGreg Clayton                                         s.Printf ("%s%s%s",
18195a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_start,
18205a31471eSGreg Clayton                                                   lldb_utility::ansi::k_bg_purple,
18215a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_end);
18225a31471eSGreg Clayton                                     }
18235a31471eSGreg Clayton                                     else if (::strncmp (var_name_begin, "cyan}", strlen("cyan}")) == 0)
18245a31471eSGreg Clayton                                     {
18255a31471eSGreg Clayton                                         s.Printf ("%s%s%s",
18265a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_start,
18275a31471eSGreg Clayton                                                   lldb_utility::ansi::k_bg_cyan,
18285a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_end);
18295a31471eSGreg Clayton                                     }
18305a31471eSGreg Clayton                                     else if (::strncmp (var_name_begin, "white}", strlen("white}")) == 0)
18315a31471eSGreg Clayton                                     {
18325a31471eSGreg Clayton                                         s.Printf ("%s%s%s",
18335a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_start,
18345a31471eSGreg Clayton                                                   lldb_utility::ansi::k_bg_white,
18355a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_end);
18365a31471eSGreg Clayton                                     }
18375a31471eSGreg Clayton                                     else
18385a31471eSGreg Clayton                                     {
18395a31471eSGreg Clayton                                         var_success = false;
18405a31471eSGreg Clayton                                     }
18415a31471eSGreg Clayton                                 }
18425a31471eSGreg Clayton                                 else if (::strncmp (var_name_begin, "normal}", strlen ("normal}")) == 0)
18435a31471eSGreg Clayton                                 {
18445a31471eSGreg Clayton                                     s.Printf ("%s%s%s",
18455a31471eSGreg Clayton                                               lldb_utility::ansi::k_escape_start,
18465a31471eSGreg Clayton                                               lldb_utility::ansi::k_ctrl_normal,
18475a31471eSGreg Clayton                                               lldb_utility::ansi::k_escape_end);
18485a31471eSGreg Clayton                                 }
18495a31471eSGreg Clayton                                 else if (::strncmp (var_name_begin, "bold}", strlen("bold}")) == 0)
18505a31471eSGreg Clayton                                 {
18515a31471eSGreg Clayton                                     s.Printf ("%s%s%s",
18525a31471eSGreg Clayton                                               lldb_utility::ansi::k_escape_start,
18535a31471eSGreg Clayton                                               lldb_utility::ansi::k_ctrl_bold,
18545a31471eSGreg Clayton                                               lldb_utility::ansi::k_escape_end);
18555a31471eSGreg Clayton                                 }
18565a31471eSGreg Clayton                                 else if (::strncmp (var_name_begin, "faint}", strlen("faint}")) == 0)
18575a31471eSGreg Clayton                                 {
18585a31471eSGreg Clayton                                     s.Printf ("%s%s%s",
18595a31471eSGreg Clayton                                               lldb_utility::ansi::k_escape_start,
18605a31471eSGreg Clayton                                               lldb_utility::ansi::k_ctrl_faint,
18615a31471eSGreg Clayton                                               lldb_utility::ansi::k_escape_end);
18625a31471eSGreg Clayton                                 }
18635a31471eSGreg Clayton                                 else if (::strncmp (var_name_begin, "italic}", strlen("italic}")) == 0)
18645a31471eSGreg Clayton                                 {
18655a31471eSGreg Clayton                                     s.Printf ("%s%s%s",
18665a31471eSGreg Clayton                                               lldb_utility::ansi::k_escape_start,
18675a31471eSGreg Clayton                                               lldb_utility::ansi::k_ctrl_italic,
18685a31471eSGreg Clayton                                               lldb_utility::ansi::k_escape_end);
18695a31471eSGreg Clayton                                 }
18705a31471eSGreg Clayton                                 else if (::strncmp (var_name_begin, "underline}", strlen("underline}")) == 0)
18715a31471eSGreg Clayton                                 {
18725a31471eSGreg Clayton                                     s.Printf ("%s%s%s",
18735a31471eSGreg Clayton                                               lldb_utility::ansi::k_escape_start,
18745a31471eSGreg Clayton                                               lldb_utility::ansi::k_ctrl_underline,
18755a31471eSGreg Clayton                                               lldb_utility::ansi::k_escape_end);
18765a31471eSGreg Clayton                                 }
18775a31471eSGreg Clayton                                 else if (::strncmp (var_name_begin, "slow-blink}", strlen("slow-blink}")) == 0)
18785a31471eSGreg Clayton                                 {
18795a31471eSGreg Clayton                                     s.Printf ("%s%s%s",
18805a31471eSGreg Clayton                                               lldb_utility::ansi::k_escape_start,
18815a31471eSGreg Clayton                                               lldb_utility::ansi::k_ctrl_slow_blink,
18825a31471eSGreg Clayton                                               lldb_utility::ansi::k_escape_end);
18835a31471eSGreg Clayton                                 }
18845a31471eSGreg Clayton                                 else if (::strncmp (var_name_begin, "fast-blink}", strlen("fast-blink}")) == 0)
18855a31471eSGreg Clayton                                 {
18865a31471eSGreg Clayton                                     s.Printf ("%s%s%s",
18875a31471eSGreg Clayton                                               lldb_utility::ansi::k_escape_start,
18885a31471eSGreg Clayton                                               lldb_utility::ansi::k_ctrl_fast_blink,
18895a31471eSGreg Clayton                                               lldb_utility::ansi::k_escape_end);
18905a31471eSGreg Clayton                                 }
18915a31471eSGreg Clayton                                 else if (::strncmp (var_name_begin, "negative}", strlen("negative}")) == 0)
18925a31471eSGreg Clayton                                 {
18935a31471eSGreg Clayton                                     s.Printf ("%s%s%s",
18945a31471eSGreg Clayton                                               lldb_utility::ansi::k_escape_start,
18955a31471eSGreg Clayton                                               lldb_utility::ansi::k_ctrl_negative,
18965a31471eSGreg Clayton                                               lldb_utility::ansi::k_escape_end);
18975a31471eSGreg Clayton                                 }
18985a31471eSGreg Clayton                                 else if (::strncmp (var_name_begin, "conceal}", strlen("conceal}")) == 0)
18995a31471eSGreg Clayton                                 {
19005a31471eSGreg Clayton                                     s.Printf ("%s%s%s",
19015a31471eSGreg Clayton                                               lldb_utility::ansi::k_escape_start,
19025a31471eSGreg Clayton                                               lldb_utility::ansi::k_ctrl_conceal,
19035a31471eSGreg Clayton                                               lldb_utility::ansi::k_escape_end);
19045a31471eSGreg Clayton 
19055a31471eSGreg Clayton                                 }
19065a31471eSGreg Clayton                                 else if (::strncmp (var_name_begin, "crossed-out}", strlen("crossed-out}")) == 0)
19075a31471eSGreg Clayton                                 {
19085a31471eSGreg Clayton                                     s.Printf ("%s%s%s",
19095a31471eSGreg Clayton                                               lldb_utility::ansi::k_escape_start,
19105a31471eSGreg Clayton                                               lldb_utility::ansi::k_ctrl_crossed_out,
19115a31471eSGreg Clayton                                               lldb_utility::ansi::k_escape_end);
19125a31471eSGreg Clayton                                 }
19135a31471eSGreg Clayton                                 else
19145a31471eSGreg Clayton                                 {
19155a31471eSGreg Clayton                                     var_success = false;
19165a31471eSGreg Clayton                                 }
19175a31471eSGreg Clayton                             }
19181b654882SGreg Clayton                             break;
19191b654882SGreg Clayton 
19201b654882SGreg Clayton                         case 'p':
19211b654882SGreg Clayton                             if (::strncmp (var_name_begin, "process.", strlen("process.")) == 0)
19221b654882SGreg Clayton                             {
1923c14ee32dSGreg Clayton                                 if (exe_ctx)
1924c14ee32dSGreg Clayton                                 {
1925c14ee32dSGreg Clayton                                     Process *process = exe_ctx->GetProcessPtr();
1926c14ee32dSGreg Clayton                                     if (process)
19271b654882SGreg Clayton                                     {
19281b654882SGreg Clayton                                         var_name_begin += ::strlen ("process.");
19291b654882SGreg Clayton                                         if (::strncmp (var_name_begin, "id}", strlen("id}")) == 0)
19301b654882SGreg Clayton                                         {
1931d01b2953SDaniel Malea                                             s.Printf("%" PRIu64, process->GetID());
19321b654882SGreg Clayton                                             var_success = true;
19331b654882SGreg Clayton                                         }
19341b654882SGreg Clayton                                         else if ((::strncmp (var_name_begin, "name}", strlen("name}")) == 0) ||
19351b654882SGreg Clayton                                                  (::strncmp (var_name_begin, "file.basename}", strlen("file.basename}")) == 0) ||
19361b654882SGreg Clayton                                                  (::strncmp (var_name_begin, "file.fullpath}", strlen("file.fullpath}")) == 0))
19371b654882SGreg Clayton                                         {
1938c14ee32dSGreg Clayton                                             Module *exe_module = process->GetTarget().GetExecutableModulePointer();
1939aa149cbdSGreg Clayton                                             if (exe_module)
19401b654882SGreg Clayton                                             {
19411b654882SGreg Clayton                                                 if (var_name_begin[0] == 'n' || var_name_begin[5] == 'f')
19421b654882SGreg Clayton                                                 {
1943aa149cbdSGreg Clayton                                                     format_file_spec.GetFilename() = exe_module->GetFileSpec().GetFilename();
19441b654882SGreg Clayton                                                     var_success = format_file_spec;
19451b654882SGreg Clayton                                                 }
19461b654882SGreg Clayton                                                 else
19471b654882SGreg Clayton                                                 {
1948aa149cbdSGreg Clayton                                                     format_file_spec = exe_module->GetFileSpec();
19491b654882SGreg Clayton                                                     var_success = format_file_spec;
19501b654882SGreg Clayton                                                 }
19511b654882SGreg Clayton                                             }
19521b654882SGreg Clayton                                         }
19531b654882SGreg Clayton                                     }
19541b654882SGreg Clayton                                 }
1955c14ee32dSGreg Clayton                             }
19561b654882SGreg Clayton                             break;
19571b654882SGreg Clayton 
19581b654882SGreg Clayton                         case 't':
19591b654882SGreg Clayton                             if (::strncmp (var_name_begin, "thread.", strlen("thread.")) == 0)
19601b654882SGreg Clayton                             {
1961c14ee32dSGreg Clayton                                 if (exe_ctx)
1962c14ee32dSGreg Clayton                                 {
1963c14ee32dSGreg Clayton                                     Thread *thread = exe_ctx->GetThreadPtr();
1964c14ee32dSGreg Clayton                                     if (thread)
19651b654882SGreg Clayton                                     {
19661b654882SGreg Clayton                                         var_name_begin += ::strlen ("thread.");
19671b654882SGreg Clayton                                         if (::strncmp (var_name_begin, "id}", strlen("id}")) == 0)
19681b654882SGreg Clayton                                         {
1969d01b2953SDaniel Malea                                             s.Printf("0x%4.4" PRIx64, thread->GetID());
19701b654882SGreg Clayton                                             var_success = true;
19711b654882SGreg Clayton                                         }
1972160c9d81SGreg Clayton                                         else if (::strncmp (var_name_begin, "protocol_id}", strlen("protocol_id}")) == 0)
1973160c9d81SGreg Clayton                                         {
1974160c9d81SGreg Clayton                                             s.Printf("0x%4.4" PRIx64, thread->GetProtocolID());
1975160c9d81SGreg Clayton                                             var_success = true;
1976160c9d81SGreg Clayton                                         }
19771b654882SGreg Clayton                                         else if (::strncmp (var_name_begin, "index}", strlen("index}")) == 0)
19781b654882SGreg Clayton                                         {
1979c14ee32dSGreg Clayton                                             s.Printf("%u", thread->GetIndexID());
19801b654882SGreg Clayton                                             var_success = true;
19811b654882SGreg Clayton                                         }
19821b654882SGreg Clayton                                         else if (::strncmp (var_name_begin, "name}", strlen("name}")) == 0)
19831b654882SGreg Clayton                                         {
1984c14ee32dSGreg Clayton                                             cstr = thread->GetName();
19851b654882SGreg Clayton                                             var_success = cstr && cstr[0];
19861b654882SGreg Clayton                                             if (var_success)
19871b654882SGreg Clayton                                                 s.PutCString(cstr);
19881b654882SGreg Clayton                                         }
19891b654882SGreg Clayton                                         else if (::strncmp (var_name_begin, "queue}", strlen("queue}")) == 0)
19901b654882SGreg Clayton                                         {
1991c14ee32dSGreg Clayton                                             cstr = thread->GetQueueName();
19921b654882SGreg Clayton                                             var_success = cstr && cstr[0];
19931b654882SGreg Clayton                                             if (var_success)
19941b654882SGreg Clayton                                                 s.PutCString(cstr);
19951b654882SGreg Clayton                                         }
19961b654882SGreg Clayton                                         else if (::strncmp (var_name_begin, "stop-reason}", strlen("stop-reason}")) == 0)
19971b654882SGreg Clayton                                         {
1998c14ee32dSGreg Clayton                                             StopInfoSP stop_info_sp = thread->GetStopInfo ();
19995d88a068SJim Ingham                                             if (stop_info_sp && stop_info_sp->IsValid())
20001b654882SGreg Clayton                                             {
2001b15bfc75SJim Ingham                                                 cstr = stop_info_sp->GetDescription();
20021b654882SGreg Clayton                                                 if (cstr && cstr[0])
20031b654882SGreg Clayton                                                 {
20041b654882SGreg Clayton                                                     s.PutCString(cstr);
20051b654882SGreg Clayton                                                     var_success = true;
20061b654882SGreg Clayton                                                 }
20071b654882SGreg Clayton                                             }
20081b654882SGreg Clayton                                         }
200973ca05a2SJim Ingham                                         else if (::strncmp (var_name_begin, "return-value}", strlen("return-value}")) == 0)
201073ca05a2SJim Ingham                                         {
201173ca05a2SJim Ingham                                             StopInfoSP stop_info_sp = thread->GetStopInfo ();
20125d88a068SJim Ingham                                             if (stop_info_sp && stop_info_sp->IsValid())
201373ca05a2SJim Ingham                                             {
201473ca05a2SJim Ingham                                                 ValueObjectSP return_valobj_sp = StopInfo::GetReturnValueObject (stop_info_sp);
201573ca05a2SJim Ingham                                                 if (return_valobj_sp)
201673ca05a2SJim Ingham                                                 {
20179fb5ab55SEnrico Granata                                                     ValueObject::DumpValueObject (s, return_valobj_sp.get());
201873ca05a2SJim Ingham                                                     var_success = true;
201973ca05a2SJim Ingham                                                 }
202073ca05a2SJim Ingham                                             }
202173ca05a2SJim Ingham                                         }
202273ca05a2SJim Ingham                                     }
20231b654882SGreg Clayton                                 }
20241b654882SGreg Clayton                             }
20251b654882SGreg Clayton                             else if (::strncmp (var_name_begin, "target.", strlen("target.")) == 0)
20261b654882SGreg Clayton                             {
202767cc0636SGreg Clayton                                 // TODO: hookup properties
202867cc0636SGreg Clayton //                                if (!target_properties_sp)
202967cc0636SGreg Clayton //                                {
203067cc0636SGreg Clayton //                                    Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
203167cc0636SGreg Clayton //                                    if (target)
203267cc0636SGreg Clayton //                                        target_properties_sp = target->GetProperties();
203367cc0636SGreg Clayton //                                }
203467cc0636SGreg Clayton //
203567cc0636SGreg Clayton //                                if (target_properties_sp)
203667cc0636SGreg Clayton //                                {
203767cc0636SGreg Clayton //                                    var_name_begin += ::strlen ("target.");
203867cc0636SGreg Clayton //                                    const char *end_property = strchr(var_name_begin, '}');
203967cc0636SGreg Clayton //                                    if (end_property)
204067cc0636SGreg Clayton //                                    {
204167cc0636SGreg Clayton //                                        ConstString property_name(var_name_begin, end_property - var_name_begin);
204267cc0636SGreg Clayton //                                        std::string property_value (target_properties_sp->GetPropertyValue(property_name));
204367cc0636SGreg Clayton //                                        if (!property_value.empty())
204467cc0636SGreg Clayton //                                        {
204567cc0636SGreg Clayton //                                            s.PutCString (property_value.c_str());
204667cc0636SGreg Clayton //                                            var_success = true;
204767cc0636SGreg Clayton //                                        }
204867cc0636SGreg Clayton //                                    }
204967cc0636SGreg Clayton //                                }
20500603aa9dSGreg Clayton                                 Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
20510603aa9dSGreg Clayton                                 if (target)
20521b654882SGreg Clayton                                 {
20531b654882SGreg Clayton                                     var_name_begin += ::strlen ("target.");
20541b654882SGreg Clayton                                     if (::strncmp (var_name_begin, "arch}", strlen("arch}")) == 0)
20551b654882SGreg Clayton                                     {
20561b654882SGreg Clayton                                         ArchSpec arch (target->GetArchitecture ());
20571b654882SGreg Clayton                                         if (arch.IsValid())
20581b654882SGreg Clayton                                         {
205964195a2cSGreg Clayton                                             s.PutCString (arch.GetArchitectureName());
20601b654882SGreg Clayton                                             var_success = true;
20611b654882SGreg Clayton                                         }
20621b654882SGreg Clayton                                     }
20631b654882SGreg Clayton                                 }
20641b654882SGreg Clayton                             }
20651b654882SGreg Clayton                             break;
20661b654882SGreg Clayton 
20671b654882SGreg Clayton 
20681b654882SGreg Clayton                         case 'm':
20691b654882SGreg Clayton                             if (::strncmp (var_name_begin, "module.", strlen("module.")) == 0)
20701b654882SGreg Clayton                             {
20710603aa9dSGreg Clayton                                 if (sc && sc->module_sp.get())
20721b654882SGreg Clayton                                 {
20730603aa9dSGreg Clayton                                     Module *module = sc->module_sp.get();
20741b654882SGreg Clayton                                     var_name_begin += ::strlen ("module.");
20751b654882SGreg Clayton 
20761b654882SGreg Clayton                                     if (::strncmp (var_name_begin, "file.", strlen("file.")) == 0)
20771b654882SGreg Clayton                                     {
20781b654882SGreg Clayton                                         if (module->GetFileSpec())
20791b654882SGreg Clayton                                         {
20801b654882SGreg Clayton                                             var_name_begin += ::strlen ("file.");
20811b654882SGreg Clayton 
20821b654882SGreg Clayton                                             if (::strncmp (var_name_begin, "basename}", strlen("basename}")) == 0)
20831b654882SGreg Clayton                                             {
20841b654882SGreg Clayton                                                 format_file_spec.GetFilename() = module->GetFileSpec().GetFilename();
20851b654882SGreg Clayton                                                 var_success = format_file_spec;
20861b654882SGreg Clayton                                             }
20871b654882SGreg Clayton                                             else if (::strncmp (var_name_begin, "fullpath}", strlen("fullpath}")) == 0)
20881b654882SGreg Clayton                                             {
20891b654882SGreg Clayton                                                 format_file_spec = module->GetFileSpec();
20901b654882SGreg Clayton                                                 var_success = format_file_spec;
20911b654882SGreg Clayton                                             }
20921b654882SGreg Clayton                                         }
20931b654882SGreg Clayton                                     }
20941b654882SGreg Clayton                                 }
20951b654882SGreg Clayton                             }
20961b654882SGreg Clayton                             break;
20971b654882SGreg Clayton 
20981b654882SGreg Clayton 
20991b654882SGreg Clayton                         case 'f':
21001b654882SGreg Clayton                             if (::strncmp (var_name_begin, "file.", strlen("file.")) == 0)
21011b654882SGreg Clayton                             {
21021b654882SGreg Clayton                                 if (sc && sc->comp_unit != NULL)
21031b654882SGreg Clayton                                 {
21041b654882SGreg Clayton                                     var_name_begin += ::strlen ("file.");
21051b654882SGreg Clayton 
21061b654882SGreg Clayton                                     if (::strncmp (var_name_begin, "basename}", strlen("basename}")) == 0)
21071b654882SGreg Clayton                                     {
21081b654882SGreg Clayton                                         format_file_spec.GetFilename() = sc->comp_unit->GetFilename();
21091b654882SGreg Clayton                                         var_success = format_file_spec;
21101b654882SGreg Clayton                                     }
21111b654882SGreg Clayton                                     else if (::strncmp (var_name_begin, "fullpath}", strlen("fullpath}")) == 0)
21121b654882SGreg Clayton                                     {
21131b654882SGreg Clayton                                         format_file_spec = *sc->comp_unit;
21141b654882SGreg Clayton                                         var_success = format_file_spec;
21151b654882SGreg Clayton                                     }
21161b654882SGreg Clayton                                 }
21171b654882SGreg Clayton                             }
21181b654882SGreg Clayton                             else if (::strncmp (var_name_begin, "frame.", strlen("frame.")) == 0)
21191b654882SGreg Clayton                             {
2120c14ee32dSGreg Clayton                                 if (exe_ctx)
2121c14ee32dSGreg Clayton                                 {
2122c14ee32dSGreg Clayton                                     StackFrame *frame = exe_ctx->GetFramePtr();
2123c14ee32dSGreg Clayton                                     if (frame)
21241b654882SGreg Clayton                                     {
21251b654882SGreg Clayton                                         var_name_begin += ::strlen ("frame.");
21261b654882SGreg Clayton                                         if (::strncmp (var_name_begin, "index}", strlen("index}")) == 0)
21271b654882SGreg Clayton                                         {
2128c14ee32dSGreg Clayton                                             s.Printf("%u", frame->GetFrameIndex());
21291b654882SGreg Clayton                                             var_success = true;
21301b654882SGreg Clayton                                         }
21311b654882SGreg Clayton                                         else if (::strncmp (var_name_begin, "pc}", strlen("pc}")) == 0)
21321b654882SGreg Clayton                                         {
21331b654882SGreg Clayton                                             reg_kind = eRegisterKindGeneric;
21341b654882SGreg Clayton                                             reg_num = LLDB_REGNUM_GENERIC_PC;
21351b654882SGreg Clayton                                             var_success = true;
21361b654882SGreg Clayton                                         }
21371b654882SGreg Clayton                                         else if (::strncmp (var_name_begin, "sp}", strlen("sp}")) == 0)
21381b654882SGreg Clayton                                         {
21391b654882SGreg Clayton                                             reg_kind = eRegisterKindGeneric;
21401b654882SGreg Clayton                                             reg_num = LLDB_REGNUM_GENERIC_SP;
21411b654882SGreg Clayton                                             var_success = true;
21421b654882SGreg Clayton                                         }
21431b654882SGreg Clayton                                         else if (::strncmp (var_name_begin, "fp}", strlen("fp}")) == 0)
21441b654882SGreg Clayton                                         {
21451b654882SGreg Clayton                                             reg_kind = eRegisterKindGeneric;
21461b654882SGreg Clayton                                             reg_num = LLDB_REGNUM_GENERIC_FP;
21471b654882SGreg Clayton                                             var_success = true;
21481b654882SGreg Clayton                                         }
21491b654882SGreg Clayton                                         else if (::strncmp (var_name_begin, "flags}", strlen("flags}")) == 0)
21501b654882SGreg Clayton                                         {
21511b654882SGreg Clayton                                             reg_kind = eRegisterKindGeneric;
21521b654882SGreg Clayton                                             reg_num = LLDB_REGNUM_GENERIC_FLAGS;
21531b654882SGreg Clayton                                             var_success = true;
21541b654882SGreg Clayton                                         }
21551b654882SGreg Clayton                                         else if (::strncmp (var_name_begin, "reg.", strlen ("reg.")) == 0)
21561b654882SGreg Clayton                                         {
2157c14ee32dSGreg Clayton                                             reg_ctx = frame->GetRegisterContext().get();
21581b654882SGreg Clayton                                             if (reg_ctx)
21591b654882SGreg Clayton                                             {
21601b654882SGreg Clayton                                                 var_name_begin += ::strlen ("reg.");
21611b654882SGreg Clayton                                                 if (var_name_begin < var_name_end)
21621b654882SGreg Clayton                                                 {
21631b654882SGreg Clayton                                                     std::string reg_name (var_name_begin, var_name_end);
21641b654882SGreg Clayton                                                     reg_info = reg_ctx->GetRegisterInfoByName (reg_name.c_str());
21651b654882SGreg Clayton                                                     if (reg_info)
21661b654882SGreg Clayton                                                         var_success = true;
21671b654882SGreg Clayton                                                 }
21681b654882SGreg Clayton                                             }
21691b654882SGreg Clayton                                         }
21701b654882SGreg Clayton                                     }
21711b654882SGreg Clayton                                 }
2172c14ee32dSGreg Clayton                             }
21731b654882SGreg Clayton                             else if (::strncmp (var_name_begin, "function.", strlen("function.")) == 0)
21741b654882SGreg Clayton                             {
21751b654882SGreg Clayton                                 if (sc && (sc->function != NULL || sc->symbol != NULL))
21761b654882SGreg Clayton                                 {
21771b654882SGreg Clayton                                     var_name_begin += ::strlen ("function.");
21781b654882SGreg Clayton                                     if (::strncmp (var_name_begin, "id}", strlen("id}")) == 0)
21791b654882SGreg Clayton                                     {
21801b654882SGreg Clayton                                         if (sc->function)
2181d01b2953SDaniel Malea                                             s.Printf("function{0x%8.8" PRIx64 "}", sc->function->GetID());
21821b654882SGreg Clayton                                         else
21831b654882SGreg Clayton                                             s.Printf("symbol[%u]", sc->symbol->GetID());
21841b654882SGreg Clayton 
21851b654882SGreg Clayton                                         var_success = true;
21861b654882SGreg Clayton                                     }
21871b654882SGreg Clayton                                     else if (::strncmp (var_name_begin, "name}", strlen("name}")) == 0)
21881b654882SGreg Clayton                                     {
21891b654882SGreg Clayton                                         if (sc->function)
21901b654882SGreg Clayton                                             cstr = sc->function->GetName().AsCString (NULL);
21911b654882SGreg Clayton                                         else if (sc->symbol)
21921b654882SGreg Clayton                                             cstr = sc->symbol->GetName().AsCString (NULL);
21931b654882SGreg Clayton                                         if (cstr)
21941b654882SGreg Clayton                                         {
21951b654882SGreg Clayton                                             s.PutCString(cstr);
21960d9c9934SGreg Clayton 
21970d9c9934SGreg Clayton                                             if (sc->block)
21980d9c9934SGreg Clayton                                             {
21990d9c9934SGreg Clayton                                                 Block *inline_block = sc->block->GetContainingInlinedBlock ();
22000d9c9934SGreg Clayton                                                 if (inline_block)
22010d9c9934SGreg Clayton                                                 {
22020d9c9934SGreg Clayton                                                     const InlineFunctionInfo *inline_info = sc->block->GetInlinedFunctionInfo();
22030d9c9934SGreg Clayton                                                     if (inline_info)
22040d9c9934SGreg Clayton                                                     {
22050d9c9934SGreg Clayton                                                         s.PutCString(" [inlined] ");
22060d9c9934SGreg Clayton                                                         inline_info->GetName().Dump(&s);
22070d9c9934SGreg Clayton                                                     }
22080d9c9934SGreg Clayton                                                 }
22090d9c9934SGreg Clayton                                             }
22101b654882SGreg Clayton                                             var_success = true;
22111b654882SGreg Clayton                                         }
22121b654882SGreg Clayton                                     }
22136d3dbf51SGreg Clayton                                     else if (::strncmp (var_name_begin, "name-with-args}", strlen("name-with-args}")) == 0)
22146d3dbf51SGreg Clayton                                     {
22156d3dbf51SGreg Clayton                                         // Print the function name with arguments in it
22166d3dbf51SGreg Clayton 
22176d3dbf51SGreg Clayton                                         if (sc->function)
22186d3dbf51SGreg Clayton                                         {
22196d3dbf51SGreg Clayton                                             var_success = true;
22206d3dbf51SGreg Clayton                                             ExecutionContextScope *exe_scope = exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL;
22216d3dbf51SGreg Clayton                                             cstr = sc->function->GetName().AsCString (NULL);
22226d3dbf51SGreg Clayton                                             if (cstr)
22236d3dbf51SGreg Clayton                                             {
22246d3dbf51SGreg Clayton                                                 const InlineFunctionInfo *inline_info = NULL;
22256d3dbf51SGreg Clayton                                                 VariableListSP variable_list_sp;
22266d3dbf51SGreg Clayton                                                 bool get_function_vars = true;
22276d3dbf51SGreg Clayton                                                 if (sc->block)
22286d3dbf51SGreg Clayton                                                 {
22296d3dbf51SGreg Clayton                                                     Block *inline_block = sc->block->GetContainingInlinedBlock ();
22306d3dbf51SGreg Clayton 
22316d3dbf51SGreg Clayton                                                     if (inline_block)
22326d3dbf51SGreg Clayton                                                     {
22336d3dbf51SGreg Clayton                                                         get_function_vars = false;
22346d3dbf51SGreg Clayton                                                         inline_info = sc->block->GetInlinedFunctionInfo();
22356d3dbf51SGreg Clayton                                                         if (inline_info)
22366d3dbf51SGreg Clayton                                                             variable_list_sp = inline_block->GetBlockVariableList (true);
22376d3dbf51SGreg Clayton                                                     }
22386d3dbf51SGreg Clayton                                                 }
22396d3dbf51SGreg Clayton 
22406d3dbf51SGreg Clayton                                                 if (get_function_vars)
22416d3dbf51SGreg Clayton                                                 {
22426d3dbf51SGreg Clayton                                                     variable_list_sp = sc->function->GetBlock(true).GetBlockVariableList (true);
22436d3dbf51SGreg Clayton                                                 }
22446d3dbf51SGreg Clayton 
22456d3dbf51SGreg Clayton                                                 if (inline_info)
22466d3dbf51SGreg Clayton                                                 {
22476d3dbf51SGreg Clayton                                                     s.PutCString (cstr);
22486d3dbf51SGreg Clayton                                                     s.PutCString (" [inlined] ");
22496d3dbf51SGreg Clayton                                                     cstr = inline_info->GetName().GetCString();
22506d3dbf51SGreg Clayton                                                 }
22516d3dbf51SGreg Clayton 
22526d3dbf51SGreg Clayton                                                 VariableList args;
22536d3dbf51SGreg Clayton                                                 if (variable_list_sp)
2254*cc7f9bf5SEnrico Granata                                                     variable_list_sp->AppendVariablesWithScope(eValueTypeVariableArgument, args);
22556d3dbf51SGreg Clayton                                                 if (args.GetSize() > 0)
22566d3dbf51SGreg Clayton                                                 {
22576d3dbf51SGreg Clayton                                                     const char *open_paren = strchr (cstr, '(');
22586d3dbf51SGreg Clayton                                                     const char *close_paren = NULL;
22596d3dbf51SGreg Clayton                                                     if (open_paren)
2260855958caSGreg Clayton                                                     {
2261855958caSGreg Clayton                                                         if (strncmp(open_paren, "(anonymous namespace)", strlen("(anonymous namespace)")) == 0)
2262855958caSGreg Clayton                                                         {
2263855958caSGreg Clayton                                                             open_paren = strchr (open_paren + strlen("(anonymous namespace)"), '(');
2264855958caSGreg Clayton                                                             if (open_paren)
22656d3dbf51SGreg Clayton                                                                 close_paren = strchr (open_paren, ')');
2266855958caSGreg Clayton                                                         }
2267855958caSGreg Clayton                                                         else
2268855958caSGreg Clayton                                                             close_paren = strchr (open_paren, ')');
2269855958caSGreg Clayton                                                     }
22706d3dbf51SGreg Clayton 
22716d3dbf51SGreg Clayton                                                     if (open_paren)
22726d3dbf51SGreg Clayton                                                         s.Write(cstr, open_paren - cstr + 1);
22736d3dbf51SGreg Clayton                                                     else
22746d3dbf51SGreg Clayton                                                     {
22756d3dbf51SGreg Clayton                                                         s.PutCString (cstr);
22766d3dbf51SGreg Clayton                                                         s.PutChar ('(');
22776d3dbf51SGreg Clayton                                                     }
22785b6889b1SGreg Clayton                                                     const size_t num_args = args.GetSize();
22796d3dbf51SGreg Clayton                                                     for (size_t arg_idx = 0; arg_idx < num_args; ++arg_idx)
22806d3dbf51SGreg Clayton                                                     {
22816d3dbf51SGreg Clayton                                                         VariableSP var_sp (args.GetVariableAtIndex (arg_idx));
22826d3dbf51SGreg Clayton                                                         ValueObjectSP var_value_sp (ValueObjectVariable::Create (exe_scope, var_sp));
22836d3dbf51SGreg Clayton                                                         const char *var_name = var_value_sp->GetName().GetCString();
22846d3dbf51SGreg Clayton                                                         const char *var_value = var_value_sp->GetValueAsCString();
22856d3dbf51SGreg Clayton                                                         if (arg_idx > 0)
22866d3dbf51SGreg Clayton                                                             s.PutCString (", ");
22873b188b17SGreg Clayton                                                         if (var_value_sp->GetError().Success())
2288*cc7f9bf5SEnrico Granata                                                         {
2289*cc7f9bf5SEnrico Granata                                                             if (var_value)
22906d3dbf51SGreg Clayton                                                                 s.Printf ("%s=%s", var_name, var_value);
22913b188b17SGreg Clayton                                                             else
2292*cc7f9bf5SEnrico Granata                                                                 s.Printf ("%s=%s at %s", var_name, var_value_sp->GetTypeName().GetCString(), var_value_sp->GetLocationAsCString());
2293*cc7f9bf5SEnrico Granata                                                         }
2294*cc7f9bf5SEnrico Granata                                                         else
22953b188b17SGreg Clayton                                                             s.Printf ("%s=<unavailable>", var_name);
22966d3dbf51SGreg Clayton                                                     }
22976d3dbf51SGreg Clayton 
22986d3dbf51SGreg Clayton                                                     if (close_paren)
22996d3dbf51SGreg Clayton                                                         s.PutCString (close_paren);
23006d3dbf51SGreg Clayton                                                     else
23016d3dbf51SGreg Clayton                                                         s.PutChar(')');
23026d3dbf51SGreg Clayton 
23036d3dbf51SGreg Clayton                                                 }
23046d3dbf51SGreg Clayton                                                 else
23056d3dbf51SGreg Clayton                                                 {
23066d3dbf51SGreg Clayton                                                     s.PutCString(cstr);
23076d3dbf51SGreg Clayton                                                 }
23086d3dbf51SGreg Clayton                                             }
23096d3dbf51SGreg Clayton                                         }
23106d3dbf51SGreg Clayton                                         else if (sc->symbol)
23116d3dbf51SGreg Clayton                                         {
23126d3dbf51SGreg Clayton                                             cstr = sc->symbol->GetName().AsCString (NULL);
23136d3dbf51SGreg Clayton                                             if (cstr)
23146d3dbf51SGreg Clayton                                             {
23156d3dbf51SGreg Clayton                                                 s.PutCString(cstr);
23166d3dbf51SGreg Clayton                                                 var_success = true;
23176d3dbf51SGreg Clayton                                             }
23186d3dbf51SGreg Clayton                                         }
23196d3dbf51SGreg Clayton                                     }
23201b654882SGreg Clayton                                     else if (::strncmp (var_name_begin, "addr-offset}", strlen("addr-offset}")) == 0)
23211b654882SGreg Clayton                                     {
23221b654882SGreg Clayton                                         var_success = addr != NULL;
23231b654882SGreg Clayton                                         if (var_success)
23241b654882SGreg Clayton                                         {
23251b654882SGreg Clayton                                             format_addr = *addr;
23261b654882SGreg Clayton                                             calculate_format_addr_function_offset = true;
23271b654882SGreg Clayton                                         }
23281b654882SGreg Clayton                                     }
23291b654882SGreg Clayton                                     else if (::strncmp (var_name_begin, "line-offset}", strlen("line-offset}")) == 0)
23301b654882SGreg Clayton                                     {
23311b654882SGreg Clayton                                         var_success = sc->line_entry.range.GetBaseAddress().IsValid();
23321b654882SGreg Clayton                                         if (var_success)
23331b654882SGreg Clayton                                         {
23341b654882SGreg Clayton                                             format_addr = sc->line_entry.range.GetBaseAddress();
23351b654882SGreg Clayton                                             calculate_format_addr_function_offset = true;
23361b654882SGreg Clayton                                         }
23371b654882SGreg Clayton                                     }
23381b654882SGreg Clayton                                     else if (::strncmp (var_name_begin, "pc-offset}", strlen("pc-offset}")) == 0)
23391b654882SGreg Clayton                                     {
2340c14ee32dSGreg Clayton                                         StackFrame *frame = exe_ctx->GetFramePtr();
2341c14ee32dSGreg Clayton                                         var_success = frame != NULL;
23421b654882SGreg Clayton                                         if (var_success)
23431b654882SGreg Clayton                                         {
2344c14ee32dSGreg Clayton                                             format_addr = frame->GetFrameCodeAddress();
23451b654882SGreg Clayton                                             calculate_format_addr_function_offset = true;
23461b654882SGreg Clayton                                         }
23471b654882SGreg Clayton                                     }
23481b654882SGreg Clayton                                 }
23491b654882SGreg Clayton                             }
23501b654882SGreg Clayton                             break;
23511b654882SGreg Clayton 
23521b654882SGreg Clayton                         case 'l':
23531b654882SGreg Clayton                             if (::strncmp (var_name_begin, "line.", strlen("line.")) == 0)
23541b654882SGreg Clayton                             {
23551b654882SGreg Clayton                                 if (sc && sc->line_entry.IsValid())
23561b654882SGreg Clayton                                 {
23571b654882SGreg Clayton                                     var_name_begin += ::strlen ("line.");
23581b654882SGreg Clayton                                     if (::strncmp (var_name_begin, "file.", strlen("file.")) == 0)
23591b654882SGreg Clayton                                     {
23601b654882SGreg Clayton                                         var_name_begin += ::strlen ("file.");
23611b654882SGreg Clayton 
23621b654882SGreg Clayton                                         if (::strncmp (var_name_begin, "basename}", strlen("basename}")) == 0)
23631b654882SGreg Clayton                                         {
23641b654882SGreg Clayton                                             format_file_spec.GetFilename() = sc->line_entry.file.GetFilename();
23651b654882SGreg Clayton                                             var_success = format_file_spec;
23661b654882SGreg Clayton                                         }
23671b654882SGreg Clayton                                         else if (::strncmp (var_name_begin, "fullpath}", strlen("fullpath}")) == 0)
23681b654882SGreg Clayton                                         {
23691b654882SGreg Clayton                                             format_file_spec = sc->line_entry.file;
23701b654882SGreg Clayton                                             var_success = format_file_spec;
23711b654882SGreg Clayton                                         }
23721b654882SGreg Clayton                                     }
23731b654882SGreg Clayton                                     else if (::strncmp (var_name_begin, "number}", strlen("number}")) == 0)
23741b654882SGreg Clayton                                     {
23751b654882SGreg Clayton                                         var_success = true;
23761b654882SGreg Clayton                                         s.Printf("%u", sc->line_entry.line);
23771b654882SGreg Clayton                                     }
23781b654882SGreg Clayton                                     else if ((::strncmp (var_name_begin, "start-addr}", strlen("start-addr}")) == 0) ||
23791b654882SGreg Clayton                                              (::strncmp (var_name_begin, "end-addr}", strlen("end-addr}")) == 0))
23801b654882SGreg Clayton                                     {
23811b654882SGreg Clayton                                         var_success = sc && sc->line_entry.range.GetBaseAddress().IsValid();
23821b654882SGreg Clayton                                         if (var_success)
23831b654882SGreg Clayton                                         {
23841b654882SGreg Clayton                                             format_addr = sc->line_entry.range.GetBaseAddress();
23851b654882SGreg Clayton                                             if (var_name_begin[0] == 'e')
23861b654882SGreg Clayton                                                 format_addr.Slide (sc->line_entry.range.GetByteSize());
23871b654882SGreg Clayton                                         }
23881b654882SGreg Clayton                                     }
23891b654882SGreg Clayton                                 }
23901b654882SGreg Clayton                             }
23911b654882SGreg Clayton                             break;
23921b654882SGreg Clayton                         }
23931b654882SGreg Clayton 
23941b654882SGreg Clayton                         if (var_success)
23951b654882SGreg Clayton                         {
23961b654882SGreg Clayton                             // If format addr is valid, then we need to print an address
23971b654882SGreg Clayton                             if (reg_num != LLDB_INVALID_REGNUM)
23981b654882SGreg Clayton                             {
2399c14ee32dSGreg Clayton                                 StackFrame *frame = exe_ctx->GetFramePtr();
24001b654882SGreg Clayton                                 // We have a register value to display...
24011b654882SGreg Clayton                                 if (reg_num == LLDB_REGNUM_GENERIC_PC && reg_kind == eRegisterKindGeneric)
24021b654882SGreg Clayton                                 {
2403c14ee32dSGreg Clayton                                     format_addr = frame->GetFrameCodeAddress();
24041b654882SGreg Clayton                                 }
24051b654882SGreg Clayton                                 else
24061b654882SGreg Clayton                                 {
24071b654882SGreg Clayton                                     if (reg_ctx == NULL)
2408c14ee32dSGreg Clayton                                         reg_ctx = frame->GetRegisterContext().get();
24091b654882SGreg Clayton 
24101b654882SGreg Clayton                                     if (reg_ctx)
24111b654882SGreg Clayton                                     {
24121b654882SGreg Clayton                                         if (reg_kind != kNumRegisterKinds)
24131b654882SGreg Clayton                                             reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(reg_kind, reg_num);
24141b654882SGreg Clayton                                         reg_info = reg_ctx->GetRegisterInfoAtIndex (reg_num);
24151b654882SGreg Clayton                                         var_success = reg_info != NULL;
24161b654882SGreg Clayton                                     }
24171b654882SGreg Clayton                                 }
24181b654882SGreg Clayton                             }
24191b654882SGreg Clayton 
24201b654882SGreg Clayton                             if (reg_info != NULL)
24211b654882SGreg Clayton                             {
24227349bd90SGreg Clayton                                 RegisterValue reg_value;
24237349bd90SGreg Clayton                                 var_success = reg_ctx->ReadRegister (reg_info, reg_value);
24247349bd90SGreg Clayton                                 if (var_success)
24251b654882SGreg Clayton                                 {
24269a8fa916SGreg Clayton                                     reg_value.Dump(&s, reg_info, false, false, eFormatDefault);
24271b654882SGreg Clayton                                 }
24281b654882SGreg Clayton                             }
24291b654882SGreg Clayton 
24301b654882SGreg Clayton                             if (format_file_spec)
24311b654882SGreg Clayton                             {
24321b654882SGreg Clayton                                 s << format_file_spec;
24331b654882SGreg Clayton                             }
24341b654882SGreg Clayton 
24351b654882SGreg Clayton                             // If format addr is valid, then we need to print an address
24361b654882SGreg Clayton                             if (format_addr.IsValid())
24371b654882SGreg Clayton                             {
24380603aa9dSGreg Clayton                                 var_success = false;
24390603aa9dSGreg Clayton 
24401b654882SGreg Clayton                                 if (calculate_format_addr_function_offset)
24411b654882SGreg Clayton                                 {
24421b654882SGreg Clayton                                     Address func_addr;
24430603aa9dSGreg Clayton 
24440603aa9dSGreg Clayton                                     if (sc)
24450603aa9dSGreg Clayton                                     {
24461b654882SGreg Clayton                                         if (sc->function)
24470d9c9934SGreg Clayton                                         {
24481b654882SGreg Clayton                                             func_addr = sc->function->GetAddressRange().GetBaseAddress();
24490d9c9934SGreg Clayton                                             if (sc->block)
24500d9c9934SGreg Clayton                                             {
24510d9c9934SGreg Clayton                                                 // Check to make sure we aren't in an inline
24520d9c9934SGreg Clayton                                                 // function. If we are, use the inline block
24530d9c9934SGreg Clayton                                                 // range that contains "format_addr" since
24540d9c9934SGreg Clayton                                                 // blocks can be discontiguous.
24550d9c9934SGreg Clayton                                                 Block *inline_block = sc->block->GetContainingInlinedBlock ();
24560d9c9934SGreg Clayton                                                 AddressRange inline_range;
24570d9c9934SGreg Clayton                                                 if (inline_block && inline_block->GetRangeContainingAddress (format_addr, inline_range))
24580d9c9934SGreg Clayton                                                     func_addr = inline_range.GetBaseAddress();
24590d9c9934SGreg Clayton                                             }
24600d9c9934SGreg Clayton                                         }
2461e7612134SGreg Clayton                                         else if (sc->symbol && sc->symbol->ValueIsAddress())
2462e7612134SGreg Clayton                                             func_addr = sc->symbol->GetAddress();
24630603aa9dSGreg Clayton                                     }
24641b654882SGreg Clayton 
24650603aa9dSGreg Clayton                                     if (func_addr.IsValid())
24661b654882SGreg Clayton                                     {
24671b654882SGreg Clayton                                         if (func_addr.GetSection() == format_addr.GetSection())
24681b654882SGreg Clayton                                         {
24691b654882SGreg Clayton                                             addr_t func_file_addr = func_addr.GetFileAddress();
24701b654882SGreg Clayton                                             addr_t addr_file_addr = format_addr.GetFileAddress();
24711b654882SGreg Clayton                                             if (addr_file_addr > func_file_addr)
2472d01b2953SDaniel Malea                                                 s.Printf(" + %" PRIu64, addr_file_addr - func_file_addr);
24731b654882SGreg Clayton                                             else if (addr_file_addr < func_file_addr)
2474d01b2953SDaniel Malea                                                 s.Printf(" - %" PRIu64, func_file_addr - addr_file_addr);
24750603aa9dSGreg Clayton                                             var_success = true;
24761b654882SGreg Clayton                                         }
24771b654882SGreg Clayton                                         else
24780603aa9dSGreg Clayton                                         {
24790603aa9dSGreg Clayton                                             Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
24800603aa9dSGreg Clayton                                             if (target)
24810603aa9dSGreg Clayton                                             {
24820603aa9dSGreg Clayton                                                 addr_t func_load_addr = func_addr.GetLoadAddress (target);
24830603aa9dSGreg Clayton                                                 addr_t addr_load_addr = format_addr.GetLoadAddress (target);
24840603aa9dSGreg Clayton                                                 if (addr_load_addr > func_load_addr)
2485d01b2953SDaniel Malea                                                     s.Printf(" + %" PRIu64, addr_load_addr - func_load_addr);
24860603aa9dSGreg Clayton                                                 else if (addr_load_addr < func_load_addr)
2487d01b2953SDaniel Malea                                                     s.Printf(" - %" PRIu64, func_load_addr - addr_load_addr);
24880603aa9dSGreg Clayton                                                 var_success = true;
24890603aa9dSGreg Clayton                                             }
24900603aa9dSGreg Clayton                                         }
24911b654882SGreg Clayton                                     }
24921b654882SGreg Clayton                                 }
24931b654882SGreg Clayton                                 else
24941b654882SGreg Clayton                                 {
24950603aa9dSGreg Clayton                                     Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
24961b654882SGreg Clayton                                     addr_t vaddr = LLDB_INVALID_ADDRESS;
24970603aa9dSGreg Clayton                                     if (exe_ctx && !target->GetSectionLoadList().IsEmpty())
24980603aa9dSGreg Clayton                                         vaddr = format_addr.GetLoadAddress (target);
24991b654882SGreg Clayton                                     if (vaddr == LLDB_INVALID_ADDRESS)
25001b654882SGreg Clayton                                         vaddr = format_addr.GetFileAddress ();
25011b654882SGreg Clayton 
25021b654882SGreg Clayton                                     if (vaddr != LLDB_INVALID_ADDRESS)
25030603aa9dSGreg Clayton                                     {
2504514487e8SGreg Clayton                                         int addr_width = target->GetArchitecture().GetAddressByteSize() * 2;
250535f1a0d5SGreg Clayton                                         if (addr_width == 0)
250635f1a0d5SGreg Clayton                                             addr_width = 16;
2507d01b2953SDaniel Malea                                         s.Printf("0x%*.*" PRIx64, addr_width, addr_width, vaddr);
25080603aa9dSGreg Clayton                                         var_success = true;
25090603aa9dSGreg Clayton                                     }
25101b654882SGreg Clayton                                 }
25111b654882SGreg Clayton                             }
25121b654882SGreg Clayton                         }
25131b654882SGreg Clayton 
25141b654882SGreg Clayton                         if (var_success == false)
25151b654882SGreg Clayton                             success = false;
25161b654882SGreg Clayton                     }
25171b654882SGreg Clayton                     p = var_name_end;
25181b654882SGreg Clayton                 }
25191b654882SGreg Clayton                 else
25201b654882SGreg Clayton                     break;
25211b654882SGreg Clayton             }
25221b654882SGreg Clayton             else
25231b654882SGreg Clayton             {
25241b654882SGreg Clayton                 // We got a dollar sign with no '{' after it, it must just be a dollar sign
25251b654882SGreg Clayton                 s.PutChar(*p);
25261b654882SGreg Clayton             }
25271b654882SGreg Clayton         }
25281b654882SGreg Clayton         else if (*p == '\\')
25291b654882SGreg Clayton         {
25301b654882SGreg Clayton             ++p; // skip the slash
25311b654882SGreg Clayton             switch (*p)
25321b654882SGreg Clayton             {
25331b654882SGreg Clayton             case 'a': s.PutChar ('\a'); break;
25341b654882SGreg Clayton             case 'b': s.PutChar ('\b'); break;
25351b654882SGreg Clayton             case 'f': s.PutChar ('\f'); break;
25361b654882SGreg Clayton             case 'n': s.PutChar ('\n'); break;
25371b654882SGreg Clayton             case 'r': s.PutChar ('\r'); break;
25381b654882SGreg Clayton             case 't': s.PutChar ('\t'); break;
25391b654882SGreg Clayton             case 'v': s.PutChar ('\v'); break;
25401b654882SGreg Clayton             case '\'': s.PutChar ('\''); break;
25411b654882SGreg Clayton             case '\\': s.PutChar ('\\'); break;
25421b654882SGreg Clayton             case '0':
25431b654882SGreg Clayton                 // 1 to 3 octal chars
25441b654882SGreg Clayton                 {
25450603aa9dSGreg Clayton                     // Make a string that can hold onto the initial zero char,
25460603aa9dSGreg Clayton                     // up to 3 octal digits, and a terminating NULL.
25470603aa9dSGreg Clayton                     char oct_str[5] = { 0, 0, 0, 0, 0 };
25480603aa9dSGreg Clayton 
25490603aa9dSGreg Clayton                     int i;
25500603aa9dSGreg Clayton                     for (i=0; (p[i] >= '0' && p[i] <= '7') && i<4; ++i)
25510603aa9dSGreg Clayton                         oct_str[i] = p[i];
25520603aa9dSGreg Clayton 
25530603aa9dSGreg Clayton                     // We don't want to consume the last octal character since
25540603aa9dSGreg Clayton                     // the main for loop will do this for us, so we advance p by
25550603aa9dSGreg Clayton                     // one less than i (even if i is zero)
25560603aa9dSGreg Clayton                     p += i - 1;
25570603aa9dSGreg Clayton                     unsigned long octal_value = ::strtoul (oct_str, NULL, 8);
25580603aa9dSGreg Clayton                     if (octal_value <= UINT8_MAX)
25591b654882SGreg Clayton                     {
2560c7bece56SGreg Clayton                         s.PutChar((char)octal_value);
25611b654882SGreg Clayton                     }
25621b654882SGreg Clayton                 }
25631b654882SGreg Clayton                 break;
25641b654882SGreg Clayton 
25651b654882SGreg Clayton             case 'x':
25661b654882SGreg Clayton                 // hex number in the format
25670603aa9dSGreg Clayton                 if (isxdigit(p[1]))
25681b654882SGreg Clayton                 {
25690603aa9dSGreg Clayton                     ++p;    // Skip the 'x'
25701b654882SGreg Clayton 
25710603aa9dSGreg Clayton                     // Make a string that can hold onto two hex chars plus a
25720603aa9dSGreg Clayton                     // NULL terminator
25731b654882SGreg Clayton                     char hex_str[3] = { 0,0,0 };
25741b654882SGreg Clayton                     hex_str[0] = *p;
25750603aa9dSGreg Clayton                     if (isxdigit(p[1]))
25760603aa9dSGreg Clayton                     {
25770603aa9dSGreg Clayton                         ++p; // Skip the first of the two hex chars
25781b654882SGreg Clayton                         hex_str[1] = *p;
25790603aa9dSGreg Clayton                     }
25800603aa9dSGreg Clayton 
25811b654882SGreg Clayton                     unsigned long hex_value = strtoul (hex_str, NULL, 16);
25820603aa9dSGreg Clayton                     if (hex_value <= UINT8_MAX)
2583c7bece56SGreg Clayton                         s.PutChar ((char)hex_value);
25841b654882SGreg Clayton                 }
25851b654882SGreg Clayton                 else
25861b654882SGreg Clayton                 {
25870603aa9dSGreg Clayton                     s.PutChar('x');
25881b654882SGreg Clayton                 }
25891b654882SGreg Clayton                 break;
25901b654882SGreg Clayton 
25911b654882SGreg Clayton             default:
25920603aa9dSGreg Clayton                 // Just desensitize any other character by just printing what
25930603aa9dSGreg Clayton                 // came after the '\'
25940603aa9dSGreg Clayton                 s << *p;
25951b654882SGreg Clayton                 break;
25961b654882SGreg Clayton 
25971b654882SGreg Clayton             }
25981b654882SGreg Clayton 
25991b654882SGreg Clayton         }
26001b654882SGreg Clayton     }
26011b654882SGreg Clayton     if (end)
26021b654882SGreg Clayton         *end = p;
26031b654882SGreg Clayton     return success;
26041b654882SGreg Clayton }
26051b654882SGreg Clayton 
2606228063cdSJim Ingham void
2607228063cdSJim Ingham Debugger::SetLoggingCallback (lldb::LogOutputCallback log_callback, void *baton)
2608228063cdSJim Ingham {
26094f02b22dSJim Ingham     // For simplicity's sake, I am not going to deal with how to close down any
26104f02b22dSJim Ingham     // open logging streams, I just redirect everything from here on out to the
26114f02b22dSJim Ingham     // callback.
2612228063cdSJim Ingham     m_log_callback_stream_sp.reset (new StreamCallback (log_callback, baton));
2613228063cdSJim Ingham }
2614228063cdSJim Ingham 
2615228063cdSJim Ingham bool
2616228063cdSJim Ingham Debugger::EnableLog (const char *channel, const char **categories, const char *log_file, uint32_t log_options, Stream &error_stream)
2617228063cdSJim Ingham {
2618228063cdSJim Ingham     Log::Callbacks log_callbacks;
2619228063cdSJim Ingham 
2620228063cdSJim Ingham     StreamSP log_stream_sp;
26219a028519SSean Callanan     if (m_log_callback_stream_sp)
2622228063cdSJim Ingham     {
2623228063cdSJim Ingham         log_stream_sp = m_log_callback_stream_sp;
2624228063cdSJim Ingham         // For now when using the callback mode you always get thread & timestamp.
2625228063cdSJim Ingham         log_options |= LLDB_LOG_OPTION_PREPEND_TIMESTAMP | LLDB_LOG_OPTION_PREPEND_THREAD_NAME;
2626228063cdSJim Ingham     }
2627228063cdSJim Ingham     else if (log_file == NULL || *log_file == '\0')
2628228063cdSJim Ingham     {
2629228063cdSJim Ingham         log_stream_sp.reset(new StreamFile(GetOutputFile().GetDescriptor(), false));
2630228063cdSJim Ingham     }
2631228063cdSJim Ingham     else
2632228063cdSJim Ingham     {
2633228063cdSJim Ingham         LogStreamMap::iterator pos = m_log_streams.find(log_file);
2634c1b2ccfdSGreg Clayton         if (pos != m_log_streams.end())
2635c1b2ccfdSGreg Clayton             log_stream_sp = pos->second.lock();
2636c1b2ccfdSGreg Clayton         if (!log_stream_sp)
2637228063cdSJim Ingham         {
2638228063cdSJim Ingham             log_stream_sp.reset (new StreamFile (log_file));
2639228063cdSJim Ingham             m_log_streams[log_file] = log_stream_sp;
2640228063cdSJim Ingham         }
2641228063cdSJim Ingham     }
2642228063cdSJim Ingham     assert (log_stream_sp.get());
2643228063cdSJim Ingham 
2644228063cdSJim Ingham     if (log_options == 0)
2645228063cdSJim Ingham         log_options = LLDB_LOG_OPTION_PREPEND_THREAD_NAME | LLDB_LOG_OPTION_THREADSAFE;
2646228063cdSJim Ingham 
2647228063cdSJim Ingham     if (Log::GetLogChannelCallbacks (channel, log_callbacks))
2648228063cdSJim Ingham     {
2649228063cdSJim Ingham         log_callbacks.enable (log_stream_sp, log_options, categories, &error_stream);
2650228063cdSJim Ingham         return true;
2651228063cdSJim Ingham     }
2652228063cdSJim Ingham     else
2653228063cdSJim Ingham     {
2654228063cdSJim Ingham         LogChannelSP log_channel_sp (LogChannel::FindPlugin (channel));
2655228063cdSJim Ingham         if (log_channel_sp)
2656228063cdSJim Ingham         {
2657228063cdSJim Ingham             if (log_channel_sp->Enable (log_stream_sp, log_options, &error_stream, categories))
2658228063cdSJim Ingham             {
2659228063cdSJim Ingham                 return true;
2660228063cdSJim Ingham             }
2661228063cdSJim Ingham             else
2662228063cdSJim Ingham             {
2663228063cdSJim Ingham                 error_stream.Printf ("Invalid log channel '%s'.\n", channel);
2664228063cdSJim Ingham                 return false;
2665228063cdSJim Ingham             }
2666228063cdSJim Ingham         }
2667228063cdSJim Ingham         else
2668228063cdSJim Ingham         {
2669228063cdSJim Ingham             error_stream.Printf ("Invalid log channel '%s'.\n", channel);
2670228063cdSJim Ingham             return false;
2671228063cdSJim Ingham         }
2672228063cdSJim Ingham     }
2673228063cdSJim Ingham     return false;
2674228063cdSJim Ingham }
2675228063cdSJim Ingham 
26769585fbfcSGreg Clayton SourceManager &
26779585fbfcSGreg Clayton Debugger::GetSourceManager ()
26789585fbfcSGreg Clayton {
26799585fbfcSGreg Clayton     if (m_source_manager_ap.get() == NULL)
26809585fbfcSGreg Clayton         m_source_manager_ap.reset (new SourceManager (shared_from_this()));
26819585fbfcSGreg Clayton     return *m_source_manager_ap;
26829585fbfcSGreg Clayton }
26839585fbfcSGreg Clayton 
26849585fbfcSGreg Clayton 
2685