//===-- FormatEntity.cpp ----------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "llvm/ADT/StringRef.h"

#include "lldb/Core/FormatEntity.h"

#include "lldb/Core/Address.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/Stream.h"
#include "lldb/Core/StreamString.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Core/ValueObjectVariable.h"
#include "lldb/DataFormatters/DataVisualization.h"
#include "lldb/DataFormatters/FormatManager.h"
#include "lldb/Expression/ClangExpressionVariable.h"
#include "lldb/Host/FileSpec.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Symbol/Block.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/LineEntry.h"
#include "lldb/Symbol/Symbol.h"
#include "lldb/Symbol/VariableList.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/SectionLoadList.h"
#include "lldb/Target/StackFrame.h"
#include "lldb/Target/StopInfo.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Utility/AnsiTerminal.h"

using namespace lldb;
using namespace lldb_private;


enum FileKind
{
    FileError = 0,
    Basename,
    Dirname,
    Fullpath
};

#define ENTRY(n,t,f)            { n, NULL, FormatEntity::Entry::Type::t, FormatEntity::Entry::FormatType::f, 0,0,NULL, false}
#define ENTRY_VALUE(n,t,f,v)    { n, NULL, FormatEntity::Entry::Type::t, FormatEntity::Entry::FormatType::f, v,0,NULL, false}
#define ENTRY_CHILDREN(n,t,f,c) { n, NULL, FormatEntity::Entry::Type::t, FormatEntity::Entry::FormatType::f, 0,llvm::array_lengthof(c),c, false}
#define ENTRY_CHILDREN_KEEP_SEP(n,t,f,c) { n, NULL, FormatEntity::Entry::Type::t, FormatEntity::Entry::FormatType::f, 0,llvm::array_lengthof(c),c, true}
#define ENTRY_STRING(n,s)       { n, s, FormatEntity::Entry::Type::InsertString, FormatEntity::Entry::FormatType::None, 0,0, NULL, false}
static FormatEntity::Entry::Definition g_string_entry[] =
{
    ENTRY("*", ParentString, None)
};

static FormatEntity::Entry::Definition g_addr_entries[] =
{
    ENTRY ("load", AddressLoad      , UInt64),
    ENTRY ("file", AddressFile      , UInt64),
    ENTRY ("load", AddressLoadOrFile, UInt64),
};

static FormatEntity::Entry::Definition g_file_child_entries[] =
{
    ENTRY_VALUE("basename", ParentNumber, CString, FileKind::Basename),
    ENTRY_VALUE("dirname", ParentNumber, CString, FileKind::Dirname),
    ENTRY_VALUE("fullpath", ParentNumber, CString, FileKind::Fullpath)
};

static FormatEntity::Entry::Definition g_frame_child_entries[] =
{
    
    ENTRY ("index", FrameIndex        , UInt32),
    ENTRY ("pc"   , FrameRegisterPC   , UInt64),
    ENTRY ("fp"   , FrameRegisterFP   , UInt64),
    ENTRY ("sp"   , FrameRegisterSP   , UInt64),
    ENTRY ("flags", FrameRegisterFlags, UInt64),
    ENTRY_CHILDREN ("reg", FrameRegisterByName, UInt64, g_string_entry),
};

static FormatEntity::Entry::Definition g_function_child_entries[] =
{
    ENTRY ("id"                  , FunctionID             , UInt64),
    ENTRY ("name"                , FunctionName           , CString),
    ENTRY ("name-without-args"   , FunctionNameNoArgs     , CString),
    ENTRY ("name-with-args"      , FunctionNameWithArgs   , CString),
    ENTRY ("addr-offset"         , FunctionAddrOffset     , UInt64),
    ENTRY ("concrete-only-addr-offset-no-padding", FunctionAddrOffsetConcrete, UInt64),
    ENTRY ("line-offset"         , FunctionLineOffset     , UInt64),
    ENTRY ("pc-offset"           , FunctionPCOffset       , UInt64),
    ENTRY ("initial-function"    , FunctionInitial        , None),
    ENTRY ("changed"             , FunctionChanged        , None)
};

static FormatEntity::Entry::Definition g_line_child_entries[] =
{
    ENTRY_CHILDREN("file", LineEntryFile        , None  , g_file_child_entries),
    ENTRY("number"       , LineEntryLineNumber  , UInt32),
    ENTRY("start-addr"   , LineEntryStartAddress, UInt64),
    ENTRY("end-addr"     , LineEntryEndAddress  , UInt64),
};

static FormatEntity::Entry::Definition g_module_child_entries[] =
{
    ENTRY_CHILDREN("file", ModuleFile, None, g_file_child_entries),
};

static FormatEntity::Entry::Definition g_process_child_entries[] =
{
    ENTRY           ( "id"      , ProcessID     , UInt64    ),
    ENTRY_VALUE     ( "name"    , ProcessFile   , CString   , FileKind::Basename),
    ENTRY_CHILDREN  ( "file"    , ProcessFile   , None      , g_file_child_entries),
};

static FormatEntity::Entry::Definition g_svar_child_entries[] =
{
    ENTRY           ( "*"       , ParentString  , None)
};

static FormatEntity::Entry::Definition g_var_child_entries[] =
{
    ENTRY           ( "*"       , ParentString  , None)
};

static FormatEntity::Entry::Definition g_thread_child_entries[] =
{
    ENTRY           ( "id"                  , ThreadID                   , UInt64   ),
    ENTRY           ( "protocol_id"         , ThreadProtocolID           , UInt64   ),
    ENTRY           ( "index"               , ThreadIndexID              , UInt32   ),
    ENTRY_CHILDREN  ( "info"                , ThreadInfo                 , None     , g_string_entry),
    ENTRY           ( "queue"               , ThreadQueue                , CString  ),
    ENTRY           ( "name"                , ThreadName                 , CString  ),
    ENTRY           ( "stop-reason"         , ThreadStopReason           , CString  ),
    ENTRY           ( "return-value"        , ThreadReturnValue          , CString  ),
    ENTRY           ( "completed-expression", ThreadCompletedExpression  , CString  ),
};

static FormatEntity::Entry::Definition g_target_child_entries[] =
{
    ENTRY           ( "arch"    , TargetArch    , CString   ),
};

#define _TO_STR2(_val) #_val
#define _TO_STR(_val) _TO_STR2(_val)

static FormatEntity::Entry::Definition g_ansi_fg_entries[] =
{
    ENTRY_STRING ("black"   , ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_BLACK)      ANSI_ESC_END),
    ENTRY_STRING ("red"     , ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_RED)        ANSI_ESC_END),
    ENTRY_STRING ("green"   , ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_GREEN)      ANSI_ESC_END),
    ENTRY_STRING ("yellow"  , ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_YELLOW)     ANSI_ESC_END),
    ENTRY_STRING ("blue"    , ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_BLUE)       ANSI_ESC_END),
    ENTRY_STRING ("purple"  , ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_PURPLE)     ANSI_ESC_END),
    ENTRY_STRING ("cyan"    , ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_CYAN)       ANSI_ESC_END),
    ENTRY_STRING ("white"   , ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_WHITE)      ANSI_ESC_END),
};

static FormatEntity::Entry::Definition g_ansi_bg_entries[] =
{
    ENTRY_STRING ("black"   , ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_BLACK)      ANSI_ESC_END),
    ENTRY_STRING ("red"     , ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_RED)        ANSI_ESC_END),
    ENTRY_STRING ("green"   , ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_GREEN)      ANSI_ESC_END),
    ENTRY_STRING ("yellow"  , ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_YELLOW)     ANSI_ESC_END),
    ENTRY_STRING ("blue"    , ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_BLUE)       ANSI_ESC_END),
    ENTRY_STRING ("purple"  , ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_PURPLE)     ANSI_ESC_END),
    ENTRY_STRING ("cyan"    , ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_CYAN)       ANSI_ESC_END),
    ENTRY_STRING ("white"   , ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_WHITE)      ANSI_ESC_END),
};

static FormatEntity::Entry::Definition g_ansi_entries[] =
{
    ENTRY_CHILDREN  ( "fg"          , Invalid  , None      , g_ansi_fg_entries),
    ENTRY_CHILDREN  ( "bg"          , Invalid  , None      , g_ansi_bg_entries),
    ENTRY_STRING    ( "normal"      , ANSI_ESC_START _TO_STR(ANSI_CTRL_NORMAL)         ANSI_ESC_END),
    ENTRY_STRING    ( "bold"        , ANSI_ESC_START _TO_STR(ANSI_CTRL_BOLD)           ANSI_ESC_END),
    ENTRY_STRING    ( "faint"       , ANSI_ESC_START _TO_STR(ANSI_CTRL_FAINT)          ANSI_ESC_END),
    ENTRY_STRING    ( "italic"      , ANSI_ESC_START _TO_STR(ANSI_CTRL_ITALIC)         ANSI_ESC_END),
    ENTRY_STRING    ( "underline"   , ANSI_ESC_START _TO_STR(ANSI_CTRL_UNDERLINE)      ANSI_ESC_END),
    ENTRY_STRING    ( "slow-blink"  , ANSI_ESC_START _TO_STR(ANSI_CTRL_SLOW_BLINK)     ANSI_ESC_END),
    ENTRY_STRING    ( "fast-blink"  , ANSI_ESC_START _TO_STR(ANSI_CTRL_FAST_BLINK)     ANSI_ESC_END),
    ENTRY_STRING    ( "negative"    , ANSI_ESC_START _TO_STR(ANSI_CTRL_IMAGE_NEGATIVE) ANSI_ESC_END),
    ENTRY_STRING    ( "conceal"     , ANSI_ESC_START _TO_STR(ANSI_CTRL_CONCEAL)        ANSI_ESC_END),
    ENTRY_STRING    ( "crossed-out" , ANSI_ESC_START _TO_STR(ANSI_CTRL_CROSSED_OUT)    ANSI_ESC_END),

};

static FormatEntity::Entry::Definition g_script_child_entries[] =
{
    ENTRY  ( "frame"   , ScriptFrame               , None),
    ENTRY  ( "process" , ScriptProcess             , None),
    ENTRY  ( "target"  , ScriptTarget              , None),
    ENTRY  ( "thread"  , ScriptThread              , None),
    ENTRY  ( "var"     , ScriptVariable            , None),
    ENTRY  ( "svar"    , ScriptVariableSynthetic   , None),
    ENTRY  ( "thread"  , ScriptThread              , None),
};

