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 m_name (global_properties.m_name),
39 m_properties (global_properties.m_properties),
40 m_name_to_index (global_properties.m_name_to_index)
42 // We now have an exact copy of "global_properties". We need to now
43 // find all non-global settings and copy the property values so that
44 // all non-global settings get new OptionValue instances created for
46 const size_t num_properties = m_properties.size();
47 for (size_t i=0; i<num_properties; ++i)
49 // Duplicate any values that are not global when contructing properties from
51 if (m_properties[i].IsGlobal() == false)
53 lldb::OptionValueSP new_value_sp (m_properties[i].GetValue()->DeepCopy());
54 m_properties[i].SetOptionValue(new_value_sp);
62 OptionValueProperties::GetNumProperties() const
64 return m_properties.size();
69 OptionValueProperties::Initialize (const PropertyDefinition *defs)
71 for (size_t i=0; defs[i].name; ++i)
73 Property property(defs[i]);
74 assert(property.IsValid());
75 m_name_to_index.Append(property.GetName().GetCString(),m_properties.size());
76 property.GetValue()->SetParent(shared_from_this());
77 m_properties.push_back(property);
79 m_name_to_index.Sort();
83 OptionValueProperties::AppendProperty(const ConstString &name,
84 const ConstString &desc,
86 const OptionValueSP &value_sp)
88 Property property(name, desc, is_global, value_sp);
89 m_name_to_index.Append(name.GetCString(),m_properties.size());
90 m_properties.push_back(property);
91 value_sp->SetParent (shared_from_this());
92 m_name_to_index.Sort();
98 //OptionValueProperties::GetQualifiedName (Stream &strm)
100 // bool dumped_something = false;
101 //// lldb::OptionValuePropertiesSP parent_sp(GetParent ());
104 //// parent_sp->GetQualifiedName (strm);
105 //// strm.PutChar('.');
106 //// dumped_something = true;
111 // dumped_something = true;
113 // return dumped_something;
117 OptionValueProperties::GetValueForKey (const ExecutionContext *exe_ctx,
118 const ConstString &key,
119 bool will_modify) const
121 lldb::OptionValueSP value_sp;
122 size_t idx = m_name_to_index.Find (key.GetCString(), SIZE_MAX);
123 if (idx < m_properties.size())
124 value_sp = GetPropertyAtIndex(exe_ctx, will_modify, idx)->GetValue();
129 OptionValueProperties::GetSubValue (const ExecutionContext *exe_ctx,
134 lldb::OptionValueSP value_sp;
138 const char *sub_name = NULL;
140 size_t key_len = ::strcspn (name, ".[{");
144 key.SetCStringWithLength (name, key_len);
145 sub_name = name + key_len;
148 key.SetCString (name);
150 value_sp = GetValueForKey (exe_ctx, key, will_modify);
151 if (sub_name && value_sp)
156 return value_sp->GetSubValue (exe_ctx, sub_name + 1, will_modify, error);
159 // Predicate matching for predicates like
160 // "<setting-name>{<predicate>}"
161 // strings are parsed by the current OptionValueProperties subclass
162 // to mean whatever they want to. For instance a subclass of
163 // OptionValueProperties for a lldb_private::Target might implement:
164 // "target.run-args{arch==i386}" -- only set run args if the arch is i386
165 // "target.run-args{path=/tmp/a/b/c/a.out}" -- only set run args if the path matches
166 // "target.run-args{basename==test&&arch==x86_64}" -- only set run args if exectable basename is "test" and arch is "x86_64"
169 const char *predicate_start = sub_name + 1;
170 const char *predicate_end = strchr(predicate_start, '}');
173 std::string predicate(predicate_start, predicate_end);
174 if (PredicateMatches(exe_ctx, predicate.c_str()))
176 if (predicate_end[1])
178 // Still more subvalue string to evaluate
179 return value_sp->GetSubValue (exe_ctx, predicate_end + 1, will_modify, error);
189 // Predicate didn't match or wasn't correctly formed
194 // Array or dictionary access for subvalues like:
195 // "[12]" -- access 12th array element
196 // "['hello']" -- dictionary access of key named hello
197 return value_sp->GetSubValue (exe_ctx, sub_name, will_modify, error);
209 OptionValueProperties::SetSubValue (const ExecutionContext *exe_ctx,
210 VarSetOperationType op,
215 const bool will_modify = true;
216 lldb::OptionValueSP value_sp (GetSubValue (exe_ctx, name, will_modify, error));
218 error = value_sp->SetValueFromCString(value, op);
221 if (error.AsCString() == NULL)
222 error.SetErrorStringWithFormat("invalid value path '%s'", name);
229 OptionValueProperties::GetPropertyNameAtIndex (uint32_t idx) const
231 const Property *property = GetPropertyAtIndex(NULL, false, idx);
233 return property->GetName();
234 return ConstString();
239 OptionValueProperties::GetPropertyDescriptionAtIndex (uint32_t idx) const
241 const Property *property = GetPropertyAtIndex(NULL, false, idx);
243 return property->GetDescription();
248 OptionValueProperties::GetPropertyIndex (const ConstString &name) const
250 return m_name_to_index.Find (name.GetCString(), SIZE_MAX);
254 OptionValueProperties::GetProperty (const ExecutionContext *exe_ctx, bool will_modify, const ConstString &name) const
256 return GetPropertyAtIndex (exe_ctx, will_modify, m_name_to_index.Find (name.GetCString(), SIZE_MAX));
260 OptionValueProperties::GetPropertyAtIndex (const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const
262 return ProtectedGetPropertyAtIndex (idx);
266 OptionValueProperties::GetPropertyValueAtIndex (const ExecutionContext *exe_ctx,
270 const Property *setting = GetPropertyAtIndex (exe_ctx, will_modify, idx);
272 return setting->GetValue();
273 return OptionValueSP();
276 OptionValuePathMappings *
277 OptionValueProperties::GetPropertyAtIndexAsOptionValuePathMappings (const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const
279 OptionValueSP value_sp(GetPropertyValueAtIndex (exe_ctx, will_modify, idx));
281 return value_sp->GetAsPathMappings();
285 OptionValueFileSpecList *
286 OptionValueProperties::GetPropertyAtIndexAsOptionValueFileSpecList (const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const
288 OptionValueSP value_sp(GetPropertyValueAtIndex (exe_ctx, will_modify, idx));
290 return value_sp->GetAsFileSpecList();
295 OptionValueProperties::GetPropertyAtIndexAsOptionValueArch (const ExecutionContext *exe_ctx, uint32_t idx) const
297 const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
299 return property->GetValue()->GetAsArch();
304 OptionValueProperties::GetPropertyAtIndexAsArgs (const ExecutionContext *exe_ctx, uint32_t idx, Args &args) const
306 const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
309 OptionValue *value = property->GetValue().get();
312 const OptionValueArray *array = value->GetAsArray();
314 return array->GetArgs(args);
317 const OptionValueDictionary *dict = value->GetAsDictionary();
319 return dict->GetArgs(args);
327 OptionValueProperties::SetPropertyAtIndexFromArgs (const ExecutionContext *exe_ctx, uint32_t idx, const Args &args)
329 const Property *property = GetPropertyAtIndex (exe_ctx, true, idx);
332 OptionValue *value = property->GetValue().get();
335 OptionValueArray *array = value->GetAsArray();
337 return array->SetArgs(args, eVarSetOperationAssign).Success();
340 OptionValueDictionary *dict = value->GetAsDictionary();
342 return dict->SetArgs(args, eVarSetOperationAssign).Success();
350 OptionValueProperties::GetPropertyAtIndexAsBoolean (const ExecutionContext *exe_ctx, uint32_t idx, bool fail_value) const
352 const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
355 OptionValue *value = property->GetValue().get();
357 return value->GetBooleanValue(fail_value);
363 OptionValueProperties::SetPropertyAtIndexAsBoolean (const ExecutionContext *exe_ctx, uint32_t idx, bool new_value)
365 const Property *property = GetPropertyAtIndex (exe_ctx, true, idx);
368 OptionValue *value = property->GetValue().get();
371 value->SetBooleanValue(new_value);
378 OptionValueDictionary *
379 OptionValueProperties::GetPropertyAtIndexAsOptionValueDictionary (const ExecutionContext *exe_ctx, uint32_t idx) const
381 const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
383 return property->GetValue()->GetAsDictionary();
388 OptionValueProperties::GetPropertyAtIndexAsEnumeration (const ExecutionContext *exe_ctx, uint32_t idx, int64_t fail_value) const
390 const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
393 OptionValue *value = property->GetValue().get();
395 return value->GetEnumerationValue(fail_value);
401 OptionValueProperties::SetPropertyAtIndexAsEnumeration (const ExecutionContext *exe_ctx, uint32_t idx, int64_t new_value)
403 const Property *property = GetPropertyAtIndex (exe_ctx, true, idx);
406 OptionValue *value = property->GetValue().get();
408 return value->SetEnumerationValue(new_value);
414 OptionValueFileSpec *
415 OptionValueProperties::GetPropertyAtIndexAsOptionValueFileSpec (const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const
417 const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
420 OptionValue *value = property->GetValue().get();
422 return value->GetAsFileSpec();
429 OptionValueProperties::GetPropertyAtIndexAsFileSpec (const ExecutionContext *exe_ctx, uint32_t idx) const
431 const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
434 OptionValue *value = property->GetValue().get();
436 return value->GetFileSpecValue();
443 OptionValueProperties::SetPropertyAtIndexAsFileSpec (const ExecutionContext *exe_ctx, uint32_t idx, const FileSpec &new_file_spec)
445 const Property *property = GetPropertyAtIndex (exe_ctx, true, idx);
448 OptionValue *value = property->GetValue().get();
450 return value->SetFileSpecValue(new_file_spec);
455 const RegularExpression *
456 OptionValueProperties::GetPropertyAtIndexAsOptionValueRegex (const ExecutionContext *exe_ctx, uint32_t idx) const
458 const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
461 OptionValue *value = property->GetValue().get();
463 return value->GetRegexValue();
469 OptionValueProperties::GetPropertyAtIndexAsOptionValueSInt64 (const ExecutionContext *exe_ctx, uint32_t idx) const
471 const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
474 OptionValue *value = property->GetValue().get();
476 return value->GetAsSInt64();
482 OptionValueProperties::GetPropertyAtIndexAsSInt64 (const ExecutionContext *exe_ctx, uint32_t idx, int64_t fail_value) const
484 const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
487 OptionValue *value = property->GetValue().get();
489 return value->GetSInt64Value(fail_value);
495 OptionValueProperties::SetPropertyAtIndexAsSInt64 (const ExecutionContext *exe_ctx, uint32_t idx, int64_t new_value)
497 const Property *property = GetPropertyAtIndex (exe_ctx, true, idx);
500 OptionValue *value = property->GetValue().get();
502 return value->SetSInt64Value(new_value);
508 OptionValueProperties::GetPropertyAtIndexAsString (const ExecutionContext *exe_ctx, uint32_t idx, const char *fail_value) const
510 const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
513 OptionValue *value = property->GetValue().get();
515 return value->GetStringValue(fail_value);
521 OptionValueProperties::SetPropertyAtIndexAsString (const ExecutionContext *exe_ctx, uint32_t idx, const char *new_value)
523 const Property *property = GetPropertyAtIndex (exe_ctx, true, idx);
526 OptionValue *value = property->GetValue().get();
528 return value->SetStringValue(new_value);
534 OptionValueProperties::GetPropertyAtIndexAsOptionValueString (const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const
536 OptionValueSP value_sp(GetPropertyValueAtIndex (exe_ctx, will_modify, idx));
538 return value_sp->GetAsString();
544 OptionValueProperties::GetPropertyAtIndexAsUInt64 (const ExecutionContext *exe_ctx, uint32_t idx, uint64_t fail_value) const
546 const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
549 OptionValue *value = property->GetValue().get();
551 return value->GetUInt64Value(fail_value);
557 OptionValueProperties::SetPropertyAtIndexAsUInt64 (const ExecutionContext *exe_ctx, uint32_t idx, uint64_t new_value)
559 const Property *property = GetPropertyAtIndex (exe_ctx, true, idx);
562 OptionValue *value = property->GetValue().get();
564 return value->SetUInt64Value(new_value);
570 OptionValueProperties::Clear ()
572 const size_t num_properties = m_properties.size();
573 for (size_t i=0; i<num_properties; ++i)
574 m_properties[i].GetValue()->Clear();
580 OptionValueProperties::SetValueFromCString (const char *value, VarSetOperationType op)
584 // Args args(value_cstr);
585 // const size_t argc = args.GetArgumentCount();
588 case eVarSetOperationClear:
592 case eVarSetOperationReplace:
593 case eVarSetOperationAssign:
594 case eVarSetOperationRemove:
595 case eVarSetOperationInsertBefore:
596 case eVarSetOperationInsertAfter:
597 case eVarSetOperationAppend:
598 case eVarSetOperationInvalid:
599 error = OptionValue::SetValueFromCString (value, op);
607 OptionValueProperties::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask)
609 const size_t num_properties = m_properties.size();
610 for (size_t i=0; i<num_properties; ++i)
612 const Property *property = GetPropertyAtIndex(exe_ctx, false, i);
615 OptionValue *option_value = property->GetValue().get();
616 assert (option_value);
617 const bool transparent_value = option_value->ValueIsTransparent ();
618 property->Dump (exe_ctx,
621 if (!transparent_value)
628 OptionValueProperties::DumpPropertyValue (const ExecutionContext *exe_ctx,
630 const char *property_path,
634 const bool will_modify = false;
635 lldb::OptionValueSP value_sp (GetSubValue (exe_ctx, property_path, will_modify, error));
638 if (!value_sp->ValueIsTransparent ())
640 if (dump_mask & eDumpOptionName)
641 strm.PutCString (property_path);
642 if (dump_mask & ~eDumpOptionName)
645 value_sp->DumpValue (exe_ctx, strm, dump_mask);
651 OptionValueProperties::DeepCopy () const
653 assert(!"this shouldn't happen");
657 OptionValueProperties::GetPropertyAtPath (const ExecutionContext *exe_ctx,
659 const char *name) const
661 const Property *property = NULL;
664 const char *sub_name = NULL;
666 size_t key_len = ::strcspn (name, ".[{");
670 key.SetCStringWithLength (name, key_len);
671 sub_name = name + key_len;
674 key.SetCString (name);
676 property = GetProperty (exe_ctx, will_modify, key);
677 if (sub_name && property)
679 if (sub_name[0] == '.')
681 OptionValueProperties *sub_properties = property->GetValue()->GetAsProperties();
683 return sub_properties->GetPropertyAtPath(exe_ctx, will_modify, sub_name + 1);
692 OptionValueProperties::DumpAllDescriptions (CommandInterpreter &interpreter,
695 size_t max_name_len = 0;
696 const size_t num_properties = m_properties.size();
697 for (size_t i=0; i<num_properties; ++i)
699 const Property *property = ProtectedGetPropertyAtIndex(i);
701 max_name_len = std::max<size_t>(property->GetName().GetLength(), max_name_len);
703 for (size_t i=0; i<num_properties; ++i)
705 const Property *property = ProtectedGetPropertyAtIndex(i);
707 property->DumpDescription (interpreter, strm, max_name_len, false);
712 OptionValueProperties::Apropos (const char *keyword, std::vector<const Property *> &matching_properties) const
714 const size_t num_properties = m_properties.size();
716 for (size_t i=0; i<num_properties; ++i)
718 const Property *property = ProtectedGetPropertyAtIndex(i);
721 const OptionValueProperties *properties = property->GetValue()->GetAsProperties();
724 properties->Apropos (keyword, matching_properties);
729 const char *name = property->GetName().GetCString();
730 if (name && ::strcasestr(name, keyword))
734 const char *desc = property->GetDescription();
735 if (desc && ::strcasestr(desc, keyword))
740 matching_properties.push_back (property);
747 lldb::OptionValuePropertiesSP
748 OptionValueProperties::GetSubProperty (const ExecutionContext *exe_ctx,
749 const ConstString &name)
751 lldb::OptionValueSP option_value_sp(GetValueForKey(exe_ctx, name, false));
754 OptionValueProperties *ov_properties = option_value_sp->GetAsProperties ();
756 return ov_properties->shared_from_this();
758 return lldb::OptionValuePropertiesSP();