blob: 7e4df3a3e1d2ed0d88478e1be9c7120f163e62fb [file] [log] [blame]
Zachary Turner067d1db2016-11-16 21:45:04 +00001//===-- OptionValueProperties.cpp --------------------------------*- C++-*-===//
Greg Clayton67cc0632012-08-22 17:17:09 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "lldb/Interpreter/OptionValueProperties.h"
11
12// C Includes
13// C++ Includes
14// Other libraries and framework includes
15// Project 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"
23
24using namespace lldb;
25using namespace lldb_private;
26
Kate Stoneb9c1b512016-09-06 20:57:50 +000027OptionValueProperties::OptionValueProperties(const ConstString &name)
28 : OptionValue(), m_name(name), m_properties(), m_name_to_index() {}
Greg Clayton67cc0632012-08-22 17:17:09 +000029
Kate Stoneb9c1b512016-09-06 20:57:50 +000030OptionValueProperties::OptionValueProperties(
31 const OptionValueProperties &global_properties)
32 : OptionValue(global_properties),
33 std::enable_shared_from_this<OptionValueProperties>(),
34 m_name(global_properties.m_name),
35 m_properties(global_properties.m_properties),
36 m_name_to_index(global_properties.m_name_to_index) {
37 // We now have an exact copy of "global_properties". We need to now
38 // find all non-global settings and copy the property values so that
39 // all non-global settings get new OptionValue instances created for
40 // them.
41 const size_t num_properties = m_properties.size();
42 for (size_t i = 0; i < num_properties; ++i) {
43 // Duplicate any values that are not global when constructing properties
44 // from
45 // a global copy
46 if (m_properties[i].IsGlobal() == false) {
47 lldb::OptionValueSP new_value_sp(m_properties[i].GetValue()->DeepCopy());
48 m_properties[i].SetOptionValue(new_value_sp);
Greg Clayton67cc0632012-08-22 17:17:09 +000049 }
Kate Stoneb9c1b512016-09-06 20:57:50 +000050 }
Greg Clayton67cc0632012-08-22 17:17:09 +000051}
52
Kate Stoneb9c1b512016-09-06 20:57:50 +000053size_t OptionValueProperties::GetNumProperties() const {
54 return m_properties.size();
Greg Clayton67cc0632012-08-22 17:17:09 +000055}
56
Kate Stoneb9c1b512016-09-06 20:57:50 +000057void OptionValueProperties::Initialize(const PropertyDefinition *defs) {
58 for (size_t i = 0; defs[i].name; ++i) {
59 Property property(defs[i]);
60 assert(property.IsValid());
Zachary Turnere6f6d4c2016-11-15 23:36:43 +000061 m_name_to_index.Append(property.GetName(), m_properties.size());
Kate Stoneb9c1b512016-09-06 20:57:50 +000062 property.GetValue()->SetParent(shared_from_this());
Greg Clayton67cc0632012-08-22 17:17:09 +000063 m_properties.push_back(property);
Kate Stoneb9c1b512016-09-06 20:57:50 +000064 }
65 m_name_to_index.Sort();
Greg Clayton67cc0632012-08-22 17:17:09 +000066}
67
Kate Stoneb9c1b512016-09-06 20:57:50 +000068void OptionValueProperties::SetValueChangedCallback(
69 uint32_t property_idx, OptionValueChangedCallback callback, void *baton) {
70 Property *property = ProtectedGetPropertyAtIndex(property_idx);
71 if (property)
72 property->SetValueChangedCallback(callback, baton);
73}
Greg Clayton67cc0632012-08-22 17:17:09 +000074
Kate Stoneb9c1b512016-09-06 20:57:50 +000075void OptionValueProperties::AppendProperty(const ConstString &name,
76 const ConstString &desc,
77 bool is_global,
78 const OptionValueSP &value_sp) {
79 Property property(name, desc, is_global, value_sp);
Zachary Turner4fa098a2016-10-06 21:22:44 +000080 m_name_to_index.Append(name.GetStringRef(), m_properties.size());
Kate Stoneb9c1b512016-09-06 20:57:50 +000081 m_properties.push_back(property);
82 value_sp->SetParent(shared_from_this());
83 m_name_to_index.Sort();
84}
Greg Clayton67cc0632012-08-22 17:17:09 +000085
Kate Stoneb9c1b512016-09-06 20:57:50 +000086// bool
87// OptionValueProperties::GetQualifiedName (Stream &strm)
Greg Clayton67cc0632012-08-22 17:17:09 +000088//{
89// bool dumped_something = false;
90//// lldb::OptionValuePropertiesSP parent_sp(GetParent ());
91//// if (parent_sp)
92//// {
93//// parent_sp->GetQualifiedName (strm);
94//// strm.PutChar('.');
95//// dumped_something = true;
96//// }
97// if (m_name)
98// {
99// strm << m_name;
100// dumped_something = true;
101// }
102// return dumped_something;
103//}
104//
105lldb::OptionValueSP
Kate Stoneb9c1b512016-09-06 20:57:50 +0000106OptionValueProperties::GetValueForKey(const ExecutionContext *exe_ctx,
107 const ConstString &key,
108 bool will_modify) const {
109 lldb::OptionValueSP value_sp;
Zachary Turner4fa098a2016-10-06 21:22:44 +0000110 size_t idx = m_name_to_index.Find(key.GetStringRef(), SIZE_MAX);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000111 if (idx < m_properties.size())
112 value_sp = GetPropertyAtIndex(exe_ctx, will_modify, idx)->GetValue();
113 return value_sp;
Greg Clayton67cc0632012-08-22 17:17:09 +0000114}
115
116lldb::OptionValueSP
Kate Stoneb9c1b512016-09-06 20:57:50 +0000117OptionValueProperties::GetSubValue(const ExecutionContext *exe_ctx,
Zachary Turner31d97a52016-11-17 18:08:12 +0000118 llvm::StringRef name, bool will_modify,
Kate Stoneb9c1b512016-09-06 20:57:50 +0000119 Error &error) const {
120 lldb::OptionValueSP value_sp;
Zachary Turner31d97a52016-11-17 18:08:12 +0000121 if (name.empty())
122 return OptionValueSP();
Greg Clayton67cc0632012-08-22 17:17:09 +0000123
Zachary Turner31d97a52016-11-17 18:08:12 +0000124 llvm::StringRef sub_name;
125 ConstString key;
126 size_t key_len = name.find_first_of(".[{");
127 if (key_len != llvm::StringRef::npos) {
128 key.SetString(name.take_front(key_len));
129 sub_name = name.drop_front(key_len);
130 } else
131 key.SetString(name);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000132
Zachary Turner31d97a52016-11-17 18:08:12 +0000133 value_sp = GetValueForKey(exe_ctx, key, will_modify);
134 if (sub_name.empty() || !value_sp)
135 return value_sp;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000136
Zachary Turner31d97a52016-11-17 18:08:12 +0000137 switch (sub_name[0]) {
138 case '.': {
139 lldb::OptionValueSP return_val_sp;
140 return_val_sp =
141 value_sp->GetSubValue(exe_ctx, sub_name.drop_front(), will_modify, error);
142 if (!return_val_sp) {
143 if (Properties::IsSettingExperimental(sub_name.drop_front())) {
144 size_t experimental_len =
145 strlen(Properties::GetExperimentalSettingsName());
146 if (sub_name[experimental_len + 1] == '.')
147 return_val_sp = value_sp->GetSubValue(
148 exe_ctx, sub_name.drop_front(experimental_len + 2), will_modify, error);
149 // It isn't an error if an experimental setting is not present.
150 if (!return_val_sp)
151 error.Clear();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000152 }
Greg Clayton67cc0632012-08-22 17:17:09 +0000153 }
Zachary Turner31d97a52016-11-17 18:08:12 +0000154 return return_val_sp;
155 }
156 case '{':
157 // Predicate matching for predicates like
158 // "<setting-name>{<predicate>}"
159 // strings are parsed by the current OptionValueProperties subclass
160 // to mean whatever they want to. For instance a subclass of
161 // OptionValueProperties for a lldb_private::Target might implement:
162 // "target.run-args{arch==i386}" -- only set run args if the arch is
163 // i386
164 // "target.run-args{path=/tmp/a/b/c/a.out}" -- only set run args if the
165 // path matches
166 // "target.run-args{basename==test&&arch==x86_64}" -- only set run args
167 // if executable basename is "test" and arch is "x86_64"
168 if (sub_name[1]) {
169 llvm::StringRef predicate_start = sub_name.drop_front();
170 size_t pos = predicate_start.find_first_of('}');
171 if (pos != llvm::StringRef::npos) {
172 auto predicate = predicate_start.take_front(pos);
173 auto rest = predicate_start.drop_front(pos);
174 if (PredicateMatches(exe_ctx, predicate)) {
175 if (!rest.empty()) {
176 // Still more subvalue string to evaluate
177 return value_sp->GetSubValue(exe_ctx, rest,
178 will_modify, error);
179 } else {
180 // We have a match!
181 break;
182 }
183 }
184 }
185 }
186 // Predicate didn't match or wasn't correctly formed
187 value_sp.reset();
188 break;
189
190 case '[':
191 // Array or dictionary access for subvalues like:
192 // "[12]" -- access 12th array element
193 // "['hello']" -- dictionary access of key named hello
194 return value_sp->GetSubValue(exe_ctx, sub_name, will_modify, error);
195
196 default:
197 value_sp.reset();
198 break;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000199 }
200 return value_sp;
Greg Clayton67cc0632012-08-22 17:17:09 +0000201}
202
Kate Stoneb9c1b512016-09-06 20:57:50 +0000203Error OptionValueProperties::SetSubValue(const ExecutionContext *exe_ctx,
204 VarSetOperationType op,
Zachary Turner31d97a52016-11-17 18:08:12 +0000205 llvm::StringRef name, llvm::StringRef value) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000206 Error error;
207 const bool will_modify = true;
208 lldb::OptionValueSP value_sp(GetSubValue(exe_ctx, name, will_modify, error));
209 if (value_sp)
Zachary Turner31d97a52016-11-17 18:08:12 +0000210 error = value_sp->SetValueFromString(value, op);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000211 else {
212 if (error.AsCString() == nullptr)
Zachary Turner31d97a52016-11-17 18:08:12 +0000213 error.SetErrorStringWithFormat("invalid value path '%s'", name.str().c_str());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000214 }
215 return error;
Greg Clayton67cc0632012-08-22 17:17:09 +0000216}
217
Greg Clayton67cc0632012-08-22 17:17:09 +0000218uint32_t
Kate Stoneb9c1b512016-09-06 20:57:50 +0000219OptionValueProperties::GetPropertyIndex(const ConstString &name) const {
Zachary Turner4fa098a2016-10-06 21:22:44 +0000220 return m_name_to_index.Find(name.GetStringRef(), SIZE_MAX);
Greg Clayton67cc0632012-08-22 17:17:09 +0000221}
222
223const Property *
Kate Stoneb9c1b512016-09-06 20:57:50 +0000224OptionValueProperties::GetProperty(const ExecutionContext *exe_ctx,
225 bool will_modify,
226 const ConstString &name) const {
Zachary Turner4fa098a2016-10-06 21:22:44 +0000227 return GetPropertyAtIndex(
228 exe_ctx, will_modify,
229 m_name_to_index.Find(name.GetStringRef(), SIZE_MAX));
Greg Clayton67cc0632012-08-22 17:17:09 +0000230}
231
Kate Stoneb9c1b512016-09-06 20:57:50 +0000232const Property *OptionValueProperties::GetPropertyAtIndex(
233 const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const {
234 return ProtectedGetPropertyAtIndex(idx);
Greg Clayton67cc0632012-08-22 17:17:09 +0000235}
236
Kate Stoneb9c1b512016-09-06 20:57:50 +0000237lldb::OptionValueSP OptionValueProperties::GetPropertyValueAtIndex(
238 const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const {
239 const Property *setting = GetPropertyAtIndex(exe_ctx, will_modify, idx);
240 if (setting)
241 return setting->GetValue();
242 return OptionValueSP();
Greg Clayton67cc0632012-08-22 17:17:09 +0000243}
244
245OptionValuePathMappings *
Kate Stoneb9c1b512016-09-06 20:57:50 +0000246OptionValueProperties::GetPropertyAtIndexAsOptionValuePathMappings(
247 const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const {
248 OptionValueSP value_sp(GetPropertyValueAtIndex(exe_ctx, will_modify, idx));
249 if (value_sp)
250 return value_sp->GetAsPathMappings();
251 return nullptr;
Greg Clayton67cc0632012-08-22 17:17:09 +0000252}
253
254OptionValueFileSpecList *
Kate Stoneb9c1b512016-09-06 20:57:50 +0000255OptionValueProperties::GetPropertyAtIndexAsOptionValueFileSpecList(
256 const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const {
257 OptionValueSP value_sp(GetPropertyValueAtIndex(exe_ctx, will_modify, idx));
258 if (value_sp)
259 return value_sp->GetAsFileSpecList();
260 return nullptr;
Greg Clayton67cc0632012-08-22 17:17:09 +0000261}
262
Kate Stoneb9c1b512016-09-06 20:57:50 +0000263OptionValueArch *OptionValueProperties::GetPropertyAtIndexAsOptionValueArch(
264 const ExecutionContext *exe_ctx, uint32_t idx) const {
265 const Property *property = GetPropertyAtIndex(exe_ctx, false, idx);
266 if (property)
267 return property->GetValue()->GetAsArch();
268 return nullptr;
Greg Clayton67cc0632012-08-22 17:17:09 +0000269}
270
Dawn Perchik23b1dec2015-07-21 22:05:07 +0000271OptionValueLanguage *
Kate Stoneb9c1b512016-09-06 20:57:50 +0000272OptionValueProperties::GetPropertyAtIndexAsOptionValueLanguage(
273 const ExecutionContext *exe_ctx, uint32_t idx) const {
274 const Property *property = GetPropertyAtIndex(exe_ctx, false, idx);
275 if (property)
276 return property->GetValue()->GetAsLanguage();
277 return nullptr;
Dawn Perchik23b1dec2015-07-21 22:05:07 +0000278}
279
Kate Stoneb9c1b512016-09-06 20:57:50 +0000280bool OptionValueProperties::GetPropertyAtIndexAsArgs(
281 const ExecutionContext *exe_ctx, uint32_t idx, Args &args) const {
282 const Property *property = GetPropertyAtIndex(exe_ctx, false, idx);
283 if (property) {
284 OptionValue *value = property->GetValue().get();
285 if (value) {
286 const OptionValueArray *array = value->GetAsArray();
287 if (array)
288 return array->GetArgs(args);
289 else {
290 const OptionValueDictionary *dict = value->GetAsDictionary();
291 if (dict)
292 return dict->GetArgs(args);
293 }
Greg Clayton67cc0632012-08-22 17:17:09 +0000294 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000295 }
296 return false;
Greg Clayton67cc0632012-08-22 17:17:09 +0000297}
298
Kate Stoneb9c1b512016-09-06 20:57:50 +0000299bool OptionValueProperties::SetPropertyAtIndexFromArgs(
300 const ExecutionContext *exe_ctx, uint32_t idx, const Args &args) {
301 const Property *property = GetPropertyAtIndex(exe_ctx, true, idx);
302 if (property) {
303 OptionValue *value = property->GetValue().get();
304 if (value) {
305 OptionValueArray *array = value->GetAsArray();
306 if (array)
307 return array->SetArgs(args, eVarSetOperationAssign).Success();
308 else {
309 OptionValueDictionary *dict = value->GetAsDictionary();
310 if (dict)
311 return dict->SetArgs(args, eVarSetOperationAssign).Success();
312 }
Greg Clayton67cc0632012-08-22 17:17:09 +0000313 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000314 }
315 return false;
Greg Clayton67cc0632012-08-22 17:17:09 +0000316}
317
Kate Stoneb9c1b512016-09-06 20:57:50 +0000318bool OptionValueProperties::GetPropertyAtIndexAsBoolean(
319 const ExecutionContext *exe_ctx, uint32_t idx, bool fail_value) const {
320 const Property *property = GetPropertyAtIndex(exe_ctx, false, idx);
321 if (property) {
322 OptionValue *value = property->GetValue().get();
323 if (value)
324 return value->GetBooleanValue(fail_value);
325 }
326 return fail_value;
Greg Clayton67cc0632012-08-22 17:17:09 +0000327}
328
Kate Stoneb9c1b512016-09-06 20:57:50 +0000329bool OptionValueProperties::SetPropertyAtIndexAsBoolean(
330 const ExecutionContext *exe_ctx, uint32_t idx, bool new_value) {
331 const Property *property = GetPropertyAtIndex(exe_ctx, true, idx);
332 if (property) {
333 OptionValue *value = property->GetValue().get();
334 if (value) {
335 value->SetBooleanValue(new_value);
336 return true;
Greg Clayton67cc0632012-08-22 17:17:09 +0000337 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000338 }
339 return false;
Greg Clayton67cc0632012-08-22 17:17:09 +0000340}
341
342OptionValueDictionary *
Kate Stoneb9c1b512016-09-06 20:57:50 +0000343OptionValueProperties::GetPropertyAtIndexAsOptionValueDictionary(
344 const ExecutionContext *exe_ctx, uint32_t idx) const {
345 const Property *property = GetPropertyAtIndex(exe_ctx, false, idx);
346 if (property)
347 return property->GetValue()->GetAsDictionary();
348 return nullptr;
Greg Clayton67cc0632012-08-22 17:17:09 +0000349}
350
Kate Stoneb9c1b512016-09-06 20:57:50 +0000351int64_t OptionValueProperties::GetPropertyAtIndexAsEnumeration(
352 const ExecutionContext *exe_ctx, uint32_t idx, int64_t fail_value) const {
353 const Property *property = GetPropertyAtIndex(exe_ctx, false, idx);
354 if (property) {
355 OptionValue *value = property->GetValue().get();
356 if (value)
357 return value->GetEnumerationValue(fail_value);
358 }
359 return fail_value;
Greg Clayton67cc0632012-08-22 17:17:09 +0000360}
361
Kate Stoneb9c1b512016-09-06 20:57:50 +0000362bool OptionValueProperties::SetPropertyAtIndexAsEnumeration(
363 const ExecutionContext *exe_ctx, uint32_t idx, int64_t new_value) {
364 const Property *property = GetPropertyAtIndex(exe_ctx, true, idx);
365 if (property) {
366 OptionValue *value = property->GetValue().get();
367 if (value)
368 return value->SetEnumerationValue(new_value);
369 }
370 return false;
Greg Clayton67cc0632012-08-22 17:17:09 +0000371}
372
Greg Clayton554f68d2015-02-04 22:00:53 +0000373const FormatEntity::Entry *
Kate Stoneb9c1b512016-09-06 20:57:50 +0000374OptionValueProperties::GetPropertyAtIndexAsFormatEntity(
375 const ExecutionContext *exe_ctx, uint32_t idx) {
376 const Property *property = GetPropertyAtIndex(exe_ctx, true, idx);
377 if (property) {
378 OptionValue *value = property->GetValue().get();
379 if (value)
380 return value->GetFormatEntity();
381 }
382 return nullptr;
Greg Clayton554f68d2015-02-04 22:00:53 +0000383}
Greg Clayton67cc0632012-08-22 17:17:09 +0000384
Greg Clayton6920b522012-08-22 18:39:03 +0000385OptionValueFileSpec *
Kate Stoneb9c1b512016-09-06 20:57:50 +0000386OptionValueProperties::GetPropertyAtIndexAsOptionValueFileSpec(
387 const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const {
388 const Property *property = GetPropertyAtIndex(exe_ctx, false, idx);
389 if (property) {
390 OptionValue *value = property->GetValue().get();
391 if (value)
392 return value->GetAsFileSpec();
393 }
394 return nullptr;
Greg Clayton6920b522012-08-22 18:39:03 +0000395}
396
Kate Stoneb9c1b512016-09-06 20:57:50 +0000397FileSpec OptionValueProperties::GetPropertyAtIndexAsFileSpec(
398 const ExecutionContext *exe_ctx, uint32_t idx) const {
399 const Property *property = GetPropertyAtIndex(exe_ctx, false, idx);
400 if (property) {
401 OptionValue *value = property->GetValue().get();
402 if (value)
403 return value->GetFileSpecValue();
404 }
405 return FileSpec();
Greg Clayton67cc0632012-08-22 17:17:09 +0000406}
407
Kate Stoneb9c1b512016-09-06 20:57:50 +0000408bool OptionValueProperties::SetPropertyAtIndexAsFileSpec(
409 const ExecutionContext *exe_ctx, uint32_t idx,
410 const FileSpec &new_file_spec) {
411 const Property *property = GetPropertyAtIndex(exe_ctx, true, idx);
412 if (property) {
413 OptionValue *value = property->GetValue().get();
414 if (value)
415 return value->SetFileSpecValue(new_file_spec);
416 }
417 return false;
Greg Clayton67cc0632012-08-22 17:17:09 +0000418}
419
420const RegularExpression *
Kate Stoneb9c1b512016-09-06 20:57:50 +0000421OptionValueProperties::GetPropertyAtIndexAsOptionValueRegex(
422 const ExecutionContext *exe_ctx, uint32_t idx) const {
423 const Property *property = GetPropertyAtIndex(exe_ctx, false, idx);
424 if (property) {
425 OptionValue *value = property->GetValue().get();
426 if (value)
427 return value->GetRegexValue();
428 }
429 return nullptr;
430}
431
432OptionValueSInt64 *OptionValueProperties::GetPropertyAtIndexAsOptionValueSInt64(
433 const ExecutionContext *exe_ctx, uint32_t idx) const {
434 const Property *property = GetPropertyAtIndex(exe_ctx, false, idx);
435 if (property) {
436 OptionValue *value = property->GetValue().get();
437 if (value)
438 return value->GetAsSInt64();
439 }
440 return nullptr;
441}
442
443int64_t OptionValueProperties::GetPropertyAtIndexAsSInt64(
444 const ExecutionContext *exe_ctx, uint32_t idx, int64_t fail_value) const {
445 const Property *property = GetPropertyAtIndex(exe_ctx, false, idx);
446 if (property) {
447 OptionValue *value = property->GetValue().get();
448 if (value)
449 return value->GetSInt64Value(fail_value);
450 }
451 return fail_value;
452}
453
454bool OptionValueProperties::SetPropertyAtIndexAsSInt64(
455 const ExecutionContext *exe_ctx, uint32_t idx, int64_t new_value) {
456 const Property *property = GetPropertyAtIndex(exe_ctx, true, idx);
457 if (property) {
458 OptionValue *value = property->GetValue().get();
459 if (value)
460 return value->SetSInt64Value(new_value);
461 }
462 return false;
463}
464
Zachary Turner31d97a52016-11-17 18:08:12 +0000465llvm::StringRef OptionValueProperties::GetPropertyAtIndexAsString(
Kate Stoneb9c1b512016-09-06 20:57:50 +0000466 const ExecutionContext *exe_ctx, uint32_t idx,
Zachary Turner31d97a52016-11-17 18:08:12 +0000467 llvm::StringRef fail_value) const {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000468 const Property *property = GetPropertyAtIndex(exe_ctx, false, idx);
469 if (property) {
470 OptionValue *value = property->GetValue().get();
471 if (value)
472 return value->GetStringValue(fail_value);
473 }
474 return fail_value;
475}
476
477bool OptionValueProperties::SetPropertyAtIndexAsString(
Zachary Turner514d8cd2016-09-23 18:06:53 +0000478 const ExecutionContext *exe_ctx, uint32_t idx, llvm::StringRef new_value) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000479 const Property *property = GetPropertyAtIndex(exe_ctx, true, idx);
480 if (property) {
481 OptionValue *value = property->GetValue().get();
482 if (value)
483 return value->SetStringValue(new_value);
484 }
485 return false;
486}
487
488OptionValueString *OptionValueProperties::GetPropertyAtIndexAsOptionValueString(
489 const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const {
490 OptionValueSP value_sp(GetPropertyValueAtIndex(exe_ctx, will_modify, idx));
491 if (value_sp)
492 return value_sp->GetAsString();
493 return nullptr;
494}
495
496uint64_t OptionValueProperties::GetPropertyAtIndexAsUInt64(
497 const ExecutionContext *exe_ctx, uint32_t idx, uint64_t fail_value) const {
498 const Property *property = GetPropertyAtIndex(exe_ctx, false, idx);
499 if (property) {
500 OptionValue *value = property->GetValue().get();
501 if (value)
502 return value->GetUInt64Value(fail_value);
503 }
504 return fail_value;
505}
506
507bool OptionValueProperties::SetPropertyAtIndexAsUInt64(
508 const ExecutionContext *exe_ctx, uint32_t idx, uint64_t new_value) {
509 const Property *property = GetPropertyAtIndex(exe_ctx, true, idx);
510 if (property) {
511 OptionValue *value = property->GetValue().get();
512 if (value)
513 return value->SetUInt64Value(new_value);
514 }
515 return false;
516}
517
518bool OptionValueProperties::Clear() {
519 const size_t num_properties = m_properties.size();
520 for (size_t i = 0; i < num_properties; ++i)
521 m_properties[i].GetValue()->Clear();
522 return true;
523}
524
525Error OptionValueProperties::SetValueFromString(llvm::StringRef value,
526 VarSetOperationType op) {
527 Error error;
528
529 // Args args(value_cstr);
530 // const size_t argc = args.GetArgumentCount();
531 switch (op) {
532 case eVarSetOperationClear:
533 Clear();
534 break;
535
536 case eVarSetOperationReplace:
537 case eVarSetOperationAssign:
538 case eVarSetOperationRemove:
539 case eVarSetOperationInsertBefore:
540 case eVarSetOperationInsertAfter:
541 case eVarSetOperationAppend:
542 case eVarSetOperationInvalid:
543 error = OptionValue::SetValueFromString(value, op);
544 break;
545 }
546
547 return error;
548}
549
550void OptionValueProperties::DumpValue(const ExecutionContext *exe_ctx,
551 Stream &strm, uint32_t dump_mask) {
552 const size_t num_properties = m_properties.size();
553 for (size_t i = 0; i < num_properties; ++i) {
554 const Property *property = GetPropertyAtIndex(exe_ctx, false, i);
555 if (property) {
556 OptionValue *option_value = property->GetValue().get();
557 assert(option_value);
558 const bool transparent_value = option_value->ValueIsTransparent();
559 property->Dump(exe_ctx, strm, dump_mask);
560 if (!transparent_value)
561 strm.EOL();
562 }
563 }
564}
565
566Error OptionValueProperties::DumpPropertyValue(const ExecutionContext *exe_ctx,
567 Stream &strm,
Zachary Turner31d97a52016-11-17 18:08:12 +0000568 llvm::StringRef property_path,
Kate Stoneb9c1b512016-09-06 20:57:50 +0000569 uint32_t dump_mask) {
570 Error error;
571 const bool will_modify = false;
572 lldb::OptionValueSP value_sp(
573 GetSubValue(exe_ctx, property_path, will_modify, error));
574 if (value_sp) {
575 if (!value_sp->ValueIsTransparent()) {
576 if (dump_mask & eDumpOptionName)
577 strm.PutCString(property_path);
578 if (dump_mask & ~eDumpOptionName)
579 strm.PutChar(' ');
580 }
581 value_sp->DumpValue(exe_ctx, strm, dump_mask);
582 }
583 return error;
584}
585
586lldb::OptionValueSP OptionValueProperties::DeepCopy() const {
David Blaikiea322f362017-01-06 00:38:06 +0000587 llvm_unreachable("this shouldn't happen");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000588}
589
590const Property *OptionValueProperties::GetPropertyAtPath(
Zachary Turner31d97a52016-11-17 18:08:12 +0000591 const ExecutionContext *exe_ctx, bool will_modify, llvm::StringRef name) const {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000592 const Property *property = nullptr;
Zachary Turner31d97a52016-11-17 18:08:12 +0000593 if (name.empty())
594 return nullptr;
595 llvm::StringRef sub_name;
596 ConstString key;
597 size_t key_len = name.find_first_of(".[{");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000598
Zachary Turner31d97a52016-11-17 18:08:12 +0000599 if (key_len != llvm::StringRef::npos) {
600 key.SetString(name.take_front(key_len));
601 sub_name = name.drop_front(key_len);
602 } else
603 key.SetString(name);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000604
Zachary Turner31d97a52016-11-17 18:08:12 +0000605 property = GetProperty(exe_ctx, will_modify, key);
606 if (sub_name.empty() || !property)
607 return property;
608
609 if (sub_name[0] == '.') {
610 OptionValueProperties *sub_properties =
611 property->GetValue()->GetAsProperties();
612 if (sub_properties)
613 return sub_properties->GetPropertyAtPath(exe_ctx, will_modify,
614 sub_name.drop_front());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000615 }
Zachary Turner31d97a52016-11-17 18:08:12 +0000616 return nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000617}
618
619void OptionValueProperties::DumpAllDescriptions(CommandInterpreter &interpreter,
620 Stream &strm) const {
621 size_t max_name_len = 0;
622 const size_t num_properties = m_properties.size();
623 for (size_t i = 0; i < num_properties; ++i) {
624 const Property *property = ProtectedGetPropertyAtIndex(i);
Greg Clayton67cc0632012-08-22 17:17:09 +0000625 if (property)
Zachary Turnere6f6d4c2016-11-15 23:36:43 +0000626 max_name_len = std::max<size_t>(property->GetName().size(), max_name_len);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000627 }
628 for (size_t i = 0; i < num_properties; ++i) {
629 const Property *property = ProtectedGetPropertyAtIndex(i);
Greg Clayton67cc0632012-08-22 17:17:09 +0000630 if (property)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000631 property->DumpDescription(interpreter, strm, max_name_len, false);
632 }
Greg Clayton67cc0632012-08-22 17:17:09 +0000633}
634
Kate Stoneb9c1b512016-09-06 20:57:50 +0000635void OptionValueProperties::Apropos(
Zachary Turner067d1db2016-11-16 21:45:04 +0000636 llvm::StringRef keyword,
Kate Stoneb9c1b512016-09-06 20:57:50 +0000637 std::vector<const Property *> &matching_properties) const {
638 const size_t num_properties = m_properties.size();
639 StreamString strm;
640 for (size_t i = 0; i < num_properties; ++i) {
641 const Property *property = ProtectedGetPropertyAtIndex(i);
642 if (property) {
643 const OptionValueProperties *properties =
644 property->GetValue()->GetAsProperties();
645 if (properties) {
646 properties->Apropos(keyword, matching_properties);
647 } else {
648 bool match = false;
Zachary Turnere6f6d4c2016-11-15 23:36:43 +0000649 llvm::StringRef name = property->GetName();
650 if (name.contains_lower(keyword))
Kate Stoneb9c1b512016-09-06 20:57:50 +0000651 match = true;
652 else {
Zachary Turnere6f6d4c2016-11-15 23:36:43 +0000653 llvm::StringRef desc = property->GetDescription();
654 if (desc.contains_lower(keyword))
Kate Stoneb9c1b512016-09-06 20:57:50 +0000655 match = true;
Greg Clayton67cc0632012-08-22 17:17:09 +0000656 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000657 if (match) {
658 matching_properties.push_back(property);
Greg Clayton67cc0632012-08-22 17:17:09 +0000659 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000660 }
Greg Clayton67cc0632012-08-22 17:17:09 +0000661 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000662 }
Greg Clayton67cc0632012-08-22 17:17:09 +0000663}
664
Greg Claytone8cd0c92012-10-19 18:02:49 +0000665lldb::OptionValuePropertiesSP
Kate Stoneb9c1b512016-09-06 20:57:50 +0000666OptionValueProperties::GetSubProperty(const ExecutionContext *exe_ctx,
667 const ConstString &name) {
668 lldb::OptionValueSP option_value_sp(GetValueForKey(exe_ctx, name, false));
669 if (option_value_sp) {
670 OptionValueProperties *ov_properties = option_value_sp->GetAsProperties();
671 if (ov_properties)
672 return ov_properties->shared_from_this();
673 }
674 return lldb::OptionValuePropertiesSP();
Greg Claytone8cd0c92012-10-19 18:02:49 +0000675}