static FormatEntity::Entry::Definition g_top_level_entries[] =
{
    ENTRY_CHILDREN          ("addr"                , AddressLoadOrFile      , UInt64    , g_addr_entries),
    ENTRY                   ("addr-file-or-load"   , AddressLoadOrFile      , UInt64    ),
    ENTRY_CHILDREN          ("ansi"                , Invalid                , None      , g_ansi_entries),
    ENTRY                   ("current-pc-arrow"    , CurrentPCArrow         , CString   ),
    ENTRY_CHILDREN          ("file"                , File                   , CString   , g_file_child_entries),
    ENTRY_CHILDREN          ("frame"               , Invalid                , None      , g_frame_child_entries),
    ENTRY_CHILDREN          ("function"            , Invalid                , None      , g_function_child_entries),
    ENTRY_CHILDREN          ("line"                , Invalid                , None      , g_line_child_entries),
    ENTRY_CHILDREN          ("module"              , Invalid                , None      , g_module_child_entries),
    ENTRY_CHILDREN          ("process"             , Invalid                , None      , g_process_child_entries),
    ENTRY_CHILDREN          ("script"              , Invalid                , None      , g_script_child_entries),
    ENTRY_CHILDREN_KEEP_SEP ("svar"                , VariableSynthetic      , None      , g_svar_child_entries),
    ENTRY_CHILDREN          ("thread"              , Invalid                , None      , g_thread_child_entries),
    ENTRY_CHILDREN          ("target"              , Invalid                , None      , g_target_child_entries),
    ENTRY_CHILDREN_KEEP_SEP ("var"                 , Variable               , None      , g_var_child_entries),
};

static FormatEntity::Entry::Definition g_root = ENTRY_CHILDREN ("<root>", Root, None, g_top_level_entries);


FormatEntity::Entry::Entry (llvm::StringRef s) :
    string (s.data(), s.size()),
    printf_format (),
    children (),
    definition (NULL),
    type (Type::String),
    fmt (lldb::eFormatDefault),
    number (0),
    deref (false)
{
}

FormatEntity::Entry::Entry (char ch) :
    string (1, ch),
    printf_format (),
    children (),
    definition (NULL),
    type (Type::String),
    fmt (lldb::eFormatDefault),
    number (0),
    deref (false)
{
}

void
FormatEntity::Entry::AppendChar (char ch)
{
    if (children.empty() || children.back().type != Entry::Type::String)
        children.push_back(Entry(ch));
    else
        children.back().string.append(1, ch);
}

void
FormatEntity::Entry::AppendText (const llvm::StringRef &s)
{
    if (children.empty() || children.back().type != Entry::Type::String)
        children.push_back(Entry(s));
    else
        children.back().string.append(s.data(), s.size());
}

void
FormatEntity::Entry::AppendText (const char *cstr)
{
    return AppendText (llvm::StringRef(cstr));
}


Error
FormatEntity::Parse (const llvm::StringRef &format_str, Entry &entry)
{
    entry.Clear();
    entry.type = Entry::Type::Root;
    llvm::StringRef modifiable_format (format_str);
    return ParseInternal (modifiable_format, entry, 0);
}

#define ENUM_TO_CSTR(eee) case FormatEntity::Entry::Type::eee: return #eee

const char *
FormatEntity::Entry::TypeToCString (Type t)
{
    switch (t)
    {
    ENUM_TO_CSTR(Invalid);
    ENUM_TO_CSTR(ParentNumber);
    ENUM_TO_CSTR(ParentString);
    ENUM_TO_CSTR(InsertString);
    ENUM_TO_CSTR(Root);
    ENUM_TO_CSTR(String);
    ENUM_TO_CSTR(Scope);
    ENUM_TO_CSTR(Variable);
    ENUM_TO_CSTR(VariableSynthetic);
    ENUM_TO_CSTR(ScriptVariable);
    ENUM_TO_CSTR(ScriptVariableSynthetic);
    ENUM_TO_CSTR(AddressLoad);
    ENUM_TO_CSTR(AddressFile);
    ENUM_TO_CSTR(AddressLoadOrFile);
    ENUM_TO_CSTR(ProcessID);
    ENUM_TO_CSTR(ProcessFile);
    ENUM_TO_CSTR(ScriptProcess);
    ENUM_TO_CSTR(ThreadID);
    ENUM_TO_CSTR(ThreadProtocolID);
    ENUM_TO_CSTR(ThreadIndexID);
    ENUM_TO_CSTR(ThreadName);
    ENUM_TO_CSTR(ThreadQueue);
    ENUM_TO_CSTR(ThreadStopReason);
    ENUM_TO_CSTR(ThreadReturnValue);
    ENUM_TO_CSTR(ThreadCompletedExpression);
    ENUM_TO_CSTR(ScriptThread);
    ENUM_TO_CSTR(ThreadInfo);
    ENUM_TO_CSTR(TargetArch);
    ENUM_TO_CSTR(ScriptTarget);
    ENUM_TO_CSTR(ModuleFile);
    ENUM_TO_CSTR(File);
    ENUM_TO_CSTR(FrameIndex);
    ENUM_TO_CSTR(FrameRegisterPC);
    ENUM_TO_CSTR(FrameRegisterSP);
    ENUM_TO_CSTR(FrameRegisterFP);
    ENUM_TO_CSTR(FrameRegisterFlags);
    ENUM_TO_CSTR(FrameRegisterByName);
    ENUM_TO_CSTR(ScriptFrame);
    ENUM_TO_CSTR(FunctionID);
    ENUM_TO_CSTR(FunctionDidChange);
    ENUM_TO_CSTR(FunctionInitialFunction);
    ENUM_TO_CSTR(FunctionName);
    ENUM_TO_CSTR(FunctionNameWithArgs);
    ENUM_TO_CSTR(FunctionNameNoArgs);
    ENUM_TO_CSTR(FunctionAddrOffset);
    ENUM_TO_CSTR(FunctionAddrOffsetConcrete);
    ENUM_TO_CSTR(FunctionLineOffset);
    ENUM_TO_CSTR(FunctionPCOffset);
    ENUM_TO_CSTR(FunctionInitial);
    ENUM_TO_CSTR(FunctionChanged);
    ENUM_TO_CSTR(LineEntryFile);
    ENUM_TO_CSTR(LineEntryLineNumber);
    ENUM_TO_CSTR(LineEntryStartAddress);
    ENUM_TO_CSTR(LineEntryEndAddress);
    ENUM_TO_CSTR(CurrentPCArrow);
    }
    return "???";
}

#undef ENUM_TO_CSTR

void
FormatEntity::Entry::Dump (Stream &s, int depth) const
{
    s.Printf ("%*.*s%-20s: ", depth * 2, depth * 2, "", TypeToCString(type));
    if (fmt != eFormatDefault)
        s.Printf ("lldb-format = %s, ", FormatManager::GetFormatAsCString (fmt));
    if (!string.empty())
        s.Printf ("string = \"%s\"", string.c_str());
    if (!printf_format.empty())
        s.Printf ("printf_format = \"%s\"", printf_format.c_str());
    if (number != 0)
        s.Printf ("number = %" PRIu64 " (0x%" PRIx64 "), ", number, number);
    if (deref)
        s.Printf ("deref = true, ");
    s.EOL();
    for (const auto &child : children)
    {
        child.Dump(s, depth + 1);
    }
}


template <typename T>
static bool RunScriptFormatKeyword(Stream &s,
                                   const SymbolContext *sc,
                                   const ExecutionContext *exe_ctx,
                                   T t,
                                   const char *script_function_name)
{
    Target *target = Target::GetTargetFromContexts (exe_ctx, sc);

    if (target)
    {
        ScriptInterpreter *script_interpreter = target->GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
        if (script_interpreter)
        {
            Error error;
            std::string script_output;

            if (script_interpreter->RunScriptFormatKeyword(script_function_name, t, script_output, error) && error.Success())
            {
                s.Printf("%s", script_output.c_str());
                return true;
            }
            else
            {
                s.Printf("<error: %s>",error.AsCString());
            }
        }
    }
    return false;
}

static bool
DumpAddress (Stream &s,
             const SymbolContext *sc,
             const ExecutionContext *exe_ctx,
             const Address &addr,
             bool print_file_addr_or_load_addr)
{
    Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
    addr_t vaddr = LLDB_INVALID_ADDRESS;
    if (exe_ctx && !target->GetSectionLoadList().IsEmpty())
        vaddr = addr.GetLoadAddress (target);
    if (vaddr == LLDB_INVALID_ADDRESS)
        vaddr = addr.GetFileAddress ();

    if (vaddr != LLDB_INVALID_ADDRESS)
    {
        int addr_width = 0;
        if (exe_ctx && target)
        {
            addr_width = target->GetArchitecture().GetAddressByteSize() * 2;
        }
        if (addr_width == 0)
            addr_width = 16;
        if (print_file_addr_or_load_addr)
        {
            ExecutionContextScope *exe_scope = NULL;
            if (exe_ctx)
                exe_scope = exe_ctx->GetBestExecutionContextScope();
            addr.Dump (&s, exe_scope, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress, 0);
        }
        else
        {
            s.Printf("0x%*.*" PRIx64, addr_width, addr_width, vaddr);
        }
        return true;
    }
    return false;
}

