1 //===-- OptionValue.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/OptionValue.h"
11 
12 // C Includes
13 // C++ Includes
14 // Other libraries and framework includes
15 // Project includes
16 #include "lldb/Core/StringList.h"
17 #include "lldb/Interpreter/OptionValues.h"
18 
19 using namespace lldb;
20 using namespace lldb_private;
21 
22 
23 //-------------------------------------------------------------------------
24 // Get this value as a uint64_t value if it is encoded as a boolean,
25 // uint64_t or int64_t. Other types will cause "fail_value" to be
26 // returned
27 //-------------------------------------------------------------------------
28 uint64_t
29 OptionValue::GetUInt64Value (uint64_t fail_value, bool *success_ptr)
30 {
31     if (success_ptr)
32         *success_ptr = true;
33     switch (GetType())
34     {
35     case OptionValue::eTypeBoolean: return static_cast<OptionValueBoolean *>(this)->GetCurrentValue();
36     case OptionValue::eTypeSInt64:  return static_cast<OptionValueSInt64 *>(this)->GetCurrentValue();
37     case OptionValue::eTypeUInt64:  return static_cast<OptionValueUInt64 *>(this)->GetCurrentValue();
38     default:
39         break;
40     }
41     if (success_ptr)
42         *success_ptr = false;
43     return fail_value;
44 }
45 
46 Error
47 OptionValue::SetSubValue (const ExecutionContext *exe_ctx,
48                           VarSetOperationType op,
49                           const char *name,
50                           const char *value)
51 {
52     Error error;
53     error.SetErrorStringWithFormat("SetSubValue is not supported");
54     return error;
55 }
56 
57 
58 OptionValueBoolean *
59 OptionValue::GetAsBoolean ()
60 {
61     if (GetType () == OptionValue::eTypeBoolean)
62         return static_cast<OptionValueBoolean *>(this);
63     return nullptr;
64 }
65 
66 const OptionValueBoolean *
67 OptionValue::GetAsBoolean () const
68 {
69     if (GetType () == OptionValue::eTypeBoolean)
70         return static_cast<const OptionValueBoolean *>(this);
71     return nullptr;
72 }
73 
74 const OptionValueChar *
75 OptionValue::GetAsChar () const
76 {
77     if (GetType () == OptionValue::eTypeChar)
78         return static_cast<const OptionValueChar *>(this);
79     return nullptr;
80 }
81 
82 OptionValueChar *
83 OptionValue::GetAsChar ()
84 {
85     if (GetType () == OptionValue::eTypeChar)
86         return static_cast<OptionValueChar *>(this);
87     return nullptr;
88 }
89 
90 OptionValueFileSpec *
91 OptionValue::GetAsFileSpec ()
92 {
93     if (GetType () == OptionValue::eTypeFileSpec)
94         return static_cast<OptionValueFileSpec *>(this);
95     return nullptr;
96 
97 }
98 
99 const OptionValueFileSpec *
100 OptionValue::GetAsFileSpec () const
101 {
102     if (GetType () == OptionValue::eTypeFileSpec)
103         return static_cast<const OptionValueFileSpec *>(this);
104     return nullptr;
105 
106 }
107 
108 OptionValueFileSpecList *
109 OptionValue::GetAsFileSpecList ()
110 {
111     if (GetType () == OptionValue::eTypeFileSpecList)
112         return static_cast<OptionValueFileSpecList *>(this);
113     return nullptr;
114 
115 }
116 
117 const OptionValueFileSpecList *
118 OptionValue::GetAsFileSpecList () const
119 {
120     if (GetType () == OptionValue::eTypeFileSpecList)
121         return static_cast<const OptionValueFileSpecList *>(this);
122     return nullptr;
123 
124 }
125 
126 OptionValueArch *
127 OptionValue::GetAsArch ()
128 {
129     if (GetType () == OptionValue::eTypeArch)
130         return static_cast<OptionValueArch *>(this);
131     return nullptr;
132 }
133 
134 
135 const OptionValueArch *
136 OptionValue::GetAsArch () const
137 {
138     if (GetType () == OptionValue::eTypeArch)
139         return static_cast<const OptionValueArch *>(this);
140     return nullptr;
141 }
142 
143 OptionValueArray *
144 OptionValue::GetAsArray ()
145 {
146     if (GetType () == OptionValue::eTypeArray)
147         return static_cast<OptionValueArray *>(this);
148     return nullptr;
149 }
150 
151 
152 const OptionValueArray *
153 OptionValue::GetAsArray () const
154 {
155     if (GetType () == OptionValue::eTypeArray)
156         return static_cast<const OptionValueArray *>(this);
157     return nullptr;
158 }
159 
160 OptionValueArgs *
161 OptionValue::GetAsArgs ()
162 {
163     if (GetType () == OptionValue::eTypeArgs)
164         return static_cast<OptionValueArgs *>(this);
165     return nullptr;
166 }
167 
168 
169 const OptionValueArgs *
170 OptionValue::GetAsArgs () const
171 {
172     if (GetType () == OptionValue::eTypeArgs)
173         return static_cast<const OptionValueArgs *>(this);
174     return nullptr;
175 }
176 
177 OptionValueDictionary *
178 OptionValue::GetAsDictionary ()
179 {
180     if (GetType () == OptionValue::eTypeDictionary)
181         return static_cast<OptionValueDictionary *>(this);
182     return nullptr;
183 }
184 
185 const OptionValueDictionary *
186 OptionValue::GetAsDictionary () const
187 {
188     if (GetType () == OptionValue::eTypeDictionary)
189         return static_cast<const OptionValueDictionary *>(this);
190     return nullptr;
191 }
192 
193 OptionValueEnumeration *
194 OptionValue::GetAsEnumeration ()
195 {
196     if (GetType () == OptionValue::eTypeEnum)
197         return static_cast<OptionValueEnumeration *>(this);
198     return nullptr;
199 }
200 
201 const OptionValueEnumeration *
202 OptionValue::GetAsEnumeration () const
203 {
204     if (GetType () == OptionValue::eTypeEnum)
205         return static_cast<const OptionValueEnumeration *>(this);
206     return nullptr;
207 }
208 
209 OptionValueFormat *
210 OptionValue::GetAsFormat ()
211 {
212     if (GetType () == OptionValue::eTypeFormat)
213         return static_cast<OptionValueFormat *>(this);
214     return nullptr;
215 }
216 
217 const OptionValueFormat *
218 OptionValue::GetAsFormat () const
219 {
220     if (GetType () == OptionValue::eTypeFormat)
221         return static_cast<const OptionValueFormat *>(this);
222     return nullptr;
223 }
224 
225 OptionValueFormatEntity *
226 OptionValue::GetAsFormatEntity ()
227 {
228     if (GetType () == OptionValue::eTypeFormatEntity)
229         return static_cast<OptionValueFormatEntity *>(this);
230     return nullptr;
231 }
232 
233 const OptionValueFormatEntity *
234 OptionValue::GetAsFormatEntity () const
235 {
236     if (GetType () == OptionValue::eTypeFormatEntity)
237         return static_cast<const OptionValueFormatEntity *>(this);
238     return nullptr;
239 }
240 
241 OptionValuePathMappings *
242 OptionValue::GetAsPathMappings ()
243 {
244     if (GetType () == OptionValue::eTypePathMap)
245         return static_cast<OptionValuePathMappings *>(this);
246     return nullptr;
247 }
248 
249 const OptionValuePathMappings *
250 OptionValue::GetAsPathMappings () const
251 {
252     if (GetType () == OptionValue::eTypePathMap)
253         return static_cast<const OptionValuePathMappings *>(this);
254     return nullptr;
255 }
256 
257 OptionValueProperties *
258 OptionValue::GetAsProperties ()
259 {
260     if (GetType () == OptionValue::eTypeProperties)
261         return static_cast<OptionValueProperties *>(this);
262     return nullptr;
263 }
264 
265 const OptionValueProperties *
266 OptionValue::GetAsProperties () const
267 {
268     if (GetType () == OptionValue::eTypeProperties)
269         return static_cast<const OptionValueProperties *>(this);
270     return nullptr;
271 }
272 
273 OptionValueRegex *
274 OptionValue::GetAsRegex ()
275 {
276     if (GetType () == OptionValue::eTypeRegex)
277         return static_cast<OptionValueRegex *>(this);
278     return nullptr;
279 }
280 
281 const OptionValueRegex *
282 OptionValue::GetAsRegex () const
283 {
284     if (GetType () == OptionValue::eTypeRegex)
285         return static_cast<const OptionValueRegex *>(this);
286     return nullptr;
287 }
288 
289 OptionValueSInt64 *
290 OptionValue::GetAsSInt64 ()
291 {
292     if (GetType () == OptionValue::eTypeSInt64)
293         return static_cast<OptionValueSInt64 *>(this);
294     return nullptr;
295 }
296 
297 const OptionValueSInt64 *
298 OptionValue::GetAsSInt64 () const
299 {
300     if (GetType () == OptionValue::eTypeSInt64)
301         return static_cast<const OptionValueSInt64 *>(this);
302     return nullptr;
303 }
304 
305 OptionValueString *
306 OptionValue::GetAsString ()
307 {
308     if (GetType () == OptionValue::eTypeString)
309         return static_cast<OptionValueString *>(this);
310     return nullptr;
311 }
312 
313 const OptionValueString *
314 OptionValue::GetAsString () const
315 {
316     if (GetType () == OptionValue::eTypeString)
317         return static_cast<const OptionValueString *>(this);
318     return nullptr;
319 }
320 
321 OptionValueUInt64 *
322 OptionValue::GetAsUInt64 ()
323 {
324     if (GetType () == OptionValue::eTypeUInt64)
325         return static_cast<OptionValueUInt64 *>(this);
326     return nullptr;
327 }
328 
329 const OptionValueUInt64 *
330 OptionValue::GetAsUInt64 () const
331 {
332     if (GetType () == OptionValue::eTypeUInt64)
333         return static_cast<const OptionValueUInt64 *>(this);
334     return nullptr;
335 }
336 
337 OptionValueUUID *
338 OptionValue::GetAsUUID ()
339 {
340     if (GetType () == OptionValue::eTypeUUID)
341         return static_cast<OptionValueUUID *>(this);
342     return nullptr;
343 
344 }
345 
346 const OptionValueUUID *
347 OptionValue::GetAsUUID () const
348 {
349     if (GetType () == OptionValue::eTypeUUID)
350         return static_cast<const OptionValueUUID *>(this);
351     return nullptr;
352 
353 }
354 
355 bool
356 OptionValue::GetBooleanValue (bool fail_value) const
357 {
358     const OptionValueBoolean *option_value = GetAsBoolean ();
359     if (option_value)
360         return option_value->GetCurrentValue();
361     return fail_value;
362 }
363 
364 bool
365 OptionValue::SetBooleanValue (bool new_value)
366 {
367     OptionValueBoolean *option_value = GetAsBoolean ();
368     if (option_value)
369     {
370         option_value->SetCurrentValue(new_value);
371         return true;
372     }
373     return false;
374 }
375 
376 char
377 OptionValue::GetCharValue(char fail_value) const
378 {
379     const OptionValueChar *option_value = GetAsChar();
380     if (option_value)
381         return option_value->GetCurrentValue();
382     return fail_value;
383 }
384 
385 char
386 OptionValue::SetCharValue(char new_value)
387 {
388     OptionValueChar *option_value = GetAsChar();
389     if (option_value)
390     {
391         option_value->SetCurrentValue(new_value);
392         return true;
393     }
394     return false;
395 }
396 
397 int64_t
398 OptionValue::GetEnumerationValue (int64_t fail_value) const
399 {
400     const OptionValueEnumeration *option_value = GetAsEnumeration();
401     if (option_value)
402         return option_value->GetCurrentValue();
403     return fail_value;
404 }
405 
406 bool
407 OptionValue::SetEnumerationValue (int64_t value)
408 {
409     OptionValueEnumeration *option_value = GetAsEnumeration();
410     if (option_value)
411     {
412         option_value->SetCurrentValue(value);
413         return true;
414     }
415     return false;
416 }
417 
418 FileSpec
419 OptionValue::GetFileSpecValue () const
420 {
421     const OptionValueFileSpec *option_value = GetAsFileSpec ();
422     if (option_value)
423         return option_value->GetCurrentValue();
424     return FileSpec();
425 }
426 
427 
428 bool
429 OptionValue::SetFileSpecValue (const FileSpec &file_spec)
430 {
431     OptionValueFileSpec *option_value = GetAsFileSpec ();
432     if (option_value)
433     {
434         option_value->SetCurrentValue(file_spec, false);
435         return true;
436     }
437     return false;
438 }
439 
440 FileSpecList
441 OptionValue::GetFileSpecListValue () const
442 {
443     const OptionValueFileSpecList *option_value = GetAsFileSpecList ();
444     if (option_value)
445         return option_value->GetCurrentValue();
446     return FileSpecList();
447 }
448 
449 
450 lldb::Format
451 OptionValue::GetFormatValue (lldb::Format fail_value) const
452 {
453     const OptionValueFormat *option_value = GetAsFormat ();
454     if (option_value)
455         return option_value->GetCurrentValue();
456     return fail_value;
457 }
458 
459 bool
460 OptionValue::SetFormatValue (lldb::Format new_value)
461 {
462     OptionValueFormat *option_value = GetAsFormat ();
463     if (option_value)
464     {
465         option_value->SetCurrentValue(new_value);
466         return true;
467     }
468     return false;
469 }
470 
471 const FormatEntity::Entry *
472 OptionValue::GetFormatEntity () const
473 {
474     const OptionValueFormatEntity *option_value = GetAsFormatEntity();
475     if (option_value)
476         return &option_value->GetCurrentValue();
477     return nullptr;
478 }
479 
480 const RegularExpression *
481 OptionValue::GetRegexValue () const
482 {
483     const OptionValueRegex *option_value = GetAsRegex ();
484     if (option_value)
485         return option_value->GetCurrentValue();
486     return nullptr;
487 }
488 
489 
490 int64_t
491 OptionValue::GetSInt64Value (int64_t fail_value) const
492 {
493     const OptionValueSInt64 *option_value = GetAsSInt64 ();
494     if (option_value)
495         return option_value->GetCurrentValue();
496     return fail_value;
497 }
498 
499 bool
500 OptionValue::SetSInt64Value (int64_t new_value)
501 {
502     OptionValueSInt64 *option_value = GetAsSInt64 ();
503     if (option_value)
504     {
505         option_value->SetCurrentValue(new_value);
506         return true;
507     }
508     return false;
509 }
510 
511 const char *
512 OptionValue::GetStringValue (const char *fail_value) const
513 {
514     const OptionValueString *option_value = GetAsString ();
515     if (option_value)
516         return option_value->GetCurrentValue();
517     return fail_value;
518 }
519 
520 bool
521 OptionValue::SetStringValue (const char *new_value)
522 {
523     OptionValueString *option_value = GetAsString ();
524     if (option_value)
525     {
526         option_value->SetCurrentValue(new_value);
527         return true;
528     }
529     return false;
530 }
531 
532 uint64_t
533 OptionValue::GetUInt64Value (uint64_t fail_value) const
534 {
535     const OptionValueUInt64 *option_value = GetAsUInt64 ();
536     if (option_value)
537         return option_value->GetCurrentValue();
538     return fail_value;
539 }
540 
541 bool
542 OptionValue::SetUInt64Value (uint64_t new_value)
543 {
544     OptionValueUInt64 *option_value = GetAsUInt64 ();
545     if (option_value)
546     {
547         option_value->SetCurrentValue(new_value);
548         return true;
549     }
550     return false;
551 }
552 
553 UUID
554 OptionValue::GetUUIDValue () const
555 {
556     const OptionValueUUID *option_value = GetAsUUID();
557     if (option_value)
558         return option_value->GetCurrentValue();
559     return UUID();
560 }
561 
562 bool
563 OptionValue::SetUUIDValue (const UUID &uuid)
564 {
565     OptionValueUUID *option_value = GetAsUUID();
566     if (option_value)
567     {
568         option_value->SetCurrentValue(uuid);
569         return true;
570     }
571     return false;
572 }
573 
574 const char *
575 OptionValue::GetBuiltinTypeAsCString (Type t)
576 {
577     switch (t)
578     {
579         case eTypeInvalid:      return "invalid";
580         case eTypeArch:         return "arch";
581         case eTypeArgs:         return "arguments";
582         case eTypeArray:        return "array";
583         case eTypeBoolean:      return "boolean";
584         case eTypeChar:
585             return "char";
586         case eTypeDictionary:   return "dictionary";
587         case eTypeEnum:         return "enum";
588         case eTypeFileSpec:     return "file";
589         case eTypeFileSpecList: return "file-list";
590         case eTypeFormat:       return "format";
591         case eTypeFormatEntity: return "format-string";
592         case eTypePathMap:      return "path-map";
593         case eTypeProperties:   return "properties";
594         case eTypeRegex:        return "regex";
595         case eTypeSInt64:       return "int";
596         case eTypeString:       return "string";
597         case eTypeUInt64:       return "unsigned";
598         case eTypeUUID:         return "uuid";
599     }
600     return nullptr;
601 }
602 
603 
604 lldb::OptionValueSP
605 OptionValue::CreateValueFromCStringForTypeMask (const char *value_cstr, uint32_t type_mask, Error &error)
606 {
607     // If only 1 bit is set in the type mask for a dictionary or array
608     // then we know how to decode a value from a cstring
609     lldb::OptionValueSP value_sp;
610     switch (type_mask)
611     {
612     case 1u << eTypeArch:           value_sp.reset(new OptionValueArch()); break;
613     case 1u << eTypeBoolean:        value_sp.reset(new OptionValueBoolean(false)); break;
614     case 1u << eTypeChar:           value_sp.reset(new OptionValueChar('\0')); break;
615     case 1u << eTypeFileSpec:       value_sp.reset(new OptionValueFileSpec()); break;
616     case 1u << eTypeFormat:         value_sp.reset(new OptionValueFormat(eFormatInvalid));    break;
617     case 1u << eTypeFormatEntity:   value_sp.reset(new OptionValueFormatEntity(NULL));    break;
618     case 1u << eTypeSInt64:         value_sp.reset(new OptionValueSInt64()); break;
619     case 1u << eTypeString:         value_sp.reset(new OptionValueString()); break;
620     case 1u << eTypeUInt64:         value_sp.reset(new OptionValueUInt64()); break;
621     case 1u << eTypeUUID:           value_sp.reset(new OptionValueUUID()); break;
622     }
623 
624     if (value_sp)
625         error = value_sp->SetValueFromCString (value_cstr, eVarSetOperationAssign);
626     else
627         error.SetErrorString("unsupported type mask");
628     return value_sp;
629 }
630 
631 bool
632 OptionValue::DumpQualifiedName (Stream &strm) const
633 {
634     bool dumped_something = false;
635     lldb::OptionValueSP m_parent_sp(m_parent_wp.lock());
636     if (m_parent_sp)
637     {
638         if (m_parent_sp->DumpQualifiedName(strm))
639             dumped_something = true;
640     }
641     ConstString name (GetName());
642     if (name)
643     {
644         if (dumped_something)
645             strm.PutChar('.');
646         else
647             dumped_something = true;
648         strm << name;
649     }
650     return dumped_something;
651 }
652 
653 size_t
654 OptionValue::AutoComplete (CommandInterpreter &interpreter,
655                            const char *s,
656                            int match_start_point,
657                            int max_return_elements,
658                            bool &word_complete,
659                            StringList &matches)
660 {
661     word_complete = false;
662     matches.Clear();
663     return matches.GetSize();
664 }
665 
666 Error
667 OptionValue::SetValueFromCString (const char *value, VarSetOperationType op)
668 {
669     Error error;
670     switch (op)
671     {
672     case eVarSetOperationReplace:
673         error.SetErrorStringWithFormat ("%s objects do not support the 'replace' operation", GetTypeAsCString());
674         break;
675     case eVarSetOperationInsertBefore:
676         error.SetErrorStringWithFormat ("%s objects do not support the 'insert-before' operation", GetTypeAsCString());
677         break;
678     case eVarSetOperationInsertAfter:
679         error.SetErrorStringWithFormat ("%s objects do not support the 'insert-after' operation", GetTypeAsCString());
680         break;
681     case eVarSetOperationRemove:
682         error.SetErrorStringWithFormat ("%s objects do not support the 'remove' operation", GetTypeAsCString());
683         break;
684     case eVarSetOperationAppend:
685         error.SetErrorStringWithFormat ("%s objects do not support the 'append' operation", GetTypeAsCString());
686         break;
687     case eVarSetOperationClear:
688         error.SetErrorStringWithFormat ("%s objects do not support the 'clear' operation", GetTypeAsCString());
689         break;
690     case eVarSetOperationAssign:
691         error.SetErrorStringWithFormat ("%s objects do not support the 'assign' operation", GetTypeAsCString());
692         break;
693     case eVarSetOperationInvalid:
694         error.SetErrorStringWithFormat ("invalid operation performed on a %s object", GetTypeAsCString());
695         break;
696     }
697     return error;
698 }
699 
700