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