173844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton//===-- OptionValueDictionary.cpp -------------------------------*- C++ -*-===//
273844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton//
373844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton//                     The LLVM Compiler Infrastructure
473844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton//
573844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton// This file is distributed under the University of Illinois Open Source
673844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton// License. See LICENSE.TXT for details.
773844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton//
873844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton//===----------------------------------------------------------------------===//
973844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton
10d891f9b872103235cfd2ed452c6f14a4394d9b3aDaniel Malea#include "lldb/lldb-python.h"
11d891f9b872103235cfd2ed452c6f14a4394d9b3aDaniel Malea
1273844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton#include "lldb/Interpreter/OptionValueDictionary.h"
1373844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton
1473844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton// C Includes
1573844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton// C++ Includes
1673844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton// Other libraries and framework includes
1773844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton#include "llvm/ADT/StringRef.h"
1873844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton// Project includes
1973844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton#include "lldb/Core/State.h"
20f509c5ec066599a3399fced39ea36996184939e8Enrico Granata#include "lldb/DataFormatters/FormatManager.h"
2173844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton#include "lldb/Interpreter/Args.h"
2273844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton#include "lldb/Interpreter/OptionValueString.h"
2373844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton
2473844aa19a7360b662e2be710fc3c969d6c86606Greg Claytonusing namespace lldb;
2573844aa19a7360b662e2be710fc3c969d6c86606Greg Claytonusing namespace lldb_private;
2673844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton
2773844aa19a7360b662e2be710fc3c969d6c86606Greg Claytonvoid
2873844aa19a7360b662e2be710fc3c969d6c86606Greg ClaytonOptionValueDictionary::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask)
2973844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton{
3073844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton    const Type dict_type = ConvertTypeMaskToType (m_type_mask);
3173844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton    if (dump_mask & eDumpOptionType)
3273844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton    {
3373844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton        if (m_type_mask != eTypeInvalid)
3473844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton            strm.Printf ("(%s of %ss)", GetTypeAsCString(), GetBuiltinTypeAsCString(dict_type));
3573844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton        else
3673844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton            strm.Printf ("(%s)", GetTypeAsCString());
3773844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton    }
3873844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton    if (dump_mask & eDumpOptionValue)
3973844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton    {
4073844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton        if (dump_mask & eDumpOptionType)
4173844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton            strm.PutCString (" =");
4273844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton
4373844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton        collection::iterator pos, end = m_values.end();
4473844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton
4573844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton        strm.IndentMore();
4673844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton
4773844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton        for (pos = m_values.begin(); pos != end; ++pos)
4873844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton        {
4973844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton            OptionValue *option_value = pos->second.get();
5073844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton            strm.EOL();
5173844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton            strm.Indent(pos->first.GetCString());
5273844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton
5373844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton            const uint32_t extra_dump_options = m_raw_value_dump ? eDumpOptionRaw : 0;
5473844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton            switch (dict_type)
5573844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton            {
5673844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                default:
5773844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                case eTypeArray:
5873844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                case eTypeDictionary:
5973844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                case eTypeProperties:
6073844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                case eTypeFileSpecList:
6173844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                case eTypePathMap:
6273844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                    strm.PutChar (' ');
6373844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                    option_value->DumpValue(exe_ctx, strm, dump_mask | extra_dump_options);
6473844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                    break;
6573844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton
6673844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                case eTypeBoolean:
6773844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                case eTypeEnum:
6873844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                case eTypeFileSpec:
6973844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                case eTypeFormat:
7073844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                case eTypeSInt64:
7173844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                case eTypeString:
7273844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                case eTypeUInt64:
7373844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                case eTypeUUID:
7473844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                    // No need to show the type for dictionaries of simple items
7573844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                    strm.PutCString("=");
7673844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                    option_value->DumpValue(exe_ctx, strm, (dump_mask & (~eDumpOptionType)) | extra_dump_options);
7773844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                    break;
7873844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton            }
7973844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton        }
8073844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton        strm.IndentLess();
8173844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton    }
8273844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton
8373844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton}
8473844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton
8573844aa19a7360b662e2be710fc3c969d6c86606Greg Claytonsize_t
8673844aa19a7360b662e2be710fc3c969d6c86606Greg ClaytonOptionValueDictionary::GetArgs (Args &args) const
8773844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton{
8873844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton    args.Clear();
8973844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton    collection::const_iterator pos, end = m_values.end();
9073844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton    for (pos = m_values.begin(); pos != end; ++pos)
9173844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton    {
9273844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton        StreamString strm;
9373844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton        strm.Printf("%s=", pos->first.GetCString());
9473844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton        pos->second->DumpValue(NULL, strm, eDumpOptionValue|eDumpOptionRaw);
9573844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton        args.AppendArgument(strm.GetString().c_str());
9673844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton    }
9773844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton    return args.GetArgumentCount();
9873844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton}
9973844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton
10073844aa19a7360b662e2be710fc3c969d6c86606Greg ClaytonError
10173844aa19a7360b662e2be710fc3c969d6c86606Greg ClaytonOptionValueDictionary::SetArgs (const Args &args, VarSetOperationType op)
10273844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton{
10373844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton    Error error;
10473844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton    const size_t argc = args.GetArgumentCount();
10573844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton    switch (op)
10673844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton    {
10773844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton    case eVarSetOperationClear:
10873844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton        Clear();
10973844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton        break;
11073844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton
11173844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton    case eVarSetOperationAppend:
11273844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton    case eVarSetOperationReplace:
11373844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton    case eVarSetOperationAssign:
11473844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton        if (argc > 0)
11573844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton        {
11673844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton            for (size_t i=0; i<argc; ++i)
11773844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton            {
11873844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                llvm::StringRef key_and_value(args.GetArgumentAtIndex(i));
11973844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                if (!key_and_value.empty())
12073844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                {
12173844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                    std::pair<llvm::StringRef, llvm::StringRef> kvp(key_and_value.split('='));
12273844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                    llvm::StringRef key = kvp.first;
12373844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                    bool key_valid = false;
12473844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                    if (!key.empty())
12573844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                    {
12673844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                        if (key.front() == '[')
12773844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                        {
12873844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                            // Key name starts with '[', so the the key value must be in single or double quotes like:
12973844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                            // ['<key>']
13073844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                            // ["<key>"]
13173844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                            if ((key.size() > 2) && (key.back() == ']'))
13273844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                            {
13373844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                                // Strip leading '[' and trailing ']'
13473844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                                key = key.substr(1, key.size()-2);
13573844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                                const char quote_char = key.front();
13673844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                                if ((quote_char == '\'') || (quote_char == '"'))
13773844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                                {
13873844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                                    if ((key.size() > 2) && (key.back() == quote_char))
13973844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                                    {
14073844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                                        // Strip the quotes
14173844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                                        key = key.substr(1, key.size()-2);
14273844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                                        key_valid = true;
14373844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                                    }
14473844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                                }
14573844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                                else
14673844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                                {
14773844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                                    // square brackets, no quotes
14873844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                                    key_valid = true;
14973844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                                }
15073844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                            }
15173844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                        }
15273844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                        else
15373844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                        {
15473844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                            // No square brackets or quotes
15573844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                            key_valid = true;
15673844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                        }
15773844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                    }
15873844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                    if (!key_valid)
15973844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                    {
16073844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                        error.SetErrorStringWithFormat("invalid key \"%s\", the key must be a bare string or surrounded by brackets with optional quotes: [<key>] or ['<key>'] or [\"<key>\"]", kvp.first.str().c_str());
16173844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                        return error;
16273844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                    }
16373844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton
16473844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                    lldb::OptionValueSP value_sp (CreateValueFromCStringForTypeMask (kvp.second.data(),
16573844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                                                                                     m_type_mask,
16673844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                                                                                     error));
16773844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                    if (value_sp)
16873844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                    {
16973844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                        if (error.Fail())
17073844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                            return error;
17173844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                        m_value_was_set = true;
17273844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                        SetValueForKey (ConstString(key), value_sp, true);
17373844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                    }
17473844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                    else
17573844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                    {
17673844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                        error.SetErrorString("dictionaries that can contain multiple types must subclass OptionValueArray");
17773844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                    }
17873844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                }
17973844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                else
18073844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                {
18173844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                    error.SetErrorString("empty argument");
18273844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                }
18373844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton            }
18473844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton        }
18573844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton        else
18673844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton        {
18773844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton            error.SetErrorString("assign operation takes one or more key=value arguments");
18873844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton        }
18973844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton        break;
19073844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton
19173844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton    case eVarSetOperationRemove:
19273844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton        if (argc > 0)
19373844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton        {
19473844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton            for (size_t i=0; i<argc; ++i)
19573844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton            {
19673844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                ConstString key(args.GetArgumentAtIndex(i));
19773844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                if (!DeleteValueForKey(key))
19873844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                {
19973844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                    error.SetErrorStringWithFormat("no value found named '%s', aborting remove operation", key.GetCString());
20073844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                    break;
20173844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                }
20273844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton            }
20373844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton        }
20473844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton        else
20573844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton        {
20673844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton            error.SetErrorString("remove operation takes one or more key arguments");
20773844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton        }
20873844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton        break;
20973844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton
21073844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton    case eVarSetOperationInsertBefore:
21173844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton    case eVarSetOperationInsertAfter:
21273844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton    case eVarSetOperationInvalid:
21373844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton        error = OptionValue::SetValueFromCString (NULL, op);
21473844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton        break;
21573844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton    }
21673844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton    return error;
21773844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton}
21873844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton
21973844aa19a7360b662e2be710fc3c969d6c86606Greg ClaytonError
22073844aa19a7360b662e2be710fc3c969d6c86606Greg ClaytonOptionValueDictionary::SetValueFromCString (const char *value_cstr, VarSetOperationType op)
22173844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton{
22273844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton    Args args(value_cstr);
22373844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton    return SetArgs (args, op);
22473844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton}
22573844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton
22673844aa19a7360b662e2be710fc3c969d6c86606Greg Claytonlldb::OptionValueSP
22773844aa19a7360b662e2be710fc3c969d6c86606Greg ClaytonOptionValueDictionary::GetSubValue (const ExecutionContext *exe_ctx, const char *name, bool will_modify, Error &error) const
22873844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton{
22973844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton    lldb::OptionValueSP value_sp;
23073844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton
23173844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton    if (name && name[0])
23273844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton    {
23373844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton        const char *sub_name = NULL;
23473844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton        ConstString key;
23573844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton        const char *open_bracket = ::strchr (name, '[');
23673844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton
23773844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton        if (open_bracket)
23873844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton        {
23973844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton            const char *key_start = open_bracket + 1;
24073844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton            const char *key_end = NULL;
24173844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton            switch (open_bracket[1])
24273844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton            {
24373844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                case '\'':
24473844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                    ++key_start;
24573844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                    key_end = strchr(key_start, '\'');
24673844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                    if (key_end)
24773844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                    {
24873844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                        if (key_end[1] == ']')
24973844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                        {
25073844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                            if (key_end[2])
25173844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                                sub_name = key_end + 2;
25273844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                        }
25373844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                        else
25473844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                        {
25573844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                            error.SetErrorStringWithFormat ("invalid value path '%s', single quoted key names must be formatted as ['<key>'] where <key> is a string that doesn't contain quotes", name);
25673844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                            return value_sp;
25773844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                        }
25873844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                    }
25973844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                    else
26073844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                    {
26173844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                        error.SetErrorString ("missing '] key name terminator, key name started with ['");
26273844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                        return value_sp;
26373844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                    }
26473844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                    break;
26573844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                case '"':
26673844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                    ++key_start;
26773844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                    key_end = strchr(key_start, '"');
26873844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                    if (key_end)
26973844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                    {
27073844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                        if (key_end[1] == ']')
27173844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                        {
27273844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                            if (key_end[2])
27373844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                                sub_name = key_end + 2;
27473844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                            break;
27573844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                        }
27673844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                        error.SetErrorStringWithFormat ("invalid value path '%s', double quoted key names must be formatted as [\"<key>\"] where <key> is a string that doesn't contain quotes", name);
27773844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                        return value_sp;
27873844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                    }
27973844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                    else
28073844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                    {
28173844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                        error.SetErrorString ("missing \"] key name terminator, key name started with [\"");
28273844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                        return value_sp;
28373844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                    }
28473844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                    break;
28573844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton
28673844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                default:
28773844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                    key_end = strchr(key_start, ']');
28873844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                    if (key_end)
28973844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                    {
29073844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                        if (key_end[1])
29173844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                            sub_name = key_end + 1;
29273844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                    }
29373844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                    else
29473844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                    {
29573844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                        error.SetErrorString ("missing ] key name terminator, key name started with [");
29673844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                        return value_sp;
29773844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                    }
29873844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                    break;
29973844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton            }
30073844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton
30173844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton            if (key_start && key_end)
30273844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton            {
30373844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                key.SetCStringWithLength (key_start, key_end - key_start);
30473844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton
30573844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                value_sp = GetValueForKey (key);
30673844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                if (value_sp)
30773844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                {
30873844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                    if (sub_name)
30973844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                        return value_sp->GetSubValue (exe_ctx, sub_name, will_modify, error);
31073844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                }
31173844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                else
31273844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                {
31373844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                    error.SetErrorStringWithFormat("dictionary does not contain a value for the key name '%s'", key.GetCString());
31473844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                }
31573844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton            }
31673844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton        }
31773844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton        if (!value_sp && error.AsCString() == NULL)
31873844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton        {
31973844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton            error.SetErrorStringWithFormat ("invalid value path '%s', %s values only support '[<key>]' subvalues where <key> a string value optionally delimitted by single or double quotes",
32073844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                                            name,
32173844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                                            GetTypeAsCString());
32273844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton        }
32373844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton    }
32473844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton    return value_sp;
32573844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton}
32673844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton
32773844aa19a7360b662e2be710fc3c969d6c86606Greg ClaytonError
32873844aa19a7360b662e2be710fc3c969d6c86606Greg ClaytonOptionValueDictionary::SetSubValue (const ExecutionContext *exe_ctx, VarSetOperationType op, const char *name, const char *value)
32973844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton{
33073844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton    Error error;
33173844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton    const bool will_modify = true;
33273844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton    lldb::OptionValueSP value_sp (GetSubValue (exe_ctx, name, will_modify, error));
33373844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton    if (value_sp)
33473844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton        error = value_sp->SetValueFromCString(value, op);
33573844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton    else
33673844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton    {
33773844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton        if (error.AsCString() == NULL)
33873844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton            error.SetErrorStringWithFormat("invalid value path '%s'", name);
33973844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton    }
34073844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton    return error;
34173844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton}
34273844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton
34373844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton
34473844aa19a7360b662e2be710fc3c969d6c86606Greg Claytonlldb::OptionValueSP
34573844aa19a7360b662e2be710fc3c969d6c86606Greg ClaytonOptionValueDictionary::GetValueForKey (const ConstString &key) const
34673844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton{
34773844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton    lldb::OptionValueSP value_sp;
34873844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton    collection::const_iterator pos = m_values.find (key);
34973844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton    if (pos != m_values.end())
35073844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton        value_sp = pos->second;
35173844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton    return value_sp;
35273844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton}
35373844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton
35473844aa19a7360b662e2be710fc3c969d6c86606Greg Claytonconst char *
35573844aa19a7360b662e2be710fc3c969d6c86606Greg ClaytonOptionValueDictionary::GetStringValueForKey (const ConstString &key)
35673844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton{
35773844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton    collection::const_iterator pos = m_values.find (key);
35873844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton    if (pos != m_values.end())
35973844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton    {
36073844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton        OptionValueString *string_value = pos->second->GetAsString();
36173844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton        if (string_value)
36273844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton            return string_value->GetCurrentValue();
36373844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton    }
36473844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton    return NULL;
36573844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton}
36673844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton
36773844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton
36873844aa19a7360b662e2be710fc3c969d6c86606Greg Claytonbool
36973844aa19a7360b662e2be710fc3c969d6c86606Greg ClaytonOptionValueDictionary::SetStringValueForKey (const ConstString &key,
37073844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                                             const char *value,
37173844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                                             bool can_replace)
37273844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton{
37373844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton    collection::const_iterator pos = m_values.find (key);
37473844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton    if (pos != m_values.end())
37573844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton    {
37673844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton        if (!can_replace)
37773844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton            return false;
37873844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton        if (pos->second->GetType() == OptionValue::eTypeString)
37973844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton        {
38073844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton            pos->second->SetValueFromCString(value);
38173844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton            return true;
38273844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton        }
38373844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton    }
38473844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton    m_values[key] = OptionValueSP (new OptionValueString (value));
38573844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton    return true;
38673844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton
38773844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton}
38873844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton
38973844aa19a7360b662e2be710fc3c969d6c86606Greg Claytonbool
39073844aa19a7360b662e2be710fc3c969d6c86606Greg ClaytonOptionValueDictionary::SetValueForKey (const ConstString &key,
39173844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                                       const lldb::OptionValueSP &value_sp,
39273844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                                       bool can_replace)
39373844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton{
39473844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton    // Make sure the value_sp object is allowed to contain
39573844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton    // values of the type passed in...
39673844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton    if (value_sp && (m_type_mask & value_sp->GetTypeAsMask()))
39773844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton    {
39873844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton        if (!can_replace)
39973844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton        {
40073844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton            collection::const_iterator pos = m_values.find (key);
40173844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton            if (pos != m_values.end())
40273844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton                return false;
40373844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton        }
40473844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton        m_values[key] = value_sp;
40573844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton        return true;
40673844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton    }
40773844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton    return false;
40873844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton}
40973844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton
41073844aa19a7360b662e2be710fc3c969d6c86606Greg Claytonbool
41173844aa19a7360b662e2be710fc3c969d6c86606Greg ClaytonOptionValueDictionary::DeleteValueForKey (const ConstString &key)
41273844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton{
41373844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton    collection::iterator pos = m_values.find (key);
41473844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton    if (pos != m_values.end())
41573844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton    {
41673844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton        m_values.erase(pos);
41773844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton        return true;
41873844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton    }
41973844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton    return false;
42073844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton}
42173844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton
42273844aa19a7360b662e2be710fc3c969d6c86606Greg Claytonlldb::OptionValueSP
42373844aa19a7360b662e2be710fc3c969d6c86606Greg ClaytonOptionValueDictionary::DeepCopy () const
42473844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton{
42573844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton    OptionValueDictionary *copied_dict = new OptionValueDictionary (m_type_mask, m_raw_value_dump);
42673844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton    lldb::OptionValueSP copied_value_sp(copied_dict);
42773844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton    collection::const_iterator pos, end = m_values.end();
42873844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton    for (pos = m_values.begin(); pos != end; ++pos)
42973844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton    {
43073844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton        StreamString strm;
43173844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton        strm.Printf("%s=", pos->first.GetCString());
43273844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton        copied_dict->SetValueForKey (pos->first, pos->second->DeepCopy(), true);
43373844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton    }
43473844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton    return copied_value_sp;
43573844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton}
43673844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton
437