blob: a3c28f70270f46cdf0843e61e55e004ed4ef550e [file] [log] [blame]
Greg Clayton67cc0632012-08-22 17:17:09 +00001//===-- OptionValueProperties.cpp ---------------------------------*- C++ -*-===//
2//
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
27
28OptionValueProperties::OptionValueProperties (const ConstString &name) :
Greg Clayton03da4cc2013-04-19 21:31:16 +000029 OptionValue (),
30 m_name (name),
31 m_properties (),
32 m_name_to_index ()
Greg Clayton67cc0632012-08-22 17:17:09 +000033{
34}
35
36OptionValueProperties::OptionValueProperties (const OptionValueProperties &global_properties) :
Greg Clayton03da4cc2013-04-19 21:31:16 +000037 OptionValue (global_properties),
Saleem Abdulrasoole0147292014-06-13 03:30:45 +000038 std::enable_shared_from_this<OptionValueProperties> (),
Greg Clayton67cc0632012-08-22 17:17:09 +000039 m_name (global_properties.m_name),
40 m_properties (global_properties.m_properties),
41 m_name_to_index (global_properties.m_name_to_index)
42{
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
46 // them.
47 const size_t num_properties = m_properties.size();
48 for (size_t i=0; i<num_properties; ++i)
49 {
Bruce Mitchener6a7f3332014-06-27 02:42:12 +000050 // Duplicate any values that are not global when constructing properties from
Greg Clayton67cc0632012-08-22 17:17:09 +000051 // a global copy
52 if (m_properties[i].IsGlobal() == false)
53 {
54 lldb::OptionValueSP new_value_sp (m_properties[i].GetValue()->DeepCopy());
55 m_properties[i].SetOptionValue(new_value_sp);
56 }
57 }
58}
59
60
61
62size_t
63OptionValueProperties::GetNumProperties() const
64{
65 return m_properties.size();
66}
67
68
69void
70OptionValueProperties::Initialize (const PropertyDefinition *defs)
71{
72 for (size_t i=0; defs[i].name; ++i)
73 {
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);
79 }
80 m_name_to_index.Sort();
81}
82
83void
Greg Clayton332e8b12015-01-13 21:13:08 +000084OptionValueProperties::SetValueChangedCallback (uint32_t property_idx,
85 OptionValueChangedCallback callback,
86 void *baton)
87{
88 Property *property = ProtectedGetPropertyAtIndex (property_idx);
89 if (property)
90 property->SetValueChangedCallback (callback, baton);
91}
92
93void
Greg Clayton67cc0632012-08-22 17:17:09 +000094OptionValueProperties::AppendProperty(const ConstString &name,
95 const ConstString &desc,
96 bool is_global,
97 const OptionValueSP &value_sp)
98{
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();
104}
105
106
107
108//bool
109//OptionValueProperties::GetQualifiedName (Stream &strm)
110//{
111// bool dumped_something = false;
112//// lldb::OptionValuePropertiesSP parent_sp(GetParent ());
113//// if (parent_sp)
114//// {
115//// parent_sp->GetQualifiedName (strm);
116//// strm.PutChar('.');
117//// dumped_something = true;
118//// }
119// if (m_name)
120// {
121// strm << m_name;
122// dumped_something = true;
123// }
124// return dumped_something;
125//}
126//
127lldb::OptionValueSP
128OptionValueProperties::GetValueForKey (const ExecutionContext *exe_ctx,
129 const ConstString &key,
130 bool will_modify) const
131{
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();
136 return value_sp;
137}
138
139lldb::OptionValueSP
140OptionValueProperties::GetSubValue (const ExecutionContext *exe_ctx,
141 const char *name,
142 bool will_modify,
143 Error &error) const
144{
145 lldb::OptionValueSP value_sp;
146
147 if (name && name[0])
148 {
Ed Masted78c9572014-04-20 00:31:37 +0000149 const char *sub_name = nullptr;
Greg Clayton67cc0632012-08-22 17:17:09 +0000150 ConstString key;
151 size_t key_len = ::strcspn (name, ".[{");
152
153 if (name[key_len])
154 {
155 key.SetCStringWithLength (name, key_len);
156 sub_name = name + key_len;
157 }
158 else
159 key.SetCString (name);
160
161 value_sp = GetValueForKey (exe_ctx, key, will_modify);
162 if (sub_name && value_sp)
163 {
164 switch (sub_name[0])
165 {
166 case '.':
167 return value_sp->GetSubValue (exe_ctx, sub_name + 1, will_modify, error);
168
169 case '{':
170 // Predicate matching for predicates like
171 // "<setting-name>{<predicate>}"
172 // strings are parsed by the current OptionValueProperties subclass
173 // to mean whatever they want to. For instance a subclass of
174 // OptionValueProperties for a lldb_private::Target might implement:
175 // "target.run-args{arch==i386}" -- only set run args if the arch is i386
176 // "target.run-args{path=/tmp/a/b/c/a.out}" -- only set run args if the path matches
Bruce Mitchener6a7f3332014-06-27 02:42:12 +0000177 // "target.run-args{basename==test&&arch==x86_64}" -- only set run args if executable basename is "test" and arch is "x86_64"
Greg Clayton67cc0632012-08-22 17:17:09 +0000178 if (sub_name[1])
179 {
180 const char *predicate_start = sub_name + 1;
181 const char *predicate_end = strchr(predicate_start, '}');
182 if (predicate_end)
183 {
184 std::string predicate(predicate_start, predicate_end);
185 if (PredicateMatches(exe_ctx, predicate.c_str()))
186 {
187 if (predicate_end[1])
188 {
189 // Still more subvalue string to evaluate
190 return value_sp->GetSubValue (exe_ctx, predicate_end + 1, will_modify, error);
191 }
192 else
193 {
194 // We have a match!
195 break;
196 }
197 }
198 }
199 }
200 // Predicate didn't match or wasn't correctly formed
201 value_sp.reset();
202 break;
203
204 case '[':
205 // Array or dictionary access for subvalues like:
206 // "[12]" -- access 12th array element
207 // "['hello']" -- dictionary access of key named hello
208 return value_sp->GetSubValue (exe_ctx, sub_name, will_modify, error);
209
210 default:
211 value_sp.reset();
212 break;
213 }
214 }
215 }
216 return value_sp;
217}
218
219Error
220OptionValueProperties::SetSubValue (const ExecutionContext *exe_ctx,
221 VarSetOperationType op,
222 const char *name,
223 const char *value)
224{
225 Error error;
226 const bool will_modify = true;
227 lldb::OptionValueSP value_sp (GetSubValue (exe_ctx, name, will_modify, error));
228 if (value_sp)
Pavel Labathc95f7e22015-02-20 11:14:59 +0000229 error = value_sp->SetValueFromString(value ? llvm::StringRef(value) : llvm::StringRef(), op);
Greg Clayton67cc0632012-08-22 17:17:09 +0000230 else
231 {
Ed Masted78c9572014-04-20 00:31:37 +0000232 if (error.AsCString() == nullptr)
Greg Clayton67cc0632012-08-22 17:17:09 +0000233 error.SetErrorStringWithFormat("invalid value path '%s'", name);
234 }
235 return error;
236}
237
238
239ConstString
240OptionValueProperties::GetPropertyNameAtIndex (uint32_t idx) const
241{
Ed Masted78c9572014-04-20 00:31:37 +0000242 const Property *property = GetPropertyAtIndex(nullptr, false, idx);
Greg Clayton67cc0632012-08-22 17:17:09 +0000243 if (property)
244 return property->GetName();
245 return ConstString();
246
247}
248
249const char *
250OptionValueProperties::GetPropertyDescriptionAtIndex (uint32_t idx) const
251{
Ed Masted78c9572014-04-20 00:31:37 +0000252 const Property *property = GetPropertyAtIndex(nullptr, false, idx);
Greg Clayton67cc0632012-08-22 17:17:09 +0000253 if (property)
254 return property->GetDescription();
Ed Masted78c9572014-04-20 00:31:37 +0000255 return nullptr;
Greg Clayton67cc0632012-08-22 17:17:09 +0000256}
257
258uint32_t
259OptionValueProperties::GetPropertyIndex (const ConstString &name) const
260{
261 return m_name_to_index.Find (name.GetCString(), SIZE_MAX);
262}
263
264const Property *
265OptionValueProperties::GetProperty (const ExecutionContext *exe_ctx, bool will_modify, const ConstString &name) const
266{
267 return GetPropertyAtIndex (exe_ctx, will_modify, m_name_to_index.Find (name.GetCString(), SIZE_MAX));
268}
269
270const Property *
271OptionValueProperties::GetPropertyAtIndex (const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const
272{
273 return ProtectedGetPropertyAtIndex (idx);
274}
275
276lldb::OptionValueSP
277OptionValueProperties::GetPropertyValueAtIndex (const ExecutionContext *exe_ctx,
278 bool will_modify,
279 uint32_t idx) const
280{
281 const Property *setting = GetPropertyAtIndex (exe_ctx, will_modify, idx);
282 if (setting)
283 return setting->GetValue();
284 return OptionValueSP();
285}
286
287OptionValuePathMappings *
288OptionValueProperties::GetPropertyAtIndexAsOptionValuePathMappings (const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const
289{
290 OptionValueSP value_sp(GetPropertyValueAtIndex (exe_ctx, will_modify, idx));
291 if (value_sp)
292 return value_sp->GetAsPathMappings();
Ed Masted78c9572014-04-20 00:31:37 +0000293 return nullptr;
Greg Clayton67cc0632012-08-22 17:17:09 +0000294}
295
296OptionValueFileSpecList *
297OptionValueProperties::GetPropertyAtIndexAsOptionValueFileSpecList (const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const
298{
299 OptionValueSP value_sp(GetPropertyValueAtIndex (exe_ctx, will_modify, idx));
300 if (value_sp)
301 return value_sp->GetAsFileSpecList();
Ed Masted78c9572014-04-20 00:31:37 +0000302 return nullptr;
Greg Clayton67cc0632012-08-22 17:17:09 +0000303}
304
305OptionValueArch *
306OptionValueProperties::GetPropertyAtIndexAsOptionValueArch (const ExecutionContext *exe_ctx, uint32_t idx) const
307{
308 const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
309 if (property)
310 return property->GetValue()->GetAsArch();
Ed Masted78c9572014-04-20 00:31:37 +0000311 return nullptr;
Greg Clayton67cc0632012-08-22 17:17:09 +0000312}
313
Dawn Perchik23b1dec2015-07-21 22:05:07 +0000314OptionValueLanguage *
315OptionValueProperties::GetPropertyAtIndexAsOptionValueLanguage (const ExecutionContext *exe_ctx, uint32_t idx) const
316{
317 const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
318 if (property)
319 return property->GetValue()->GetAsLanguage();
320 return nullptr;
321}
322
Greg Clayton67cc0632012-08-22 17:17:09 +0000323bool
324OptionValueProperties::GetPropertyAtIndexAsArgs (const ExecutionContext *exe_ctx, uint32_t idx, Args &args) const
325{
326 const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
327 if (property)
328 {
329 OptionValue *value = property->GetValue().get();
330 if (value)
331 {
332 const OptionValueArray *array = value->GetAsArray();
333 if (array)
334 return array->GetArgs(args);
335 else
336 {
337 const OptionValueDictionary *dict = value->GetAsDictionary();
338 if (dict)
339 return dict->GetArgs(args);
340 }
341 }
342 }
343 return false;
344}
345
346bool
347OptionValueProperties::SetPropertyAtIndexFromArgs (const ExecutionContext *exe_ctx, uint32_t idx, const Args &args)
348{
349 const Property *property = GetPropertyAtIndex (exe_ctx, true, idx);
350 if (property)
351 {
352 OptionValue *value = property->GetValue().get();
353 if (value)
354 {
355 OptionValueArray *array = value->GetAsArray();
356 if (array)
357 return array->SetArgs(args, eVarSetOperationAssign).Success();
358 else
359 {
360 OptionValueDictionary *dict = value->GetAsDictionary();
361 if (dict)
362 return dict->SetArgs(args, eVarSetOperationAssign).Success();
363 }
364 }
365 }
366 return false;
367}
368
369bool
370OptionValueProperties::GetPropertyAtIndexAsBoolean (const ExecutionContext *exe_ctx, uint32_t idx, bool fail_value) const
371{
372 const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
373 if (property)
374 {
375 OptionValue *value = property->GetValue().get();
376 if (value)
377 return value->GetBooleanValue(fail_value);
378 }
379 return fail_value;
380}
381
382bool
383OptionValueProperties::SetPropertyAtIndexAsBoolean (const ExecutionContext *exe_ctx, uint32_t idx, bool new_value)
384{
385 const Property *property = GetPropertyAtIndex (exe_ctx, true, idx);
386 if (property)
387 {
388 OptionValue *value = property->GetValue().get();
389 if (value)
390 {
391 value->SetBooleanValue(new_value);
392 return true;
393 }
394 }
395 return false;
396}
397
398OptionValueDictionary *
399OptionValueProperties::GetPropertyAtIndexAsOptionValueDictionary (const ExecutionContext *exe_ctx, uint32_t idx) const
400{
401 const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
402 if (property)
403 return property->GetValue()->GetAsDictionary();
Ed Masted78c9572014-04-20 00:31:37 +0000404 return nullptr;
Greg Clayton67cc0632012-08-22 17:17:09 +0000405}
406
407int64_t
408OptionValueProperties::GetPropertyAtIndexAsEnumeration (const ExecutionContext *exe_ctx, uint32_t idx, int64_t fail_value) const
409{
410 const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
411 if (property)
412 {
413 OptionValue *value = property->GetValue().get();
414 if (value)
415 return value->GetEnumerationValue(fail_value);
416 }
417 return fail_value;
418}
419
420bool
421OptionValueProperties::SetPropertyAtIndexAsEnumeration (const ExecutionContext *exe_ctx, uint32_t idx, int64_t new_value)
422{
423 const Property *property = GetPropertyAtIndex (exe_ctx, true, idx);
424 if (property)
425 {
426 OptionValue *value = property->GetValue().get();
427 if (value)
428 return value->SetEnumerationValue(new_value);
429 }
430 return false;
431}
432
Greg Clayton554f68d2015-02-04 22:00:53 +0000433const FormatEntity::Entry *
434OptionValueProperties::GetPropertyAtIndexAsFormatEntity (const ExecutionContext *exe_ctx, uint32_t idx)
435{
436 const Property *property = GetPropertyAtIndex (exe_ctx, true, idx);
437 if (property)
438 {
439 OptionValue *value = property->GetValue().get();
440 if (value)
441 return value->GetFormatEntity();
442 }
443 return nullptr;
444}
Greg Clayton67cc0632012-08-22 17:17:09 +0000445
Greg Clayton6920b522012-08-22 18:39:03 +0000446OptionValueFileSpec *
447OptionValueProperties::GetPropertyAtIndexAsOptionValueFileSpec (const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const
448{
449 const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
450 if (property)
451 {
452 OptionValue *value = property->GetValue().get();
453 if (value)
454 return value->GetAsFileSpec();
455 }
Ed Masted78c9572014-04-20 00:31:37 +0000456 return nullptr;
Greg Clayton6920b522012-08-22 18:39:03 +0000457}
458
459
Greg Clayton67cc0632012-08-22 17:17:09 +0000460FileSpec
461OptionValueProperties::GetPropertyAtIndexAsFileSpec (const ExecutionContext *exe_ctx, uint32_t idx) const
462{
463 const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
464 if (property)
465 {
466 OptionValue *value = property->GetValue().get();
467 if (value)
468 return value->GetFileSpecValue();
469 }
470 return FileSpec();
471}
472
473
474bool
475OptionValueProperties::SetPropertyAtIndexAsFileSpec (const ExecutionContext *exe_ctx, uint32_t idx, const FileSpec &new_file_spec)
476{
477 const Property *property = GetPropertyAtIndex (exe_ctx, true, idx);
478 if (property)
479 {
480 OptionValue *value = property->GetValue().get();
481 if (value)
482 return value->SetFileSpecValue(new_file_spec);
483 }
484 return false;
485}
486
487const RegularExpression *
488OptionValueProperties::GetPropertyAtIndexAsOptionValueRegex (const ExecutionContext *exe_ctx, uint32_t idx) const
489{
490 const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
491 if (property)
492 {
493 OptionValue *value = property->GetValue().get();
494 if (value)
495 return value->GetRegexValue();
496 }
Ed Masted78c9572014-04-20 00:31:37 +0000497 return nullptr;
Greg Clayton67cc0632012-08-22 17:17:09 +0000498}
499
500OptionValueSInt64 *
501OptionValueProperties::GetPropertyAtIndexAsOptionValueSInt64 (const ExecutionContext *exe_ctx, uint32_t idx) const
502{
503 const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
504 if (property)
505 {
506 OptionValue *value = property->GetValue().get();
507 if (value)
508 return value->GetAsSInt64();
509 }
Ed Masted78c9572014-04-20 00:31:37 +0000510 return nullptr;
Greg Clayton67cc0632012-08-22 17:17:09 +0000511}
512
513int64_t
514OptionValueProperties::GetPropertyAtIndexAsSInt64 (const ExecutionContext *exe_ctx, uint32_t idx, int64_t fail_value) const
515{
516 const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
517 if (property)
518 {
519 OptionValue *value = property->GetValue().get();
520 if (value)
521 return value->GetSInt64Value(fail_value);
522 }
523 return fail_value;
524}
525
526bool
527OptionValueProperties::SetPropertyAtIndexAsSInt64 (const ExecutionContext *exe_ctx, uint32_t idx, int64_t new_value)
528{
529 const Property *property = GetPropertyAtIndex (exe_ctx, true, idx);
530 if (property)
531 {
532 OptionValue *value = property->GetValue().get();
533 if (value)
534 return value->SetSInt64Value(new_value);
535 }
536 return false;
537}
538
539const char *
540OptionValueProperties::GetPropertyAtIndexAsString (const ExecutionContext *exe_ctx, uint32_t idx, const char *fail_value) const
541{
542 const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
543 if (property)
544 {
545 OptionValue *value = property->GetValue().get();
546 if (value)
547 return value->GetStringValue(fail_value);
548 }
549 return fail_value;
550}
551
552bool
553OptionValueProperties::SetPropertyAtIndexAsString (const ExecutionContext *exe_ctx, uint32_t idx, const char *new_value)
554{
555 const Property *property = GetPropertyAtIndex (exe_ctx, true, idx);
556 if (property)
557 {
558 OptionValue *value = property->GetValue().get();
559 if (value)
560 return value->SetStringValue(new_value);
561 }
562 return false;
563}
564
Greg Clayton4c054102012-09-01 00:38:36 +0000565OptionValueString *
566OptionValueProperties::GetPropertyAtIndexAsOptionValueString (const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const
567{
568 OptionValueSP value_sp(GetPropertyValueAtIndex (exe_ctx, will_modify, idx));
569 if (value_sp)
570 return value_sp->GetAsString();
Ed Masted78c9572014-04-20 00:31:37 +0000571 return nullptr;
Greg Clayton4c054102012-09-01 00:38:36 +0000572}
573
574
Greg Clayton67cc0632012-08-22 17:17:09 +0000575uint64_t
576OptionValueProperties::GetPropertyAtIndexAsUInt64 (const ExecutionContext *exe_ctx, uint32_t idx, uint64_t fail_value) const
577{
578 const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
579 if (property)
580 {
581 OptionValue *value = property->GetValue().get();
582 if (value)
583 return value->GetUInt64Value(fail_value);
584 }
585 return fail_value;
586}
587
588bool
589OptionValueProperties::SetPropertyAtIndexAsUInt64 (const ExecutionContext *exe_ctx, uint32_t idx, uint64_t new_value)
590{
591 const Property *property = GetPropertyAtIndex (exe_ctx, true, idx);
592 if (property)
593 {
594 OptionValue *value = property->GetValue().get();
595 if (value)
596 return value->SetUInt64Value(new_value);
597 }
598 return false;
599}
600
601bool
602OptionValueProperties::Clear ()
603{
604 const size_t num_properties = m_properties.size();
605 for (size_t i=0; i<num_properties; ++i)
606 m_properties[i].GetValue()->Clear();
607 return true;
608}
609
610
611Error
Pavel Labathc95f7e22015-02-20 11:14:59 +0000612OptionValueProperties::SetValueFromString (llvm::StringRef value, VarSetOperationType op)
Greg Clayton67cc0632012-08-22 17:17:09 +0000613{
614 Error error;
615
616// Args args(value_cstr);
617// const size_t argc = args.GetArgumentCount();
618 switch (op)
619 {
620 case eVarSetOperationClear:
621 Clear ();
622 break;
623
624 case eVarSetOperationReplace:
625 case eVarSetOperationAssign:
626 case eVarSetOperationRemove:
627 case eVarSetOperationInsertBefore:
628 case eVarSetOperationInsertAfter:
629 case eVarSetOperationAppend:
630 case eVarSetOperationInvalid:
Pavel Labathc95f7e22015-02-20 11:14:59 +0000631 error = OptionValue::SetValueFromString (value, op);
Greg Clayton67cc0632012-08-22 17:17:09 +0000632 break;
633 }
634
635 return error;
636}
637
638void
639OptionValueProperties::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask)
640{
641 const size_t num_properties = m_properties.size();
642 for (size_t i=0; i<num_properties; ++i)
643 {
644 const Property *property = GetPropertyAtIndex(exe_ctx, false, i);
645 if (property)
646 {
647 OptionValue *option_value = property->GetValue().get();
648 assert (option_value);
649 const bool transparent_value = option_value->ValueIsTransparent ();
650 property->Dump (exe_ctx,
651 strm,
652 dump_mask);
653 if (!transparent_value)
654 strm.EOL();
655 }
656 }
657}
658
659Error
660OptionValueProperties::DumpPropertyValue (const ExecutionContext *exe_ctx,
661 Stream &strm,
662 const char *property_path,
663 uint32_t dump_mask)
664{
665 Error error;
666 const bool will_modify = false;
667 lldb::OptionValueSP value_sp (GetSubValue (exe_ctx, property_path, will_modify, error));
668 if (value_sp)
669 {
670 if (!value_sp->ValueIsTransparent ())
671 {
672 if (dump_mask & eDumpOptionName)
673 strm.PutCString (property_path);
674 if (dump_mask & ~eDumpOptionName)
675 strm.PutChar (' ');
676 }
677 value_sp->DumpValue (exe_ctx, strm, dump_mask);
678 }
679 return error;
680}
681
682lldb::OptionValueSP
683OptionValueProperties::DeepCopy () const
684{
685 assert(!"this shouldn't happen");
Virgile Bello51d21912013-09-05 16:57:48 +0000686 return lldb::OptionValueSP();
Greg Clayton67cc0632012-08-22 17:17:09 +0000687}
688
689const Property *
690OptionValueProperties::GetPropertyAtPath (const ExecutionContext *exe_ctx,
691 bool will_modify,
692 const char *name) const
693{
Ed Masted78c9572014-04-20 00:31:37 +0000694 const Property *property = nullptr;
Greg Clayton67cc0632012-08-22 17:17:09 +0000695 if (name && name[0])
696 {
Ed Masted78c9572014-04-20 00:31:37 +0000697 const char *sub_name = nullptr;
Greg Clayton67cc0632012-08-22 17:17:09 +0000698 ConstString key;
699 size_t key_len = ::strcspn (name, ".[{");
700
701 if (name[key_len])
702 {
703 key.SetCStringWithLength (name, key_len);
704 sub_name = name + key_len;
705 }
706 else
707 key.SetCString (name);
708
709 property = GetProperty (exe_ctx, will_modify, key);
710 if (sub_name && property)
711 {
712 if (sub_name[0] == '.')
713 {
714 OptionValueProperties *sub_properties = property->GetValue()->GetAsProperties();
715 if (sub_properties)
716 return sub_properties->GetPropertyAtPath(exe_ctx, will_modify, sub_name + 1);
717 }
Ed Masted78c9572014-04-20 00:31:37 +0000718 property = nullptr;
Greg Clayton67cc0632012-08-22 17:17:09 +0000719 }
720 }
721 return property;
722}
723
724void
725OptionValueProperties::DumpAllDescriptions (CommandInterpreter &interpreter,
726 Stream &strm) const
727{
728 size_t max_name_len = 0;
729 const size_t num_properties = m_properties.size();
730 for (size_t i=0; i<num_properties; ++i)
731 {
732 const Property *property = ProtectedGetPropertyAtIndex(i);
733 if (property)
734 max_name_len = std::max<size_t>(property->GetName().GetLength(), max_name_len);
735 }
736 for (size_t i=0; i<num_properties; ++i)
737 {
738 const Property *property = ProtectedGetPropertyAtIndex(i);
739 if (property)
740 property->DumpDescription (interpreter, strm, max_name_len, false);
741 }
742}
743
744void
745OptionValueProperties::Apropos (const char *keyword, std::vector<const Property *> &matching_properties) const
746{
747 const size_t num_properties = m_properties.size();
748 StreamString strm;
749 for (size_t i=0; i<num_properties; ++i)
750 {
751 const Property *property = ProtectedGetPropertyAtIndex(i);
752 if (property)
753 {
754 const OptionValueProperties *properties = property->GetValue()->GetAsProperties();
755 if (properties)
756 {
757 properties->Apropos (keyword, matching_properties);
758 }
759 else
760 {
761 bool match = false;
762 const char *name = property->GetName().GetCString();
763 if (name && ::strcasestr(name, keyword))
764 match = true;
765 else
766 {
767 const char *desc = property->GetDescription();
768 if (desc && ::strcasestr(desc, keyword))
769 match = true;
770 }
771 if (match)
772 {
773 matching_properties.push_back (property);
774 }
775 }
776 }
777 }
778}
779
Greg Claytone8cd0c92012-10-19 18:02:49 +0000780lldb::OptionValuePropertiesSP
781OptionValueProperties::GetSubProperty (const ExecutionContext *exe_ctx,
782 const ConstString &name)
783{
784 lldb::OptionValueSP option_value_sp(GetValueForKey(exe_ctx, name, false));
785 if (option_value_sp)
786 {
787 OptionValueProperties *ov_properties = option_value_sp->GetAsProperties ();
788 if (ov_properties)
789 return ov_properties->shared_from_this();
790 }
791 return lldb::OptionValuePropertiesSP();
792}
793
794
Greg Clayton67cc0632012-08-22 17:17:09 +0000795