]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - source/Interpreter/OptionValueProperties.cpp
Vendor import of lldb release_39 branch r276489:
[FreeBSD/FreeBSD.git] / source / Interpreter / OptionValueProperties.cpp
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
28 OptionValueProperties::OptionValueProperties (const ConstString &name) :
29     OptionValue (),
30     m_name (name),
31     m_properties (),
32     m_name_to_index ()
33 {
34 }
35
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
63 OptionValueProperties::GetNumProperties() const
64 {
65     return m_properties.size();
66 }
67
68
69 void
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
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
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
128 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
140 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             {
168                 lldb::OptionValueSP return_val_sp;
169                 return_val_sp = value_sp->GetSubValue (exe_ctx, sub_name + 1, will_modify, error);
170                 if (!return_val_sp)
171                 {
172                     if (Properties::IsSettingExperimental(sub_name + 1))
173                     {
174                         size_t experimental_len = strlen(Properties::GetExperimentalSettingsName()); 
175                         if (*(sub_name + experimental_len + 1) == '.')
176                         return_val_sp = value_sp->GetSubValue(exe_ctx, sub_name + experimental_len + 2, will_modify, error);
177                         // It isn't an error if an experimental setting is not present.
178                         if (!return_val_sp)
179                             error.Clear();
180                     }
181                 }
182                 return return_val_sp;
183             }
184             case '{':
185                 // Predicate matching for predicates like
186                 // "<setting-name>{<predicate>}"
187                 // strings are parsed by the current OptionValueProperties subclass
188                 // to mean whatever they want to. For instance a subclass of
189                 // OptionValueProperties for a lldb_private::Target might implement:
190                 // "target.run-args{arch==i386}"   -- only set run args if the arch is i386
191                 // "target.run-args{path=/tmp/a/b/c/a.out}" -- only set run args if the path matches
192                 // "target.run-args{basename==test&&arch==x86_64}" -- only set run args if executable basename is "test" and arch is "x86_64"
193                 if (sub_name[1])
194                 {
195                     const char *predicate_start = sub_name + 1;
196                     const char *predicate_end = strchr(predicate_start, '}');
197                     if (predicate_end)
198                     {
199                         std::string predicate(predicate_start, predicate_end);
200                         if (PredicateMatches(exe_ctx, predicate.c_str()))
201                         {
202                             if (predicate_end[1])
203                             {
204                                 // Still more subvalue string to evaluate
205                                 return value_sp->GetSubValue (exe_ctx, predicate_end + 1, will_modify, error);
206                             }
207                             else
208                             {
209                                 // We have a match!
210                                 break;
211                             }
212                         }
213                     }
214                 }
215                 // Predicate didn't match or wasn't correctly formed
216                 value_sp.reset();
217                 break;
218             
219             case '[':
220                 // Array or dictionary access for subvalues like:
221                 // "[12]"       -- access 12th array element
222                 // "['hello']"  -- dictionary access of key named hello
223                 return value_sp->GetSubValue (exe_ctx, sub_name, will_modify, error);
224
225             default:
226                 value_sp.reset();
227                 break;
228             }
229         }
230     }
231     return value_sp;
232 }
233
234 Error
235 OptionValueProperties::SetSubValue (const ExecutionContext *exe_ctx,
236                                     VarSetOperationType op,
237                                     const char *name,
238                                     const char *value)
239 {
240     Error error;
241     const bool will_modify = true;
242     lldb::OptionValueSP value_sp (GetSubValue (exe_ctx, name, will_modify, error));
243     if (value_sp)
244         error = value_sp->SetValueFromString(value ? llvm::StringRef(value) : llvm::StringRef(), op);
245     else
246     {
247         if (error.AsCString() == nullptr)
248             error.SetErrorStringWithFormat("invalid value path '%s'", name);
249     }
250     return error;
251 }
252
253
254 ConstString
255 OptionValueProperties::GetPropertyNameAtIndex (uint32_t idx) const
256 {
257     const Property *property = GetPropertyAtIndex(nullptr, false, idx);
258     if (property)
259         return property->GetName();
260     return ConstString();
261     
262 }
263
264 const char *
265 OptionValueProperties::GetPropertyDescriptionAtIndex (uint32_t idx) const
266 {
267     const Property *property = GetPropertyAtIndex(nullptr, false, idx);
268     if (property)
269         return property->GetDescription();
270     return nullptr;
271 }
272
273 uint32_t
274 OptionValueProperties::GetPropertyIndex (const ConstString &name) const
275 {
276     return m_name_to_index.Find (name.GetCString(), SIZE_MAX);
277 }
278
279 const Property *
280 OptionValueProperties::GetProperty (const ExecutionContext *exe_ctx, bool will_modify, const ConstString &name) const
281 {
282     return GetPropertyAtIndex (exe_ctx, will_modify, m_name_to_index.Find (name.GetCString(), SIZE_MAX));
283 }
284
285 const Property *
286 OptionValueProperties::GetPropertyAtIndex (const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const
287 {
288     return ProtectedGetPropertyAtIndex (idx);
289 }
290
291 lldb::OptionValueSP
292 OptionValueProperties::GetPropertyValueAtIndex (const ExecutionContext *exe_ctx,
293                                                 bool will_modify,
294                                                 uint32_t idx) const
295 {
296     const Property *setting = GetPropertyAtIndex (exe_ctx, will_modify, idx);
297     if (setting)
298         return setting->GetValue();
299     return OptionValueSP();
300 }
301
302 OptionValuePathMappings *
303 OptionValueProperties::GetPropertyAtIndexAsOptionValuePathMappings (const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const
304 {
305     OptionValueSP value_sp(GetPropertyValueAtIndex (exe_ctx, will_modify, idx));
306     if (value_sp)
307         return value_sp->GetAsPathMappings();
308     return nullptr;
309 }
310
311 OptionValueFileSpecList *
312 OptionValueProperties::GetPropertyAtIndexAsOptionValueFileSpecList (const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const
313 {
314     OptionValueSP value_sp(GetPropertyValueAtIndex (exe_ctx, will_modify, idx));
315     if (value_sp)
316         return value_sp->GetAsFileSpecList();
317     return nullptr;
318 }
319
320 OptionValueArch *
321 OptionValueProperties::GetPropertyAtIndexAsOptionValueArch (const ExecutionContext *exe_ctx, uint32_t idx) const
322 {
323     const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
324     if (property)
325         return property->GetValue()->GetAsArch();
326     return nullptr;
327 }
328
329 OptionValueLanguage *
330 OptionValueProperties::GetPropertyAtIndexAsOptionValueLanguage (const ExecutionContext *exe_ctx, uint32_t idx) const
331 {
332     const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
333     if (property)
334         return property->GetValue()->GetAsLanguage();
335     return nullptr;
336 }
337
338 bool
339 OptionValueProperties::GetPropertyAtIndexAsArgs (const ExecutionContext *exe_ctx, uint32_t idx, Args &args) const
340 {
341     const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
342     if (property)
343     {
344         OptionValue *value = property->GetValue().get();
345         if (value)
346         {
347             const OptionValueArray *array = value->GetAsArray();
348             if (array)
349                 return array->GetArgs(args);
350             else
351             {
352                 const OptionValueDictionary *dict = value->GetAsDictionary();
353                 if (dict)
354                     return dict->GetArgs(args);
355             }
356         }
357     }
358     return false;
359 }
360
361 bool
362 OptionValueProperties::SetPropertyAtIndexFromArgs (const ExecutionContext *exe_ctx, uint32_t idx, const Args &args)
363 {
364     const Property *property = GetPropertyAtIndex (exe_ctx, true, idx);
365     if (property)
366     {
367         OptionValue *value = property->GetValue().get();
368         if (value)
369         {
370             OptionValueArray *array = value->GetAsArray();
371             if (array)
372                 return array->SetArgs(args, eVarSetOperationAssign).Success();
373             else
374             {
375                 OptionValueDictionary *dict = value->GetAsDictionary();
376                 if (dict)
377                     return dict->SetArgs(args, eVarSetOperationAssign).Success();
378             }
379         }
380     }
381     return false;
382 }
383
384 bool
385 OptionValueProperties::GetPropertyAtIndexAsBoolean (const ExecutionContext *exe_ctx, uint32_t idx, bool fail_value) const
386 {
387     const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
388     if (property)
389     {
390         OptionValue *value = property->GetValue().get();
391         if (value)
392             return value->GetBooleanValue(fail_value);
393     }
394     return fail_value;
395 }
396
397 bool
398 OptionValueProperties::SetPropertyAtIndexAsBoolean (const ExecutionContext *exe_ctx, uint32_t idx, bool new_value)
399 {
400     const Property *property = GetPropertyAtIndex (exe_ctx, true, idx);
401     if (property)
402     {
403         OptionValue *value = property->GetValue().get();
404         if (value)
405         {
406             value->SetBooleanValue(new_value);
407             return true;
408         }
409     }
410     return false;
411 }
412
413 OptionValueDictionary *
414 OptionValueProperties::GetPropertyAtIndexAsOptionValueDictionary (const ExecutionContext *exe_ctx, uint32_t idx) const
415 {
416     const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
417     if (property)
418         return property->GetValue()->GetAsDictionary();
419     return nullptr;
420 }
421
422 int64_t
423 OptionValueProperties::GetPropertyAtIndexAsEnumeration (const ExecutionContext *exe_ctx, uint32_t idx, int64_t fail_value) const
424 {
425     const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
426     if (property)
427     {
428         OptionValue *value = property->GetValue().get();
429         if (value)
430             return value->GetEnumerationValue(fail_value);
431     }
432     return fail_value;
433 }
434
435 bool
436 OptionValueProperties::SetPropertyAtIndexAsEnumeration (const ExecutionContext *exe_ctx, uint32_t idx, int64_t new_value)
437 {
438     const Property *property = GetPropertyAtIndex (exe_ctx, true, idx);
439     if (property)
440     {
441         OptionValue *value = property->GetValue().get();
442         if (value)
443             return value->SetEnumerationValue(new_value);
444     }
445     return false;
446 }
447
448 const FormatEntity::Entry *
449 OptionValueProperties::GetPropertyAtIndexAsFormatEntity (const ExecutionContext *exe_ctx, uint32_t idx)
450 {
451     const Property *property = GetPropertyAtIndex (exe_ctx, true, idx);
452     if (property)
453     {
454         OptionValue *value = property->GetValue().get();
455         if (value)
456             return value->GetFormatEntity();
457     }
458     return nullptr;
459 }
460
461 OptionValueFileSpec *
462 OptionValueProperties::GetPropertyAtIndexAsOptionValueFileSpec (const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const
463 {
464     const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
465     if (property)
466     {
467         OptionValue *value = property->GetValue().get();
468         if (value)
469             return value->GetAsFileSpec();
470     }
471     return nullptr;
472 }
473
474
475 FileSpec
476 OptionValueProperties::GetPropertyAtIndexAsFileSpec (const ExecutionContext *exe_ctx, uint32_t idx) const
477 {
478     const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
479     if (property)
480     {
481         OptionValue *value = property->GetValue().get();
482         if (value)
483             return value->GetFileSpecValue();
484     }
485     return FileSpec();
486 }
487
488
489 bool
490 OptionValueProperties::SetPropertyAtIndexAsFileSpec (const ExecutionContext *exe_ctx, uint32_t idx, const FileSpec &new_file_spec)
491 {
492     const Property *property = GetPropertyAtIndex (exe_ctx, true, idx);
493     if (property)
494     {
495         OptionValue *value = property->GetValue().get();
496         if (value)
497             return value->SetFileSpecValue(new_file_spec);
498     }
499     return false;
500 }
501
502 const RegularExpression *
503 OptionValueProperties::GetPropertyAtIndexAsOptionValueRegex (const ExecutionContext *exe_ctx, uint32_t idx) const
504 {
505     const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
506     if (property)
507     {
508         OptionValue *value = property->GetValue().get();
509         if (value)
510             return value->GetRegexValue();
511     }
512     return nullptr;
513 }
514
515 OptionValueSInt64 *
516 OptionValueProperties::GetPropertyAtIndexAsOptionValueSInt64 (const ExecutionContext *exe_ctx, uint32_t idx) const
517 {
518     const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
519     if (property)
520     {
521         OptionValue *value = property->GetValue().get();
522         if (value)
523             return value->GetAsSInt64();
524     }
525     return nullptr;
526 }
527
528 int64_t
529 OptionValueProperties::GetPropertyAtIndexAsSInt64 (const ExecutionContext *exe_ctx, uint32_t idx, int64_t fail_value) const
530 {
531     const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
532     if (property)
533     {
534         OptionValue *value = property->GetValue().get();
535         if (value)
536             return value->GetSInt64Value(fail_value);
537     }
538     return fail_value;
539 }
540
541 bool
542 OptionValueProperties::SetPropertyAtIndexAsSInt64 (const ExecutionContext *exe_ctx, uint32_t idx, int64_t new_value)
543 {
544     const Property *property = GetPropertyAtIndex (exe_ctx, true, idx);
545     if (property)
546     {
547         OptionValue *value = property->GetValue().get();
548         if (value)
549             return value->SetSInt64Value(new_value);
550     }
551     return false;
552 }
553
554 const char *
555 OptionValueProperties::GetPropertyAtIndexAsString (const ExecutionContext *exe_ctx, uint32_t idx, const char *fail_value) const
556 {
557     const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
558     if (property)
559     {
560         OptionValue *value = property->GetValue().get();
561         if (value)
562             return value->GetStringValue(fail_value);
563     }
564     return fail_value;
565 }
566
567 bool
568 OptionValueProperties::SetPropertyAtIndexAsString (const ExecutionContext *exe_ctx, uint32_t idx, const char *new_value)
569 {
570     const Property *property = GetPropertyAtIndex (exe_ctx, true, idx);
571     if (property)
572     {
573         OptionValue *value = property->GetValue().get();
574         if (value)
575             return value->SetStringValue(new_value);
576     }
577     return false;
578 }
579
580 OptionValueString *
581 OptionValueProperties::GetPropertyAtIndexAsOptionValueString (const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const
582 {
583     OptionValueSP value_sp(GetPropertyValueAtIndex (exe_ctx, will_modify, idx));
584     if (value_sp)
585         return value_sp->GetAsString();
586     return nullptr;
587 }
588
589
590 uint64_t
591 OptionValueProperties::GetPropertyAtIndexAsUInt64 (const ExecutionContext *exe_ctx, uint32_t idx, uint64_t fail_value) const
592 {
593     const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
594     if (property)
595     {
596         OptionValue *value = property->GetValue().get();
597         if (value)
598             return value->GetUInt64Value(fail_value);
599     }
600     return fail_value;
601 }
602
603 bool
604 OptionValueProperties::SetPropertyAtIndexAsUInt64 (const ExecutionContext *exe_ctx, uint32_t idx, uint64_t new_value)
605 {
606     const Property *property = GetPropertyAtIndex (exe_ctx, true, idx);
607     if (property)
608     {
609         OptionValue *value = property->GetValue().get();
610         if (value)
611             return value->SetUInt64Value(new_value);
612     }
613     return false;
614 }
615
616 bool
617 OptionValueProperties::Clear ()
618 {
619     const size_t num_properties = m_properties.size();
620     for (size_t i=0; i<num_properties; ++i)
621         m_properties[i].GetValue()->Clear();
622     return true;
623 }
624
625
626 Error
627 OptionValueProperties::SetValueFromString (llvm::StringRef value, VarSetOperationType op)
628 {
629     Error error;
630     
631 //    Args args(value_cstr);
632 //    const size_t argc = args.GetArgumentCount();
633     switch (op)
634     {
635         case eVarSetOperationClear:
636             Clear ();
637             break;
638             
639         case eVarSetOperationReplace:
640         case eVarSetOperationAssign:
641         case eVarSetOperationRemove:
642         case eVarSetOperationInsertBefore:
643         case eVarSetOperationInsertAfter:
644         case eVarSetOperationAppend:
645         case eVarSetOperationInvalid:
646             error = OptionValue::SetValueFromString (value, op);
647             break;
648     }
649     
650     return error;
651 }
652
653 void
654 OptionValueProperties::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask)
655 {
656     const size_t num_properties = m_properties.size();
657     for (size_t i=0; i<num_properties; ++i)
658     {
659         const Property *property = GetPropertyAtIndex(exe_ctx, false, i);
660         if (property)
661         {
662             OptionValue *option_value = property->GetValue().get();
663             assert (option_value);
664             const bool transparent_value = option_value->ValueIsTransparent ();
665             property->Dump (exe_ctx,
666                             strm,
667                             dump_mask);
668             if (!transparent_value)
669                 strm.EOL();
670         }
671     }
672 }
673
674 Error
675 OptionValueProperties::DumpPropertyValue (const ExecutionContext *exe_ctx,
676                                           Stream &strm,
677                                           const char *property_path,
678                                           uint32_t dump_mask)
679 {
680     Error error;
681     const bool will_modify = false;
682     lldb::OptionValueSP value_sp (GetSubValue (exe_ctx, property_path, will_modify, error));
683     if (value_sp)
684     {
685         if (!value_sp->ValueIsTransparent ())
686         {
687             if (dump_mask & eDumpOptionName)
688                 strm.PutCString (property_path);
689             if (dump_mask & ~eDumpOptionName)
690                 strm.PutChar (' ');
691         }
692         value_sp->DumpValue (exe_ctx, strm, dump_mask);
693     }
694     return error;
695 }
696
697 lldb::OptionValueSP
698 OptionValueProperties::DeepCopy () const
699 {
700     assert(!"this shouldn't happen");
701     return lldb::OptionValueSP();
702 }
703
704 const Property *
705 OptionValueProperties::GetPropertyAtPath (const ExecutionContext *exe_ctx,
706                                           bool will_modify,
707                                           const char *name) const
708 {
709     const Property *property = nullptr;
710     if (name && name[0])
711     {
712         const char *sub_name = nullptr;
713         ConstString key;
714         size_t key_len = ::strcspn (name, ".[{");
715         
716         if (name[key_len])
717         {
718             key.SetCStringWithLength (name, key_len);
719             sub_name = name + key_len;
720         }
721         else
722             key.SetCString (name);
723         
724         property = GetProperty (exe_ctx, will_modify, key);
725         if (sub_name && property)
726         {
727             if (sub_name[0] == '.')
728             {
729                 OptionValueProperties *sub_properties = property->GetValue()->GetAsProperties();
730                 if (sub_properties)
731                     return sub_properties->GetPropertyAtPath(exe_ctx, will_modify, sub_name + 1);
732             }
733             property = nullptr;
734         }
735     }
736     return property;
737 }
738
739 void
740 OptionValueProperties::DumpAllDescriptions (CommandInterpreter &interpreter,
741                                             Stream &strm) const
742 {
743     size_t max_name_len = 0;
744     const size_t num_properties = m_properties.size();
745     for (size_t i=0; i<num_properties; ++i)
746     {
747         const Property *property = ProtectedGetPropertyAtIndex(i);
748         if (property)
749             max_name_len = std::max<size_t>(property->GetName().GetLength(), max_name_len);
750     }
751     for (size_t i=0; i<num_properties; ++i)
752     {
753         const Property *property = ProtectedGetPropertyAtIndex(i);
754         if (property)
755             property->DumpDescription (interpreter, strm, max_name_len, false);
756     }
757 }
758
759 void
760 OptionValueProperties::Apropos (const char *keyword, std::vector<const Property *> &matching_properties) const
761 {
762     const size_t num_properties = m_properties.size();
763     StreamString strm;
764     for (size_t i=0; i<num_properties; ++i)
765     {
766         const Property *property = ProtectedGetPropertyAtIndex(i);
767         if (property)
768         {
769             const OptionValueProperties *properties = property->GetValue()->GetAsProperties();
770             if (properties)
771             {
772                 properties->Apropos (keyword, matching_properties);
773             }
774             else
775             {
776                 bool match = false;
777                 const char *name = property->GetName().GetCString();
778                 if (name && ::strcasestr(name, keyword))
779                     match = true;
780                 else
781                 {
782                     const char *desc = property->GetDescription();
783                     if (desc && ::strcasestr(desc, keyword))
784                         match = true;
785                 }
786                 if (match)
787                 {
788                     matching_properties.push_back (property);
789                 }
790             }
791         }
792     }
793 }
794
795 lldb::OptionValuePropertiesSP
796 OptionValueProperties::GetSubProperty (const ExecutionContext *exe_ctx,
797                                        const ConstString &name)
798 {
799     lldb::OptionValueSP option_value_sp(GetValueForKey(exe_ctx, name, false));
800     if (option_value_sp)
801     {
802         OptionValueProperties *ov_properties = option_value_sp->GetAsProperties ();
803         if (ov_properties)
804             return ov_properties->shared_from_this();
805     }
806     return lldb::OptionValuePropertiesSP();
807 }
808
809
810