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     m_name (global_properties.m_name),
39     m_properties (global_properties.m_properties),
40     m_name_to_index (global_properties.m_name_to_index)
41 {
42     // We now have an exact copy of "global_properties". We need to now
43     // find all non-global settings and copy the property values so that
44     // all non-global settings get new OptionValue instances created for
45     // them.
46     const size_t num_properties = m_properties.size();
47     for (size_t i=0; i<num_properties; ++i)
48     {
49         // Duplicate any values that are not global when contructing properties from
50         // a global copy
51         if (m_properties[i].IsGlobal() == false)
52         {
53             lldb::OptionValueSP new_value_sp (m_properties[i].GetValue()->DeepCopy());
54             m_properties[i].SetOptionValue(new_value_sp);
55         }
56     }
57 }
58 
59 
60 
61 size_t
GetNumProperties() const62 OptionValueProperties::GetNumProperties() const
63 {
64     return m_properties.size();
65 }
66 
67 
68 void
Initialize(const PropertyDefinition * defs)69 OptionValueProperties::Initialize (const PropertyDefinition *defs)
70 {
71     for (size_t i=0; defs[i].name; ++i)
72     {
73         Property property(defs[i]);
74         assert(property.IsValid());
75         m_name_to_index.Append(property.GetName().GetCString(),m_properties.size());
76         property.GetValue()->SetParent(shared_from_this());
77         m_properties.push_back(property);
78     }
79     m_name_to_index.Sort();
80 }
81 
82 void
AppendProperty(const ConstString & name,const ConstString & desc,bool is_global,const OptionValueSP & value_sp)83 OptionValueProperties::AppendProperty(const ConstString &name,
84                                       const ConstString &desc,
85                                       bool is_global,
86                                       const OptionValueSP &value_sp)
87 {
88     Property property(name, desc, is_global, value_sp);
89     m_name_to_index.Append(name.GetCString(),m_properties.size());
90     m_properties.push_back(property);
91     value_sp->SetParent (shared_from_this());
92     m_name_to_index.Sort();
93 }
94 
95 
96 
97 //bool
98 //OptionValueProperties::GetQualifiedName (Stream &strm)
99 //{
100 //    bool dumped_something = false;
101 ////    lldb::OptionValuePropertiesSP parent_sp(GetParent ());
102 ////    if (parent_sp)
103 ////    {
104 ////        parent_sp->GetQualifiedName (strm);
105 ////        strm.PutChar('.');
106 ////        dumped_something = true;
107 ////    }
108 //    if (m_name)
109 //    {
110 //        strm << m_name;
111 //        dumped_something = true;
112 //    }
113 //    return dumped_something;
114 //}
115 //
116 lldb::OptionValueSP
GetValueForKey(const ExecutionContext * exe_ctx,const ConstString & key,bool will_modify) const117 OptionValueProperties::GetValueForKey  (const ExecutionContext *exe_ctx,
118                                         const ConstString &key,
119                                         bool will_modify) const
120 {
121     lldb::OptionValueSP value_sp;
122     size_t idx = m_name_to_index.Find (key.GetCString(), SIZE_MAX);
123     if (idx < m_properties.size())
124         value_sp = GetPropertyAtIndex(exe_ctx, will_modify, idx)->GetValue();
125     return value_sp;
126 }
127 
128 lldb::OptionValueSP
GetSubValue(const ExecutionContext * exe_ctx,const char * name,bool will_modify,Error & error) const129 OptionValueProperties::GetSubValue (const ExecutionContext *exe_ctx,
130                                     const char *name,
131                                     bool will_modify,
132                                     Error &error) const
133 {
134     lldb::OptionValueSP value_sp;
135 
136     if (name && name[0])
137     {
138         const char *sub_name = NULL;
139         ConstString key;
140         size_t key_len = ::strcspn (name, ".[{");
141 
142         if (name[key_len])
143         {
144             key.SetCStringWithLength (name, key_len);
145             sub_name = name + key_len;
146         }
147         else
148             key.SetCString (name);
149 
150         value_sp = GetValueForKey (exe_ctx, key, will_modify);
151         if (sub_name && value_sp)
152         {
153             switch (sub_name[0])
154             {
155             case '.':
156                 return value_sp->GetSubValue (exe_ctx, sub_name + 1, will_modify, error);
157 
158             case '{':
159                 // Predicate matching for predicates like
160                 // "<setting-name>{<predicate>}"
161                 // strings are parsed by the current OptionValueProperties subclass
162                 // to mean whatever they want to. For instance a subclass of
163                 // OptionValueProperties for a lldb_private::Target might implement:
164                 // "target.run-args{arch==i386}"   -- only set run args if the arch is i386
165                 // "target.run-args{path=/tmp/a/b/c/a.out}" -- only set run args if the path matches
166                 // "target.run-args{basename==test&&arch==x86_64}" -- only set run args if exectable basename is "test" and arch is "x86_64"
167                 if (sub_name[1])
168                 {
169                     const char *predicate_start = sub_name + 1;
170                     const char *predicate_end = strchr(predicate_start, '}');
171                     if (predicate_end)
172                     {
173                         std::string predicate(predicate_start, predicate_end);
174                         if (PredicateMatches(exe_ctx, predicate.c_str()))
175                         {
176                             if (predicate_end[1])
177                             {
178                                 // Still more subvalue string to evaluate
179                                 return value_sp->GetSubValue (exe_ctx, predicate_end + 1, will_modify, error);
180                             }
181                             else
182                             {
183                                 // We have a match!
184                                 break;
185                             }
186                         }
187                     }
188                 }
189                 // Predicate didn't match or wasn't correctly formed
190                 value_sp.reset();
191                 break;
192 
193             case '[':
194                 // Array or dictionary access for subvalues like:
195                 // "[12]"       -- access 12th array element
196                 // "['hello']"  -- dictionary access of key named hello
197                 return value_sp->GetSubValue (exe_ctx, sub_name, will_modify, error);
198 
199             default:
200                 value_sp.reset();
201                 break;
202             }
203         }
204     }
205     return value_sp;
206 }
207 
208 Error
SetSubValue(const ExecutionContext * exe_ctx,VarSetOperationType op,const char * name,const char * value)209 OptionValueProperties::SetSubValue (const ExecutionContext *exe_ctx,
210                                     VarSetOperationType op,
211                                     const char *name,
212                                     const char *value)
213 {
214     Error error;
215     const bool will_modify = true;
216     lldb::OptionValueSP value_sp (GetSubValue (exe_ctx, name, will_modify, error));
217     if (value_sp)
218         error = value_sp->SetValueFromCString(value, op);
219     else
220     {
221         if (error.AsCString() == NULL)
222             error.SetErrorStringWithFormat("invalid value path '%s'", name);
223     }
224     return error;
225 }
226 
227 
228 ConstString
GetPropertyNameAtIndex(uint32_t idx) const229 OptionValueProperties::GetPropertyNameAtIndex (uint32_t idx) const
230 {
231     const Property *property = GetPropertyAtIndex(NULL, false, idx);
232     if (property)
233         return property->GetName();
234     return ConstString();
235 
236 }
237 
238 const char *
GetPropertyDescriptionAtIndex(uint32_t idx) const239 OptionValueProperties::GetPropertyDescriptionAtIndex (uint32_t idx) const
240 {
241     const Property *property = GetPropertyAtIndex(NULL, false, idx);
242     if (property)
243         return property->GetDescription();
244     return NULL;
245 }
246 
247 uint32_t
GetPropertyIndex(const ConstString & name) const248 OptionValueProperties::GetPropertyIndex (const ConstString &name) const
249 {
250     return m_name_to_index.Find (name.GetCString(), SIZE_MAX);
251 }
252 
253 const Property *
GetProperty(const ExecutionContext * exe_ctx,bool will_modify,const ConstString & name) const254 OptionValueProperties::GetProperty (const ExecutionContext *exe_ctx, bool will_modify, const ConstString &name) const
255 {
256     return GetPropertyAtIndex (exe_ctx, will_modify, m_name_to_index.Find (name.GetCString(), SIZE_MAX));
257 }
258 
259 const Property *
GetPropertyAtIndex(const ExecutionContext * exe_ctx,bool will_modify,uint32_t idx) const260 OptionValueProperties::GetPropertyAtIndex (const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const
261 {
262     return ProtectedGetPropertyAtIndex (idx);
263 }
264 
265 lldb::OptionValueSP
GetPropertyValueAtIndex(const ExecutionContext * exe_ctx,bool will_modify,uint32_t idx) const266 OptionValueProperties::GetPropertyValueAtIndex (const ExecutionContext *exe_ctx,
267                                                 bool will_modify,
268                                                 uint32_t idx) const
269 {
270     const Property *setting = GetPropertyAtIndex (exe_ctx, will_modify, idx);
271     if (setting)
272         return setting->GetValue();
273     return OptionValueSP();
274 }
275 
276 OptionValuePathMappings *
GetPropertyAtIndexAsOptionValuePathMappings(const ExecutionContext * exe_ctx,bool will_modify,uint32_t idx) const277 OptionValueProperties::GetPropertyAtIndexAsOptionValuePathMappings (const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const
278 {
279     OptionValueSP value_sp(GetPropertyValueAtIndex (exe_ctx, will_modify, idx));
280     if (value_sp)
281         return value_sp->GetAsPathMappings();
282     return NULL;
283 }
284 
285 OptionValueFileSpecList *
GetPropertyAtIndexAsOptionValueFileSpecList(const ExecutionContext * exe_ctx,bool will_modify,uint32_t idx) const286 OptionValueProperties::GetPropertyAtIndexAsOptionValueFileSpecList (const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const
287 {
288     OptionValueSP value_sp(GetPropertyValueAtIndex (exe_ctx, will_modify, idx));
289     if (value_sp)
290         return value_sp->GetAsFileSpecList();
291     return NULL;
292 }
293 
294 OptionValueArch *
GetPropertyAtIndexAsOptionValueArch(const ExecutionContext * exe_ctx,uint32_t idx) const295 OptionValueProperties::GetPropertyAtIndexAsOptionValueArch (const ExecutionContext *exe_ctx, uint32_t idx) const
296 {
297     const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
298     if (property)
299         return property->GetValue()->GetAsArch();
300     return NULL;
301 }
302 
303 bool
GetPropertyAtIndexAsArgs(const ExecutionContext * exe_ctx,uint32_t idx,Args & args) const304 OptionValueProperties::GetPropertyAtIndexAsArgs (const ExecutionContext *exe_ctx, uint32_t idx, Args &args) const
305 {
306     const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
307     if (property)
308     {
309         OptionValue *value = property->GetValue().get();
310         if (value)
311         {
312             const OptionValueArray *array = value->GetAsArray();
313             if (array)
314                 return array->GetArgs(args);
315             else
316             {
317                 const OptionValueDictionary *dict = value->GetAsDictionary();
318                 if (dict)
319                     return dict->GetArgs(args);
320             }
321         }
322     }
323     return false;
324 }
325 
326 bool
SetPropertyAtIndexFromArgs(const ExecutionContext * exe_ctx,uint32_t idx,const Args & args)327 OptionValueProperties::SetPropertyAtIndexFromArgs (const ExecutionContext *exe_ctx, uint32_t idx, const Args &args)
328 {
329     const Property *property = GetPropertyAtIndex (exe_ctx, true, idx);
330     if (property)
331     {
332         OptionValue *value = property->GetValue().get();
333         if (value)
334         {
335             OptionValueArray *array = value->GetAsArray();
336             if (array)
337                 return array->SetArgs(args, eVarSetOperationAssign).Success();
338             else
339             {
340                 OptionValueDictionary *dict = value->GetAsDictionary();
341                 if (dict)
342                     return dict->SetArgs(args, eVarSetOperationAssign).Success();
343             }
344         }
345     }
346     return false;
347 }
348 
349 bool
GetPropertyAtIndexAsBoolean(const ExecutionContext * exe_ctx,uint32_t idx,bool fail_value) const350 OptionValueProperties::GetPropertyAtIndexAsBoolean (const ExecutionContext *exe_ctx, uint32_t idx, bool fail_value) const
351 {
352     const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
353     if (property)
354     {
355         OptionValue *value = property->GetValue().get();
356         if (value)
357             return value->GetBooleanValue(fail_value);
358     }
359     return fail_value;
360 }
361 
362 bool
SetPropertyAtIndexAsBoolean(const ExecutionContext * exe_ctx,uint32_t idx,bool new_value)363 OptionValueProperties::SetPropertyAtIndexAsBoolean (const ExecutionContext *exe_ctx, uint32_t idx, bool new_value)
364 {
365     const Property *property = GetPropertyAtIndex (exe_ctx, true, idx);
366     if (property)
367     {
368         OptionValue *value = property->GetValue().get();
369         if (value)
370         {
371             value->SetBooleanValue(new_value);
372             return true;
373         }
374     }
375     return false;
376 }
377 
378 OptionValueDictionary *
GetPropertyAtIndexAsOptionValueDictionary(const ExecutionContext * exe_ctx,uint32_t idx) const379 OptionValueProperties::GetPropertyAtIndexAsOptionValueDictionary (const ExecutionContext *exe_ctx, uint32_t idx) const
380 {
381     const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
382     if (property)
383         return property->GetValue()->GetAsDictionary();
384     return NULL;
385 }
386 
387 int64_t
GetPropertyAtIndexAsEnumeration(const ExecutionContext * exe_ctx,uint32_t idx,int64_t fail_value) const388 OptionValueProperties::GetPropertyAtIndexAsEnumeration (const ExecutionContext *exe_ctx, uint32_t idx, int64_t fail_value) const
389 {
390     const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
391     if (property)
392     {
393         OptionValue *value = property->GetValue().get();
394         if (value)
395             return value->GetEnumerationValue(fail_value);
396     }
397     return fail_value;
398 }
399 
400 bool
SetPropertyAtIndexAsEnumeration(const ExecutionContext * exe_ctx,uint32_t idx,int64_t new_value)401 OptionValueProperties::SetPropertyAtIndexAsEnumeration (const ExecutionContext *exe_ctx, uint32_t idx, int64_t new_value)
402 {
403     const Property *property = GetPropertyAtIndex (exe_ctx, true, idx);
404     if (property)
405     {
406         OptionValue *value = property->GetValue().get();
407         if (value)
408             return value->SetEnumerationValue(new_value);
409     }
410     return false;
411 }
412 
413 
414 OptionValueFileSpec *
GetPropertyAtIndexAsOptionValueFileSpec(const ExecutionContext * exe_ctx,bool will_modify,uint32_t idx) const415 OptionValueProperties::GetPropertyAtIndexAsOptionValueFileSpec (const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const
416 {
417     const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
418     if (property)
419     {
420         OptionValue *value = property->GetValue().get();
421         if (value)
422             return value->GetAsFileSpec();
423     }
424     return NULL;
425 }
426 
427 
428 FileSpec
GetPropertyAtIndexAsFileSpec(const ExecutionContext * exe_ctx,uint32_t idx) const429 OptionValueProperties::GetPropertyAtIndexAsFileSpec (const ExecutionContext *exe_ctx, uint32_t idx) const
430 {
431     const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
432     if (property)
433     {
434         OptionValue *value = property->GetValue().get();
435         if (value)
436             return value->GetFileSpecValue();
437     }
438     return FileSpec();
439 }
440 
441 
442 bool
SetPropertyAtIndexAsFileSpec(const ExecutionContext * exe_ctx,uint32_t idx,const FileSpec & new_file_spec)443 OptionValueProperties::SetPropertyAtIndexAsFileSpec (const ExecutionContext *exe_ctx, uint32_t idx, const FileSpec &new_file_spec)
444 {
445     const Property *property = GetPropertyAtIndex (exe_ctx, true, idx);
446     if (property)
447     {
448         OptionValue *value = property->GetValue().get();
449         if (value)
450             return value->SetFileSpecValue(new_file_spec);
451     }
452     return false;
453 }
454 
455 const RegularExpression *
GetPropertyAtIndexAsOptionValueRegex(const ExecutionContext * exe_ctx,uint32_t idx) const456 OptionValueProperties::GetPropertyAtIndexAsOptionValueRegex (const ExecutionContext *exe_ctx, uint32_t idx) const
457 {
458     const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
459     if (property)
460     {
461         OptionValue *value = property->GetValue().get();
462         if (value)
463             return value->GetRegexValue();
464     }
465     return NULL;
466 }
467 
468 OptionValueSInt64 *
GetPropertyAtIndexAsOptionValueSInt64(const ExecutionContext * exe_ctx,uint32_t idx) const469 OptionValueProperties::GetPropertyAtIndexAsOptionValueSInt64 (const ExecutionContext *exe_ctx, uint32_t idx) const
470 {
471     const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
472     if (property)
473     {
474         OptionValue *value = property->GetValue().get();
475         if (value)
476             return value->GetAsSInt64();
477     }
478     return NULL;
479 }
480 
481 int64_t
GetPropertyAtIndexAsSInt64(const ExecutionContext * exe_ctx,uint32_t idx,int64_t fail_value) const482 OptionValueProperties::GetPropertyAtIndexAsSInt64 (const ExecutionContext *exe_ctx, uint32_t idx, int64_t fail_value) const
483 {
484     const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
485     if (property)
486     {
487         OptionValue *value = property->GetValue().get();
488         if (value)
489             return value->GetSInt64Value(fail_value);
490     }
491     return fail_value;
492 }
493 
494 bool
SetPropertyAtIndexAsSInt64(const ExecutionContext * exe_ctx,uint32_t idx,int64_t new_value)495 OptionValueProperties::SetPropertyAtIndexAsSInt64 (const ExecutionContext *exe_ctx, uint32_t idx, int64_t new_value)
496 {
497     const Property *property = GetPropertyAtIndex (exe_ctx, true, idx);
498     if (property)
499     {
500         OptionValue *value = property->GetValue().get();
501         if (value)
502             return value->SetSInt64Value(new_value);
503     }
504     return false;
505 }
506 
507 const char *
GetPropertyAtIndexAsString(const ExecutionContext * exe_ctx,uint32_t idx,const char * fail_value) const508 OptionValueProperties::GetPropertyAtIndexAsString (const ExecutionContext *exe_ctx, uint32_t idx, const char *fail_value) const
509 {
510     const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
511     if (property)
512     {
513         OptionValue *value = property->GetValue().get();
514         if (value)
515             return value->GetStringValue(fail_value);
516     }
517     return fail_value;
518 }
519 
520 bool
SetPropertyAtIndexAsString(const ExecutionContext * exe_ctx,uint32_t idx,const char * new_value)521 OptionValueProperties::SetPropertyAtIndexAsString (const ExecutionContext *exe_ctx, uint32_t idx, const char *new_value)
522 {
523     const Property *property = GetPropertyAtIndex (exe_ctx, true, idx);
524     if (property)
525     {
526         OptionValue *value = property->GetValue().get();
527         if (value)
528             return value->SetStringValue(new_value);
529     }
530     return false;
531 }
532 
533 OptionValueString *
GetPropertyAtIndexAsOptionValueString(const ExecutionContext * exe_ctx,bool will_modify,uint32_t idx) const534 OptionValueProperties::GetPropertyAtIndexAsOptionValueString (const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const
535 {
536     OptionValueSP value_sp(GetPropertyValueAtIndex (exe_ctx, will_modify, idx));
537     if (value_sp)
538         return value_sp->GetAsString();
539     return NULL;
540 }
541 
542 
543 uint64_t
GetPropertyAtIndexAsUInt64(const ExecutionContext * exe_ctx,uint32_t idx,uint64_t fail_value) const544 OptionValueProperties::GetPropertyAtIndexAsUInt64 (const ExecutionContext *exe_ctx, uint32_t idx, uint64_t fail_value) const
545 {
546     const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
547     if (property)
548     {
549         OptionValue *value = property->GetValue().get();
550         if (value)
551             return value->GetUInt64Value(fail_value);
552     }
553     return fail_value;
554 }
555 
556 bool
SetPropertyAtIndexAsUInt64(const ExecutionContext * exe_ctx,uint32_t idx,uint64_t new_value)557 OptionValueProperties::SetPropertyAtIndexAsUInt64 (const ExecutionContext *exe_ctx, uint32_t idx, uint64_t new_value)
558 {
559     const Property *property = GetPropertyAtIndex (exe_ctx, true, idx);
560     if (property)
561     {
562         OptionValue *value = property->GetValue().get();
563         if (value)
564             return value->SetUInt64Value(new_value);
565     }
566     return false;
567 }
568 
569 bool
Clear()570 OptionValueProperties::Clear ()
571 {
572     const size_t num_properties = m_properties.size();
573     for (size_t i=0; i<num_properties; ++i)
574         m_properties[i].GetValue()->Clear();
575     return true;
576 }
577 
578 
579 Error
SetValueFromCString(const char * value,VarSetOperationType op)580 OptionValueProperties::SetValueFromCString (const char *value, VarSetOperationType op)
581 {
582     Error error;
583 
584 //    Args args(value_cstr);
585 //    const size_t argc = args.GetArgumentCount();
586     switch (op)
587     {
588         case eVarSetOperationClear:
589             Clear ();
590             break;
591 
592         case eVarSetOperationReplace:
593         case eVarSetOperationAssign:
594         case eVarSetOperationRemove:
595         case eVarSetOperationInsertBefore:
596         case eVarSetOperationInsertAfter:
597         case eVarSetOperationAppend:
598         case eVarSetOperationInvalid:
599             error = OptionValue::SetValueFromCString (value, op);
600             break;
601     }
602 
603     return error;
604 }
605 
606 void
DumpValue(const ExecutionContext * exe_ctx,Stream & strm,uint32_t dump_mask)607 OptionValueProperties::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask)
608 {
609     const size_t num_properties = m_properties.size();
610     for (size_t i=0; i<num_properties; ++i)
611     {
612         const Property *property = GetPropertyAtIndex(exe_ctx, false, i);
613         if (property)
614         {
615             OptionValue *option_value = property->GetValue().get();
616             assert (option_value);
617             const bool transparent_value = option_value->ValueIsTransparent ();
618             property->Dump (exe_ctx,
619                             strm,
620                             dump_mask);
621             if (!transparent_value)
622                 strm.EOL();
623         }
624     }
625 }
626 
627 Error
DumpPropertyValue(const ExecutionContext * exe_ctx,Stream & strm,const char * property_path,uint32_t dump_mask)628 OptionValueProperties::DumpPropertyValue (const ExecutionContext *exe_ctx,
629                                           Stream &strm,
630                                           const char *property_path,
631                                           uint32_t dump_mask)
632 {
633     Error error;
634     const bool will_modify = false;
635     lldb::OptionValueSP value_sp (GetSubValue (exe_ctx, property_path, will_modify, error));
636     if (value_sp)
637     {
638         if (!value_sp->ValueIsTransparent ())
639         {
640             if (dump_mask & eDumpOptionName)
641                 strm.PutCString (property_path);
642             if (dump_mask & ~eDumpOptionName)
643                 strm.PutChar (' ');
644         }
645         value_sp->DumpValue (exe_ctx, strm, dump_mask);
646     }
647     return error;
648 }
649 
650 lldb::OptionValueSP
DeepCopy() const651 OptionValueProperties::DeepCopy () const
652 {
653     assert(!"this shouldn't happen");
654 }
655 
656 const Property *
GetPropertyAtPath(const ExecutionContext * exe_ctx,bool will_modify,const char * name) const657 OptionValueProperties::GetPropertyAtPath (const ExecutionContext *exe_ctx,
658                                           bool will_modify,
659                                           const char *name) const
660 {
661     const Property *property = NULL;
662     if (name && name[0])
663     {
664         const char *sub_name = NULL;
665         ConstString key;
666         size_t key_len = ::strcspn (name, ".[{");
667 
668         if (name[key_len])
669         {
670             key.SetCStringWithLength (name, key_len);
671             sub_name = name + key_len;
672         }
673         else
674             key.SetCString (name);
675 
676         property = GetProperty (exe_ctx, will_modify, key);
677         if (sub_name && property)
678         {
679             if (sub_name[0] == '.')
680             {
681                 OptionValueProperties *sub_properties = property->GetValue()->GetAsProperties();
682                 if (sub_properties)
683                     return sub_properties->GetPropertyAtPath(exe_ctx, will_modify, sub_name + 1);
684             }
685             property = NULL;
686         }
687     }
688     return property;
689 }
690 
691 void
DumpAllDescriptions(CommandInterpreter & interpreter,Stream & strm) const692 OptionValueProperties::DumpAllDescriptions (CommandInterpreter &interpreter,
693                                             Stream &strm) const
694 {
695     size_t max_name_len = 0;
696     const size_t num_properties = m_properties.size();
697     for (size_t i=0; i<num_properties; ++i)
698     {
699         const Property *property = ProtectedGetPropertyAtIndex(i);
700         if (property)
701             max_name_len = std::max<size_t>(property->GetName().GetLength(), max_name_len);
702     }
703     for (size_t i=0; i<num_properties; ++i)
704     {
705         const Property *property = ProtectedGetPropertyAtIndex(i);
706         if (property)
707             property->DumpDescription (interpreter, strm, max_name_len, false);
708     }
709 }
710 
711 void
Apropos(const char * keyword,std::vector<const Property * > & matching_properties) const712 OptionValueProperties::Apropos (const char *keyword, std::vector<const Property *> &matching_properties) const
713 {
714     const size_t num_properties = m_properties.size();
715     StreamString strm;
716     for (size_t i=0; i<num_properties; ++i)
717     {
718         const Property *property = ProtectedGetPropertyAtIndex(i);
719         if (property)
720         {
721             const OptionValueProperties *properties = property->GetValue()->GetAsProperties();
722             if (properties)
723             {
724                 properties->Apropos (keyword, matching_properties);
725             }
726             else
727             {
728                 bool match = false;
729                 const char *name = property->GetName().GetCString();
730                 if (name && ::strcasestr(name, keyword))
731                     match = true;
732                 else
733                 {
734                     const char *desc = property->GetDescription();
735                     if (desc && ::strcasestr(desc, keyword))
736                         match = true;
737                 }
738                 if (match)
739                 {
740                     matching_properties.push_back (property);
741                 }
742             }
743         }
744     }
745 }
746 
747 lldb::OptionValuePropertiesSP
GetSubProperty(const ExecutionContext * exe_ctx,const ConstString & name)748 OptionValueProperties::GetSubProperty (const ExecutionContext *exe_ctx,
749                                        const ConstString &name)
750 {
751     lldb::OptionValueSP option_value_sp(GetValueForKey(exe_ctx, name, false));
752     if (option_value_sp)
753     {
754         OptionValueProperties *ov_properties = option_value_sp->GetAsProperties ();
755         if (ov_properties)
756             return ov_properties->shared_from_this();
757     }
758     return lldb::OptionValuePropertiesSP();
759 }
760 
761 
762 
763