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"
5084a53dfbSEnrico Granata #include "lldb/Target/Target.h"
5130fdc8d8SChris Lattner #include "lldb/Target/Thread.h"
525a31471eSGreg Clayton #include "lldb/Utility/AnsiTerminal.h"
5330fdc8d8SChris Lattner 
5430fdc8d8SChris Lattner using namespace lldb;
5530fdc8d8SChris Lattner using namespace lldb_private;
5630fdc8d8SChris Lattner 
5730fdc8d8SChris Lattner 
581b654882SGreg Clayton static uint32_t g_shared_debugger_refcount = 0;
59ebc1bb27SCaroline Tice static lldb::user_id_t g_unique_id = 1;
60ebc1bb27SCaroline Tice 
611b654882SGreg Clayton #pragma mark Static Functions
621b654882SGreg Clayton 
631b654882SGreg Clayton static Mutex &
641b654882SGreg Clayton GetDebuggerListMutex ()
651b654882SGreg Clayton {
661b654882SGreg Clayton     static Mutex g_mutex(Mutex::eMutexTypeRecursive);
671b654882SGreg Clayton     return g_mutex;
681b654882SGreg Clayton }
691b654882SGreg Clayton 
701b654882SGreg Clayton typedef std::vector<DebuggerSP> DebuggerList;
711b654882SGreg Clayton 
721b654882SGreg Clayton static DebuggerList &
731b654882SGreg Clayton GetDebuggerList()
741b654882SGreg Clayton {
751b654882SGreg Clayton     // hide the static debugger list inside a singleton accessor to avoid
761b654882SGreg Clayton     // global init contructors
771b654882SGreg Clayton     static DebuggerList g_list;
781b654882SGreg Clayton     return g_list;
791b654882SGreg Clayton }
80e372b98dSGreg Clayton 
81e372b98dSGreg Clayton OptionEnumValueElement
8267cc0636SGreg Clayton g_show_disassembly_enum_values[] =
83e372b98dSGreg Clayton {
8467cc0636SGreg Clayton     { Debugger::eStopDisassemblyTypeNever,    "never",     "Never show disassembly when displaying a stop context."},
8567cc0636SGreg Clayton     { Debugger::eStopDisassemblyTypeNoSource, "no-source", "Show disassembly when there is no source information, or the source file is missing when displaying a stop context."},
8667cc0636SGreg Clayton     { Debugger::eStopDisassemblyTypeAlways,   "always",    "Always show disassembly when displaying a stop context."},
87e372b98dSGreg Clayton     { 0, NULL, NULL }
88e372b98dSGreg Clayton };
89e372b98dSGreg Clayton 
9067cc0636SGreg Clayton OptionEnumValueElement
9167cc0636SGreg Clayton g_language_enumerators[] =
9267cc0636SGreg Clayton {
9367cc0636SGreg Clayton     { eScriptLanguageNone,      "none",     "Disable scripting languages."},
9467cc0636SGreg Clayton     { eScriptLanguagePython,    "python",   "Select python as the default scripting language."},
9567cc0636SGreg Clayton     { eScriptLanguageDefault,   "default",  "Select the lldb default as the default scripting language."},
96a12993c9SGreg Clayton     { 0, NULL, NULL }
9767cc0636SGreg Clayton };
98e372b98dSGreg Clayton 
9967cc0636SGreg Clayton #define MODULE_WITH_FUNC "{ ${module.file.basename}{`${function.name-with-args}${function.pc-offset}}}"
10067cc0636SGreg Clayton #define FILE_AND_LINE "{ at ${line.file.basename}:${line.number}}"
10167cc0636SGreg Clayton 
10267cc0636SGreg Clayton #define DEFAULT_THREAD_FORMAT "thread #${thread.index}: tid = ${thread.id}"\
10367cc0636SGreg Clayton     "{, ${frame.pc}}"\
10467cc0636SGreg Clayton     MODULE_WITH_FUNC\
10567cc0636SGreg Clayton     FILE_AND_LINE\
10685d0c57bSGreg Clayton     "{, name = '${thread.name}}"\
10785d0c57bSGreg Clayton     "{, queue = '${thread.queue}}"\
10867cc0636SGreg Clayton     "{, stop reason = ${thread.stop-reason}}"\
10967cc0636SGreg Clayton     "{\\nReturn value: ${thread.return-value}}"\
11067cc0636SGreg Clayton     "\\n"
11167cc0636SGreg Clayton 
11267cc0636SGreg Clayton #define DEFAULT_FRAME_FORMAT "frame #${frame.index}: ${frame.pc}"\
11367cc0636SGreg Clayton     MODULE_WITH_FUNC\
11467cc0636SGreg Clayton     FILE_AND_LINE\
11567cc0636SGreg Clayton     "\\n"
11667cc0636SGreg Clayton 
11767cc0636SGreg Clayton 
11867cc0636SGreg Clayton 
119754a9369SGreg Clayton static PropertyDefinition
120754a9369SGreg Clayton g_properties[] =
12167cc0636SGreg Clayton {
12267cc0636SGreg Clayton {   "auto-confirm",             OptionValue::eTypeBoolean, true, false, NULL, NULL, "If true all confirmation prompts will receive their default reply." },
12367cc0636SGreg 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." },
12467cc0636SGreg Clayton {   "notify-void",              OptionValue::eTypeBoolean, true, false, NULL, NULL, "Notify the user explicitly if an expression returns void (default: false)." },
1254c05410fSGreg Clayton {   "prompt",                   OptionValue::eTypeString , true, OptionValueString::eOptionEncodeCharacterEscapeSequences, "(lldb) ", NULL, "The debugger command line prompt displayed for the user." },
12667cc0636SGreg Clayton {   "script-lang",              OptionValue::eTypeEnum   , true, eScriptLanguagePython, NULL, g_language_enumerators, "The script language to be used for evaluating user-written scripts." },
12767cc0636SGreg Clayton {   "stop-disassembly-count",   OptionValue::eTypeSInt64 , true, 4    , NULL, NULL, "The number of disassembly lines to show when displaying a stopped context." },
12867cc0636SGreg 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." },
12967cc0636SGreg 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." },
13067cc0636SGreg 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." },
13167cc0636SGreg Clayton {   "term-width",               OptionValue::eTypeSInt64 , true, 80   , NULL, NULL, "The maximum number of columns to use for displaying text." },
13267cc0636SGreg Clayton {   "thread-format",            OptionValue::eTypeString , true, 0    , DEFAULT_THREAD_FORMAT, NULL, "The default thread format string to use when displaying thread information." },
13367cc0636SGreg Clayton {   "use-external-editor",      OptionValue::eTypeBoolean, true, false, NULL, NULL, "Whether to use an external editor or not." },
134c3ce7f27SMichael Sartain {   "use-color",                OptionValue::eTypeBoolean, true, true , NULL, NULL, "Whether to use Ansi color codes or not." },
135e8cd0c98SGreg Clayton 
13667cc0636SGreg Clayton     {   NULL,                       OptionValue::eTypeInvalid, true, 0    , NULL, NULL, NULL }
13767cc0636SGreg Clayton };
13867cc0636SGreg Clayton 
13967cc0636SGreg Clayton enum
14067cc0636SGreg Clayton {
14167cc0636SGreg Clayton     ePropertyAutoConfirm = 0,
14267cc0636SGreg Clayton     ePropertyFrameFormat,
14367cc0636SGreg Clayton     ePropertyNotiftVoid,
14467cc0636SGreg Clayton     ePropertyPrompt,
14567cc0636SGreg Clayton     ePropertyScriptLanguage,
14667cc0636SGreg Clayton     ePropertyStopDisassemblyCount,
14767cc0636SGreg Clayton     ePropertyStopDisassemblyDisplay,
14867cc0636SGreg Clayton     ePropertyStopLineCountAfter,
14967cc0636SGreg Clayton     ePropertyStopLineCountBefore,
15067cc0636SGreg Clayton     ePropertyTerminalWidth,
15167cc0636SGreg Clayton     ePropertyThreadFormat,
152c3ce7f27SMichael Sartain     ePropertyUseExternalEditor,
153c3ce7f27SMichael Sartain     ePropertyUseColor,
15467cc0636SGreg Clayton };
15567cc0636SGreg Clayton 
15667cc0636SGreg Clayton //
15767cc0636SGreg Clayton //const char *
15867cc0636SGreg Clayton //Debugger::GetFrameFormat() const
15967cc0636SGreg Clayton //{
16067cc0636SGreg Clayton //    return m_properties_sp->GetFrameFormat();
16167cc0636SGreg Clayton //}
16267cc0636SGreg Clayton //const char *
16367cc0636SGreg Clayton //Debugger::GetThreadFormat() const
16467cc0636SGreg Clayton //{
16567cc0636SGreg Clayton //    return m_properties_sp->GetThreadFormat();
16667cc0636SGreg Clayton //}
16767cc0636SGreg Clayton //
1684c05410fSGreg Clayton 
1694c05410fSGreg Clayton 
1704c05410fSGreg Clayton Error
1714c05410fSGreg Clayton Debugger::SetPropertyValue (const ExecutionContext *exe_ctx,
1724c05410fSGreg Clayton                             VarSetOperationType op,
1734c05410fSGreg Clayton                             const char *property_path,
1744c05410fSGreg Clayton                             const char *value)
1754c05410fSGreg Clayton {
17684a53dfbSEnrico Granata     bool is_load_script = strcmp(property_path,"target.load-script-from-symbol-file") == 0;
17784a53dfbSEnrico Granata     TargetSP target_sp;
178397ddd5fSEnrico Granata     LoadScriptFromSymFile load_script_old_value;
17984a53dfbSEnrico Granata     if (is_load_script && exe_ctx->GetTargetSP())
18084a53dfbSEnrico Granata     {
18184a53dfbSEnrico Granata         target_sp = exe_ctx->GetTargetSP();
18284a53dfbSEnrico Granata         load_script_old_value = target_sp->TargetProperties::GetLoadScriptFromSymbolFile();
18384a53dfbSEnrico Granata     }
1844c05410fSGreg Clayton     Error error (Properties::SetPropertyValue (exe_ctx, op, property_path, value));
1854c05410fSGreg Clayton     if (error.Success())
1864c05410fSGreg Clayton     {
18784a53dfbSEnrico Granata         // FIXME it would be nice to have "on-change" callbacks for properties
1884c05410fSGreg Clayton         if (strcmp(property_path, g_properties[ePropertyPrompt].name) == 0)
1894c05410fSGreg Clayton         {
1904c05410fSGreg Clayton             const char *new_prompt = GetPrompt();
191c3ce7f27SMichael Sartain             std::string str = lldb_utility::ansi::FormatAnsiTerminalCodes (new_prompt, GetUseColor());
192c3ce7f27SMichael Sartain             if (str.length())
193c3ce7f27SMichael Sartain                 new_prompt = str.c_str();
1944c05410fSGreg Clayton             EventSP prompt_change_event_sp (new Event(CommandInterpreter::eBroadcastBitResetPrompt, new EventDataBytes (new_prompt)));
1954c05410fSGreg Clayton             GetCommandInterpreter().BroadcastEvent (prompt_change_event_sp);
1964c05410fSGreg Clayton         }
197c3ce7f27SMichael Sartain         else if (strcmp(property_path, g_properties[ePropertyUseColor].name) == 0)
198c3ce7f27SMichael Sartain         {
199c3ce7f27SMichael Sartain 			// use-color changed. Ping the prompt so it can reset the ansi terminal codes.
200c3ce7f27SMichael Sartain             SetPrompt (GetPrompt());
201c3ce7f27SMichael Sartain         }
202397ddd5fSEnrico Granata         else if (is_load_script && target_sp && load_script_old_value == eLoadScriptFromSymFileWarn)
20384a53dfbSEnrico Granata         {
204397ddd5fSEnrico Granata             if (target_sp->TargetProperties::GetLoadScriptFromSymbolFile() == eLoadScriptFromSymFileTrue)
20584a53dfbSEnrico Granata             {
20684a53dfbSEnrico Granata                 std::list<Error> errors;
2079730339bSEnrico Granata                 StreamString feedback_stream;
2089730339bSEnrico Granata                 if (!target_sp->LoadScriptingResources(errors,&feedback_stream))
20984a53dfbSEnrico Granata                 {
21084a53dfbSEnrico Granata                     for (auto error : errors)
21184a53dfbSEnrico Granata                     {
2129730339bSEnrico Granata                         GetErrorStream().Printf("%s\n",error.AsCString());
21384a53dfbSEnrico Granata                     }
2149730339bSEnrico Granata                     if (feedback_stream.GetSize())
2159730339bSEnrico Granata                         GetErrorStream().Printf("%s",feedback_stream.GetData());
21684a53dfbSEnrico Granata                 }
21784a53dfbSEnrico Granata             }
21884a53dfbSEnrico Granata         }
2194c05410fSGreg Clayton     }
2204c05410fSGreg Clayton     return error;
2214c05410fSGreg Clayton }
2224c05410fSGreg Clayton 
22367cc0636SGreg Clayton bool
22467cc0636SGreg Clayton Debugger::GetAutoConfirm () const
22567cc0636SGreg Clayton {
22667cc0636SGreg Clayton     const uint32_t idx = ePropertyAutoConfirm;
227754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
22867cc0636SGreg Clayton }
22967cc0636SGreg Clayton 
23067cc0636SGreg Clayton const char *
23167cc0636SGreg Clayton Debugger::GetFrameFormat() const
23267cc0636SGreg Clayton {
23367cc0636SGreg Clayton     const uint32_t idx = ePropertyFrameFormat;
234754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsString (NULL, idx, g_properties[idx].default_cstr_value);
23567cc0636SGreg Clayton }
23667cc0636SGreg Clayton 
23767cc0636SGreg Clayton bool
23867cc0636SGreg Clayton Debugger::GetNotifyVoid () const
23967cc0636SGreg Clayton {
24067cc0636SGreg Clayton     const uint32_t idx = ePropertyNotiftVoid;
241754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
24267cc0636SGreg Clayton }
24367cc0636SGreg Clayton 
24467cc0636SGreg Clayton const char *
24567cc0636SGreg Clayton Debugger::GetPrompt() const
24667cc0636SGreg Clayton {
24767cc0636SGreg Clayton     const uint32_t idx = ePropertyPrompt;
248754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsString (NULL, idx, g_properties[idx].default_cstr_value);
24967cc0636SGreg Clayton }
25067cc0636SGreg Clayton 
25167cc0636SGreg Clayton void
25267cc0636SGreg Clayton Debugger::SetPrompt(const char *p)
25367cc0636SGreg Clayton {
25467cc0636SGreg Clayton     const uint32_t idx = ePropertyPrompt;
25567cc0636SGreg Clayton     m_collection_sp->SetPropertyAtIndexAsString (NULL, idx, p);
25667cc0636SGreg Clayton     const char *new_prompt = GetPrompt();
257c3ce7f27SMichael Sartain     std::string str = lldb_utility::ansi::FormatAnsiTerminalCodes (new_prompt, GetUseColor());
258c3ce7f27SMichael Sartain     if (str.length())
259c3ce7f27SMichael Sartain         new_prompt = str.c_str();
26067cc0636SGreg Clayton     EventSP prompt_change_event_sp (new Event(CommandInterpreter::eBroadcastBitResetPrompt, new EventDataBytes (new_prompt)));;
26167cc0636SGreg Clayton     GetCommandInterpreter().BroadcastEvent (prompt_change_event_sp);
26267cc0636SGreg Clayton }
26367cc0636SGreg Clayton 
26467cc0636SGreg Clayton const char *
26567cc0636SGreg Clayton Debugger::GetThreadFormat() const
26667cc0636SGreg Clayton {
26767cc0636SGreg Clayton     const uint32_t idx = ePropertyThreadFormat;
268754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsString (NULL, idx, g_properties[idx].default_cstr_value);
26967cc0636SGreg Clayton }
27067cc0636SGreg Clayton 
27167cc0636SGreg Clayton lldb::ScriptLanguage
27267cc0636SGreg Clayton Debugger::GetScriptLanguage() const
27367cc0636SGreg Clayton {
27467cc0636SGreg Clayton     const uint32_t idx = ePropertyScriptLanguage;
275754a9369SGreg Clayton     return (lldb::ScriptLanguage)m_collection_sp->GetPropertyAtIndexAsEnumeration (NULL, idx, g_properties[idx].default_uint_value);
27667cc0636SGreg Clayton }
27767cc0636SGreg Clayton 
27867cc0636SGreg Clayton bool
27967cc0636SGreg Clayton Debugger::SetScriptLanguage (lldb::ScriptLanguage script_lang)
28067cc0636SGreg Clayton {
28167cc0636SGreg Clayton     const uint32_t idx = ePropertyScriptLanguage;
28267cc0636SGreg Clayton     return m_collection_sp->SetPropertyAtIndexAsEnumeration (NULL, idx, script_lang);
28367cc0636SGreg Clayton }
28467cc0636SGreg Clayton 
28567cc0636SGreg Clayton uint32_t
28667cc0636SGreg Clayton Debugger::GetTerminalWidth () const
28767cc0636SGreg Clayton {
28867cc0636SGreg Clayton     const uint32_t idx = ePropertyTerminalWidth;
289754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsSInt64 (NULL, idx, g_properties[idx].default_uint_value);
29067cc0636SGreg Clayton }
29167cc0636SGreg Clayton 
29267cc0636SGreg Clayton bool
29367cc0636SGreg Clayton Debugger::SetTerminalWidth (uint32_t term_width)
29467cc0636SGreg Clayton {
29567cc0636SGreg Clayton     const uint32_t idx = ePropertyTerminalWidth;
29667cc0636SGreg Clayton     return m_collection_sp->SetPropertyAtIndexAsSInt64 (NULL, idx, term_width);
29767cc0636SGreg Clayton }
29867cc0636SGreg Clayton 
29967cc0636SGreg Clayton bool
30067cc0636SGreg Clayton Debugger::GetUseExternalEditor () const
30167cc0636SGreg Clayton {
30267cc0636SGreg Clayton     const uint32_t idx = ePropertyUseExternalEditor;
303754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
30467cc0636SGreg Clayton }
30567cc0636SGreg Clayton 
30667cc0636SGreg Clayton bool
30767cc0636SGreg Clayton Debugger::SetUseExternalEditor (bool b)
30867cc0636SGreg Clayton {
30967cc0636SGreg Clayton     const uint32_t idx = ePropertyUseExternalEditor;
31067cc0636SGreg Clayton     return m_collection_sp->SetPropertyAtIndexAsBoolean (NULL, idx, b);
31167cc0636SGreg Clayton }
31267cc0636SGreg Clayton 
313c3ce7f27SMichael Sartain bool
314c3ce7f27SMichael Sartain Debugger::GetUseColor () const
315c3ce7f27SMichael Sartain {
316c3ce7f27SMichael Sartain     const uint32_t idx = ePropertyUseColor;
317c3ce7f27SMichael Sartain     return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
318c3ce7f27SMichael Sartain }
319c3ce7f27SMichael Sartain 
320c3ce7f27SMichael Sartain bool
321c3ce7f27SMichael Sartain Debugger::SetUseColor (bool b)
322c3ce7f27SMichael Sartain {
323c3ce7f27SMichael Sartain     const uint32_t idx = ePropertyUseColor;
324c3ce7f27SMichael Sartain     bool ret = m_collection_sp->SetPropertyAtIndexAsBoolean (NULL, idx, b);
325c3ce7f27SMichael Sartain     SetPrompt (GetPrompt());
326c3ce7f27SMichael Sartain     return ret;
327c3ce7f27SMichael Sartain }
328c3ce7f27SMichael Sartain 
32967cc0636SGreg Clayton uint32_t
33067cc0636SGreg Clayton Debugger::GetStopSourceLineCount (bool before) const
33167cc0636SGreg Clayton {
33267cc0636SGreg Clayton     const uint32_t idx = before ? ePropertyStopLineCountBefore : ePropertyStopLineCountAfter;
333754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsSInt64 (NULL, idx, g_properties[idx].default_uint_value);
33467cc0636SGreg Clayton }
33567cc0636SGreg Clayton 
33667cc0636SGreg Clayton Debugger::StopDisassemblyType
33767cc0636SGreg Clayton Debugger::GetStopDisassemblyDisplay () const
33867cc0636SGreg Clayton {
33967cc0636SGreg Clayton     const uint32_t idx = ePropertyStopDisassemblyDisplay;
340754a9369SGreg Clayton     return (Debugger::StopDisassemblyType)m_collection_sp->GetPropertyAtIndexAsEnumeration (NULL, idx, g_properties[idx].default_uint_value);
34167cc0636SGreg Clayton }
34267cc0636SGreg Clayton 
34367cc0636SGreg Clayton uint32_t
34467cc0636SGreg Clayton Debugger::GetDisassemblyLineCount () const
34567cc0636SGreg Clayton {
34667cc0636SGreg Clayton     const uint32_t idx = ePropertyStopDisassemblyCount;
347754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsSInt64 (NULL, idx, g_properties[idx].default_uint_value);
34867cc0636SGreg Clayton }
349e372b98dSGreg Clayton 
3501b654882SGreg Clayton #pragma mark Debugger
3511b654882SGreg Clayton 
35267cc0636SGreg Clayton //const DebuggerPropertiesSP &
35367cc0636SGreg Clayton //Debugger::GetSettings() const
35467cc0636SGreg Clayton //{
35567cc0636SGreg Clayton //    return m_properties_sp;
35667cc0636SGreg Clayton //}
35767cc0636SGreg Clayton //
35899d0faf2SGreg Clayton 
3592f88aadfSCaroline Tice int
3602f88aadfSCaroline Tice Debugger::TestDebuggerRefCount ()
3612f88aadfSCaroline Tice {
3622f88aadfSCaroline Tice     return g_shared_debugger_refcount;
3632f88aadfSCaroline Tice }
3642f88aadfSCaroline Tice 
36530fdc8d8SChris Lattner void
36630fdc8d8SChris Lattner Debugger::Initialize ()
36730fdc8d8SChris Lattner {
368c15f55e2SGreg Clayton     if (g_shared_debugger_refcount++ == 0)
369dbe54508SGreg Clayton         lldb_private::Initialize();
37099d0faf2SGreg Clayton }
37130fdc8d8SChris Lattner 
37230fdc8d8SChris Lattner void
37330fdc8d8SChris Lattner Debugger::Terminate ()
37430fdc8d8SChris Lattner {
3756611103cSGreg Clayton     if (g_shared_debugger_refcount > 0)
3766611103cSGreg Clayton     {
37730fdc8d8SChris Lattner         g_shared_debugger_refcount--;
37830fdc8d8SChris Lattner         if (g_shared_debugger_refcount == 0)
37930fdc8d8SChris Lattner         {
380dbe54508SGreg Clayton             lldb_private::WillTerminate();
381dbe54508SGreg Clayton             lldb_private::Terminate();
3826760a517SCaroline Tice 
38399d0faf2SGreg Clayton             // Clear our master list of debugger objects
38499d0faf2SGreg Clayton             Mutex::Locker locker (GetDebuggerListMutex ());
38599d0faf2SGreg Clayton             GetDebuggerList().clear();
38630fdc8d8SChris Lattner         }
3876760a517SCaroline Tice     }
3886760a517SCaroline Tice }
38930fdc8d8SChris Lattner 
39020bd37f7SCaroline Tice void
39120bd37f7SCaroline Tice Debugger::SettingsInitialize ()
39220bd37f7SCaroline Tice {
3936920b52bSGreg Clayton     Target::SettingsInitialize ();
39420bd37f7SCaroline Tice }
39520bd37f7SCaroline Tice 
39620bd37f7SCaroline Tice void
39720bd37f7SCaroline Tice Debugger::SettingsTerminate ()
39820bd37f7SCaroline Tice {
3996920b52bSGreg Clayton     Target::SettingsTerminate ();
40020bd37f7SCaroline Tice }
40120bd37f7SCaroline Tice 
40221dfcd9dSEnrico Granata bool
403e743c782SEnrico Granata Debugger::LoadPlugin (const FileSpec& spec, Error& error)
40421dfcd9dSEnrico Granata {
40521dfcd9dSEnrico Granata     lldb::DynamicLibrarySP dynlib_sp(new lldb_private::DynamicLibrary(spec));
406e743c782SEnrico Granata     if (!dynlib_sp || dynlib_sp->IsValid() == false)
407e743c782SEnrico Granata     {
408e743c782SEnrico Granata         if (spec.Exists())
409e743c782SEnrico Granata             error.SetErrorString("this file does not represent a loadable dylib");
410e743c782SEnrico Granata         else
411e743c782SEnrico Granata             error.SetErrorString("no such file");
412e743c782SEnrico Granata         return false;
413e743c782SEnrico Granata     }
41421dfcd9dSEnrico Granata     lldb::DebuggerSP debugger_sp(shared_from_this());
41521dfcd9dSEnrico Granata     lldb::SBDebugger debugger_sb(debugger_sp);
41621dfcd9dSEnrico Granata     // TODO: mangle this differently for your system - on OSX, the first underscore needs to be removed and the second one stays
41721dfcd9dSEnrico Granata     LLDBCommandPluginInit init_func = dynlib_sp->GetSymbol<LLDBCommandPluginInit>("_ZN4lldb16PluginInitializeENS_10SBDebuggerE");
41821dfcd9dSEnrico Granata     if (!init_func)
419e743c782SEnrico Granata     {
420e743c782SEnrico Granata         error.SetErrorString("cannot find the initialization function lldb::PluginInitialize(lldb::SBDebugger)");
42121dfcd9dSEnrico Granata         return false;
422e743c782SEnrico Granata     }
42321dfcd9dSEnrico Granata     if (init_func(debugger_sb))
42421dfcd9dSEnrico Granata     {
42521dfcd9dSEnrico Granata         m_loaded_plugins.push_back(dynlib_sp);
42621dfcd9dSEnrico Granata         return true;
42721dfcd9dSEnrico Granata     }
428e743c782SEnrico Granata     error.SetErrorString("dylib refused to be loaded");
42921dfcd9dSEnrico Granata     return false;
43021dfcd9dSEnrico Granata }
43121dfcd9dSEnrico Granata 
43221dfcd9dSEnrico Granata static FileSpec::EnumerateDirectoryResult
43321dfcd9dSEnrico Granata LoadPluginCallback
43421dfcd9dSEnrico Granata (
43521dfcd9dSEnrico Granata  void *baton,
43621dfcd9dSEnrico Granata  FileSpec::FileType file_type,
43721dfcd9dSEnrico Granata  const FileSpec &file_spec
43821dfcd9dSEnrico Granata  )
43921dfcd9dSEnrico Granata {
44021dfcd9dSEnrico Granata     Error error;
44121dfcd9dSEnrico Granata 
44221dfcd9dSEnrico Granata     static ConstString g_dylibext("dylib");
44321dfcd9dSEnrico Granata 
44421dfcd9dSEnrico Granata     if (!baton)
44521dfcd9dSEnrico Granata         return FileSpec::eEnumerateDirectoryResultQuit;
44621dfcd9dSEnrico Granata 
44721dfcd9dSEnrico Granata     Debugger *debugger = (Debugger*)baton;
44821dfcd9dSEnrico Granata 
44921dfcd9dSEnrico Granata     // If we have a regular file, a symbolic link or unknown file type, try
45021dfcd9dSEnrico Granata     // and process the file. We must handle unknown as sometimes the directory
45121dfcd9dSEnrico Granata     // enumeration might be enumerating a file system that doesn't have correct
45221dfcd9dSEnrico Granata     // file type information.
45321dfcd9dSEnrico Granata     if (file_type == FileSpec::eFileTypeRegular         ||
45421dfcd9dSEnrico Granata         file_type == FileSpec::eFileTypeSymbolicLink    ||
45521dfcd9dSEnrico Granata         file_type == FileSpec::eFileTypeUnknown          )
45621dfcd9dSEnrico Granata     {
45721dfcd9dSEnrico Granata         FileSpec plugin_file_spec (file_spec);
45821dfcd9dSEnrico Granata         plugin_file_spec.ResolvePath ();
45921dfcd9dSEnrico Granata 
46021dfcd9dSEnrico Granata         if (plugin_file_spec.GetFileNameExtension() != g_dylibext)
46121dfcd9dSEnrico Granata             return FileSpec::eEnumerateDirectoryResultNext;
46221dfcd9dSEnrico Granata 
463e743c782SEnrico Granata         Error plugin_load_error;
464e743c782SEnrico Granata         debugger->LoadPlugin (plugin_file_spec, plugin_load_error);
46521dfcd9dSEnrico Granata 
46621dfcd9dSEnrico Granata         return FileSpec::eEnumerateDirectoryResultNext;
46721dfcd9dSEnrico Granata     }
46821dfcd9dSEnrico Granata 
46921dfcd9dSEnrico Granata     else if (file_type == FileSpec::eFileTypeUnknown     ||
47021dfcd9dSEnrico Granata         file_type == FileSpec::eFileTypeDirectory   ||
47121dfcd9dSEnrico Granata         file_type == FileSpec::eFileTypeSymbolicLink )
47221dfcd9dSEnrico Granata     {
47321dfcd9dSEnrico Granata         // Try and recurse into anything that a directory or symbolic link.
47421dfcd9dSEnrico Granata         // We must also do this for unknown as sometimes the directory enumeration
47521dfcd9dSEnrico Granata         // might be enurating a file system that doesn't have correct file type
47621dfcd9dSEnrico Granata         // information.
47721dfcd9dSEnrico Granata         return FileSpec::eEnumerateDirectoryResultEnter;
47821dfcd9dSEnrico Granata     }
47921dfcd9dSEnrico Granata 
48021dfcd9dSEnrico Granata     return FileSpec::eEnumerateDirectoryResultNext;
48121dfcd9dSEnrico Granata }
48221dfcd9dSEnrico Granata 
48321dfcd9dSEnrico Granata void
48421dfcd9dSEnrico Granata Debugger::InstanceInitialize ()
48521dfcd9dSEnrico Granata {
48621dfcd9dSEnrico Granata     FileSpec dir_spec;
48721dfcd9dSEnrico Granata     const bool find_directories = true;
48821dfcd9dSEnrico Granata     const bool find_files = true;
48921dfcd9dSEnrico Granata     const bool find_other = true;
49021dfcd9dSEnrico Granata     char dir_path[PATH_MAX];
49121dfcd9dSEnrico Granata     if (Host::GetLLDBPath (ePathTypeLLDBSystemPlugins, dir_spec))
49221dfcd9dSEnrico Granata     {
49321dfcd9dSEnrico Granata         if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path)))
49421dfcd9dSEnrico Granata         {
49521dfcd9dSEnrico Granata             FileSpec::EnumerateDirectory (dir_path,
49621dfcd9dSEnrico Granata                                           find_directories,
49721dfcd9dSEnrico Granata                                           find_files,
49821dfcd9dSEnrico Granata                                           find_other,
49921dfcd9dSEnrico Granata                                           LoadPluginCallback,
50021dfcd9dSEnrico Granata                                           this);
50121dfcd9dSEnrico Granata         }
50221dfcd9dSEnrico Granata     }
50321dfcd9dSEnrico Granata 
50421dfcd9dSEnrico Granata     if (Host::GetLLDBPath (ePathTypeLLDBUserPlugins, dir_spec))
50521dfcd9dSEnrico Granata     {
50621dfcd9dSEnrico Granata         if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path)))
50721dfcd9dSEnrico Granata         {
50821dfcd9dSEnrico Granata             FileSpec::EnumerateDirectory (dir_path,
50921dfcd9dSEnrico Granata                                           find_directories,
51021dfcd9dSEnrico Granata                                           find_files,
51121dfcd9dSEnrico Granata                                           find_other,
51221dfcd9dSEnrico Granata                                           LoadPluginCallback,
51321dfcd9dSEnrico Granata                                           this);
51421dfcd9dSEnrico Granata         }
51521dfcd9dSEnrico Granata     }
516e8cd0c98SGreg Clayton 
517e8cd0c98SGreg Clayton     PluginManager::DebuggerInitialize (*this);
51821dfcd9dSEnrico Granata }
51921dfcd9dSEnrico Granata 
5206611103cSGreg Clayton DebuggerSP
521228063cdSJim Ingham Debugger::CreateInstance (lldb::LogOutputCallback log_callback, void *baton)
5226611103cSGreg Clayton {
523228063cdSJim Ingham     DebuggerSP debugger_sp (new Debugger(log_callback, baton));
524c15f55e2SGreg Clayton     if (g_shared_debugger_refcount > 0)
5256611103cSGreg Clayton     {
5266611103cSGreg Clayton         Mutex::Locker locker (GetDebuggerListMutex ());
5276611103cSGreg Clayton         GetDebuggerList().push_back(debugger_sp);
5286611103cSGreg Clayton     }
52921dfcd9dSEnrico Granata     debugger_sp->InstanceInitialize ();
5306611103cSGreg Clayton     return debugger_sp;
5316611103cSGreg Clayton }
5326611103cSGreg Clayton 
533e02657b1SCaroline Tice void
5344d122c40SGreg Clayton Debugger::Destroy (DebuggerSP &debugger_sp)
535e02657b1SCaroline Tice {
536e02657b1SCaroline Tice     if (debugger_sp.get() == NULL)
537e02657b1SCaroline Tice         return;
538e02657b1SCaroline Tice 
5398314c525SJim Ingham     debugger_sp->Clear();
5408314c525SJim Ingham 
541c15f55e2SGreg Clayton     if (g_shared_debugger_refcount > 0)
542c15f55e2SGreg Clayton     {
543e02657b1SCaroline Tice         Mutex::Locker locker (GetDebuggerListMutex ());
544e02657b1SCaroline Tice         DebuggerList &debugger_list = GetDebuggerList ();
545e02657b1SCaroline Tice         DebuggerList::iterator pos, end = debugger_list.end();
546e02657b1SCaroline Tice         for (pos = debugger_list.begin (); pos != end; ++pos)
547e02657b1SCaroline Tice         {
548e02657b1SCaroline Tice             if ((*pos).get() == debugger_sp.get())
549e02657b1SCaroline Tice             {
550e02657b1SCaroline Tice                 debugger_list.erase (pos);
551e02657b1SCaroline Tice                 return;
552e02657b1SCaroline Tice             }
553e02657b1SCaroline Tice         }
554e02657b1SCaroline Tice     }
555c15f55e2SGreg Clayton }
556e02657b1SCaroline Tice 
5574d122c40SGreg Clayton DebuggerSP
5583df9a8dfSCaroline Tice Debugger::FindDebuggerWithInstanceName (const ConstString &instance_name)
5593df9a8dfSCaroline Tice {
5604d122c40SGreg Clayton     DebuggerSP debugger_sp;
5616920b52bSGreg Clayton     if (g_shared_debugger_refcount > 0)
5626920b52bSGreg Clayton     {
5636920b52bSGreg Clayton         Mutex::Locker locker (GetDebuggerListMutex ());
5646920b52bSGreg Clayton         DebuggerList &debugger_list = GetDebuggerList();
5656920b52bSGreg Clayton         DebuggerList::iterator pos, end = debugger_list.end();
5666920b52bSGreg Clayton 
5676920b52bSGreg Clayton         for (pos = debugger_list.begin(); pos != end; ++pos)
5686920b52bSGreg Clayton         {
5696920b52bSGreg Clayton             if ((*pos).get()->m_instance_name == instance_name)
5706920b52bSGreg Clayton             {
5716920b52bSGreg Clayton                 debugger_sp = *pos;
5726920b52bSGreg Clayton                 break;
5736920b52bSGreg Clayton             }
5746920b52bSGreg Clayton         }
5756920b52bSGreg Clayton     }
5763df9a8dfSCaroline Tice     return debugger_sp;
5773df9a8dfSCaroline Tice }
5786611103cSGreg Clayton 
5796611103cSGreg Clayton TargetSP
5806611103cSGreg Clayton Debugger::FindTargetWithProcessID (lldb::pid_t pid)
5816611103cSGreg Clayton {
5824d122c40SGreg Clayton     TargetSP target_sp;
583c15f55e2SGreg Clayton     if (g_shared_debugger_refcount > 0)
584c15f55e2SGreg Clayton     {
5856611103cSGreg Clayton         Mutex::Locker locker (GetDebuggerListMutex ());
5866611103cSGreg Clayton         DebuggerList &debugger_list = GetDebuggerList();
5876611103cSGreg Clayton         DebuggerList::iterator pos, end = debugger_list.end();
5886611103cSGreg Clayton         for (pos = debugger_list.begin(); pos != end; ++pos)
5896611103cSGreg Clayton         {
5906611103cSGreg Clayton             target_sp = (*pos)->GetTargetList().FindTargetWithProcessID (pid);
5916611103cSGreg Clayton             if (target_sp)
5926611103cSGreg Clayton                 break;
5936611103cSGreg Clayton         }
594c15f55e2SGreg Clayton     }
5956611103cSGreg Clayton     return target_sp;
5966611103cSGreg Clayton }
5976611103cSGreg Clayton 
598e4e45924SGreg Clayton TargetSP
599e4e45924SGreg Clayton Debugger::FindTargetWithProcess (Process *process)
600e4e45924SGreg Clayton {
601e4e45924SGreg Clayton     TargetSP target_sp;
602c15f55e2SGreg Clayton     if (g_shared_debugger_refcount > 0)
603c15f55e2SGreg Clayton     {
604e4e45924SGreg Clayton         Mutex::Locker locker (GetDebuggerListMutex ());
605e4e45924SGreg Clayton         DebuggerList &debugger_list = GetDebuggerList();
606e4e45924SGreg Clayton         DebuggerList::iterator pos, end = debugger_list.end();
607e4e45924SGreg Clayton         for (pos = debugger_list.begin(); pos != end; ++pos)
608e4e45924SGreg Clayton         {
609e4e45924SGreg Clayton             target_sp = (*pos)->GetTargetList().FindTargetWithProcess (process);
610e4e45924SGreg Clayton             if (target_sp)
611e4e45924SGreg Clayton                 break;
612e4e45924SGreg Clayton         }
613c15f55e2SGreg Clayton     }
614e4e45924SGreg Clayton     return target_sp;
615e4e45924SGreg Clayton }
616e4e45924SGreg Clayton 
617228063cdSJim Ingham Debugger::Debugger (lldb::LogOutputCallback log_callback, void *baton) :
618ebc1bb27SCaroline Tice     UserID (g_unique_id++),
61967cc0636SGreg Clayton     Properties(OptionValuePropertiesSP(new OptionValueProperties())),
620d46c87a1SGreg Clayton     m_input_comm("debugger.input"),
62130fdc8d8SChris Lattner     m_input_file (),
62230fdc8d8SChris Lattner     m_output_file (),
62330fdc8d8SChris Lattner     m_error_file (),
624c5917d9aSJim Ingham     m_terminal_state (),
6254bddaeb5SJim Ingham     m_target_list (*this),
626ded470d3SGreg Clayton     m_platform_list (),
62730fdc8d8SChris Lattner     m_listener ("lldb.Debugger"),
6289585fbfcSGreg Clayton     m_source_manager_ap(),
629e37d605eSJim Ingham     m_source_file_cache(),
6306611103cSGreg Clayton     m_command_interpreter_ap (new CommandInterpreter (*this, eScriptLanguageDefault, false)),
631d5a0a01bSCaroline Tice     m_input_reader_stack (),
63267cc0636SGreg Clayton     m_input_reader_data (),
63367cc0636SGreg Clayton     m_instance_name()
63430fdc8d8SChris Lattner {
63567cc0636SGreg Clayton     char instance_cstr[256];
63667cc0636SGreg Clayton     snprintf(instance_cstr, sizeof(instance_cstr), "debugger_%d", (int)GetID());
63767cc0636SGreg Clayton     m_instance_name.SetCString(instance_cstr);
638228063cdSJim Ingham     if (log_callback)
639228063cdSJim Ingham         m_log_callback_stream_sp.reset (new StreamCallback (log_callback, baton));
6406611103cSGreg Clayton     m_command_interpreter_ap->Initialize ();
641ded470d3SGreg Clayton     // Always add our default platform to the platform list
642ded470d3SGreg Clayton     PlatformSP default_platform_sp (Platform::GetDefaultPlatform());
643ded470d3SGreg Clayton     assert (default_platform_sp.get());
644ded470d3SGreg Clayton     m_platform_list.Append (default_platform_sp, true);
64567cc0636SGreg Clayton 
646754a9369SGreg Clayton     m_collection_sp->Initialize (g_properties);
64767cc0636SGreg Clayton     m_collection_sp->AppendProperty (ConstString("target"),
64867cc0636SGreg Clayton                                      ConstString("Settings specify to debugging targets."),
64967cc0636SGreg Clayton                                      true,
65067cc0636SGreg Clayton                                      Target::GetGlobalProperties()->GetValueProperties());
651754a9369SGreg Clayton     if (m_command_interpreter_ap.get())
652754a9369SGreg Clayton     {
653754a9369SGreg Clayton         m_collection_sp->AppendProperty (ConstString("interpreter"),
654754a9369SGreg Clayton                                          ConstString("Settings specify to the debugger's command interpreter."),
655754a9369SGreg Clayton                                          true,
656754a9369SGreg Clayton                                          m_command_interpreter_ap->GetValueProperties());
657754a9369SGreg Clayton     }
65867cc0636SGreg Clayton     OptionValueSInt64 *term_width = m_collection_sp->GetPropertyAtIndexAsOptionValueSInt64 (NULL, ePropertyTerminalWidth);
65967cc0636SGreg Clayton     term_width->SetMinimumValue(10);
66067cc0636SGreg Clayton     term_width->SetMaximumValue(1024);
661c3ce7f27SMichael Sartain 
662c3ce7f27SMichael Sartain     // Turn off use-color if this is a dumb terminal.
663c3ce7f27SMichael Sartain     const char *term = getenv ("TERM");
664c3ce7f27SMichael Sartain     if (term && !strcmp (term, "dumb"))
665c3ce7f27SMichael Sartain         SetUseColor (false);
66630fdc8d8SChris Lattner }
66730fdc8d8SChris Lattner 
66830fdc8d8SChris Lattner Debugger::~Debugger ()
66930fdc8d8SChris Lattner {
6708314c525SJim Ingham     Clear();
6718314c525SJim Ingham }
6728314c525SJim Ingham 
6738314c525SJim Ingham void
6748314c525SJim Ingham Debugger::Clear()
6758314c525SJim Ingham {
6763d6086f6SCaroline Tice     CleanUpInputReaders();
6771ed54f50SGreg Clayton     m_listener.Clear();
6786611103cSGreg Clayton     int num_targets = m_target_list.GetNumTargets();
6796611103cSGreg Clayton     for (int i = 0; i < num_targets; i++)
6806611103cSGreg Clayton     {
681ccbc08e6SGreg Clayton         TargetSP target_sp (m_target_list.GetTargetAtIndex (i));
682ccbc08e6SGreg Clayton         if (target_sp)
683ccbc08e6SGreg Clayton         {
684ccbc08e6SGreg Clayton             ProcessSP process_sp (target_sp->GetProcessSP());
6856611103cSGreg Clayton             if (process_sp)
6861fd07059SJim Ingham                 process_sp->Finalize();
687ccbc08e6SGreg Clayton             target_sp->Destroy();
6886611103cSGreg Clayton         }
68930fdc8d8SChris Lattner     }
6904bddaeb5SJim Ingham     BroadcasterManager::Clear ();
69130fdc8d8SChris Lattner 
6920d69a3a4SGreg Clayton     // Close the input file _before_ we close the input read communications class
6930d69a3a4SGreg Clayton     // as it does NOT own the input file, our m_input_file does.
694c5917d9aSJim Ingham     m_terminal_state.Clear();
6950d69a3a4SGreg Clayton     GetInputFile().Close ();
6960d69a3a4SGreg Clayton     // Now that we have closed m_input_file, we can now tell our input communication
6970d69a3a4SGreg Clayton     // class to close down. Its read thread should quickly exit after we close
6980d69a3a4SGreg Clayton     // the input file handle above.
6990d69a3a4SGreg Clayton     m_input_comm.Clear ();
7008314c525SJim Ingham }
70130fdc8d8SChris Lattner 
70230fdc8d8SChris Lattner bool
703fc3f027dSGreg Clayton Debugger::GetCloseInputOnEOF () const
704fc3f027dSGreg Clayton {
705fc3f027dSGreg Clayton     return m_input_comm.GetCloseOnEOF();
706fc3f027dSGreg Clayton }
707fc3f027dSGreg Clayton 
708fc3f027dSGreg Clayton void
709fc3f027dSGreg Clayton Debugger::SetCloseInputOnEOF (bool b)
710fc3f027dSGreg Clayton {
711fc3f027dSGreg Clayton     m_input_comm.SetCloseOnEOF(b);
712fc3f027dSGreg Clayton }
713fc3f027dSGreg Clayton 
714fc3f027dSGreg Clayton bool
71530fdc8d8SChris Lattner Debugger::GetAsyncExecution ()
71630fdc8d8SChris Lattner {
7176611103cSGreg Clayton     return !m_command_interpreter_ap->GetSynchronous();
71830fdc8d8SChris Lattner }
71930fdc8d8SChris Lattner 
72030fdc8d8SChris Lattner void
72130fdc8d8SChris Lattner Debugger::SetAsyncExecution (bool async_execution)
72230fdc8d8SChris Lattner {
7236611103cSGreg Clayton     m_command_interpreter_ap->SetSynchronous (!async_execution);
72430fdc8d8SChris Lattner }
72530fdc8d8SChris Lattner 
72630fdc8d8SChris Lattner 
72730fdc8d8SChris Lattner void
72830fdc8d8SChris Lattner Debugger::SetInputFileHandle (FILE *fh, bool tranfer_ownership)
72930fdc8d8SChris Lattner {
73051b1e2d2SGreg Clayton     File &in_file = GetInputFile();
73151b1e2d2SGreg Clayton     in_file.SetStream (fh, tranfer_ownership);
73251b1e2d2SGreg Clayton     if (in_file.IsValid() == false)
73351b1e2d2SGreg Clayton         in_file.SetStream (stdin, true);
73430fdc8d8SChris Lattner 
73530fdc8d8SChris Lattner     // Disconnect from any old connection if we had one
73630fdc8d8SChris Lattner     m_input_comm.Disconnect ();
73732720b51SGreg Clayton     // Pass false as the second argument to ConnectionFileDescriptor below because
73832720b51SGreg Clayton     // our "in_file" above will already take ownership if requested and we don't
73932720b51SGreg Clayton     // want to objects trying to own and close a file descriptor.
74032720b51SGreg Clayton     m_input_comm.SetConnection (new ConnectionFileDescriptor (in_file.GetDescriptor(), false));
74130fdc8d8SChris Lattner     m_input_comm.SetReadThreadBytesReceivedCallback (Debugger::DispatchInputCallback, this);
74230fdc8d8SChris Lattner 
743c5917d9aSJim Ingham     // Save away the terminal state if that is relevant, so that we can restore it in RestoreInputState.
744c5917d9aSJim Ingham     SaveInputTerminalState ();
745c5917d9aSJim Ingham 
74630fdc8d8SChris Lattner     Error error;
74730fdc8d8SChris Lattner     if (m_input_comm.StartReadThread (&error) == false)
74830fdc8d8SChris Lattner     {
74951b1e2d2SGreg Clayton         File &err_file = GetErrorFile();
75051b1e2d2SGreg Clayton 
75151b1e2d2SGreg Clayton         err_file.Printf ("error: failed to main input read thread: %s", error.AsCString() ? error.AsCString() : "unkown error");
75230fdc8d8SChris Lattner         exit(1);
75330fdc8d8SChris Lattner     }
75430fdc8d8SChris Lattner }
75530fdc8d8SChris Lattner 
75630fdc8d8SChris Lattner void
75730fdc8d8SChris Lattner Debugger::SetOutputFileHandle (FILE *fh, bool tranfer_ownership)
75830fdc8d8SChris Lattner {
75951b1e2d2SGreg Clayton     File &out_file = GetOutputFile();
76051b1e2d2SGreg Clayton     out_file.SetStream (fh, tranfer_ownership);
76151b1e2d2SGreg Clayton     if (out_file.IsValid() == false)
76251b1e2d2SGreg Clayton         out_file.SetStream (stdout, false);
7632f88aadfSCaroline Tice 
764b588726eSEnrico Granata     // do not create the ScriptInterpreter just for setting the output file handle
765b588726eSEnrico Granata     // as the constructor will know how to do the right thing on its own
766b588726eSEnrico Granata     const bool can_create = false;
767b588726eSEnrico Granata     ScriptInterpreter* script_interpreter = GetCommandInterpreter().GetScriptInterpreter(can_create);
768b588726eSEnrico Granata     if (script_interpreter)
769b588726eSEnrico Granata         script_interpreter->ResetOutputFileHandle (fh);
77030fdc8d8SChris Lattner }
77130fdc8d8SChris Lattner 
77230fdc8d8SChris Lattner void
77330fdc8d8SChris Lattner Debugger::SetErrorFileHandle (FILE *fh, bool tranfer_ownership)
77430fdc8d8SChris Lattner {
77551b1e2d2SGreg Clayton     File &err_file = GetErrorFile();
77651b1e2d2SGreg Clayton     err_file.SetStream (fh, tranfer_ownership);
77751b1e2d2SGreg Clayton     if (err_file.IsValid() == false)
77851b1e2d2SGreg Clayton         err_file.SetStream (stderr, false);
77930fdc8d8SChris Lattner }
78030fdc8d8SChris Lattner 
781c5917d9aSJim Ingham void
782c5917d9aSJim Ingham Debugger::SaveInputTerminalState ()
783c5917d9aSJim Ingham {
784c5917d9aSJim Ingham     File &in_file = GetInputFile();
785c5917d9aSJim Ingham     if (in_file.GetDescriptor() != File::kInvalidDescriptor)
786c5917d9aSJim Ingham         m_terminal_state.Save(in_file.GetDescriptor(), true);
787c5917d9aSJim Ingham }
788c5917d9aSJim Ingham 
789c5917d9aSJim Ingham void
790c5917d9aSJim Ingham Debugger::RestoreInputTerminalState ()
791c5917d9aSJim Ingham {
792c5917d9aSJim Ingham     m_terminal_state.Restore();
793c5917d9aSJim Ingham }
794c5917d9aSJim Ingham 
79530fdc8d8SChris Lattner ExecutionContext
7962976d00aSJim Ingham Debugger::GetSelectedExecutionContext ()
79730fdc8d8SChris Lattner {
79830fdc8d8SChris Lattner     ExecutionContext exe_ctx;
799c14ee32dSGreg Clayton     TargetSP target_sp(GetSelectedTarget());
800c14ee32dSGreg Clayton     exe_ctx.SetTargetSP (target_sp);
80130fdc8d8SChris Lattner 
80230fdc8d8SChris Lattner     if (target_sp)
80330fdc8d8SChris Lattner     {
804c14ee32dSGreg Clayton         ProcessSP process_sp (target_sp->GetProcessSP());
805c14ee32dSGreg Clayton         exe_ctx.SetProcessSP (process_sp);
806c14ee32dSGreg Clayton         if (process_sp && process_sp->IsRunning() == false)
80730fdc8d8SChris Lattner         {
808c14ee32dSGreg Clayton             ThreadSP thread_sp (process_sp->GetThreadList().GetSelectedThread());
809c14ee32dSGreg Clayton             if (thread_sp)
81030fdc8d8SChris Lattner             {
811c14ee32dSGreg Clayton                 exe_ctx.SetThreadSP (thread_sp);
812c14ee32dSGreg Clayton                 exe_ctx.SetFrameSP (thread_sp->GetSelectedFrame());
813c14ee32dSGreg Clayton                 if (exe_ctx.GetFramePtr() == NULL)
814c14ee32dSGreg Clayton                     exe_ctx.SetFrameSP (thread_sp->GetStackFrameAtIndex (0));
81530fdc8d8SChris Lattner             }
81630fdc8d8SChris Lattner         }
81730fdc8d8SChris Lattner     }
81830fdc8d8SChris Lattner     return exe_ctx;
81930fdc8d8SChris Lattner 
82030fdc8d8SChris Lattner }
82130fdc8d8SChris Lattner 
822b44880caSCaroline Tice InputReaderSP
823b44880caSCaroline Tice Debugger::GetCurrentInputReader ()
824b44880caSCaroline Tice {
825b44880caSCaroline Tice     InputReaderSP reader_sp;
826b44880caSCaroline Tice 
827d5a0a01bSCaroline Tice     if (!m_input_reader_stack.IsEmpty())
828b44880caSCaroline Tice     {
829b44880caSCaroline Tice         // Clear any finished readers from the stack
830b44880caSCaroline Tice         while (CheckIfTopInputReaderIsDone()) ;
831b44880caSCaroline Tice 
832d5a0a01bSCaroline Tice         if (!m_input_reader_stack.IsEmpty())
833d5a0a01bSCaroline Tice             reader_sp = m_input_reader_stack.Top();
834b44880caSCaroline Tice     }
835b44880caSCaroline Tice 
836b44880caSCaroline Tice     return reader_sp;
837b44880caSCaroline Tice }
838b44880caSCaroline Tice 
83930fdc8d8SChris Lattner void
84030fdc8d8SChris Lattner Debugger::DispatchInputCallback (void *baton, const void *bytes, size_t bytes_len)
84130fdc8d8SChris Lattner {
842efed6131SCaroline Tice     if (bytes_len > 0)
84330fdc8d8SChris Lattner         ((Debugger *)baton)->DispatchInput ((char *)bytes, bytes_len);
844efed6131SCaroline Tice     else
845efed6131SCaroline Tice         ((Debugger *)baton)->DispatchInputEndOfFile ();
84630fdc8d8SChris Lattner }
84730fdc8d8SChris Lattner 
84830fdc8d8SChris Lattner 
84930fdc8d8SChris Lattner void
85030fdc8d8SChris Lattner Debugger::DispatchInput (const char *bytes, size_t bytes_len)
85130fdc8d8SChris Lattner {
852efed6131SCaroline Tice     if (bytes == NULL || bytes_len == 0)
853efed6131SCaroline Tice         return;
85430fdc8d8SChris Lattner 
85530fdc8d8SChris Lattner     WriteToDefaultReader (bytes, bytes_len);
85630fdc8d8SChris Lattner }
85730fdc8d8SChris Lattner 
85830fdc8d8SChris Lattner void
859efed6131SCaroline Tice Debugger::DispatchInputInterrupt ()
860efed6131SCaroline Tice {
861efed6131SCaroline Tice     m_input_reader_data.clear();
862efed6131SCaroline Tice 
863b44880caSCaroline Tice     InputReaderSP reader_sp (GetCurrentInputReader ());
864efed6131SCaroline Tice     if (reader_sp)
865b44880caSCaroline Tice     {
866efed6131SCaroline Tice         reader_sp->Notify (eInputReaderInterrupt);
867efed6131SCaroline Tice 
868b44880caSCaroline Tice         // If notifying the reader of the interrupt finished the reader, we should pop it off the stack.
869efed6131SCaroline Tice         while (CheckIfTopInputReaderIsDone ()) ;
870efed6131SCaroline Tice     }
871efed6131SCaroline Tice }
872efed6131SCaroline Tice 
873efed6131SCaroline Tice void
874efed6131SCaroline Tice Debugger::DispatchInputEndOfFile ()
875efed6131SCaroline Tice {
876efed6131SCaroline Tice     m_input_reader_data.clear();
877efed6131SCaroline Tice 
878b44880caSCaroline Tice     InputReaderSP reader_sp (GetCurrentInputReader ());
879efed6131SCaroline Tice     if (reader_sp)
880b44880caSCaroline Tice     {
881efed6131SCaroline Tice         reader_sp->Notify (eInputReaderEndOfFile);
882efed6131SCaroline Tice 
883b44880caSCaroline Tice         // If notifying the reader of the end-of-file finished the reader, we should pop it off the stack.
884efed6131SCaroline Tice         while (CheckIfTopInputReaderIsDone ()) ;
885efed6131SCaroline Tice     }
886efed6131SCaroline Tice }
887efed6131SCaroline Tice 
888efed6131SCaroline Tice void
8893d6086f6SCaroline Tice Debugger::CleanUpInputReaders ()
8903d6086f6SCaroline Tice {
8913d6086f6SCaroline Tice     m_input_reader_data.clear();
8923d6086f6SCaroline Tice 
893b44880caSCaroline Tice     // The bottom input reader should be the main debugger input reader.  We do not want to close that one here.
894d5a0a01bSCaroline Tice     while (m_input_reader_stack.GetSize() > 1)
8953d6086f6SCaroline Tice     {
896b44880caSCaroline Tice         InputReaderSP reader_sp (GetCurrentInputReader ());
8973d6086f6SCaroline Tice         if (reader_sp)
8983d6086f6SCaroline Tice         {
8993d6086f6SCaroline Tice             reader_sp->Notify (eInputReaderEndOfFile);
9003d6086f6SCaroline Tice             reader_sp->SetIsDone (true);
9013d6086f6SCaroline Tice         }
9023d6086f6SCaroline Tice     }
9033d6086f6SCaroline Tice }
9043d6086f6SCaroline Tice 
9053d6086f6SCaroline Tice void
906969ed3d1SCaroline Tice Debugger::NotifyTopInputReader (InputReaderAction notification)
907969ed3d1SCaroline Tice {
908969ed3d1SCaroline Tice     InputReaderSP reader_sp (GetCurrentInputReader());
909969ed3d1SCaroline Tice     if (reader_sp)
910969ed3d1SCaroline Tice 	{
911969ed3d1SCaroline Tice         reader_sp->Notify (notification);
912969ed3d1SCaroline Tice 
913969ed3d1SCaroline Tice         // Flush out any input readers that are done.
914969ed3d1SCaroline Tice         while (CheckIfTopInputReaderIsDone ())
915969ed3d1SCaroline Tice             /* Do nothing. */;
916969ed3d1SCaroline Tice     }
917969ed3d1SCaroline Tice }
918969ed3d1SCaroline Tice 
9199088b068SCaroline Tice bool
9204d122c40SGreg Clayton Debugger::InputReaderIsTopReader (const InputReaderSP& reader_sp)
9219088b068SCaroline Tice {
9229088b068SCaroline Tice     InputReaderSP top_reader_sp (GetCurrentInputReader());
9239088b068SCaroline Tice 
924d61c10bcSCaroline Tice     return (reader_sp.get() == top_reader_sp.get());
9259088b068SCaroline Tice }
9269088b068SCaroline Tice 
9279088b068SCaroline Tice 
928969ed3d1SCaroline Tice void
92930fdc8d8SChris Lattner Debugger::WriteToDefaultReader (const char *bytes, size_t bytes_len)
93030fdc8d8SChris Lattner {
93130fdc8d8SChris Lattner     if (bytes && bytes_len)
93230fdc8d8SChris Lattner         m_input_reader_data.append (bytes, bytes_len);
93330fdc8d8SChris Lattner 
93430fdc8d8SChris Lattner     if (m_input_reader_data.empty())
93530fdc8d8SChris Lattner         return;
93630fdc8d8SChris Lattner 
937d5a0a01bSCaroline Tice     while (!m_input_reader_stack.IsEmpty() && !m_input_reader_data.empty())
93830fdc8d8SChris Lattner     {
93930fdc8d8SChris Lattner         // Get the input reader from the top of the stack
940b44880caSCaroline Tice         InputReaderSP reader_sp (GetCurrentInputReader ());
94130fdc8d8SChris Lattner         if (!reader_sp)
94230fdc8d8SChris Lattner             break;
94330fdc8d8SChris Lattner 
944471b31ceSGreg Clayton         size_t bytes_handled = reader_sp->HandleRawBytes (m_input_reader_data.c_str(),
94530fdc8d8SChris Lattner                                                           m_input_reader_data.size());
94630fdc8d8SChris Lattner         if (bytes_handled)
94730fdc8d8SChris Lattner         {
94830fdc8d8SChris Lattner             m_input_reader_data.erase (0, bytes_handled);
94930fdc8d8SChris Lattner         }
95030fdc8d8SChris Lattner         else
95130fdc8d8SChris Lattner         {
95230fdc8d8SChris Lattner             // No bytes were handled, we might not have reached our
95330fdc8d8SChris Lattner             // granularity, just return and wait for more data
95430fdc8d8SChris Lattner             break;
95530fdc8d8SChris Lattner         }
95630fdc8d8SChris Lattner     }
95730fdc8d8SChris Lattner 
958b44880caSCaroline Tice     // Flush out any input readers that are done.
95930fdc8d8SChris Lattner     while (CheckIfTopInputReaderIsDone ())
96030fdc8d8SChris Lattner         /* Do nothing. */;
96130fdc8d8SChris Lattner 
96230fdc8d8SChris Lattner }
96330fdc8d8SChris Lattner 
96430fdc8d8SChris Lattner void
96530fdc8d8SChris Lattner Debugger::PushInputReader (const InputReaderSP& reader_sp)
96630fdc8d8SChris Lattner {
96730fdc8d8SChris Lattner     if (!reader_sp)
96830fdc8d8SChris Lattner         return;
969b44880caSCaroline Tice 
97030fdc8d8SChris Lattner     // Deactivate the old top reader
971b44880caSCaroline Tice     InputReaderSP top_reader_sp (GetCurrentInputReader ());
972b44880caSCaroline Tice 
97330fdc8d8SChris Lattner     if (top_reader_sp)
97430fdc8d8SChris Lattner         top_reader_sp->Notify (eInputReaderDeactivate);
975b44880caSCaroline Tice 
976d5a0a01bSCaroline Tice     m_input_reader_stack.Push (reader_sp);
97730fdc8d8SChris Lattner     reader_sp->Notify (eInputReaderActivate);
97830fdc8d8SChris Lattner     ActivateInputReader (reader_sp);
97930fdc8d8SChris Lattner }
98030fdc8d8SChris Lattner 
98130fdc8d8SChris Lattner bool
9824d122c40SGreg Clayton Debugger::PopInputReader (const InputReaderSP& pop_reader_sp)
98330fdc8d8SChris Lattner {
98430fdc8d8SChris Lattner     bool result = false;
98530fdc8d8SChris Lattner 
98630fdc8d8SChris Lattner     // The reader on the stop of the stack is done, so let the next
98730fdc8d8SChris Lattner     // read on the stack referesh its prompt and if there is one...
988d5a0a01bSCaroline Tice     if (!m_input_reader_stack.IsEmpty())
98930fdc8d8SChris Lattner     {
990b44880caSCaroline Tice         // Cannot call GetCurrentInputReader here, as that would cause an infinite loop.
991d5a0a01bSCaroline Tice         InputReaderSP reader_sp(m_input_reader_stack.Top());
99230fdc8d8SChris Lattner 
99330fdc8d8SChris Lattner         if (!pop_reader_sp || pop_reader_sp.get() == reader_sp.get())
99430fdc8d8SChris Lattner         {
995d5a0a01bSCaroline Tice             m_input_reader_stack.Pop ();
99630fdc8d8SChris Lattner             reader_sp->Notify (eInputReaderDeactivate);
99730fdc8d8SChris Lattner             reader_sp->Notify (eInputReaderDone);
99830fdc8d8SChris Lattner             result = true;
99930fdc8d8SChris Lattner 
1000d5a0a01bSCaroline Tice             if (!m_input_reader_stack.IsEmpty())
100130fdc8d8SChris Lattner             {
1002d5a0a01bSCaroline Tice                 reader_sp = m_input_reader_stack.Top();
100330fdc8d8SChris Lattner                 if (reader_sp)
100430fdc8d8SChris Lattner                 {
100530fdc8d8SChris Lattner                     ActivateInputReader (reader_sp);
100630fdc8d8SChris Lattner                     reader_sp->Notify (eInputReaderReactivate);
100730fdc8d8SChris Lattner                 }
100830fdc8d8SChris Lattner             }
100930fdc8d8SChris Lattner         }
101030fdc8d8SChris Lattner     }
101130fdc8d8SChris Lattner     return result;
101230fdc8d8SChris Lattner }
101330fdc8d8SChris Lattner 
101430fdc8d8SChris Lattner bool
101530fdc8d8SChris Lattner Debugger::CheckIfTopInputReaderIsDone ()
101630fdc8d8SChris Lattner {
101730fdc8d8SChris Lattner     bool result = false;
1018d5a0a01bSCaroline Tice     if (!m_input_reader_stack.IsEmpty())
101930fdc8d8SChris Lattner     {
1020b44880caSCaroline Tice         // Cannot call GetCurrentInputReader here, as that would cause an infinite loop.
1021d5a0a01bSCaroline Tice         InputReaderSP reader_sp(m_input_reader_stack.Top());
102230fdc8d8SChris Lattner 
102330fdc8d8SChris Lattner         if (reader_sp && reader_sp->IsDone())
102430fdc8d8SChris Lattner         {
102530fdc8d8SChris Lattner             result = true;
102630fdc8d8SChris Lattner             PopInputReader (reader_sp);
102730fdc8d8SChris Lattner         }
102830fdc8d8SChris Lattner     }
102930fdc8d8SChris Lattner     return result;
103030fdc8d8SChris Lattner }
103130fdc8d8SChris Lattner 
103230fdc8d8SChris Lattner void
103330fdc8d8SChris Lattner Debugger::ActivateInputReader (const InputReaderSP &reader_sp)
103430fdc8d8SChris Lattner {
103551b1e2d2SGreg Clayton     int input_fd = m_input_file.GetFile().GetDescriptor();
103630fdc8d8SChris Lattner 
103751b1e2d2SGreg Clayton     if (input_fd >= 0)
103830fdc8d8SChris Lattner     {
103951b1e2d2SGreg Clayton         Terminal tty(input_fd);
1040a3406614SGreg Clayton 
1041a3406614SGreg Clayton         tty.SetEcho(reader_sp->GetEcho());
104230fdc8d8SChris Lattner 
104330fdc8d8SChris Lattner         switch (reader_sp->GetGranularity())
104430fdc8d8SChris Lattner         {
104530fdc8d8SChris Lattner         case eInputReaderGranularityByte:
104630fdc8d8SChris Lattner         case eInputReaderGranularityWord:
1047a3406614SGreg Clayton             tty.SetCanonical (false);
104830fdc8d8SChris Lattner             break;
104930fdc8d8SChris Lattner 
105030fdc8d8SChris Lattner         case eInputReaderGranularityLine:
105130fdc8d8SChris Lattner         case eInputReaderGranularityAll:
1052a3406614SGreg Clayton             tty.SetCanonical (true);
105330fdc8d8SChris Lattner             break;
105430fdc8d8SChris Lattner 
105530fdc8d8SChris Lattner         default:
105630fdc8d8SChris Lattner             break;
105730fdc8d8SChris Lattner         }
105830fdc8d8SChris Lattner     }
105930fdc8d8SChris Lattner }
10606611103cSGreg Clayton 
10615b52f0c7SJim Ingham StreamSP
10625b52f0c7SJim Ingham Debugger::GetAsyncOutputStream ()
10635b52f0c7SJim Ingham {
10645b52f0c7SJim Ingham     return StreamSP (new StreamAsynchronousIO (GetCommandInterpreter(),
10655b52f0c7SJim Ingham                                                CommandInterpreter::eBroadcastBitAsynchronousOutputData));
10665b52f0c7SJim Ingham }
10675b52f0c7SJim Ingham 
10685b52f0c7SJim Ingham StreamSP
10695b52f0c7SJim Ingham Debugger::GetAsyncErrorStream ()
10705b52f0c7SJim Ingham {
10715b52f0c7SJim Ingham     return StreamSP (new StreamAsynchronousIO (GetCommandInterpreter(),
10725b52f0c7SJim Ingham                                                CommandInterpreter::eBroadcastBitAsynchronousErrorData));
10735b52f0c7SJim Ingham }
10745b52f0c7SJim Ingham 
1075c7bece56SGreg Clayton size_t
1076061858ceSEnrico Granata Debugger::GetNumDebuggers()
1077061858ceSEnrico Granata {
1078c15f55e2SGreg Clayton     if (g_shared_debugger_refcount > 0)
1079c15f55e2SGreg Clayton     {
1080061858ceSEnrico Granata         Mutex::Locker locker (GetDebuggerListMutex ());
1081061858ceSEnrico Granata         return GetDebuggerList().size();
1082061858ceSEnrico Granata     }
1083c15f55e2SGreg Clayton     return 0;
1084c15f55e2SGreg Clayton }
1085061858ceSEnrico Granata 
1086061858ceSEnrico Granata lldb::DebuggerSP
1087c7bece56SGreg Clayton Debugger::GetDebuggerAtIndex (size_t index)
1088061858ceSEnrico Granata {
1089061858ceSEnrico Granata     DebuggerSP debugger_sp;
1090061858ceSEnrico Granata 
1091c15f55e2SGreg Clayton     if (g_shared_debugger_refcount > 0)
1092c15f55e2SGreg Clayton     {
1093061858ceSEnrico Granata         Mutex::Locker locker (GetDebuggerListMutex ());
1094061858ceSEnrico Granata         DebuggerList &debugger_list = GetDebuggerList();
1095061858ceSEnrico Granata 
1096061858ceSEnrico Granata         if (index < debugger_list.size())
1097061858ceSEnrico Granata             debugger_sp = debugger_list[index];
1098c15f55e2SGreg Clayton     }
1099061858ceSEnrico Granata 
1100061858ceSEnrico Granata     return debugger_sp;
1101061858ceSEnrico Granata }
1102061858ceSEnrico Granata 
1103ebc1bb27SCaroline Tice DebuggerSP
1104ebc1bb27SCaroline Tice Debugger::FindDebuggerWithID (lldb::user_id_t id)
1105ebc1bb27SCaroline Tice {
11064d122c40SGreg Clayton     DebuggerSP debugger_sp;
1107ebc1bb27SCaroline Tice 
1108c15f55e2SGreg Clayton     if (g_shared_debugger_refcount > 0)
1109c15f55e2SGreg Clayton     {
1110ebc1bb27SCaroline Tice         Mutex::Locker locker (GetDebuggerListMutex ());
1111ebc1bb27SCaroline Tice         DebuggerList &debugger_list = GetDebuggerList();
1112ebc1bb27SCaroline Tice         DebuggerList::iterator pos, end = debugger_list.end();
1113ebc1bb27SCaroline Tice         for (pos = debugger_list.begin(); pos != end; ++pos)
1114ebc1bb27SCaroline Tice         {
1115ebc1bb27SCaroline Tice             if ((*pos).get()->GetID() == id)
1116ebc1bb27SCaroline Tice             {
1117ebc1bb27SCaroline Tice                 debugger_sp = *pos;
1118ebc1bb27SCaroline Tice                 break;
1119ebc1bb27SCaroline Tice             }
1120ebc1bb27SCaroline Tice         }
1121c15f55e2SGreg Clayton     }
1122ebc1bb27SCaroline Tice     return debugger_sp;
1123ebc1bb27SCaroline Tice }
11243df9a8dfSCaroline Tice 
11251b654882SGreg Clayton static void
11261b654882SGreg Clayton TestPromptFormats (StackFrame *frame)
11271b654882SGreg Clayton {
11281b654882SGreg Clayton     if (frame == NULL)
11291b654882SGreg Clayton         return;
11301b654882SGreg Clayton 
11311b654882SGreg Clayton     StreamString s;
11321b654882SGreg Clayton     const char *prompt_format =
11331b654882SGreg Clayton     "{addr = '${addr}'\n}"
11341b654882SGreg Clayton     "{process.id = '${process.id}'\n}"
11351b654882SGreg Clayton     "{process.name = '${process.name}'\n}"
11361b654882SGreg Clayton     "{process.file.basename = '${process.file.basename}'\n}"
11371b654882SGreg Clayton     "{process.file.fullpath = '${process.file.fullpath}'\n}"
11381b654882SGreg Clayton     "{thread.id = '${thread.id}'\n}"
11391b654882SGreg Clayton     "{thread.index = '${thread.index}'\n}"
11401b654882SGreg Clayton     "{thread.name = '${thread.name}'\n}"
11411b654882SGreg Clayton     "{thread.queue = '${thread.queue}'\n}"
11421b654882SGreg Clayton     "{thread.stop-reason = '${thread.stop-reason}'\n}"
11431b654882SGreg Clayton     "{target.arch = '${target.arch}'\n}"
11441b654882SGreg Clayton     "{module.file.basename = '${module.file.basename}'\n}"
11451b654882SGreg Clayton     "{module.file.fullpath = '${module.file.fullpath}'\n}"
11461b654882SGreg Clayton     "{file.basename = '${file.basename}'\n}"
11471b654882SGreg Clayton     "{file.fullpath = '${file.fullpath}'\n}"
11481b654882SGreg Clayton     "{frame.index = '${frame.index}'\n}"
11491b654882SGreg Clayton     "{frame.pc = '${frame.pc}'\n}"
11501b654882SGreg Clayton     "{frame.sp = '${frame.sp}'\n}"
11511b654882SGreg Clayton     "{frame.fp = '${frame.fp}'\n}"
11521b654882SGreg Clayton     "{frame.flags = '${frame.flags}'\n}"
11531b654882SGreg Clayton     "{frame.reg.rdi = '${frame.reg.rdi}'\n}"
11541b654882SGreg Clayton     "{frame.reg.rip = '${frame.reg.rip}'\n}"
11551b654882SGreg Clayton     "{frame.reg.rsp = '${frame.reg.rsp}'\n}"
11561b654882SGreg Clayton     "{frame.reg.rbp = '${frame.reg.rbp}'\n}"
11571b654882SGreg Clayton     "{frame.reg.rflags = '${frame.reg.rflags}'\n}"
11581b654882SGreg Clayton     "{frame.reg.xmm0 = '${frame.reg.xmm0}'\n}"
11591b654882SGreg Clayton     "{frame.reg.carp = '${frame.reg.carp}'\n}"
11601b654882SGreg Clayton     "{function.id = '${function.id}'\n}"
11611b654882SGreg Clayton     "{function.name = '${function.name}'\n}"
1162ccbc08e6SGreg Clayton     "{function.name-with-args = '${function.name-with-args}'\n}"
11631b654882SGreg Clayton     "{function.addr-offset = '${function.addr-offset}'\n}"
11641b654882SGreg Clayton     "{function.line-offset = '${function.line-offset}'\n}"
11651b654882SGreg Clayton     "{function.pc-offset = '${function.pc-offset}'\n}"
11661b654882SGreg Clayton     "{line.file.basename = '${line.file.basename}'\n}"
11671b654882SGreg Clayton     "{line.file.fullpath = '${line.file.fullpath}'\n}"
11681b654882SGreg Clayton     "{line.number = '${line.number}'\n}"
11691b654882SGreg Clayton     "{line.start-addr = '${line.start-addr}'\n}"
11701b654882SGreg Clayton     "{line.end-addr = '${line.end-addr}'\n}"
11711b654882SGreg Clayton ;
11721b654882SGreg Clayton 
11731b654882SGreg Clayton     SymbolContext sc (frame->GetSymbolContext(eSymbolContextEverything));
11741b654882SGreg Clayton     ExecutionContext exe_ctx;
11750603aa9dSGreg Clayton     frame->CalculateExecutionContext(exe_ctx);
1176c3ce7f27SMichael Sartain     if (Debugger::FormatPrompt (prompt_format, &sc, &exe_ctx, &sc.line_entry.range.GetBaseAddress(), s))
11771b654882SGreg Clayton     {
11781b654882SGreg Clayton         printf("%s\n", s.GetData());
11791b654882SGreg Clayton     }
11801b654882SGreg Clayton     else
11811b654882SGreg Clayton     {
11821b654882SGreg Clayton         printf ("what we got: %s\n", s.GetData());
11831b654882SGreg Clayton     }
11841b654882SGreg Clayton }
11851b654882SGreg Clayton 
11869fc1944eSEnrico Granata static bool
11879fc1944eSEnrico Granata ScanFormatDescriptor (const char* var_name_begin,
11889fc1944eSEnrico Granata                       const char* var_name_end,
11899fc1944eSEnrico Granata                       const char** var_name_final,
11909fc1944eSEnrico Granata                       const char** percent_position,
11914d122c40SGreg Clayton                       Format* custom_format,
11929fc1944eSEnrico Granata                       ValueObject::ValueObjectRepresentationStyle* val_obj_display)
11939fc1944eSEnrico Granata {
11945160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
11959fc1944eSEnrico Granata     *percent_position = ::strchr(var_name_begin,'%');
11969fc1944eSEnrico Granata     if (!*percent_position || *percent_position > var_name_end)
1197e992a089SEnrico Granata     {
1198e992a089SEnrico Granata         if (log)
1199d228483dSEnrico Granata             log->Printf("[ScanFormatDescriptor] no format descriptor in string, skipping");
12009fc1944eSEnrico Granata         *var_name_final = var_name_end;
1201e992a089SEnrico Granata     }
12029fc1944eSEnrico Granata     else
12039fc1944eSEnrico Granata     {
12049fc1944eSEnrico Granata         *var_name_final = *percent_position;
120536aa5ae6SEnrico Granata         std::string format_name(*var_name_final+1, var_name_end-*var_name_final-1);
1206e992a089SEnrico Granata         if (log)
120768ae4117SEnrico Granata             log->Printf("[ScanFormatDescriptor] parsing %s as a format descriptor", format_name.c_str());
120836aa5ae6SEnrico Granata         if ( !FormatManager::GetFormatFromCString(format_name.c_str(),
12099fc1944eSEnrico Granata                                                   true,
12109fc1944eSEnrico Granata                                                   *custom_format) )
12119fc1944eSEnrico Granata         {
1212e992a089SEnrico Granata             if (log)
121368ae4117SEnrico Granata                 log->Printf("[ScanFormatDescriptor] %s is an unknown format", format_name.c_str());
121436aa5ae6SEnrico Granata 
121536aa5ae6SEnrico Granata             switch (format_name.front())
121636aa5ae6SEnrico Granata             {
121736aa5ae6SEnrico Granata                 case '@':             // if this is an @ sign, print ObjC description
121886cc9829SEnrico Granata                     *val_obj_display = ValueObject::eValueObjectRepresentationStyleLanguageSpecific;
121936aa5ae6SEnrico Granata                     break;
122036aa5ae6SEnrico Granata                 case 'V': // if this is a V, print the value using the default format
122186cc9829SEnrico Granata                     *val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
122236aa5ae6SEnrico Granata                     break;
122336aa5ae6SEnrico Granata                 case 'L': // if this is an L, print the location of the value
122486cc9829SEnrico Granata                     *val_obj_display = ValueObject::eValueObjectRepresentationStyleLocation;
122536aa5ae6SEnrico Granata                     break;
122636aa5ae6SEnrico Granata                 case 'S': // if this is an S, print the summary after all
122786cc9829SEnrico Granata                     *val_obj_display = ValueObject::eValueObjectRepresentationStyleSummary;
122836aa5ae6SEnrico Granata                     break;
122936aa5ae6SEnrico Granata                 case '#': // if this is a '#', print the number of children
123086cc9829SEnrico Granata                     *val_obj_display = ValueObject::eValueObjectRepresentationStyleChildrenCount;
123136aa5ae6SEnrico Granata                     break;
123236aa5ae6SEnrico Granata                 case 'T': // if this is a 'T', print the type
123386cc9829SEnrico Granata                     *val_obj_display = ValueObject::eValueObjectRepresentationStyleType;
123436aa5ae6SEnrico Granata                     break;
1235*2c75f11eSEnrico Granata                 case 'N': // if this is a 'N', print the name
1236*2c75f11eSEnrico Granata                     *val_obj_display = ValueObject::eValueObjectRepresentationStyleName;
1237*2c75f11eSEnrico Granata                     break;
1238*2c75f11eSEnrico Granata                 case '>': // if this is a '>', print the name
1239*2c75f11eSEnrico Granata                     *val_obj_display = ValueObject::eValueObjectRepresentationStyleExpressionPath;
1240*2c75f11eSEnrico Granata                     break;
124136aa5ae6SEnrico Granata                 default:
12425c42d8a8SJim Ingham                     if (log)
124336aa5ae6SEnrico Granata                         log->Printf("ScanFormatDescriptor] %s is an error, leaving the previous value alone", format_name.c_str());
124436aa5ae6SEnrico Granata                     break;
124536aa5ae6SEnrico Granata             }
12469fc1944eSEnrico Granata         }
12479fc1944eSEnrico Granata         // a good custom format tells us to print the value using it
12489fc1944eSEnrico Granata         else
1249e992a089SEnrico Granata         {
1250e992a089SEnrico Granata             if (log)
125168ae4117SEnrico Granata                 log->Printf("[ScanFormatDescriptor] will display value for this VO");
125286cc9829SEnrico Granata             *val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
1253e992a089SEnrico Granata         }
12549fc1944eSEnrico Granata     }
1255e992a089SEnrico Granata     if (log)
125668ae4117SEnrico Granata         log->Printf("[ScanFormatDescriptor] final format description outcome: custom_format = %d, val_obj_display = %d",
1257e992a089SEnrico Granata                     *custom_format,
1258e992a089SEnrico Granata                     *val_obj_display);
12599fc1944eSEnrico Granata     return true;
12609fc1944eSEnrico Granata }
12619fc1944eSEnrico Granata 
12629fc1944eSEnrico Granata static bool
12639fc1944eSEnrico Granata ScanBracketedRange (const char* var_name_begin,
12649fc1944eSEnrico Granata                     const char* var_name_end,
12659fc1944eSEnrico Granata                     const char* var_name_final,
12669fc1944eSEnrico Granata                     const char** open_bracket_position,
12679fc1944eSEnrico Granata                     const char** separator_position,
12689fc1944eSEnrico Granata                     const char** close_bracket_position,
12699fc1944eSEnrico Granata                     const char** var_name_final_if_array_range,
12709fc1944eSEnrico Granata                     int64_t* index_lower,
12719fc1944eSEnrico Granata                     int64_t* index_higher)
12729fc1944eSEnrico Granata {
12735160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
12749fc1944eSEnrico Granata     *open_bracket_position = ::strchr(var_name_begin,'[');
12759fc1944eSEnrico Granata     if (*open_bracket_position && *open_bracket_position < var_name_final)
12769fc1944eSEnrico Granata     {
12779fc1944eSEnrico Granata         *separator_position = ::strchr(*open_bracket_position,'-'); // might be NULL if this is a simple var[N] bitfield
12789fc1944eSEnrico Granata         *close_bracket_position = ::strchr(*open_bracket_position,']');
12799fc1944eSEnrico Granata         // as usual, we assume that [] will come before %
12809fc1944eSEnrico Granata         //printf("trying to expand a []\n");
12819fc1944eSEnrico Granata         *var_name_final_if_array_range = *open_bracket_position;
12829fc1944eSEnrico Granata         if (*close_bracket_position - *open_bracket_position == 1)
12839fc1944eSEnrico Granata         {
1284e992a089SEnrico Granata             if (log)
1285d228483dSEnrico Granata                 log->Printf("[ScanBracketedRange] '[]' detected.. going from 0 to end of data");
12869fc1944eSEnrico Granata             *index_lower = 0;
12879fc1944eSEnrico Granata         }
12889fc1944eSEnrico Granata         else if (*separator_position == NULL || *separator_position > var_name_end)
12899fc1944eSEnrico Granata         {
12909fc1944eSEnrico Granata             char *end = NULL;
12919fc1944eSEnrico Granata             *index_lower = ::strtoul (*open_bracket_position+1, &end, 0);
12929fc1944eSEnrico Granata             *index_higher = *index_lower;
1293e992a089SEnrico Granata             if (log)
1294d01b2953SDaniel Malea                 log->Printf("[ScanBracketedRange] [%" PRId64 "] detected, high index is same", *index_lower);
12959fc1944eSEnrico Granata         }
12969fc1944eSEnrico Granata         else if (*close_bracket_position && *close_bracket_position < var_name_end)
12979fc1944eSEnrico Granata         {
12989fc1944eSEnrico Granata             char *end = NULL;
12999fc1944eSEnrico Granata             *index_lower = ::strtoul (*open_bracket_position+1, &end, 0);
13009fc1944eSEnrico Granata             *index_higher = ::strtoul (*separator_position+1, &end, 0);
1301e992a089SEnrico Granata             if (log)
1302d01b2953SDaniel Malea                 log->Printf("[ScanBracketedRange] [%" PRId64 "-%" PRId64 "] detected", *index_lower, *index_higher);
13039fc1944eSEnrico Granata         }
13049fc1944eSEnrico Granata         else
1305e992a089SEnrico Granata         {
1306e992a089SEnrico Granata             if (log)
1307d228483dSEnrico Granata                 log->Printf("[ScanBracketedRange] expression is erroneous, cannot extract indices out of it");
13089fc1944eSEnrico Granata             return false;
1309e992a089SEnrico Granata         }
13109fc1944eSEnrico Granata         if (*index_lower > *index_higher && *index_higher > 0)
13119fc1944eSEnrico Granata         {
1312e992a089SEnrico Granata             if (log)
1313d228483dSEnrico Granata                 log->Printf("[ScanBracketedRange] swapping indices");
1314c7bece56SGreg Clayton             int64_t temp = *index_lower;
13159fc1944eSEnrico Granata             *index_lower = *index_higher;
13169fc1944eSEnrico Granata             *index_higher = temp;
13179fc1944eSEnrico Granata         }
13189fc1944eSEnrico Granata     }
1319e992a089SEnrico Granata     else if (log)
1320d228483dSEnrico Granata             log->Printf("[ScanBracketedRange] no bracketed range, skipping entirely");
13219fc1944eSEnrico Granata     return true;
13229fc1944eSEnrico Granata }
13239fc1944eSEnrico Granata 
13249fc1944eSEnrico Granata static ValueObjectSP
1325c482a192SEnrico Granata ExpandIndexedExpression (ValueObject* valobj,
1326c7bece56SGreg Clayton                          size_t index,
13279fc1944eSEnrico Granata                          StackFrame* frame,
1328fc7a7f3bSEnrico Granata                          bool deref_pointer)
13299fc1944eSEnrico Granata {
13305160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
1331fc7a7f3bSEnrico Granata     const char* ptr_deref_format = "[%d]";
1332599171adSEnrico Granata     std::string ptr_deref_buffer(10,0);
1333599171adSEnrico Granata     ::sprintf(&ptr_deref_buffer[0], ptr_deref_format, index);
1334e992a089SEnrico Granata     if (log)
1335599171adSEnrico Granata         log->Printf("[ExpandIndexedExpression] name to deref: %s",ptr_deref_buffer.c_str());
1336fc7a7f3bSEnrico Granata     const char* first_unparsed;
1337fc7a7f3bSEnrico Granata     ValueObject::GetValueForExpressionPathOptions options;
1338fc7a7f3bSEnrico Granata     ValueObject::ExpressionPathEndResultType final_value_type;
1339fc7a7f3bSEnrico Granata     ValueObject::ExpressionPathScanEndReason reason_to_stop;
134086cc9829SEnrico Granata     ValueObject::ExpressionPathAftermath what_next = (deref_pointer ? ValueObject::eExpressionPathAftermathDereference : ValueObject::eExpressionPathAftermathNothing);
1341599171adSEnrico Granata     ValueObjectSP item = valobj->GetValueForExpressionPath (ptr_deref_buffer.c_str(),
1342fc7a7f3bSEnrico Granata                                                           &first_unparsed,
1343fc7a7f3bSEnrico Granata                                                           &reason_to_stop,
1344fc7a7f3bSEnrico Granata                                                           &final_value_type,
1345fc7a7f3bSEnrico Granata                                                           options,
1346fc7a7f3bSEnrico Granata                                                           &what_next);
1347fc7a7f3bSEnrico Granata     if (!item)
1348fc7a7f3bSEnrico Granata     {
1349e992a089SEnrico Granata         if (log)
1350d228483dSEnrico Granata             log->Printf("[ExpandIndexedExpression] ERROR: unparsed portion = %s, why stopping = %d,"
1351e992a089SEnrico Granata                " final_value_type %d",
1352fc7a7f3bSEnrico Granata                first_unparsed, reason_to_stop, final_value_type);
1353fc7a7f3bSEnrico Granata     }
13549fc1944eSEnrico Granata     else
13559fc1944eSEnrico Granata     {
1356e992a089SEnrico Granata         if (log)
1357d228483dSEnrico Granata             log->Printf("[ExpandIndexedExpression] ALL RIGHT: unparsed portion = %s, why stopping = %d,"
1358e992a089SEnrico Granata                " final_value_type %d",
1359fc7a7f3bSEnrico Granata                first_unparsed, reason_to_stop, final_value_type);
13609fc1944eSEnrico Granata     }
13619fc1944eSEnrico Granata     return item;
13629fc1944eSEnrico Granata }
13639fc1944eSEnrico Granata 
1364c3ce7f27SMichael Sartain static bool
1365c3ce7f27SMichael Sartain FormatPromptRecurse
13661b654882SGreg Clayton (
13671b654882SGreg Clayton     const char *format,
13681b654882SGreg Clayton     const SymbolContext *sc,
13691b654882SGreg Clayton     const ExecutionContext *exe_ctx,
13701b654882SGreg Clayton     const Address *addr,
13711b654882SGreg Clayton     Stream &s,
13724becb37eSEnrico Granata     const char **end,
1373c482a192SEnrico Granata     ValueObject* valobj
13741b654882SGreg Clayton )
13751b654882SGreg Clayton {
1376c482a192SEnrico Granata     ValueObject* realvalobj = NULL; // makes it super-easy to parse pointers
13771b654882SGreg Clayton     bool success = true;
13781b654882SGreg Clayton     const char *p;
13795160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
1380c3ce7f27SMichael Sartain 
13811b654882SGreg Clayton     for (p = format; *p != '\0'; ++p)
13821b654882SGreg Clayton     {
1383c482a192SEnrico Granata         if (realvalobj)
13844becb37eSEnrico Granata         {
1385c482a192SEnrico Granata             valobj = realvalobj;
1386c482a192SEnrico Granata             realvalobj = NULL;
13874becb37eSEnrico Granata         }
13881b654882SGreg Clayton         size_t non_special_chars = ::strcspn (p, "${}\\");
13891b654882SGreg Clayton         if (non_special_chars > 0)
13901b654882SGreg Clayton         {
13911b654882SGreg Clayton             if (success)
13921b654882SGreg Clayton                 s.Write (p, non_special_chars);
13931b654882SGreg Clayton             p += non_special_chars;
13941b654882SGreg Clayton         }
13951b654882SGreg Clayton 
13961b654882SGreg Clayton         if (*p == '\0')
13971b654882SGreg Clayton         {
13981b654882SGreg Clayton             break;
13991b654882SGreg Clayton         }
14001b654882SGreg Clayton         else if (*p == '{')
14011b654882SGreg Clayton         {
14021b654882SGreg Clayton             // Start a new scope that must have everything it needs if it is to
14031b654882SGreg Clayton             // to make it into the final output stream "s". If you want to make
14041b654882SGreg Clayton             // a format that only prints out the function or symbol name if there
14051b654882SGreg Clayton             // is one in the symbol context you can use:
14061b654882SGreg Clayton             //      "{function =${function.name}}"
14071b654882SGreg Clayton             // The first '{' starts a new scope that end with the matching '}' at
14081b654882SGreg Clayton             // the end of the string. The contents "function =${function.name}"
14091b654882SGreg Clayton             // will then be evaluated and only be output if there is a function
14101b654882SGreg Clayton             // or symbol with a valid name.
14111b654882SGreg Clayton             StreamString sub_strm;
14121b654882SGreg Clayton 
14131b654882SGreg Clayton             ++p;  // Skip the '{'
14141b654882SGreg Clayton 
1415c3ce7f27SMichael Sartain             if (FormatPromptRecurse (p, sc, exe_ctx, addr, sub_strm, &p, valobj))
14161b654882SGreg Clayton             {
14171b654882SGreg Clayton                 // The stream had all it needed
14181b654882SGreg Clayton                 s.Write(sub_strm.GetData(), sub_strm.GetSize());
14191b654882SGreg Clayton             }
14201b654882SGreg Clayton             if (*p != '}')
14211b654882SGreg Clayton             {
14221b654882SGreg Clayton                 success = false;
14231b654882SGreg Clayton                 break;
14241b654882SGreg Clayton             }
14251b654882SGreg Clayton         }
14261b654882SGreg Clayton         else if (*p == '}')
14271b654882SGreg Clayton         {
14281b654882SGreg Clayton             // End of a enclosing scope
14291b654882SGreg Clayton             break;
14301b654882SGreg Clayton         }
14311b654882SGreg Clayton         else if (*p == '$')
14321b654882SGreg Clayton         {
14331b654882SGreg Clayton             // We have a prompt variable to print
14341b654882SGreg Clayton             ++p;
14351b654882SGreg Clayton             if (*p == '{')
14361b654882SGreg Clayton             {
14371b654882SGreg Clayton                 ++p;
14381b654882SGreg Clayton                 const char *var_name_begin = p;
14391b654882SGreg Clayton                 const char *var_name_end = ::strchr (p, '}');
14401b654882SGreg Clayton 
14411b654882SGreg Clayton                 if (var_name_end && var_name_begin < var_name_end)
14421b654882SGreg Clayton                 {
14431b654882SGreg Clayton                     // if we have already failed to parse, skip this variable
14441b654882SGreg Clayton                     if (success)
14451b654882SGreg Clayton                     {
14461b654882SGreg Clayton                         const char *cstr = NULL;
14471b654882SGreg Clayton                         Address format_addr;
14481b654882SGreg Clayton                         bool calculate_format_addr_function_offset = false;
14491b654882SGreg Clayton                         // Set reg_kind and reg_num to invalid values
14501b654882SGreg Clayton                         RegisterKind reg_kind = kNumRegisterKinds;
14511b654882SGreg Clayton                         uint32_t reg_num = LLDB_INVALID_REGNUM;
14521b654882SGreg Clayton                         FileSpec format_file_spec;
1453e0d378b3SGreg Clayton                         const RegisterInfo *reg_info = NULL;
14541b654882SGreg Clayton                         RegisterContext *reg_ctx = NULL;
14559fc1944eSEnrico Granata                         bool do_deref_pointer = false;
145686cc9829SEnrico Granata                         ValueObject::ExpressionPathScanEndReason reason_to_stop = ValueObject::eExpressionPathScanEndReasonEndOfString;
145786cc9829SEnrico Granata                         ValueObject::ExpressionPathEndResultType final_value_type = ValueObject::eExpressionPathEndResultTypePlain;
14581b654882SGreg Clayton 
14591b654882SGreg Clayton                         // Each variable must set success to true below...
14601b654882SGreg Clayton                         bool var_success = false;
14611b654882SGreg Clayton                         switch (var_name_begin[0])
14621b654882SGreg Clayton                         {
14634becb37eSEnrico Granata                         case '*':
14646f3533fbSEnrico Granata                         case 'v':
14656f3533fbSEnrico Granata                         case 's':
14664becb37eSEnrico Granata                             {
1467c482a192SEnrico Granata                                 if (!valobj)
146834132754SGreg Clayton                                     break;
14696f3533fbSEnrico Granata 
1470c3e320a7SEnrico Granata                                 if (log)
1471d228483dSEnrico Granata                                     log->Printf("[Debugger::FormatPrompt] initial string: %s",var_name_begin);
1472c3e320a7SEnrico Granata 
14736f3533fbSEnrico Granata                                 // check for *var and *svar
14746f3533fbSEnrico Granata                                 if (*var_name_begin == '*')
14756f3533fbSEnrico Granata                                 {
14769fc1944eSEnrico Granata                                     do_deref_pointer = true;
14779fc1944eSEnrico Granata                                     var_name_begin++;
1478c3e320a7SEnrico Granata                                     if (log)
147968ae4117SEnrico Granata                                         log->Printf("[Debugger::FormatPrompt] found a deref, new string is: %s",var_name_begin);
148068ae4117SEnrico Granata                                 }
1481c3e320a7SEnrico Granata 
14826f3533fbSEnrico Granata                                 if (*var_name_begin == 's')
14834becb37eSEnrico Granata                                 {
1484c5bc412cSEnrico Granata                                     if (!valobj->IsSynthetic())
148586cc9829SEnrico Granata                                         valobj = valobj->GetSyntheticValue().get();
148686cc9829SEnrico Granata                                     if (!valobj)
148786cc9829SEnrico Granata                                         break;
14886f3533fbSEnrico Granata                                     var_name_begin++;
1489c3e320a7SEnrico Granata                                     if (log)
149068ae4117SEnrico Granata                                         log->Printf("[Debugger::FormatPrompt] found a synthetic, new string is: %s",var_name_begin);
149168ae4117SEnrico Granata                                 }
1492c3e320a7SEnrico Granata 
14936f3533fbSEnrico Granata                                 // should be a 'v' by now
14946f3533fbSEnrico Granata                                 if (*var_name_begin != 'v')
14956f3533fbSEnrico Granata                                     break;
14966f3533fbSEnrico Granata 
1497c3e320a7SEnrico Granata                                 if (log)
149868ae4117SEnrico Granata                                     log->Printf("[Debugger::FormatPrompt] string I am working with: %s",var_name_begin);
1499c3e320a7SEnrico Granata 
1500fc7a7f3bSEnrico Granata                                 ValueObject::ExpressionPathAftermath what_next = (do_deref_pointer ?
150186cc9829SEnrico Granata                                                                                   ValueObject::eExpressionPathAftermathDereference : ValueObject::eExpressionPathAftermathNothing);
1502fc7a7f3bSEnrico Granata                                 ValueObject::GetValueForExpressionPathOptions options;
15038c9d3560SEnrico Granata                                 options.DontCheckDotVsArrowSyntax().DoAllowBitfieldSyntax().DoAllowFragileIVar().DoAllowSyntheticChildren();
150486cc9829SEnrico Granata                                 ValueObject::ValueObjectRepresentationStyle val_obj_display = ValueObject::eValueObjectRepresentationStyleSummary;
150534132754SGreg Clayton                                 ValueObject* target = NULL;
15064d122c40SGreg Clayton                                 Format custom_format = eFormatInvalid;
150734132754SGreg Clayton                                 const char* var_name_final = NULL;
15089fc1944eSEnrico Granata                                 const char* var_name_final_if_array_range = NULL;
150934132754SGreg Clayton                                 const char* close_bracket_position = NULL;
151034132754SGreg Clayton                                 int64_t index_lower = -1;
151134132754SGreg Clayton                                 int64_t index_higher = -1;
15129fc1944eSEnrico Granata                                 bool is_array_range = false;
1513fc7a7f3bSEnrico Granata                                 const char* first_unparsed;
151485933ed4SEnrico Granata                                 bool was_plain_var = false;
151585933ed4SEnrico Granata                                 bool was_var_format = false;
1516a777dc2aSEnrico Granata                                 bool was_var_indexed = false;
1517fc7a7f3bSEnrico Granata 
1518c482a192SEnrico Granata                                 if (!valobj) break;
1519c482a192SEnrico Granata                                 // simplest case ${var}, just print valobj's value
15209fc1944eSEnrico Granata                                 if (::strncmp (var_name_begin, "var}", strlen("var}")) == 0)
15210a3958e0SEnrico Granata                                 {
152285933ed4SEnrico Granata                                     was_plain_var = true;
1523c482a192SEnrico Granata                                     target = valobj;
152486cc9829SEnrico Granata                                     val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
15250a3958e0SEnrico Granata                                 }
15269fc1944eSEnrico Granata                                 else if (::strncmp(var_name_begin,"var%",strlen("var%")) == 0)
15279fc1944eSEnrico Granata                                 {
152885933ed4SEnrico Granata                                     was_var_format = true;
15299fc1944eSEnrico Granata                                     // this is a variable with some custom format applied to it
15309fc1944eSEnrico Granata                                     const char* percent_position;
1531c482a192SEnrico Granata                                     target = valobj;
153286cc9829SEnrico Granata                                     val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
15339fc1944eSEnrico Granata                                     ScanFormatDescriptor (var_name_begin,
15349fc1944eSEnrico Granata                                                           var_name_end,
15359fc1944eSEnrico Granata                                                           &var_name_final,
15369fc1944eSEnrico Granata                                                           &percent_position,
15379fc1944eSEnrico Granata                                                           &custom_format,
15389fc1944eSEnrico Granata                                                           &val_obj_display);
15390a3958e0SEnrico Granata                                 }
15409fc1944eSEnrico Granata                                     // this is ${var.something} or multiple .something nested
15419fc1944eSEnrico Granata                                 else if (::strncmp (var_name_begin, "var", strlen("var")) == 0)
15429fc1944eSEnrico Granata                                 {
1543a777dc2aSEnrico Granata                                     if (::strncmp(var_name_begin, "var[", strlen("var[")) == 0)
1544a777dc2aSEnrico Granata                                         was_var_indexed = true;
15459fc1944eSEnrico Granata                                     const char* percent_position;
15469fc1944eSEnrico Granata                                     ScanFormatDescriptor (var_name_begin,
15479fc1944eSEnrico Granata                                                           var_name_end,
15489fc1944eSEnrico Granata                                                           &var_name_final,
15499fc1944eSEnrico Granata                                                           &percent_position,
15509fc1944eSEnrico Granata                                                           &custom_format,
15519fc1944eSEnrico Granata                                                           &val_obj_display);
15529fc1944eSEnrico Granata 
15539fc1944eSEnrico Granata                                     const char* open_bracket_position;
15549fc1944eSEnrico Granata                                     const char* separator_position;
15559fc1944eSEnrico Granata                                     ScanBracketedRange (var_name_begin,
15569fc1944eSEnrico Granata                                                         var_name_end,
15579fc1944eSEnrico Granata                                                         var_name_final,
15589fc1944eSEnrico Granata                                                         &open_bracket_position,
15599fc1944eSEnrico Granata                                                         &separator_position,
15609fc1944eSEnrico Granata                                                         &close_bracket_position,
15619fc1944eSEnrico Granata                                                         &var_name_final_if_array_range,
15629fc1944eSEnrico Granata                                                         &index_lower,
15639fc1944eSEnrico Granata                                                         &index_higher);
15649fc1944eSEnrico Granata 
15659fc1944eSEnrico Granata                                     Error error;
15669fc1944eSEnrico Granata 
1567599171adSEnrico Granata                                     std::string expr_path(var_name_final-var_name_begin-1,0);
1568599171adSEnrico Granata                                     memcpy(&expr_path[0], var_name_begin+3,var_name_final-var_name_begin-3);
1569fc7a7f3bSEnrico Granata 
1570e992a089SEnrico Granata                                     if (log)
1571599171adSEnrico Granata                                         log->Printf("[Debugger::FormatPrompt] symbol to expand: %s",expr_path.c_str());
1572fc7a7f3bSEnrico Granata 
1573599171adSEnrico Granata                                     target = valobj->GetValueForExpressionPath(expr_path.c_str(),
1574fc7a7f3bSEnrico Granata                                                                              &first_unparsed,
1575fc7a7f3bSEnrico Granata                                                                              &reason_to_stop,
1576fc7a7f3bSEnrico Granata                                                                              &final_value_type,
1577fc7a7f3bSEnrico Granata                                                                              options,
1578fc7a7f3bSEnrico Granata                                                                              &what_next).get();
1579fc7a7f3bSEnrico Granata 
1580fc7a7f3bSEnrico Granata                                     if (!target)
15819fc1944eSEnrico Granata                                     {
1582e992a089SEnrico Granata                                         if (log)
1583d228483dSEnrico Granata                                             log->Printf("[Debugger::FormatPrompt] ERROR: unparsed portion = %s, why stopping = %d,"
1584e992a089SEnrico Granata                                                " final_value_type %d",
1585fc7a7f3bSEnrico Granata                                                first_unparsed, reason_to_stop, final_value_type);
1586fc7a7f3bSEnrico Granata                                         break;
15870a3958e0SEnrico Granata                                     }
1588a7187d00SEnrico Granata                                     else
1589fc7a7f3bSEnrico Granata                                     {
1590e992a089SEnrico Granata                                         if (log)
1591d228483dSEnrico Granata                                             log->Printf("[Debugger::FormatPrompt] ALL RIGHT: unparsed portion = %s, why stopping = %d,"
1592e992a089SEnrico Granata                                                " final_value_type %d",
1593fc7a7f3bSEnrico Granata                                                first_unparsed, reason_to_stop, final_value_type);
1594a7187d00SEnrico Granata                                     }
15950a3958e0SEnrico Granata                                 }
15960a3958e0SEnrico Granata                                 else
15970a3958e0SEnrico Granata                                     break;
15989fc1944eSEnrico Granata 
159986cc9829SEnrico Granata                                 is_array_range = (final_value_type == ValueObject::eExpressionPathEndResultTypeBoundedRange ||
160086cc9829SEnrico Granata                                                   final_value_type == ValueObject::eExpressionPathEndResultTypeUnboundedRange);
1601fc7a7f3bSEnrico Granata 
160286cc9829SEnrico Granata                                 do_deref_pointer = (what_next == ValueObject::eExpressionPathAftermathDereference);
1603fc7a7f3bSEnrico Granata 
1604a7187d00SEnrico Granata                                 if (do_deref_pointer && !is_array_range)
16050a3958e0SEnrico Granata                                 {
16069fc1944eSEnrico Granata                                     // I have not deref-ed yet, let's do it
16079fc1944eSEnrico Granata                                     // this happens when we are not going through GetValueForVariableExpressionPath
16089fc1944eSEnrico Granata                                     // to get to the target ValueObject
16099fc1944eSEnrico Granata                                     Error error;
16109fc1944eSEnrico Granata                                     target = target->Dereference(error).get();
1611dc940730SEnrico Granata                                     if (error.Fail())
1612dc940730SEnrico Granata                                     {
1613dc940730SEnrico Granata                                         if (log)
1614d228483dSEnrico Granata                                             log->Printf("[Debugger::FormatPrompt] ERROR: %s\n", error.AsCString("unknown")); \
1615dc940730SEnrico Granata                                         break;
1616dc940730SEnrico Granata                                     }
16179fc1944eSEnrico Granata                                     do_deref_pointer = false;
16180a3958e0SEnrico Granata                                 }
16190a3958e0SEnrico Granata 
1620a777dc2aSEnrico Granata                                 // <rdar://problem/11338654>
1621a777dc2aSEnrico Granata                                 // we do not want to use the summary for a bitfield of type T:n
1622a777dc2aSEnrico Granata                                 // if we were originally dealing with just a T - that would get
1623a777dc2aSEnrico Granata                                 // us into an endless recursion
1624a777dc2aSEnrico Granata                                 if (target->IsBitfield() && was_var_indexed)
1625a777dc2aSEnrico Granata                                 {
1626a777dc2aSEnrico Granata                                     // TODO: check for a (T:n)-specific summary - we should still obey that
1627a777dc2aSEnrico Granata                                     StreamString bitfield_name;
1628a777dc2aSEnrico Granata                                     bitfield_name.Printf("%s:%d", target->GetTypeName().AsCString(), target->GetBitfieldBitSize());
1629a777dc2aSEnrico Granata                                     lldb::TypeNameSpecifierImplSP type_sp(new TypeNameSpecifierImpl(bitfield_name.GetData(),false));
1630a777dc2aSEnrico Granata                                     if (!DataVisualization::GetSummaryForType(type_sp))
1631a777dc2aSEnrico Granata                                         val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
1632a777dc2aSEnrico Granata                                 }
1633a777dc2aSEnrico Granata 
163485933ed4SEnrico Granata                                 // TODO use flags for these
16354ef877f5SGreg Clayton                                 bool is_array = ClangASTContext::IsArrayType(target->GetClangType(), NULL, NULL, NULL);
1636f4efecd9SEnrico Granata                                 bool is_pointer = ClangASTContext::IsPointerType(target->GetClangType());
163785933ed4SEnrico Granata                                 bool is_aggregate = ClangASTContext::IsAggregateType(target->GetClangType());
1638f4efecd9SEnrico Granata 
163986cc9829SEnrico Granata                                 if ((is_array || is_pointer) && (!is_array_range) && val_obj_display == ValueObject::eValueObjectRepresentationStyleValue) // this should be wrong, but there are some exceptions
1640f4efecd9SEnrico Granata                                 {
164185933ed4SEnrico Granata                                     StreamString str_temp;
1642e992a089SEnrico Granata                                     if (log)
1643d228483dSEnrico Granata                                         log->Printf("[Debugger::FormatPrompt] I am into array || pointer && !range");
1644d64d0bc0SEnrico Granata 
16455088c486SGreg Clayton                                     if (target->HasSpecialPrintableRepresentation(val_obj_display, custom_format))
1646d64d0bc0SEnrico Granata                                     {
1647f4efecd9SEnrico Granata                                         // try to use the special cases
164885933ed4SEnrico Granata                                         var_success = target->DumpPrintableRepresentation(str_temp,
164985933ed4SEnrico Granata                                                                                           val_obj_display,
165085933ed4SEnrico Granata                                                                                           custom_format);
1651e992a089SEnrico Granata                                         if (log)
1652d228483dSEnrico Granata                                             log->Printf("[Debugger::FormatPrompt] special cases did%s match", var_success ? "" : "n't");
1653d64d0bc0SEnrico Granata 
1654d64d0bc0SEnrico Granata                                         // should not happen
16555088c486SGreg Clayton                                         if (var_success)
165685933ed4SEnrico Granata                                             s << str_temp.GetData();
1657d64d0bc0SEnrico Granata                                         var_success = true;
1658d64d0bc0SEnrico Granata                                         break;
1659d64d0bc0SEnrico Granata                                     }
1660d64d0bc0SEnrico Granata                                     else
1661d64d0bc0SEnrico Granata                                     {
166288da35f8SEnrico Granata                                         if (was_plain_var) // if ${var}
1663d64d0bc0SEnrico Granata                                         {
1664d64d0bc0SEnrico Granata                                             s << target->GetTypeName() << " @ " << target->GetLocationAsCString();
1665d64d0bc0SEnrico Granata                                         }
166688da35f8SEnrico Granata                                         else if (is_pointer) // if pointer, value is the address stored
166788da35f8SEnrico Granata                                         {
166823f59509SGreg Clayton                                             target->DumpPrintableRepresentation (s,
166988da35f8SEnrico Granata                                                                                  val_obj_display,
167086cc9829SEnrico Granata                                                                                  custom_format,
167186cc9829SEnrico Granata                                                                                  ValueObject::ePrintableRepresentationSpecialCasesDisable);
167288da35f8SEnrico Granata                                         }
1673d64d0bc0SEnrico Granata                                         var_success = true;
1674d64d0bc0SEnrico Granata                                         break;
1675d64d0bc0SEnrico Granata                                     }
1676d64d0bc0SEnrico Granata                                 }
1677d64d0bc0SEnrico Granata 
1678d64d0bc0SEnrico Granata                                 // if directly trying to print ${var}, and this is an aggregate, display a nice
1679d64d0bc0SEnrico Granata                                 // type @ location message
1680d64d0bc0SEnrico Granata                                 if (is_aggregate && was_plain_var)
1681d64d0bc0SEnrico Granata                                 {
1682d64d0bc0SEnrico Granata                                     s << target->GetTypeName() << " @ " << target->GetLocationAsCString();
1683d64d0bc0SEnrico Granata                                     var_success = true;
168485933ed4SEnrico Granata                                     break;
168585933ed4SEnrico Granata                                 }
168685933ed4SEnrico Granata 
1687d64d0bc0SEnrico Granata                                 // if directly trying to print ${var%V}, and this is an aggregate, do not let the user do it
168886cc9829SEnrico Granata                                 if (is_aggregate && ((was_var_format && val_obj_display == ValueObject::eValueObjectRepresentationStyleValue)))
168985933ed4SEnrico Granata                                 {
169085933ed4SEnrico Granata                                     s << "<invalid use of aggregate type>";
169185933ed4SEnrico Granata                                     var_success = true;
1692f4efecd9SEnrico Granata                                     break;
1693f4efecd9SEnrico Granata                                 }
1694f4efecd9SEnrico Granata 
16959fc1944eSEnrico Granata                                 if (!is_array_range)
1696e992a089SEnrico Granata                                 {
1697e992a089SEnrico Granata                                     if (log)
1698d228483dSEnrico Granata                                         log->Printf("[Debugger::FormatPrompt] dumping ordinary printable output");
16999fc1944eSEnrico Granata                                     var_success = target->DumpPrintableRepresentation(s,val_obj_display, custom_format);
1700e992a089SEnrico Granata                                 }
17019fc1944eSEnrico Granata                                 else
17029fc1944eSEnrico Granata                                 {
1703e992a089SEnrico Granata                                     if (log)
1704d228483dSEnrico Granata                                         log->Printf("[Debugger::FormatPrompt] checking if I can handle as array");
17059fc1944eSEnrico Granata                                     if (!is_array && !is_pointer)
17069fc1944eSEnrico Granata                                         break;
1707e992a089SEnrico Granata                                     if (log)
1708d228483dSEnrico Granata                                         log->Printf("[Debugger::FormatPrompt] handle as array");
1709fc7a7f3bSEnrico Granata                                     const char* special_directions = NULL;
1710fc7a7f3bSEnrico Granata                                     StreamString special_directions_writer;
17110a3958e0SEnrico Granata                                     if (close_bracket_position && (var_name_end-close_bracket_position > 1))
17120a3958e0SEnrico Granata                                     {
1713fc7a7f3bSEnrico Granata                                         ConstString additional_data;
1714fc7a7f3bSEnrico Granata                                         additional_data.SetCStringWithLength(close_bracket_position+1, var_name_end-close_bracket_position-1);
1715fc7a7f3bSEnrico Granata                                         special_directions_writer.Printf("${%svar%s}",
1716fc7a7f3bSEnrico Granata                                                                          do_deref_pointer ? "*" : "",
1717fc7a7f3bSEnrico Granata                                                                          additional_data.GetCString());
1718fc7a7f3bSEnrico Granata                                         special_directions = special_directions_writer.GetData();
17190a3958e0SEnrico Granata                                     }
17200a3958e0SEnrico Granata 
17210a3958e0SEnrico Granata                                     // let us display items index_lower thru index_higher of this array
17220a3958e0SEnrico Granata                                     s.PutChar('[');
17230a3958e0SEnrico Granata                                     var_success = true;
17240a3958e0SEnrico Granata 
17259fc1944eSEnrico Granata                                     if (index_higher < 0)
1726c482a192SEnrico Granata                                         index_higher = valobj->GetNumChildren() - 1;
17270a3958e0SEnrico Granata 
1728cc4d0146SGreg Clayton                                     uint32_t max_num_children = target->GetTargetSP()->GetMaximumNumberOfChildrenToDisplay();
172922c55d18SEnrico Granata 
17300a3958e0SEnrico Granata                                     for (;index_lower<=index_higher;index_lower++)
17310a3958e0SEnrico Granata                                     {
1732fc7a7f3bSEnrico Granata                                         ValueObject* item = ExpandIndexedExpression (target,
17339fc1944eSEnrico Granata                                                                                      index_lower,
1734c14ee32dSGreg Clayton                                                                                      exe_ctx->GetFramePtr(),
1735fc7a7f3bSEnrico Granata                                                                                      false).get();
17360a3958e0SEnrico Granata 
1737fc7a7f3bSEnrico Granata                                         if (!item)
1738fc7a7f3bSEnrico Granata                                         {
1739e992a089SEnrico Granata                                             if (log)
1740d01b2953SDaniel Malea                                                 log->Printf("[Debugger::FormatPrompt] ERROR in getting child item at index %" PRId64, index_lower);
1741fc7a7f3bSEnrico Granata                                         }
1742fc7a7f3bSEnrico Granata                                         else
1743fc7a7f3bSEnrico Granata                                         {
1744e992a089SEnrico Granata                                             if (log)
1745d228483dSEnrico Granata                                                 log->Printf("[Debugger::FormatPrompt] special_directions for child item: %s",special_directions);
1746fc7a7f3bSEnrico Granata                                         }
1747fc7a7f3bSEnrico Granata 
17480a3958e0SEnrico Granata                                         if (!special_directions)
17499fc1944eSEnrico Granata                                             var_success &= item->DumpPrintableRepresentation(s,val_obj_display, custom_format);
17500a3958e0SEnrico Granata                                         else
1751c3ce7f27SMichael Sartain                                             var_success &= FormatPromptRecurse(special_directions, sc, exe_ctx, addr, s, NULL, item);
17520a3958e0SEnrico Granata 
175322c55d18SEnrico Granata                                         if (--max_num_children == 0)
175422c55d18SEnrico Granata                                         {
175522c55d18SEnrico Granata                                             s.PutCString(", ...");
175622c55d18SEnrico Granata                                             break;
175722c55d18SEnrico Granata                                         }
175822c55d18SEnrico Granata 
17590a3958e0SEnrico Granata                                         if (index_lower < index_higher)
17600a3958e0SEnrico Granata                                             s.PutChar(',');
17610a3958e0SEnrico Granata                                     }
17620a3958e0SEnrico Granata                                     s.PutChar(']');
17634becb37eSEnrico Granata                                 }
17644becb37eSEnrico Granata                             }
176534132754SGreg Clayton                             break;
17661b654882SGreg Clayton                         case 'a':
17671b654882SGreg Clayton                             if (::strncmp (var_name_begin, "addr}", strlen("addr}")) == 0)
17681b654882SGreg Clayton                             {
17691b654882SGreg Clayton                                 if (addr && addr->IsValid())
17701b654882SGreg Clayton                                 {
17711b654882SGreg Clayton                                     var_success = true;
17721b654882SGreg Clayton                                     format_addr = *addr;
17731b654882SGreg Clayton                                 }
17741b654882SGreg Clayton                             }
17751b654882SGreg Clayton                             break;
17761b654882SGreg Clayton 
17771b654882SGreg Clayton                         case 'p':
17781b654882SGreg Clayton                             if (::strncmp (var_name_begin, "process.", strlen("process.")) == 0)
17791b654882SGreg Clayton                             {
1780c14ee32dSGreg Clayton                                 if (exe_ctx)
1781c14ee32dSGreg Clayton                                 {
1782c14ee32dSGreg Clayton                                     Process *process = exe_ctx->GetProcessPtr();
1783c14ee32dSGreg Clayton                                     if (process)
17841b654882SGreg Clayton                                     {
17851b654882SGreg Clayton                                         var_name_begin += ::strlen ("process.");
17861b654882SGreg Clayton                                         if (::strncmp (var_name_begin, "id}", strlen("id}")) == 0)
17871b654882SGreg Clayton                                         {
1788d01b2953SDaniel Malea                                             s.Printf("%" PRIu64, process->GetID());
17891b654882SGreg Clayton                                             var_success = true;
17901b654882SGreg Clayton                                         }
17911b654882SGreg Clayton                                         else if ((::strncmp (var_name_begin, "name}", strlen("name}")) == 0) ||
17921b654882SGreg Clayton                                                  (::strncmp (var_name_begin, "file.basename}", strlen("file.basename}")) == 0) ||
17931b654882SGreg Clayton                                                  (::strncmp (var_name_begin, "file.fullpath}", strlen("file.fullpath}")) == 0))
17941b654882SGreg Clayton                                         {
1795c14ee32dSGreg Clayton                                             Module *exe_module = process->GetTarget().GetExecutableModulePointer();
1796aa149cbdSGreg Clayton                                             if (exe_module)
17971b654882SGreg Clayton                                             {
17981b654882SGreg Clayton                                                 if (var_name_begin[0] == 'n' || var_name_begin[5] == 'f')
17991b654882SGreg Clayton                                                 {
1800aa149cbdSGreg Clayton                                                     format_file_spec.GetFilename() = exe_module->GetFileSpec().GetFilename();
18011b654882SGreg Clayton                                                     var_success = format_file_spec;
18021b654882SGreg Clayton                                                 }
18031b654882SGreg Clayton                                                 else
18041b654882SGreg Clayton                                                 {
1805aa149cbdSGreg Clayton                                                     format_file_spec = exe_module->GetFileSpec();
18061b654882SGreg Clayton                                                     var_success = format_file_spec;
18071b654882SGreg Clayton                                                 }
18081b654882SGreg Clayton                                             }
18091b654882SGreg Clayton                                         }
1810aad8e480SEnrico Granata                                         else if (::strncmp(var_name_begin, "script:", strlen("script:")) == 0)
1811aad8e480SEnrico Granata                                         {
1812aad8e480SEnrico Granata                                             var_name_begin += ::strlen("script:");
1813aad8e480SEnrico Granata                                             std::string script_name(var_name_begin,var_name_end);
1814aad8e480SEnrico Granata                                             ScriptInterpreter* script_interpreter = process->GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
1815aad8e480SEnrico Granata                                             if (script_interpreter)
1816aad8e480SEnrico Granata                                             {
1817aad8e480SEnrico Granata                                                 std::string script_output;
1818aad8e480SEnrico Granata                                                 Error script_error;
1819aad8e480SEnrico Granata                                                 if (script_interpreter->RunScriptFormatKeyword(script_name.c_str(), process,script_output,script_error) && script_error.Success())
1820aad8e480SEnrico Granata                                                 {
1821aad8e480SEnrico Granata                                                     s.Printf("%s", script_output.c_str());
1822aad8e480SEnrico Granata                                                     var_success = true;
1823aad8e480SEnrico Granata                                                 }
1824aad8e480SEnrico Granata                                                 else
1825aad8e480SEnrico Granata                                                     s.Printf("<error: %s>",script_error.AsCString());
1826aad8e480SEnrico Granata                                             }
1827aad8e480SEnrico Granata                                         }
18281b654882SGreg Clayton                                     }
18291b654882SGreg Clayton                                 }
1830c14ee32dSGreg Clayton                             }
18311b654882SGreg Clayton                             break;
18321b654882SGreg Clayton 
18331b654882SGreg Clayton                         case 't':
18341b654882SGreg Clayton                             if (::strncmp (var_name_begin, "thread.", strlen("thread.")) == 0)
18351b654882SGreg Clayton                             {
1836c14ee32dSGreg Clayton                                 if (exe_ctx)
1837c14ee32dSGreg Clayton                                 {
1838c14ee32dSGreg Clayton                                     Thread *thread = exe_ctx->GetThreadPtr();
1839c14ee32dSGreg Clayton                                     if (thread)
18401b654882SGreg Clayton                                     {
18411b654882SGreg Clayton                                         var_name_begin += ::strlen ("thread.");
18421b654882SGreg Clayton                                         if (::strncmp (var_name_begin, "id}", strlen("id}")) == 0)
18431b654882SGreg Clayton                                         {
1844d01b2953SDaniel Malea                                             s.Printf("0x%4.4" PRIx64, thread->GetID());
18451b654882SGreg Clayton                                             var_success = true;
18461b654882SGreg Clayton                                         }
1847160c9d81SGreg Clayton                                         else if (::strncmp (var_name_begin, "protocol_id}", strlen("protocol_id}")) == 0)
1848160c9d81SGreg Clayton                                         {
1849160c9d81SGreg Clayton                                             s.Printf("0x%4.4" PRIx64, thread->GetProtocolID());
1850160c9d81SGreg Clayton                                             var_success = true;
1851160c9d81SGreg Clayton                                         }
18521b654882SGreg Clayton                                         else if (::strncmp (var_name_begin, "index}", strlen("index}")) == 0)
18531b654882SGreg Clayton                                         {
1854c14ee32dSGreg Clayton                                             s.Printf("%u", thread->GetIndexID());
18551b654882SGreg Clayton                                             var_success = true;
18561b654882SGreg Clayton                                         }
18571b654882SGreg Clayton                                         else if (::strncmp (var_name_begin, "name}", strlen("name}")) == 0)
18581b654882SGreg Clayton                                         {
1859c14ee32dSGreg Clayton                                             cstr = thread->GetName();
18601b654882SGreg Clayton                                             var_success = cstr && cstr[0];
18611b654882SGreg Clayton                                             if (var_success)
18621b654882SGreg Clayton                                                 s.PutCString(cstr);
18631b654882SGreg Clayton                                         }
18641b654882SGreg Clayton                                         else if (::strncmp (var_name_begin, "queue}", strlen("queue}")) == 0)
18651b654882SGreg Clayton                                         {
1866c14ee32dSGreg Clayton                                             cstr = thread->GetQueueName();
18671b654882SGreg Clayton                                             var_success = cstr && cstr[0];
18681b654882SGreg Clayton                                             if (var_success)
18691b654882SGreg Clayton                                                 s.PutCString(cstr);
18701b654882SGreg Clayton                                         }
18711b654882SGreg Clayton                                         else if (::strncmp (var_name_begin, "stop-reason}", strlen("stop-reason}")) == 0)
18721b654882SGreg Clayton                                         {
1873c14ee32dSGreg Clayton                                             StopInfoSP stop_info_sp = thread->GetStopInfo ();
18745d88a068SJim Ingham                                             if (stop_info_sp && stop_info_sp->IsValid())
18751b654882SGreg Clayton                                             {
1876b15bfc75SJim Ingham                                                 cstr = stop_info_sp->GetDescription();
18771b654882SGreg Clayton                                                 if (cstr && cstr[0])
18781b654882SGreg Clayton                                                 {
18791b654882SGreg Clayton                                                     s.PutCString(cstr);
18801b654882SGreg Clayton                                                     var_success = true;
18811b654882SGreg Clayton                                                 }
18821b654882SGreg Clayton                                             }
18831b654882SGreg Clayton                                         }
188473ca05a2SJim Ingham                                         else if (::strncmp (var_name_begin, "return-value}", strlen("return-value}")) == 0)
188573ca05a2SJim Ingham                                         {
188673ca05a2SJim Ingham                                             StopInfoSP stop_info_sp = thread->GetStopInfo ();
18875d88a068SJim Ingham                                             if (stop_info_sp && stop_info_sp->IsValid())
188873ca05a2SJim Ingham                                             {
188973ca05a2SJim Ingham                                                 ValueObjectSP return_valobj_sp = StopInfo::GetReturnValueObject (stop_info_sp);
189073ca05a2SJim Ingham                                                 if (return_valobj_sp)
189173ca05a2SJim Ingham                                                 {
18929fb5ab55SEnrico Granata                                                     ValueObject::DumpValueObject (s, return_valobj_sp.get());
189373ca05a2SJim Ingham                                                     var_success = true;
189473ca05a2SJim Ingham                                                 }
189573ca05a2SJim Ingham                                             }
189673ca05a2SJim Ingham                                         }
1897aad8e480SEnrico Granata                                         else if (::strncmp(var_name_begin, "script:", strlen("script:")) == 0)
1898aad8e480SEnrico Granata                                         {
1899aad8e480SEnrico Granata                                             var_name_begin += ::strlen("script:");
1900aad8e480SEnrico Granata                                             std::string script_name(var_name_begin,var_name_end);
1901aad8e480SEnrico Granata                                             ScriptInterpreter* script_interpreter = thread->GetProcess()->GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
1902aad8e480SEnrico Granata                                             if (script_interpreter)
1903aad8e480SEnrico Granata                                             {
1904aad8e480SEnrico Granata                                                 std::string script_output;
1905aad8e480SEnrico Granata                                                 Error script_error;
1906aad8e480SEnrico Granata                                                 if (script_interpreter->RunScriptFormatKeyword(script_name.c_str(), thread,script_output,script_error) && script_error.Success())
1907aad8e480SEnrico Granata                                                 {
1908aad8e480SEnrico Granata                                                     s.Printf("%s", script_output.c_str());
1909aad8e480SEnrico Granata                                                     var_success = true;
1910aad8e480SEnrico Granata                                                 }
1911aad8e480SEnrico Granata                                                 else
1912aad8e480SEnrico Granata                                                     s.Printf("<error: %s>",script_error.AsCString());
1913aad8e480SEnrico Granata                                             }
1914aad8e480SEnrico Granata                                         }
191573ca05a2SJim Ingham                                     }
19161b654882SGreg Clayton                                 }
19171b654882SGreg Clayton                             }
19181b654882SGreg Clayton                             else if (::strncmp (var_name_begin, "target.", strlen("target.")) == 0)
19191b654882SGreg Clayton                             {
192067cc0636SGreg Clayton                                 // TODO: hookup properties
192167cc0636SGreg Clayton //                                if (!target_properties_sp)
192267cc0636SGreg Clayton //                                {
192367cc0636SGreg Clayton //                                    Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
192467cc0636SGreg Clayton //                                    if (target)
192567cc0636SGreg Clayton //                                        target_properties_sp = target->GetProperties();
192667cc0636SGreg Clayton //                                }
192767cc0636SGreg Clayton //
192867cc0636SGreg Clayton //                                if (target_properties_sp)
192967cc0636SGreg Clayton //                                {
193067cc0636SGreg Clayton //                                    var_name_begin += ::strlen ("target.");
193167cc0636SGreg Clayton //                                    const char *end_property = strchr(var_name_begin, '}');
193267cc0636SGreg Clayton //                                    if (end_property)
193367cc0636SGreg Clayton //                                    {
193467cc0636SGreg Clayton //                                        ConstString property_name(var_name_begin, end_property - var_name_begin);
193567cc0636SGreg Clayton //                                        std::string property_value (target_properties_sp->GetPropertyValue(property_name));
193667cc0636SGreg Clayton //                                        if (!property_value.empty())
193767cc0636SGreg Clayton //                                        {
193867cc0636SGreg Clayton //                                            s.PutCString (property_value.c_str());
193967cc0636SGreg Clayton //                                            var_success = true;
194067cc0636SGreg Clayton //                                        }
194167cc0636SGreg Clayton //                                    }
194267cc0636SGreg Clayton //                                }
19430603aa9dSGreg Clayton                                 Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
19440603aa9dSGreg Clayton                                 if (target)
19451b654882SGreg Clayton                                 {
19461b654882SGreg Clayton                                     var_name_begin += ::strlen ("target.");
19471b654882SGreg Clayton                                     if (::strncmp (var_name_begin, "arch}", strlen("arch}")) == 0)
19481b654882SGreg Clayton                                     {
19491b654882SGreg Clayton                                         ArchSpec arch (target->GetArchitecture ());
19501b654882SGreg Clayton                                         if (arch.IsValid())
19511b654882SGreg Clayton                                         {
195264195a2cSGreg Clayton                                             s.PutCString (arch.GetArchitectureName());
19531b654882SGreg Clayton                                             var_success = true;
19541b654882SGreg Clayton                                         }
19551b654882SGreg Clayton                                     }
1956aad8e480SEnrico Granata                                     else if (::strncmp(var_name_begin, "script:", strlen("script:")) == 0)
1957aad8e480SEnrico Granata                                     {
1958aad8e480SEnrico Granata                                         var_name_begin += ::strlen("script:");
1959aad8e480SEnrico Granata                                         std::string script_name(var_name_begin,var_name_end);
1960aad8e480SEnrico Granata                                         ScriptInterpreter* script_interpreter = target->GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
1961aad8e480SEnrico Granata                                         if (script_interpreter)
1962aad8e480SEnrico Granata                                         {
1963aad8e480SEnrico Granata                                             std::string script_output;
1964aad8e480SEnrico Granata                                             Error script_error;
1965aad8e480SEnrico Granata                                             if (script_interpreter->RunScriptFormatKeyword(script_name.c_str(), target,script_output,script_error) && script_error.Success())
1966aad8e480SEnrico Granata                                             {
1967aad8e480SEnrico Granata                                                 s.Printf("%s", script_output.c_str());
1968aad8e480SEnrico Granata                                                 var_success = true;
1969aad8e480SEnrico Granata                                             }
1970aad8e480SEnrico Granata                                             else
1971aad8e480SEnrico Granata                                                 s.Printf("<error: %s>",script_error.AsCString());
1972aad8e480SEnrico Granata                                         }
1973aad8e480SEnrico Granata                                     }
19741b654882SGreg Clayton                                 }
19751b654882SGreg Clayton                             }
19761b654882SGreg Clayton                             break;
19771b654882SGreg Clayton 
19781b654882SGreg Clayton 
19791b654882SGreg Clayton                         case 'm':
19801b654882SGreg Clayton                             if (::strncmp (var_name_begin, "module.", strlen("module.")) == 0)
19811b654882SGreg Clayton                             {
19820603aa9dSGreg Clayton                                 if (sc && sc->module_sp.get())
19831b654882SGreg Clayton                                 {
19840603aa9dSGreg Clayton                                     Module *module = sc->module_sp.get();
19851b654882SGreg Clayton                                     var_name_begin += ::strlen ("module.");
19861b654882SGreg Clayton 
19871b654882SGreg Clayton                                     if (::strncmp (var_name_begin, "file.", strlen("file.")) == 0)
19881b654882SGreg Clayton                                     {
19891b654882SGreg Clayton                                         if (module->GetFileSpec())
19901b654882SGreg Clayton                                         {
19911b654882SGreg Clayton                                             var_name_begin += ::strlen ("file.");
19921b654882SGreg Clayton 
19931b654882SGreg Clayton                                             if (::strncmp (var_name_begin, "basename}", strlen("basename}")) == 0)
19941b654882SGreg Clayton                                             {
19951b654882SGreg Clayton                                                 format_file_spec.GetFilename() = module->GetFileSpec().GetFilename();
19961b654882SGreg Clayton                                                 var_success = format_file_spec;
19971b654882SGreg Clayton                                             }
19981b654882SGreg Clayton                                             else if (::strncmp (var_name_begin, "fullpath}", strlen("fullpath}")) == 0)
19991b654882SGreg Clayton                                             {
20001b654882SGreg Clayton                                                 format_file_spec = module->GetFileSpec();
20011b654882SGreg Clayton                                                 var_success = format_file_spec;
20021b654882SGreg Clayton                                             }
20031b654882SGreg Clayton                                         }
20041b654882SGreg Clayton                                     }
20051b654882SGreg Clayton                                 }
20061b654882SGreg Clayton                             }
20071b654882SGreg Clayton                             break;
20081b654882SGreg Clayton 
20091b654882SGreg Clayton 
20101b654882SGreg Clayton                         case 'f':
20111b654882SGreg Clayton                             if (::strncmp (var_name_begin, "file.", strlen("file.")) == 0)
20121b654882SGreg Clayton                             {
20131b654882SGreg Clayton                                 if (sc && sc->comp_unit != NULL)
20141b654882SGreg Clayton                                 {
20151b654882SGreg Clayton                                     var_name_begin += ::strlen ("file.");
20161b654882SGreg Clayton 
20171b654882SGreg Clayton                                     if (::strncmp (var_name_begin, "basename}", strlen("basename}")) == 0)
20181b654882SGreg Clayton                                     {
20191b654882SGreg Clayton                                         format_file_spec.GetFilename() = sc->comp_unit->GetFilename();
20201b654882SGreg Clayton                                         var_success = format_file_spec;
20211b654882SGreg Clayton                                     }
20221b654882SGreg Clayton                                     else if (::strncmp (var_name_begin, "fullpath}", strlen("fullpath}")) == 0)
20231b654882SGreg Clayton                                     {
20241b654882SGreg Clayton                                         format_file_spec = *sc->comp_unit;
20251b654882SGreg Clayton                                         var_success = format_file_spec;
20261b654882SGreg Clayton                                     }
20271b654882SGreg Clayton                                 }
20281b654882SGreg Clayton                             }
20291b654882SGreg Clayton                             else if (::strncmp (var_name_begin, "frame.", strlen("frame.")) == 0)
20301b654882SGreg Clayton                             {
2031c14ee32dSGreg Clayton                                 if (exe_ctx)
2032c14ee32dSGreg Clayton                                 {
2033c14ee32dSGreg Clayton                                     StackFrame *frame = exe_ctx->GetFramePtr();
2034c14ee32dSGreg Clayton                                     if (frame)
20351b654882SGreg Clayton                                     {
20361b654882SGreg Clayton                                         var_name_begin += ::strlen ("frame.");
20371b654882SGreg Clayton                                         if (::strncmp (var_name_begin, "index}", strlen("index}")) == 0)
20381b654882SGreg Clayton                                         {
2039c14ee32dSGreg Clayton                                             s.Printf("%u", frame->GetFrameIndex());
20401b654882SGreg Clayton                                             var_success = true;
20411b654882SGreg Clayton                                         }
20421b654882SGreg Clayton                                         else if (::strncmp (var_name_begin, "pc}", strlen("pc}")) == 0)
20431b654882SGreg Clayton                                         {
20441b654882SGreg Clayton                                             reg_kind = eRegisterKindGeneric;
20451b654882SGreg Clayton                                             reg_num = LLDB_REGNUM_GENERIC_PC;
20461b654882SGreg Clayton                                             var_success = true;
20471b654882SGreg Clayton                                         }
20481b654882SGreg Clayton                                         else if (::strncmp (var_name_begin, "sp}", strlen("sp}")) == 0)
20491b654882SGreg Clayton                                         {
20501b654882SGreg Clayton                                             reg_kind = eRegisterKindGeneric;
20511b654882SGreg Clayton                                             reg_num = LLDB_REGNUM_GENERIC_SP;
20521b654882SGreg Clayton                                             var_success = true;
20531b654882SGreg Clayton                                         }
20541b654882SGreg Clayton                                         else if (::strncmp (var_name_begin, "fp}", strlen("fp}")) == 0)
20551b654882SGreg Clayton                                         {
20561b654882SGreg Clayton                                             reg_kind = eRegisterKindGeneric;
20571b654882SGreg Clayton                                             reg_num = LLDB_REGNUM_GENERIC_FP;
20581b654882SGreg Clayton                                             var_success = true;
20591b654882SGreg Clayton                                         }
20601b654882SGreg Clayton                                         else if (::strncmp (var_name_begin, "flags}", strlen("flags}")) == 0)
20611b654882SGreg Clayton                                         {
20621b654882SGreg Clayton                                             reg_kind = eRegisterKindGeneric;
20631b654882SGreg Clayton                                             reg_num = LLDB_REGNUM_GENERIC_FLAGS;
20641b654882SGreg Clayton                                             var_success = true;
20651b654882SGreg Clayton                                         }
20661b654882SGreg Clayton                                         else if (::strncmp (var_name_begin, "reg.", strlen ("reg.")) == 0)
20671b654882SGreg Clayton                                         {
2068c14ee32dSGreg Clayton                                             reg_ctx = frame->GetRegisterContext().get();
20691b654882SGreg Clayton                                             if (reg_ctx)
20701b654882SGreg Clayton                                             {
20711b654882SGreg Clayton                                                 var_name_begin += ::strlen ("reg.");
20721b654882SGreg Clayton                                                 if (var_name_begin < var_name_end)
20731b654882SGreg Clayton                                                 {
20741b654882SGreg Clayton                                                     std::string reg_name (var_name_begin, var_name_end);
20751b654882SGreg Clayton                                                     reg_info = reg_ctx->GetRegisterInfoByName (reg_name.c_str());
20761b654882SGreg Clayton                                                     if (reg_info)
20771b654882SGreg Clayton                                                         var_success = true;
20781b654882SGreg Clayton                                                 }
20791b654882SGreg Clayton                                             }
20801b654882SGreg Clayton                                         }
2081aad8e480SEnrico Granata                                         else if (::strncmp(var_name_begin, "script:", strlen("script:")) == 0)
2082aad8e480SEnrico Granata                                         {
2083aad8e480SEnrico Granata                                             var_name_begin += ::strlen("script:");
2084aad8e480SEnrico Granata                                             std::string script_name(var_name_begin,var_name_end);
2085aad8e480SEnrico Granata                                             ScriptInterpreter* script_interpreter = frame->GetThread()->GetProcess()->GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
2086aad8e480SEnrico Granata                                             if (script_interpreter)
2087aad8e480SEnrico Granata                                             {
2088aad8e480SEnrico Granata                                                 std::string script_output;
2089aad8e480SEnrico Granata                                                 Error script_error;
2090aad8e480SEnrico Granata                                                 if (script_interpreter->RunScriptFormatKeyword(script_name.c_str(), frame,script_output,script_error) && script_error.Success())
2091aad8e480SEnrico Granata                                                 {
2092aad8e480SEnrico Granata                                                     s.Printf("%s", script_output.c_str());
2093aad8e480SEnrico Granata                                                     var_success = true;
2094aad8e480SEnrico Granata                                                 }
2095aad8e480SEnrico Granata                                                 else
2096aad8e480SEnrico Granata                                                     s.Printf("<error: %s>",script_error.AsCString());
2097aad8e480SEnrico Granata                                             }
2098aad8e480SEnrico Granata                                         }
20991b654882SGreg Clayton                                     }
21001b654882SGreg Clayton                                 }
2101c14ee32dSGreg Clayton                             }
21021b654882SGreg Clayton                             else if (::strncmp (var_name_begin, "function.", strlen("function.")) == 0)
21031b654882SGreg Clayton                             {
21041b654882SGreg Clayton                                 if (sc && (sc->function != NULL || sc->symbol != NULL))
21051b654882SGreg Clayton                                 {
21061b654882SGreg Clayton                                     var_name_begin += ::strlen ("function.");
21071b654882SGreg Clayton                                     if (::strncmp (var_name_begin, "id}", strlen("id}")) == 0)
21081b654882SGreg Clayton                                     {
21091b654882SGreg Clayton                                         if (sc->function)
2110d01b2953SDaniel Malea                                             s.Printf("function{0x%8.8" PRIx64 "}", sc->function->GetID());
21111b654882SGreg Clayton                                         else
21121b654882SGreg Clayton                                             s.Printf("symbol[%u]", sc->symbol->GetID());
21131b654882SGreg Clayton 
21141b654882SGreg Clayton                                         var_success = true;
21151b654882SGreg Clayton                                     }
21161b654882SGreg Clayton                                     else if (::strncmp (var_name_begin, "name}", strlen("name}")) == 0)
21171b654882SGreg Clayton                                     {
21181b654882SGreg Clayton                                         if (sc->function)
21191b654882SGreg Clayton                                             cstr = sc->function->GetName().AsCString (NULL);
21201b654882SGreg Clayton                                         else if (sc->symbol)
21211b654882SGreg Clayton                                             cstr = sc->symbol->GetName().AsCString (NULL);
21221b654882SGreg Clayton                                         if (cstr)
21231b654882SGreg Clayton                                         {
21241b654882SGreg Clayton                                             s.PutCString(cstr);
21250d9c9934SGreg Clayton 
21260d9c9934SGreg Clayton                                             if (sc->block)
21270d9c9934SGreg Clayton                                             {
21280d9c9934SGreg Clayton                                                 Block *inline_block = sc->block->GetContainingInlinedBlock ();
21290d9c9934SGreg Clayton                                                 if (inline_block)
21300d9c9934SGreg Clayton                                                 {
21310d9c9934SGreg Clayton                                                     const InlineFunctionInfo *inline_info = sc->block->GetInlinedFunctionInfo();
21320d9c9934SGreg Clayton                                                     if (inline_info)
21330d9c9934SGreg Clayton                                                     {
21340d9c9934SGreg Clayton                                                         s.PutCString(" [inlined] ");
21350d9c9934SGreg Clayton                                                         inline_info->GetName().Dump(&s);
21360d9c9934SGreg Clayton                                                     }
21370d9c9934SGreg Clayton                                                 }
21380d9c9934SGreg Clayton                                             }
21391b654882SGreg Clayton                                             var_success = true;
21401b654882SGreg Clayton                                         }
21411b654882SGreg Clayton                                     }
21426d3dbf51SGreg Clayton                                     else if (::strncmp (var_name_begin, "name-with-args}", strlen("name-with-args}")) == 0)
21436d3dbf51SGreg Clayton                                     {
21446d3dbf51SGreg Clayton                                         // Print the function name with arguments in it
21456d3dbf51SGreg Clayton 
21466d3dbf51SGreg Clayton                                         if (sc->function)
21476d3dbf51SGreg Clayton                                         {
21486d3dbf51SGreg Clayton                                             var_success = true;
21496d3dbf51SGreg Clayton                                             ExecutionContextScope *exe_scope = exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL;
21506d3dbf51SGreg Clayton                                             cstr = sc->function->GetName().AsCString (NULL);
21516d3dbf51SGreg Clayton                                             if (cstr)
21526d3dbf51SGreg Clayton                                             {
21536d3dbf51SGreg Clayton                                                 const InlineFunctionInfo *inline_info = NULL;
21546d3dbf51SGreg Clayton                                                 VariableListSP variable_list_sp;
21556d3dbf51SGreg Clayton                                                 bool get_function_vars = true;
21566d3dbf51SGreg Clayton                                                 if (sc->block)
21576d3dbf51SGreg Clayton                                                 {
21586d3dbf51SGreg Clayton                                                     Block *inline_block = sc->block->GetContainingInlinedBlock ();
21596d3dbf51SGreg Clayton 
21606d3dbf51SGreg Clayton                                                     if (inline_block)
21616d3dbf51SGreg Clayton                                                     {
21626d3dbf51SGreg Clayton                                                         get_function_vars = false;
21636d3dbf51SGreg Clayton                                                         inline_info = sc->block->GetInlinedFunctionInfo();
21646d3dbf51SGreg Clayton                                                         if (inline_info)
21656d3dbf51SGreg Clayton                                                             variable_list_sp = inline_block->GetBlockVariableList (true);
21666d3dbf51SGreg Clayton                                                     }
21676d3dbf51SGreg Clayton                                                 }
21686d3dbf51SGreg Clayton 
21696d3dbf51SGreg Clayton                                                 if (get_function_vars)
21706d3dbf51SGreg Clayton                                                 {
21716d3dbf51SGreg Clayton                                                     variable_list_sp = sc->function->GetBlock(true).GetBlockVariableList (true);
21726d3dbf51SGreg Clayton                                                 }
21736d3dbf51SGreg Clayton 
21746d3dbf51SGreg Clayton                                                 if (inline_info)
21756d3dbf51SGreg Clayton                                                 {
21766d3dbf51SGreg Clayton                                                     s.PutCString (cstr);
21776d3dbf51SGreg Clayton                                                     s.PutCString (" [inlined] ");
21786d3dbf51SGreg Clayton                                                     cstr = inline_info->GetName().GetCString();
21796d3dbf51SGreg Clayton                                                 }
21806d3dbf51SGreg Clayton 
21816d3dbf51SGreg Clayton                                                 VariableList args;
21826d3dbf51SGreg Clayton                                                 if (variable_list_sp)
2183cc7f9bf5SEnrico Granata                                                     variable_list_sp->AppendVariablesWithScope(eValueTypeVariableArgument, args);
21846d3dbf51SGreg Clayton                                                 if (args.GetSize() > 0)
21856d3dbf51SGreg Clayton                                                 {
21866d3dbf51SGreg Clayton                                                     const char *open_paren = strchr (cstr, '(');
21876d3dbf51SGreg Clayton                                                     const char *close_paren = NULL;
21886d3dbf51SGreg Clayton                                                     if (open_paren)
2189855958caSGreg Clayton                                                     {
2190855958caSGreg Clayton                                                         if (strncmp(open_paren, "(anonymous namespace)", strlen("(anonymous namespace)")) == 0)
2191855958caSGreg Clayton                                                         {
2192855958caSGreg Clayton                                                             open_paren = strchr (open_paren + strlen("(anonymous namespace)"), '(');
2193855958caSGreg Clayton                                                             if (open_paren)
21946d3dbf51SGreg Clayton                                                                 close_paren = strchr (open_paren, ')');
2195855958caSGreg Clayton                                                         }
2196855958caSGreg Clayton                                                         else
2197855958caSGreg Clayton                                                             close_paren = strchr (open_paren, ')');
2198855958caSGreg Clayton                                                     }
21996d3dbf51SGreg Clayton 
22006d3dbf51SGreg Clayton                                                     if (open_paren)
22016d3dbf51SGreg Clayton                                                         s.Write(cstr, open_paren - cstr + 1);
22026d3dbf51SGreg Clayton                                                     else
22036d3dbf51SGreg Clayton                                                     {
22046d3dbf51SGreg Clayton                                                         s.PutCString (cstr);
22056d3dbf51SGreg Clayton                                                         s.PutChar ('(');
22066d3dbf51SGreg Clayton                                                     }
22075b6889b1SGreg Clayton                                                     const size_t num_args = args.GetSize();
22086d3dbf51SGreg Clayton                                                     for (size_t arg_idx = 0; arg_idx < num_args; ++arg_idx)
22096d3dbf51SGreg Clayton                                                     {
22106d3dbf51SGreg Clayton                                                         VariableSP var_sp (args.GetVariableAtIndex (arg_idx));
22116d3dbf51SGreg Clayton                                                         ValueObjectSP var_value_sp (ValueObjectVariable::Create (exe_scope, var_sp));
22126d3dbf51SGreg Clayton                                                         const char *var_name = var_value_sp->GetName().GetCString();
22136d3dbf51SGreg Clayton                                                         const char *var_value = var_value_sp->GetValueAsCString();
22146d3dbf51SGreg Clayton                                                         if (arg_idx > 0)
22156d3dbf51SGreg Clayton                                                             s.PutCString (", ");
22163b188b17SGreg Clayton                                                         if (var_value_sp->GetError().Success())
2217cc7f9bf5SEnrico Granata                                                         {
2218cc7f9bf5SEnrico Granata                                                             if (var_value)
22196d3dbf51SGreg Clayton                                                                 s.Printf ("%s=%s", var_name, var_value);
22203b188b17SGreg Clayton                                                             else
2221cc7f9bf5SEnrico Granata                                                                 s.Printf ("%s=%s at %s", var_name, var_value_sp->GetTypeName().GetCString(), var_value_sp->GetLocationAsCString());
2222cc7f9bf5SEnrico Granata                                                         }
2223cc7f9bf5SEnrico Granata                                                         else
22243b188b17SGreg Clayton                                                             s.Printf ("%s=<unavailable>", var_name);
22256d3dbf51SGreg Clayton                                                     }
22266d3dbf51SGreg Clayton 
22276d3dbf51SGreg Clayton                                                     if (close_paren)
22286d3dbf51SGreg Clayton                                                         s.PutCString (close_paren);
22296d3dbf51SGreg Clayton                                                     else
22306d3dbf51SGreg Clayton                                                         s.PutChar(')');
22316d3dbf51SGreg Clayton 
22326d3dbf51SGreg Clayton                                                 }
22336d3dbf51SGreg Clayton                                                 else
22346d3dbf51SGreg Clayton                                                 {
22356d3dbf51SGreg Clayton                                                     s.PutCString(cstr);
22366d3dbf51SGreg Clayton                                                 }
22376d3dbf51SGreg Clayton                                             }
22386d3dbf51SGreg Clayton                                         }
22396d3dbf51SGreg Clayton                                         else if (sc->symbol)
22406d3dbf51SGreg Clayton                                         {
22416d3dbf51SGreg Clayton                                             cstr = sc->symbol->GetName().AsCString (NULL);
22426d3dbf51SGreg Clayton                                             if (cstr)
22436d3dbf51SGreg Clayton                                             {
22446d3dbf51SGreg Clayton                                                 s.PutCString(cstr);
22456d3dbf51SGreg Clayton                                                 var_success = true;
22466d3dbf51SGreg Clayton                                             }
22476d3dbf51SGreg Clayton                                         }
22486d3dbf51SGreg Clayton                                     }
22491b654882SGreg Clayton                                     else if (::strncmp (var_name_begin, "addr-offset}", strlen("addr-offset}")) == 0)
22501b654882SGreg Clayton                                     {
22511b654882SGreg Clayton                                         var_success = addr != NULL;
22521b654882SGreg Clayton                                         if (var_success)
22531b654882SGreg Clayton                                         {
22541b654882SGreg Clayton                                             format_addr = *addr;
22551b654882SGreg Clayton                                             calculate_format_addr_function_offset = true;
22561b654882SGreg Clayton                                         }
22571b654882SGreg Clayton                                     }
22581b654882SGreg Clayton                                     else if (::strncmp (var_name_begin, "line-offset}", strlen("line-offset}")) == 0)
22591b654882SGreg Clayton                                     {
22601b654882SGreg Clayton                                         var_success = sc->line_entry.range.GetBaseAddress().IsValid();
22611b654882SGreg Clayton                                         if (var_success)
22621b654882SGreg Clayton                                         {
22631b654882SGreg Clayton                                             format_addr = sc->line_entry.range.GetBaseAddress();
22641b654882SGreg Clayton                                             calculate_format_addr_function_offset = true;
22651b654882SGreg Clayton                                         }
22661b654882SGreg Clayton                                     }
22671b654882SGreg Clayton                                     else if (::strncmp (var_name_begin, "pc-offset}", strlen("pc-offset}")) == 0)
22681b654882SGreg Clayton                                     {
2269c14ee32dSGreg Clayton                                         StackFrame *frame = exe_ctx->GetFramePtr();
2270c14ee32dSGreg Clayton                                         var_success = frame != NULL;
22711b654882SGreg Clayton                                         if (var_success)
22721b654882SGreg Clayton                                         {
2273c14ee32dSGreg Clayton                                             format_addr = frame->GetFrameCodeAddress();
22741b654882SGreg Clayton                                             calculate_format_addr_function_offset = true;
22751b654882SGreg Clayton                                         }
22761b654882SGreg Clayton                                     }
22771b654882SGreg Clayton                                 }
22781b654882SGreg Clayton                             }
22791b654882SGreg Clayton                             break;
22801b654882SGreg Clayton 
22811b654882SGreg Clayton                         case 'l':
22821b654882SGreg Clayton                             if (::strncmp (var_name_begin, "line.", strlen("line.")) == 0)
22831b654882SGreg Clayton                             {
22841b654882SGreg Clayton                                 if (sc && sc->line_entry.IsValid())
22851b654882SGreg Clayton                                 {
22861b654882SGreg Clayton                                     var_name_begin += ::strlen ("line.");
22871b654882SGreg Clayton                                     if (::strncmp (var_name_begin, "file.", strlen("file.")) == 0)
22881b654882SGreg Clayton                                     {
22891b654882SGreg Clayton                                         var_name_begin += ::strlen ("file.");
22901b654882SGreg Clayton 
22911b654882SGreg Clayton                                         if (::strncmp (var_name_begin, "basename}", strlen("basename}")) == 0)
22921b654882SGreg Clayton                                         {
22931b654882SGreg Clayton                                             format_file_spec.GetFilename() = sc->line_entry.file.GetFilename();
22941b654882SGreg Clayton                                             var_success = format_file_spec;
22951b654882SGreg Clayton                                         }
22961b654882SGreg Clayton                                         else if (::strncmp (var_name_begin, "fullpath}", strlen("fullpath}")) == 0)
22971b654882SGreg Clayton                                         {
22981b654882SGreg Clayton                                             format_file_spec = sc->line_entry.file;
22991b654882SGreg Clayton                                             var_success = format_file_spec;
23001b654882SGreg Clayton                                         }
23011b654882SGreg Clayton                                     }
23021b654882SGreg Clayton                                     else if (::strncmp (var_name_begin, "number}", strlen("number}")) == 0)
23031b654882SGreg Clayton                                     {
23041b654882SGreg Clayton                                         var_success = true;
23051b654882SGreg Clayton                                         s.Printf("%u", sc->line_entry.line);
23061b654882SGreg Clayton                                     }
23071b654882SGreg Clayton                                     else if ((::strncmp (var_name_begin, "start-addr}", strlen("start-addr}")) == 0) ||
23081b654882SGreg Clayton                                              (::strncmp (var_name_begin, "end-addr}", strlen("end-addr}")) == 0))
23091b654882SGreg Clayton                                     {
23101b654882SGreg Clayton                                         var_success = sc && sc->line_entry.range.GetBaseAddress().IsValid();
23111b654882SGreg Clayton                                         if (var_success)
23121b654882SGreg Clayton                                         {
23131b654882SGreg Clayton                                             format_addr = sc->line_entry.range.GetBaseAddress();
23141b654882SGreg Clayton                                             if (var_name_begin[0] == 'e')
23151b654882SGreg Clayton                                                 format_addr.Slide (sc->line_entry.range.GetByteSize());
23161b654882SGreg Clayton                                         }
23171b654882SGreg Clayton                                     }
23181b654882SGreg Clayton                                 }
23191b654882SGreg Clayton                             }
23201b654882SGreg Clayton                             break;
23211b654882SGreg Clayton                         }
23221b654882SGreg Clayton 
23231b654882SGreg Clayton                         if (var_success)
23241b654882SGreg Clayton                         {
23251b654882SGreg Clayton                             // If format addr is valid, then we need to print an address
23261b654882SGreg Clayton                             if (reg_num != LLDB_INVALID_REGNUM)
23271b654882SGreg Clayton                             {
2328c14ee32dSGreg Clayton                                 StackFrame *frame = exe_ctx->GetFramePtr();
23291b654882SGreg Clayton                                 // We have a register value to display...
23301b654882SGreg Clayton                                 if (reg_num == LLDB_REGNUM_GENERIC_PC && reg_kind == eRegisterKindGeneric)
23311b654882SGreg Clayton                                 {
2332c14ee32dSGreg Clayton                                     format_addr = frame->GetFrameCodeAddress();
23331b654882SGreg Clayton                                 }
23341b654882SGreg Clayton                                 else
23351b654882SGreg Clayton                                 {
23361b654882SGreg Clayton                                     if (reg_ctx == NULL)
2337c14ee32dSGreg Clayton                                         reg_ctx = frame->GetRegisterContext().get();
23381b654882SGreg Clayton 
23391b654882SGreg Clayton                                     if (reg_ctx)
23401b654882SGreg Clayton                                     {
23411b654882SGreg Clayton                                         if (reg_kind != kNumRegisterKinds)
23421b654882SGreg Clayton                                             reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(reg_kind, reg_num);
23431b654882SGreg Clayton                                         reg_info = reg_ctx->GetRegisterInfoAtIndex (reg_num);
23441b654882SGreg Clayton                                         var_success = reg_info != NULL;
23451b654882SGreg Clayton                                     }
23461b654882SGreg Clayton                                 }
23471b654882SGreg Clayton                             }
23481b654882SGreg Clayton 
23491b654882SGreg Clayton                             if (reg_info != NULL)
23501b654882SGreg Clayton                             {
23517349bd90SGreg Clayton                                 RegisterValue reg_value;
23527349bd90SGreg Clayton                                 var_success = reg_ctx->ReadRegister (reg_info, reg_value);
23537349bd90SGreg Clayton                                 if (var_success)
23541b654882SGreg Clayton                                 {
23559a8fa916SGreg Clayton                                     reg_value.Dump(&s, reg_info, false, false, eFormatDefault);
23561b654882SGreg Clayton                                 }
23571b654882SGreg Clayton                             }
23581b654882SGreg Clayton 
23591b654882SGreg Clayton                             if (format_file_spec)
23601b654882SGreg Clayton                             {
23611b654882SGreg Clayton                                 s << format_file_spec;
23621b654882SGreg Clayton                             }
23631b654882SGreg Clayton 
23641b654882SGreg Clayton                             // If format addr is valid, then we need to print an address
23651b654882SGreg Clayton                             if (format_addr.IsValid())
23661b654882SGreg Clayton                             {
23670603aa9dSGreg Clayton                                 var_success = false;
23680603aa9dSGreg Clayton 
23691b654882SGreg Clayton                                 if (calculate_format_addr_function_offset)
23701b654882SGreg Clayton                                 {
23711b654882SGreg Clayton                                     Address func_addr;
23720603aa9dSGreg Clayton 
23730603aa9dSGreg Clayton                                     if (sc)
23740603aa9dSGreg Clayton                                     {
23751b654882SGreg Clayton                                         if (sc->function)
23760d9c9934SGreg Clayton                                         {
23771b654882SGreg Clayton                                             func_addr = sc->function->GetAddressRange().GetBaseAddress();
23780d9c9934SGreg Clayton                                             if (sc->block)
23790d9c9934SGreg Clayton                                             {
23800d9c9934SGreg Clayton                                                 // Check to make sure we aren't in an inline
23810d9c9934SGreg Clayton                                                 // function. If we are, use the inline block
23820d9c9934SGreg Clayton                                                 // range that contains "format_addr" since
23830d9c9934SGreg Clayton                                                 // blocks can be discontiguous.
23840d9c9934SGreg Clayton                                                 Block *inline_block = sc->block->GetContainingInlinedBlock ();
23850d9c9934SGreg Clayton                                                 AddressRange inline_range;
23860d9c9934SGreg Clayton                                                 if (inline_block && inline_block->GetRangeContainingAddress (format_addr, inline_range))
23870d9c9934SGreg Clayton                                                     func_addr = inline_range.GetBaseAddress();
23880d9c9934SGreg Clayton                                             }
23890d9c9934SGreg Clayton                                         }
2390e7612134SGreg Clayton                                         else if (sc->symbol && sc->symbol->ValueIsAddress())
2391e7612134SGreg Clayton                                             func_addr = sc->symbol->GetAddress();
23920603aa9dSGreg Clayton                                     }
23931b654882SGreg Clayton 
23940603aa9dSGreg Clayton                                     if (func_addr.IsValid())
23951b654882SGreg Clayton                                     {
23961b654882SGreg Clayton                                         if (func_addr.GetSection() == format_addr.GetSection())
23971b654882SGreg Clayton                                         {
23981b654882SGreg Clayton                                             addr_t func_file_addr = func_addr.GetFileAddress();
23991b654882SGreg Clayton                                             addr_t addr_file_addr = format_addr.GetFileAddress();
24001b654882SGreg Clayton                                             if (addr_file_addr > func_file_addr)
2401d01b2953SDaniel Malea                                                 s.Printf(" + %" PRIu64, addr_file_addr - func_file_addr);
24021b654882SGreg Clayton                                             else if (addr_file_addr < func_file_addr)
2403d01b2953SDaniel Malea                                                 s.Printf(" - %" PRIu64, func_file_addr - addr_file_addr);
24040603aa9dSGreg Clayton                                             var_success = true;
24051b654882SGreg Clayton                                         }
24061b654882SGreg Clayton                                         else
24070603aa9dSGreg Clayton                                         {
24080603aa9dSGreg Clayton                                             Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
24090603aa9dSGreg Clayton                                             if (target)
24100603aa9dSGreg Clayton                                             {
24110603aa9dSGreg Clayton                                                 addr_t func_load_addr = func_addr.GetLoadAddress (target);
24120603aa9dSGreg Clayton                                                 addr_t addr_load_addr = format_addr.GetLoadAddress (target);
24130603aa9dSGreg Clayton                                                 if (addr_load_addr > func_load_addr)
2414d01b2953SDaniel Malea                                                     s.Printf(" + %" PRIu64, addr_load_addr - func_load_addr);
24150603aa9dSGreg Clayton                                                 else if (addr_load_addr < func_load_addr)
2416d01b2953SDaniel Malea                                                     s.Printf(" - %" PRIu64, func_load_addr - addr_load_addr);
24170603aa9dSGreg Clayton                                                 var_success = true;
24180603aa9dSGreg Clayton                                             }
24190603aa9dSGreg Clayton                                         }
24201b654882SGreg Clayton                                     }
24211b654882SGreg Clayton                                 }
24221b654882SGreg Clayton                                 else
24231b654882SGreg Clayton                                 {
24240603aa9dSGreg Clayton                                     Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
24251b654882SGreg Clayton                                     addr_t vaddr = LLDB_INVALID_ADDRESS;
24260603aa9dSGreg Clayton                                     if (exe_ctx && !target->GetSectionLoadList().IsEmpty())
24270603aa9dSGreg Clayton                                         vaddr = format_addr.GetLoadAddress (target);
24281b654882SGreg Clayton                                     if (vaddr == LLDB_INVALID_ADDRESS)
24291b654882SGreg Clayton                                         vaddr = format_addr.GetFileAddress ();
24301b654882SGreg Clayton 
24311b654882SGreg Clayton                                     if (vaddr != LLDB_INVALID_ADDRESS)
24320603aa9dSGreg Clayton                                     {
2433514487e8SGreg Clayton                                         int addr_width = target->GetArchitecture().GetAddressByteSize() * 2;
243435f1a0d5SGreg Clayton                                         if (addr_width == 0)
243535f1a0d5SGreg Clayton                                             addr_width = 16;
2436d01b2953SDaniel Malea                                         s.Printf("0x%*.*" PRIx64, addr_width, addr_width, vaddr);
24370603aa9dSGreg Clayton                                         var_success = true;
24380603aa9dSGreg Clayton                                     }
24391b654882SGreg Clayton                                 }
24401b654882SGreg Clayton                             }
24411b654882SGreg Clayton                         }
24421b654882SGreg Clayton 
24431b654882SGreg Clayton                         if (var_success == false)
24441b654882SGreg Clayton                             success = false;
24451b654882SGreg Clayton                     }
24461b654882SGreg Clayton                     p = var_name_end;
24471b654882SGreg Clayton                 }
24481b654882SGreg Clayton                 else
24491b654882SGreg Clayton                     break;
24501b654882SGreg Clayton             }
24511b654882SGreg Clayton             else
24521b654882SGreg Clayton             {
24531b654882SGreg Clayton                 // We got a dollar sign with no '{' after it, it must just be a dollar sign
24541b654882SGreg Clayton                 s.PutChar(*p);
24551b654882SGreg Clayton             }
24561b654882SGreg Clayton         }
24571b654882SGreg Clayton         else if (*p == '\\')
24581b654882SGreg Clayton         {
24591b654882SGreg Clayton             ++p; // skip the slash
24601b654882SGreg Clayton             switch (*p)
24611b654882SGreg Clayton             {
24621b654882SGreg Clayton             case 'a': s.PutChar ('\a'); break;
24631b654882SGreg Clayton             case 'b': s.PutChar ('\b'); break;
24641b654882SGreg Clayton             case 'f': s.PutChar ('\f'); break;
24651b654882SGreg Clayton             case 'n': s.PutChar ('\n'); break;
24661b654882SGreg Clayton             case 'r': s.PutChar ('\r'); break;
24671b654882SGreg Clayton             case 't': s.PutChar ('\t'); break;
24681b654882SGreg Clayton             case 'v': s.PutChar ('\v'); break;
24691b654882SGreg Clayton             case '\'': s.PutChar ('\''); break;
24701b654882SGreg Clayton             case '\\': s.PutChar ('\\'); break;
24711b654882SGreg Clayton             case '0':
24721b654882SGreg Clayton                 // 1 to 3 octal chars
24731b654882SGreg Clayton                 {
24740603aa9dSGreg Clayton                     // Make a string that can hold onto the initial zero char,
24750603aa9dSGreg Clayton                     // up to 3 octal digits, and a terminating NULL.
24760603aa9dSGreg Clayton                     char oct_str[5] = { 0, 0, 0, 0, 0 };
24770603aa9dSGreg Clayton 
24780603aa9dSGreg Clayton                     int i;
24790603aa9dSGreg Clayton                     for (i=0; (p[i] >= '0' && p[i] <= '7') && i<4; ++i)
24800603aa9dSGreg Clayton                         oct_str[i] = p[i];
24810603aa9dSGreg Clayton 
24820603aa9dSGreg Clayton                     // We don't want to consume the last octal character since
24830603aa9dSGreg Clayton                     // the main for loop will do this for us, so we advance p by
24840603aa9dSGreg Clayton                     // one less than i (even if i is zero)
24850603aa9dSGreg Clayton                     p += i - 1;
24860603aa9dSGreg Clayton                     unsigned long octal_value = ::strtoul (oct_str, NULL, 8);
24870603aa9dSGreg Clayton                     if (octal_value <= UINT8_MAX)
24881b654882SGreg Clayton                     {
2489c7bece56SGreg Clayton                         s.PutChar((char)octal_value);
24901b654882SGreg Clayton                     }
24911b654882SGreg Clayton                 }
24921b654882SGreg Clayton                 break;
24931b654882SGreg Clayton 
24941b654882SGreg Clayton             case 'x':
24951b654882SGreg Clayton                 // hex number in the format
24960603aa9dSGreg Clayton                 if (isxdigit(p[1]))
24971b654882SGreg Clayton                 {
24980603aa9dSGreg Clayton                     ++p;    // Skip the 'x'
24991b654882SGreg Clayton 
25000603aa9dSGreg Clayton                     // Make a string that can hold onto two hex chars plus a
25010603aa9dSGreg Clayton                     // NULL terminator
25021b654882SGreg Clayton                     char hex_str[3] = { 0,0,0 };
25031b654882SGreg Clayton                     hex_str[0] = *p;
25040603aa9dSGreg Clayton                     if (isxdigit(p[1]))
25050603aa9dSGreg Clayton                     {
25060603aa9dSGreg Clayton                         ++p; // Skip the first of the two hex chars
25071b654882SGreg Clayton                         hex_str[1] = *p;
25080603aa9dSGreg Clayton                     }
25090603aa9dSGreg Clayton 
25101b654882SGreg Clayton                     unsigned long hex_value = strtoul (hex_str, NULL, 16);
25110603aa9dSGreg Clayton                     if (hex_value <= UINT8_MAX)
2512c7bece56SGreg Clayton                         s.PutChar ((char)hex_value);
25131b654882SGreg Clayton                 }
25141b654882SGreg Clayton                 else
25151b654882SGreg Clayton                 {
25160603aa9dSGreg Clayton                     s.PutChar('x');
25171b654882SGreg Clayton                 }
25181b654882SGreg Clayton                 break;
25191b654882SGreg Clayton 
25201b654882SGreg Clayton             default:
25210603aa9dSGreg Clayton                 // Just desensitize any other character by just printing what
25220603aa9dSGreg Clayton                 // came after the '\'
25230603aa9dSGreg Clayton                 s << *p;
25241b654882SGreg Clayton                 break;
25251b654882SGreg Clayton 
25261b654882SGreg Clayton             }
25271b654882SGreg Clayton 
25281b654882SGreg Clayton         }
25291b654882SGreg Clayton     }
25301b654882SGreg Clayton     if (end)
25311b654882SGreg Clayton         *end = p;
25321b654882SGreg Clayton     return success;
25331b654882SGreg Clayton }
25341b654882SGreg Clayton 
2535c3ce7f27SMichael Sartain bool
2536c3ce7f27SMichael Sartain Debugger::FormatPrompt
2537c3ce7f27SMichael Sartain (
2538c3ce7f27SMichael Sartain     const char *format,
2539c3ce7f27SMichael Sartain     const SymbolContext *sc,
2540c3ce7f27SMichael Sartain     const ExecutionContext *exe_ctx,
2541c3ce7f27SMichael Sartain     const Address *addr,
2542c3ce7f27SMichael Sartain     Stream &s,
2543c3ce7f27SMichael Sartain     ValueObject* valobj
2544c3ce7f27SMichael Sartain )
2545c3ce7f27SMichael Sartain {
2546c3ce7f27SMichael Sartain     bool use_color = exe_ctx ? exe_ctx->GetTargetRef().GetDebugger().GetUseColor() : true;
2547c3ce7f27SMichael Sartain     std::string format_str = lldb_utility::ansi::FormatAnsiTerminalCodes (format, use_color);
2548c3ce7f27SMichael Sartain     if (format_str.length())
2549c3ce7f27SMichael Sartain         format = format_str.c_str();
2550c3ce7f27SMichael Sartain     return FormatPromptRecurse (format, sc, exe_ctx, addr, s, NULL, valobj);
2551c3ce7f27SMichael Sartain }
2552c3ce7f27SMichael Sartain 
2553228063cdSJim Ingham void
2554228063cdSJim Ingham Debugger::SetLoggingCallback (lldb::LogOutputCallback log_callback, void *baton)
2555228063cdSJim Ingham {
25564f02b22dSJim Ingham     // For simplicity's sake, I am not going to deal with how to close down any
25574f02b22dSJim Ingham     // open logging streams, I just redirect everything from here on out to the
25584f02b22dSJim Ingham     // callback.
2559228063cdSJim Ingham     m_log_callback_stream_sp.reset (new StreamCallback (log_callback, baton));
2560228063cdSJim Ingham }
2561228063cdSJim Ingham 
2562228063cdSJim Ingham bool
2563228063cdSJim Ingham Debugger::EnableLog (const char *channel, const char **categories, const char *log_file, uint32_t log_options, Stream &error_stream)
2564228063cdSJim Ingham {
2565228063cdSJim Ingham     Log::Callbacks log_callbacks;
2566228063cdSJim Ingham 
2567228063cdSJim Ingham     StreamSP log_stream_sp;
25689a028519SSean Callanan     if (m_log_callback_stream_sp)
2569228063cdSJim Ingham     {
2570228063cdSJim Ingham         log_stream_sp = m_log_callback_stream_sp;
2571228063cdSJim Ingham         // For now when using the callback mode you always get thread & timestamp.
2572228063cdSJim Ingham         log_options |= LLDB_LOG_OPTION_PREPEND_TIMESTAMP | LLDB_LOG_OPTION_PREPEND_THREAD_NAME;
2573228063cdSJim Ingham     }
2574228063cdSJim Ingham     else if (log_file == NULL || *log_file == '\0')
2575228063cdSJim Ingham     {
2576228063cdSJim Ingham         log_stream_sp.reset(new StreamFile(GetOutputFile().GetDescriptor(), false));
2577228063cdSJim Ingham     }
2578228063cdSJim Ingham     else
2579228063cdSJim Ingham     {
2580228063cdSJim Ingham         LogStreamMap::iterator pos = m_log_streams.find(log_file);
2581c1b2ccfdSGreg Clayton         if (pos != m_log_streams.end())
2582c1b2ccfdSGreg Clayton             log_stream_sp = pos->second.lock();
2583c1b2ccfdSGreg Clayton         if (!log_stream_sp)
2584228063cdSJim Ingham         {
2585228063cdSJim Ingham             log_stream_sp.reset (new StreamFile (log_file));
2586228063cdSJim Ingham             m_log_streams[log_file] = log_stream_sp;
2587228063cdSJim Ingham         }
2588228063cdSJim Ingham     }
2589228063cdSJim Ingham     assert (log_stream_sp.get());
2590228063cdSJim Ingham 
2591228063cdSJim Ingham     if (log_options == 0)
2592228063cdSJim Ingham         log_options = LLDB_LOG_OPTION_PREPEND_THREAD_NAME | LLDB_LOG_OPTION_THREADSAFE;
2593228063cdSJim Ingham 
259457abc5d6SGreg Clayton     if (Log::GetLogChannelCallbacks (ConstString(channel), log_callbacks))
2595228063cdSJim Ingham     {
2596228063cdSJim Ingham         log_callbacks.enable (log_stream_sp, log_options, categories, &error_stream);
2597228063cdSJim Ingham         return true;
2598228063cdSJim Ingham     }
2599228063cdSJim Ingham     else
2600228063cdSJim Ingham     {
2601228063cdSJim Ingham         LogChannelSP log_channel_sp (LogChannel::FindPlugin (channel));
2602228063cdSJim Ingham         if (log_channel_sp)
2603228063cdSJim Ingham         {
2604228063cdSJim Ingham             if (log_channel_sp->Enable (log_stream_sp, log_options, &error_stream, categories))
2605228063cdSJim Ingham             {
2606228063cdSJim Ingham                 return true;
2607228063cdSJim Ingham             }
2608228063cdSJim Ingham             else
2609228063cdSJim Ingham             {
2610228063cdSJim Ingham                 error_stream.Printf ("Invalid log channel '%s'.\n", channel);
2611228063cdSJim Ingham                 return false;
2612228063cdSJim Ingham             }
2613228063cdSJim Ingham         }
2614228063cdSJim Ingham         else
2615228063cdSJim Ingham         {
2616228063cdSJim Ingham             error_stream.Printf ("Invalid log channel '%s'.\n", channel);
2617228063cdSJim Ingham             return false;
2618228063cdSJim Ingham         }
2619228063cdSJim Ingham     }
2620228063cdSJim Ingham     return false;
2621228063cdSJim Ingham }
2622228063cdSJim Ingham 
26239585fbfcSGreg Clayton SourceManager &
26249585fbfcSGreg Clayton Debugger::GetSourceManager ()
26259585fbfcSGreg Clayton {
26269585fbfcSGreg Clayton     if (m_source_manager_ap.get() == NULL)
26279585fbfcSGreg Clayton         m_source_manager_ap.reset (new SourceManager (shared_from_this()));
26289585fbfcSGreg Clayton     return *m_source_manager_ap;
26299585fbfcSGreg Clayton }
26309585fbfcSGreg Clayton 
26319585fbfcSGreg Clayton 
2632