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