diff options
Diffstat (limited to 'lldb/source/Interpreter')
21 files changed, 3748 insertions, 515 deletions
diff --git a/lldb/source/Interpreter/CommandInterpreter.cpp b/lldb/source/Interpreter/CommandInterpreter.cpp index 979e21a5492..05384e4a3e5 100644 --- a/lldb/source/Interpreter/CommandInterpreter.cpp +++ b/lldb/source/Interpreter/CommandInterpreter.cpp @@ -84,17 +84,10 @@ CommandInterpreter::CommandInterpreter m_truncation_warning(eNoTruncation), m_command_source_depth (0) { - const char *dbg_name = debugger.GetInstanceName().AsCString(); - std::string lang_name = ScriptInterpreter::LanguageToString (script_language); - StreamString var_name; - var_name.Printf ("[%s].script-lang", dbg_name); - debugger.GetSettingsController()->SetVariable (var_name.GetData(), lang_name.c_str(), - eVarSetOperationAssign, false, - m_debugger.GetInstanceName().AsCString()); + debugger.SetScriptLanguage (script_language); SetEventName (eBroadcastBitThreadShouldExit, "thread-should-exit"); SetEventName (eBroadcastBitResetPrompt, "reset-prompt"); - SetEventName (eBroadcastBitQuitCommandReceived, "quit"); - + SetEventName (eBroadcastBitQuitCommandReceived, "quit"); CheckInWithManager (); } @@ -2505,6 +2498,7 @@ CommandInterpreter::OutputFormattedHelpText (Stream &strm, while (end > start && text[end] != ' ' && text[end] != '\t' && text[end] != '\n') end--; + assert (end > 0); } sub_len = end - start; diff --git a/lldb/source/Interpreter/NamedOptionValue.cpp b/lldb/source/Interpreter/NamedOptionValue.cpp deleted file mode 100644 index 33753b94155..00000000000 --- a/lldb/source/Interpreter/NamedOptionValue.cpp +++ /dev/null @@ -1,503 +0,0 @@ -//===-- NamedOptionValue.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/NamedOptionValue.h" - -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes -#include "lldb/Core/FormatManager.h" -#include "lldb/Core/State.h" -#include "lldb/Core/Stream.h" -#include "lldb/Interpreter/Args.h" - -using namespace lldb; -using namespace lldb_private; - - -//------------------------------------------------------------------------- -// OptionValue -//------------------------------------------------------------------------- - -// 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; -} - - -OptionValueBoolean * -OptionValue::GetAsBoolean () -{ - if (GetType () == OptionValue::eTypeBoolean) - return static_cast<OptionValueBoolean *>(this); - return NULL; -} - -OptionValueSInt64 * -OptionValue::GetAsSInt64 () -{ - if (GetType () == OptionValue::eTypeSInt64) - return static_cast<OptionValueSInt64 *>(this); - return NULL; -} - -OptionValueUInt64 * -OptionValue::GetAsUInt64 () -{ - if (GetType () == OptionValue::eTypeUInt64) - return static_cast<OptionValueUInt64 *>(this); - return NULL; -} - -OptionValueString * -OptionValue::GetAsString () -{ - if (GetType () == OptionValue::eTypeString) - return static_cast<OptionValueString *>(this); - return NULL; -} - -OptionValueFileSpec * -OptionValue::GetAsFileSpec () -{ - if (GetType () == OptionValue::eTypeFileSpec) - return static_cast<OptionValueFileSpec *>(this); - return NULL; - -} - -OptionValueFormat * -OptionValue::GetAsFormat () -{ - if (GetType () == OptionValue::eTypeFormat) - return static_cast<OptionValueFormat *>(this); - return NULL; -} - -OptionValueUUID * -OptionValue::GetAsUUID () -{ - if (GetType () == OptionValue::eTypeUUID) - return static_cast<OptionValueUUID *>(this); - return NULL; - -} - - -OptionValueArray * -OptionValue::GetAsArray () -{ - if (GetType () == OptionValue::eTypeArray) - return static_cast<OptionValueArray *>(this); - return NULL; -} - -OptionValueDictionary * -OptionValue::GetAsDictionary () -{ - if (GetType () == OptionValue::eTypeDictionary) - return static_cast<OptionValueDictionary *>(this); - return NULL; -} - -const char * -OptionValue::GetStringValue (const char *fail_value) -{ - OptionValueString *option_value = GetAsString (); - if (option_value) - return option_value->GetCurrentValue(); - return fail_value; -} - -uint64_t -OptionValue::GetUInt64Value (uint64_t fail_value) -{ - OptionValueUInt64 *option_value = GetAsUInt64 (); - if (option_value) - return option_value->GetCurrentValue(); - return fail_value; -} - -lldb::Format -OptionValue::GetFormatValue (lldb::Format fail_value) -{ - OptionValueFormat *option_value = GetAsFormat (); - if (option_value) - return option_value->GetCurrentValue(); - return fail_value; -} - -//------------------------------------------------------------------------- -// OptionValueCollection -//------------------------------------------------------------------------- - -void -OptionValueCollection::GetQualifiedName (Stream &strm) -{ - if (m_parent) - { - m_parent->GetQualifiedName (strm); - strm.PutChar('.'); - } - strm << m_name; -} - - -//------------------------------------------------------------------------- -// OptionValueBoolean -//------------------------------------------------------------------------- -void -OptionValueBoolean::DumpValue (Stream &strm) -{ - strm.PutCString (m_current_value ? "true" : "false"); -} - -Error -OptionValueBoolean::SetValueFromCString (const char *value_cstr) -{ - Error error; - bool success = false; - bool value = Args::StringToBoolean(value_cstr, false, &success); - if (success) - { - m_value_was_set = true; - m_current_value = value; - } - else - { - if (value_cstr == NULL) - error.SetErrorString ("invalid boolean string value: NULL"); - else if (value_cstr[0] == '\0') - error.SetErrorString ("invalid boolean string value <empty>"); - else - error.SetErrorStringWithFormat ("invalid boolean string value: '%s'", value_cstr); - } - return error; -} - -//------------------------------------------------------------------------- -// OptionValueSInt64 -//------------------------------------------------------------------------- -void -OptionValueSInt64::DumpValue (Stream &strm) -{ - strm.Printf ("%lli", m_current_value); -} - -Error -OptionValueSInt64::SetValueFromCString (const char *value_cstr) -{ - - Error error; - bool success = false; - int64_t value = Args::StringToSInt64 (value_cstr, 0, 0, &success); - if (success) - { - m_value_was_set = true; - m_current_value = value; - } - else - { - error.SetErrorStringWithFormat ("invalid int64_t string value: '%s'", value_cstr); - } - return error; -} - -//------------------------------------------------------------------------- -// OptionValueUInt64 -//------------------------------------------------------------------------- - -lldb::OptionValueSP -OptionValueUInt64::Create (const char *value_cstr, Error &error) -{ - lldb::OptionValueSP value_sp (new OptionValueUInt64()); - error = value_sp->SetValueFromCString (value_cstr); - if (error.Fail()) - value_sp.reset(); - return value_sp; -} - - -void -OptionValueUInt64::DumpValue (Stream &strm) -{ - strm.Printf ("0x%llx", m_current_value); -} - -Error -OptionValueUInt64::SetValueFromCString (const char *value_cstr) -{ - Error error; - bool success = false; - uint64_t value = Args::StringToUInt64 (value_cstr, 0, 0, &success); - if (success) - { - m_value_was_set = true; - m_current_value = value; - } - else - { - error.SetErrorStringWithFormat ("invalid uint64_t string value: '%s'", value_cstr); - } - return error; -} - -//------------------------------------------------------------------------- -// OptionValueDictionary -//------------------------------------------------------------------------- -void -OptionValueString::DumpValue (Stream &strm) -{ - strm.Printf ("\"%s\"", m_current_value.c_str()); -} - -Error -OptionValueString::SetValueFromCString (const char *value_cstr) -{ - m_value_was_set = true; - SetCurrentValue (value_cstr); - return Error (); -} - -//------------------------------------------------------------------------- -// OptionValueFileSpec -//------------------------------------------------------------------------- -void -OptionValueFileSpec::DumpValue (Stream &strm) -{ - if (m_current_value) - { - if (m_current_value.GetDirectory()) - { - strm << '"' << m_current_value.GetDirectory(); - if (m_current_value.GetFilename()) - strm << '/' << m_current_value.GetFilename(); - strm << '"'; - } - else - { - strm << '"' << m_current_value.GetFilename() << '"'; - } - } -} - -Error -OptionValueFileSpec::SetValueFromCString (const char *value_cstr) -{ - if (value_cstr && value_cstr[0]) - m_current_value.SetFile(value_cstr, false); - else - m_current_value.Clear(); - m_value_was_set = true; - return Error(); -} - -//------------------------------------------------------------------------- -// OptionValueFileSpecList -//------------------------------------------------------------------------- -void -OptionValueFileSpecList::DumpValue (Stream &strm) -{ - m_current_value.Dump(&strm, "\n"); -} - -Error -OptionValueFileSpecList::SetValueFromCString (const char *value_cstr) -{ - if (value_cstr && value_cstr[0]) - { - FileSpec file (value_cstr, false); - m_current_value.Append(file); - } - m_value_was_set = true; - return Error(); -} - - -//------------------------------------------------------------------------- -// OptionValueUUID -//------------------------------------------------------------------------- -void -OptionValueUUID::DumpValue (Stream &strm) -{ - m_uuid.Dump (&strm); -} - -Error -OptionValueUUID::SetValueFromCString (const char *value_cstr) -{ - Error error; - if (m_uuid.SetfromCString(value_cstr) == 0) - error.SetErrorStringWithFormat ("invalid uuid string value '%s'", value_cstr); - return error; -} - -//------------------------------------------------------------------------- -// OptionValueFormat -//------------------------------------------------------------------------- -void -OptionValueFormat::DumpValue (Stream &strm) -{ - strm.PutCString (FormatManager::GetFormatAsCString (m_current_value)); -} - -Error -OptionValueFormat::SetValueFromCString (const char *value_cstr) -{ - Format new_format; - Error error (Args::StringToFormat (value_cstr, new_format, NULL)); - if (error.Success()) - { - m_value_was_set = true; - m_current_value = new_format; - } - return error; -} - - -//------------------------------------------------------------------------- -// OptionValueArray -//------------------------------------------------------------------------- -void -OptionValueArray::DumpValue (Stream &strm) -{ - const uint32_t size = m_values.size(); - for (uint32_t i = 0; i<size; ++i) - { - strm.Printf("[%u] ", i); - m_values[i]->DumpValue (strm); - } -} - -Error -OptionValueArray::SetValueFromCString (const char *value_cstr) -{ - Error error; - error.SetErrorStringWithFormat ("array option values don't yet support being set by string: '%s'", value_cstr); - return error; -} - -//------------------------------------------------------------------------- -// OptionValueDictionary -//------------------------------------------------------------------------- -void -OptionValueDictionary::DumpValue (Stream &strm) -{ - collection::iterator pos, end = m_values.end(); - - for (pos = m_values.begin(); pos != end; ++pos) - { - strm.Printf("%s=", pos->first.GetCString()); - pos->second->DumpValue (strm); - } -} - -Error -OptionValueDictionary::SetValueFromCString (const char *value_cstr) -{ - Error error; - error.SetErrorStringWithFormat ("dictionary option values don't yet support being set by string: '%s'", value_cstr); - return error; -} - -lldb::OptionValueSP -OptionValueDictionary::GetValueForKey (const ConstString &key) const -{ - lldb::OptionValueSP value_sp; - collection::const_iterator pos = m_values.find (key); - if (pos != m_values.end()) - value_sp = pos->second; - return value_sp; -} - -const char * -OptionValueDictionary::GetStringValueForKey (const ConstString &key) -{ - collection::const_iterator pos = m_values.find (key); - if (pos != m_values.end()) - { - if (pos->second->GetType() == OptionValue::eTypeString) - return static_cast<OptionValueString *>(pos->second.get())->GetCurrentValue(); - } - return NULL; -} - - -bool -OptionValueDictionary::SetStringValueForKey (const ConstString &key, - const char *value, - bool can_replace) -{ - collection::const_iterator pos = m_values.find (key); - if (pos != m_values.end()) - { - if (!can_replace) - return false; - if (pos->second->GetType() == OptionValue::eTypeString) - { - pos->second->SetValueFromCString(value); - return true; - } - } - m_values[key] = OptionValueSP (new OptionValueString (value)); - return true; - -} - -bool -OptionValueDictionary::SetValueForKey (const ConstString &key, - const lldb::OptionValueSP &value_sp, - bool can_replace) -{ - // Make sure the value_sp object is allowed to contain - // values of the type passed in... - if (value_sp && (m_type_mask & value_sp->GetTypeAsMask())) - { - if (!can_replace) - { - collection::const_iterator pos = m_values.find (key); - if (pos != m_values.end()) - return false; - } - m_values[key] = value_sp; - return true; - } - return false; -} - -bool -OptionValueDictionary::DeleteValueForKey (const ConstString &key) -{ - collection::iterator pos = m_values.find (key); - if (pos != m_values.end()) - { - m_values.erase(pos); - return true; - } - return false; -} - - diff --git a/lldb/source/Interpreter/OptionGroupValueObjectDisplay.cpp b/lldb/source/Interpreter/OptionGroupValueObjectDisplay.cpp index ced2c5c69c7..bf58dd26f21 100644 --- a/lldb/source/Interpreter/OptionGroupValueObjectDisplay.cpp +++ b/lldb/source/Interpreter/OptionGroupValueObjectDisplay.cpp @@ -31,8 +31,7 @@ OptionGroupValueObjectDisplay::~OptionGroupValueObjectDisplay () static OptionDefinition g_option_table[] = { - { LLDB_OPT_SET_1, false, "dynamic-type", 'd', required_argument, TargetInstanceSettings::g_dynamic_value_types, - 0, eArgTypeNone, "Show the object as its full dynamic type, not its static type, if available."}, + { LLDB_OPT_SET_1, false, "dynamic-type", 'd', required_argument, g_dynamic_value_types, 0, eArgTypeNone, "Show the object as its full dynamic type, not its static type, if available."}, { LLDB_OPT_SET_1, false, "synthetic-type", 'S', required_argument, NULL, 0, eArgTypeBoolean, "Show the object obeying its synthetic provider, if available."}, { LLDB_OPT_SET_1, false, "depth", 'D', required_argument, NULL, 0, eArgTypeCount, "Set the max recurse depth when dumping aggregate types (default is infinity)."}, { LLDB_OPT_SET_1, false, "flat", 'F', no_argument, NULL, 0, eArgTypeNone, "Display results in a flat format that uses expression paths for each variable or member."}, @@ -73,7 +72,7 @@ OptionGroupValueObjectDisplay::SetOptionValue (CommandInterpreter &interpreter, case 'd': { int32_t result; - result = Args::StringToOptionEnum (option_arg, TargetInstanceSettings::g_dynamic_value_types, 2, error); + result = Args::StringToOptionEnum (option_arg, g_dynamic_value_types, 2, error); if (error.Success()) use_dynamic = (lldb::DynamicValueType) result; } diff --git a/lldb/source/Interpreter/OptionValue.cpp b/lldb/source/Interpreter/OptionValue.cpp new file mode 100644 index 00000000000..01ba65cf107 --- /dev/null +++ b/lldb/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; +} + diff --git a/lldb/source/Interpreter/OptionValueArch.cpp b/lldb/source/Interpreter/OptionValueArch.cpp new file mode 100644 index 00000000000..90ae77527b2 --- /dev/null +++ b/lldb/source/Interpreter/OptionValueArch.cpp @@ -0,0 +1,109 @@ +//===-- OptionValueArch.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/OptionValueArch.h" + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/Core/FormatManager.h" +#include "lldb/Core/State.h" +#include "lldb/Interpreter/Args.h" +#include "lldb/Interpreter/CommandCompletions.h" + +using namespace lldb; +using namespace lldb_private; + +void +OptionValueArch::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask) +{ + if (dump_mask & eDumpOptionType) + strm.Printf ("(%s)", GetTypeAsCString ()); + if (dump_mask & eDumpOptionValue) + { + if (dump_mask & eDumpOptionType) + strm.PutCString (" = "); + + if (m_current_value.IsValid()) + { + const char *arch_name = m_current_value.GetArchitectureName(); + if (arch_name) + strm.PutCString (arch_name); + } + } +} + +Error +OptionValueArch::SetValueFromCString (const char *value_cstr, VarSetOperationType op) +{ + Error error; + switch (op) + { + case eVarSetOperationClear: + Clear(); + break; + + case eVarSetOperationReplace: + case eVarSetOperationAssign: + if (value_cstr && value_cstr[0]) + { + if (m_current_value.SetTriple (value_cstr)) + m_value_was_set = true; + else + error.SetErrorStringWithFormat("unsupported architecture '%s'", value_cstr); + } + else + { + error.SetErrorString("invalid value string"); + } + break; + + case eVarSetOperationInsertBefore: + case eVarSetOperationInsertAfter: + case eVarSetOperationRemove: + case eVarSetOperationAppend: + case eVarSetOperationInvalid: + error = OptionValue::SetValueFromCString (value_cstr, op); + break; + } + return error; +} + +lldb::OptionValueSP +OptionValueArch::DeepCopy () const +{ + return OptionValueSP(new OptionValueArch(*this)); +} + + +size_t +OptionValueArch::AutoComplete (CommandInterpreter &interpreter, + const char *s, + int match_start_point, + int max_return_elements, + bool &word_complete, + StringList &matches) +{ + word_complete = false; + matches.Clear(); + CommandCompletions::InvokeCommonCompletionCallbacks (interpreter, + CommandCompletions::eArchitectureCompletion, + s, + match_start_point, + max_return_elements, + NULL, + word_complete, + matches); + return matches.GetSize(); +} + + + + diff --git a/lldb/source/Interpreter/OptionValueArgs.cpp b/lldb/source/Interpreter/OptionValueArgs.cpp new file mode 100644 index 00000000000..e28d884581f --- /dev/null +++ b/lldb/source/Interpreter/OptionValueArgs.cpp @@ -0,0 +1,38 @@ +//===-- OptionValueArgs.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/OptionValueArgs.h" + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/Interpreter/Args.h" + +using namespace lldb; +using namespace lldb_private; + +size_t +OptionValueArgs::GetArgs (Args &args) +{ + const uint32_t size = m_values.size(); + std::vector<const char *> argv; + for (uint32_t i = 0; i<size; ++i) + { + const char *string_value = m_values[i]->GetStringValue (); + if (string_value) + argv.push_back(string_value); + } + + if (argv.empty()) + args.Clear(); + else + args.SetArguments(argv.size(), &argv[0]); + return args.GetArgumentCount(); +} diff --git a/lldb/source/Interpreter/OptionValueArray.cpp b/lldb/source/Interpreter/OptionValueArray.cpp new file mode 100644 index 00000000000..fbddd7b70a3 --- /dev/null +++ b/lldb/source/Interpreter/OptionValueArray.cpp @@ -0,0 +1,350 @@ +//===-- OptionValueArray.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/OptionValueArray.h" + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/Core/Stream.h" +#include "lldb/Interpreter/Args.h" + +using namespace lldb; +using namespace lldb_private; + +void +OptionValueArray::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask) +{ + const Type array_element_type = ConvertTypeMaskToType (m_type_mask); + if (dump_mask & eDumpOptionType) + { + if ((GetType() == eTypeArray) && (m_type_mask != eTypeInvalid)) + strm.Printf ("(%s of %ss)", GetTypeAsCString(), GetBuiltinTypeAsCString(array_element_type)); + else + strm.Printf ("(%s)", GetTypeAsCString()); + } + if (dump_mask & eDumpOptionValue) + { + if (dump_mask & eDumpOptionType) + strm.Printf (" =%s", (m_values.size() > 0) ? "\n" : ""); + strm.IndentMore(); + const uint32_t size = m_values.size(); + for (uint32_t i = 0; i<size; ++i) + { + strm.Indent(); + strm.Printf("[%u]: ", i); + const uint32_t extra_dump_options = m_raw_value_dump ? eDumpOptionRaw : 0; + switch (array_element_type) + { + default: + case eTypeArray: + case eTypeDictionary: + case eTypeProperties: + case eTypeFileSpecList: + case eTypePathMap: + m_values[i]->DumpValue(exe_ctx, strm, dump_mask | extra_dump_options); + break; + + case eTypeBoolean: + case eTypeEnum: + case eTypeFileSpec: + case eTypeFormat: + case eTypeSInt64: + case eTypeString: + case eTypeUInt64: + case eTypeUUID: + // No need to show the type for dictionaries of simple items + m_values[i]->DumpValue(exe_ctx, strm, (dump_mask & (~eDumpOptionType)) | extra_dump_options); + break; + } + if (i < (size - 1)) + strm.EOL(); + } + strm.IndentLess(); + } +} + +Error +OptionValueArray::SetValueFromCString (const char *value, VarSetOperationType op) +{ + Args args(value); + return SetArgs (args, op); +} + + +lldb::OptionValueSP +OptionValueArray::GetSubValue (const ExecutionContext *exe_ctx, + const char *name, + bool will_modify, + Error &error) const +{ + if (name && name[0] == '[') + { + const char *end_bracket = strchr (name+1, ']'); + if (end_bracket) + { + const char *sub_value = NULL; + if (end_bracket[1]) + sub_value = end_bracket + 1; + std::string index_str (name+1, end_bracket); + const size_t array_count = m_values.size(); + int32_t idx = Args::StringToSInt32(index_str.c_str(), INT32_MAX, 0, NULL); + if (idx != INT32_MAX) + { + ; + uint32_t new_idx = UINT32_MAX; + if (idx < 0) + { + // Access from the end of the array if the index is negative + new_idx = array_count - idx; + } + else + { + // Just a standard index + new_idx = idx; + } + + if (new_idx < array_count) + { + if (m_values[new_idx]) + { + if (sub_value) + return m_values[new_idx]->GetSubValue (exe_ctx, sub_value, will_modify, error); + else + return m_values[new_idx]; + } + } + else + { + if (array_count == 0) + error.SetErrorStringWithFormat("index %i is not valid for an empty array", idx); + else if (idx > 0) + error.SetErrorStringWithFormat("index %i out of range, valid values are 0 through %zu", idx, array_count - 1); + else + error.SetErrorStringWithFormat("negative index %i out of range, valid values are -1 through -%zu", idx, array_count); + } + } + } + } + else + { + error.SetErrorStringWithFormat("invalid value path '%s', %s values only support '[<index>]' subvalues where <index> is a positive or negative array index", name, GetTypeAsCString()); + } + return OptionValueSP(); +} + + +size_t +OptionValueArray::GetArgs (Args &args) const +{ + const uint32_t size = m_values.size(); + std::vector<const char *> argv; + for (uint32_t i = 0; i<size; ++i) + { + const char *string_value = m_values[i]->GetStringValue (); + if (string_value) + argv.push_back(string_value); + } + + if (argv.empty()) + args.Clear(); + else + args.SetArguments(argv.size(), &argv[0]); + return args.GetArgumentCount(); +} + +Error +OptionValueArray::SetArgs (const Args &args, VarSetOperationType op) +{ + Error error; + const size_t argc = args.GetArgumentCount(); + switch (op) + { + case eVarSetOperationInvalid: + error.SetErrorString("unsupported operation"); + break; + + case eVarSetOperationInsertBefore: + case eVarSetOperationInsertAfter: + if (argc > 1) + { + uint32_t idx = Args::StringToUInt32(args.GetArgumentAtIndex(0), UINT32_MAX); + const uint32_t count = GetSize(); + if (idx > count) + { + error.SetErrorStringWithFormat("invalid insert array index %u, index must be 0 through %u", idx, count); + } + else + { + if (op == eVarSetOperationInsertAfter) + ++idx; + for (size_t i=1; i<argc; ++i, ++idx) + { + lldb::OptionValueSP value_sp (CreateValueFromCStringForTypeMask (args.GetArgumentAtIndex(i), + m_type_mask, + error)); + if (value_sp) + { + if (error.Fail()) + return error; + if (idx >= m_values.size()) + m_values.push_back(value_sp); + else + m_values.insert(m_values.begin() + idx, value_sp); + } + else + { + error.SetErrorString("array of complex types must subclass OptionValueArray"); + return error; + } + } + } + } + else + { + error.SetErrorString("insert operation takes an array index followed by one or more values"); + } + break; + + case eVarSetOperationRemove: + if (argc > 0) + { + const uint32_t size = m_values.size(); + std::vector<int> remove_indexes; + bool all_indexes_valid = true; + size_t i; + for (i=0; i<argc; ++i) + { + const int idx = Args::StringToSInt32(args.GetArgumentAtIndex(i), INT32_MAX); + if (idx >= size) + { + all_indexes_valid = false; + break; + } + else + remove_indexes.push_back(idx); + } + + if (all_indexes_valid) + { + size_t num_remove_indexes = remove_indexes.size(); + if (num_remove_indexes) + { + // Sort and then erase in reverse so indexes are always valid + if (num_remove_indexes > 1) + { + std::sort(remove_indexes.begin(), remove_indexes.end()); + for (std::vector<int>::const_reverse_iterator pos = remove_indexes.rbegin(), end = remove_indexes.rend(); pos != end; ++pos) + { + m_values.erase(m_values.begin() + *pos); + } + } + else + { + // Only one index + m_values.erase(m_values.begin() + remove_indexes.front()); + } + } + } + else + { + error.SetErrorStringWithFormat("invalid array index '%s', aborting remove operation", args.GetArgumentAtIndex(i)); + } + } + else + { + error.SetErrorString("remove operation takes one or more array indices"); + } + break; + + case eVarSetOperationClear: + Clear (); + break; + + case eVarSetOperationReplace: + if (argc > 1) + { + uint32_t idx = Args::StringToUInt32(args.GetArgumentAtIndex(0), UINT32_MAX); + const uint32_t count = GetSize(); + if (idx > count) + { + error.SetErrorStringWithFormat("invalid replace array index %u, index must be 0 through %u", idx, count); + } + else + { + for (size_t i=1; i<argc; ++i, ++idx) + { + lldb::OptionValueSP value_sp (CreateValueFromCStringForTypeMask (args.GetArgumentAtIndex(i), + m_type_mask, + error)); + if (value_sp) + { + if (error.Fail()) + return error; + if (idx < count) + m_values[idx] = value_sp; + else + m_values.push_back(value_sp); + } + else + { + error.SetErrorString("array of complex types must subclass OptionValueArray"); + return error; + } + } + } + } + else + { + error.SetErrorString("replace operation takes an array index followed by one or more values"); + } + break; + + case eVarSetOperationAssign: + m_values.clear(); + // Fall through to append case + case eVarSetOperationAppend: + for (size_t i=0; i<argc; ++i) + { + lldb::OptionValueSP value_sp (CreateValueFromCStringForTypeMask (args.GetArgumentAtIndex(i), + m_type_mask, + error)); + if (value_sp) + { + if (error.Fail()) + return error; + m_value_was_set = true; + AppendValue(value_sp); + } + else + { + error.SetErrorString("array of complex types must subclass OptionValueArray"); + } + } + break; + } + return error; +} + +lldb::OptionValueSP +OptionValueArray::DeepCopy () const +{ + OptionValueArray *copied_array = new OptionValueArray (m_type_mask, m_raw_value_dump); + lldb::OptionValueSP copied_value_sp(copied_array); + const uint32_t size = m_values.size(); + for (uint32_t i = 0; i<size; ++i) + { + copied_array->AppendValue (m_values[i]->DeepCopy()); + } + return copied_value_sp; +} + + + diff --git a/lldb/source/Interpreter/OptionValueBoolean.cpp b/lldb/source/Interpreter/OptionValueBoolean.cpp new file mode 100644 index 00000000000..4e6fd62bb69 --- /dev/null +++ b/lldb/source/Interpreter/OptionValueBoolean.cpp @@ -0,0 +1,87 @@ +//===-- OptionValueBoolean.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/OptionValueBoolean.h" + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/Core/Stream.h" +#include "lldb/Interpreter/Args.h" + +using namespace lldb; +using namespace lldb_private; + +void +OptionValueBoolean::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask) +{ + if (dump_mask & eDumpOptionType) + strm.Printf ("(%s)", GetTypeAsCString ()); +// if (dump_mask & eDumpOptionName) +// DumpQualifiedName (strm); + if (dump_mask & eDumpOptionValue) + { + if (dump_mask & eDumpOptionType) + strm.PutCString (" = "); + strm.PutCString (m_current_value ? "true" : "false"); + } +} + +Error +OptionValueBoolean::SetValueFromCString (const char *value_cstr, + VarSetOperationType op) +{ + Error error; + switch (op) + { + case eVarSetOperationClear: + Clear(); + break; + + case eVarSetOperationReplace: + case eVarSetOperationAssign: + { + bool success = false; + bool value = Args::StringToBoolean(value_cstr, false, &success); + if (success) + { + m_value_was_set = true; + m_current_value = value; + } + else + { + if (value_cstr == NULL) + error.SetErrorString ("invalid boolean string value: NULL"); + else if (value_cstr[0] == '\0') + error.SetErrorString ("invalid boolean string value <empty>"); + else + error.SetErrorStringWithFormat ("invalid boolean string value: '%s'", value_cstr); + } + } + break; + + case eVarSetOperationInsertBefore: + case eVarSetOperationInsertAfter: + case eVarSetOperationRemove: + case eVarSetOperationAppend: + case eVarSetOperationInvalid: + error = OptionValue::SetValueFromCString (value_cstr, op); + break; + } + return error; +} + +lldb::OptionValueSP +OptionValueBoolean::DeepCopy () const +{ + return OptionValueSP(new OptionValueBoolean(*this)); +} + + diff --git a/lldb/source/Interpreter/OptionValueDictionary.cpp b/lldb/source/Interpreter/OptionValueDictionary.cpp new file mode 100644 index 00000000000..e291f7faa54 --- /dev/null +++ b/lldb/source/Interpreter/OptionValueDictionary.cpp @@ -0,0 +1,434 @@ +//===-- OptionValueDictionary.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/OptionValueDictionary.h" + +// C Includes +// C++ Includes +// Other libraries and framework includes +#include "llvm/ADT/StringRef.h" +// Project includes +#include "lldb/Core/FormatManager.h" +#include "lldb/Core/State.h" +#include "lldb/Interpreter/Args.h" +#include "lldb/Interpreter/OptionValueString.h" + +using namespace lldb; +using namespace lldb_private; + +void +OptionValueDictionary::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask) +{ + const Type dict_type = ConvertTypeMaskToType (m_type_mask); + if (dump_mask & eDumpOptionType) + { + if (m_type_mask != eTypeInvalid) + strm.Printf ("(%s of %ss)", GetTypeAsCString(), GetBuiltinTypeAsCString(dict_type)); + else + strm.Printf ("(%s)", GetTypeAsCString()); + } + if (dump_mask & eDumpOptionValue) + { + if (dump_mask & eDumpOptionType) + strm.PutCString (" ="); + + collection::iterator pos, end = m_values.end(); + + strm.IndentMore(); + + for (pos = m_values.begin(); pos != end; ++pos) + { + OptionValue *option_value = pos->second.get(); + strm.EOL(); + strm.Indent(pos->first.GetCString()); + + const uint32_t extra_dump_options = m_raw_value_dump ? eDumpOptionRaw : 0; + switch (dict_type) + { + default: + case eTypeArray: + case eTypeDictionary: + case eTypeProperties: + case eTypeFileSpecList: + case eTypePathMap: + strm.PutChar (' '); + option_value->DumpValue(exe_ctx, strm, dump_mask | extra_dump_options); + break; + + case eTypeBoolean: + case eTypeEnum: + case eTypeFileSpec: + case eTypeFormat: + case eTypeSInt64: + case eTypeString: + case eTypeUInt64: + case eTypeUUID: + // No need to show the type for dictionaries of simple items + strm.PutCString("="); + option_value->DumpValue(exe_ctx, strm, (dump_mask & (~eDumpOptionType)) | extra_dump_options); + break; + } + } + strm.IndentLess(); + } + +} + +size_t +OptionValueDictionary::GetArgs (Args &args) const +{ + args.Clear(); + collection::const_iterator pos, end = m_values.end(); + for (pos = m_values.begin(); pos != end; ++pos) + { + StreamString strm; + strm.Printf("%s=", pos->first.GetCString()); + pos->second->DumpValue(NULL, strm, eDumpOptionValue|eDumpOptionRaw); + args.AppendArgument(strm.GetString().c_str()); + } + return args.GetArgumentCount(); +} + +Error +OptionValueDictionary::SetArgs (const Args &args, VarSetOperationType op) +{ + Error error; + const size_t argc = args.GetArgumentCount(); + switch (op) + { + case eVarSetOperationClear: + Clear(); + break; + + case eVarSetOperationAppend: + case eVarSetOperationReplace: + case eVarSetOperationAssign: + if (argc > 0) + { + for (size_t i=0; i<argc; ++i) + { + llvm::StringRef key_and_value(args.GetArgumentAtIndex(i)); + if (!key_and_value.empty()) + { + std::pair<llvm::StringRef, llvm::StringRef> kvp(key_and_value.split('=')); + llvm::StringRef key = kvp.first; + bool key_valid = false; + if (!key.empty()) + { + if (key.front() == '[') + { + // Key name starts with '[', so the the key value must be in single or double quotes like: + // ['<key>'] + // ["<key>"] + if ((key.size() > 2) && (key.back() == ']')) + { + // Strip leading '[' and trailing ']' + key = key.substr(1, key.size()-2); + const char quote_char = key.front(); + if ((quote_char == '\'') || (quote_char == '"')) + { + if ((key.size() > 2) && (key.back() == quote_char)) + { + // Strip the quotes + key = key.substr(1, key.size()-2); + key_valid = true; + } + } + else + { + // square brackets, no quotes + key_valid = true; + } + } + } + else + { + // No square brackets or quotes + key_valid = true; + } + } + if (!key_valid) + { + 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()); + return error; + } + + lldb::OptionValueSP value_sp (CreateValueFromCStringForTypeMask (kvp.second.data(), + m_type_mask, + error)); + if (value_sp) + { + if (error.Fail()) + return error; + m_value_was_set = true; + SetValueForKey (ConstString(key), value_sp, true); + } + else + { + error.SetErrorString("dictionaries that can contain multiple types must subclass OptionValueArray"); + } + } + else + { + error.SetErrorString("empty argument"); + } + } + } + else + { + error.SetErrorString("assign operation takes one or more key=value arguments"); + } + break; + + case eVarSetOperationRemove: + if (argc > 0) + { + for (size_t i=0; i<argc; ++i) + { + ConstString key(args.GetArgumentAtIndex(i)); + if (!DeleteValueForKey(key)) + { + error.SetErrorStringWithFormat("no value found named '%s', aborting remove operation", key.GetCString()); + break; + } + } + } + else + { + error.SetErrorString("remove operation takes one or more key arguments"); + } + break; + + case eVarSetOperationInsertBefore: + case eVarSetOperationInsertAfter: + case eVarSetOperationInvalid: + error = OptionValue::SetValueFromCString (NULL, op); + break; + } + return error; +} + +Error +OptionValueDictionary::SetValueFromCString (const char *value_cstr, VarSetOperationType op) +{ + Args args(value_cstr); + return SetArgs (args, op); +} + +lldb::OptionValueSP +OptionValueDictionary::GetSubValue (const ExecutionContext *exe_ctx, const char *name, bool will_modify, Error &error) const +{ + lldb::OptionValueSP value_sp; + + if (name && name[0]) + { + const char *sub_name = NULL; + ConstString key; + const char *open_bracket = ::strchr (name, '['); + + if (open_bracket) + { + const char *key_start = open_bracket + 1; + const char *key_end = NULL; + switch (open_bracket[1]) + { + case '\'': + ++key_start; + key_end = strchr(key_start, '\''); + if (key_end) + { + if (key_end[1] == ']') + { + if (key_end[2]) + sub_name = key_end + 2; + } + else + { + 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); + return value_sp; + } + } + else + { + error.SetErrorString ("missing '] key name terminator, key name started with ['"); + return value_sp; + } + break; + case '"': + ++key_start; + key_end = strchr(key_start, '"'); + if (key_end) + { + if (key_end[1] == ']') + { + if (key_end[2]) + sub_name = key_end + 2; + break; + } + 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); + return value_sp; + } + else + { + error.SetErrorString ("missing \"] key name terminator, key name started with [\""); + return value_sp; + } + break; + + default: + key_end = strchr(key_start, ']'); + if (key_end) + { + if (key_end[1]) + sub_name = key_end + 1; + } + else + { + error.SetErrorString ("missing ] key name terminator, key name started with ["); + return value_sp; + } + break; + } + + if (key_start && key_end) + { + key.SetCStringWithLength (key_start, key_end - key_start); + + value_sp = GetValueForKey (key); + if (value_sp) + { + if (sub_name) + return value_sp->GetSubValue (exe_ctx, sub_name, will_modify, error); + } + else + { + error.SetErrorStringWithFormat("dictionary does not contain a value for the key name '%s'", key.GetCString()); + } + } + } + if (!value_sp && error.AsCString() == NULL) + { + error.SetErrorStringWithFormat ("invalid value path '%s', %s values only support '[<key>]' subvalues where <key> a string value optionally delimitted by single or double quotes", + name, + GetTypeAsCString()); + } + } + return value_sp; +} + +Error +OptionValueDictionary::SetSubValue (const ExecutionContext *exe_ctx, VarSetOperationType op, const char *name, const char *value) +{ + Error error; + const bool will_modify = true; + lldb::OptionValueSP value_sp (GetSubValue (exe_ctx, name, will_modify, error)); + if (value_sp) + error = value_sp->SetValueFromCString(value, op); + else + { + if (error.AsCString() == NULL) + error.SetErrorStringWithFormat("invalid value path '%s'", name); + } + return error; +} + + +lldb::OptionValueSP +OptionValueDictionary::GetValueForKey (const ConstString &key) const +{ + lldb::OptionValueSP value_sp; + collection::const_iterator pos = m_values.find (key); + if (pos != m_values.end()) + value_sp = pos->second; + return value_sp; +} + +const char * +OptionValueDictionary::GetStringValueForKey (const ConstString &key) +{ + collection::const_iterator pos = m_values.find (key); + if (pos != m_values.end()) + { + OptionValueString *string_value = pos->second->GetAsString(); + if (string_value) + return string_value->GetCurrentValue(); + } + return NULL; +} + + +bool +OptionValueDictionary::SetStringValueForKey (const ConstString &key, + const char *value, + bool can_replace) +{ + collection::const_iterator pos = m_values.find (key); + if (pos != m_values.end()) + { + if (!can_replace) + return false; + if (pos->second->GetType() == OptionValue::eTypeString) + { + pos->second->SetValueFromCString(value); + return true; + } + } + m_values[key] = OptionValueSP (new OptionValueString (value)); + return true; + +} + +bool +OptionValueDictionary::SetValueForKey (const ConstString &key, + const lldb::OptionValueSP &value_sp, + bool can_replace) +{ + // Make sure the value_sp object is allowed to contain + // values of the type passed in... + if (value_sp && (m_type_mask & value_sp->GetTypeAsMask())) + { + if (!can_replace) + { + collection::const_iterator pos = m_values.find (key); + if (pos != m_values.end()) + return false; + } + m_values[key] = value_sp; + return true; + } + return false; +} + +bool +OptionValueDictionary::DeleteValueForKey (const ConstString &key) +{ + collection::iterator pos = m_values.find (key); + if (pos != m_values.end()) + { + m_values.erase(pos); + return true; + } + return false; +} + +lldb::OptionValueSP +OptionValueDictionary::DeepCopy () const +{ + OptionValueDictionary *copied_dict = new OptionValueDictionary (m_type_mask, m_raw_value_dump); + lldb::OptionValueSP copied_value_sp(copied_dict); + collection::const_iterator pos, end = m_values.end(); + for (pos = m_values.begin(); pos != end; ++pos) + { + StreamString strm; + strm.Printf("%s=", pos->first.GetCString()); + copied_dict->SetValueForKey (pos->first, pos->second->DeepCopy(), true); + } + return copied_value_sp; +} + diff --git a/lldb/source/Interpreter/OptionValueEnumeration.cpp b/lldb/source/Interpreter/OptionValueEnumeration.cpp new file mode 100644 index 00000000000..61b184fe0a5 --- /dev/null +++ b/lldb/source/Interpreter/OptionValueEnumeration.cpp @@ -0,0 +1,131 @@ +//===-- OptionValueEnumeration.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/OptionValueEnumeration.h" + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes + +using namespace lldb; +using namespace lldb_private; + +OptionValueEnumeration::OptionValueEnumeration (const OptionEnumValueElement *enumerators, + enum_type value) : + OptionValue(), + m_current_value (value), + m_default_value (value), + m_enumerations () +{ + SetEnumerations(enumerators); +} + +OptionValueEnumeration::~OptionValueEnumeration() +{ +} + +void +OptionValueEnumeration::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask) +{ + if (dump_mask & eDumpOptionType) + strm.Printf ("(%s)", GetTypeAsCString ()); + if (dump_mask & eDumpOptionValue) + { + if (dump_mask & eDumpOptionType) + strm.PutCString (" = "); + const size_t count = m_enumerations.GetSize (); + for (size_t i=0; i<count; ++i) + { + if (m_enumerations.GetValueAtIndexUnchecked(i).value == m_current_value) + { + strm.PutCString(m_enumerations.GetCStringAtIndex(i)); + return; + } + } + strm.Printf("%llu", (uint64_t)m_current_value); + } +} + +Error +OptionValueEnumeration::SetValueFromCString (const char *value, VarSetOperationType op) +{ + Error error; + switch (op) + { + case eVarSetOperationClear: + Clear (); + break; + + case eVarSetOperationReplace: + case eVarSetOperationAssign: + if (value && value[0]) + { + ConstString const_enumerator_name(value); + const EnumerationMapEntry *enumerator_entry = m_enumerations.FindFirstValueForName (const_enumerator_name.GetCString()); + if (enumerator_entry) + { + m_current_value = enumerator_entry->value.value; + } + else + { + StreamString error_strm; + error_strm.Printf("invalid enumeration value '%s'", value); + const size_t count = m_enumerations.GetSize (); + if (count) + { + error_strm.Printf(", valid values are: %s", m_enumerations.GetCStringAtIndex(0)); + for (size_t i=1; i<count; ++i) + { + error_strm.Printf (", %s", m_enumerations.GetCStringAtIndex(i)); + } + } + error.SetErrorString(error_strm.GetData()); + } + } + else + { + error.SetErrorString("invalid enumeration value"); + } + break; + + case eVarSetOperationInsertBefore: + case eVarSetOperationInsertAfter: + case eVarSetOperationRemove: + case eVarSetOperationAppend: + case eVarSetOperationInvalid: + error = OptionValue::SetValueFromCString (value, op); + break; + } + return error; +} + +void +OptionValueEnumeration::SetEnumerations (const OptionEnumValueElement *enumerators) +{ + m_enumerations.Clear(); + if (enumerators) + { + for (size_t i=0; enumerators[i].string_value != NULL; ++i) + { + ConstString const_enumerator_name(enumerators[i].string_value); + EnumeratorInfo enumerator_info = { enumerators[i].value, enumerators[i].usage }; + m_enumerations.Append (const_enumerator_name.GetCString(), enumerator_info); + } + m_enumerations.Sort(); + } +} + + +lldb::OptionValueSP +OptionValueEnumeration::DeepCopy () const +{ + return OptionValueSP(new OptionValueEnumeration(*this)); +} + diff --git a/lldb/source/Interpreter/OptionValueFileSpec.cpp b/lldb/source/Interpreter/OptionValueFileSpec.cpp new file mode 100644 index 00000000000..20b0b043e0b --- /dev/null +++ b/lldb/source/Interpreter/OptionValueFileSpec.cpp @@ -0,0 +1,116 @@ +//===-- OptionValueFileSpec.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/OptionValueFileSpec.h" + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/Core/FormatManager.h" +#include "lldb/Core/State.h" +#include "lldb/Interpreter/Args.h" +#include "lldb/Interpreter/CommandCompletions.h" + +using namespace lldb; +using namespace lldb_private; + +void +OptionValueFileSpec::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask) +{ + if (dump_mask & eDumpOptionType) + strm.Printf ("(%s)", GetTypeAsCString ()); + if (dump_mask & eDumpOptionValue) + { + if (dump_mask & eDumpOptionType) + strm.PutCString (" = "); + + if (m_current_value) + { + if (m_current_value.GetDirectory()) + { + strm << '"' << m_current_value.GetDirectory(); + if (m_current_value.GetFilename()) + strm << '/' << m_current_value.GetFilename(); + strm << '"'; + } + else + { + strm << '"' << m_current_value.GetFilename() << '"'; + } + } + } +} + +Error +OptionValueFileSpec::SetValueFromCString (const char *value_cstr, + VarSetOperationType op) +{ + Error error; + switch (op) + { + case eVarSetOperationClear: + Clear (); + break; + + case eVarSetOperationReplace: + case eVarSetOperationAssign: + if (value_cstr && value_cstr[0]) + { + m_value_was_set = true; + m_current_value.SetFile(value_cstr, false); + } + else + { + error.SetErrorString("invalid value string"); + } + break; + + case eVarSetOperationInsertBefore: + case eVarSetOperationInsertAfter: + case eVarSetOperationRemove: + case eVarSetOperationAppend: + case eVarSetOperationInvalid: + error = OptionValue::SetValueFromCString (value_cstr, op); + break; + } + return error; +} + +lldb::OptionValueSP +OptionValueFileSpec::DeepCopy () const +{ + return OptionValueSP(new OptionValueFileSpec(*this)); +} + + +size_t +OptionValueFileSpec::AutoComplete (CommandInterpreter &interpreter, + const char *s, + int match_start_point, + int max_return_elements, + bool &word_complete, + StringList &matches) +{ + word_complete = false; + matches.Clear(); + CommandCompletions::InvokeCommonCompletionCallbacks (interpreter, + CommandCompletions::eDiskFileCompletion, + s, + match_start_point, + max_return_elements, + NULL, + word_complete, + matches); + return matches.GetSize(); +} + + + + diff --git a/lldb/source/Interpreter/OptionValueFileSpecLIst.cpp b/lldb/source/Interpreter/OptionValueFileSpecLIst.cpp new file mode 100644 index 00000000000..3328dc6e1ca --- /dev/null +++ b/lldb/source/Interpreter/OptionValueFileSpecLIst.cpp @@ -0,0 +1,186 @@ +//===-- OptionValueFileSpecList.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/OptionValueFileSpecList.h" + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/Core/Stream.h" +#include "lldb/Interpreter/Args.h" + +using namespace lldb; +using namespace lldb_private; + +void +OptionValueFileSpecList::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask) +{ + if (dump_mask & eDumpOptionType) + strm.Printf ("(%s)", GetTypeAsCString ()); + if (dump_mask & eDumpOptionValue) + { + if (dump_mask & eDumpOptionType) + strm.Printf (" =%s", m_current_value.GetSize() > 0 ? "\n" : ""); + strm.IndentMore(); + const uint32_t size = m_current_value.GetSize(); + for (uint32_t i = 0; i<size; ++i) + { + strm.Indent(); + strm.Printf("[%u]: ", i); + m_current_value.GetFileSpecAtIndex(i).Dump(&strm); + } + strm.IndentLess(); + } +} + +Error +OptionValueFileSpecList::SetValueFromCString (const char *value, VarSetOperationType op) +{ + Error error; + Args args(value); + const size_t argc = args.GetArgumentCount(); + + switch (op) + { + case eVarSetOperationClear: + Clear (); + break; + + case eVarSetOperationReplace: + if (argc > 1) + { + uint32_t idx = Args::StringToUInt32(args.GetArgumentAtIndex(0), UINT32_MAX); + const uint32_t count = m_current_value.GetSize(); + if (idx > count) + { + error.SetErrorStringWithFormat("invalid file list index %u, index must be 0 through %u", idx, count); + } + else + { + for (size_t i=1; i<argc; ++i, ++idx) + { + FileSpec file (args.GetArgumentAtIndex(i), false); + if (idx < count) + m_current_value.Replace(idx, file); + else + m_current_value.Append(file); + } + } + } + else + { + error.SetErrorString("replace operation takes an array index followed by one or more values"); + } + break; + + + + case eVarSetOperationAssign: + m_current_value.Clear(); + // Fall through to append case + case eVarSetOperationAppend: + if (argc > 0) + { + m_value_was_set = true; + for (size_t i=0; i<argc; ++i) + { + FileSpec file (args.GetArgumentAtIndex(i), false); + m_current_value.Append(file); + } + } + else + { + error.SetErrorString("assign operation takes at least one file path argument"); + } + break; + + case eVarSetOperationInsertBefore: + case eVarSetOperationInsertAfter: + if (argc > 1) + { + uint32_t idx = Args::StringToUInt32(args.GetArgumentAtIndex(0), UINT32_MAX); + const uint32_t count = m_current_value.GetSize(); + if (idx > count) + { + error.SetErrorStringWithFormat("invalid insert file list index %u, index must be 0 through %u", idx, count); + } + else + { + if (op == eVarSetOperationInsertAfter) + ++idx; + for (size_t i=1; i<argc; ++i, ++idx) + { + FileSpec file (args.GetArgumentAtIndex(i), false); + m_current_value.Insert (idx, file); + } + } + } + else + { + error.SetErrorString("insert operation takes an array index followed by one or more values"); + } + break; + + case eVarSetOperationRemove: + if (argc > 0) + { + std::vector<int> remove_indexes; + bool all_indexes_valid = true; + size_t i; + for (i=0; all_indexes_valid && i<argc; ++i) + { + const int idx = Args::StringToSInt32(args.GetArgumentAtIndex(i), INT32_MAX); + if (idx == INT32_MAX) + all_indexes_valid = false; + else + remove_indexes.push_back(idx); + } + + if (all_indexes_valid) + { + size_t num_remove_indexes = remove_indexes.size(); + if (num_remove_indexes) + { + // Sort and then erase in reverse so indexes are always valid + std::sort(remove_indexes.begin(), remove_indexes.end()); + for (int i=num_remove_indexes-1; i<num_remove_indexes; ++i) + { + m_current_value.Remove (i); + } + } + } + else + { + error.SetErrorStringWithFormat("invalid array index '%s', aborting remove operation", args.GetArgumentAtIndex(i)); + } + } + else + { + error.SetErrorString("remove operation takes one or more array index"); + } + break; + + case eVarSetOperationInvalid: + error = OptionValue::SetValueFromCString (value, op); + break; + } + return error; + + m_value_was_set = true; + return Error(); +} + +lldb::OptionValueSP +OptionValueFileSpecList::DeepCopy () const +{ + return OptionValueSP(new OptionValueFileSpecList(*this)); +} + + diff --git a/lldb/source/Interpreter/OptionValueFormat.cpp b/lldb/source/Interpreter/OptionValueFormat.cpp new file mode 100644 index 00000000000..7d09fb1cc6b --- /dev/null +++ b/lldb/source/Interpreter/OptionValueFormat.cpp @@ -0,0 +1,76 @@ +//===-- OptionValueFormat.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/OptionValueFormat.h" + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/Core/FormatManager.h" +#include "lldb/Core/Stream.h" +#include "lldb/Interpreter/Args.h" + +using namespace lldb; +using namespace lldb_private; + +void +OptionValueFormat::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask) +{ + if (dump_mask & eDumpOptionType) + strm.Printf ("(%s)", GetTypeAsCString ()); + if (dump_mask & eDumpOptionValue) + { + if (dump_mask & eDumpOptionType) + strm.PutCString (" = "); + strm.PutCString (FormatManager::GetFormatAsCString (m_current_value)); + } +} + +Error +OptionValueFormat::SetValueFromCString (const char *value_cstr, VarSetOperationType op) +{ + Error error; + switch (op) + { + case eVarSetOperationClear: + Clear(); + break; + + case eVarSetOperationReplace: + case eVarSetOperationAssign: + { + Format new_format; + error = Args::StringToFormat (value_cstr, new_format, NULL); + if (error.Success()) + { + m_value_was_set = true; + m_current_value = new_format; + } + } + break; + + case eVarSetOperationInsertBefore: + case eVarSetOperationInsertAfter: + case eVarSetOperationRemove: + case eVarSetOperationAppend: + case eVarSetOperationInvalid: + error = OptionValue::SetValueFromCString (value_cstr, op); + break; + } + return error; +} + + +lldb::OptionValueSP +OptionValueFormat::DeepCopy () const +{ + return OptionValueSP(new OptionValueFormat(*this)); +} + diff --git a/lldb/source/Interpreter/OptionValuePathMappings.cpp b/lldb/source/Interpreter/OptionValuePathMappings.cpp new file mode 100644 index 00000000000..d507b146747 --- /dev/null +++ b/lldb/source/Interpreter/OptionValuePathMappings.cpp @@ -0,0 +1,185 @@ +//===-- OptionValuePathMappings.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/OptionValuePathMappings.h" + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/Core/Stream.h" +#include "lldb/Interpreter/Args.h" + +using namespace lldb; +using namespace lldb_private; + +void +OptionValuePathMappings::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask) +{ + if (dump_mask & eDumpOptionType) + strm.Printf ("(%s)", GetTypeAsCString ()); + if (dump_mask & eDumpOptionValue) + { + if (dump_mask & eDumpOptionType) + strm.Printf (" =%s", (m_path_mappings.GetSize() > 0) ? "\n" : ""); + m_path_mappings.Dump(&strm); + } +} + +Error +OptionValuePathMappings::SetValueFromCString (const char *value, VarSetOperationType op) +{ + Error error; + Args args(value); + const size_t argc = args.GetArgumentCount(); + + switch (op) + { + case eVarSetOperationClear: + Clear (); + break; + + case eVarSetOperationReplace: + // Must be at least one index + 1 pair of paths, and the pair count must be even + if (argc >= 3 && (((argc - 1) & 1) == 0)) + { + uint32_t idx = Args::StringToUInt32(args.GetArgumentAtIndex(0), UINT32_MAX); + const uint32_t count = m_path_mappings.GetSize(); + if (idx > count) + { + error.SetErrorStringWithFormat("invalid file list index %u, index must be 0 through %u", idx, count); + } + else + { + for (size_t i=1; i<argc; i += 2, ++idx) + { + ConstString a(args.GetArgumentAtIndex(i)); + ConstString b(args.GetArgumentAtIndex(i+1)); + if (!m_path_mappings.Replace (a, b, idx, m_notify_changes)) + m_path_mappings.Append(a, b, m_notify_changes); + } + } + } + else + { + error.SetErrorString("replace operation takes an array index followed by one or more path pairs"); + } + break; + + + + case eVarSetOperationAssign: + if (argc < 2 || (argc & 1)) + { + error.SetErrorString("assign operation takes one or more path pairs"); + break; + } + m_path_mappings.Clear(m_notify_changes); + // Fall through to append case + case eVarSetOperationAppend: + if (argc < 2 || (argc & 1)) + { + error.SetErrorString("append operation takes one or more path pairs"); + break; + } + else + { + for (size_t i=0; i<argc; i += 2) + { + ConstString a(args.GetArgumentAtIndex(i)); + ConstString b(args.GetArgumentAtIndex(i+1)); + m_path_mappings.Append(a, b, m_notify_changes); + m_value_was_set = true; + } + } + break; + + case eVarSetOperationInsertBefore: + case eVarSetOperationInsertAfter: + // Must be at least one index + 1 pair of paths, and the pair count must be even + if (argc >= 3 && (((argc - 1) & 1) == 0)) + { + uint32_t idx = Args::StringToUInt32(args.GetArgumentAtIndex(0), UINT32_MAX); + const uint32_t count = m_path_mappings.GetSize(); + if (idx > count) + { + error.SetErrorStringWithFormat("invalid file list index %u, index must be 0 through %u", idx, count); + } + else + { + if (op == eVarSetOperationInsertAfter) + ++idx; + for (size_t i=1; i<argc; i += 2, ++idx) + { + ConstString a(args.GetArgumentAtIndex(i)); + ConstString b(args.GetArgumentAtIndex(i+1)); + m_path_mappings.Insert (a, b, idx, m_notify_changes); + } + } + } + else + { + error.SetErrorString("insert operation takes an array index followed by one or more path pairs"); + } + break; + + case eVarSetOperationRemove: + if (argc > 0) + { + std::vector<int> remove_indexes; + bool all_indexes_valid = true; + size_t i; + for (i=0; all_indexes_valid && i<argc; ++i) + { + const int idx = Args::StringToSInt32(args.GetArgumentAtIndex(i), INT32_MAX); + if (idx == INT32_MAX) + all_indexes_valid = false; + else + remove_indexes.push_back(idx); + } + + if (all_indexes_valid) + { + size_t num_remove_indexes = remove_indexes.size(); + if (num_remove_indexes) + { + // Sort and then erase in reverse so indexes are always valid + std::sort(remove_indexes.begin(), remove_indexes.end()); + for (int i=num_remove_indexes-1; i<num_remove_indexes; ++i) + { + m_path_mappings.Remove (i, m_notify_changes); + } + } + } + else + { + error.SetErrorStringWithFormat("invalid array index '%s', aborting remove operation", args.GetArgumentAtIndex(i)); + } + } + else + { + error.SetErrorString("remove operation takes one or more array index"); + } + break; + + case eVarSetOperationInvalid: + error = OptionValue::SetValueFromCString (value, op); + break; + } + return error; + + m_value_was_set = true; + return Error(); +} + +lldb::OptionValueSP +OptionValuePathMappings::DeepCopy () const +{ + return OptionValueSP(new OptionValuePathMappings(*this)); +} diff --git a/lldb/source/Interpreter/OptionValueProperties.cpp b/lldb/source/Interpreter/OptionValueProperties.cpp new file mode 100644 index 00000000000..ce31c15678a --- /dev/null +++ b/lldb/source/Interpreter/OptionValueProperties.cpp @@ -0,0 +1,719 @@ +//===-- OptionValueProperties.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/OptionValueProperties.h" + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/Core/Flags.h" +#include "lldb/Core/Stream.h" +#include "lldb/Core/StringList.h" +#include "lldb/Core/UserSettingsController.h" +#include "lldb/Interpreter/Args.h" +#include "lldb/Interpreter/OptionValues.h" +#include "lldb/Interpreter/Property.h" + +using namespace lldb; +using namespace lldb_private; + + +OptionValueProperties::OptionValueProperties (const ConstString &name) : + m_name (name) +{ +} + +OptionValueProperties::OptionValueProperties (const OptionValueProperties &global_properties) : + m_name (global_properties.m_name), + m_properties (global_properties.m_properties), + m_name_to_index (global_properties.m_name_to_index) +{ + // We now have an exact copy of "global_properties". We need to now + // find all non-global settings and copy the property values so that + // all non-global settings get new OptionValue instances created for + // them. + const size_t num_properties = m_properties.size(); + for (size_t i=0; i<num_properties; ++i) + { + // Duplicate any values that are not global when contructing properties from + // a global copy + if (m_properties[i].IsGlobal() == false) + { + lldb::OptionValueSP new_value_sp (m_properties[i].GetValue()->DeepCopy()); + m_properties[i].SetOptionValue(new_value_sp); + } + } +} + + + +size_t +OptionValueProperties::GetNumProperties() const +{ + return m_properties.size(); +} + + +void +OptionValueProperties::Initialize (const PropertyDefinition *defs) +{ + for (size_t i=0; defs[i].name; ++i) + { + Property property(defs[i]); + assert(property.IsValid()); + m_name_to_index.Append(property.GetName().GetCString(),m_properties.size()); + property.GetValue()->SetParent(shared_from_this()); + m_properties.push_back(property); + } + m_name_to_index.Sort(); +} + +void +OptionValueProperties::AppendProperty(const ConstString &name, + const ConstString &desc, + bool is_global, + const OptionValueSP &value_sp) +{ + Property property(name, desc, is_global, value_sp); + m_name_to_index.Append(name.GetCString(),m_properties.size()); + m_properties.push_back(property); + value_sp->SetParent (shared_from_this()); + m_name_to_index.Sort(); +} + + + +//bool +//OptionValueProperties::GetQualifiedName (Stream &strm) +//{ +// bool dumped_something = false; +//// lldb::OptionValuePropertiesSP parent_sp(GetParent ()); +//// if (parent_sp) +//// { +//// parent_sp->GetQualifiedName (strm); +//// strm.PutChar('.'); +//// dumped_something = true; +//// } +// if (m_name) +// { +// strm << m_name; +// dumped_something = true; +// } +// return dumped_something; +//} +// +lldb::OptionValueSP +OptionValueProperties::GetValueForKey (const ExecutionContext *exe_ctx, + const ConstString &key, + bool will_modify) const +{ + lldb::OptionValueSP value_sp; + size_t idx = m_name_to_index.Find (key.GetCString(), SIZE_MAX); + if (idx < m_properties.size()) + value_sp = GetPropertyAtIndex(exe_ctx, will_modify, idx)->GetValue(); + return value_sp; +} + +lldb::OptionValueSP +OptionValueProperties::GetSubValue (const ExecutionContext *exe_ctx, + const char *name, + bool will_modify, + Error &error) const +{ + lldb::OptionValueSP value_sp; + + if (name && name[0]) + { + const char *sub_name = NULL; + ConstString key; + size_t key_len = ::strcspn (name, ".[{"); + + if (name[key_len]) + { + key.SetCStringWithLength (name, key_len); + sub_name = name + key_len; + } + else + key.SetCString (name); + + value_sp = GetValueForKey (exe_ctx, key, will_modify); + if (sub_name && value_sp) + { + switch (sub_name[0]) + { + case '.': + return value_sp->GetSubValue (exe_ctx, sub_name + 1, will_modify, error); + + case '{': + // Predicate matching for predicates like + // "<setting-name>{<predicate>}" + // strings are parsed by the current OptionValueProperties subclass + // to mean whatever they want to. For instance a subclass of + // OptionValueProperties for a lldb_private::Target might implement: + // "target.run-args{arch==i386}" -- only set run args if the arch is i386 + // "target.run-args{path=/tmp/a/b/c/a.out}" -- only set run args if the path matches + // "target.run-args{basename==test&&arch==x86_64}" -- only set run args if exectable basename is "test" and arch is "x86_64" + if (sub_name[1]) + { + const char *predicate_start = sub_name + 1; + const char *predicate_end = strchr(predicate_start, '}'); + if (predicate_end) + { + std::string predicate(predicate_start, predicate_end); + if (PredicateMatches(exe_ctx, predicate.c_str())) + { + if (predicate_end[1]) + { + // Still more subvalue string to evaluate + return value_sp->GetSubValue (exe_ctx, predicate_end + 1, will_modify, error); + } + else + { + // We have a match! + break; + } + } + } + } + // Predicate didn't match or wasn't correctly formed + value_sp.reset(); + break; + + case '[': + // Array or dictionary access for subvalues like: + // "[12]" -- access 12th array element + // "['hello']" -- dictionary access of key named hello + return value_sp->GetSubValue (exe_ctx, sub_name, will_modify, error); + + default: + value_sp.reset(); + break; + } + } + } + return value_sp; +} + +Error +OptionValueProperties::SetSubValue (const ExecutionContext *exe_ctx, + VarSetOperationType op, + const char *name, + const char *value) +{ + Error error; + const bool will_modify = true; + lldb::OptionValueSP value_sp (GetSubValue (exe_ctx, name, will_modify, error)); + if (value_sp) + error = value_sp->SetValueFromCString(value, op); + else + { + if (error.AsCString() == NULL) + error.SetErrorStringWithFormat("invalid value path '%s'", name); + } + return error; +} + + +ConstString +OptionValueProperties::GetPropertyNameAtIndex (uint32_t idx) const +{ + const Property *property = GetPropertyAtIndex(NULL, false, idx); + if (property) + return property->GetName(); + return ConstString(); + +} + +const char * +OptionValueProperties::GetPropertyDescriptionAtIndex (uint32_t idx) const +{ + const Property *property = GetPropertyAtIndex(NULL, false, idx); + if (property) + return property->GetDescription(); + return NULL; +} + +uint32_t +OptionValueProperties::GetPropertyIndex (const ConstString &name) const +{ + return m_name_to_index.Find (name.GetCString(), SIZE_MAX); +} + +const Property * +OptionValueProperties::GetProperty (const ExecutionContext *exe_ctx, bool will_modify, const ConstString &name) const +{ + return GetPropertyAtIndex (exe_ctx, will_modify, m_name_to_index.Find (name.GetCString(), SIZE_MAX)); +} + +const Property * +OptionValueProperties::GetPropertyAtIndex (const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const +{ + return ProtectedGetPropertyAtIndex (idx); +} + +lldb::OptionValueSP +OptionValueProperties::GetPropertyValueAtIndex (const ExecutionContext *exe_ctx, + bool will_modify, + uint32_t idx) const +{ + const Property *setting = GetPropertyAtIndex (exe_ctx, will_modify, idx); + if (setting) + return setting->GetValue(); + return OptionValueSP(); +} + +OptionValuePathMappings * +OptionValueProperties::GetPropertyAtIndexAsOptionValuePathMappings (const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const +{ + OptionValueSP value_sp(GetPropertyValueAtIndex (exe_ctx, will_modify, idx)); + if (value_sp) + return value_sp->GetAsPathMappings(); + return NULL; +} + +OptionValueFileSpecList * +OptionValueProperties::GetPropertyAtIndexAsOptionValueFileSpecList (const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const +{ + OptionValueSP value_sp(GetPropertyValueAtIndex (exe_ctx, will_modify, idx)); + if (value_sp) + return value_sp->GetAsFileSpecList(); + return NULL; +} + +OptionValueArch * +OptionValueProperties::GetPropertyAtIndexAsOptionValueArch (const ExecutionContext *exe_ctx, uint32_t idx) const +{ + const Property *property = GetPropertyAtIndex (exe_ctx, false, idx); + if (property) + return property->GetValue()->GetAsArch(); + return NULL; +} + +bool +OptionValueProperties::GetPropertyAtIndexAsArgs (const ExecutionContext *exe_ctx, uint32_t idx, Args &args) const +{ + const Property *property = GetPropertyAtIndex (exe_ctx, false, idx); + if (property) + { + OptionValue *value = property->GetValue().get(); + if (value) + { + const OptionValueArray *array = value->GetAsArray(); + if (array) + return array->GetArgs(args); + else + { + const OptionValueDictionary *dict = value->GetAsDictionary(); + if (dict) + return dict->GetArgs(args); + } + } + } + return false; +} + +bool +OptionValueProperties::SetPropertyAtIndexFromArgs (const ExecutionContext *exe_ctx, uint32_t idx, const Args &args) +{ + const Property *property = GetPropertyAtIndex (exe_ctx, true, idx); + if (property) + { + OptionValue *value = property->GetValue().get(); + if (value) + { + OptionValueArray *array = value->GetAsArray(); + if (array) + return array->SetArgs(args, eVarSetOperationAssign).Success(); + else + { + OptionValueDictionary *dict = value->GetAsDictionary(); + if (dict) + return dict->SetArgs(args, eVarSetOperationAssign).Success(); + } + } + } + return false; +} + +bool +OptionValueProperties::GetPropertyAtIndexAsBoolean (const ExecutionContext *exe_ctx, uint32_t idx, bool fail_value) const +{ + const Property *property = GetPropertyAtIndex (exe_ctx, false, idx); + if (property) + { + OptionValue *value = property->GetValue().get(); + if (value) + return value->GetBooleanValue(fail_value); + } + return fail_value; +} + +bool +OptionValueProperties::SetPropertyAtIndexAsBoolean (const ExecutionContext *exe_ctx, uint32_t idx, bool new_value) +{ + const Property *property = GetPropertyAtIndex (exe_ctx, true, idx); + if (property) + { + OptionValue *value = property->GetValue().get(); + if (value) + { + value->SetBooleanValue(new_value); + return true; + } + } + return false; +} + +OptionValueDictionary * +OptionValueProperties::GetPropertyAtIndexAsOptionValueDictionary (const ExecutionContext *exe_ctx, uint32_t idx) const +{ + const Property *property = GetPropertyAtIndex (exe_ctx, false, idx); + if (property) + return property->GetValue()->GetAsDictionary(); + return NULL; +} + +int64_t +OptionValueProperties::GetPropertyAtIndexAsEnumeration (const ExecutionContext *exe_ctx, uint32_t idx, int64_t fail_value) const +{ + const Property *property = GetPropertyAtIndex (exe_ctx, false, idx); + if (property) + { + OptionValue *value = property->GetValue().get(); + if (value) + return value->GetEnumerationValue(fail_value); + } + return fail_value; +} + +bool +OptionValueProperties::SetPropertyAtIndexAsEnumeration (const ExecutionContext *exe_ctx, uint32_t idx, int64_t new_value) +{ + const Property *property = GetPropertyAtIndex (exe_ctx, true, idx); + if (property) + { + OptionValue *value = property->GetValue().get(); + if (value) + return value->SetEnumerationValue(new_value); + } + return false; +} + + +FileSpec +OptionValueProperties::GetPropertyAtIndexAsFileSpec (const ExecutionContext *exe_ctx, uint32_t idx) const +{ + const Property *property = GetPropertyAtIndex (exe_ctx, false, idx); + if (property) + { + OptionValue *value = property->GetValue().get(); + if (value) + return value->GetFileSpecValue(); + } + return FileSpec(); +} + + +bool +OptionValueProperties::SetPropertyAtIndexAsFileSpec (const ExecutionContext *exe_ctx, uint32_t idx, const FileSpec &new_file_spec) +{ + const Property *property = GetPropertyAtIndex (exe_ctx, true, idx); + if (property) + { + OptionValue *value = property->GetValue().get(); + if (value) + return value->SetFileSpecValue(new_file_spec); + } + return false; +} + +const RegularExpression * +OptionValueProperties::GetPropertyAtIndexAsOptionValueRegex (const ExecutionContext *exe_ctx, uint32_t idx) const +{ + const Property *property = GetPropertyAtIndex (exe_ctx, false, idx); + if (property) + { + OptionValue *value = property->GetValue().get(); + if (value) + return value->GetRegexValue(); + } + return NULL; +} + +OptionValueSInt64 * +OptionValueProperties::GetPropertyAtIndexAsOptionValueSInt64 (const ExecutionContext *exe_ctx, uint32_t idx) const +{ + const Property *property = GetPropertyAtIndex (exe_ctx, false, idx); + if (property) + { + OptionValue *value = property->GetValue().get(); + if (value) + return value->GetAsSInt64(); + } + return NULL; +} + +int64_t +OptionValueProperties::GetPropertyAtIndexAsSInt64 (const ExecutionContext *exe_ctx, uint32_t idx, int64_t fail_value) const +{ + const Property *property = GetPropertyAtIndex (exe_ctx, false, idx); + if (property) + { + OptionValue *value = property->GetValue().get(); + if (value) + return value->GetSInt64Value(fail_value); + } + return fail_value; +} + +bool +OptionValueProperties::SetPropertyAtIndexAsSInt64 (const ExecutionContext *exe_ctx, uint32_t idx, int64_t new_value) +{ + const Property *property = GetPropertyAtIndex (exe_ctx, true, idx); + if (property) + { + OptionValue *value = property->GetValue().get(); + if (value) + return value->SetSInt64Value(new_value); + } + return false; +} + +const char * +OptionValueProperties::GetPropertyAtIndexAsString (const ExecutionContext *exe_ctx, uint32_t idx, const char *fail_value) const +{ + const Property *property = GetPropertyAtIndex (exe_ctx, false, idx); + if (property) + { + OptionValue *value = property->GetValue().get(); + if (value) + return value->GetStringValue(fail_value); + } + return fail_value; +} + +bool +OptionValueProperties::SetPropertyAtIndexAsString (const ExecutionContext *exe_ctx, uint32_t idx, const char *new_value) +{ + const Property *property = GetPropertyAtIndex (exe_ctx, true, idx); + if (property) + { + OptionValue *value = property->GetValue().get(); + if (value) + return value->SetStringValue(new_value); + } + return false; +} + +uint64_t +OptionValueProperties::GetPropertyAtIndexAsUInt64 (const ExecutionContext *exe_ctx, uint32_t idx, uint64_t fail_value) const +{ + const Property *property = GetPropertyAtIndex (exe_ctx, false, idx); + if (property) + { + OptionValue *value = property->GetValue().get(); + if (value) + return value->GetUInt64Value(fail_value); + } + return fail_value; +} + +bool +OptionValueProperties::SetPropertyAtIndexAsUInt64 (const ExecutionContext *exe_ctx, uint32_t idx, uint64_t new_value) +{ + const Property *property = GetPropertyAtIndex (exe_ctx, true, idx); + if (property) + { + OptionValue *value = property->GetValue().get(); + if (value) + return value->SetUInt64Value(new_value); + } + return false; +} + +bool +OptionValueProperties::Clear () +{ + const size_t num_properties = m_properties.size(); + for (size_t i=0; i<num_properties; ++i) + m_properties[i].GetValue()->Clear(); + return true; +} + + +Error +OptionValueProperties::SetValueFromCString (const char *value, VarSetOperationType op) +{ + Error error; + +// Args args(value_cstr); +// const size_t argc = args.GetArgumentCount(); + switch (op) + { + case eVarSetOperationClear: + Clear (); + break; + + case eVarSetOperationReplace: + case eVarSetOperationAssign: + case eVarSetOperationRemove: + case eVarSetOperationInsertBefore: + case eVarSetOperationInsertAfter: + case eVarSetOperationAppend: + case eVarSetOperationInvalid: + error = OptionValue::SetValueFromCString (value, op); + break; + } + + return error; +} + +void +OptionValueProperties::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask) +{ + const size_t num_properties = m_properties.size(); + for (size_t i=0; i<num_properties; ++i) + { + const Property *property = GetPropertyAtIndex(exe_ctx, false, i); + if (property) + { + OptionValue *option_value = property->GetValue().get(); + assert (option_value); + const bool transparent_value = option_value->ValueIsTransparent (); + property->Dump (exe_ctx, + strm, + dump_mask); + if (!transparent_value) + strm.EOL(); + } + } +} + +Error +OptionValueProperties::DumpPropertyValue (const ExecutionContext *exe_ctx, + Stream &strm, + const char *property_path, + uint32_t dump_mask) +{ + Error error; + const bool will_modify = false; + lldb::OptionValueSP value_sp (GetSubValue (exe_ctx, property_path, will_modify, error)); + if (value_sp) + { + if (!value_sp->ValueIsTransparent ()) + { + if (dump_mask & eDumpOptionName) + strm.PutCString (property_path); + if (dump_mask & ~eDumpOptionName) + strm.PutChar (' '); + } + value_sp->DumpValue (exe_ctx, strm, dump_mask); + } + return error; +} + +lldb::OptionValueSP +OptionValueProperties::DeepCopy () const +{ + assert(!"this shouldn't happen"); +} + +const Property * +OptionValueProperties::GetPropertyAtPath (const ExecutionContext *exe_ctx, + bool will_modify, + const char *name) const +{ + const Property *property = NULL; + if (name && name[0]) + { + const char *sub_name = NULL; + ConstString key; + size_t key_len = ::strcspn (name, ".[{"); + + if (name[key_len]) + { + key.SetCStringWithLength (name, key_len); + sub_name = name + key_len; + } + else + key.SetCString (name); + + property = GetProperty (exe_ctx, will_modify, key); + if (sub_name && property) + { + if (sub_name[0] == '.') + { + OptionValueProperties *sub_properties = property->GetValue()->GetAsProperties(); + if (sub_properties) + return sub_properties->GetPropertyAtPath(exe_ctx, will_modify, sub_name + 1); + } + property = NULL; + } + } + return property; +} + +void +OptionValueProperties::DumpAllDescriptions (CommandInterpreter &interpreter, + Stream &strm) const +{ + size_t max_name_len = 0; + const size_t num_properties = m_properties.size(); + for (size_t i=0; i<num_properties; ++i) + { + const Property *property = ProtectedGetPropertyAtIndex(i); + if (property) + max_name_len = std::max<size_t>(property->GetName().GetLength(), max_name_len); + } + for (size_t i=0; i<num_properties; ++i) + { + const Property *property = ProtectedGetPropertyAtIndex(i); + if (property) + property->DumpDescription (interpreter, strm, max_name_len, false); + } +} + +void +OptionValueProperties::Apropos (const char *keyword, std::vector<const Property *> &matching_properties) const +{ + const size_t num_properties = m_properties.size(); + StreamString strm; + for (size_t i=0; i<num_properties; ++i) + { + const Property *property = ProtectedGetPropertyAtIndex(i); + if (property) + { + const OptionValueProperties *properties = property->GetValue()->GetAsProperties(); + if (properties) + { + properties->Apropos (keyword, matching_properties); + } + else + { + bool match = false; + const char *name = property->GetName().GetCString(); + if (name && ::strcasestr(name, keyword)) + match = true; + else + { + const char *desc = property->GetDescription(); + if (desc && ::strcasestr(desc, keyword)) + match = true; + } + if (match) + { + matching_properties.push_back (property); + } + } + } + } +} + + diff --git a/lldb/source/Interpreter/OptionValueRegex.cpp b/lldb/source/Interpreter/OptionValueRegex.cpp new file mode 100644 index 00000000000..f1ba0ed04d6 --- /dev/null +++ b/lldb/source/Interpreter/OptionValueRegex.cpp @@ -0,0 +1,86 @@ +//===-- OptionValueRegex.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/OptionValueRegex.h" + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/Core/Stream.h" + +using namespace lldb; +using namespace lldb_private; + +void +OptionValueRegex::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask) +{ + if (dump_mask & eDumpOptionType) + strm.Printf ("(%s)", GetTypeAsCString ()); + if (dump_mask & eDumpOptionValue) + { + if (dump_mask & eDumpOptionType) + strm.PutCString (" = "); + if (m_regex.IsValid()) + { + const char *regex_text = m_regex.GetText(); + if (regex_text && regex_text[0]) + strm.Printf ("%s", regex_text); + } + else + { + + } + } +} + +Error +OptionValueRegex::SetValueFromCString (const char *value_cstr, + VarSetOperationType op) +{ + Error error; + switch (op) + { + case eVarSetOperationInvalid: + case eVarSetOperationInsertBefore: + case eVarSetOperationInsertAfter: + case eVarSetOperationRemove: + case eVarSetOperationAppend: + error = OptionValue::SetValueFromCString (value_cstr, op); + break; + + case eVarSetOperationClear: + Clear(); + break; + + case eVarSetOperationReplace: + case eVarSetOperationAssign: + if (m_regex.Compile (value_cstr, m_regex.GetCompileFlags())) + { + m_value_was_set = true; + } + else + { + char regex_error[1024]; + if (m_regex.GetErrorAsCString(regex_error, sizeof(regex_error))) + error.SetErrorString (regex_error); + else + error.SetErrorStringWithFormat ("regex error %u", m_regex.GetErrorCode()); + } + break; + } + return error; +} + + +lldb::OptionValueSP +OptionValueRegex::DeepCopy () const +{ + return OptionValueSP(new OptionValueRegex(m_regex.GetText(), m_regex.GetCompileFlags())); +} diff --git a/lldb/source/Interpreter/OptionValueSInt64.cpp b/lldb/source/Interpreter/OptionValueSInt64.cpp new file mode 100644 index 00000000000..9d7f4cc58af --- /dev/null +++ b/lldb/source/Interpreter/OptionValueSInt64.cpp @@ -0,0 +1,89 @@ +//===-- OptionValueSInt64.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/OptionValueSInt64.h" + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/Core/Stream.h" +#include "lldb/Interpreter/Args.h" + +using namespace lldb; +using namespace lldb_private; + +void +OptionValueSInt64::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask) +{ + //printf ("%p: DumpValue (exe_ctx=%p, strm, mask) m_current_value = %lli\n", this, exe_ctx, m_current_value); + if (dump_mask & eDumpOptionType) + strm.Printf ("(%s)", GetTypeAsCString ()); +// if (dump_mask & eDumpOptionName) +// DumpQualifiedName (strm); + if (dump_mask & eDumpOptionValue) + { + if (dump_mask & eDumpOptionType) + strm.PutCString (" = "); + strm.Printf ("%lli", m_current_value); + } +} + +Error +OptionValueSInt64::SetValueFromCString (const char *value_cstr, VarSetOperationType op) +{ + //printf ("%p: SetValueFromCString (s=\"%s\", op=%i)\n", this, value_cstr, op); + Error error; + switch (op) + { + case eVarSetOperationClear: + Clear(); + break; + + case eVarSetOperationReplace: + case eVarSetOperationAssign: + { + bool success = false; + int64_t value = Args::StringToSInt64 (value_cstr, 0, 0, &success); + if (success) + { + if (value >= m_min_value && value <= m_max_value) + { + m_value_was_set = true; + m_current_value = value; + } + else + error.SetErrorStringWithFormat ("%lli is out of range, valid values must be between %lli and %lli.", + value, + m_min_value, + m_max_value); + } + else + { + error.SetErrorStringWithFormat ("invalid int64_t string value: '%s'", value_cstr); + } + } + break; + + case eVarSetOperationInsertBefore: + case eVarSetOperationInsertAfter: + case eVarSetOperationRemove: + case eVarSetOperationAppend: + case eVarSetOperationInvalid: + error = OptionValue::SetValueFromCString (value_cstr, op); + break; + } + return error; +} + +lldb::OptionValueSP +OptionValueSInt64::DeepCopy () const +{ + return OptionValueSP(new OptionValueSInt64(*this)); +} diff --git a/lldb/source/Interpreter/OptionValueString.cpp b/lldb/source/Interpreter/OptionValueString.cpp new file mode 100644 index 00000000000..35ab8c8f7ce --- /dev/null +++ b/lldb/source/Interpreter/OptionValueString.cpp @@ -0,0 +1,77 @@ +//===-- OptionValueString.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/OptionValueString.h" + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/Core/Stream.h" + +using namespace lldb; +using namespace lldb_private; + +void +OptionValueString::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask) +{ + if (dump_mask & eDumpOptionType) + strm.Printf ("(%s)", GetTypeAsCString ()); + if (dump_mask & eDumpOptionValue) + { + if (dump_mask & eDumpOptionType) + strm.PutCString (" = "); + if (!m_current_value.empty() || m_value_was_set) + { + if (dump_mask & eDumpOptionRaw) + strm.Printf ("%s", m_current_value.c_str()); + else + strm.Printf ("\"%s\"", m_current_value.c_str()); + } + } +} + +Error +OptionValueString::SetValueFromCString (const char *value_cstr, + VarSetOperationType op) +{ + Error error; + switch (op) + { + case eVarSetOperationInvalid: + case eVarSetOperationInsertBefore: + case eVarSetOperationInsertAfter: + case eVarSetOperationRemove: + error = OptionValue::SetValueFromCString (value_cstr, op); + break; + + case eVarSetOperationAppend: + if (value_cstr && value_cstr[0]) + m_current_value += value_cstr; + break; + + case eVarSetOperationClear: + Clear (); + break; + + case eVarSetOperationReplace: + case eVarSetOperationAssign: + m_value_was_set = true; + SetCurrentValue (value_cstr); + break; + } + return error; +} + + +lldb::OptionValueSP +OptionValueString::DeepCopy () const +{ + return OptionValueSP(new OptionValueString(*this)); +} diff --git a/lldb/source/Interpreter/OptionValueUInt64.cpp b/lldb/source/Interpreter/OptionValueUInt64.cpp new file mode 100644 index 00000000000..59f1e5f4189 --- /dev/null +++ b/lldb/source/Interpreter/OptionValueUInt64.cpp @@ -0,0 +1,89 @@ +//===-- OptionValueUInt64.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/OptionValueUInt64.h" + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/Core/Stream.h" +#include "lldb/Interpreter/Args.h" + +using namespace lldb; +using namespace lldb_private; + +lldb::OptionValueSP +OptionValueUInt64::Create (const char *value_cstr, Error &error) +{ + lldb::OptionValueSP value_sp (new OptionValueUInt64()); + error = value_sp->SetValueFromCString (value_cstr); + if (error.Fail()) + value_sp.reset(); + return value_sp; +} + + +void +OptionValueUInt64::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask) +{ + if (dump_mask & eDumpOptionType) + strm.Printf ("(%s)", GetTypeAsCString ()); + if (dump_mask & eDumpOptionValue) + { + if (dump_mask & eDumpOptionType) + strm.PutCString (" = "); + strm.Printf ("%llu", m_current_value); + } +} + +Error +OptionValueUInt64::SetValueFromCString (const char *value_cstr, VarSetOperationType op) +{ + Error error; + switch (op) + { + case eVarSetOperationClear: + Clear (); + break; + + case eVarSetOperationReplace: + case eVarSetOperationAssign: + { + bool success = false; + uint64_t value = Args::StringToUInt64 (value_cstr, 0, 0, &success); + if (success) + { + m_value_was_set = true; + m_current_value = value; + } + else + { + error.SetErrorStringWithFormat ("invalid uint64_t string value: '%s'", value_cstr); + } + } + break; + + case eVarSetOperationInsertBefore: + case eVarSetOperationInsertAfter: + case eVarSetOperationRemove: + case eVarSetOperationAppend: + case eVarSetOperationInvalid: + error = OptionValue::SetValueFromCString (value_cstr, op); + break; + } + return error; +} + +lldb::OptionValueSP +OptionValueUInt64::DeepCopy () const +{ + return OptionValueSP(new OptionValueUInt64(*this)); +} + diff --git a/lldb/source/Interpreter/OptionValueUUID.cpp b/lldb/source/Interpreter/OptionValueUUID.cpp new file mode 100644 index 00000000000..03a5684b1d0 --- /dev/null +++ b/lldb/source/Interpreter/OptionValueUUID.cpp @@ -0,0 +1,70 @@ +//===-- OptionValueUUID.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/OptionValueUUID.h" + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/Core/Stream.h" + +using namespace lldb; +using namespace lldb_private; + +void +OptionValueUUID::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask) +{ + if (dump_mask & eDumpOptionType) + strm.Printf ("(%s)", GetTypeAsCString ()); + if (dump_mask & eDumpOptionValue) + { + if (dump_mask & eDumpOptionType) + strm.PutCString (" = "); + m_uuid.Dump (&strm); + } +} + +Error +OptionValueUUID::SetValueFromCString (const char *value_cstr, + VarSetOperationType op) +{ + Error error; + switch (op) + { + case eVarSetOperationClear: + Clear(); + break; + + case eVarSetOperationReplace: + case eVarSetOperationAssign: + { + if (m_uuid.SetfromCString(value_cstr) == 0) + error.SetErrorStringWithFormat ("invalid uuid string value '%s'", value_cstr); + else + m_value_was_set = true; + } + break; + + case eVarSetOperationInsertBefore: + case eVarSetOperationInsertAfter: + case eVarSetOperationRemove: + case eVarSetOperationAppend: + case eVarSetOperationInvalid: + error = OptionValue::SetValueFromCString (value_cstr, op); + break; + } + return error; +} + +lldb::OptionValueSP +OptionValueUUID::DeepCopy () const +{ + return OptionValueSP(new OptionValueUUID(*this)); +} diff --git a/lldb/source/Interpreter/Property.cpp b/lldb/source/Interpreter/Property.cpp new file mode 100644 index 00000000000..7e7dc010997 --- /dev/null +++ b/lldb/source/Interpreter/Property.cpp @@ -0,0 +1,268 @@ +//===-- Property.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/Property.h" + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/Core/UserSettingsController.h" +#include "lldb/Interpreter/Args.h" +#include "lldb/Interpreter/CommandInterpreter.h" +#include "lldb/Interpreter/OptionValues.h" + +using namespace lldb; +using namespace lldb_private; + +Property::Property (const PropertyDefinition &definition) : + m_name (definition.name), + m_description (definition.description), + m_value_sp (), + m_is_global (definition.global) +{ + switch (definition.type) + { + case OptionValue::eTypeInvalid: + case OptionValue::eTypeProperties: + break; + case OptionValue::eTypeArch: + // "definition.default_uint_value" is not used + // "definition.default_cstr_value" as a string value that represents the default string value for the architecture/triple + m_value_sp.reset (new OptionValueArch(definition.default_cstr_value)); + break; + + case OptionValue::eTypeArgs: + // "definition.default_uint_value" is always a OptionValue::Type + m_value_sp.reset (new OptionValueArgs()); + break; + + case OptionValue::eTypeArray: + // "definition.default_uint_value" is always a OptionValue::Type + m_value_sp.reset (new OptionValueArray(OptionValue::ConvertTypeToMask((OptionValue::Type)definition.default_uint_value))); + break; + + case OptionValue::eTypeBoolean: + // "definition.default_uint_value" is the default boolean value if + // "definition.default_cstr_value" is NULL, otherwise interpret + // "definition.default_cstr_value" as a string value that represents the default + // value. + if (definition.default_cstr_value) + m_value_sp.reset (new OptionValueBoolean(Args::StringToBoolean (definition.default_cstr_value, false, NULL))); + else + m_value_sp.reset (new OptionValueBoolean(definition.default_uint_value != 0)); + break; + + case OptionValue::eTypeDictionary: + // "definition.default_uint_value" is always a OptionValue::Type + m_value_sp.reset (new OptionValueDictionary(OptionValue::ConvertTypeToMask((OptionValue::Type)definition.default_uint_value))); + break; + + case OptionValue::eTypeEnum: + // "definition.default_uint_value" is the default enumeration value if + // "definition.default_cstr_value" is NULL, otherwise interpret + // "definition.default_cstr_value" as a string value that represents the default + // value. + { + OptionValueEnumeration *enum_value = new OptionValueEnumeration(definition.enum_values, definition.default_uint_value); + m_value_sp.reset (enum_value); + if (definition.default_cstr_value) + { + if (enum_value->SetValueFromCString(definition.default_cstr_value).Success()) + { + enum_value->SetDefaultValue(enum_value->GetCurrentValue()); + // Call Clear() since we don't want the value to appear as + // having been set since we called SetValueFromCString() above. + // Clear will set the current value to the default and clear + // the boolean that says that the value has been set. + enum_value->Clear(); + } + } + } + break; + + case OptionValue::eTypeFileSpec: + // "definition.default_uint_value" represents if the "definition.default_cstr_value" should + // be resolved or not + m_value_sp.reset (new OptionValueFileSpec(FileSpec(definition.default_cstr_value, definition.default_uint_value != 0))); + break; + + case OptionValue::eTypeFileSpecList: + // "definition.default_uint_value" is not used for a OptionValue::eTypeFileSpecList + m_value_sp.reset (new OptionValueFileSpecList()); + break; + + case OptionValue::eTypeFormat: + // "definition.default_uint_value" is the default format enumeration value if + // "definition.default_cstr_value" is NULL, otherwise interpret + // "definition.default_cstr_value" as a string value that represents the default + // value. + { + Format new_format = eFormatInvalid; + if (definition.default_cstr_value) + Args::StringToFormat (definition.default_cstr_value, new_format, NULL); + else + new_format = (Format)definition.default_uint_value; + m_value_sp.reset (new OptionValueFormat(new_format)); + } + break; + + case OptionValue::eTypePathMap: + // "definition.default_uint_value" tells us if notifications should occur for + // path mappings + m_value_sp.reset (new OptionValuePathMappings(definition.default_uint_value != 0)); + break; + + case OptionValue::eTypeRegex: + // "definition.default_uint_value" is used to the regular expression flags + // "definition.default_cstr_value" the default regular expression value + // value. + m_value_sp.reset (new OptionValueRegex(definition.default_cstr_value, definition.default_uint_value)); + break; + + case OptionValue::eTypeSInt64: + // "definition.default_uint_value" is the default integer value if + // "definition.default_cstr_value" is NULL, otherwise interpret + // "definition.default_cstr_value" as a string value that represents the default + // value. + m_value_sp.reset (new OptionValueSInt64(definition.default_cstr_value ? Args::StringToSInt64 (definition.default_cstr_value) : definition.default_uint_value)); + break; + + case OptionValue::eTypeUInt64: + // "definition.default_uint_value" is the default unsigned integer value if + // "definition.default_cstr_value" is NULL, otherwise interpret + // "definition.default_cstr_value" as a string value that represents the default + // value. + m_value_sp.reset (new OptionValueUInt64(definition.default_cstr_value ? Args::StringToUInt64 (definition.default_cstr_value) : definition.default_uint_value)); + break; + + case OptionValue::eTypeUUID: + // "definition.default_uint_value" is not used for a OptionValue::eTypeUUID + // "definition.default_cstr_value" can contain a default UUID value + { + UUID uuid; + if (definition.default_cstr_value) + uuid.SetfromCString (definition.default_cstr_value); + m_value_sp.reset (new OptionValueUUID(uuid)); + } + break; + + case OptionValue::eTypeString: + // "definition.default_uint_value" is not used for a OptionValueFileSpecList + // "definition.default_cstr_value" can contain a default string value + m_value_sp.reset (new OptionValueString(definition.default_cstr_value)); + break; + } +} + +Property::Property (const ConstString &name, + const ConstString &desc, + bool is_global, + const lldb::OptionValueSP &value_sp) : + m_name (name), + m_description (desc), + m_value_sp (value_sp), + m_is_global (is_global) +{ +} + +bool +Property::DumpQualifiedName(Stream &strm) const +{ + if (m_name) + { + if (m_value_sp->DumpQualifiedName(strm)) + strm.PutChar('.'); + strm << m_name; + return true; + } + return false; +} + + +void +Property::Dump (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask) const +{ + if (m_value_sp) + { + const bool dump_desc = dump_mask & OptionValue::eDumpOptionDescription; + const bool transparent = m_value_sp->ValueIsTransparent (); + if (dump_desc || !transparent) + { + if ((dump_mask & OptionValue::eDumpOptionName) && m_name) + { + DumpQualifiedName(strm); + if (dump_mask & ~OptionValue::eDumpOptionName) + strm.PutChar(' '); + } + } + if (dump_desc) + { + const char *desc = GetDescription(); + if (desc) + strm.Printf ("-- %s", desc); + + if (transparent && (dump_mask == (OptionValue::eDumpOptionName | OptionValue::eDumpOptionDescription))) + strm.EOL(); + } + m_value_sp->DumpValue(exe_ctx, strm, dump_mask); + } +} + + +void +Property::DumpDescription (CommandInterpreter &interpreter, + Stream &strm, + uint32_t output_width, + bool display_qualified_name) const +{ + if (m_value_sp) + { + const char *desc = GetDescription(); + + if (desc) + { + StreamString qualified_name; + const OptionValueProperties *sub_properties = m_value_sp->GetAsProperties(); + if (sub_properties) + { + strm.EOL(); + + if (m_value_sp->DumpQualifiedName(qualified_name)) + strm.Printf("'%s' variables:\n\n", qualified_name.GetString().c_str()); + sub_properties->DumpAllDescriptions(interpreter, strm); + } + else + { + if (desc) + { + if (display_qualified_name) + { + StreamString qualified_name; + DumpQualifiedName(qualified_name); + interpreter.OutputFormattedHelpText (strm, + qualified_name.GetString().c_str(), + "--", + desc, + output_width); + } + else + { + interpreter.OutputFormattedHelpText (strm, + m_name.GetCString(), + "--", + desc, + output_width); + } + } + } + } + } +} + |