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
GetUInt64Value(uint64_t fail_value,bool * success_ptr)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
SetSubValue(const ExecutionContext * exe_ctx,VarSetOperationType op,const char * name,const char * value)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 *
GetAsBoolean()59 OptionValue::GetAsBoolean ()
60 {
61     if (GetType () == OptionValue::eTypeBoolean)
62         return static_cast<OptionValueBoolean *>(this);
63     return NULL;
64 }
65 
66 const OptionValueBoolean *
GetAsBoolean() const67 OptionValue::GetAsBoolean () const
68 {
69     if (GetType () == OptionValue::eTypeBoolean)
70         return static_cast<const OptionValueBoolean *>(this);
71     return NULL;
72 }
73 
74 
75 OptionValueFileSpec *
GetAsFileSpec()76 OptionValue::GetAsFileSpec ()
77 {
78     if (GetType () == OptionValue::eTypeFileSpec)
79         return static_cast<OptionValueFileSpec *>(this);
80     return NULL;
81 
82 }
83 
84 const OptionValueFileSpec *
GetAsFileSpec() const85 OptionValue::GetAsFileSpec () const
86 {
87     if (GetType () == OptionValue::eTypeFileSpec)
88         return static_cast<const OptionValueFileSpec *>(this);
89     return NULL;
90 
91 }
92 
93 OptionValueFileSpecList *
GetAsFileSpecList()94 OptionValue::GetAsFileSpecList ()
95 {
96     if (GetType () == OptionValue::eTypeFileSpecList)
97         return static_cast<OptionValueFileSpecList *>(this);
98     return NULL;
99 
100 }
101 
102 const OptionValueFileSpecList *
GetAsFileSpecList() const103 OptionValue::GetAsFileSpecList () const
104 {
105     if (GetType () == OptionValue::eTypeFileSpecList)
106         return static_cast<const OptionValueFileSpecList *>(this);
107     return NULL;
108 
109 }
110 
111 OptionValueArch *
GetAsArch()112 OptionValue::GetAsArch ()
113 {
114     if (GetType () == OptionValue::eTypeArch)
115         return static_cast<OptionValueArch *>(this);
116     return NULL;
117 }
118 
119 
120 const OptionValueArch *
GetAsArch() const121 OptionValue::GetAsArch () const
122 {
123     if (GetType () == OptionValue::eTypeArch)
124         return static_cast<const OptionValueArch *>(this);
125     return NULL;
126 }
127 
128 OptionValueArray *
GetAsArray()129 OptionValue::GetAsArray ()
130 {
131     if (GetType () == OptionValue::eTypeArray)
132         return static_cast<OptionValueArray *>(this);
133     return NULL;
134 }
135 
136 
137 const OptionValueArray *
GetAsArray() const138 OptionValue::GetAsArray () const
139 {
140     if (GetType () == OptionValue::eTypeArray)
141         return static_cast<const OptionValueArray *>(this);
142     return NULL;
143 }
144 
145 OptionValueArgs *
GetAsArgs()146 OptionValue::GetAsArgs ()
147 {
148     if (GetType () == OptionValue::eTypeArgs)
149         return static_cast<OptionValueArgs *>(this);
150     return NULL;
151 }
152 
153 
154 const OptionValueArgs *
GetAsArgs() const155 OptionValue::GetAsArgs () const
156 {
157     if (GetType () == OptionValue::eTypeArgs)
158         return static_cast<const OptionValueArgs *>(this);
159     return NULL;
160 }
161 
162 OptionValueDictionary *
GetAsDictionary()163 OptionValue::GetAsDictionary ()
164 {
165     if (GetType () == OptionValue::eTypeDictionary)
166         return static_cast<OptionValueDictionary *>(this);
167     return NULL;
168 }
169 
170 const OptionValueDictionary *
GetAsDictionary() const171 OptionValue::GetAsDictionary () const
172 {
173     if (GetType () == OptionValue::eTypeDictionary)
174         return static_cast<const OptionValueDictionary *>(this);
175     return NULL;
176 }
177 
178 OptionValueEnumeration *
GetAsEnumeration()179 OptionValue::GetAsEnumeration ()
180 {
181     if (GetType () == OptionValue::eTypeEnum)
182         return static_cast<OptionValueEnumeration *>(this);
183     return NULL;
184 }
185 
186 const OptionValueEnumeration *
GetAsEnumeration() const187 OptionValue::GetAsEnumeration () const
188 {
189     if (GetType () == OptionValue::eTypeEnum)
190         return static_cast<const OptionValueEnumeration *>(this);
191     return NULL;
192 }
193 
194 OptionValueFormat *
GetAsFormat()195 OptionValue::GetAsFormat ()
196 {
197     if (GetType () == OptionValue::eTypeFormat)
198         return static_cast<OptionValueFormat *>(this);
199     return NULL;
200 }
201 
202 const OptionValueFormat *
GetAsFormat() const203 OptionValue::GetAsFormat () const
204 {
205     if (GetType () == OptionValue::eTypeFormat)
206         return static_cast<const OptionValueFormat *>(this);
207     return NULL;
208 }
209 
210 OptionValuePathMappings *
GetAsPathMappings()211 OptionValue::GetAsPathMappings ()
212 {
213     if (GetType () == OptionValue::eTypePathMap)
214         return static_cast<OptionValuePathMappings *>(this);
215     return NULL;
216 }
217 
218 const OptionValuePathMappings *
GetAsPathMappings() const219 OptionValue::GetAsPathMappings () const
220 {
221     if (GetType () == OptionValue::eTypePathMap)
222         return static_cast<const OptionValuePathMappings *>(this);
223     return NULL;
224 }
225 
226 OptionValueProperties *
GetAsProperties()227 OptionValue::GetAsProperties ()
228 {
229     if (GetType () == OptionValue::eTypeProperties)
230         return static_cast<OptionValueProperties *>(this);
231     return NULL;
232 }
233 
234 const OptionValueProperties *
GetAsProperties() const235 OptionValue::GetAsProperties () const
236 {
237     if (GetType () == OptionValue::eTypeProperties)
238         return static_cast<const OptionValueProperties *>(this);
239     return NULL;
240 }
241 
242 OptionValueRegex *
GetAsRegex()243 OptionValue::GetAsRegex ()
244 {
245     if (GetType () == OptionValue::eTypeRegex)
246         return static_cast<OptionValueRegex *>(this);
247     return NULL;
248 }
249 
250 const OptionValueRegex *
GetAsRegex() const251 OptionValue::GetAsRegex () const
252 {
253     if (GetType () == OptionValue::eTypeRegex)
254         return static_cast<const OptionValueRegex *>(this);
255     return NULL;
256 }
257 
258 OptionValueSInt64 *
GetAsSInt64()259 OptionValue::GetAsSInt64 ()
260 {
261     if (GetType () == OptionValue::eTypeSInt64)
262         return static_cast<OptionValueSInt64 *>(this);
263     return NULL;
264 }
265 
266 const OptionValueSInt64 *
GetAsSInt64() const267 OptionValue::GetAsSInt64 () const
268 {
269     if (GetType () == OptionValue::eTypeSInt64)
270         return static_cast<const OptionValueSInt64 *>(this);
271     return NULL;
272 }
273 
274 OptionValueString *
GetAsString()275 OptionValue::GetAsString ()
276 {
277     if (GetType () == OptionValue::eTypeString)
278         return static_cast<OptionValueString *>(this);
279     return NULL;
280 }
281 
282 const OptionValueString *
GetAsString() const283 OptionValue::GetAsString () const
284 {
285     if (GetType () == OptionValue::eTypeString)
286         return static_cast<const OptionValueString *>(this);
287     return NULL;
288 }
289 
290 OptionValueUInt64 *
GetAsUInt64()291 OptionValue::GetAsUInt64 ()
292 {
293     if (GetType () == OptionValue::eTypeUInt64)
294         return static_cast<OptionValueUInt64 *>(this);
295     return NULL;
296 }
297 
298 const OptionValueUInt64 *
GetAsUInt64() const299 OptionValue::GetAsUInt64 () const
300 {
301     if (GetType () == OptionValue::eTypeUInt64)
302         return static_cast<const OptionValueUInt64 *>(this);
303     return NULL;
304 }
305 
306 OptionValueUUID *
GetAsUUID()307 OptionValue::GetAsUUID ()
308 {
309     if (GetType () == OptionValue::eTypeUUID)
310         return static_cast<OptionValueUUID *>(this);
311     return NULL;
312 
313 }
314 
315 const OptionValueUUID *
GetAsUUID() const316 OptionValue::GetAsUUID () const
317 {
318     if (GetType () == OptionValue::eTypeUUID)
319         return static_cast<const OptionValueUUID *>(this);
320     return NULL;
321 
322 }
323 
324 bool
GetBooleanValue(bool fail_value) const325 OptionValue::GetBooleanValue (bool fail_value) const
326 {
327     const OptionValueBoolean *option_value = GetAsBoolean ();
328     if (option_value)
329         return option_value->GetCurrentValue();
330     return fail_value;
331 }
332 
333 bool
SetBooleanValue(bool new_value)334 OptionValue::SetBooleanValue (bool new_value)
335 {
336     OptionValueBoolean *option_value = GetAsBoolean ();
337     if (option_value)
338     {
339         option_value->SetCurrentValue(new_value);
340         return true;
341     }
342     return false;
343 }
344 
345 int64_t
GetEnumerationValue(int64_t fail_value) const346 OptionValue::GetEnumerationValue (int64_t fail_value) const
347 {
348     const OptionValueEnumeration *option_value = GetAsEnumeration();
349     if (option_value)
350         return option_value->GetCurrentValue();
351     return fail_value;
352 }
353 
354 bool
SetEnumerationValue(int64_t value)355 OptionValue::SetEnumerationValue (int64_t value)
356 {
357     OptionValueEnumeration *option_value = GetAsEnumeration();
358     if (option_value)
359     {
360         option_value->SetCurrentValue(value);
361         return true;
362     }
363     return false;
364 }
365 
366 FileSpec
GetFileSpecValue() const367 OptionValue::GetFileSpecValue () const
368 {
369     const OptionValueFileSpec *option_value = GetAsFileSpec ();
370     if (option_value)
371         return option_value->GetCurrentValue();
372     return FileSpec();
373 }
374 
375 
376 bool
SetFileSpecValue(const FileSpec & file_spec)377 OptionValue::SetFileSpecValue (const FileSpec &file_spec)
378 {
379     OptionValueFileSpec *option_value = GetAsFileSpec ();
380     if (option_value)
381     {
382         option_value->SetCurrentValue(file_spec, false);
383         return true;
384     }
385     return false;
386 }
387 
388 FileSpecList
GetFileSpecListValue() const389 OptionValue::GetFileSpecListValue () const
390 {
391     const OptionValueFileSpecList *option_value = GetAsFileSpecList ();
392     if (option_value)
393         return option_value->GetCurrentValue();
394     return FileSpecList();
395 }
396 
397 
398 lldb::Format
GetFormatValue(lldb::Format fail_value) const399 OptionValue::GetFormatValue (lldb::Format fail_value) const
400 {
401     const OptionValueFormat *option_value = GetAsFormat ();
402     if (option_value)
403         return option_value->GetCurrentValue();
404     return fail_value;
405 }
406 
407 bool
SetFormatValue(lldb::Format new_value)408 OptionValue::SetFormatValue (lldb::Format new_value)
409 {
410     OptionValueFormat *option_value = GetAsFormat ();
411     if (option_value)
412     {
413         option_value->SetCurrentValue(new_value);
414         return true;
415     }
416     return false;
417 }
418 
419 const RegularExpression *
GetRegexValue() const420 OptionValue::GetRegexValue () const
421 {
422     const OptionValueRegex *option_value = GetAsRegex ();
423     if (option_value)
424         return option_value->GetCurrentValue();
425     return NULL;
426 }
427 
428 
429 int64_t
GetSInt64Value(int64_t fail_value) const430 OptionValue::GetSInt64Value (int64_t fail_value) const
431 {
432     const OptionValueSInt64 *option_value = GetAsSInt64 ();
433     if (option_value)
434         return option_value->GetCurrentValue();
435     return fail_value;
436 }
437 
438 bool
SetSInt64Value(int64_t new_value)439 OptionValue::SetSInt64Value (int64_t new_value)
440 {
441     OptionValueSInt64 *option_value = GetAsSInt64 ();
442     if (option_value)
443     {
444         option_value->SetCurrentValue(new_value);
445         return true;
446     }
447     return false;
448 }
449 
450 const char *
GetStringValue(const char * fail_value) const451 OptionValue::GetStringValue (const char *fail_value) const
452 {
453     const OptionValueString *option_value = GetAsString ();
454     if (option_value)
455         return option_value->GetCurrentValue();
456     return fail_value;
457 }
458 
459 bool
SetStringValue(const char * new_value)460 OptionValue::SetStringValue (const char *new_value)
461 {
462     OptionValueString *option_value = GetAsString ();
463     if (option_value)
464     {
465         option_value->SetCurrentValue(new_value);
466         return true;
467     }
468     return false;
469 }
470 
471 uint64_t
GetUInt64Value(uint64_t fail_value) const472 OptionValue::GetUInt64Value (uint64_t fail_value) const
473 {
474     const OptionValueUInt64 *option_value = GetAsUInt64 ();
475     if (option_value)
476         return option_value->GetCurrentValue();
477     return fail_value;
478 }
479 
480 bool
SetUInt64Value(uint64_t new_value)481 OptionValue::SetUInt64Value (uint64_t new_value)
482 {
483     OptionValueUInt64 *option_value = GetAsUInt64 ();
484     if (option_value)
485     {
486         option_value->SetCurrentValue(new_value);
487         return true;
488     }
489     return false;
490 }
491 
492 UUID
GetUUIDValue() const493 OptionValue::GetUUIDValue () const
494 {
495     const OptionValueUUID *option_value = GetAsUUID();
496     if (option_value)
497         return option_value->GetCurrentValue();
498     return UUID();
499 }
500 
501 bool
SetUUIDValue(const UUID & uuid)502 OptionValue::SetUUIDValue (const UUID &uuid)
503 {
504     OptionValueUUID *option_value = GetAsUUID();
505     if (option_value)
506     {
507         option_value->SetCurrentValue(uuid);
508         return true;
509     }
510     return false;
511 }
512 
513 const char *
GetBuiltinTypeAsCString(Type t)514 OptionValue::GetBuiltinTypeAsCString (Type t)
515 {
516     switch (t)
517     {
518         case eTypeInvalid:      return "invalid";
519         case eTypeArch:         return "arch";
520         case eTypeArgs:         return "arguments";
521         case eTypeArray:        return "array";
522         case eTypeBoolean:      return "boolean";
523         case eTypeDictionary:   return "dictionary";
524         case eTypeEnum:         return "enum";
525         case eTypeFileSpec:     return "file";
526         case eTypeFileSpecList: return "file-list";
527         case eTypeFormat:       return "format";
528         case eTypePathMap:      return "path-map";
529         case eTypeProperties:   return "properties";
530         case eTypeRegex:        return "regex";
531         case eTypeSInt64:       return "int";
532         case eTypeString:       return "string";
533         case eTypeUInt64:       return "unsigned";
534         case eTypeUUID:         return "uuid";
535     }
536     return NULL;
537 }
538 
539 
540 lldb::OptionValueSP
CreateValueFromCStringForTypeMask(const char * value_cstr,uint32_t type_mask,Error & error)541 OptionValue::CreateValueFromCStringForTypeMask (const char *value_cstr, uint32_t type_mask, Error &error)
542 {
543     // If only 1 bit is set in the type mask for a dictionary or array
544     // then we know how to decode a value from a cstring
545     lldb::OptionValueSP value_sp;
546     switch (type_mask)
547     {
548     case 1u << eTypeArch:       value_sp.reset(new OptionValueArch()); break;
549     case 1u << eTypeBoolean:    value_sp.reset(new OptionValueBoolean(false)); break;
550     case 1u << eTypeFileSpec:   value_sp.reset(new OptionValueFileSpec()); break;
551     case 1u << eTypeFormat:     value_sp.reset(new OptionValueFormat(eFormatInvalid));    break;
552     case 1u << eTypeSInt64:     value_sp.reset(new OptionValueSInt64()); break;
553     case 1u << eTypeString:     value_sp.reset(new OptionValueString()); break;
554     case 1u << eTypeUInt64:     value_sp.reset(new OptionValueUInt64()); break;
555     case 1u << eTypeUUID:       value_sp.reset(new OptionValueUUID()); break;
556     }
557 
558     if (value_sp)
559         error = value_sp->SetValueFromCString (value_cstr, eVarSetOperationAssign);
560     else
561         error.SetErrorString("unsupported type mask");
562     return value_sp;
563 }
564 
565 bool
DumpQualifiedName(Stream & strm) const566 OptionValue::DumpQualifiedName (Stream &strm) const
567 {
568     bool dumped_something = false;
569     lldb::OptionValueSP m_parent_sp(m_parent_wp.lock());
570     if (m_parent_sp)
571     {
572         if (m_parent_sp->DumpQualifiedName(strm))
573             dumped_something = true;
574     }
575     ConstString name (GetName());
576     if (name)
577     {
578         if (dumped_something)
579             strm.PutChar('.');
580         else
581             dumped_something = true;
582         strm << name;
583     }
584     return dumped_something;
585 }
586 
587 size_t
AutoComplete(CommandInterpreter & interpreter,const char * s,int match_start_point,int max_return_elements,bool & word_complete,StringList & matches)588 OptionValue::AutoComplete (CommandInterpreter &interpreter,
589                            const char *s,
590                            int match_start_point,
591                            int max_return_elements,
592                            bool &word_complete,
593                            StringList &matches)
594 {
595     word_complete = false;
596     matches.Clear();
597     return matches.GetSize();
598 }
599 
600 Error
SetValueFromCString(const char * value,VarSetOperationType op)601 OptionValue::SetValueFromCString (const char *value, VarSetOperationType op)
602 {
603     Error error;
604     switch (op)
605     {
606     case eVarSetOperationReplace:
607         error.SetErrorStringWithFormat ("%s objects do not support the 'replace' operation", GetTypeAsCString());
608         break;
609     case eVarSetOperationInsertBefore:
610         error.SetErrorStringWithFormat ("%s objects do not support the 'insert-before' operation", GetTypeAsCString());
611         break;
612     case eVarSetOperationInsertAfter:
613         error.SetErrorStringWithFormat ("%s objects do not support the 'insert-after' operation", GetTypeAsCString());
614         break;
615     case eVarSetOperationRemove:
616         error.SetErrorStringWithFormat ("%s objects do not support the 'remove' operation", GetTypeAsCString());
617         break;
618     case eVarSetOperationAppend:
619         error.SetErrorStringWithFormat ("%s objects do not support the 'append' operation", GetTypeAsCString());
620         break;
621     case eVarSetOperationClear:
622         error.SetErrorStringWithFormat ("%s objects do not support the 'clear' operation", GetTypeAsCString());
623         break;
624     case eVarSetOperationAssign:
625         error.SetErrorStringWithFormat ("%s objects do not support the 'assign' operation", GetTypeAsCString());
626         break;
627     case eVarSetOperationInvalid:
628         error.SetErrorStringWithFormat ("invalid operation performed on a %s object", GetTypeAsCString());
629         break;
630     }
631     return error;
632 }
633 
634