forked from OSchip/llvm-project
				
			
		
			
				
	
	
		
			678 lines
		
	
	
		
			22 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			678 lines
		
	
	
		
			22 KiB
		
	
	
	
		
			C++
		
	
	
	
//===-- 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/Utility/Flags.h"
 | 
						|
 | 
						|
#include "lldb/Core/UserSettingsController.h"
 | 
						|
#include "lldb/Interpreter/Args.h"
 | 
						|
#include "lldb/Interpreter/OptionValues.h"
 | 
						|
#include "lldb/Interpreter/Property.h"
 | 
						|
#include "lldb/Utility/Stream.h"
 | 
						|
#include "lldb/Utility/StringList.h"
 | 
						|
 | 
						|
using namespace lldb;
 | 
						|
using namespace lldb_private;
 | 
						|
 | 
						|
OptionValueProperties::OptionValueProperties(const ConstString &name)
 | 
						|
    : OptionValue(), m_name(name), m_properties(), m_name_to_index() {}
 | 
						|
 | 
						|
OptionValueProperties::OptionValueProperties(
 | 
						|
    const OptionValueProperties &global_properties)
 | 
						|
    : OptionValue(global_properties),
 | 
						|
      std::enable_shared_from_this<OptionValueProperties>(),
 | 
						|
      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 constructing 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(ConstString(property.GetName()), m_properties.size());
 | 
						|
    property.GetValue()->SetParent(shared_from_this());
 | 
						|
    m_properties.push_back(property);
 | 
						|
  }
 | 
						|
  m_name_to_index.Sort();
 | 
						|
}
 | 
						|
 | 
						|