static bool
DumpAddressOffsetFromFunction (Stream &s,
                               const SymbolContext *sc,
                               const ExecutionContext *exe_ctx,
                               const Address &format_addr,
                               bool concrete_only,
                               bool no_padding,
                               bool print_zero_offsets)
{
    if (format_addr.IsValid())
    {
        Address func_addr;
        
        if (sc)
        {
            if (sc->function)
            {
                func_addr = sc->function->GetAddressRange().GetBaseAddress();
                if (sc->block && !concrete_only)
                {
                    // Check to make sure we aren't in an inline
                    // function. If we are, use the inline block
                    // range that contains "format_addr" since
                    // blocks can be discontiguous.
                    Block *inline_block = sc->block->GetContainingInlinedBlock ();
                    AddressRange inline_range;
                    if (inline_block && inline_block->GetRangeContainingAddress (format_addr, inline_range))
                        func_addr = inline_range.GetBaseAddress();
                }
            }
            else if (sc->symbol && sc->symbol->ValueIsAddress())
                func_addr = sc->symbol->GetAddress();
        }

        if (func_addr.IsValid())
        {
            const char *addr_offset_padding = no_padding ? "" : " ";

            if (func_addr.GetSection() == format_addr.GetSection())
            {
                addr_t func_file_addr = func_addr.GetFileAddress();
                addr_t addr_file_addr = format_addr.GetFileAddress();
                if (addr_file_addr > func_file_addr
                    || (addr_file_addr == func_file_addr && print_zero_offsets))
                {
                    s.Printf("%s+%s%" PRIu64, addr_offset_padding, addr_offset_padding, addr_file_addr - func_file_addr);
                }
                else if (addr_file_addr < func_file_addr)
                {
                    s.Printf("%s-%s%" PRIu64, addr_offset_padding, addr_offset_padding, func_file_addr - addr_file_addr);
                }
                return true;
            }
            else
            {
                Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
                if (target)
                {
                    addr_t func_load_addr = func_addr.GetLoadAddress (target);
                    addr_t addr_load_addr = format_addr.GetLoadAddress (target);
                    if (addr_load_addr > func_load_addr
                        || (addr_load_addr == func_load_addr && print_zero_offsets))
                    {
                        s.Printf("%s+%s%" PRIu64, addr_offset_padding, addr_offset_padding, addr_load_addr - func_load_addr);
                    }
                    else if (addr_load_addr < func_load_addr)
                    {
                        s.Printf("%s-%s%" PRIu64, addr_offset_padding, addr_offset_padding, func_load_addr - addr_load_addr);
                    }
                    return true;
                }
            }
        }
    }
    return false;
}

static bool
ScanBracketedRange (llvm::StringRef subpath,
                    size_t& close_bracket_index,
                    const char*& var_name_final_if_array_range,
                    int64_t& index_lower,
                    int64_t& index_higher)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
    close_bracket_index = llvm::StringRef::npos;
    const size_t open_bracket_index = subpath.find('[');
    if (open_bracket_index == llvm::StringRef::npos)
    {
        if (log)
            log->Printf("[ScanBracketedRange] no bracketed range, skipping entirely");
        return false;
    }

    close_bracket_index = subpath.find(']', open_bracket_index + 1);

    if (close_bracket_index == llvm::StringRef::npos)
    {
        if (log)
            log->Printf("[ScanBracketedRange] no bracketed range, skipping entirely");
        return false;
    }
    else
    {
        var_name_final_if_array_range = subpath.data() + open_bracket_index;

        if (close_bracket_index - open_bracket_index == 1)
        {
            if (log)
                log->Printf("[ScanBracketedRange] '[]' detected.. going from 0 to end of data");
            index_lower = 0;
        }
        else
        {
            const size_t separator_index = subpath.find('-', open_bracket_index + 1);

            if (separator_index == llvm::StringRef::npos)
            {
                const char *index_lower_cstr = subpath.data() + open_bracket_index + 1;
                index_lower = ::strtoul (index_lower_cstr, NULL, 0);
                index_higher = index_lower;
                if (log)
                    log->Printf("[ScanBracketedRange] [%" PRId64 "] detected, high index is same", index_lower);
            }
            else
            {
                const char *index_lower_cstr = subpath.data() + open_bracket_index + 1;
                const char *index_higher_cstr = subpath.data() + separator_index + 1;
                index_lower = ::strtoul (index_lower_cstr, NULL, 0);
                index_higher = ::strtoul (index_higher_cstr, NULL, 0);
                if (log)
                    log->Printf("[ScanBracketedRange] [%" PRId64 "-%" PRId64 "] detected", index_lower, index_higher);
            }
            if (index_lower > index_higher && index_higher > 0)
            {
                if (log)
                    log->Printf("[ScanBracketedRange] swapping indices");
                const int64_t temp = index_lower;
                index_lower = index_higher;
                index_higher = temp;
            }
        }
    }
    return true;
}

static bool
DumpFile (Stream &s, const FileSpec &file, FileKind file_kind)
{
    switch (file_kind)
    {
    case FileKind::FileError:
        break;

    case FileKind::Basename:
        if (file.GetFilename())
        {
            s << file.GetFilename();
            return true;
        }
        break;

    case FileKind::Dirname:
        if (file.GetDirectory())
        {
            s << file.GetDirectory();
            return true;
        }
        break;

    case FileKind::Fullpath:
        if (file)
        {
            s << file;
            return true;
        }
        break;
    }
    return false;
}

static bool
DumpRegister (Stream &s,
              StackFrame *frame,
              RegisterKind reg_kind,
              uint32_t reg_num,
              Format format)

{
    if (frame)
    {
        RegisterContext *reg_ctx = frame->GetRegisterContext().get();

        if (reg_ctx)
        {
            const uint32_t lldb_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(reg_kind, reg_num);
            if (lldb_reg_num != LLDB_INVALID_REGNUM)
            {
                const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex (lldb_reg_num);
                if (reg_info)
                {
                    RegisterValue reg_value;
                    if (reg_ctx->ReadRegister (reg_info, reg_value))
                    {
                        reg_value.Dump(&s, reg_info, false, false, format);
                        return true;
                    }
                }
            }
        }
    }
    return false;
}


static ValueObjectSP
ExpandIndexedExpression (ValueObject* valobj,
                         size_t index,
                         StackFrame* frame,
                         bool deref_pointer)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
    const char* ptr_deref_format = "[%d]";
    std::string ptr_deref_buffer(10,0);
    ::sprintf(&ptr_deref_buffer[0], ptr_deref_format, index);
    if (log)
        log->Printf("[ExpandIndexedExpression] name to deref: %s",ptr_deref_buffer.c_str());
    const char* first_unparsed;
    ValueObject::GetValueForExpressionPathOptions options;
    ValueObject::ExpressionPathEndResultType final_value_type;
    ValueObject::ExpressionPathScanEndReason reason_to_stop;
    ValueObject::ExpressionPathAftermath what_next = (deref_pointer ? ValueObject::eExpressionPathAftermathDereference : ValueObject::eExpressionPathAftermathNothing);
    ValueObjectSP item = valobj->GetValueForExpressionPath (ptr_deref_buffer.c_str(),
                                                            &first_unparsed,
                                                            &reason_to_stop,
                                                            &final_value_type,
                                                            options,
                                                            &what_next);
    if (!item)
    {
        if (log)
            log->Printf("[ExpandIndexedExpression] ERROR: unparsed portion = %s, why stopping = %d,"
                        " final_value_type %d",
                        first_unparsed, reason_to_stop, final_value_type);
    }
    else
    {
        if (log)
            log->Printf("[ExpandIndexedExpression] ALL RIGHT: unparsed portion = %s, why stopping = %d,"
                        " final_value_type %d",
                        first_unparsed, reason_to_stop, final_value_type);
    }
    return item;
}

static char
ConvertValueObjectStyleToChar(ValueObject::ValueObjectRepresentationStyle style)
{
    switch (style)
    {
        case ValueObject::eValueObjectRepresentationStyleLanguageSpecific:  return '@';
        case ValueObject::eValueObjectRepresentationStyleValue:             return 'V';
        case ValueObject::eValueObjectRepresentationStyleLocation:          return 'L';
        case ValueObject::eValueObjectRepresentationStyleSummary:           return 'S';
        case ValueObject::eValueObjectRepresentationStyleChildrenCount:     return '#';
        case ValueObject::eValueObjectRepresentationStyleType:              return 'T';
        case ValueObject::eValueObjectRepresentationStyleName:              return 'N';
        case ValueObject::eValueObjectRepresentationStyleExpressionPath:    return '>';
    }
    return '\0';
}

