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 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 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 45 OptionValueBoolean *OptionValue::GetAsBoolean() { 46 if (GetType() == OptionValue::eTypeBoolean) 47 return static_cast<OptionValueBoolean *>(this); 48 return nullptr; 49 } 50 51 const OptionValueBoolean *OptionValue::GetAsBoolean() const { 52 if (GetType() == OptionValue::eTypeBoolean) 53 return static_cast<const OptionValueBoolean *>(this); 54 return nullptr; 55 } 56 57 const OptionValueChar *OptionValue::GetAsChar() const { 58 if (GetType() == OptionValue::eTypeChar) 59 return static_cast<const OptionValueChar *>(this); 60 return nullptr; 61 } 62 63 OptionValueChar *OptionValue::GetAsChar() { 64 if (GetType() == OptionValue::eTypeChar) 65 return static_cast<OptionValueChar *>(this); 66 return nullptr; 67 } 68 69 OptionValueFileSpec *OptionValue::GetAsFileSpec() { 70 if (GetType() == OptionValue::eTypeFileSpec) 71 return static_cast<OptionValueFileSpec *>(this); 72 return nullptr; 73 } 74 75 const OptionValueFileSpec *OptionValue::GetAsFileSpec() const { 76 if (GetType() == OptionValue::eTypeFileSpec) 77 return static_cast<const OptionValueFileSpec *>(this); 78 return nullptr; 79 } 80 81 OptionValueFileSpecList *OptionValue::GetAsFileSpecList() { 82 if (GetType() == OptionValue::eTypeFileSpecList) 83 return static_cast<OptionValueFileSpecList *>(this); 84 return nullptr; 85 } 86 87 const OptionValueFileSpecList *OptionValue::GetAsFileSpecList() const { 88 if (GetType() == OptionValue::eTypeFileSpecList) 89 return static_cast<const OptionValueFileSpecList *>(this); 90 return nullptr; 91 } 92 93 OptionValueArch *OptionValue::GetAsArch() { 94 if (GetType() == OptionValue::eTypeArch) 95 return static_cast<OptionValueArch *>(this); 96 return nullptr; 97 } 98 99 const OptionValueArch *OptionValue::GetAsArch() const { 100 if (GetType() == OptionValue::eTypeArch) 101 return static_cast<const OptionValueArch *>(this); 102 return nullptr; 103 } 104 105 OptionValueArray *OptionValue::GetAsArray() { 106 if (GetType() == OptionValue::eTypeArray) 107 return static_cast<OptionValueArray *>(this); 108 return nullptr; 109 } 110 111 const OptionValueArray *OptionValue::GetAsArray() const { 112 if (GetType() == OptionValue::eTypeArray) 113 return static_cast<const OptionValueArray *>(this); 114 return nullptr; 115 } 116 117 OptionValueArgs *OptionValue::GetAsArgs() { 118 if (GetType() == OptionValue::eTypeArgs) 119 return static_cast<OptionValueArgs *>(this); 120 return nullptr; 121 } 122 123 const OptionValueArgs *OptionValue::GetAsArgs() const { 124 if (GetType() == OptionValue::eTypeArgs) 125 return static_cast<const OptionValueArgs *>(this); 126 return nullptr; 127 } 128 129 OptionValueDictionary *OptionValue::GetAsDictionary() { 130 if (GetType() == OptionValue::eTypeDictionary) 131 return static_cast<OptionValueDictionary *>(this); 132 return nullptr; 133 } 134 135 const OptionValueDictionary *OptionValue::GetAsDictionary() const { 136 if (GetType() == OptionValue::eTypeDictionary) 137 return static_cast<const OptionValueDictionary *>(this); 138 return nullptr; 139 } 140 141 OptionValueEnumeration *OptionValue::GetAsEnumeration() { 142 if (GetType() == OptionValue::eTypeEnum) 143 return static_cast<OptionValueEnumeration *>(this); 144 return nullptr; 145 } 146 147 const OptionValueEnumeration *OptionValue::GetAsEnumeration() const { 148 if (GetType() == OptionValue::eTypeEnum) 149 return static_cast<const OptionValueEnumeration *>(this); 150 return nullptr; 151 } 152 153 OptionValueFormat *OptionValue::GetAsFormat() { 154 if (GetType() == OptionValue::eTypeFormat) 155 return static_cast<OptionValueFormat *>(this); 156 return nullptr; 157 } 158 159 const OptionValueFormat *OptionValue::GetAsFormat() const { 160 if (GetType() == OptionValue::eTypeFormat) 161 return static_cast<const OptionValueFormat *>(this); 162 return nullptr; 163 } 164 165 OptionValueLanguage *OptionValue::GetAsLanguage() { 166 if (GetType() == OptionValue::eTypeLanguage) 167 return static_cast<OptionValueLanguage *>(this); 168 return nullptr; 169 } 170 171 const OptionValueLanguage *OptionValue::GetAsLanguage() const { 172 if (GetType() == OptionValue::eTypeLanguage) 173 return static_cast<const OptionValueLanguage *>(this); 174 return nullptr; 175 } 176 177 OptionValueFormatEntity *OptionValue::GetAsFormatEntity() { 178 if (GetType() == OptionValue::eTypeFormatEntity) 179 return static_cast<OptionValueFormatEntity *>(this); 180 return nullptr; 181 } 182 183 const OptionValueFormatEntity *OptionValue::GetAsFormatEntity() const { 184 if (GetType() == OptionValue::eTypeFormatEntity) 185 return static_cast<const OptionValueFormatEntity *>(this); 186 return nullptr; 187 } 188 189 OptionValuePathMappings *OptionValue::GetAsPathMappings() { 190 if (GetType() == OptionValue::eTypePathMap) 191 return static_cast<OptionValuePathMappings *>(this); 192 return nullptr; 193 } 194 195 const OptionValuePathMappings *OptionValue::GetAsPathMappings() const { 196 if (GetType() == OptionValue::eTypePathMap) 197 return static_cast<const OptionValuePathMappings *>(this); 198 return nullptr; 199 } 200 201 OptionValueProperties *OptionValue::GetAsProperties() { 202 if (GetType() == OptionValue::eTypeProperties) 203 return static_cast<OptionValueProperties *>(this); 204 return nullptr; 205 } 206 207 const OptionValueProperties *OptionValue::GetAsProperties() const { 208 if (GetType() == OptionValue::eTypeProperties) 209 return static_cast<const OptionValueProperties *>(this); 210 return nullptr; 211 } 212 213 OptionValueRegex *OptionValue::GetAsRegex() { 214 if (GetType() == OptionValue::eTypeRegex) 215 return static_cast<OptionValueRegex *>(this); 216 return nullptr; 217 } 218 219 const OptionValueRegex *OptionValue::GetAsRegex() const { 220 if (GetType() == OptionValue::eTypeRegex) 221 return static_cast<const OptionValueRegex *>(this); 222 return nullptr; 223 } 224 225 OptionValueSInt64 *OptionValue::GetAsSInt64() { 226 if (GetType() == OptionValue::eTypeSInt64) 227 return static_cast<OptionValueSInt64 *>(this); 228 return nullptr; 229 } 230 231 const OptionValueSInt64 *OptionValue::GetAsSInt64() const { 232 if (GetType() == OptionValue::eTypeSInt64) 233 return static_cast<const OptionValueSInt64 *>(this); 234 return nullptr; 235 } 236 237 OptionValueString *OptionValue::GetAsString() { 238 if (GetType() == OptionValue::eTypeString) 239 return static_cast<OptionValueString *>(this); 240 return nullptr; 241 } 242 243 const OptionValueString *OptionValue::GetAsString() const { 244 if (GetType() == OptionValue::eTypeString) 245 return static_cast<const OptionValueString *>(this); 246 return nullptr; 247 } 248 249 OptionValueUInt64 *OptionValue::GetAsUInt64() { 250 if (GetType() == OptionValue::eTypeUInt64) 251 return static_cast<OptionValueUInt64 *>(this); 252 return nullptr; 253 } 254 255 const OptionValueUInt64 *OptionValue::GetAsUInt64() const { 256 if (GetType() == OptionValue::eTypeUInt64) 257 return static_cast<const OptionValueUInt64 *>(this); 258 return nullptr; 259 } 260 261 OptionValueUUID *OptionValue::GetAsUUID() { 262 if (GetType() == OptionValue::eTypeUUID) 263 return static_cast<OptionValueUUID *>(this); 264 return nullptr; 265 } 266 267 const OptionValueUUID *OptionValue::GetAsUUID() const { 268 if (GetType() == OptionValue::eTypeUUID) 269 return static_cast<const OptionValueUUID *>(this); 270 return nullptr; 271 } 272 273 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 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 289 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 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 305 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 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 321 FileSpec OptionValue::GetFileSpecValue() const { 322 const OptionValueFileSpec *option_value = GetAsFileSpec(); 323 if (option_value) 324 return option_value->GetCurrentValue(); 325 return FileSpec(); 326 } 327 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 337 FileSpecList OptionValue::GetFileSpecListValue() const { 338 const OptionValueFileSpecList *option_value = GetAsFileSpecList(); 339 if (option_value) 340 return option_value->GetCurrentValue(); 341 return FileSpecList(); 342 } 343 344 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 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 361 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 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 377 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 384 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 391 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 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 407 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 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 423 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 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 439 UUID OptionValue::GetUUIDValue() const { 440 const OptionValueUUID *option_value = GetAsUUID(); 441 if (option_value) 442 return option_value->GetCurrentValue(); 443 return UUID(); 444 } 445 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 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 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 550 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 568 size_t OptionValue::AutoComplete(CommandInterpreter &interpreter, 569 CompletionRequest &request) { 570 request.SetWordComplete(false); 571 return request.GetNumberOfMatches(); 572 } 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