void OptionValueProperties::SetValueChangedCallback(
 | 
						|
    uint32_t property_idx, OptionValueChangedCallback callback, void *baton) {
 | 
						|
  Property *property = ProtectedGetPropertyAtIndex(property_idx);
 | 
						|
  if (property)
 | 
						|
    property->SetValueChangedCallback(callback, baton);
 | 
						|
}
 | 
						|
 | 
						|
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, 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, 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,
 | 
						|
                                   llvm::StringRef name, bool will_modify,
 | 
						|
                                   Status &error) const {
 | 
						|
  lldb::OptionValueSP value_sp;
 | 
						|
  if (name.empty())
 | 
						|
    return OptionValueSP();
 | 
						|
 | 
						|
  llvm::StringRef sub_name;
 | 
						|
  ConstString key;
 | 
						|
  size_t key_len = name.find_first_of(".[{");
 | 
						|
  if (key_len != llvm::StringRef::npos) {
 | 
						|
    key.SetString(name.take_front(key_len));
 | 
						|
    sub_name = name.drop_front(key_len);
 | 
						|
  } else
 | 
						|
    key.SetString(name);
 | 
						|
 | 
						|
  value_sp = GetValueForKey(exe_ctx, key, will_modify);
 | 
						|
  if (sub_name.empty() || !value_sp)
 | 
						|
    return value_sp;
 | 
						|
 | 
						|
  switch (sub_name[0]) {
 | 
						|
  case '.': {
 | 
						|
    lldb::OptionValueSP return_val_sp;
 | 
						|
    return_val_sp =
 | 
						|
        value_sp->GetSubValue(exe_ctx, sub_name.drop_front(), will_modify, error);
 | 
						|
    if (!return_val_sp) {
 | 
						|
      if (Properties::IsSettingExperimental(sub_name.drop_front())) {
 | 
						|
        size_t experimental_len =
 | 
						|
            strlen(Properties::GetExperimentalSettingsName());
 | 
						|
        if (sub_name[experimental_len + 1] == '.')
 | 
						|
          return_val_sp = value_sp->GetSubValue(
 | 
						|
              exe_ctx, sub_name.drop_front(experimental_len + 2), will_modify, error);
 | 
						|
        // It isn't an error if an experimental setting is not present.
 | 
						|
        if (!return_val_sp)
 | 
						|
          error.Clear();
 | 
						|
      }
 | 
						|
    }
 | 
						|
    return return_val_sp;
 | 
						|
  }
 | 
						|
  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 executable basename is "test" and arch is "x86_64"
 | 
						|
    if (sub_name[1]) {
 | 
						|
      llvm::StringRef predicate_start = sub_name.drop_front();
 | 
						|
      size_t pos = predicate_start.find_first_of('}');
 | 
						|
      if (pos != llvm::StringRef::npos) {
 | 
						|
        auto predicate = predicate_start.take_front(pos);
 | 
						|
        auto rest = predicate_start.drop_front(pos);
 | 
						|
        if (PredicateMatches(exe_ctx, predicate)) {
 | 
						|
          if (!rest.empty()) {
 | 
						|
            // Still more subvalue string to evaluate
 | 
						|
            return value_sp->GetSubValue(exe_ctx, rest,
 | 
						|
                                          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;
 | 
						|
}
 | 
						|
 | 
						|
Status OptionValueProperties::SetSubValue(const ExecutionContext *exe_ctx,
 | 
						|
                                          VarSetOperationType op,
 | 
						|
                                          llvm::StringRef name,
 | 
						|
                                          llvm::StringRef value) {
 | 
						|
  Status error;
 | 
						|
  const bool will_modify = true;
 | 
						|
  lldb::OptionValueSP value_sp(GetSubValue(exe_ctx, name, will_modify, error));
 | 
						|
  if (value_sp)
 | 
						|
    error = value_sp->SetValueFromString(value, op);
 | 
						|
  else {
 | 
						|
    if (error.AsCString() == nullptr)
 | 
						|
      error.SetErrorStringWithFormat("invalid value path '%s'", name.str().c_str());
 | 
						|
  }
 | 
						|
  return error;
 | 
						|
}
 | 
						|
 | 
						|
uint32_t
 | 
						|
OptionValueProperties::GetPropertyIndex(const ConstString &name) const {
 | 
						|
  return m_name_to_index.Find(name, 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, 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 nullptr;
 | 
						|
}
 | 
						|
 | 
						|
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 nullptr;
 | 
						|
}
 | 
						|
 | 
						|
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 nullptr;
 | 
						|
}
 | 
						|
 | 
						|
OptionValueLanguage *
 | 
						|
OptionValueProperties::GetPropertyAtIndexAsOptionValueLanguage(
 | 
						|
    const ExecutionContext *exe_ctx, uint32_t idx) const {
 | 
						|
  const Property *property = GetPropertyAtIndex(exe_ctx, false, idx);
 | 
						|
  if (property)
 | 
						|
    return property->GetValue()->GetAsLanguage();
 | 
						|
  return nullptr;
 | 
						|
}
 | 
						|
 | 
						|
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 nullptr;
 | 
						|
}
 | 
						|
 | 
						|
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;
 | 
						|
}
 | 
						|
 | 
						|
const FormatEntity::Entry *
 | 
						|
OptionValueProperties::GetPropertyAtIndexAsFormatEntity(
 | 
						|
    const ExecutionContext *exe_ctx, uint32_t idx) {
 | 
						|
  const Property *property = GetPropertyAtIndex(exe_ctx, true, idx);
 | 
						|
  if (property) {
 | 
						|
    OptionValue *value = property->GetValue().get();
 | 
						|
    if (value)
 | 
						|
      return value->GetFormatEntity();
 | 
						|
  }
 | 
						|
  return nullptr;
 | 
						|
}
 | 
						|
 | 
						|
OptionValueFileSpec *
 | 
						|
OptionValueProperties::GetPropertyAtIndexAsOptionValueFileSpec(
 | 
						|
    const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const {
 | 
						|
  const Property *property = GetPropertyAtIndex(exe_ctx, false, idx);
 | 
						|
  if (property) {
 | 
						|
    OptionValue *value = property->GetValue().get();
 | 
						|
    if (value)
 | 
						|
      return value->GetAsFileSpec();
 | 
						|
  }
 | 
						|
  return nullptr;
 | 
						|
}
 | 
						|
 | 
						|
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 nullptr;
 | 
						|
}
 | 
						|
 | 
						|
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 nullptr;
 | 
						|
}
 | 
						|
 | 
						|
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;
 | 
						|
}
 | 
						|
 | 
						|
llvm::StringRef OptionValueProperties::GetPropertyAtIndexAsString(
 | 
						|
    const ExecutionContext *exe_ctx, uint32_t idx,
 | 
						|
    llvm::StringRef 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, llvm::StringRef 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;
 | 
						|
}
 | 
						|
 | 
						|
OptionValueString *OptionValueProperties::GetPropertyAtIndexAsOptionValueString(
 | 
						|
    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->GetAsString();
 | 
						|
  return nullptr;
 | 
						|
}
 | 
						|
 | 
						|
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;
 | 
						|
}
 | 
						|
 | 
						|