static bool
DumpValue (Stream &s,
           const SymbolContext *sc,
           const ExecutionContext *exe_ctx,
           const FormatEntity::Entry &entry,
           ValueObject *valobj)
{
    if (valobj == NULL)
        return false;

    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
    Format custom_format = eFormatInvalid;
    ValueObject::ValueObjectRepresentationStyle val_obj_display = entry.string.empty() ? ValueObject::eValueObjectRepresentationStyleValue : ValueObject::eValueObjectRepresentationStyleSummary;

    bool do_deref_pointer = entry.deref;
    bool is_script = false;
    switch (entry.type)
    {
        case FormatEntity::Entry::Type::ScriptVariable:
            is_script = true;
            break;

        case FormatEntity::Entry::Type::Variable:
            custom_format = entry.fmt;
            val_obj_display = (ValueObject::ValueObjectRepresentationStyle)entry.number;
            break;

        case FormatEntity::Entry::Type::ScriptVariableSynthetic:
            is_script = true;
            // Fall through
        case FormatEntity::Entry::Type::VariableSynthetic:
            custom_format = entry.fmt;
            val_obj_display = (ValueObject::ValueObjectRepresentationStyle)entry.number;
            if (!valobj->IsSynthetic())
            {
                valobj = valobj->GetSyntheticValue().get();
                if (valobj == nullptr)
                    return false;
            }
            break;

        default:
            return false;
    }

    if (valobj == NULL)
        return false;

    ValueObject::ExpressionPathAftermath what_next = (do_deref_pointer ?
                                                      ValueObject::eExpressionPathAftermathDereference : ValueObject::eExpressionPathAftermathNothing);
    ValueObject::GetValueForExpressionPathOptions options;
    options.DontCheckDotVsArrowSyntax().DoAllowBitfieldSyntax().DoAllowFragileIVar().SetSyntheticChildrenTraversal(ValueObject::GetValueForExpressionPathOptions::SyntheticChildrenTraversal::Both);
    ValueObject* target = NULL;
    const char* var_name_final_if_array_range = NULL;
    size_t close_bracket_index = llvm::StringRef::npos;
    int64_t index_lower = -1;
    int64_t index_higher = -1;
    bool is_array_range = false;
    const char* first_unparsed;
    bool was_plain_var = false;
    bool was_var_format = false;
    bool was_var_indexed = false;
    ValueObject::ExpressionPathScanEndReason reason_to_stop = ValueObject::eExpressionPathScanEndReasonEndOfString;
    ValueObject::ExpressionPathEndResultType final_value_type = ValueObject::eExpressionPathEndResultTypePlain;

    if (is_script)
    {
        return RunScriptFormatKeyword (s, sc, exe_ctx, valobj, entry.string.c_str());
    }

    llvm::StringRef subpath (entry.string);
    // simplest case ${var}, just print valobj's value
    if (entry.string.empty())
    {
        if (entry.printf_format.empty() && entry.fmt == eFormatDefault && entry.number == ValueObject::eValueObjectRepresentationStyleValue)
            was_plain_var = true;
        else
            was_var_format = true;
        target = valobj;
    }
    else    // this is ${var.something} or multiple .something nested
    {
        if (entry.string[0] == '[')
            was_var_indexed = true;
        ScanBracketedRange (subpath,
                            close_bracket_index,
                            var_name_final_if_array_range,
                            index_lower,
                            index_higher);

        Error error;

        const std::string &expr_path = entry.string;

        if (log)
            log->Printf("[Debugger::FormatPrompt] symbol to expand: %s",expr_path.c_str());

        target = valobj->GetValueForExpressionPath(expr_path.c_str(),
                                                   &first_unparsed,
                                                   &reason_to_stop,
                                                   &final_value_type,
                                                   options,
                                                   &what_next).get();

        if (!target)
        {
            if (log)
                log->Printf("[Debugger::FormatPrompt] ERROR: unparsed portion = %s, why stopping = %d,"
                            " final_value_type %d",
                            first_unparsed, reason_to_stop, final_value_type);
            return false;
        }
        else
        {
            if (log)
                log->Printf("[Debugger::FormatPrompt] ALL RIGHT: unparsed portion = %s, why stopping = %d,"
                            " final_value_type %d",
                            first_unparsed, reason_to_stop, final_value_type);
            target = target->GetQualifiedRepresentationIfAvailable(target->GetDynamicValueType(), true).get();
        }
    }


    is_array_range = (final_value_type == ValueObject::eExpressionPathEndResultTypeBoundedRange ||
                      final_value_type == ValueObject::eExpressionPathEndResultTypeUnboundedRange);

    do_deref_pointer = (what_next == ValueObject::eExpressionPathAftermathDereference);

    if (do_deref_pointer && !is_array_range)
    {
        // I have not deref-ed yet, let's do it
        // this happens when we are not going through GetValueForVariableExpressionPath
        // to get to the target ValueObject
        Error error;
        target = target->Dereference(error).get();
        if (error.Fail())
        {
            if (log)
                log->Printf("[Debugger::FormatPrompt] ERROR: %s\n", error.AsCString("unknown")); \
            return false;
        }
        do_deref_pointer = false;
    }

    if (!target)
    {
        if (log)
            log->Printf("[Debugger::FormatPrompt] could not calculate target for prompt expression");
        return false;
    }

    // we do not want to use the summary for a bitfield of type T:n
    // if we were originally dealing with just a T - that would get
    // us into an endless recursion
    if (target->IsBitfield() && was_var_indexed)
    {
        // TODO: check for a (T:n)-specific summary - we should still obey that
        StreamString bitfield_name;
        bitfield_name.Printf("%s:%d", target->GetTypeName().AsCString(), target->GetBitfieldBitSize());
        lldb::TypeNameSpecifierImplSP type_sp(new TypeNameSpecifierImpl(bitfield_name.GetData(),false));
        if (val_obj_display == ValueObject::eValueObjectRepresentationStyleSummary && !DataVisualization::GetSummaryForType(type_sp))
            val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
    }

    // TODO use flags for these
    const uint32_t type_info_flags = target->GetClangType().GetTypeInfo(NULL);
    bool is_array = (type_info_flags & eTypeIsArray) != 0;
    bool is_pointer = (type_info_flags & eTypeIsPointer) != 0;
    bool is_aggregate = target->GetClangType().IsAggregateType();

    if ((is_array || is_pointer) && (!is_array_range) && val_obj_display == ValueObject::eValueObjectRepresentationStyleValue) // this should be wrong, but there are some exceptions
    {
        StreamString str_temp;
        if (log)
            log->Printf("[Debugger::FormatPrompt] I am into array || pointer && !range");

        if (target->HasSpecialPrintableRepresentation(val_obj_display, custom_format))
        {
            // try to use the special cases
            bool success = target->DumpPrintableRepresentation(str_temp,
                                                               val_obj_display,
                                                               custom_format);
            if (log)
                log->Printf("[Debugger::FormatPrompt] special cases did%s match", success ? "" : "n't");

            // should not happen
            if (success)
                s << str_temp.GetData();
            return true;
        }
        else
        {
            if (was_plain_var) // if ${var}
            {
                s << target->GetTypeName() << " @ " << target->GetLocationAsCString();
            }
            else if (is_pointer) // if pointer, value is the address stored
            {
                target->DumpPrintableRepresentation (s,
                                                     val_obj_display,
                                                     custom_format,
                                                     ValueObject::ePrintableRepresentationSpecialCasesDisable);
            }
            return true;
        }
    }

    // if directly trying to print ${var}, and this is an aggregate, display a nice
    // type @ location message
    if (is_aggregate && was_plain_var)
    {
        s << target->GetTypeName() << " @ " << target->GetLocationAsCString();
        return true;
    }

    // if directly trying to print ${var%V}, and this is an aggregate, do not let the user do it
    if (is_aggregate && ((was_var_format && val_obj_display == ValueObject::eValueObjectRepresentationStyleValue)))
    {
        s << "<invalid use of aggregate type>";
        return true;
    }

    if (!is_array_range)
    {
        if (log)
            log->Printf("[Debugger::FormatPrompt] dumping ordinary printable output");
        return target->DumpPrintableRepresentation(s,val_obj_display, custom_format);
    }
    else
    {
        if (log)
            log->Printf("[Debugger::FormatPrompt] checking if I can handle as array");
        if (!is_array && !is_pointer)
            return false;
        if (log)
            log->Printf("[Debugger::FormatPrompt] handle as array");
        StreamString special_directions_stream;
        llvm::StringRef special_directions;
        if (close_bracket_index != llvm::StringRef::npos && subpath.size() > close_bracket_index)
        {
            ConstString additional_data (subpath.drop_front(close_bracket_index+1));
            special_directions_stream.Printf("${%svar%s",
                                             do_deref_pointer ? "*" : "",
                                             additional_data.GetCString());

            if (entry.fmt != eFormatDefault)
            {
                const char format_char = FormatManager::GetFormatAsFormatChar(entry.fmt);
                if (format_char != '\0')
                    special_directions_stream.Printf("%%%c", format_char);
                else
                {
                    const char *format_cstr = FormatManager::GetFormatAsCString(entry.fmt);
                    special_directions_stream.Printf("%%%s", format_cstr);
                }
            }
            else if (entry.number != 0)
            {
                const char style_char = ConvertValueObjectStyleToChar ((ValueObject::ValueObjectRepresentationStyle)entry.number);
                if (style_char)
                    special_directions_stream.Printf("%%%c", style_char);
            }
            special_directions_stream.PutChar('}');
            special_directions = llvm::StringRef(special_directions_stream.GetString());
        }

        // let us display items index_lower thru index_higher of this array
        s.PutChar('[');

        if (index_higher < 0)
            index_higher = valobj->GetNumChildren() - 1;

        uint32_t max_num_children = target->GetTargetSP()->GetMaximumNumberOfChildrenToDisplay();

        bool success = true;
        for (int64_t index = index_lower;index<=index_higher; ++index)
        {
            ValueObject* item = ExpandIndexedExpression (target,
                                                         index,
                                                         exe_ctx->GetFramePtr(),
                                                         false).get();

            if (!item)
            {
                if (log)
                    log->Printf("[Debugger::FormatPrompt] ERROR in getting child item at index %" PRId64, index);
            }
            else
            {
                if (log)
                    log->Printf("[Debugger::FormatPrompt] special_directions for child item: %s",special_directions.data() ? special_directions.data() : "");
            }

            if (special_directions.empty())
            {
                success &= item->DumpPrintableRepresentation(s,val_obj_display, custom_format);
            }
            else
            {
                success &= FormatEntity::FormatStringRef(special_directions, s, sc, exe_ctx, NULL, item, false, false);
            }

            if (--max_num_children == 0)
            {
                s.PutCString(", ...");
                break;
            }

            if (index < index_higher)
                s.PutChar(',');
        }
        s.PutChar(']');
        return success;
    }

}

static bool
DumpRegister (Stream &s,
              StackFrame *frame,
              const char *reg_name,
              Format format)

{
    if (frame)
    {
        RegisterContext *reg_ctx = frame->GetRegisterContext().get();

        if (reg_ctx)
        {
            const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(reg_name);
            if (reg_info)
            {
                RegisterValue reg_value;
                if (reg_ctx->ReadRegister (reg_info, reg_value))
                {
                    reg_value.Dump(&s, reg_info, false, false, format);
                    return true;
                }
            }
        }
    }
    return false;
}

static bool
FormatThreadExtendedInfoRecurse(const FormatEntity::Entry &entry,
                                const StructuredData::ObjectSP &thread_info_dictionary,
                                const SymbolContext *sc,
                                const ExecutionContext *exe_ctx,
                                Stream &s)
{
    llvm::StringRef path(entry.string);

    StructuredData::ObjectSP value = thread_info_dictionary->GetObjectForDotSeparatedPath (path);

    if (value.get())
    {
        if (value->GetType() == StructuredData::Type::eTypeInteger)
        {
            const char *token_format = "0x%4.4" PRIx64;
            if (!entry.printf_format.empty())
                token_format = entry.printf_format.c_str();
            s.Printf(token_format, value->GetAsInteger()->GetValue());
            return true;
        }
        else if (value->GetType() == StructuredData::Type::eTypeFloat)
        {
            s.Printf ("%f", value->GetAsFloat()->GetValue());
            return true;
        }
        else if (value->GetType() == StructuredData::Type::eTypeString)
        {
            s.Printf("%s", value->GetAsString()->GetValue().c_str());
            return true;
        }
        else if (value->GetType() == StructuredData::Type::eTypeArray)
        {
            if (value->GetAsArray()->GetSize() > 0)
            {
                s.Printf ("%zu", value->GetAsArray()->GetSize());
                return true;
            }
        }
        else if (value->GetType() == StructuredData::Type::eTypeDictionary)
        {
            s.Printf ("%zu", value->GetAsDictionary()->GetKeys()->GetAsArray()->GetSize());
            return true;
        }
    }

    return false;
}


