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