1 //===-- OptionValue.cpp ---------------------------------------------------===// 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 #include "lldb/Interpreter/OptionValues.h" 11 #include "lldb/Utility/StringList.h" 12 13 #include <memory> 14 15 using namespace lldb; 16 using namespace lldb_private; 17 18 // Get this value as a uint64_t value if it is encoded as a boolean, uint64_t 19 // or int64_t. Other types will cause "fail_value" to be returned 20 uint64_t OptionValue::GetUInt64Value(uint64_t fail_value, bool *success_ptr) { 21 if (success_ptr) 22 *success_ptr = true; 23 switch (GetType()) { 24 case OptionValue::eTypeBoolean: 25 return static_cast<OptionValueBoolean *>(this)->GetCurrentValue(); 26 case OptionValue::eTypeSInt64: 27 return static_cast<OptionValueSInt64 *>(this)->GetCurrentValue(); 28 case OptionValue::eTypeUInt64: 29 return static_cast<OptionValueUInt64 *>(this)->GetCurrentValue(); 30 default: 31 break; 32 } 33 if (success_ptr) 34 *success_ptr = false; 35 return fail_value; 36 } 37 38 Status OptionValue::SetSubValue(const ExecutionContext *exe_ctx, 39 VarSetOperationType op, llvm::StringRef name, 40 llvm::StringRef value) { 41 Status error; 42 error.SetErrorString("SetSubValue is not supported"); 43 return error; 44 } 45 46 OptionValueBoolean *OptionValue::GetAsBoolean() { 47 if (GetType() == OptionValue::eTypeBoolean) 48 return static_cast<OptionValueBoolean *>(this); 49 return nullptr; 50 } 51 52 const OptionValueBoolean *OptionValue::GetAsBoolean() const { 53 if (GetType() == OptionValue::eTypeBoolean) 54 return static_cast<const OptionValueBoolean *>(this); 55 return nullptr; 56 } 57 58 const OptionValueChar *OptionValue::GetAsChar() const { 59 if (GetType() == OptionValue::eTypeChar) 60 return static_cast<const OptionValueChar *>(this); 61 return nullptr; 62 } 63 64 OptionValueChar *OptionValue::GetAsChar() { 65 if (GetType() == OptionValue::eTypeChar) 66 return static_cast<OptionValueChar *>(this); 67 return nullptr; 68 } 69 70 OptionValueFileSpec *OptionValue::GetAsFileSpec() { 71 if (GetType() == OptionValue::eTypeFileSpec) 72 return static_cast<OptionValueFileSpec *>(this); 73 return nullptr; 74 } 75 76 const OptionValueFileSpec *OptionValue::GetAsFileSpec() const { 77 if (GetType() == OptionValue::eTypeFileSpec) 78 return static_cast<const OptionValueFileSpec *>(this); 79 return nullptr; 80 } 81 82 OptionValueFileSpecList *OptionValue::GetAsFileSpecList() { 83 if (GetType() == OptionValue::eTypeFileSpecList) 84 return static_cast<OptionValueFileSpecList *>(this); 85 return nullptr; 86 } 87 88 const OptionValueFileSpecList *OptionValue::GetAsFileSpecList() const { 89 if (GetType() == OptionValue::eTypeFileSpecList) 90 return static_cast<const OptionValueFileSpecList *>(this); 91 return nullptr; 92 } 93 94 OptionValueArch *OptionValue::GetAsArch() { 95 if (GetType() == OptionValue::eTypeArch) 96 return static_cast<OptionValueArch *>(this); 97 return nullptr; 98 } 99 100 const OptionValueArch *OptionValue::GetAsArch() const { 101 if (GetType() == OptionValue::eTypeArch) 102 return static_cast<const OptionValueArch *>(this); 103 return nullptr; 104 } 105 106 OptionValueArray *OptionValue::GetAsArray() { 107 if (GetType() == OptionValue::eTypeArray) 108 return static_cast<OptionValueArray *>(this); 109 return nullptr; 110 } 111 112 const OptionValueArray *OptionValue::GetAsArray() const { 113 if (GetType() == OptionValue::eTypeArray) 114 return static_cast<const OptionValueArray *>(this); 115 return nullptr; 116 } 117 118 OptionValueArgs *OptionValue::GetAsArgs() { 119 if (GetType() == OptionValue::eTypeArgs) 120 return static_cast<OptionValueArgs *>(this); 121 return nullptr; 122 } 123 124 const OptionValueArgs *OptionValue::GetAsArgs() const { 125 if (GetType() == OptionValue::eTypeArgs) 126 return static_cast<const OptionValueArgs *>(this); 127 return nullptr; 128 } 129 130 OptionValueDictionary *OptionValue::GetAsDictionary() { 131 if (GetType() == OptionValue::eTypeDictionary) 132 return static_cast<OptionValueDictionary *>(this); 133 return nullptr; 134 } 135 136 const OptionValueDictionary *OptionValue::GetAsDictionary() const { 137 if (GetType() == OptionValue::eTypeDictionary) 138 return static_cast<const OptionValueDictionary *>(this); 139 return nullptr; 140 } 141 142 OptionValueEnumeration *OptionValue::GetAsEnumeration() { 143 if (GetType() == OptionValue::eTypeEnum) 144 return static_cast<OptionValueEnumeration *>(this); 145 return nullptr; 146 } 147 148 const OptionValueEnumeration *OptionValue::GetAsEnumeration() const { 149 if (GetType() == OptionValue::eTypeEnum) 150 return static_cast<const OptionValueEnumeration *>(this); 151 return nullptr; 152 } 153 154 OptionValueFormat *OptionValue::GetAsFormat() { 155 if (GetType() == OptionValue::eTypeFormat) 156 return static_cast<OptionValueFormat *>(this); 157 return nullptr; 158 } 159 160 const OptionValueFormat *OptionValue::GetAsFormat() const { 161 if (GetType() == OptionValue::eTypeFormat) 162 return static_cast<const OptionValueFormat *>(this); 163 return nullptr; 164 } 165 166 OptionValueLanguage *OptionValue::GetAsLanguage() { 167 if (GetType() == OptionValue::eTypeLanguage) 168 return static_cast<OptionValueLanguage *>(this); 169 return nullptr; 170 } 171 172 const OptionValueLanguage *OptionValue::GetAsLanguage() const { 173 if (GetType() == OptionValue::eTypeLanguage) 174 return static_cast<const OptionValueLanguage *>(this); 175 return nullptr; 176 } 177 178 OptionValueFormatEntity *OptionValue::GetAsFormatEntity() { 179 if (GetType() == OptionValue::eTypeFormatEntity) 180 return static_cast<OptionValueFormatEntity *>(this); 181 return nullptr; 182 } 183 184 const OptionValueFormatEntity *OptionValue::GetAsFormatEntity() const { 185 if (GetType() == OptionValue::eTypeFormatEntity) 186 return static_cast<const OptionValueFormatEntity *>(this); 187 return nullptr; 188 } 189 190 OptionValuePathMappings *OptionValue::GetAsPathMappings() { 191 if (GetType() == OptionValue::eTypePathMap) 192 return static_cast<OptionValuePathMappings *>(this); 193 return nullptr; 194 } 195 196 const OptionValuePathMappings *OptionValue::GetAsPathMappings() const { 197 if (GetType() == OptionValue::eTypePathMap) 198 return static_cast<const OptionValuePathMappings *>(this); 199 return nullptr; 200 } 201 202 OptionValueProperties *OptionValue::GetAsProperties() { 203 if (GetType() == OptionValue::eTypeProperties) 204 return static_cast<OptionValueProperties *>(this); 205 return nullptr; 206 } 207 208 const OptionValueProperties *OptionValue::GetAsProperties() const { 209 if (GetType() == OptionValue::eTypeProperties) 210 return static_cast<const OptionValueProperties *>(this); 211 return nullptr; 212 } 213 214 OptionValueRegex *OptionValue::GetAsRegex() { 215 if (GetType() == OptionValue::eTypeRegex) 216 return static_cast<OptionValueRegex *>(this); 217 return nullptr; 218 } 219 220 const OptionValueRegex *OptionValue::GetAsRegex() const { 221 if (GetType() == OptionValue::eTypeRegex) 222 return static_cast<const OptionValueRegex *>(this); 223 return nullptr; 224 } 225 226 OptionValueSInt64 *OptionValue::GetAsSInt64() { 227 if (GetType() == OptionValue::eTypeSInt64) 228 return static_cast<OptionValueSInt64 *>(this); 229 return nullptr; 230 } 231 232 const OptionValueSInt64 *OptionValue::GetAsSInt64() const { 233 if (GetType() == OptionValue::eTypeSInt64) 234 return static_cast<const OptionValueSInt64 *>(this); 235 return nullptr; 236 } 237 238 OptionValueString *OptionValue::GetAsString() { 239 if (GetType() == OptionValue::eTypeString) 240 return static_cast<OptionValueString *>(this); 241 return nullptr; 242 } 243 244 const OptionValueString *OptionValue::GetAsString() const { 245 if (GetType() == OptionValue::eTypeString) 246 return static_cast<const OptionValueString *>(this); 247 return nullptr; 248 } 249 250 OptionValueUInt64 *OptionValue::GetAsUInt64() { 251 if (GetType() == OptionValue::eTypeUInt64) 252 return static_cast<OptionValueUInt64 *>(this); 253 return nullptr; 254 } 255 256 const OptionValueUInt64 *OptionValue::GetAsUInt64() const { 257 if (GetType() == OptionValue::eTypeUInt64) 258 return static_cast<const OptionValueUInt64 *>(this); 259 return nullptr; 260 } 261 262 OptionValueUUID *OptionValue::GetAsUUID() { 263 if (GetType() == OptionValue::eTypeUUID) 264 return static_cast<OptionValueUUID *>(this); 265 return nullptr; 266 } 267 268 const OptionValueUUID *OptionValue::GetAsUUID() const { 269 if (GetType() == OptionValue::eTypeUUID) 270 return static_cast<const OptionValueUUID *>(this); 271 return nullptr; 272 } 273 274 bool OptionValue::GetBooleanValue(bool fail_value) const { 275 const OptionValueBoolean *option_value = GetAsBoolean(); 276 if (option_value) 277 return option_value->GetCurrentValue(); 278 return fail_value; 279 } 280 281 bool OptionValue::SetBooleanValue(bool new_value) { 282 OptionValueBoolean *option_value = GetAsBoolean(); 283 if (option_value) { 284 option_value->SetCurrentValue(new_value); 285 return true; 286 } 287 return false; 288 } 289 290 char OptionValue::GetCharValue(char fail_value) const { 291 const OptionValueChar *option_value = GetAsChar(); 292 if (option_value) 293 return option_value->GetCurrentValue(); 294 return fail_value; 295 } 296 297 char OptionValue::SetCharValue(char new_value) { 298 OptionValueChar *option_value = GetAsChar(); 299 if (option_value) { 300 option_value->SetCurrentValue(new_value); 301 return true; 302 } 303 return false; 304 } 305 306 int64_t OptionValue::GetEnumerationValue(int64_t fail_value) const { 307 const OptionValueEnumeration *option_value = GetAsEnumeration(); 308 if (option_value) 309 return option_value->GetCurrentValue(); 310 return fail_value; 311 } 312 313 bool OptionValue::SetEnumerationValue(int64_t value) { 314 OptionValueEnumeration *option_value = GetAsEnumeration(); 315 if (option_value) { 316 option_value->SetCurrentValue(value); 317 return true; 318 } 319 return false; 320 } 321 322 FileSpec OptionValue::GetFileSpecValue() const { 323 const OptionValueFileSpec *option_value = GetAsFileSpec(); 324 if (option_value) 325 return option_value->GetCurrentValue(); 326 return FileSpec(); 327 } 328 329 bool OptionValue::SetFileSpecValue(const FileSpec &file_spec) { 330 OptionValueFileSpec *option_value = GetAsFileSpec(); 331 if (option_value) { 332 option_value->SetCurrentValue(file_spec, false); 333 return true; 334 } 335 return false; 336 } 337 338 FileSpecList OptionValue::GetFileSpecListValue() const { 339 const OptionValueFileSpecList *option_value = GetAsFileSpecList(); 340 if (option_value) 341 return option_value->GetCurrentValue(); 342 return FileSpecList(); 343 } 344 345 lldb::Format OptionValue::GetFormatValue(lldb::Format fail_value) const { 346 const OptionValueFormat *option_value = GetAsFormat(); 347 if (option_value) 348 return option_value->GetCurrentValue(); 349 return fail_value; 350 } 351 352 bool OptionValue::SetFormatValue(lldb::Format new_value) { 353 OptionValueFormat *option_value = GetAsFormat(); 354 if (option_value) { 355 option_value->SetCurrentValue(new_value); 356 return true; 357 } 358 return false; 359 } 360 361 lldb::LanguageType 362 OptionValue::GetLanguageValue(lldb::LanguageType fail_value) const { 363 const OptionValueLanguage *option_value = GetAsLanguage(); 364 if (option_value) 365 return option_value->GetCurrentValue(); 366 return fail_value; 367 } 368 369 bool OptionValue::SetLanguageValue(lldb::LanguageType new_language) { 370 OptionValueLanguage *option_value = GetAsLanguage(); 371 if (option_value) { 372 option_value->SetCurrentValue(new_language); 373 return true; 374 } 375 return false; 376 } 377 378 const FormatEntity::Entry *OptionValue::GetFormatEntity() const { 379 const OptionValueFormatEntity *option_value = GetAsFormatEntity(); 380 if (option_value) 381 return &option_value->GetCurrentValue(); 382 return nullptr; 383 } 384 385 const RegularExpression *OptionValue::GetRegexValue() const { 386 const OptionValueRegex *option_value = GetAsRegex(); 387 if (option_value) 388 return option_value->GetCurrentValue(); 389 return nullptr; 390 } 391 392 int64_t OptionValue::GetSInt64Value(int64_t fail_value) const { 393 const OptionValueSInt64 *option_value = GetAsSInt64(); 394 if (option_value) 395 return option_value->GetCurrentValue(); 396 return fail_value; 397 } 398 399 bool OptionValue::SetSInt64Value(int64_t new_value) { 400 OptionValueSInt64 *option_value = GetAsSInt64(); 401 if (option_value) { 402 option_value->SetCurrentValue(new_value); 403 return true; 404 } 405 return false; 406 } 407 408 llvm::StringRef OptionValue::GetStringValue(llvm::StringRef fail_value) const { 409 const OptionValueString *option_value = GetAsString(); 410 if (option_value) 411 return option_value->GetCurrentValueAsRef(); 412 return fail_value; 413 } 414 415 bool OptionValue::SetStringValue(llvm::StringRef new_value) { 416 OptionValueString *option_value = GetAsString(); 417 if (option_value) { 418 option_value->SetCurrentValue(new_value); 419 return true; 420 } 421 return false; 422 } 423 424 uint64_t OptionValue::GetUInt64Value(uint64_t fail_value) const { 425 const OptionValueUInt64 *option_value = GetAsUInt64(); 426 if (option_value) 427 return option_value->GetCurrentValue(); 428 return fail_value; 429 } 430 431 bool OptionValue::SetUInt64Value(uint64_t new_value) { 432 OptionValueUInt64 *option_value = GetAsUInt64(); 433 if (option_value) { 434 option_value->SetCurrentValue(new_value); 435 return true; 436 } 437 return false; 438 } 439 440 UUID OptionValue::GetUUIDValue() const { 441 const OptionValueUUID *option_value = GetAsUUID(); 442 if (option_value) 443 return option_value->GetCurrentValue(); 444 return UUID(); 445 } 446 447 bool OptionValue::SetUUIDValue(const UUID &uuid) { 448 OptionValueUUID *option_value = GetAsUUID(); 449 if (option_value) { 450 option_value->SetCurrentValue(uuid); 451 return true; 452 } 453 return false; 454 } 455 456 const char *OptionValue::GetBuiltinTypeAsCString(Type t) { 457 switch (t) { 458 case eTypeInvalid: 459 return "invalid"; 460 case eTypeArch: 461 return "arch"; 462 case eTypeArgs: 463 return "arguments"; 464 case eTypeArray: 465 return "array"; 466 case eTypeBoolean: 467 return "boolean"; 468 case eTypeChar: 469 return "char"; 470 case eTypeDictionary: 471 return "dictionary"; 472 case eTypeEnum: 473 return "enum"; 474 case eTypeFileLineColumn: 475 return "file:line:column specifier"; 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 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 = std::make_shared<OptionValueArch>(); 512 break; 513 case 1u << eTypeBoolean: 514 value_sp = std::make_shared<OptionValueBoolean>(false); 515 break; 516 case 1u << eTypeChar: 517 value_sp = std::make_shared<OptionValueChar>('\0'); 518 break; 519 case 1u << eTypeFileSpec: 520 value_sp = std::make_shared<OptionValueFileSpec>(); 521 break; 522 case 1u << eTypeFormat: 523 value_sp = std::make_shared<OptionValueFormat>(eFormatInvalid); 524 break; 525 case 1u << eTypeFormatEntity: 526 value_sp = std::make_shared<OptionValueFormatEntity>(nullptr); 527 break; 528 case 1u << eTypeLanguage: 529 value_sp = std::make_shared<OptionValueLanguage>(eLanguageTypeUnknown); 530 break; 531 case 1u << eTypeSInt64: 532 value_sp = std::make_shared<OptionValueSInt64>(); 533 break; 534 case 1u << eTypeString: 535 value_sp = std::make_shared<OptionValueString>(); 536 break; 537 case 1u << eTypeUInt64: 538 value_sp = std::make_shared<OptionValueUInt64>(); 539 break; 540 case 1u << eTypeUUID: 541 value_sp = std::make_shared<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 553 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 571 void OptionValue::AutoComplete(CommandInterpreter &interpreter, 572 CompletionRequest &request) {} 573 574 Status OptionValue::SetValueFromString(llvm::StringRef value, 575 VarSetOperationType op) { 576 Status error; 577 switch (op) { 578 case eVarSetOperationReplace: 579 error.SetErrorStringWithFormat( 580 "%s objects do not support the 'replace' operation", 581 GetTypeAsCString()); 582 break; 583 case eVarSetOperationInsertBefore: 584 error.SetErrorStringWithFormat( 585 "%s objects do not support the 'insert-before' operation", 586 GetTypeAsCString()); 587 break; 588 case eVarSetOperationInsertAfter: 589 error.SetErrorStringWithFormat( 590 "%s objects do not support the 'insert-after' operation", 591 GetTypeAsCString()); 592 break; 593 case eVarSetOperationRemove: 594 error.SetErrorStringWithFormat( 595 "%s objects do not support the 'remove' operation", GetTypeAsCString()); 596 break; 597 case eVarSetOperationAppend: 598 error.SetErrorStringWithFormat( 599 "%s objects do not support the 'append' operation", GetTypeAsCString()); 600 break; 601 case eVarSetOperationClear: 602 error.SetErrorStringWithFormat( 603 "%s objects do not support the 'clear' operation", GetTypeAsCString()); 604 break; 605 case eVarSetOperationAssign: 606 error.SetErrorStringWithFormat( 607 "%s objects do not support the 'assign' operation", GetTypeAsCString()); 608 break; 609 case eVarSetOperationInvalid: 610 error.SetErrorStringWithFormat("invalid operation performed on a %s object", 611 GetTypeAsCString()); 612 break; 613 } 614 return error; 615 } 616