static inline bool
IsToken(const char *var_name_begin, const char *var)
{
    return (::strncmp (var_name_begin, var, strlen(var)) == 0);
}

bool
FormatEntity::FormatStringRef (const llvm::StringRef &format_str,
                               Stream &s,
                               const SymbolContext *sc,
                               const ExecutionContext *exe_ctx,
                               const Address *addr,
                               ValueObject* valobj,
                               bool function_changed,
                               bool initial_function)
{
    if (!format_str.empty())
    {
        FormatEntity::Entry root;
        Error error = FormatEntity::Parse(format_str, root);
        if (error.Success())
        {
            return FormatEntity::Format (root,
                                         s,
                                         sc,
                                         exe_ctx,
                                         addr,
                                         valobj,
                                         function_changed,
                                         initial_function);
        }
    }
    return false;

}
bool
FormatEntity::FormatCString (const char *format,
                             Stream &s,
                             const SymbolContext *sc,
                             const ExecutionContext *exe_ctx,
                             const Address *addr,
                             ValueObject* valobj,
                             bool function_changed,
                             bool initial_function)
{
    if (format && format[0])
    {
        FormatEntity::Entry root;
        llvm::StringRef format_str(format);
        Error error = FormatEntity::Parse(format_str, root);
        if (error.Success())
        {
            return FormatEntity::Format (root,
                                         s,
                                         sc,
                                         exe_ctx,
                                         addr,
                                         valobj,
                                         function_changed,
                                         initial_function);
        }
    }
    return false;
}

