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