Status OptionValueProperties::SetValueFromString(llvm::StringRef value,
 | 
						|
                                                 VarSetOperationType op) {
 | 
						|
  Status 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::SetValueFromString(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();
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
Status OptionValueProperties::DumpPropertyValue(const ExecutionContext *exe_ctx,
 | 
						|
                                                Stream &strm,
 | 
						|
                                                llvm::StringRef property_path,
 | 
						|
                                                uint32_t dump_mask) {
 | 
						|
  Status 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 {
 | 
						|
  llvm_unreachable("this shouldn't happen");
 | 
						|
}
 | 
						|
 | 
						|
const Property *OptionValueProperties::GetPropertyAtPath(
 | 
						|
    const ExecutionContext *exe_ctx, bool will_modify, llvm::StringRef name) const {
 | 
						|
  const Property *property = nullptr;
 | 
						|
  if (name.empty())
 | 
						|
    return nullptr;
 | 
						|
  llvm::StringRef sub_name;
 | 
						|
  ConstString key;
 | 
						|
  size_t key_len = name.find_first_of(".[{");
 | 
						|
 | 
						|
  if (key_len != llvm::StringRef::npos) {
 | 
						|
    key.SetString(name.take_front(key_len));
 | 
						|
    sub_name = name.drop_front(key_len);
 | 
						|
  } else
 | 
						|
    key.SetString(name);
 | 
						|
 | 
						|
  property = GetProperty(exe_ctx, will_modify, key);
 | 
						|
  if (sub_name.empty() || !property)
 | 
						|
    return property;
 | 
						|
 | 
						|
  if (sub_name[0] == '.') {
 | 
						|
    OptionValueProperties *sub_properties =
 | 
						|
        property->GetValue()->GetAsProperties();
 | 
						|
    if (sub_properties)
 | 
						|
      return sub_properties->GetPropertyAtPath(exe_ctx, will_modify,
 | 
						|
                                                sub_name.drop_front());
 | 
						|
  }
 | 
						|
  return nullptr;
 | 
						|
}
 | 
						|
 | 
						|
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().size(), 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(
 | 
						|
    llvm::StringRef 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;
 | 
						|
        llvm::StringRef name = property->GetName();
 | 
						|
        if (name.contains_lower(keyword))
 | 
						|
          match = true;
 | 
						|
        else {
 | 
						|
          llvm::StringRef desc = property->GetDescription();
 | 
						|
          if (desc.contains_lower(keyword))
 | 
						|
            match = true;
 | 
						|
        }
 | 
						|
        if (match) {
 | 
						|
          matching_properties.push_back(property);
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
lldb::OptionValuePropertiesSP
 | 
						|
OptionValueProperties::GetSubProperty(const ExecutionContext *exe_ctx,
 | 
						|
                                      const ConstString &name) {
 | 
						|
  lldb::OptionValueSP option_value_sp(GetValueForKey(exe_ctx, name, false));
 | 
						|
  if (option_value_sp) {
 | 
						|
    OptionValueProperties *ov_properties = option_value_sp->GetAsProperties();
 | 
						|
    if (ov_properties)
 | 
						|
      return ov_properties->shared_from_this();
 | 
						|
  }
 | 
						|
  return lldb::OptionValuePropertiesSP();
 | 
						|
}
 |