bool
FormatEntity::Format (const Entry &entry,
                      Stream &s,
                      const SymbolContext *sc,
                      const ExecutionContext *exe_ctx,
                      const Address *addr,
                      ValueObject* valobj,
                      bool function_changed,
                      bool initial_function)
{
    switch (entry.type)
    {
        case Entry::Type::Invalid:
        case Entry::Type::ParentNumber: // Only used for FormatEntity::Entry::Definition encoding
        case Entry::Type::ParentString: // Only used for FormatEntity::Entry::Definition encoding
        case Entry::Type::InsertString: // Only used for FormatEntity::Entry::Definition encoding
            return false;

        case Entry::Type::Root:
            for (const auto &child : entry.children)
            {
                if (Format (child,
                            s,
                            sc,
                            exe_ctx,
                            addr,
                            valobj,
                            function_changed,
                            initial_function) == false)
                {
                    return false; // If any item of root fails, then the formatting fails
                }
            }
            return true; // Only return true if all items succeeded

        case Entry::Type::String:
            s.PutCString(entry.string.c_str());
            return true;

        case Entry::Type::Scope:
            {
                StreamString scope_stream;
                bool success = false;
                for (const auto &child : entry.children)
                {
                    success = Format (child, scope_stream, sc, exe_ctx, addr, valobj, function_changed, initial_function);
                    if (!success)
                        break;
                }
                // Only if all items in a scope succeed, then do we
                // print the output into the main stream
                if (success)
                    s.Write(scope_stream.GetString().data(), scope_stream.GetString().size());
            }
            return true; // Scopes always successfully print themselves

        case Entry::Type::Variable:
        case Entry::Type::VariableSynthetic:
        case Entry::Type::ScriptVariable:
        case Entry::Type::ScriptVariableSynthetic:
            if (DumpValue(s, sc, exe_ctx, entry, valobj))
                return true;
            return false;

        case Entry::Type::AddressFile:
        case Entry::Type::AddressLoad:
        case Entry::Type::AddressLoadOrFile:
            if (addr && addr->IsValid() && DumpAddress(s, sc, exe_ctx, *addr, entry.type == Entry::Type::AddressLoadOrFile))
                return true;
            return false;

        case Entry::Type::ProcessID:
            if (exe_ctx)
            {
                Process *process = exe_ctx->GetProcessPtr();
                if (process)
                {
                    const char *format = "%" PRIu64;
                    if (!entry.printf_format.empty())
                        format = entry.printf_format.c_str();
                    s.Printf(format, process->GetID());
                    return true;
                }
            }
            return false;

        case Entry::Type::ProcessFile:
            if (exe_ctx)
            {
                Process *process = exe_ctx->GetProcessPtr();
                if (process)
                {
                    Module *exe_module = process->GetTarget().GetExecutableModulePointer();
                    if (exe_module)
                    {
                        if (DumpFile(s, exe_module->GetFileSpec(), (FileKind)entry.number))
                            return true;
                    }
                }
            }
            return false;

        case Entry::Type::ScriptProcess:
            if (exe_ctx)
            {
                Process *process = exe_ctx->GetProcessPtr();
                if (process)
                    return RunScriptFormatKeyword (s, sc, exe_ctx, process, entry.string.c_str());
            }
            return false;


        case Entry::Type::ThreadID:
            if (exe_ctx)
            {
                Thread *thread = exe_ctx->GetThreadPtr();
                if (thread)
                {
                    const char *format = "0x%4.4" PRIx64;
                    if (!entry.printf_format.empty())
                    {
                        // Watch for the special "tid" format...
                        if (entry.printf_format == "tid")
                        {
                            bool handled = false;
                            Target &target = thread->GetProcess()->GetTarget();
                            ArchSpec arch (target.GetArchitecture ());
                            llvm::Triple::OSType ostype = arch.IsValid() ? arch.GetTriple().getOS() : llvm::Triple::UnknownOS;
                            if ((ostype == llvm::Triple::FreeBSD) || (ostype == llvm::Triple::Linux))
                            {
                                handled = true;
                                format = "%" PRIu64;
                            }
                        }
                        else
                        {
                            format = entry.printf_format.c_str();
                        }
                    }
                    s.Printf(format, thread->GetID());
                    return true;
                }
            }
            return false;

        case Entry::Type::ThreadProtocolID:
            if (exe_ctx)
            {
                Thread *thread = exe_ctx->GetThreadPtr();
                if (thread)
                {
                    const char *format = "0x%4.4" PRIx64;
                    if (!entry.printf_format.empty())
                        format = entry.printf_format.c_str();
                    s.Printf(format, thread->GetProtocolID());
                    return true;
                }
            }
            return false;

        case Entry::Type::ThreadIndexID:
            if (exe_ctx)
            {
                Thread *thread = exe_ctx->GetThreadPtr();
                if (thread)
                {
                    const char *format = "%" PRIu32;
                    if (!entry.printf_format.empty())
                        format = entry.printf_format.c_str();
                    s.Printf(format, thread->GetIndexID());
                    return true;
                }
            }
            return false;

        case Entry::Type::ThreadName:
            if (exe_ctx)
            {
                Thread *thread = exe_ctx->GetThreadPtr();
                if (thread)
                {
                    const char *cstr = thread->GetName();
                    if (cstr && cstr[0])
                    {
                        s.PutCString(cstr);
                        return true;
                    }
                }
            }
            return false;

        case Entry::Type::ThreadQueue:
            if (exe_ctx)
            {
                Thread *thread = exe_ctx->GetThreadPtr();
                if (thread)
                {
                    const char *cstr = thread->GetQueueName();
                    if (cstr && cstr[0])
                    {
                        s.PutCString(cstr);
                        return true;
                    }
                }
            }
            return false;

        case Entry::Type::ThreadStopReason:
            if (exe_ctx)
            {
                Thread *thread = exe_ctx->GetThreadPtr();
                if (thread)
                {
                    StopInfoSP stop_info_sp = thread->GetStopInfo ();
                    if (stop_info_sp && stop_info_sp->IsValid())
                    {
                        const char *cstr = stop_info_sp->GetDescription();
                        if (cstr && cstr[0])
                        {
                            s.PutCString(cstr);
                            return true;
                        }
                    }
                }
            }
            return false;

        case Entry::Type::ThreadReturnValue:
            if (exe_ctx)
            {
                Thread *thread = exe_ctx->GetThreadPtr();
                if (thread)
                {
                    StopInfoSP stop_info_sp = thread->GetStopInfo ();
                    if (stop_info_sp && stop_info_sp->IsValid())
                    {
                        ValueObjectSP return_valobj_sp = StopInfo::GetReturnValueObject (stop_info_sp);
                        if (return_valobj_sp)
                        {
                            return_valobj_sp->Dump(s);
                            return true;
                        }
                    }
                }
            }
            return false;

        case Entry::Type::ThreadCompletedExpression:
            if (exe_ctx)
            {
                Thread *thread = exe_ctx->GetThreadPtr();
                if (thread)
                {
                    StopInfoSP stop_info_sp = thread->GetStopInfo ();
                    if (stop_info_sp && stop_info_sp->IsValid())
                    {
                        ClangExpressionVariableSP expression_var_sp = StopInfo::GetExpressionVariable (stop_info_sp);
                        if (expression_var_sp && expression_var_sp->GetValueObject())
                        {
                            expression_var_sp->GetValueObject()->Dump(s);
                            return true;
                        }
                    }
                }
            }
            return false;

        case Entry::Type::ScriptThread:
            if (exe_ctx)
            {
                Thread *thread = exe_ctx->GetThreadPtr();
                if (thread)
                    return RunScriptFormatKeyword (s, sc, exe_ctx, thread, entry.string.c_str());
            }
            return false;

        case Entry::Type::ThreadInfo:
            if (exe_ctx)
            {
                Thread *thread = exe_ctx->GetThreadPtr();
                if (thread)
                {
                    StructuredData::ObjectSP object_sp = thread->GetExtendedInfo();
                    if (object_sp && object_sp->GetType() == StructuredData::Type::eTypeDictionary)
                    {
                        if (FormatThreadExtendedInfoRecurse (entry, object_sp, sc, exe_ctx, s))
                            return true;
                    }
                }
            }
            return false;

        case Entry::Type::TargetArch:
            if (exe_ctx)
            {
                Target *target = exe_ctx->GetTargetPtr();
                if (target)
                {
                    const ArchSpec &arch = target->GetArchitecture ();
                    if (arch.IsValid())
                    {
                        s.PutCString (arch.GetArchitectureName());
                        return true;
                    }
                }
            }
            return false;

        case Entry::Type::ScriptTarget:
            if (exe_ctx)
            {
                Target *target = exe_ctx->GetTargetPtr();
                if (target)
                    return RunScriptFormatKeyword (s, sc, exe_ctx, target, entry.string.c_str());
            }
            return false;

        case Entry::Type::ModuleFile:
            if (sc)
            {
                Module *module = sc->module_sp.get();
                if (module)
                {
                    if (DumpFile(s, module->GetFileSpec(), (FileKind)entry.number))
                        return true;
                }
            }
            return false;

        case Entry::Type::File:
            if (sc)
            {
                CompileUnit *cu = sc->comp_unit;
                if (cu)
                {
                    // CompileUnit is a FileSpec
                    if (DumpFile(s, *cu, (FileKind)entry.number))
                        return true;
                }
            }
            return false;

        case Entry::Type::FrameIndex:
            if (exe_ctx)
            {
                StackFrame *frame = exe_ctx->GetFramePtr();
                if (frame)
                {
                    const char *format = "%" PRIu32;
                    if (!entry.printf_format.empty())
                        format = entry.printf_format.c_str();
                    s.Printf(format, frame->GetFrameIndex());
                    return true;
                }
            }
            return false;

        case Entry::Type::FrameRegisterPC:
            if (exe_ctx)
            {
                StackFrame *frame = exe_ctx->GetFramePtr();
                if (frame)
                {
                    const Address &pc_addr = frame->GetFrameCodeAddress();
                    if (pc_addr.IsValid())
                    {
                        if (DumpAddress(s, sc, exe_ctx, pc_addr, false))
                            return true;
                    }
                }
            }
            return false;

        case Entry::Type::FrameRegisterSP:
            if (exe_ctx)
            {
                StackFrame *frame = exe_ctx->GetFramePtr();
                if (frame)
                {
                    if (DumpRegister (s, frame, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, (lldb::Format)entry.number))
                        return true;
                }
            }
            return false;

        case Entry::Type::FrameRegisterFP:
            if (exe_ctx)
            {
                StackFrame *frame = exe_ctx->GetFramePtr();
                if (frame)
                {
                    if (DumpRegister (s, frame, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FP, (lldb::Format)entry.number))
                        return true;
                }
            }
            return false;

        case Entry::Type::FrameRegisterFlags:
            if (exe_ctx)
            {
                StackFrame *frame = exe_ctx->GetFramePtr();
                if (frame)
                {
                    if (DumpRegister (s, frame, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, (lldb::Format)entry.number))
                        return true;
                }
            }
            return false;


        case Entry::Type::FrameRegisterByName:
            if (exe_ctx)
            {
                StackFrame *frame = exe_ctx->GetFramePtr();
                if (frame)
                {
                    if (DumpRegister (s, frame, entry.string.c_str(), (lldb::Format)entry.number))
                        return true;
                }
            }
            return false;

        case Entry::Type::ScriptFrame:
            if (exe_ctx)
            {
                StackFrame *frame = exe_ctx->GetFramePtr();
                if (frame)
                    return RunScriptFormatKeyword (s, sc, exe_ctx, frame, entry.string.c_str());
            }
            return false;

        case Entry::Type::FunctionID:
            if (sc)
            {
                if (sc->function)
                {
                    s.Printf("function{0x%8.8" PRIx64 "}", sc->function->GetID());
                    return true;
                }
                else if (sc->symbol)
                {
                    s.Printf("symbol[%u]", sc->symbol->GetID());
                    return true;
                }
            }
            return false;

        case Entry::Type::FunctionDidChange:
            return function_changed;

        case Entry::Type::FunctionInitialFunction:
            return initial_function;

        case Entry::Type::FunctionName:
            {
                const char *name = NULL;
                if (sc->function)
                    name = sc->function->GetName().AsCString (NULL);
                else if (sc->symbol)
                    name = sc->symbol->GetName().AsCString (NULL);
                if (name)
                {
                    s.PutCString(name);

                    if (sc->block)
                    {
                        Block *inline_block = sc->block->GetContainingInlinedBlock ();
                        if (inline_block)
                        {
                            const InlineFunctionInfo *inline_info = sc->block->GetInlinedFunctionInfo();
                            if (inline_info)
                            {
                                s.PutCString(" [inlined] ");
                                inline_info->GetName().Dump(&s);
                            }
                        }
                    }
                    return true;
                }
            }
            return false;

        case Entry::Type::FunctionNameNoArgs:
            {
                ConstString name;
                if (sc->function)
                    name = sc->function->GetMangled().GetName (Mangled::ePreferDemangledWithoutArguments);
                else if (sc->symbol)
                    name = sc->symbol->GetMangled().GetName (Mangled::ePreferDemangledWithoutArguments);
                if (name)
                {
                    s.PutCString(name.GetCString());
                    return true;
                }
            }
            return false;

        case Entry::Type::FunctionNameWithArgs:
            {
                // Print the function name with arguments in it
                if (sc->function)
                {
                    ExecutionContextScope *exe_scope = exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL;
                    const char *cstr = sc->function->GetName().AsCString (NULL);
                    if (cstr)
                    {
                        const InlineFunctionInfo *inline_info = NULL;
                        VariableListSP variable_list_sp;
                        bool get_function_vars = true;
                        if (sc->block)
                        {
                            Block *inline_block = sc->block->GetContainingInlinedBlock ();

                            if (inline_block)
                            {
                                get_function_vars = false;
                                inline_info = sc->block->GetInlinedFunctionInfo();
                                if (inline_info)
                                    variable_list_sp = inline_block->GetBlockVariableList (true);
                            }
                        }

                        if (get_function_vars)
                        {
                            variable_list_sp = sc->function->GetBlock(true).GetBlockVariableList (true);
                        }

                        if (inline_info)
                        {
                            s.PutCString (cstr);
                            s.PutCString (" [inlined] ");
                            cstr = inline_info->GetName().GetCString();
                        }

                        VariableList args;
                        if (variable_list_sp)
                            variable_list_sp->AppendVariablesWithScope(eValueTypeVariableArgument, args);
                        if (args.GetSize() > 0)
                        {
                            const char *open_paren = strchr (cstr, '(');
                            const char *close_paren = nullptr;
                            const char *generic = strchr(cstr, '<');
                            // if before the arguments list begins there is a template sign
                            // then scan to the end of the generic args before you try to find
                            // the arguments list
                            if (generic && open_paren && generic < open_paren)
                            {
                                int generic_depth = 1;
                                ++generic;
                                for (;
                                     *generic && generic_depth > 0;
                                     generic++)
                                {
                                    if (*generic == '<')
                                        generic_depth++;
                                    if (*generic == '>')
                                        generic_depth--;
                                }
                                if (*generic)
                                    open_paren = strchr(generic, '(');
                                else
                                    open_paren = nullptr;
                            }
                            if (open_paren)
                            {
                                if (IsToken (open_paren, "(anonymous namespace)"))
                                {
                                    open_paren = strchr (open_paren + strlen("(anonymous namespace)"), '(');
                                    if (open_paren)
                                        close_paren = strchr (open_paren, ')');
                                }
                                else
                                    close_paren = strchr (open_paren, ')');
                            }

                            if (open_paren)
                                s.Write(cstr, open_paren - cstr + 1);
                            else
                            {
                                s.PutCString (cstr);
                                s.PutChar ('(');
                            }
                            const size_t num_args = args.GetSize();
                            for (size_t arg_idx = 0; arg_idx < num_args; ++arg_idx)
                            {
                                std::string buffer;

                                VariableSP var_sp (args.GetVariableAtIndex (arg_idx));
                                ValueObjectSP var_value_sp (ValueObjectVariable::Create (exe_scope, var_sp));
                                const char *var_representation = nullptr;
                                const char *var_name = var_value_sp->GetName().GetCString();
                                if (var_value_sp->GetClangType().IsAggregateType() &&
                                    DataVisualization::ShouldPrintAsOneLiner(*var_value_sp.get()))
                                {
                                    static StringSummaryFormat format(TypeSummaryImpl::Flags()
                                                                      .SetHideItemNames(false)
                                                                      .SetShowMembersOneLiner(true),
                                                                      "");
                                    format.FormatObject(var_value_sp.get(), buffer, TypeSummaryOptions());
                                    var_representation = buffer.c_str();
                                }
                                else
                                    var_representation = var_value_sp->GetValueAsCString();
                                if (arg_idx > 0)
                                    s.PutCString (", ");
                                if (var_value_sp->GetError().Success())
                                {
                                    if (var_representation)
                                        s.Printf ("%s=%s", var_name, var_representation);
                                    else
                                        s.Printf ("%s=%s at %s", var_name, var_value_sp->GetTypeName().GetCString(), var_value_sp->GetLocationAsCString());
                                }
                                else
                                    s.Printf ("%s=<unavailable>", var_name);
                            }

                            if (close_paren)
                                s.PutCString (close_paren);
                            else
                                s.PutChar(')');

                        }
                        else
                        {
                            s.PutCString(cstr);
                        }
                        return true;
                    }
                }
                else if (sc->symbol)
                {
                    const char *cstr = sc->symbol->GetName().AsCString (NULL);
                    if (cstr)
                    {
                        s.PutCString(cstr);
                        return true;
                    }
                }
            }
            return false;

        case Entry::Type::FunctionAddrOffset:
            if (addr)
            {
                if (DumpAddressOffsetFromFunction (s, sc, exe_ctx, *addr, false, false, false))
                    return true;
            }
            return false;

        case Entry::Type::FunctionAddrOffsetConcrete:
            if (addr)
            {
                if (DumpAddressOffsetFromFunction (s, sc, exe_ctx, *addr, true, true, true))
                    return true;
            }
            return false;

        case Entry::Type::FunctionLineOffset:
            if (DumpAddressOffsetFromFunction (s, sc, exe_ctx, sc->line_entry.range.GetBaseAddress(), false, false, false))
                return true;
            return false;

        case Entry::Type::FunctionPCOffset:
            if (exe_ctx)
            {
                StackFrame *frame = exe_ctx->GetFramePtr();
                if (frame)
                {
                    if (DumpAddressOffsetFromFunction (s, sc, exe_ctx, frame->GetFrameCodeAddress(), false, false, false))
                        return true;
                }
            }
            return false;

        case Entry::Type::FunctionChanged:
            return function_changed == true;

        case Entry::Type::FunctionInitial:
            return initial_function == true;

        case Entry::Type::LineEntryFile:
            if (sc && sc->line_entry.IsValid())
            {
                Module *module = sc->module_sp.get();
                if (module)
                {
                    if (DumpFile(s, sc->line_entry.file, (FileKind)entry.number))
                        return true;
                }
            }
            return false;

        case Entry::Type::LineEntryLineNumber:
            if (sc && sc->line_entry.IsValid())
            {
                const char *format = "%" PRIu32;
                if (!entry.printf_format.empty())
                    format = entry.printf_format.c_str();
                s.Printf(format, sc->line_entry.line);
                return true;
            }
            return false;

        case Entry::Type::LineEntryStartAddress:
        case Entry::Type::LineEntryEndAddress:
            if (sc && sc->line_entry.range.GetBaseAddress().IsValid())
            {
                Address addr = sc->line_entry.range.GetBaseAddress();

                if (entry.type == Entry::Type::LineEntryEndAddress)
                    addr.Slide(sc->line_entry.range.GetByteSize());
                if (DumpAddress(s, sc, exe_ctx, addr, false))
                    return true;
            }
            return false;

        case Entry::Type::CurrentPCArrow:
            if (addr && exe_ctx && exe_ctx->GetFramePtr())
            {
                RegisterContextSP reg_ctx = exe_ctx->GetFramePtr()->GetRegisterContextSP();
                if (reg_ctx.get())
                {
                    addr_t pc_loadaddr = reg_ctx->GetPC();
                    if (pc_loadaddr != LLDB_INVALID_ADDRESS)
                    {
                        Address pc;
                        pc.SetLoadAddress (pc_loadaddr, exe_ctx->GetTargetPtr());
                        if (pc == *addr)
                        {
                            s.Printf ("-> ");
                            return true;
                        }
                    }
                }
                s.Printf("   ");
                return true;
            }
            return false;
    }
    return false;
}

