1 //===-- 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
24 using namespace lldb;
25 using namespace lldb_private;
26
27
OptionValueProperties(const ConstString & name)28 OptionValueProperties::OptionValueProperties (const ConstString &name) :
29 OptionValue (),
30 m_name (name),
31 m_properties (),
32 m_name_to_index ()
33 {
34 }
35
OptionValueProperties(const OptionValueProperties & global_properties)36 OptionValueProperties::OptionValueProperties (const OptionValueProperties &global_properties) :
37 OptionValue (global_properties),
38 std::enable_shared_from_this<OptionValueProperties> (),
39 m_name (global_properties.m_name),
40 m_properties (global_properties.m_properties),
41 m_name_to_index (global_properties.m_name_to_index)
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 {
50 // Duplicate any values that are not global when constructing properties from
51 // 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
62 size_t
GetNumProperties() const63 OptionValueProperties::GetNumProperties() const
64 {
65 return m_properties.size();
66 }
67
68
69 void
Initialize(const PropertyDefinition * defs)70 OptionValueProperties::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
83 void
SetValueChangedCallback(uint32_t property_idx,OptionValueChangedCallback callback,void * baton)84 OptionValueProperties::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
93 void
AppendProperty(const ConstString & name,const ConstString & desc,bool is_global,const OptionValueSP & value_sp)94 OptionValueProperties::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 //
127 lldb::OptionValueSP
GetValueForKey(const ExecutionContext * exe_ctx,const ConstString & key,bool will_modify) const128 OptionValueProperties::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
139 lldb::OptionValueSP
GetSubValue(const ExecutionContext * exe_ctx,const char * name,bool will_modify,Error & error) const140 OptionValueProperties::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 {
149 const char *sub_name = nullptr;
150 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
177 // "target.run-args{basename==test&&arch==x86_64}" -- only set run args if executable basename is "test" and arch is "x86_64"
178 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
219 Error
SetSubValue(const ExecutionContext * exe_ctx,VarSetOperationType op,const char * name,const char * value)220 OptionValueProperties::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)
229 error = value_sp->SetValueFromString(value ? llvm::StringRef(value) : llvm::StringRef(), op);
230 else
231 {
232 if (error.AsCString() == nullptr)
233 error.SetErrorStringWithFormat("invalid value path '%s'", name);
234 }
235 return error;
236 }
237
238
239 ConstString
GetPropertyNameAtIndex(uint32_t idx) const240 OptionValueProperties::GetPropertyNameAtIndex (uint32_t idx) const
241 {
242 const Property *property = GetPropertyAtIndex(nullptr, false, idx);
243 if (property)
244 return property->GetName();
245 return ConstString();
246
247 }
248
249 const char *
GetPropertyDescriptionAtIndex(uint32_t idx) const250 OptionValueProperties::GetPropertyDescriptionAtIndex (uint32_t idx) const
251 {
252 const Property *property = GetPropertyAtIndex(nullptr, false, idx);
253 if (property)
254 return property->GetDescription();
255 return nullptr;
256 }
257
258 uint32_t
GetPropertyIndex(const ConstString & name) const259 OptionValueProperties::GetPropertyIndex (const ConstString &name) const
260 {
261 return m_name_to_index.Find (name.GetCString(), SIZE_MAX);
262 }
263
264 const Property *
GetProperty(const ExecutionContext * exe_ctx,bool will_modify,const ConstString & name) const265 OptionValueProperties::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
270 const Property *
GetPropertyAtIndex(const ExecutionContext * exe_ctx,bool will_modify,uint32_t idx) const271 OptionValueProperties::GetPropertyAtIndex (const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const
272 {
273 return ProtectedGetPropertyAtIndex (idx);
274 }
275
276 lldb::OptionValueSP
GetPropertyValueAtIndex(const ExecutionContext * exe_ctx,bool will_modify,uint32_t idx) const277 OptionValueProperties::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
287 OptionValuePathMappings *
GetPropertyAtIndexAsOptionValuePathMappings(const ExecutionContext * exe_ctx,bool will_modify,uint32_t idx) const288 OptionValueProperties::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();
293 return nullptr;
294 }
295
296 OptionValueFileSpecList *
GetPropertyAtIndexAsOptionValueFileSpecList(const ExecutionContext * exe_ctx,bool will_modify,uint32_t idx) const297 OptionValueProperties::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();
302 return nullptr;
303 }
304
305 OptionValueArch *
GetPropertyAtIndexAsOptionValueArch(const ExecutionContext * exe_ctx,uint32_t idx) const306 OptionValueProperties::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();
311 return nullptr;
312 }
313
314 bool
GetPropertyAtIndexAsArgs(const ExecutionContext * exe_ctx,uint32_t idx,Args & args) const315 OptionValueProperties::GetPropertyAtIndexAsArgs (const ExecutionContext *exe_ctx, uint32_t idx, Args &args) const
316 {
317 const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
318 if (property)
319 {
320 OptionValue *value = property->GetValue().get();
321 if (value)
322 {
323 const OptionValueArray *array = value->GetAsArray();
324 if (array)
325 return array->GetArgs(args);
326 else
327 {
328 const OptionValueDictionary *dict = value->GetAsDictionary();
329 if (dict)
330 return dict->GetArgs(args);
331 }
332 }
333 }
334 return false;
335 }
336
337 bool
SetPropertyAtIndexFromArgs(const ExecutionContext * exe_ctx,uint32_t idx,const Args & args)338 OptionValueProperties::SetPropertyAtIndexFromArgs (const ExecutionContext *exe_ctx, uint32_t idx, const Args &args)
339 {
340 const Property *property = GetPropertyAtIndex (exe_ctx, true, idx);
341 if (property)
342 {
343 OptionValue *value = property->GetValue().get();
344 if (value)
345 {
346 OptionValueArray *array = value->GetAsArray();
347 if (array)
348 return array->SetArgs(args, eVarSetOperationAssign).Success();
349 else
350 {
351 OptionValueDictionary *dict = value->GetAsDictionary();
352 if (dict)
353 return dict->SetArgs(args, eVarSetOperationAssign).Success();
354 }
355 }
356 }
357 return false;
358 }
359
360 bool
GetPropertyAtIndexAsBoolean(const ExecutionContext * exe_ctx,uint32_t idx,bool fail_value) const361 OptionValueProperties::GetPropertyAtIndexAsBoolean (const ExecutionContext *exe_ctx, uint32_t idx, bool fail_value) const
362 {
363 const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
364 if (property)
365 {
366 OptionValue *value = property->GetValue().get();
367 if (value)
368 return value->GetBooleanValue(fail_value);
369 }
370 return fail_value;
371 }
372
373 bool
SetPropertyAtIndexAsBoolean(const ExecutionContext * exe_ctx,uint32_t idx,bool new_value)374 OptionValueProperties::SetPropertyAtIndexAsBoolean (const ExecutionContext *exe_ctx, uint32_t idx, bool new_value)
375 {
376 const Property *property = GetPropertyAtIndex (exe_ctx, true, idx);
377 if (property)
378 {
379 OptionValue *value = property->GetValue().get();
380 if (value)
381 {
382 value->SetBooleanValue(new_value);
383 return true;
384 }
385 }
386 return false;
387 }
388
389 OptionValueDictionary *
GetPropertyAtIndexAsOptionValueDictionary(const ExecutionContext * exe_ctx,uint32_t idx) const390 OptionValueProperties::GetPropertyAtIndexAsOptionValueDictionary (const ExecutionContext *exe_ctx, uint32_t idx) const
391 {
392 const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
393 if (property)
394 return property->GetValue()->GetAsDictionary();
395 return nullptr;
396 }
397
398 int64_t
GetPropertyAtIndexAsEnumeration(const ExecutionContext * exe_ctx,uint32_t idx,int64_t fail_value) const399 OptionValueProperties::GetPropertyAtIndexAsEnumeration (const ExecutionContext *exe_ctx, uint32_t idx, int64_t fail_value) const
400 {
401 const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
402 if (property)
403 {
404 OptionValue *value = property->GetValue().get();
405 if (value)
406 return value->GetEnumerationValue(fail_value);
407 }
408 return fail_value;
409 }
410
411 bool
SetPropertyAtIndexAsEnumeration(const ExecutionContext * exe_ctx,uint32_t idx,int64_t new_value)412 OptionValueProperties::SetPropertyAtIndexAsEnumeration (const ExecutionContext *exe_ctx, uint32_t idx, int64_t new_value)
413 {
414 const Property *property = GetPropertyAtIndex (exe_ctx, true, idx);
415 if (property)
416 {
417 OptionValue *value = property->GetValue().get();
418 if (value)
419 return value->SetEnumerationValue(new_value);
420 }
421 return false;
422 }
423
424 const FormatEntity::Entry *
GetPropertyAtIndexAsFormatEntity(const ExecutionContext * exe_ctx,uint32_t idx)425 OptionValueProperties::GetPropertyAtIndexAsFormatEntity (const ExecutionContext *exe_ctx, uint32_t idx)
426 {
427 const Property *property = GetPropertyAtIndex (exe_ctx, true, idx);
428 if (property)
429 {
430 OptionValue *value = property->GetValue().get();
431 if (value)
432 return value->GetFormatEntity();
433 }
434 return nullptr;
435 }
436
437 OptionValueFileSpec *
GetPropertyAtIndexAsOptionValueFileSpec(const ExecutionContext * exe_ctx,bool will_modify,uint32_t idx) const438 OptionValueProperties::GetPropertyAtIndexAsOptionValueFileSpec (const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const
439 {
440 const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
441 if (property)
442 {
443 OptionValue *value = property->GetValue().get();
444 if (value)
445 return value->GetAsFileSpec();
446 }
447 return nullptr;
448 }
449
450
451 FileSpec
GetPropertyAtIndexAsFileSpec(const ExecutionContext * exe_ctx,uint32_t idx) const452 OptionValueProperties::GetPropertyAtIndexAsFileSpec (const ExecutionContext *exe_ctx, uint32_t idx) const
453 {
454 const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
455 if (property)
456 {
457 OptionValue *value = property->GetValue().get();
458 if (value)
459 return value->GetFileSpecValue();
460 }
461 return FileSpec();
462 }
463
464
465 bool
SetPropertyAtIndexAsFileSpec(const ExecutionContext * exe_ctx,uint32_t idx,const FileSpec & new_file_spec)466 OptionValueProperties::SetPropertyAtIndexAsFileSpec (const ExecutionContext *exe_ctx, uint32_t idx, const FileSpec &new_file_spec)
467 {
468 const Property *property = GetPropertyAtIndex (exe_ctx, true, idx);
469 if (property)
470 {
471 OptionValue *value = property->GetValue().get();
472 if (value)
473 return value->SetFileSpecValue(new_file_spec);
474 }
475 return false;
476 }
477
478 const RegularExpression *
GetPropertyAtIndexAsOptionValueRegex(const ExecutionContext * exe_ctx,uint32_t idx) const479 OptionValueProperties::GetPropertyAtIndexAsOptionValueRegex (const ExecutionContext *exe_ctx, uint32_t idx) const
480 {
481 const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
482 if (property)
483 {
484 OptionValue *value = property->GetValue().get();
485 if (value)
486 return value->GetRegexValue();
487 }
488 return nullptr;
489 }
490
491 OptionValueSInt64 *
GetPropertyAtIndexAsOptionValueSInt64(const ExecutionContext * exe_ctx,uint32_t idx) const492 OptionValueProperties::GetPropertyAtIndexAsOptionValueSInt64 (const ExecutionContext *exe_ctx, uint32_t idx) const
493 {
494 const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
495 if (property)
496 {
497 OptionValue *value = property->GetValue().get();
498 if (value)
499 return value->GetAsSInt64();
500 }
501 return nullptr;
502 }
503
504 int64_t
GetPropertyAtIndexAsSInt64(const ExecutionContext * exe_ctx,uint32_t idx,int64_t fail_value) const505 OptionValueProperties::GetPropertyAtIndexAsSInt64 (const ExecutionContext *exe_ctx, uint32_t idx, int64_t fail_value) const
506 {
507 const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
508 if (property)
509 {
510 OptionValue *value = property->GetValue().get();
511 if (value)
512 return value->GetSInt64Value(fail_value);
513 }
514 return fail_value;
515 }
516
517 bool
SetPropertyAtIndexAsSInt64(const ExecutionContext * exe_ctx,uint32_t idx,int64_t new_value)518 OptionValueProperties::SetPropertyAtIndexAsSInt64 (const ExecutionContext *exe_ctx, uint32_t idx, int64_t new_value)
519 {
520 const Property *property = GetPropertyAtIndex (exe_ctx, true, idx);
521 if (property)
522 {
523 OptionValue *value = property->GetValue().get();
524 if (value)
525 return value->SetSInt64Value(new_value);
526 }
527 return false;
528 }
529
530 const char *
GetPropertyAtIndexAsString(const ExecutionContext * exe_ctx,uint32_t idx,const char * fail_value) const531 OptionValueProperties::GetPropertyAtIndexAsString (const ExecutionContext *exe_ctx, uint32_t idx, const char *fail_value) const
532 {
533 const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
534 if (property)
535 {
536 OptionValue *value = property->GetValue().get();
537 if (value)
538 return value->GetStringValue(fail_value);
539 }
540 return fail_value;
541 }
542
543 bool
SetPropertyAtIndexAsString(const ExecutionContext * exe_ctx,uint32_t idx,const char * new_value)544 OptionValueProperties::SetPropertyAtIndexAsString (const ExecutionContext *exe_ctx, uint32_t idx, const char *new_value)
545 {
546 const Property *property = GetPropertyAtIndex (exe_ctx, true, idx);
547 if (property)
548 {
549 OptionValue *value = property->GetValue().get();
550 if (value)
551 return value->SetStringValue(new_value);
552 }
553 return false;
554 }
555
556 OptionValueString *
GetPropertyAtIndexAsOptionValueString(const ExecutionContext * exe_ctx,bool will_modify,uint32_t idx) const557 OptionValueProperties::GetPropertyAtIndexAsOptionValueString (const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const
558 {
559 OptionValueSP value_sp(GetPropertyValueAtIndex (exe_ctx, will_modify, idx));
560 if (value_sp)
561 return value_sp->GetAsString();
562 return nullptr;
563 }
564
565
566 uint64_t
GetPropertyAtIndexAsUInt64(const ExecutionContext * exe_ctx,uint32_t idx,uint64_t fail_value) const567 OptionValueProperties::GetPropertyAtIndexAsUInt64 (const ExecutionContext *exe_ctx, uint32_t idx, uint64_t fail_value) const
568 {
569 const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
570 if (property)
571 {
572 OptionValue *value = property->GetValue().get();
573 if (value)
574 return value->GetUInt64Value(fail_value);
575 }
576 return fail_value;
577 }
578
579 bool
SetPropertyAtIndexAsUInt64(const ExecutionContext * exe_ctx,uint32_t idx,uint64_t new_value)580 OptionValueProperties::SetPropertyAtIndexAsUInt64 (const ExecutionContext *exe_ctx, uint32_t idx, uint64_t new_value)
581 {
582 const Property *property = GetPropertyAtIndex (exe_ctx, true, idx);
583 if (property)
584 {
585 OptionValue *value = property->GetValue().get();
586 if (value)
587 return value->SetUInt64Value(new_value);
588 }
589 return false;
590 }
591
592 bool
Clear()593 OptionValueProperties::Clear ()
594 {
595 const size_t num_properties = m_properties.size();
596 for (size_t i=0; i<num_properties; ++i)
597 m_properties[i].GetValue()->Clear();
598 return true;
599 }
600
601
602 Error
SetValueFromString(llvm::StringRef value,VarSetOperationType op)603 OptionValueProperties::SetValueFromString (llvm::StringRef value, VarSetOperationType op)
604 {
605 Error error;
606
607 // Args args(value_cstr);
608 // const size_t argc = args.GetArgumentCount();
609 switch (op)
610 {
611 case eVarSetOperationClear:
612 Clear ();
613 break;
614
615 case eVarSetOperationReplace:
616 case eVarSetOperationAssign:
617 case eVarSetOperationRemove:
618 case eVarSetOperationInsertBefore:
619 case eVarSetOperationInsertAfter:
620 case eVarSetOperationAppend:
621 case eVarSetOperationInvalid:
622 error = OptionValue::SetValueFromString (value, op);
623 break;
624 }
625
626 return error;
627 }
628
629 void
DumpValue(const ExecutionContext * exe_ctx,Stream & strm,uint32_t dump_mask)630 OptionValueProperties::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask)
631 {
632 const size_t num_properties = m_properties.size();
633 for (size_t i=0; i<num_properties; ++i)
634 {
635 const Property *property = GetPropertyAtIndex(exe_ctx, false, i);
636 if (property)
637 {
638 OptionValue *option_value = property->GetValue().get();
639 assert (option_value);
640 const bool transparent_value = option_value->ValueIsTransparent ();
641 property->Dump (exe_ctx,
642 strm,
643 dump_mask);
644 if (!transparent_value)
645 strm.EOL();
646 }
647 }
648 }
649
650 Error
DumpPropertyValue(const ExecutionContext * exe_ctx,Stream & strm,const char * property_path,uint32_t dump_mask)651 OptionValueProperties::DumpPropertyValue (const ExecutionContext *exe_ctx,
652 Stream &strm,
653 const char *property_path,
654 uint32_t dump_mask)
655 {
656 Error error;
657 const bool will_modify = false;
658 lldb::OptionValueSP value_sp (GetSubValue (exe_ctx, property_path, will_modify, error));
659 if (value_sp)
660 {
661 if (!value_sp->ValueIsTransparent ())
662 {
663 if (dump_mask & eDumpOptionName)
664 strm.PutCString (property_path);
665 if (dump_mask & ~eDumpOptionName)
666 strm.PutChar (' ');
667 }
668 value_sp->DumpValue (exe_ctx, strm, dump_mask);
669 }
670 return error;
671 }
672
673 lldb::OptionValueSP
DeepCopy() const674 OptionValueProperties::DeepCopy () const
675 {
676 assert(!"this shouldn't happen");
677 return lldb::OptionValueSP();
678 }
679
680 const Property *
GetPropertyAtPath(const ExecutionContext * exe_ctx,bool will_modify,const char * name) const681 OptionValueProperties::GetPropertyAtPath (const ExecutionContext *exe_ctx,
682 bool will_modify,
683 const char *name) const
684 {
685 const Property *property = nullptr;
686 if (name && name[0])
687 {
688 const char *sub_name = nullptr;
689 ConstString key;
690 size_t key_len = ::strcspn (name, ".[{");
691
692 if (name[key_len])
693 {
694 key.SetCStringWithLength (name, key_len);
695 sub_name = name + key_len;
696 }
697 else
698 key.SetCString (name);
699
700 property = GetProperty (exe_ctx, will_modify, key);
701 if (sub_name && property)
702 {
703 if (sub_name[0] == '.')
704 {
705 OptionValueProperties *sub_properties = property->GetValue()->GetAsProperties();
706 if (sub_properties)
707 return sub_properties->GetPropertyAtPath(exe_ctx, will_modify, sub_name + 1);
708 }
709 property = nullptr;
710 }
711 }
712 return property;
713 }
714
715 void
DumpAllDescriptions(CommandInterpreter & interpreter,Stream & strm) const716 OptionValueProperties::DumpAllDescriptions (CommandInterpreter &interpreter,
717 Stream &strm) const
718 {
719 size_t max_name_len = 0;
720 const size_t num_properties = m_properties.size();
721 for (size_t i=0; i<num_properties; ++i)
722 {
723 const Property *property = ProtectedGetPropertyAtIndex(i);
724 if (property)
725 max_name_len = std::max<size_t>(property->GetName().GetLength(), max_name_len);
726 }
727 for (size_t i=0; i<num_properties; ++i)
728 {
729 const Property *property = ProtectedGetPropertyAtIndex(i);
730 if (property)
731 property->DumpDescription (interpreter, strm, max_name_len, false);
732 }
733 }
734
735 void
Apropos(const char * keyword,std::vector<const Property * > & matching_properties) const736 OptionValueProperties::Apropos (const char *keyword, std::vector<const Property *> &matching_properties) const
737 {
738 const size_t num_properties = m_properties.size();
739 StreamString strm;
740 for (size_t i=0; i<num_properties; ++i)
741 {
742 const Property *property = ProtectedGetPropertyAtIndex(i);
743 if (property)
744 {
745 const OptionValueProperties *properties = property->GetValue()->GetAsProperties();
746 if (properties)
747 {
748 properties->Apropos (keyword, matching_properties);
749 }
750 else
751 {
752 bool match = false;
753 const char *name = property->GetName().GetCString();
754 if (name && ::strcasestr(name, keyword))
755 match = true;
756 else
757 {
758 const char *desc = property->GetDescription();
759 if (desc && ::strcasestr(desc, keyword))
760 match = true;
761 }
762 if (match)
763 {
764 matching_properties.push_back (property);
765 }
766 }
767 }
768 }
769 }
770
771 lldb::OptionValuePropertiesSP
GetSubProperty(const ExecutionContext * exe_ctx,const ConstString & name)772 OptionValueProperties::GetSubProperty (const ExecutionContext *exe_ctx,
773 const ConstString &name)
774 {
775 lldb::OptionValueSP option_value_sp(GetValueForKey(exe_ctx, name, false));
776 if (option_value_sp)
777 {
778 OptionValueProperties *ov_properties = option_value_sp->GetAsProperties ();
779 if (ov_properties)
780 return ov_properties->shared_from_this();
781 }
782 return lldb::OptionValuePropertiesSP();
783 }
784
785
786
787