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