static bool
DumpCommaSeparatedChildEntryNames (Stream &s, const FormatEntity::Entry::Definition *parent)
{
    if (parent->children)
    {
        const size_t n = parent->num_children;
        for (size_t i=0; i<n; ++i)
        {
            if (i > 0)
                s.PutCString(", ");
            s.Printf ("\"%s\"", parent->children[i].name);
        }
        return true;
    }
    return false;
}


static Error
ParseEntry (const llvm::StringRef &format_str,
            const FormatEntity::Entry::Definition *parent,
            FormatEntity::Entry &entry)
{
    Error error;

    const size_t sep_pos = format_str.find_first_of(".[:");
    const char sep_char = (sep_pos == llvm::StringRef::npos) ? '\0' : format_str[sep_pos];
    llvm::StringRef key = format_str.substr(0, sep_pos);

    const size_t n = parent->num_children;
    for (size_t i=0; i<n; ++i)
    {
        const FormatEntity::Entry::Definition *entry_def = parent->children + i;
        if (key.equals(entry_def->name) || entry_def->name[0] == '*')
        {
            llvm::StringRef value;
            if (sep_char)
                value = format_str.substr(sep_pos + (entry_def->keep_separator ? 0 : 1));
            switch (entry_def->type)
            {
                case FormatEntity::Entry::Type::ParentString:
                    entry.string = std::move(format_str.str());
                    return error; // Success

                case FormatEntity::Entry::Type::ParentNumber:
                    entry.number = entry_def->data;
                    return error; // Success

                case FormatEntity::Entry::Type::InsertString:
                    entry.type = entry_def->type;
                    entry.string = entry_def->string;
                    return error; // Success

                default:
                    entry.type = entry_def->type;
                    break;
            }

            if (value.empty())
            {
                if (entry_def->type == FormatEntity::Entry::Type::Invalid)
                {
                    if (entry_def->children)
                    {
                        StreamString error_strm;
                        error_strm.Printf("'%s' can't be specified on its own, you must access one of its children: ", entry_def->name);
                        DumpCommaSeparatedChildEntryNames (error_strm, entry_def);
                        error.SetErrorStringWithFormat("%s", error_strm.GetString().c_str());
                    }
                    else if (sep_char == ':')
                    {
                        // Any value whose separator is a with a ':' means this value has a string argument
                        // that needs to be stored in the entry (like "${script.var:}").
                        // In this case the string value is the empty string which is ok.
                    }
                    else
                    {
                        error.SetErrorStringWithFormat("%s", "invalid entry definitions");
                    }
                }
            }
            else
            {
                if (entry_def->children)
                {
                    error = ParseEntry (value, entry_def, entry);
                }
                else if (sep_char == ':')
                {
                    // Any value whose separator is a with a ':' means this value has a string argument
                    // that needs to be stored in the entry (like "${script.var:modulename.function}")
                    entry.string = std::move(value.str());
                }
                else
                {
                    error.SetErrorStringWithFormat("'%s' followed by '%s' but it has no children",
                                                   key.str().c_str(),
                                                   value.str().c_str());
                }
            }
            return error;
        }
    }
    StreamString error_strm;
    if (parent->type == FormatEntity::Entry::Type::Root)
        error_strm.Printf("invalid top level item '%s'. Valid top level items are: ", key.str().c_str());
    else
        error_strm.Printf("invalid member '%s' in '%s'. Valid members are: ", key.str().c_str(), parent->name);
    DumpCommaSeparatedChildEntryNames (error_strm, parent);
    error.SetErrorStringWithFormat("%s", error_strm.GetString().c_str());
    return error;
}


static const FormatEntity::Entry::Definition *
FindEntry (const llvm::StringRef &format_str, const FormatEntity::Entry::Definition *parent, llvm::StringRef &remainder)
{
    Error error;
    
    std::pair<llvm::StringRef, llvm::StringRef> p = format_str.split('.');
    const size_t n = parent->num_children;
    for (size_t i=0; i<n; ++i)
    {
        const FormatEntity::Entry::Definition *entry_def = parent->children + i;
        if (p.first.equals(entry_def->name) || entry_def->name[0] == '*')
        {
            if (p.second.empty())
            {
                if (format_str.back() == '.')
                    remainder = format_str.drop_front(format_str.size() - 1);
                else
                    remainder = llvm::StringRef(); // Exact match
                return entry_def;
            }
            else
            {
                if (entry_def->children)
                {
                    return FindEntry (p.second, entry_def, remainder);
                }
                else
                {
                    remainder = p.second;
                    return entry_def;
                }
            }
        }
    }
    remainder = format_str;
    return parent;
}

