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