Reimplemented the code that backed the "settings" in lldb. There were many issues with the previous implementation:
- no setting auto completion
- very manual and error prone way of getting/setting variables
- tons of code duplication
- useless instance names for processes, threads

Now settings can easily be defined like option values. The new settings makes use of the "OptionValue" classes so we can re-use the option value code that we use to set settings in command options. No more instances, just "does the right thing".



git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@162366 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Interpreter/OptionValue.cpp b/source/Interpreter/OptionValue.cpp
new file mode 100644
index 0000000..01ba65c
--- /dev/null
+++ b/source/Interpreter/OptionValue.cpp
@@ -0,0 +1,633 @@
+//===-- OptionValue.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/Interpreter/OptionValue.h"
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Core/StringList.h"
+#include "lldb/Interpreter/OptionValues.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+
+//-------------------------------------------------------------------------
+// Get this value as a uint64_t value if it is encoded as a boolean,
+// uint64_t or int64_t. Other types will cause "fail_value" to be 
+// returned
+//-------------------------------------------------------------------------
+uint64_t
+OptionValue::GetUInt64Value (uint64_t fail_value, bool *success_ptr)
+{
+    if (success_ptr)
+        *success_ptr = true;
+    switch (GetType())
+    {
+    case OptionValue::eTypeBoolean: return static_cast<OptionValueBoolean *>(this)->GetCurrentValue();
+    case OptionValue::eTypeSInt64:  return static_cast<OptionValueSInt64 *>(this)->GetCurrentValue();
+    case OptionValue::eTypeUInt64:  return static_cast<OptionValueUInt64 *>(this)->GetCurrentValue();
+    default: 
+        break;
+    }
+    if (success_ptr)
+        *success_ptr = false;
+    return fail_value;
+}
+
+Error
+OptionValue::SetSubValue (const ExecutionContext *exe_ctx,
+                          VarSetOperationType op,
+                          const char *name,
+                          const char *value)
+{
+    Error error;
+    error.SetErrorStringWithFormat("SetSubValue is not supported");
+    return error;
+}
+
+
+OptionValueBoolean *
+OptionValue::GetAsBoolean ()
+{
+    if (GetType () == OptionValue::eTypeBoolean)
+        return static_cast<OptionValueBoolean *>(this);
+    return NULL;
+}
+
+const OptionValueBoolean *
+OptionValue::GetAsBoolean () const
+{
+    if (GetType () == OptionValue::eTypeBoolean)
+        return static_cast<const OptionValueBoolean *>(this);
+    return NULL;
+}
+
+
+OptionValueFileSpec *
+OptionValue::GetAsFileSpec ()
+{
+    if (GetType () == OptionValue::eTypeFileSpec)
+        return static_cast<OptionValueFileSpec *>(this);
+    return NULL;
+    
+}
+
+const OptionValueFileSpec *
+OptionValue::GetAsFileSpec () const
+{
+    if (GetType () == OptionValue::eTypeFileSpec)
+        return static_cast<const OptionValueFileSpec *>(this);
+    return NULL;
+    
+}
+
+OptionValueFileSpecList *
+OptionValue::GetAsFileSpecList ()
+{
+    if (GetType () == OptionValue::eTypeFileSpecList)
+        return static_cast<OptionValueFileSpecList *>(this);
+    return NULL;
+    
+}
+
+const OptionValueFileSpecList *
+OptionValue::GetAsFileSpecList () const
+{
+    if (GetType () == OptionValue::eTypeFileSpecList)
+        return static_cast<const OptionValueFileSpecList *>(this);
+    return NULL;
+    
+}
+
+OptionValueArch *
+OptionValue::GetAsArch ()
+{
+    if (GetType () == OptionValue::eTypeArch)
+        return static_cast<OptionValueArch *>(this);
+    return NULL;
+}
+
+
+const OptionValueArch *
+OptionValue::GetAsArch () const
+{
+    if (GetType () == OptionValue::eTypeArch)
+        return static_cast<const OptionValueArch *>(this);
+    return NULL;
+}
+
+OptionValueArray *
+OptionValue::GetAsArray ()
+{
+    if (GetType () == OptionValue::eTypeArray)
+        return static_cast<OptionValueArray *>(this);
+    return NULL;
+}
+
+
+const OptionValueArray *
+OptionValue::GetAsArray () const
+{
+    if (GetType () == OptionValue::eTypeArray)
+        return static_cast<const OptionValueArray *>(this);
+    return NULL;
+}
+
+OptionValueArgs *
+OptionValue::GetAsArgs ()
+{
+    if (GetType () == OptionValue::eTypeArgs)
+        return static_cast<OptionValueArgs *>(this);
+    return NULL;
+}
+
+
+const OptionValueArgs *
+OptionValue::GetAsArgs () const
+{
+    if (GetType () == OptionValue::eTypeArgs)
+        return static_cast<const OptionValueArgs *>(this);
+    return NULL;
+}
+
+OptionValueDictionary *
+OptionValue::GetAsDictionary ()
+{
+    if (GetType () == OptionValue::eTypeDictionary)
+        return static_cast<OptionValueDictionary *>(this);
+    return NULL;
+}
+
+const OptionValueDictionary *
+OptionValue::GetAsDictionary () const
+{
+    if (GetType () == OptionValue::eTypeDictionary)
+        return static_cast<const OptionValueDictionary *>(this);
+    return NULL;
+}
+
+OptionValueEnumeration *
+OptionValue::GetAsEnumeration ()
+{
+    if (GetType () == OptionValue::eTypeEnum)
+        return static_cast<OptionValueEnumeration *>(this);
+    return NULL;
+}
+
+const OptionValueEnumeration *
+OptionValue::GetAsEnumeration () const
+{
+    if (GetType () == OptionValue::eTypeEnum)
+        return static_cast<const OptionValueEnumeration *>(this);
+    return NULL;
+}
+
+OptionValueFormat *
+OptionValue::GetAsFormat ()
+{
+    if (GetType () == OptionValue::eTypeFormat)
+        return static_cast<OptionValueFormat *>(this);
+    return NULL;
+}
+
+const OptionValueFormat *
+OptionValue::GetAsFormat () const
+{
+    if (GetType () == OptionValue::eTypeFormat)
+        return static_cast<const OptionValueFormat *>(this);
+    return NULL;
+}
+
+OptionValuePathMappings *
+OptionValue::GetAsPathMappings ()
+{
+    if (GetType () == OptionValue::eTypePathMap)
+        return static_cast<OptionValuePathMappings *>(this);
+    return NULL;
+}
+
+const OptionValuePathMappings *
+OptionValue::GetAsPathMappings () const
+{
+    if (GetType () == OptionValue::eTypePathMap)
+        return static_cast<const OptionValuePathMappings *>(this);
+    return NULL;
+}
+
+OptionValueProperties *
+OptionValue::GetAsProperties ()
+{
+    if (GetType () == OptionValue::eTypeProperties)
+        return static_cast<OptionValueProperties *>(this);
+    return NULL;
+}
+
+const OptionValueProperties *
+OptionValue::GetAsProperties () const
+{
+    if (GetType () == OptionValue::eTypeProperties)
+        return static_cast<const OptionValueProperties *>(this);
+    return NULL;
+}
+
+OptionValueRegex *
+OptionValue::GetAsRegex ()
+{
+    if (GetType () == OptionValue::eTypeRegex)
+        return static_cast<OptionValueRegex *>(this);
+    return NULL;
+}
+
+const OptionValueRegex *
+OptionValue::GetAsRegex () const
+{
+    if (GetType () == OptionValue::eTypeRegex)
+        return static_cast<const OptionValueRegex *>(this);
+    return NULL;
+}
+
+OptionValueSInt64 *
+OptionValue::GetAsSInt64 ()
+{
+    if (GetType () == OptionValue::eTypeSInt64)
+        return static_cast<OptionValueSInt64 *>(this);
+    return NULL;
+}
+
+const OptionValueSInt64 *
+OptionValue::GetAsSInt64 () const
+{
+    if (GetType () == OptionValue::eTypeSInt64)
+        return static_cast<const OptionValueSInt64 *>(this);
+    return NULL;
+}
+
+OptionValueString *
+OptionValue::GetAsString ()
+{
+    if (GetType () == OptionValue::eTypeString)
+        return static_cast<OptionValueString *>(this);
+    return NULL;
+}
+
+const OptionValueString *
+OptionValue::GetAsString () const
+{
+    if (GetType () == OptionValue::eTypeString)
+        return static_cast<const OptionValueString *>(this);
+    return NULL;
+}
+
+OptionValueUInt64 *
+OptionValue::GetAsUInt64 ()
+{
+    if (GetType () == OptionValue::eTypeUInt64)
+        return static_cast<OptionValueUInt64 *>(this);
+    return NULL;
+}
+
+const OptionValueUInt64 *
+OptionValue::GetAsUInt64 () const
+{
+    if (GetType () == OptionValue::eTypeUInt64)
+        return static_cast<const OptionValueUInt64 *>(this);
+    return NULL;
+}
+
+OptionValueUUID *
+OptionValue::GetAsUUID ()
+{
+    if (GetType () == OptionValue::eTypeUUID)
+        return static_cast<OptionValueUUID *>(this);
+    return NULL;
+    
+}
+
+const OptionValueUUID *
+OptionValue::GetAsUUID () const
+{
+    if (GetType () == OptionValue::eTypeUUID)
+        return static_cast<const OptionValueUUID *>(this);
+    return NULL;
+    
+}
+
+bool
+OptionValue::GetBooleanValue (bool fail_value) const
+{
+    const OptionValueBoolean *option_value = GetAsBoolean ();
+    if (option_value)
+        return option_value->GetCurrentValue();
+    return fail_value;
+}
+
+bool
+OptionValue::SetBooleanValue (bool new_value)
+{
+    OptionValueBoolean *option_value = GetAsBoolean ();
+    if (option_value)
+    {
+        option_value->SetCurrentValue(new_value);
+        return true;
+    }
+    return false;
+}
+
+int64_t
+OptionValue::GetEnumerationValue (int64_t fail_value) const
+{
+    const OptionValueEnumeration *option_value = GetAsEnumeration();
+    if (option_value)
+        option_value->GetCurrentValue();
+    return fail_value;
+}
+
+bool
+OptionValue::SetEnumerationValue (int64_t value)
+{
+    OptionValueEnumeration *option_value = GetAsEnumeration();
+    if (option_value)
+    {
+        option_value->SetCurrentValue(value);
+        return true;
+    }
+    return false;
+}
+
+FileSpec
+OptionValue::GetFileSpecValue () const
+{
+    const OptionValueFileSpec *option_value = GetAsFileSpec ();
+    if (option_value)
+        return option_value->GetCurrentValue();
+    return FileSpec();
+}
+
+
+bool
+OptionValue::SetFileSpecValue (const FileSpec &file_spec)
+{
+    OptionValueFileSpec *option_value = GetAsFileSpec ();
+    if (option_value)
+    {
+        option_value->SetCurrentValue(file_spec);
+        return true;
+    }
+    return false;
+}
+
+FileSpecList
+OptionValue::GetFileSpecListValue () const
+{
+    const OptionValueFileSpecList *option_value = GetAsFileSpecList ();
+    if (option_value)
+        return option_value->GetCurrentValue();
+    return FileSpecList();
+}
+
+
+lldb::Format
+OptionValue::GetFormatValue (lldb::Format fail_value) const
+{
+    const OptionValueFormat *option_value = GetAsFormat ();
+    if (option_value)
+        return option_value->GetCurrentValue();
+    return fail_value;
+}
+
+bool
+OptionValue::SetFormatValue (lldb::Format new_value)
+{
+    OptionValueFormat *option_value = GetAsFormat ();
+    if (option_value)
+    {
+        option_value->SetCurrentValue(new_value);
+        return true;
+    }
+    return false;
+}
+
+const RegularExpression *
+OptionValue::GetRegexValue () const
+{
+    const OptionValueRegex *option_value = GetAsRegex ();
+    if (option_value)
+        return option_value->GetCurrentValue();
+    return NULL;
+}
+
+
+int64_t
+OptionValue::GetSInt64Value (int64_t fail_value) const
+{
+    const OptionValueSInt64 *option_value = GetAsSInt64 ();
+    if (option_value)
+        return option_value->GetCurrentValue();
+    return fail_value;
+}
+
+bool
+OptionValue::SetSInt64Value (int64_t new_value)
+{
+    OptionValueSInt64 *option_value = GetAsSInt64 ();
+    if (option_value)
+    {
+        option_value->SetCurrentValue(new_value);
+        return true;
+    }
+    return false;
+}
+
+const char *
+OptionValue::GetStringValue (const char *fail_value) const
+{
+    const OptionValueString *option_value = GetAsString ();
+    if (option_value)
+        return option_value->GetCurrentValue();
+    return fail_value;
+}
+
+bool
+OptionValue::SetStringValue (const char *new_value)
+{
+    OptionValueString *option_value = GetAsString ();
+    if (option_value)
+    {
+        option_value->SetCurrentValue(new_value);
+        return true;
+    }
+    return false;
+}
+
+uint64_t
+OptionValue::GetUInt64Value (uint64_t fail_value) const
+{
+    const OptionValueUInt64 *option_value = GetAsUInt64 ();
+    if (option_value)
+        return option_value->GetCurrentValue();
+    return fail_value;
+}
+
+bool
+OptionValue::SetUInt64Value (uint64_t new_value)
+{
+    OptionValueUInt64 *option_value = GetAsUInt64 ();
+    if (option_value)
+    {
+        option_value->SetCurrentValue(new_value);
+        return true;
+    }
+    return false;
+}
+
+UUID
+OptionValue::GetUUIDValue () const
+{
+    const OptionValueUUID *option_value = GetAsUUID();
+    if (option_value)
+        return option_value->GetCurrentValue();
+    return UUID();
+}
+
+bool
+OptionValue::SetUUIDValue (const UUID &uuid)
+{
+    OptionValueUUID *option_value = GetAsUUID();
+    if (option_value)
+    {
+        option_value->SetCurrentValue(uuid);
+        return true;
+    }
+    return false;
+}
+
+const char *
+OptionValue::GetBuiltinTypeAsCString (Type t)
+{
+    switch (t)
+    {
+        case eTypeInvalid:      return "invalid";
+        case eTypeArch:         return "arch";
+        case eTypeArgs:         return "arguments";
+        case eTypeArray:        return "array";
+        case eTypeBoolean:      return "boolean";
+        case eTypeDictionary:   return "dictionary";
+        case eTypeEnum:         return "enum";
+        case eTypeFileSpec:     return "file";
+        case eTypeFileSpecList: return "file-list";
+        case eTypeFormat:       return "format";
+        case eTypePathMap:      return "path-map";
+        case eTypeProperties:   return "properties";
+        case eTypeRegex:        return "regex";
+        case eTypeSInt64:       return "int";
+        case eTypeString:       return "string";
+        case eTypeUInt64:       return "unsigned";
+        case eTypeUUID:         return "uuid";
+    }
+    return NULL;
+}
+
+
+lldb::OptionValueSP
+OptionValue::CreateValueFromCStringForTypeMask (const char *value_cstr, uint32_t type_mask, Error &error)
+{
+    // If only 1 bit is set in the type mask for a dictionary or array
+    // then we know how to decode a value from a cstring
+    lldb::OptionValueSP value_sp;
+    switch (type_mask)
+    {
+    case 1u << eTypeArch:       value_sp.reset(new OptionValueArch()); break;
+    case 1u << eTypeBoolean:    value_sp.reset(new OptionValueBoolean(false)); break;
+    case 1u << eTypeFileSpec:   value_sp.reset(new OptionValueFileSpec()); break;
+    case 1u << eTypeFormat:     value_sp.reset(new OptionValueFormat(eFormatInvalid));    break;
+    case 1u << eTypeSInt64:     value_sp.reset(new OptionValueSInt64()); break;
+    case 1u << eTypeString:     value_sp.reset(new OptionValueString()); break;
+    case 1u << eTypeUInt64:     value_sp.reset(new OptionValueUInt64()); break;
+    case 1u << eTypeUUID:       value_sp.reset(new OptionValueUUID()); break;
+    }
+
+    if (value_sp)
+        error = value_sp->SetValueFromCString (value_cstr, eVarSetOperationAssign);
+    else
+        error.SetErrorString("unsupported type mask");
+    return value_sp;
+}
+
+bool
+OptionValue::DumpQualifiedName (Stream &strm) const
+{
+    bool dumped_something = false;
+    lldb::OptionValueSP m_parent_sp(m_parent_wp.lock());
+    if (m_parent_sp)
+    {
+        if (m_parent_sp->DumpQualifiedName(strm))
+            dumped_something = true;
+    }
+    ConstString name (GetName());
+    if (name)
+    {
+        if (dumped_something)
+            strm.PutChar('.');
+        else
+            dumped_something = true;
+        strm << name;
+    }
+    return dumped_something;
+}
+
+size_t
+OptionValue::AutoComplete (CommandInterpreter &interpreter,
+                           const char *s,
+                           int match_start_point,
+                           int max_return_elements,
+                           bool &word_complete,
+                           StringList &matches)
+{
+    word_complete = false;
+    matches.Clear();
+    return matches.GetSize();
+}
+
+Error
+OptionValue::SetValueFromCString (const char *value, VarSetOperationType op)
+{
+    Error error;
+    switch (op)
+    {
+    case eVarSetOperationReplace:
+        error.SetErrorStringWithFormat ("%s objects do not support the 'replace' operation", GetTypeAsCString());
+        break;
+    case eVarSetOperationInsertBefore:
+        error.SetErrorStringWithFormat ("%s objects do not support the 'insert-before' operation", GetTypeAsCString());
+        break;
+    case eVarSetOperationInsertAfter:
+        error.SetErrorStringWithFormat ("%s objects do not support the 'insert-after' operation", GetTypeAsCString());
+        break;
+    case eVarSetOperationRemove:
+        error.SetErrorStringWithFormat ("%s objects do not support the 'remove' operation", GetTypeAsCString());
+        break;
+    case eVarSetOperationAppend:
+        error.SetErrorStringWithFormat ("%s objects do not support the 'append' operation", GetTypeAsCString());
+        break;
+    case eVarSetOperationClear:
+        error.SetErrorStringWithFormat ("%s objects do not support the 'clear' operation", GetTypeAsCString());
+        break;
+    case eVarSetOperationAssign:
+        error.SetErrorStringWithFormat ("%s objects do not support the 'assign' operation", GetTypeAsCString());
+        break;
+    case eVarSetOperationInvalid:
+        error.SetErrorStringWithFormat ("invalid operation performed on a %s object", GetTypeAsCString());
+        break;
+    }
+    return error;
+}
+