1 //===-- OptionValueProperties.cpp ---------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "lldb/Interpreter/OptionValueProperties.h"
14 // Other libraries and framework includes
16 #include "lldb/Core/Flags.h"
17 #include "lldb/Core/Stream.h"
18 #include "lldb/Core/StringList.h"
19 #include "lldb/Core/UserSettingsController.h"
20 #include "lldb/Interpreter/Args.h"
21 #include "lldb/Interpreter/OptionValues.h"
22 #include "lldb/Interpreter/Property.h"
25 using namespace lldb_private;
28 OptionValueProperties::OptionValueProperties (const ConstString &name) :
36 OptionValueProperties::OptionValueProperties (const OptionValueProperties &global_properties) :
37 OptionValue (global_properties),
38 std::enable_shared_from_this<OptionValueProperties> (),
39 m_name (global_properties.m_name),
40 m_properties (global_properties.m_properties),
41 m_name_to_index (global_properties.m_name_to_index)
43 // We now have an exact copy of "global_properties". We need to now
44 // find all non-global settings and copy the property values so that
45 // all non-global settings get new OptionValue instances created for
47 const size_t num_properties = m_properties.size();
48 for (size_t i=0; i<num_properties; ++i)
50 // Duplicate any values that are not global when constructing properties from
52 if (m_properties[i].IsGlobal() == false)
54 lldb::OptionValueSP new_value_sp (m_properties[i].GetValue()->DeepCopy());
55 m_properties[i].SetOptionValue(new_value_sp);
63 OptionValueProperties::GetNumProperties() const
65 return m_properties.size();
70 OptionValueProperties::Initialize (const PropertyDefinition *defs)
72 for (size_t i=0; defs[i].name; ++i)
74 Property property(defs[i]);
75 assert(property.IsValid());
76 m_name_to_index.Append(property.GetName().GetCString(),m_properties.size());
77 property.GetValue()->SetParent(shared_from_this());
78 m_properties.push_back(property);
80 m_name_to_index.Sort();
84 OptionValueProperties::SetValueChangedCallback (uint32_t property_idx,
85 OptionValueChangedCallback callback,
88 Property *property = ProtectedGetPropertyAtIndex (property_idx);
90 property->SetValueChangedCallback (callback, baton);
94 OptionValueProperties::AppendProperty(const ConstString &name,
95 const ConstString &desc,
97 const OptionValueSP &value_sp)
99 Property property(name, desc, is_global, value_sp);
100 m_name_to_index.Append(name.GetCString(),m_properties.size());
101 m_properties.push_back(property);
102 value_sp->SetParent (shared_from_this());
103 m_name_to_index.Sort();
109 //OptionValueProperties::GetQualifiedName (Stream &strm)
111 // bool dumped_something = false;
112 //// lldb::OptionValuePropertiesSP parent_sp(GetParent ());
115 //// parent_sp->GetQualifiedName (strm);
116 //// strm.PutChar('.');
117 //// dumped_something = true;
122 // dumped_something = true;
124 // return dumped_something;
128 OptionValueProperties::GetValueForKey (const ExecutionContext *exe_ctx,
129 const ConstString &key,
130 bool will_modify) const
132 lldb::OptionValueSP value_sp;
133 size_t idx = m_name_to_index.Find (key.GetCString(), SIZE_MAX);
134 if (idx < m_properties.size())
135 value_sp = GetPropertyAtIndex(exe_ctx, will_modify, idx)->GetValue();
140 OptionValueProperties::GetSubValue (const ExecutionContext *exe_ctx,
145 lldb::OptionValueSP value_sp;
149 const char *sub_name = nullptr;
151 size_t key_len = ::strcspn (name, ".[{");
155 key.SetCStringWithLength (name, key_len);
156 sub_name = name + key_len;
159 key.SetCString (name);
161 value_sp = GetValueForKey (exe_ctx, key, will_modify);
162 if (sub_name && value_sp)
168 lldb::OptionValueSP return_val_sp;
169 return_val_sp = value_sp->GetSubValue (exe_ctx, sub_name + 1, will_modify, error);
172 if (Properties::IsSettingExperimental(sub_name + 1))
174 size_t experimental_len = strlen(Properties::GetExperimentalSettingsName());
175 if (*(sub_name + experimental_len + 1) == '.')
176 return_val_sp = value_sp->GetSubValue(exe_ctx, sub_name + experimental_len + 2, will_modify, error);
177 // It isn't an error if an experimental setting is not present.
182 return return_val_sp;
185 // Predicate matching for predicates like
186 // "<setting-name>{<predicate>}"
187 // strings are parsed by the current OptionValueProperties subclass
188 // to mean whatever they want to. For instance a subclass of
189 // OptionValueProperties for a lldb_private::Target might implement:
190 // "target.run-args{arch==i386}" -- only set run args if the arch is i386
191 // "target.run-args{path=/tmp/a/b/c/a.out}" -- only set run args if the path matches
192 // "target.run-args{basename==test&&arch==x86_64}" -- only set run args if executable basename is "test" and arch is "x86_64"
195 const char *predicate_start = sub_name + 1;
196 const char *predicate_end = strchr(predicate_start, '}');
199 std::string predicate(predicate_start, predicate_end);
200 if (PredicateMatches(exe_ctx, predicate.c_str()))
202 if (predicate_end[1])
204 // Still more subvalue string to evaluate
205 return value_sp->GetSubValue (exe_ctx, predicate_end + 1, will_modify, error);
215 // Predicate didn't match or wasn't correctly formed
220 // Array or dictionary access for subvalues like:
221 // "[12]" -- access 12th array element
222 // "['hello']" -- dictionary access of key named hello
223 return value_sp->GetSubValue (exe_ctx, sub_name, will_modify, error);
235 OptionValueProperties::SetSubValue (const ExecutionContext *exe_ctx,
236 VarSetOperationType op,
241 const bool will_modify = true;
242 lldb::OptionValueSP value_sp (GetSubValue (exe_ctx, name, will_modify, error));
244 error = value_sp->SetValueFromString(value ? llvm::StringRef(value) : llvm::StringRef(), op);
247 if (error.AsCString() == nullptr)
248 error.SetErrorStringWithFormat("invalid value path '%s'", name);
255 OptionValueProperties::GetPropertyNameAtIndex (uint32_t idx) const
257 const Property *property = GetPropertyAtIndex(nullptr, false, idx);
259 return property->GetName();
260 return ConstString();
265 OptionValueProperties::GetPropertyDescriptionAtIndex (uint32_t idx) const
267 const Property *property = GetPropertyAtIndex(nullptr, false, idx);
269 return property->GetDescription();
274 OptionValueProperties::GetPropertyIndex (const ConstString &name) const
276 return m_name_to_index.Find (name.GetCString(), SIZE_MAX);
280 OptionValueProperties::GetProperty (const ExecutionContext *exe_ctx, bool will_modify, const ConstString &name) const
282 return GetPropertyAtIndex (exe_ctx, will_modify, m_name_to_index.Find (name.GetCString(), SIZE_MAX));
286 OptionValueProperties::GetPropertyAtIndex (const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const
288 return ProtectedGetPropertyAtIndex (idx);
292 OptionValueProperties::GetPropertyValueAtIndex (const ExecutionContext *exe_ctx,
296 const Property *setting = GetPropertyAtIndex (exe_ctx, will_modify, idx);
298 return setting->GetValue();
299 return OptionValueSP();
302 OptionValuePathMappings *
303 OptionValueProperties::GetPropertyAtIndexAsOptionValuePathMappings (const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const
305 OptionValueSP value_sp(GetPropertyValueAtIndex (exe_ctx, will_modify, idx));
307 return value_sp->GetAsPathMappings();
311 OptionValueFileSpecList *
312 OptionValueProperties::GetPropertyAtIndexAsOptionValueFileSpecList (const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const
314 OptionValueSP value_sp(GetPropertyValueAtIndex (exe_ctx, will_modify, idx));
316 return value_sp->GetAsFileSpecList();
321 OptionValueProperties::GetPropertyAtIndexAsOptionValueArch (const ExecutionContext *exe_ctx, uint32_t idx) const
323 const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
325 return property->GetValue()->GetAsArch();
329 OptionValueLanguage *
330 OptionValueProperties::GetPropertyAtIndexAsOptionValueLanguage (const ExecutionContext *exe_ctx, uint32_t idx) const
332 const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
334 return property->GetValue()->GetAsLanguage();
339 OptionValueProperties::GetPropertyAtIndexAsArgs (const ExecutionContext *exe_ctx, uint32_t idx, Args &args) const
341 const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
344 OptionValue *value = property->GetValue().get();
347 const OptionValueArray *array = value->GetAsArray();
349 return array->GetArgs(args);
352 const OptionValueDictionary *dict = value->GetAsDictionary();
354 return dict->GetArgs(args);
362 OptionValueProperties::SetPropertyAtIndexFromArgs (const ExecutionContext *exe_ctx, uint32_t idx, const Args &args)
364 const Property *property = GetPropertyAtIndex (exe_ctx, true, idx);
367 OptionValue *value = property->GetValue().get();
370 OptionValueArray *array = value->GetAsArray();
372 return array->SetArgs(args, eVarSetOperationAssign).Success();
375 OptionValueDictionary *dict = value->GetAsDictionary();
377 return dict->SetArgs(args, eVarSetOperationAssign).Success();
385 OptionValueProperties::GetPropertyAtIndexAsBoolean (const ExecutionContext *exe_ctx, uint32_t idx, bool fail_value) const
387 const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
390 OptionValue *value = property->GetValue().get();
392 return value->GetBooleanValue(fail_value);
398 OptionValueProperties::SetPropertyAtIndexAsBoolean (const ExecutionContext *exe_ctx, uint32_t idx, bool new_value)
400 const Property *property = GetPropertyAtIndex (exe_ctx, true, idx);
403 OptionValue *value = property->GetValue().get();
406 value->SetBooleanValue(new_value);
413 OptionValueDictionary *
414 OptionValueProperties::GetPropertyAtIndexAsOptionValueDictionary (const ExecutionContext *exe_ctx, uint32_t idx) const
416 const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
418 return property->GetValue()->GetAsDictionary();
423 OptionValueProperties::GetPropertyAtIndexAsEnumeration (const ExecutionContext *exe_ctx, uint32_t idx, int64_t fail_value) const
425 const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
428 OptionValue *value = property->GetValue().get();
430 return value->GetEnumerationValue(fail_value);
436 OptionValueProperties::SetPropertyAtIndexAsEnumeration (const ExecutionContext *exe_ctx, uint32_t idx, int64_t new_value)
438 const Property *property = GetPropertyAtIndex (exe_ctx, true, idx);
441 OptionValue *value = property->GetValue().get();
443 return value->SetEnumerationValue(new_value);
448 const FormatEntity::Entry *
449 OptionValueProperties::GetPropertyAtIndexAsFormatEntity (const ExecutionContext *exe_ctx, uint32_t idx)
451 const Property *property = GetPropertyAtIndex (exe_ctx, true, idx);
454 OptionValue *value = property->GetValue().get();
456 return value->GetFormatEntity();
461 OptionValueFileSpec *
462 OptionValueProperties::GetPropertyAtIndexAsOptionValueFileSpec (const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const
464 const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
467 OptionValue *value = property->GetValue().get();
469 return value->GetAsFileSpec();
476 OptionValueProperties::GetPropertyAtIndexAsFileSpec (const ExecutionContext *exe_ctx, uint32_t idx) const
478 const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
481 OptionValue *value = property->GetValue().get();
483 return value->GetFileSpecValue();
490 OptionValueProperties::SetPropertyAtIndexAsFileSpec (const ExecutionContext *exe_ctx, uint32_t idx, const FileSpec &new_file_spec)
492 const Property *property = GetPropertyAtIndex (exe_ctx, true, idx);
495 OptionValue *value = property->GetValue().get();
497 return value->SetFileSpecValue(new_file_spec);
502 const RegularExpression *
503 OptionValueProperties::GetPropertyAtIndexAsOptionValueRegex (const ExecutionContext *exe_ctx, uint32_t idx) const
505 const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
508 OptionValue *value = property->GetValue().get();
510 return value->GetRegexValue();
516 OptionValueProperties::GetPropertyAtIndexAsOptionValueSInt64 (const ExecutionContext *exe_ctx, uint32_t idx) const
518 const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
521 OptionValue *value = property->GetValue().get();
523 return value->GetAsSInt64();
529 OptionValueProperties::GetPropertyAtIndexAsSInt64 (const ExecutionContext *exe_ctx, uint32_t idx, int64_t fail_value) const
531 const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
534 OptionValue *value = property->GetValue().get();
536 return value->GetSInt64Value(fail_value);
542 OptionValueProperties::SetPropertyAtIndexAsSInt64 (const ExecutionContext *exe_ctx, uint32_t idx, int64_t new_value)
544 const Property *property = GetPropertyAtIndex (exe_ctx, true, idx);
547 OptionValue *value = property->GetValue().get();
549 return value->SetSInt64Value(new_value);
555 OptionValueProperties::GetPropertyAtIndexAsString (const ExecutionContext *exe_ctx, uint32_t idx, const char *fail_value) const
557 const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
560 OptionValue *value = property->GetValue().get();
562 return value->GetStringValue(fail_value);
568 OptionValueProperties::SetPropertyAtIndexAsString (const ExecutionContext *exe_ctx, uint32_t idx, const char *new_value)
570 const Property *property = GetPropertyAtIndex (exe_ctx, true, idx);
573 OptionValue *value = property->GetValue().get();
575 return value->SetStringValue(new_value);
581 OptionValueProperties::GetPropertyAtIndexAsOptionValueString (const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const
583 OptionValueSP value_sp(GetPropertyValueAtIndex (exe_ctx, will_modify, idx));
585 return value_sp->GetAsString();
591 OptionValueProperties::GetPropertyAtIndexAsUInt64 (const ExecutionContext *exe_ctx, uint32_t idx, uint64_t fail_value) const
593 const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
596 OptionValue *value = property->GetValue().get();
598 return value->GetUInt64Value(fail_value);
604 OptionValueProperties::SetPropertyAtIndexAsUInt64 (const ExecutionContext *exe_ctx, uint32_t idx, uint64_t new_value)
606 const Property *property = GetPropertyAtIndex (exe_ctx, true, idx);
609 OptionValue *value = property->GetValue().get();
611 return value->SetUInt64Value(new_value);
617 OptionValueProperties::Clear ()
619 const size_t num_properties = m_properties.size();
620 for (size_t i=0; i<num_properties; ++i)
621 m_properties[i].GetValue()->Clear();
627 OptionValueProperties::SetValueFromString (llvm::StringRef value, VarSetOperationType op)
631 // Args args(value_cstr);
632 // const size_t argc = args.GetArgumentCount();
635 case eVarSetOperationClear:
639 case eVarSetOperationReplace:
640 case eVarSetOperationAssign:
641 case eVarSetOperationRemove:
642 case eVarSetOperationInsertBefore:
643 case eVarSetOperationInsertAfter:
644 case eVarSetOperationAppend:
645 case eVarSetOperationInvalid:
646 error = OptionValue::SetValueFromString (value, op);
654 OptionValueProperties::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask)
656 const size_t num_properties = m_properties.size();
657 for (size_t i=0; i<num_properties; ++i)
659 const Property *property = GetPropertyAtIndex(exe_ctx, false, i);
662 OptionValue *option_value = property->GetValue().get();
663 assert (option_value);
664 const bool transparent_value = option_value->ValueIsTransparent ();
665 property->Dump (exe_ctx,
668 if (!transparent_value)
675 OptionValueProperties::DumpPropertyValue (const ExecutionContext *exe_ctx,
677 const char *property_path,
681 const bool will_modify = false;
682 lldb::OptionValueSP value_sp (GetSubValue (exe_ctx, property_path, will_modify, error));
685 if (!value_sp->ValueIsTransparent ())
687 if (dump_mask & eDumpOptionName)
688 strm.PutCString (property_path);
689 if (dump_mask & ~eDumpOptionName)
692 value_sp->DumpValue (exe_ctx, strm, dump_mask);
698 OptionValueProperties::DeepCopy () const
700 assert(!"this shouldn't happen");
701 return lldb::OptionValueSP();
705 OptionValueProperties::GetPropertyAtPath (const ExecutionContext *exe_ctx,
707 const char *name) const
709 const Property *property = nullptr;
712 const char *sub_name = nullptr;
714 size_t key_len = ::strcspn (name, ".[{");
718 key.SetCStringWithLength (name, key_len);
719 sub_name = name + key_len;
722 key.SetCString (name);
724 property = GetProperty (exe_ctx, will_modify, key);
725 if (sub_name && property)
727 if (sub_name[0] == '.')
729 OptionValueProperties *sub_properties = property->GetValue()->GetAsProperties();
731 return sub_properties->GetPropertyAtPath(exe_ctx, will_modify, sub_name + 1);
740 OptionValueProperties::DumpAllDescriptions (CommandInterpreter &interpreter,
743 size_t max_name_len = 0;
744 const size_t num_properties = m_properties.size();
745 for (size_t i=0; i<num_properties; ++i)
747 const Property *property = ProtectedGetPropertyAtIndex(i);
749 max_name_len = std::max<size_t>(property->GetName().GetLength(), max_name_len);
751 for (size_t i=0; i<num_properties; ++i)
753 const Property *property = ProtectedGetPropertyAtIndex(i);
755 property->DumpDescription (interpreter, strm, max_name_len, false);
760 OptionValueProperties::Apropos (const char *keyword, std::vector<const Property *> &matching_properties) const
762 const size_t num_properties = m_properties.size();
764 for (size_t i=0; i<num_properties; ++i)
766 const Property *property = ProtectedGetPropertyAtIndex(i);
769 const OptionValueProperties *properties = property->GetValue()->GetAsProperties();
772 properties->Apropos (keyword, matching_properties);
777 const char *name = property->GetName().GetCString();
778 if (name && ::strcasestr(name, keyword))
782 const char *desc = property->GetDescription();
783 if (desc && ::strcasestr(desc, keyword))
788 matching_properties.push_back (property);
795 lldb::OptionValuePropertiesSP
796 OptionValueProperties::GetSubProperty (const ExecutionContext *exe_ctx,
797 const ConstString &name)
799 lldb::OptionValueSP option_value_sp(GetValueForKey(exe_ctx, name, false));
802 OptionValueProperties *ov_properties = option_value_sp->GetAsProperties ();
804 return ov_properties->shared_from_this();
806 return lldb::OptionValuePropertiesSP();