xref: /openbsd-src/gnu/llvm/lldb/source/Interpreter/OptionValueProperties.cpp (revision f6aab3d83b51b91c24247ad2c2573574de475a82)
1dda28197Spatrick //===-- OptionValueProperties.cpp -----------------------------------------===//
2061da546Spatrick //
3061da546Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4061da546Spatrick // See https://llvm.org/LICENSE.txt for license information.
5061da546Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6061da546Spatrick //
7061da546Spatrick //===----------------------------------------------------------------------===//
8061da546Spatrick 
9061da546Spatrick #include "lldb/Interpreter/OptionValueProperties.h"
10061da546Spatrick 
11061da546Spatrick #include "lldb/Utility/Flags.h"
12061da546Spatrick 
13061da546Spatrick #include "lldb/Core/UserSettingsController.h"
14061da546Spatrick #include "lldb/Interpreter/OptionValues.h"
15061da546Spatrick #include "lldb/Interpreter/Property.h"
16061da546Spatrick #include "lldb/Utility/Args.h"
17061da546Spatrick #include "lldb/Utility/Stream.h"
18061da546Spatrick #include "lldb/Utility/StringList.h"
19061da546Spatrick 
20061da546Spatrick using namespace lldb;
21061da546Spatrick using namespace lldb_private;
22061da546Spatrick 
OptionValueProperties(ConstString name)23be691f3bSpatrick OptionValueProperties::OptionValueProperties(ConstString name) : m_name(name) {}
24061da546Spatrick 
GetNumProperties() const25061da546Spatrick size_t OptionValueProperties::GetNumProperties() const {
26061da546Spatrick   return m_properties.size();
27061da546Spatrick }
28061da546Spatrick 
Initialize(const PropertyDefinitions & defs)29061da546Spatrick void OptionValueProperties::Initialize(const PropertyDefinitions &defs) {
30061da546Spatrick   for (const auto &definition : defs) {
31061da546Spatrick     Property property(definition);
32061da546Spatrick     assert(property.IsValid());
33061da546Spatrick     m_name_to_index.Append(ConstString(property.GetName()), m_properties.size());
34061da546Spatrick     property.GetValue()->SetParent(shared_from_this());
35061da546Spatrick     m_properties.push_back(property);
36061da546Spatrick   }
37061da546Spatrick   m_name_to_index.Sort();
38061da546Spatrick }
39061da546Spatrick 
SetValueChangedCallback(uint32_t property_idx,std::function<void ()> callback)40061da546Spatrick void OptionValueProperties::SetValueChangedCallback(
41061da546Spatrick     uint32_t property_idx, std::function<void()> callback) {
42061da546Spatrick   Property *property = ProtectedGetPropertyAtIndex(property_idx);
43061da546Spatrick   if (property)
44061da546Spatrick     property->SetValueChangedCallback(std::move(callback));
45061da546Spatrick }
46061da546Spatrick 
AppendProperty(ConstString name,ConstString desc,bool is_global,const OptionValueSP & value_sp)47061da546Spatrick void OptionValueProperties::AppendProperty(ConstString name,
48061da546Spatrick                                            ConstString desc,
49061da546Spatrick                                            bool is_global,
50061da546Spatrick                                            const OptionValueSP &value_sp) {
51*f6aab3d8Srobert   Property property(name.GetStringRef(), desc.GetStringRef(), is_global,
52*f6aab3d8Srobert                     value_sp);
53061da546Spatrick   m_name_to_index.Append(name, m_properties.size());
54061da546Spatrick   m_properties.push_back(property);
55061da546Spatrick   value_sp->SetParent(shared_from_this());
56061da546Spatrick   m_name_to_index.Sort();
57061da546Spatrick }
58061da546Spatrick 
59061da546Spatrick // bool
60061da546Spatrick // OptionValueProperties::GetQualifiedName (Stream &strm)
61061da546Spatrick //{
62061da546Spatrick //    bool dumped_something = false;
63061da546Spatrick ////    lldb::OptionValuePropertiesSP parent_sp(GetParent ());
64061da546Spatrick ////    if (parent_sp)
65061da546Spatrick ////    {
66061da546Spatrick ////        parent_sp->GetQualifiedName (strm);
67061da546Spatrick ////        strm.PutChar('.');
68061da546Spatrick ////        dumped_something = true;
69061da546Spatrick ////    }
70061da546Spatrick //    if (m_name)
71061da546Spatrick //    {
72061da546Spatrick //        strm << m_name;
73061da546Spatrick //        dumped_something = true;
74061da546Spatrick //    }
75061da546Spatrick //    return dumped_something;
76061da546Spatrick //}
77061da546Spatrick //
78061da546Spatrick lldb::OptionValueSP
GetValueForKey(const ExecutionContext * exe_ctx,ConstString key,bool will_modify) const79061da546Spatrick OptionValueProperties::GetValueForKey(const ExecutionContext *exe_ctx,
80061da546Spatrick                                       ConstString key,
81061da546Spatrick                                       bool will_modify) const {
82061da546Spatrick   lldb::OptionValueSP value_sp;
83061da546Spatrick   size_t idx = m_name_to_index.Find(key, SIZE_MAX);
84061da546Spatrick   if (idx < m_properties.size())
85061da546Spatrick     value_sp = GetPropertyAtIndex(exe_ctx, will_modify, idx)->GetValue();
86061da546Spatrick   return value_sp;
87061da546Spatrick }
88061da546Spatrick 
89061da546Spatrick lldb::OptionValueSP
GetSubValue(const ExecutionContext * exe_ctx,llvm::StringRef name,bool will_modify,Status & error) const90061da546Spatrick OptionValueProperties::GetSubValue(const ExecutionContext *exe_ctx,
91061da546Spatrick                                    llvm::StringRef name, bool will_modify,
92061da546Spatrick                                    Status &error) const {
93061da546Spatrick   lldb::OptionValueSP value_sp;
94061da546Spatrick   if (name.empty())
95061da546Spatrick     return OptionValueSP();
96061da546Spatrick 
97061da546Spatrick   llvm::StringRef sub_name;
98061da546Spatrick   ConstString key;
99061da546Spatrick   size_t key_len = name.find_first_of(".[{");
100061da546Spatrick   if (key_len != llvm::StringRef::npos) {
101061da546Spatrick     key.SetString(name.take_front(key_len));
102061da546Spatrick     sub_name = name.drop_front(key_len);
103061da546Spatrick   } else
104061da546Spatrick     key.SetString(name);
105061da546Spatrick 
106061da546Spatrick   value_sp = GetValueForKey(exe_ctx, key, will_modify);
107061da546Spatrick   if (sub_name.empty() || !value_sp)
108061da546Spatrick     return value_sp;
109061da546Spatrick 
110061da546Spatrick   switch (sub_name[0]) {
111061da546Spatrick   case '.': {
112061da546Spatrick     lldb::OptionValueSP return_val_sp;
113061da546Spatrick     return_val_sp =
114061da546Spatrick         value_sp->GetSubValue(exe_ctx, sub_name.drop_front(), will_modify, error);
115061da546Spatrick     if (!return_val_sp) {
116061da546Spatrick       if (Properties::IsSettingExperimental(sub_name.drop_front())) {
117061da546Spatrick         size_t experimental_len =
118061da546Spatrick             strlen(Properties::GetExperimentalSettingsName());
119061da546Spatrick         if (sub_name[experimental_len + 1] == '.')
120061da546Spatrick           return_val_sp = value_sp->GetSubValue(
121061da546Spatrick               exe_ctx, sub_name.drop_front(experimental_len + 2), will_modify, error);
122061da546Spatrick         // It isn't an error if an experimental setting is not present.
123061da546Spatrick         if (!return_val_sp)
124061da546Spatrick           error.Clear();
125061da546Spatrick       }
126061da546Spatrick     }
127061da546Spatrick     return return_val_sp;
128061da546Spatrick   }
129061da546Spatrick   case '[':
130061da546Spatrick     // Array or dictionary access for subvalues like: "[12]"       -- access
131061da546Spatrick     // 12th array element "['hello']"  -- dictionary access of key named hello
132061da546Spatrick     return value_sp->GetSubValue(exe_ctx, sub_name, will_modify, error);
133061da546Spatrick 
134061da546Spatrick   default:
135061da546Spatrick     value_sp.reset();
136061da546Spatrick     break;
137061da546Spatrick   }
138061da546Spatrick   return value_sp;
139061da546Spatrick }
140061da546Spatrick 
SetSubValue(const ExecutionContext * exe_ctx,VarSetOperationType op,llvm::StringRef name,llvm::StringRef value)141061da546Spatrick Status OptionValueProperties::SetSubValue(const ExecutionContext *exe_ctx,
142061da546Spatrick                                           VarSetOperationType op,
143061da546Spatrick                                           llvm::StringRef name,
144061da546Spatrick                                           llvm::StringRef value) {
145061da546Spatrick   Status error;
146061da546Spatrick   const bool will_modify = true;
147061da546Spatrick   llvm::SmallVector<llvm::StringRef, 8> components;
148061da546Spatrick   name.split(components, '.');
149061da546Spatrick   bool name_contains_experimental = false;
150061da546Spatrick   for (const auto &part : components)
151061da546Spatrick     if (Properties::IsSettingExperimental(part))
152061da546Spatrick       name_contains_experimental = true;
153061da546Spatrick 
154061da546Spatrick   lldb::OptionValueSP value_sp(GetSubValue(exe_ctx, name, will_modify, error));
155061da546Spatrick   if (value_sp)
156061da546Spatrick     error = value_sp->SetValueFromString(value, op);
157061da546Spatrick   else {
158061da546Spatrick     // Don't set an error if the path contained .experimental. - those are
159061da546Spatrick     // allowed to be missing and should silently fail.
160061da546Spatrick     if (!name_contains_experimental && error.AsCString() == nullptr) {
161061da546Spatrick       error.SetErrorStringWithFormat("invalid value path '%s'", name.str().c_str());
162061da546Spatrick     }
163061da546Spatrick   }
164061da546Spatrick   return error;
165061da546Spatrick }
166061da546Spatrick 
167061da546Spatrick uint32_t
GetPropertyIndex(ConstString name) const168061da546Spatrick OptionValueProperties::GetPropertyIndex(ConstString name) const {
169061da546Spatrick   return m_name_to_index.Find(name, SIZE_MAX);
170061da546Spatrick }
171061da546Spatrick 
172061da546Spatrick const Property *
GetProperty(const ExecutionContext * exe_ctx,bool will_modify,ConstString name) const173061da546Spatrick OptionValueProperties::GetProperty(const ExecutionContext *exe_ctx,
174061da546Spatrick                                    bool will_modify,
175061da546Spatrick                                    ConstString name) const {
176061da546Spatrick   return GetPropertyAtIndex(
177061da546Spatrick       exe_ctx, will_modify,
178061da546Spatrick       m_name_to_index.Find(name, SIZE_MAX));
179061da546Spatrick }
180061da546Spatrick 
GetPropertyAtIndex(const ExecutionContext * exe_ctx,bool will_modify,uint32_t idx) const181061da546Spatrick const Property *OptionValueProperties::GetPropertyAtIndex(
182061da546Spatrick     const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const {
183061da546Spatrick   return ProtectedGetPropertyAtIndex(idx);
184061da546Spatrick }
185061da546Spatrick 
GetPropertyValueAtIndex(const ExecutionContext * exe_ctx,bool will_modify,uint32_t idx) const186061da546Spatrick lldb::OptionValueSP OptionValueProperties::GetPropertyValueAtIndex(
187061da546Spatrick     const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const {
188061da546Spatrick   const Property *setting = GetPropertyAtIndex(exe_ctx, will_modify, idx);
189061da546Spatrick   if (setting)
190061da546Spatrick     return setting->GetValue();
191061da546Spatrick   return OptionValueSP();
192061da546Spatrick }
193061da546Spatrick 
194061da546Spatrick OptionValuePathMappings *
GetPropertyAtIndexAsOptionValuePathMappings(const ExecutionContext * exe_ctx,bool will_modify,uint32_t idx) const195061da546Spatrick OptionValueProperties::GetPropertyAtIndexAsOptionValuePathMappings(
196061da546Spatrick     const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const {
197061da546Spatrick   OptionValueSP value_sp(GetPropertyValueAtIndex(exe_ctx, will_modify, idx));
198061da546Spatrick   if (value_sp)
199061da546Spatrick     return value_sp->GetAsPathMappings();
200061da546Spatrick   return nullptr;
201061da546Spatrick }
202061da546Spatrick 
203061da546Spatrick OptionValueFileSpecList *
GetPropertyAtIndexAsOptionValueFileSpecList(const ExecutionContext * exe_ctx,bool will_modify,uint32_t idx) const204061da546Spatrick OptionValueProperties::GetPropertyAtIndexAsOptionValueFileSpecList(
205061da546Spatrick     const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const {
206061da546Spatrick   OptionValueSP value_sp(GetPropertyValueAtIndex(exe_ctx, will_modify, idx));
207061da546Spatrick   if (value_sp)
208061da546Spatrick     return value_sp->GetAsFileSpecList();
209061da546Spatrick   return nullptr;
210061da546Spatrick }
211061da546Spatrick 
GetPropertyAtIndexAsOptionValueArch(const ExecutionContext * exe_ctx,uint32_t idx) const212061da546Spatrick OptionValueArch *OptionValueProperties::GetPropertyAtIndexAsOptionValueArch(
213061da546Spatrick     const ExecutionContext *exe_ctx, uint32_t idx) const {
214061da546Spatrick   const Property *property = GetPropertyAtIndex(exe_ctx, false, idx);
215061da546Spatrick   if (property)
216061da546Spatrick     return property->GetValue()->GetAsArch();
217061da546Spatrick   return nullptr;
218061da546Spatrick }
219061da546Spatrick 
220061da546Spatrick OptionValueLanguage *
GetPropertyAtIndexAsOptionValueLanguage(const ExecutionContext * exe_ctx,uint32_t idx) const221061da546Spatrick OptionValueProperties::GetPropertyAtIndexAsOptionValueLanguage(
222061da546Spatrick     const ExecutionContext *exe_ctx, uint32_t idx) const {
223061da546Spatrick   const Property *property = GetPropertyAtIndex(exe_ctx, false, idx);
224061da546Spatrick   if (property)
225061da546Spatrick     return property->GetValue()->GetAsLanguage();
226061da546Spatrick   return nullptr;
227061da546Spatrick }
228061da546Spatrick 
SetPropertyAtIndexAsLanguage(const ExecutionContext * exe_ctx,uint32_t idx,const LanguageType lang)229*f6aab3d8Srobert bool OptionValueProperties::SetPropertyAtIndexAsLanguage(
230*f6aab3d8Srobert     const ExecutionContext *exe_ctx, uint32_t idx, const LanguageType lang) {
231*f6aab3d8Srobert   const Property *property = GetPropertyAtIndex(exe_ctx, true, idx);
232*f6aab3d8Srobert   if (property) {
233*f6aab3d8Srobert     OptionValue *value = property->GetValue().get();
234*f6aab3d8Srobert     if (value)
235*f6aab3d8Srobert       return value->SetLanguageValue(lang);
236*f6aab3d8Srobert   }
237*f6aab3d8Srobert   return false;
238*f6aab3d8Srobert }
239*f6aab3d8Srobert 
GetPropertyAtIndexAsArgs(const ExecutionContext * exe_ctx,uint32_t idx,Args & args) const240061da546Spatrick bool OptionValueProperties::GetPropertyAtIndexAsArgs(
241061da546Spatrick     const ExecutionContext *exe_ctx, uint32_t idx, Args &args) const {
242061da546Spatrick   const Property *property = GetPropertyAtIndex(exe_ctx, false, idx);
243be691f3bSpatrick   if (!property)
244be691f3bSpatrick     return false;
245be691f3bSpatrick 
246061da546Spatrick   OptionValue *value = property->GetValue().get();
247be691f3bSpatrick   if (!value)
248be691f3bSpatrick     return false;
249be691f3bSpatrick 
250be691f3bSpatrick   const OptionValueArgs *arguments = value->GetAsArgs();
251*f6aab3d8Srobert   if (arguments) {
252*f6aab3d8Srobert     arguments->GetArgs(args);
253*f6aab3d8Srobert     return true;
254*f6aab3d8Srobert   }
255be691f3bSpatrick 
256061da546Spatrick   const OptionValueArray *array = value->GetAsArray();
257*f6aab3d8Srobert   if (array) {
258*f6aab3d8Srobert     array->GetArgs(args);
259*f6aab3d8Srobert     return true;
260*f6aab3d8Srobert   }
261be691f3bSpatrick 
262061da546Spatrick   const OptionValueDictionary *dict = value->GetAsDictionary();
263*f6aab3d8Srobert   if (dict) {
264*f6aab3d8Srobert     dict->GetArgs(args);
265*f6aab3d8Srobert     return true;
266*f6aab3d8Srobert   }
267be691f3bSpatrick 
268061da546Spatrick   return false;
269061da546Spatrick }
270061da546Spatrick 
SetPropertyAtIndexFromArgs(const ExecutionContext * exe_ctx,uint32_t idx,const Args & args)271061da546Spatrick bool OptionValueProperties::SetPropertyAtIndexFromArgs(
272061da546Spatrick     const ExecutionContext *exe_ctx, uint32_t idx, const Args &args) {
273061da546Spatrick   const Property *property = GetPropertyAtIndex(exe_ctx, true, idx);
274be691f3bSpatrick   if (!property)
275be691f3bSpatrick     return false;
276be691f3bSpatrick 
277061da546Spatrick   OptionValue *value = property->GetValue().get();
278be691f3bSpatrick   if (!value)
279be691f3bSpatrick     return false;
280be691f3bSpatrick 
281be691f3bSpatrick   OptionValueArgs *arguments = value->GetAsArgs();
282be691f3bSpatrick   if (arguments)
283be691f3bSpatrick     return arguments->SetArgs(args, eVarSetOperationAssign).Success();
284be691f3bSpatrick 
285061da546Spatrick   OptionValueArray *array = value->GetAsArray();
286061da546Spatrick   if (array)
287061da546Spatrick     return array->SetArgs(args, eVarSetOperationAssign).Success();
288be691f3bSpatrick 
289061da546Spatrick   OptionValueDictionary *dict = value->GetAsDictionary();
290061da546Spatrick   if (dict)
291061da546Spatrick     return dict->SetArgs(args, eVarSetOperationAssign).Success();
292be691f3bSpatrick 
293061da546Spatrick   return false;
294061da546Spatrick }
295061da546Spatrick 
GetPropertyAtIndexAsBoolean(const ExecutionContext * exe_ctx,uint32_t idx,bool fail_value) const296061da546Spatrick bool OptionValueProperties::GetPropertyAtIndexAsBoolean(
297061da546Spatrick     const ExecutionContext *exe_ctx, uint32_t idx, bool fail_value) const {
298061da546Spatrick   const Property *property = GetPropertyAtIndex(exe_ctx, false, idx);
299061da546Spatrick   if (property) {
300061da546Spatrick     OptionValue *value = property->GetValue().get();
301061da546Spatrick     if (value)
302061da546Spatrick       return value->GetBooleanValue(fail_value);
303061da546Spatrick   }
304061da546Spatrick   return fail_value;
305061da546Spatrick }
306061da546Spatrick 
SetPropertyAtIndexAsBoolean(const ExecutionContext * exe_ctx,uint32_t idx,bool new_value)307061da546Spatrick bool OptionValueProperties::SetPropertyAtIndexAsBoolean(
308061da546Spatrick     const ExecutionContext *exe_ctx, uint32_t idx, bool new_value) {
309061da546Spatrick   const Property *property = GetPropertyAtIndex(exe_ctx, true, idx);
310061da546Spatrick   if (property) {
311061da546Spatrick     OptionValue *value = property->GetValue().get();
312061da546Spatrick     if (value) {
313061da546Spatrick       value->SetBooleanValue(new_value);
314061da546Spatrick       return true;
315061da546Spatrick     }
316061da546Spatrick   }
317061da546Spatrick   return false;
318061da546Spatrick }
319061da546Spatrick 
320061da546Spatrick OptionValueDictionary *
GetPropertyAtIndexAsOptionValueDictionary(const ExecutionContext * exe_ctx,uint32_t idx) const321061da546Spatrick OptionValueProperties::GetPropertyAtIndexAsOptionValueDictionary(
322061da546Spatrick     const ExecutionContext *exe_ctx, uint32_t idx) const {
323061da546Spatrick   const Property *property = GetPropertyAtIndex(exe_ctx, false, idx);
324061da546Spatrick   if (property)
325061da546Spatrick     return property->GetValue()->GetAsDictionary();
326061da546Spatrick   return nullptr;
327061da546Spatrick }
328061da546Spatrick 
GetPropertyAtIndexAsEnumeration(const ExecutionContext * exe_ctx,uint32_t idx,int64_t fail_value) const329061da546Spatrick int64_t OptionValueProperties::GetPropertyAtIndexAsEnumeration(
330061da546Spatrick     const ExecutionContext *exe_ctx, uint32_t idx, int64_t fail_value) const {
331061da546Spatrick   const Property *property = GetPropertyAtIndex(exe_ctx, false, idx);
332061da546Spatrick   if (property) {
333061da546Spatrick     OptionValue *value = property->GetValue().get();
334061da546Spatrick     if (value)
335061da546Spatrick       return value->GetEnumerationValue(fail_value);
336061da546Spatrick   }
337061da546Spatrick   return fail_value;
338061da546Spatrick }
339061da546Spatrick 
SetPropertyAtIndexAsEnumeration(const ExecutionContext * exe_ctx,uint32_t idx,int64_t new_value)340061da546Spatrick bool OptionValueProperties::SetPropertyAtIndexAsEnumeration(
341061da546Spatrick     const ExecutionContext *exe_ctx, uint32_t idx, int64_t new_value) {
342061da546Spatrick   const Property *property = GetPropertyAtIndex(exe_ctx, true, idx);
343061da546Spatrick   if (property) {
344061da546Spatrick     OptionValue *value = property->GetValue().get();
345061da546Spatrick     if (value)
346061da546Spatrick       return value->SetEnumerationValue(new_value);
347061da546Spatrick   }
348061da546Spatrick   return false;
349061da546Spatrick }
350061da546Spatrick 
351061da546Spatrick const FormatEntity::Entry *
GetPropertyAtIndexAsFormatEntity(const ExecutionContext * exe_ctx,uint32_t idx)352061da546Spatrick OptionValueProperties::GetPropertyAtIndexAsFormatEntity(
353061da546Spatrick     const ExecutionContext *exe_ctx, uint32_t idx) {
354061da546Spatrick   const Property *property = GetPropertyAtIndex(exe_ctx, true, idx);
355061da546Spatrick   if (property) {
356061da546Spatrick     OptionValue *value = property->GetValue().get();
357061da546Spatrick     if (value)
358061da546Spatrick       return value->GetFormatEntity();
359061da546Spatrick   }
360061da546Spatrick   return nullptr;
361061da546Spatrick }
362061da546Spatrick 
363061da546Spatrick OptionValueFileSpec *
GetPropertyAtIndexAsOptionValueFileSpec(const ExecutionContext * exe_ctx,bool will_modify,uint32_t idx) const364061da546Spatrick OptionValueProperties::GetPropertyAtIndexAsOptionValueFileSpec(
365061da546Spatrick     const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const {
366061da546Spatrick   const Property *property = GetPropertyAtIndex(exe_ctx, false, idx);
367061da546Spatrick   if (property) {
368061da546Spatrick     OptionValue *value = property->GetValue().get();
369061da546Spatrick     if (value)
370061da546Spatrick       return value->GetAsFileSpec();
371061da546Spatrick   }
372061da546Spatrick   return nullptr;
373061da546Spatrick }
374061da546Spatrick 
GetPropertyAtIndexAsFileSpec(const ExecutionContext * exe_ctx,uint32_t idx) const375061da546Spatrick FileSpec OptionValueProperties::GetPropertyAtIndexAsFileSpec(
376061da546Spatrick     const ExecutionContext *exe_ctx, uint32_t idx) const {
377061da546Spatrick   const Property *property = GetPropertyAtIndex(exe_ctx, false, idx);
378061da546Spatrick   if (property) {
379061da546Spatrick     OptionValue *value = property->GetValue().get();
380061da546Spatrick     if (value)
381061da546Spatrick       return value->GetFileSpecValue();
382061da546Spatrick   }
383061da546Spatrick   return FileSpec();
384061da546Spatrick }
385061da546Spatrick 
SetPropertyAtIndexAsFileSpec(const ExecutionContext * exe_ctx,uint32_t idx,const FileSpec & new_file_spec)386061da546Spatrick bool OptionValueProperties::SetPropertyAtIndexAsFileSpec(
387061da546Spatrick     const ExecutionContext *exe_ctx, uint32_t idx,
388061da546Spatrick     const FileSpec &new_file_spec) {
389061da546Spatrick   const Property *property = GetPropertyAtIndex(exe_ctx, true, idx);
390061da546Spatrick   if (property) {
391061da546Spatrick     OptionValue *value = property->GetValue().get();
392061da546Spatrick     if (value)
393061da546Spatrick       return value->SetFileSpecValue(new_file_spec);
394061da546Spatrick   }
395061da546Spatrick   return false;
396061da546Spatrick }
397061da546Spatrick 
398061da546Spatrick const RegularExpression *
GetPropertyAtIndexAsOptionValueRegex(const ExecutionContext * exe_ctx,uint32_t idx) const399061da546Spatrick OptionValueProperties::GetPropertyAtIndexAsOptionValueRegex(
400061da546Spatrick     const ExecutionContext *exe_ctx, uint32_t idx) const {
401061da546Spatrick   const Property *property = GetPropertyAtIndex(exe_ctx, false, idx);
402061da546Spatrick   if (property) {
403061da546Spatrick     OptionValue *value = property->GetValue().get();
404061da546Spatrick     if (value)
405061da546Spatrick       return value->GetRegexValue();
406061da546Spatrick   }
407061da546Spatrick   return nullptr;
408061da546Spatrick }
409061da546Spatrick 
GetPropertyAtIndexAsOptionValueSInt64(const ExecutionContext * exe_ctx,uint32_t idx) const410061da546Spatrick OptionValueSInt64 *OptionValueProperties::GetPropertyAtIndexAsOptionValueSInt64(
411061da546Spatrick     const ExecutionContext *exe_ctx, uint32_t idx) const {
412061da546Spatrick   const Property *property = GetPropertyAtIndex(exe_ctx, false, idx);
413061da546Spatrick   if (property) {
414061da546Spatrick     OptionValue *value = property->GetValue().get();
415061da546Spatrick     if (value)
416061da546Spatrick       return value->GetAsSInt64();
417061da546Spatrick   }
418061da546Spatrick   return nullptr;
419061da546Spatrick }
420061da546Spatrick 
GetPropertyAtIndexAsOptionValueUInt64(const ExecutionContext * exe_ctx,uint32_t idx) const421*f6aab3d8Srobert OptionValueUInt64 *OptionValueProperties::GetPropertyAtIndexAsOptionValueUInt64(
422*f6aab3d8Srobert     const ExecutionContext *exe_ctx, uint32_t idx) const {
423*f6aab3d8Srobert   const Property *property = GetPropertyAtIndex(exe_ctx, false, idx);
424*f6aab3d8Srobert   if (property) {
425*f6aab3d8Srobert     OptionValue *value = property->GetValue().get();
426*f6aab3d8Srobert     if (value)
427*f6aab3d8Srobert       return value->GetAsUInt64();
428*f6aab3d8Srobert   }
429*f6aab3d8Srobert   return nullptr;
430*f6aab3d8Srobert }
431*f6aab3d8Srobert 
GetPropertyAtIndexAsSInt64(const ExecutionContext * exe_ctx,uint32_t idx,int64_t fail_value) const432061da546Spatrick int64_t OptionValueProperties::GetPropertyAtIndexAsSInt64(
433061da546Spatrick     const ExecutionContext *exe_ctx, uint32_t idx, int64_t fail_value) const {
434061da546Spatrick   const Property *property = GetPropertyAtIndex(exe_ctx, false, idx);
435061da546Spatrick   if (property) {
436061da546Spatrick     OptionValue *value = property->GetValue().get();
437061da546Spatrick     if (value)
438061da546Spatrick       return value->GetSInt64Value(fail_value);
439061da546Spatrick   }
440061da546Spatrick   return fail_value;
441061da546Spatrick }
442061da546Spatrick 
SetPropertyAtIndexAsSInt64(const ExecutionContext * exe_ctx,uint32_t idx,int64_t new_value)443061da546Spatrick bool OptionValueProperties::SetPropertyAtIndexAsSInt64(
444061da546Spatrick     const ExecutionContext *exe_ctx, uint32_t idx, int64_t new_value) {
445061da546Spatrick   const Property *property = GetPropertyAtIndex(exe_ctx, true, idx);
446061da546Spatrick   if (property) {
447061da546Spatrick     OptionValue *value = property->GetValue().get();
448061da546Spatrick     if (value)
449061da546Spatrick       return value->SetSInt64Value(new_value);
450061da546Spatrick   }
451061da546Spatrick   return false;
452061da546Spatrick }
453061da546Spatrick 
GetPropertyAtIndexAsString(const ExecutionContext * exe_ctx,uint32_t idx,llvm::StringRef fail_value) const454061da546Spatrick llvm::StringRef OptionValueProperties::GetPropertyAtIndexAsString(
455061da546Spatrick     const ExecutionContext *exe_ctx, uint32_t idx,
456061da546Spatrick     llvm::StringRef fail_value) const {
457061da546Spatrick   const Property *property = GetPropertyAtIndex(exe_ctx, false, idx);
458061da546Spatrick   if (property) {
459061da546Spatrick     OptionValue *value = property->GetValue().get();
460061da546Spatrick     if (value)
461061da546Spatrick       return value->GetStringValue(fail_value);
462061da546Spatrick   }
463061da546Spatrick   return fail_value;
464061da546Spatrick }
465061da546Spatrick 
SetPropertyAtIndexAsString(const ExecutionContext * exe_ctx,uint32_t idx,llvm::StringRef new_value)466061da546Spatrick bool OptionValueProperties::SetPropertyAtIndexAsString(
467061da546Spatrick     const ExecutionContext *exe_ctx, uint32_t idx, llvm::StringRef new_value) {
468061da546Spatrick   const Property *property = GetPropertyAtIndex(exe_ctx, true, idx);
469061da546Spatrick   if (property) {
470061da546Spatrick     OptionValue *value = property->GetValue().get();
471061da546Spatrick     if (value)
472061da546Spatrick       return value->SetStringValue(new_value);
473061da546Spatrick   }
474061da546Spatrick   return false;
475061da546Spatrick }
476061da546Spatrick 
GetPropertyAtIndexAsOptionValueString(const ExecutionContext * exe_ctx,bool will_modify,uint32_t idx) const477061da546Spatrick OptionValueString *OptionValueProperties::GetPropertyAtIndexAsOptionValueString(
478061da546Spatrick     const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const {
479061da546Spatrick   OptionValueSP value_sp(GetPropertyValueAtIndex(exe_ctx, will_modify, idx));
480061da546Spatrick   if (value_sp)
481061da546Spatrick     return value_sp->GetAsString();
482061da546Spatrick   return nullptr;
483061da546Spatrick }
484061da546Spatrick 
GetPropertyAtIndexAsUInt64(const ExecutionContext * exe_ctx,uint32_t idx,uint64_t fail_value) const485061da546Spatrick uint64_t OptionValueProperties::GetPropertyAtIndexAsUInt64(
486061da546Spatrick     const ExecutionContext *exe_ctx, uint32_t idx, uint64_t fail_value) const {
487061da546Spatrick   const Property *property = GetPropertyAtIndex(exe_ctx, false, idx);
488061da546Spatrick   if (property) {
489061da546Spatrick     OptionValue *value = property->GetValue().get();
490061da546Spatrick     if (value)
491061da546Spatrick       return value->GetUInt64Value(fail_value);
492061da546Spatrick   }
493061da546Spatrick   return fail_value;
494061da546Spatrick }
495061da546Spatrick 
SetPropertyAtIndexAsUInt64(const ExecutionContext * exe_ctx,uint32_t idx,uint64_t new_value)496061da546Spatrick bool OptionValueProperties::SetPropertyAtIndexAsUInt64(
497061da546Spatrick     const ExecutionContext *exe_ctx, uint32_t idx, uint64_t new_value) {
498061da546Spatrick   const Property *property = GetPropertyAtIndex(exe_ctx, true, idx);
499061da546Spatrick   if (property) {
500061da546Spatrick     OptionValue *value = property->GetValue().get();
501061da546Spatrick     if (value)
502061da546Spatrick       return value->SetUInt64Value(new_value);
503061da546Spatrick   }
504061da546Spatrick   return false;
505061da546Spatrick }
506061da546Spatrick 
Clear()507be691f3bSpatrick void OptionValueProperties::Clear() {
508061da546Spatrick   const size_t num_properties = m_properties.size();
509061da546Spatrick   for (size_t i = 0; i < num_properties; ++i)
510061da546Spatrick     m_properties[i].GetValue()->Clear();
511061da546Spatrick }
512061da546Spatrick 
SetValueFromString(llvm::StringRef value,VarSetOperationType op)513061da546Spatrick Status OptionValueProperties::SetValueFromString(llvm::StringRef value,
514061da546Spatrick                                                  VarSetOperationType op) {
515061da546Spatrick   Status error;
516061da546Spatrick 
517061da546Spatrick   //    Args args(value_cstr);
518061da546Spatrick   //    const size_t argc = args.GetArgumentCount();
519061da546Spatrick   switch (op) {
520061da546Spatrick   case eVarSetOperationClear:
521061da546Spatrick     Clear();
522061da546Spatrick     break;
523061da546Spatrick 
524061da546Spatrick   case eVarSetOperationReplace:
525061da546Spatrick   case eVarSetOperationAssign:
526061da546Spatrick   case eVarSetOperationRemove:
527061da546Spatrick   case eVarSetOperationInsertBefore:
528061da546Spatrick   case eVarSetOperationInsertAfter:
529061da546Spatrick   case eVarSetOperationAppend:
530061da546Spatrick   case eVarSetOperationInvalid:
531061da546Spatrick     error = OptionValue::SetValueFromString(value, op);
532061da546Spatrick     break;
533061da546Spatrick   }
534061da546Spatrick 
535061da546Spatrick   return error;
536061da546Spatrick }
537061da546Spatrick 
DumpValue(const ExecutionContext * exe_ctx,Stream & strm,uint32_t dump_mask)538061da546Spatrick void OptionValueProperties::DumpValue(const ExecutionContext *exe_ctx,
539061da546Spatrick                                       Stream &strm, uint32_t dump_mask) {
540061da546Spatrick   const size_t num_properties = m_properties.size();
541061da546Spatrick   for (size_t i = 0; i < num_properties; ++i) {
542061da546Spatrick     const Property *property = GetPropertyAtIndex(exe_ctx, false, i);
543061da546Spatrick     if (property) {
544061da546Spatrick       OptionValue *option_value = property->GetValue().get();
545061da546Spatrick       assert(option_value);
546061da546Spatrick       const bool transparent_value = option_value->ValueIsTransparent();
547061da546Spatrick       property->Dump(exe_ctx, strm, dump_mask);
548061da546Spatrick       if (!transparent_value)
549061da546Spatrick         strm.EOL();
550061da546Spatrick     }
551061da546Spatrick   }
552061da546Spatrick }
553061da546Spatrick 
554*f6aab3d8Srobert llvm::json::Value
ToJSON(const ExecutionContext * exe_ctx)555*f6aab3d8Srobert OptionValueProperties::ToJSON(const ExecutionContext *exe_ctx) {
556*f6aab3d8Srobert   llvm::json::Object json_properties;
557*f6aab3d8Srobert   const size_t num_properties = m_properties.size();
558*f6aab3d8Srobert   for (size_t i = 0; i < num_properties; ++i) {
559*f6aab3d8Srobert     const Property *property = GetPropertyAtIndex(exe_ctx, false, i);
560*f6aab3d8Srobert     if (property) {
561*f6aab3d8Srobert       OptionValue *option_value = property->GetValue().get();
562*f6aab3d8Srobert       assert(option_value);
563*f6aab3d8Srobert       json_properties.try_emplace(property->GetName(),
564*f6aab3d8Srobert                                   option_value->ToJSON(exe_ctx));
565*f6aab3d8Srobert     }
566*f6aab3d8Srobert   }
567*f6aab3d8Srobert   return json_properties;
568*f6aab3d8Srobert }
569*f6aab3d8Srobert 
DumpPropertyValue(const ExecutionContext * exe_ctx,Stream & strm,llvm::StringRef property_path,uint32_t dump_mask,bool is_json)570061da546Spatrick Status OptionValueProperties::DumpPropertyValue(const ExecutionContext *exe_ctx,
571061da546Spatrick                                                 Stream &strm,
572061da546Spatrick                                                 llvm::StringRef property_path,
573*f6aab3d8Srobert                                                 uint32_t dump_mask, bool is_json) {
574061da546Spatrick   Status error;
575061da546Spatrick   const bool will_modify = false;
576061da546Spatrick   lldb::OptionValueSP value_sp(
577061da546Spatrick       GetSubValue(exe_ctx, property_path, will_modify, error));
578061da546Spatrick   if (value_sp) {
579061da546Spatrick     if (!value_sp->ValueIsTransparent()) {
580061da546Spatrick       if (dump_mask & eDumpOptionName)
581061da546Spatrick         strm.PutCString(property_path);
582061da546Spatrick       if (dump_mask & ~eDumpOptionName)
583061da546Spatrick         strm.PutChar(' ');
584061da546Spatrick     }
585*f6aab3d8Srobert     if (is_json) {
586*f6aab3d8Srobert       strm.Printf("%s", llvm::formatv("{0:2}", value_sp->ToJSON(exe_ctx)).str().c_str());
587*f6aab3d8Srobert     } else
588061da546Spatrick       value_sp->DumpValue(exe_ctx, strm, dump_mask);
589061da546Spatrick   }
590061da546Spatrick   return error;
591061da546Spatrick }
592061da546Spatrick 
593be691f3bSpatrick OptionValuePropertiesSP
CreateLocalCopy(const Properties & global_properties)594be691f3bSpatrick OptionValueProperties::CreateLocalCopy(const Properties &global_properties) {
595be691f3bSpatrick   auto global_props_sp = global_properties.GetValueProperties();
596be691f3bSpatrick   lldbassert(global_props_sp);
597be691f3bSpatrick 
598be691f3bSpatrick   auto copy_sp = global_props_sp->DeepCopy(global_props_sp->GetParent());
599be691f3bSpatrick   return std::static_pointer_cast<OptionValueProperties>(copy_sp);
600be691f3bSpatrick }
601be691f3bSpatrick 
602be691f3bSpatrick OptionValueSP
DeepCopy(const OptionValueSP & new_parent) const603be691f3bSpatrick OptionValueProperties::DeepCopy(const OptionValueSP &new_parent) const {
604be691f3bSpatrick   auto copy_sp = OptionValue::DeepCopy(new_parent);
605be691f3bSpatrick   // copy_sp->GetAsProperties cannot be used here as it doesn't work for derived
606be691f3bSpatrick   // types that override GetType returning a different value.
607be691f3bSpatrick   auto *props_value_ptr = static_cast<OptionValueProperties *>(copy_sp.get());
608be691f3bSpatrick   lldbassert(props_value_ptr);
609be691f3bSpatrick 
610be691f3bSpatrick   for (auto &property : props_value_ptr->m_properties) {
611be691f3bSpatrick     // Duplicate any values that are not global when constructing properties
612be691f3bSpatrick     // from a global copy.
613be691f3bSpatrick     if (!property.IsGlobal()) {
614be691f3bSpatrick       auto value_sp = property.GetValue()->DeepCopy(copy_sp);
615be691f3bSpatrick       property.SetOptionValue(value_sp);
616be691f3bSpatrick     }
617be691f3bSpatrick   }
618be691f3bSpatrick   return copy_sp;
619061da546Spatrick }
620061da546Spatrick 
GetPropertyAtPath(const ExecutionContext * exe_ctx,bool will_modify,llvm::StringRef name) const621061da546Spatrick const Property *OptionValueProperties::GetPropertyAtPath(
622061da546Spatrick     const ExecutionContext *exe_ctx, bool will_modify, llvm::StringRef name) const {
623061da546Spatrick   const Property *property = nullptr;
624061da546Spatrick   if (name.empty())
625061da546Spatrick     return nullptr;
626061da546Spatrick   llvm::StringRef sub_name;
627061da546Spatrick   ConstString key;
628061da546Spatrick   size_t key_len = name.find_first_of(".[{");
629061da546Spatrick 
630061da546Spatrick   if (key_len != llvm::StringRef::npos) {
631061da546Spatrick     key.SetString(name.take_front(key_len));
632061da546Spatrick     sub_name = name.drop_front(key_len);
633061da546Spatrick   } else
634061da546Spatrick     key.SetString(name);
635061da546Spatrick 
636061da546Spatrick   property = GetProperty(exe_ctx, will_modify, key);
637061da546Spatrick   if (sub_name.empty() || !property)
638061da546Spatrick     return property;
639061da546Spatrick 
640061da546Spatrick   if (sub_name[0] == '.') {
641061da546Spatrick     OptionValueProperties *sub_properties =
642061da546Spatrick         property->GetValue()->GetAsProperties();
643061da546Spatrick     if (sub_properties)
644061da546Spatrick       return sub_properties->GetPropertyAtPath(exe_ctx, will_modify,
645061da546Spatrick                                                 sub_name.drop_front());
646061da546Spatrick   }
647061da546Spatrick   return nullptr;
648061da546Spatrick }
649061da546Spatrick 
DumpAllDescriptions(CommandInterpreter & interpreter,Stream & strm) const650061da546Spatrick void OptionValueProperties::DumpAllDescriptions(CommandInterpreter &interpreter,
651061da546Spatrick                                                 Stream &strm) const {
652061da546Spatrick   size_t max_name_len = 0;
653061da546Spatrick   const size_t num_properties = m_properties.size();
654061da546Spatrick   for (size_t i = 0; i < num_properties; ++i) {
655061da546Spatrick     const Property *property = ProtectedGetPropertyAtIndex(i);
656061da546Spatrick     if (property)
657061da546Spatrick       max_name_len = std::max<size_t>(property->GetName().size(), max_name_len);
658061da546Spatrick   }
659061da546Spatrick   for (size_t i = 0; i < num_properties; ++i) {
660061da546Spatrick     const Property *property = ProtectedGetPropertyAtIndex(i);
661061da546Spatrick     if (property)
662061da546Spatrick       property->DumpDescription(interpreter, strm, max_name_len, false);
663061da546Spatrick   }
664061da546Spatrick }
665061da546Spatrick 
Apropos(llvm::StringRef keyword,std::vector<const Property * > & matching_properties) const666061da546Spatrick void OptionValueProperties::Apropos(
667061da546Spatrick     llvm::StringRef keyword,
668061da546Spatrick     std::vector<const Property *> &matching_properties) const {
669061da546Spatrick   const size_t num_properties = m_properties.size();
670061da546Spatrick   StreamString strm;
671061da546Spatrick   for (size_t i = 0; i < num_properties; ++i) {
672061da546Spatrick     const Property *property = ProtectedGetPropertyAtIndex(i);
673061da546Spatrick     if (property) {
674061da546Spatrick       const OptionValueProperties *properties =
675061da546Spatrick           property->GetValue()->GetAsProperties();
676061da546Spatrick       if (properties) {
677061da546Spatrick         properties->Apropos(keyword, matching_properties);
678061da546Spatrick       } else {
679061da546Spatrick         bool match = false;
680061da546Spatrick         llvm::StringRef name = property->GetName();
681be691f3bSpatrick         if (name.contains_insensitive(keyword))
682061da546Spatrick           match = true;
683061da546Spatrick         else {
684061da546Spatrick           llvm::StringRef desc = property->GetDescription();
685be691f3bSpatrick           if (desc.contains_insensitive(keyword))
686061da546Spatrick             match = true;
687061da546Spatrick         }
688061da546Spatrick         if (match) {
689061da546Spatrick           matching_properties.push_back(property);
690061da546Spatrick         }
691061da546Spatrick       }
692061da546Spatrick     }
693061da546Spatrick   }
694061da546Spatrick }
695061da546Spatrick 
696061da546Spatrick lldb::OptionValuePropertiesSP
GetSubProperty(const ExecutionContext * exe_ctx,ConstString name)697061da546Spatrick OptionValueProperties::GetSubProperty(const ExecutionContext *exe_ctx,
698061da546Spatrick                                       ConstString name) {
699061da546Spatrick   lldb::OptionValueSP option_value_sp(GetValueForKey(exe_ctx, name, false));
700061da546Spatrick   if (option_value_sp) {
701061da546Spatrick     OptionValueProperties *ov_properties = option_value_sp->GetAsProperties();
702061da546Spatrick     if (ov_properties)
703061da546Spatrick       return ov_properties->shared_from_this();
704061da546Spatrick   }
705061da546Spatrick   return lldb::OptionValuePropertiesSP();
706061da546Spatrick }
707