//===-- 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 "lldb/Core/FormatEntity.h"

#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.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/DataFormatters/ValueObjectPrinter.h"
#include "lldb/Expression/ExpressionVariable.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/Language.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),
    ENTRY ("is-optimized"        , FunctionIsOptimized    , 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                   ("language"            , Lang                   , CString),
    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(Lang);
    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(FunctionIsOptimized);
    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->GetAddressRef();
        }

        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_DATAFORMATTERS));
    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_DATAFORMATTERS));
    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_DATAFORMATTERS));
    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->GetCompilerType().GetTypeInfo(NULL);
    bool is_array = (type_info_flags & eTypeIsArray) != 0;
    bool is_pointer = (type_info_flags & eTypeIsPointer) != 0;
    bool is_aggregate = target->GetCompilerType().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")
                        {
                            // TODO(zturner): Rather than hardcoding this to be platform specific, it should be controlled by a
                            // setting and the default value of the setting can be different depending on the platform.
                            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))
                            {
                                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())
                    {
                        ExpressionVariableSP 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::Lang:
            if (sc)
            {
                CompileUnit *cu = sc->comp_unit;
                if (cu)
                {
                    const char *lang_name = Language::GetNameForLanguageType(cu->GetLanguage());
                    if (lang_name)
                    {
                        s.PutCString(lang_name);
                        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:
            {
                Language *language_plugin = nullptr;
                bool language_plugin_handled = false;
                StreamString ss;
                if (sc->function)
                    language_plugin = Language::FindPlugin(sc->function->GetLanguage());
                else if (sc->symbol)
                    language_plugin = Language::FindPlugin(sc->symbol->GetLanguage());
                if (language_plugin)
                {
                    language_plugin_handled = language_plugin->GetFunctionDisplayName(sc,
                                                                                      exe_ctx,
                                                                                      Language::FunctionNameRepresentation::eName,
                                                                                      ss);
                }
                if (language_plugin_handled)
                {
                    s.PutCString(ss.GetData());
                    return true;
                }
                else
                {
                    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(sc->function->GetLanguage()).Dump(&s);
                                }
                            }
                        }
                        return true;
                    }
                }
            }
            return false;

        case Entry::Type::FunctionNameNoArgs:
            {
                Language *language_plugin = nullptr;
                bool language_plugin_handled = false;
                StreamString ss;
                if (sc->function)
                    language_plugin = Language::FindPlugin(sc->function->GetLanguage());
                else if (sc->symbol)
                    language_plugin = Language::FindPlugin(sc->symbol->GetLanguage());
                if (language_plugin)
                {
                    language_plugin_handled = language_plugin->GetFunctionDisplayName(sc,
                                                                                      exe_ctx,
                                                                                      Language::FunctionNameRepresentation::eNameWithNoArgs,
                                                                                      ss);
                }
                if (language_plugin_handled)
                {
                    s.PutCString(ss.GetData());
                    return true;
                }
                else
                {
                    ConstString name;
                    if (sc->function)
                        name = sc->function->GetNameNoArguments();
                    else if (sc->symbol)
                        name = sc->symbol->GetNameNoArguments();
                    if (name)
                    {
                        s.PutCString(name.GetCString());
                        return true;
                    }
                }
            }
            return false;

        case Entry::Type::FunctionNameWithArgs:
            {
                Language *language_plugin = nullptr;
                bool language_plugin_handled = false;
                StreamString ss;
                if (sc->function)
                    language_plugin = Language::FindPlugin(sc->function->GetLanguage());
                else if (sc->symbol)
                    language_plugin = Language::FindPlugin(sc->symbol->GetLanguage());
                if (language_plugin)
                {
                    language_plugin_handled = language_plugin->GetFunctionDisplayName(sc,
                                                                                      exe_ctx,
                                                                                      Language::FunctionNameRepresentation::eNameWithArgs,
                                                                                      ss);
                }
                if (language_plugin_handled)
                {
                    s.PutCString(ss.GetData());
                    return true;
                }
                else
                {
                    // 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(sc->function->GetLanguage()).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));
                                    StreamString ss;
                                    const char *var_representation = nullptr;
                                    const char *var_name = var_value_sp->GetName().GetCString();
                                    if (var_value_sp->GetCompilerType().IsValid())
                                    {
                                        if (var_value_sp && exe_scope->CalculateTarget())
                                            var_value_sp = var_value_sp->GetQualifiedRepresentationIfAvailable(exe_scope->CalculateTarget()->TargetProperties::GetPreferDynamicValue(),
                                                                                                               exe_scope->CalculateTarget()->TargetProperties::GetEnableSyntheticValue());
                                        if (var_value_sp->GetCompilerType().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_value_sp->DumpPrintableRepresentation(ss,
                                                                                      ValueObject::ValueObjectRepresentationStyle::eValueObjectRepresentationStyleSummary,
                                                                                      eFormatDefault,
                                                                                      ValueObject::PrintableRepresentationSpecialCases::ePrintableRepresentationSpecialCasesAllow,
                                                                                      false);
                                    }
                                    
                                    if (ss.GetData() && ss.GetSize())
                                        var_representation = ss.GetData();
                                    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::FunctionIsOptimized:
            {
                bool is_optimized = false;
                if (sc->function && sc->function->GetIsOptimized())
                {
                    is_optimized = true;
                }
                return is_optimized;
            }

        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 = 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 = 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 = 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('}');
    if (paren_pos != llvm::StringRef::npos)
    {
        const size_t percent_pos = format_str.find('%');
        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 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 = 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 = 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(MakeMatch(str, "."));
                                }
                                else
                                {
                                    // "${thread.id" <TAB>
                                    matches.AppendString(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();
}