Error
FormatEntity::ParseInternal (llvm::StringRef &format, Entry &parent_entry, uint32_t depth)
{
    Error error;
    while (!format.empty() && error.Success())
    {
        const size_t non_special_chars = format.find_first_of("${}\\");

        if (non_special_chars == llvm::StringRef::npos)
        {
            // No special characters, just string bytes so add them and we are done
            parent_entry.AppendText(format);
            return error;
        }

        if (non_special_chars > 0)
        {
            // We have a special character, so add all characters before these as a plain string
            parent_entry.AppendText(format.substr(0,non_special_chars));
            format = format.drop_front(non_special_chars);
        }

        switch (format[0])
        {
            case '\0':
                return error;

            case '{':
                {
                    format = format.drop_front(); // Skip the '{'
                    Entry scope_entry(Entry::Type::Scope);
                    error = FormatEntity::ParseInternal (format, scope_entry, depth+1);
                    if (error.Fail())
                        return error;
                    parent_entry.AppendEntry(std::move(scope_entry));
                }
                break;

            case '}':
                if (depth == 0)
                    error.SetErrorString("unmatched '}' character");
                else
                    format = format.drop_front(); // Skip the '}' as we are at the end of the scope
                return error;

            case '\\':
                {
                    format = format.drop_front(); // Skip the '\' character
                    if (format.empty())
                    {
                        error.SetErrorString("'\\' character was not followed by another character");
                        return error;
                    }

                    const char desens_char = format[0];
                    format = format.drop_front(); // Skip the desensitized char character
                    switch (desens_char)
                    {
                        case 'a': parent_entry.AppendChar('\a'); break;
                        case 'b': parent_entry.AppendChar('\b'); break;
                        case 'f': parent_entry.AppendChar('\f'); break;
                        case 'n': parent_entry.AppendChar('\n'); break;
                        case 'r': parent_entry.AppendChar('\r'); break;
                        case 't': parent_entry.AppendChar('\t'); break;
                        case 'v': parent_entry.AppendChar('\v'); break;
                        case '\'': parent_entry.AppendChar('\''); break;
                        case '\\': parent_entry.AppendChar('\\'); break;
                        case '0':
                            // 1 to 3 octal chars
                        {
                            // Make a string that can hold onto the initial zero char,
                            // up to 3 octal digits, and a terminating NULL.
                            char oct_str[5] = { 0, 0, 0, 0, 0 };

                            int i;
                            for (i=0; (format[i] >= '0' && format[i] <= '7') && i<4; ++i)
                                oct_str[i] = format[i];

                            // We don't want to consume the last octal character since
                            // the main for loop will do this for us, so we advance p by
                            // one less than i (even if i is zero)
                            format = format.drop_front(i);
                            unsigned long octal_value = ::strtoul (oct_str, NULL, 8);
                            if (octal_value <= UINT8_MAX)
                            {
                                parent_entry.AppendChar((char)octal_value);
                            }
                            else
                            {
                                error.SetErrorString("octal number is larger than a single byte");
                                return error;
                            }
                        }
                            break;

                        case 'x':
                            // hex number in the format
                            if (isxdigit(format[0]))
                            {
                                // Make a string that can hold onto two hex chars plus a
                                // NULL terminator
                                char hex_str[3] = { 0,0,0 };
                                hex_str[0] = format[0];

                                format = format.drop_front();

                                if (isxdigit(format[0]))
                                {
                                    hex_str[1] = format[0];
                                    format = format.drop_front();
                                }

                                unsigned long hex_value = strtoul (hex_str, NULL, 16);
                                if (hex_value <= UINT8_MAX)
                                {
                                    parent_entry.AppendChar((char)hex_value);
                                }
                                else
                                {
                                    error.SetErrorString("hex number is larger than a single byte");
                                    return error;
                                }
                            }
                            else
                            {
                                parent_entry.AppendChar(desens_char);
                            }
                            break;

                        default:
                            // Just desensitize any other character by just printing what
                            // came after the '\'
                            parent_entry.AppendChar(desens_char);
                            break;
                    }
                }
                break;

            case '$':
                if (format.size() == 1)
                {
                    // '$' at the end of a format string, just print the '$'
                    parent_entry.AppendText("$");
                }
                else
                {
                    format = format.drop_front(); // Skip the '$'

                    if (format[0] == '{')
                    {
                        format = format.drop_front(); // Skip the '{'

                        llvm::StringRef variable, variable_format;
                        error = FormatEntity::ExtractVariableInfo (format, variable, variable_format);
                        if (error.Fail())
                            return error;
                        bool verify_is_thread_id = false;
                        Entry entry;
                        if (!variable_format.empty())
                        {
                            entry.printf_format = std::move(variable_format.str());
                            
                            // If the format contains a '%' we are going to assume this is
                            // a printf style format. So if you want to format your thread ID
                            // using "0x%llx" you can use:
                            // ${thread.id%0x%llx}
                            //
                            // If there is no '%' in the format, then it is assumed to be a
                            // LLDB format name, or one of the extended formats specified in
                            // the switch statement below.
                            
                            if (entry.printf_format.find('%') == std::string::npos)
                            {
                                bool clear_printf = false;

                                if (FormatManager::GetFormatFromCString(entry.printf_format.c_str(),
                                                                        false,
                                                                        entry.fmt))
                                {
                                    // We have an LLDB format, so clear the printf format
                                    clear_printf = true;
                                }
                                else if (entry.printf_format.size() == 1)
                                {
                                    switch (entry.printf_format[0])
                                    {
                                        case '@':             // if this is an @ sign, print ObjC description
                                            entry.number = ValueObject::eValueObjectRepresentationStyleLanguageSpecific;
                                            clear_printf = true;
                                            break;
                                        case 'V': // if this is a V, print the value using the default format
                                            entry.number = ValueObject::eValueObjectRepresentationStyleValue;
                                            clear_printf = true;
                                            break;
                                        case 'L': // if this is an L, print the location of the value
                                            entry.number = ValueObject::eValueObjectRepresentationStyleLocation;
                                            clear_printf = true;
                                            break;
                                        case 'S': // if this is an S, print the summary after all
                                            entry.number = ValueObject::eValueObjectRepresentationStyleSummary;
                                            clear_printf = true;
                                            break;
                                        case '#': // if this is a '#', print the number of children
                                            entry.number = ValueObject::eValueObjectRepresentationStyleChildrenCount;
                                            clear_printf = true;
                                            break;
                                        case 'T': // if this is a 'T', print the type
                                            entry.number = ValueObject::eValueObjectRepresentationStyleType;
                                            clear_printf = true;
                                            break;
                                        case 'N': // if this is a 'N', print the name
                                            entry.number = ValueObject::eValueObjectRepresentationStyleName;
                                            clear_printf = true;
                                            break;
                                        case '>': // if this is a '>', print the expression path
                                            entry.number = ValueObject::eValueObjectRepresentationStyleExpressionPath;
                                            clear_printf = true;
                                            break;
                                        default:
                                            error.SetErrorStringWithFormat("invalid format: '%s'", entry.printf_format.c_str());
                                            return error;
                                    }
                                }
                                else if (FormatManager::GetFormatFromCString(entry.printf_format.c_str(),
                                                                             true,
                                                                             entry.fmt))
                                {
                                    clear_printf = true;
                                }
                                else if (entry.printf_format == "tid")
                                {
                                    verify_is_thread_id = true;
                                }
                                else
                                {
                                    error.SetErrorStringWithFormat("invalid format: '%s'", entry.printf_format.c_str());
                                    return error;
                                }
                                
                                // Our format string turned out to not be a printf style format
                                // so lets clear the string
                                if (clear_printf)
                                    entry.printf_format.clear();
                            }
                        }

                        // Check for dereferences
                        if (variable[0] == '*')
                        {
                            entry.deref = true;
                            variable = variable.drop_front();
                        }

                        error = ParseEntry (variable, &g_root, entry);
                        if (error.Fail())
                            return error;

                        if (verify_is_thread_id)
                        {
                            if (entry.type != Entry::Type::ThreadID &&
                                entry.type != Entry::Type::ThreadProtocolID)
                            {
                                error.SetErrorString("the 'tid' format can only be used on ${thread.id} and ${thread.protocol_id}");
                            }
                        }

                        switch (entry.type)
                        {
                            case Entry::Type::Variable:
                            case Entry::Type::VariableSynthetic:
                                if (entry.number == 0)
                                {
                                    if (entry.string.empty())
                                        entry.number = ValueObject::eValueObjectRepresentationStyleValue;
                                    else
                                        entry.number = ValueObject::eValueObjectRepresentationStyleSummary;
                                }
                                break;
                            default:
                                // Make sure someone didn't try to dereference anything but ${var} or ${svar}
                                if (entry.deref)
                                {
                                    error.SetErrorStringWithFormat("${%s} can't be dereferenced, only ${var} and ${svar} can.", variable.str().c_str());
                                    return error;
                                }
                        }
                        // Check if this entry just wants to insert a constant string
                        // value into the parent_entry, if so, insert the string with
                        // AppendText, else append the entry to the parent_entry.
                        if (entry.type == Entry::Type::InsertString)
                            parent_entry.AppendText(entry.string.c_str());
                        else
                            parent_entry.AppendEntry(std::move(entry));
                    }
                }
                break;
        }
    }
    return error;
}


Error
FormatEntity::ExtractVariableInfo (llvm::StringRef &format_str, llvm::StringRef &variable_name, llvm::StringRef &variable_format)
{
    Error error;
    variable_name = llvm::StringRef();
    variable_format = llvm::StringRef();

    const size_t paren_pos = format_str.find_first_of('}');
    if (paren_pos != llvm::StringRef::npos)
    {
        const size_t percent_pos = format_str.find_first_of('%');
        if (percent_pos < paren_pos)
        {
            if (percent_pos > 0)
            {
                if (percent_pos > 1)
                    variable_name = format_str.substr(0, percent_pos);
                variable_format = format_str.substr(percent_pos + 1, paren_pos - (percent_pos + 1));
            }
        }
        else
        {
            variable_name = format_str.substr(0, paren_pos);
        }
        // Strip off elements and the formatting and the trailing '}'
        format_str = format_str.substr(paren_pos + 1);
    }
    else
    {
        error.SetErrorStringWithFormat("missing terminating '}' character for '${%s'", format_str.str().c_str());
    }
    return error;
}

bool
FormatEntity::FormatFileSpec (const FileSpec &file_spec, Stream &s, llvm::StringRef variable_name, llvm::StringRef variable_format)
{
    if (variable_name.empty() || variable_name.equals(".fullpath"))
    {
        file_spec.Dump(&s);
        return true;
    }
    else if (variable_name.equals(".basename"))
    {
        s.PutCString(file_spec.GetFilename().AsCString(""));
        return true;
    }
    else if (variable_name.equals(".dirname"))
    {
        s.PutCString(file_spec.GetFilename().AsCString(""));
        return true;
    }
    return false;
}

static std::string
MakeMatch (const llvm::StringRef &prefix, const char *suffix)
{
    std::string match(prefix.str());
    match.append(suffix);
    return std::move(match);
}

static void
AddMatches (const FormatEntity::Entry::Definition *def,
            const llvm::StringRef &prefix,
            const llvm::StringRef &match_prefix,
            StringList &matches)
{
    const size_t n = def->num_children;
    if (n > 0)
    {
        for (size_t i=0; i<n; ++i)
        {
            std::string match = std::move(prefix.str());
            if (match_prefix.empty())
                matches.AppendString(MakeMatch (prefix, def->children[i].name));
            else if (strncmp(def->children[i].name, match_prefix.data(), match_prefix.size()) == 0)
                matches.AppendString(MakeMatch (prefix, def->children[i].name + match_prefix.size()));
        }
    }
}
size_t
FormatEntity::AutoComplete (const char *s,
                            int match_start_point,
                            int max_return_elements,
                            bool &word_complete,
                            StringList &matches)
{
    word_complete = false;
    llvm::StringRef str(s + match_start_point);
    matches.Clear();
    
    const size_t dollar_pos = str.rfind('$');
    if (dollar_pos != llvm::StringRef::npos)
    {
        // Hitting TAB after $ at the end of the string add a "{"
        if (dollar_pos == str.size() - 1)
        {
            std::string match = std::move(str.str());
            match.append("{");
            matches.AppendString(std::move(match));
        }
        else if (str[dollar_pos + 1] == '{')
        {
            const size_t close_pos = str.find('}', dollar_pos + 2);
            if (close_pos == llvm::StringRef::npos)
            {
                const size_t format_pos = str.find('%', dollar_pos + 2);
                if (format_pos == llvm::StringRef::npos)
                {
                    llvm::StringRef partial_variable (str.substr(dollar_pos + 2));
                    if (partial_variable.empty())
                    {
                        // Suggest all top level entites as we are just past "${"
                        AddMatches(&g_root, str, llvm::StringRef(), matches);
                    }
                    else
                    {
                        // We have a partially specified variable, find it
                        llvm::StringRef remainder;
                        const FormatEntity::Entry::Definition* entry_def = FindEntry (partial_variable, &g_root, remainder);
                        if (entry_def)
                        {
                            const size_t n = entry_def->num_children;

                            if (remainder.empty())
                            {
                                // Exact match
                                if (n > 0)
                                {
                                    // "${thread.info" <TAB>
                                    matches.AppendString(std::move(MakeMatch (str, ".")));
                                }
                                else
                                {
                                    // "${thread.id" <TAB>
                                    matches.AppendString(std::move(MakeMatch (str, "}")));
                                    word_complete = true;
                                }
                            }
                            else if (remainder.equals("."))
                            {
                                // "${thread." <TAB>
                                AddMatches(entry_def, str, llvm::StringRef(), matches);
                            }
                            else
                            {
                                // We have a partial match
                                // "${thre" <TAB>
                                AddMatches(entry_def, str, remainder, matches);
                            }
                        }
                    }
                }
            }
        }
    }
    return matches.GetSize();
}
