1 //====-- UserSettingsController.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 <string.h> 11 #include <algorithm> 12 13 #include "lldb/Core/UserSettingsController.h" 14 #include "lldb/Core/Error.h" 15 #include "lldb/Core/Stream.h" 16 #include "lldb/Core/StreamString.h" 17 #include "lldb/Interpreter/CommandInterpreter.h" 18 19 using namespace lldb_private; 20 21 UserSettingsController::UserSettingsController (const char *level_name, 22 const lldb::UserSettingsControllerSP &parent) : 23 m_default_settings (), 24 m_settings (), 25 m_children (), 26 m_pending_settings (), 27 m_live_settings (), 28 m_children_mutex (Mutex::eMutexTypeNormal), 29 m_pending_settings_mutex (Mutex::eMutexTypeRecursive), 30 m_live_settings_mutex (Mutex::eMutexTypeRecursive) 31 { 32 m_settings.parent = parent; 33 m_settings.level_name.SetCString (level_name); 34 } 35 36 UserSettingsController::~UserSettingsController () 37 { 38 m_live_settings.clear(); 39 } 40 41 bool 42 UserSettingsController::SetGlobalVariable 43 ( 44 const ConstString &var_name, 45 const char *index_value, 46 const char *value, 47 const SettingEntry &entry, 48 const lldb::VarSetOperationType op, 49 Error &err 50 ) 51 { 52 err.SetErrorString ("UserSettingsController has no global settings"); 53 return false; 54 } 55 56 bool 57 UserSettingsController::GetGlobalVariable 58 ( 59 const ConstString &var_name, 60 StringList &value, 61 Error &err 62 ) 63 { 64 return false; 65 } 66 67 bool 68 UserSettingsController::InitializeSettingsController (lldb::UserSettingsControllerSP &controller_sp, 69 SettingEntry *global_settings, 70 SettingEntry *instance_settings) 71 { 72 const lldb::UserSettingsControllerSP &parent = controller_sp->GetParent (); 73 if (parent) 74 parent->RegisterChild (controller_sp); 75 76 controller_sp->CreateSettingsVector (global_settings, true); 77 controller_sp->CreateSettingsVector (instance_settings, false); 78 79 controller_sp->InitializeGlobalVariables (); 80 controller_sp->CreateDefaultInstanceSettings (); 81 82 return true; 83 } 84 85 void 86 UserSettingsController::FinalizeSettingsController (lldb::UserSettingsControllerSP &controller_sp) 87 { 88 const lldb::UserSettingsControllerSP &parent = controller_sp->GetParent (); 89 if (parent) 90 parent->RemoveChild (controller_sp); 91 } 92 93 void 94 UserSettingsController::InitializeGlobalVariables () 95 { 96 int num_entries; 97 const char *prefix = GetLevelName().AsCString(); 98 99 num_entries = m_settings.global_settings.size(); 100 for (int i = 0; i < num_entries; ++i) 101 { 102 SettingEntry &entry = m_settings.global_settings[i]; 103 if (entry.default_value != NULL) 104 { 105 StreamString full_name; 106 if (prefix[0] != '\0') 107 full_name.Printf ("%s.%s", prefix, entry.var_name); 108 else 109 full_name.Printf ("%s", entry.var_name); 110 SetVariable (full_name.GetData(), entry.default_value, lldb::eVarSetOperationAssign, false, ""); 111 } 112 else if ((entry.var_type == lldb::eSetVarTypeEnum) 113 && (entry.enum_values != NULL)) 114 { 115 StreamString full_name; 116 if (prefix[0] != '\0') 117 full_name.Printf ("%s.%s", prefix, entry.var_name); 118 else 119 full_name.Printf ("%s", entry.var_name); 120 SetVariable (full_name.GetData(), entry.enum_values[0].string_value, lldb::eVarSetOperationAssign, 121 false, ""); 122 } 123 } 124 } 125 126 const lldb::UserSettingsControllerSP & 127 UserSettingsController::GetParent () 128 { 129 return m_settings.parent; 130 } 131 132 void 133 UserSettingsController::RegisterChild (const lldb::UserSettingsControllerSP &child) 134 { 135 Mutex::Locker locker (m_children_mutex); 136 137 // Verify child is not already in m_children. 138 size_t num_children = m_children.size(); 139 bool found = false; 140 for (size_t i = 0; i < num_children; ++i) 141 { 142 if (m_children[i].get() == child.get()) 143 found = true; 144 } 145 146 // Add child to m_children. 147 if (! found) 148 m_children.push_back (child); 149 } 150 151 const ConstString & 152 UserSettingsController::GetLevelName () 153 { 154 return m_settings.level_name; 155 } 156 157 size_t 158 UserSettingsController::GetNumChildren () 159 { 160 return m_children.size(); 161 } 162 163 const lldb::UserSettingsControllerSP 164 UserSettingsController::GetChildAtIndex (size_t index) 165 { 166 if (index < m_children.size()) 167 return m_children[index]; 168 169 lldb::UserSettingsControllerSP dummy_value; 170 171 return dummy_value; 172 } 173 174 const SettingEntry * 175 UserSettingsController::GetGlobalEntry (const ConstString &var_name) 176 { 177 178 for (int i = 0; i < m_settings.global_settings.size(); ++i) 179 { 180 SettingEntry &entry = m_settings.global_settings[i]; 181 ConstString entry_name (entry.var_name); 182 if (entry_name == var_name) 183 return &entry; 184 } 185 186 return NULL; 187 } 188 189 const SettingEntry * 190 UserSettingsController::GetInstanceEntry (const ConstString &const_var_name) 191 { 192 193 for (int i = 0; i < m_settings.instance_settings.size(); ++i) 194 { 195 SettingEntry &entry = m_settings.instance_settings[i]; 196 ConstString entry_name (entry.var_name); 197 if (entry_name == const_var_name) 198 return &entry; 199 } 200 201 return NULL; 202 } 203 204 void 205 UserSettingsController::BuildParentPrefix (std::string &parent_prefix) 206 { 207 lldb::UserSettingsControllerSP parent = GetParent(); 208 if (parent.get() != NULL) 209 { 210 parent->BuildParentPrefix (parent_prefix); 211 if (parent_prefix.length() > 0) 212 parent_prefix.append ("."); 213 } 214 parent_prefix.append (GetLevelName().AsCString()); 215 } 216 217 void 218 UserSettingsController::RemoveChild (const lldb::UserSettingsControllerSP &child) 219 { 220 Mutex::Locker locker (m_children_mutex); 221 std::vector<lldb::UserSettingsControllerSP>::iterator pos, end = m_children.end(); 222 223 for (pos = m_children.begin(); pos != end; ++pos) 224 { 225 lldb::UserSettingsControllerSP entry = *pos; 226 if (entry == child) 227 { 228 m_children.erase (pos); 229 break; 230 } 231 } 232 } 233 234 Error 235 UserSettingsController::SetVariable (const char *full_dot_name, 236 const char *value, 237 const lldb::VarSetOperationType op, 238 const bool override, 239 const char *debugger_instance_name, 240 const char *index_value) 241 { 242 Error err; 243 ConstString const_var_name; 244 const ConstString &default_name = InstanceSettings::GetDefaultName(); 245 246 Args names = UserSettingsController::BreakNameIntoPieces (full_dot_name); 247 int num_pieces = names.GetArgumentCount(); 248 249 if (num_pieces < 1) 250 { 251 err.SetErrorStringWithFormat ("'%s' is not a valid variable name; cannot assign value.\n", full_dot_name); 252 return err; 253 } 254 255 ConstString prefix (names.GetArgumentAtIndex (0)); 256 257 if ((prefix == m_settings.level_name) 258 || (m_settings.level_name.GetLength() == 0)) 259 { 260 261 if (prefix == m_settings.level_name) 262 { 263 names.Shift (); 264 num_pieces = names.GetArgumentCount(); 265 } 266 267 if (num_pieces == 0) 268 { 269 err.SetErrorString ("No variable name specified; cannot assign value.\n"); 270 return err; 271 } 272 else if (num_pieces == 1) 273 { 274 275 // Must be one of the class-wide settings. 276 277 const_var_name.SetCString (names.GetArgumentAtIndex (0)); 278 const SettingEntry *entry = GetGlobalEntry (const_var_name); 279 if (entry) 280 { 281 UserSettingsController::VerifyOperationForType (entry->var_type, op, const_var_name, err); 282 283 if (err.Fail()) 284 return err; 285 286 if ((value == NULL || value[0] == '\0') 287 && (op == lldb::eVarSetOperationAssign)) 288 { 289 if (entry->var_type != lldb::eSetVarTypeEnum) 290 value = entry->default_value; 291 else 292 value = entry->enum_values[0].string_value; 293 } 294 SetGlobalVariable (const_var_name, index_value, value, *entry, op, err); 295 } 296 else 297 { 298 // MIGHT be instance variable, to be for ALL instances. 299 300 entry = GetInstanceEntry (const_var_name); 301 if (entry == NULL) 302 { 303 err.SetErrorStringWithFormat ("Unable to find variable '%s.%s'; cannot assign value.\n", 304 prefix.AsCString(), const_var_name.AsCString()); 305 return err; 306 } 307 else 308 { 309 UserSettingsController::VerifyOperationForType (entry->var_type, op, const_var_name, err); 310 311 if (err.Fail()) 312 return err; 313 314 if ((value == NULL || value[0] == '\0') 315 && (op == lldb::eVarSetOperationAssign)) 316 { 317 if (entry->var_type != lldb::eSetVarTypeEnum) 318 value = entry->default_value; 319 else 320 value = entry->enum_values[0].string_value; 321 } 322 323 if ((m_settings.level_name.GetLength() > 0) 324 || strlen (debugger_instance_name) == 0) 325 { 326 // Set the default settings 327 m_default_settings->UpdateInstanceSettingsVariable (const_var_name, index_value, value, 328 default_name, *entry, op, err, true); 329 } 330 else 331 { 332 // We're at the Debugger level; find the correct debugger instance and set those settings 333 StreamString tmp_name; 334 if (debugger_instance_name[0] != '[') 335 tmp_name.Printf ("[%s]", debugger_instance_name); 336 else 337 tmp_name.Printf ("%s", debugger_instance_name); 338 ConstString dbg_name (tmp_name.GetData()); 339 InstanceSettings *dbg_settings = FindSettingsForInstance (dbg_name); 340 if (dbg_settings) 341 dbg_settings->UpdateInstanceSettingsVariable (const_var_name, index_value, value, dbg_name, 342 *entry, op, err, false); 343 } 344 345 if (override) 346 { 347 OverrideAllInstances (const_var_name, value, op, index_value, err); 348 349 // Update all pending records as well. 350 // std::map<std::string, lldb::InstanceSettingsSP>::iterator pos, end = m_pending_settings.end(); 351 // for (pos = m_pending_settings.begin(); pos != end; end++) 352 // { 353 // const ConstString instance_name (pos->first.c_str()); 354 // lldb::InstanceSettingsSP setting_sp = pos->second; 355 // setting_sp->UpdateInstanceSettingsVariable (const_var_name, index_value, value, 356 // instance_name, *entry, op, err, true); 357 // } 358 } 359 } 360 } 361 } 362 else 363 { 364 // Either a child's setting or an instance setting. 365 366 if (names.GetArgumentAtIndex(0)[0] == '[') 367 { 368 // An instance setting. Supposedly. 369 370 ConstString instance_name (names.GetArgumentAtIndex (0)); 371 372 // First verify that there is only one more name. 373 374 names.Shift(); 375 376 if (names.GetArgumentCount() != 1) 377 { 378 err.SetErrorStringWithFormat ("Invalid variable name format '%s'; cannot assign value.\n", 379 full_dot_name); 380 return err; 381 } 382 383 // Next verify that it is a valid instance setting name. 384 385 const_var_name.SetCString (names.GetArgumentAtIndex (0)); 386 const SettingEntry *entry = GetInstanceEntry (const_var_name); 387 388 if (entry == NULL) 389 { 390 err.SetErrorStringWithFormat ("Unknown instance variable '%s'; cannot assign value.\n", 391 const_var_name.AsCString()); 392 return err; 393 } 394 395 UserSettingsController::VerifyOperationForType (entry->var_type, op, const_var_name, err); 396 397 if (err.Fail()) 398 return err; 399 400 if ((value == NULL || value[0] == '\0') 401 && (op == lldb::eVarSetOperationAssign)) 402 { 403 if (entry->var_type != lldb::eSetVarTypeEnum) 404 value = entry->default_value; 405 else 406 value = entry->enum_values[0].string_value; 407 } 408 409 // Now look for existing instance with given instance name; if not found, find or create pending 410 // setting for instance with given name. 411 412 InstanceSettings *current_settings = FindSettingsForInstance (instance_name); 413 414 if (current_settings != NULL) 415 { 416 current_settings->UpdateInstanceSettingsVariable (const_var_name, index_value, value, 417 instance_name, *entry, op, err, false); 418 419 } 420 else 421 { 422 // Instance does not currently exist; make or update a pending setting for it. 423 lldb::InstanceSettingsSP current_settings_sp = PendingSettingsForInstance (instance_name); 424 425 // Now we have a settings record, update it appropriately. 426 427 current_settings_sp->UpdateInstanceSettingsVariable (const_var_name, index_value, value, 428 instance_name, *entry, op, err, true); 429 430 { // Scope for mutex. 431 Mutex::Locker locker (m_pending_settings_mutex); 432 m_pending_settings[instance_name.AsCString()] = current_settings_sp; 433 } 434 435 if (override) 436 { 437 OverrideAllInstances (const_var_name, value, op, index_value, err); 438 439 // Update all pending records as well. 440 std::map<std::string, lldb::InstanceSettingsSP>::iterator pos; 441 std::map<std::string, lldb::InstanceSettingsSP>::iterator end = m_pending_settings.end(); 442 for (pos = m_pending_settings.begin(); pos != end; end++) 443 { 444 const ConstString tmp_inst_name (pos->first.c_str()); 445 lldb::InstanceSettingsSP setting_sp = pos->second; 446 setting_sp->UpdateInstanceSettingsVariable (const_var_name, index_value, value, 447 tmp_inst_name, *entry, op, err, true); 448 } 449 } 450 } 451 } 452 else 453 { 454 // A child setting. 455 lldb::UserSettingsControllerSP child; 456 ConstString child_prefix (names.GetArgumentAtIndex (0)); 457 int num_children = GetNumChildren(); 458 bool found = false; 459 for (int i = 0; i < num_children && !found; ++i) 460 { 461 child = GetChildAtIndex (i); 462 ConstString current_prefix = child->GetLevelName(); 463 if (current_prefix == child_prefix) 464 { 465 found = true; 466 std::string new_name; 467 for (int j = 0; j < names.GetArgumentCount(); ++j) 468 { 469 if (j > 0) 470 new_name += '.'; 471 new_name += names.GetArgumentAtIndex (j); 472 } 473 return child->SetVariable (new_name.c_str(), value, op, override, debugger_instance_name, 474 index_value); 475 } 476 } 477 if (!found) 478 { 479 err.SetErrorStringWithFormat ("Unable to find variable '%s'; cannot assign value.\n", 480 full_dot_name); 481 return err; 482 } 483 } 484 } 485 } 486 else 487 { 488 err.SetErrorStringWithFormat ("'%s' is not a valid level name; was expecting '%s'. Cannot assign value.\n", 489 prefix.AsCString(), m_settings.level_name.AsCString()); 490 } 491 492 return err; 493 } 494 495 StringList 496 UserSettingsController::GetVariable 497 ( 498 const char *full_dot_name, 499 lldb::SettableVariableType &var_type, 500 const char *debugger_instance_name, 501 Error &err 502 ) 503 { 504 Args names = UserSettingsController::BreakNameIntoPieces (full_dot_name); 505 ConstString const_var_name; 506 StringList value; 507 508 int num_pieces = names.GetArgumentCount(); 509 510 ConstString prefix (names.GetArgumentAtIndex (0)); 511 const_var_name.SetCString (names.GetArgumentAtIndex (num_pieces - 1)); 512 513 const SettingEntry *global_entry = GetGlobalEntry (const_var_name); 514 const SettingEntry *instance_entry = GetInstanceEntry (const_var_name); 515 516 if ((prefix != m_settings.level_name) 517 && (m_settings.level_name.GetLength () > 0)) 518 { 519 err.SetErrorString ("Invalid variable name"); 520 return value; 521 } 522 523 // prefix name matched; remove it from names. 524 if (m_settings.level_name.GetLength() > 0) 525 names.Shift(); 526 527 // Should we pass this off to a child? If there is more than one name piece left, and the next name piece 528 // matches a child prefix, then yes. 529 530 lldb::UserSettingsControllerSP child; 531 if (names.GetArgumentCount() > 1) 532 { 533 ConstString child_prefix (names.GetArgumentAtIndex (0)); 534 bool found = false; 535 for (int i = 0; i < m_children.size() && !found; ++i) 536 { 537 if (child_prefix == m_children[i]->GetLevelName()) 538 { 539 found = true; 540 child = m_children[i]; 541 std::string new_name; 542 for (int j = 0; j < names.GetArgumentCount(); ++j) 543 { 544 if (j > 0) 545 new_name += '.'; 546 new_name += names.GetArgumentAtIndex (j); 547 } 548 return child->GetVariable (new_name.c_str(), var_type, debugger_instance_name, err); 549 } 550 } 551 552 if (!found) 553 { 554 // Cannot be handled by a child, because name did not match any child prefixes. 555 // Cannot be a class-wide variable because there are too many name pieces. 556 557 if (instance_entry != NULL) 558 { 559 var_type = instance_entry->var_type; 560 ConstString instance_name (names.GetArgumentAtIndex (0)); 561 InstanceSettings *current_settings = FindSettingsForInstance (instance_name); 562 563 if (current_settings != NULL) 564 { 565 current_settings->GetInstanceSettingsValue (*instance_entry, const_var_name, value, &err); 566 } 567 else 568 { 569 // Look for instance name setting in pending settings. 570 571 std::string inst_name_str = instance_name.AsCString(); 572 std::map<std::string, lldb::InstanceSettingsSP>::iterator pos; 573 574 pos = m_pending_settings.find (inst_name_str); 575 if (pos != m_pending_settings.end()) 576 { 577 lldb::InstanceSettingsSP settings_sp = pos->second; 578 settings_sp->GetInstanceSettingsValue (*instance_entry, const_var_name, value, &err); 579 } 580 else 581 { 582 if (m_settings.level_name.GetLength() > 0) 583 { 584 // No valid instance name; assume they want the default settings. 585 m_default_settings->GetInstanceSettingsValue (*instance_entry, const_var_name, value, &err); 586 } 587 else 588 { 589 // We're at the Debugger level; use the debugger's instance settings. 590 StreamString tmp_name; 591 if (debugger_instance_name[0] != '[') 592 tmp_name.Printf ("[%s]", debugger_instance_name); 593 else 594 tmp_name.Printf ("%s", debugger_instance_name); 595 ConstString dbg_name (debugger_instance_name); 596 InstanceSettings *dbg_settings = FindSettingsForInstance (dbg_name); 597 if (dbg_settings) 598 dbg_settings->GetInstanceSettingsValue (*instance_entry, const_var_name, value, &err); 599 } 600 } 601 } 602 } 603 else 604 err.SetErrorString ("Invalid variable name"); 605 } 606 } 607 else 608 { 609 // Only one name left. It must belong to the current level, or be an error. 610 if ((global_entry == NULL) 611 && (instance_entry == NULL)) 612 { 613 err.SetErrorString ("Invalid variable name"); 614 } 615 else if (global_entry) 616 { 617 var_type = global_entry->var_type; 618 GetGlobalVariable (const_var_name, value, err); 619 } 620 else if (instance_entry) 621 { 622 var_type = instance_entry->var_type; 623 if (m_settings.level_name.GetLength() > 0) 624 m_default_settings->GetInstanceSettingsValue (*instance_entry, const_var_name, value, &err); 625 else 626 { 627 // We're at the Debugger level; use the debugger's instance settings. 628 StreamString tmp_name; 629 if (debugger_instance_name[0] != '[') 630 tmp_name.Printf ("[%s]", debugger_instance_name); 631 else 632 tmp_name.Printf ("%s", debugger_instance_name); 633 ConstString dbg_name (tmp_name.GetData()); 634 InstanceSettings *dbg_settings = FindSettingsForInstance (dbg_name); 635 if (dbg_settings) 636 dbg_settings->GetInstanceSettingsValue (*instance_entry, const_var_name, value, &err); 637 } 638 } 639 } 640 641 return value; 642 } 643 644 void 645 UserSettingsController::RemovePendingSettings (const ConstString &instance_name) 646 { 647 StreamString tmp_name; 648 649 // Add surrounding brackets to instance name if not already present. 650 651 if (instance_name.AsCString()[0] != '[') 652 tmp_name.Printf ("[%s]", instance_name.AsCString()); 653 else 654 tmp_name.Printf ("%s", instance_name.AsCString()); 655 656 std::string instance_name_str (tmp_name.GetData()); 657 std::map<std::string, lldb::InstanceSettingsSP>::iterator pos; 658 Mutex::Locker locker (m_pending_settings_mutex); 659 660 m_pending_settings.erase (instance_name_str); 661 } 662 663 const lldb::InstanceSettingsSP & 664 UserSettingsController::FindPendingSettings (const ConstString &instance_name) 665 { 666 std::map<std::string, lldb::InstanceSettingsSP>::iterator pos; 667 StreamString tmp_name; 668 669 // Add surrounding brackets to instance name if not already present. 670 671 if (instance_name.AsCString()[0] != '[') 672 tmp_name.Printf ("[%s]", instance_name.AsCString()); 673 else 674 tmp_name.Printf ("%s", instance_name.AsCString()); 675 676 std::string instance_name_str (tmp_name.GetData()); // Need std::string for std::map look-up 677 678 { // Scope for mutex. 679 Mutex::Locker locker (m_pending_settings_mutex); 680 681 pos = m_pending_settings.find (instance_name_str); 682 if (pos != m_pending_settings.end()) 683 return pos->second; 684 } 685 686 return m_default_settings; 687 } 688 689 void 690 UserSettingsController::CreateDefaultInstanceSettings () 691 { 692 Error err; 693 const ConstString &default_name = InstanceSettings::GetDefaultName(); 694 for (int i = 0; i < m_settings.instance_settings.size(); ++i) 695 { 696 SettingEntry &entry = m_settings.instance_settings[i]; 697 ConstString var_name (entry.var_name); 698 const char *value = entry.default_value; 699 700 if (entry.var_type == lldb::eSetVarTypeEnum) 701 value = entry.enum_values[0].string_value; 702 703 m_default_settings->UpdateInstanceSettingsVariable (var_name, NULL, value, default_name, entry, 704 lldb::eVarSetOperationAssign, err, true); 705 } 706 } 707 708 void 709 UserSettingsController::CopyDefaultSettings (const lldb::InstanceSettingsSP &actual_settings, 710 const ConstString &instance_name, 711 bool pending) 712 { 713 Error err; 714 for (int i = 0; i < m_settings.instance_settings.size(); ++i) 715 { 716 SettingEntry &entry = m_settings.instance_settings[i]; 717 ConstString var_name (entry.var_name); 718 StringList value; 719 m_default_settings->GetInstanceSettingsValue (entry, var_name, value, NULL); 720 721 std::string value_str; 722 if (value.GetSize() == 1) 723 value_str.append (value.GetStringAtIndex (0)); 724 else if (value.GetSize() > 1) 725 { 726 for (int j = 0; j < value.GetSize(); ++j) 727 { 728 if (j > 0) 729 value_str.append (" "); 730 value_str.append (value.GetStringAtIndex (j)); 731 } 732 } 733 734 actual_settings->UpdateInstanceSettingsVariable (var_name, NULL, value_str.c_str(), instance_name, entry, 735 lldb::eVarSetOperationAssign, err, pending); 736 737 } 738 } 739 740 lldb::InstanceSettingsSP 741 UserSettingsController::PendingSettingsForInstance (const ConstString &instance_name) 742 { 743 std::string name_str (instance_name.AsCString()); 744 std::map<std::string, lldb::InstanceSettingsSP>::iterator pos; 745 Mutex::Locker locker (m_pending_settings_mutex); 746 747 pos = m_pending_settings.find (name_str); 748 if (pos != m_pending_settings.end()) 749 { 750 lldb::InstanceSettingsSP settings_sp = pos->second; 751 return settings_sp; 752 } 753 else 754 { 755 lldb::InstanceSettingsSP new_settings_sp = CreateInstanceSettings (instance_name.AsCString()); 756 CopyDefaultSettings (new_settings_sp, instance_name, true); 757 m_pending_settings[name_str] = new_settings_sp; 758 return new_settings_sp; 759 } 760 761 // Should never reach this line. 762 763 lldb::InstanceSettingsSP dummy; 764 765 return dummy; 766 } 767 768 void 769 UserSettingsController::GetAllDefaultSettingValues (StreamString &result_stream) 770 { 771 std::string parent_prefix; 772 BuildParentPrefix (parent_prefix); 773 const char *prefix = parent_prefix.c_str(); 774 775 for (int i = 0; i < m_settings.instance_settings.size(); ++i) 776 { 777 SettingEntry &entry = m_settings.instance_settings[i]; 778 ConstString var_name (entry.var_name); 779 StringList tmp_value; 780 m_default_settings->GetInstanceSettingsValue (entry, var_name, tmp_value, NULL); 781 782 StreamString value_string; 783 784 if (tmp_value.GetSize() == 1) 785 value_string.Printf ("%s", tmp_value.GetStringAtIndex (0)); 786 else 787 { 788 for (int j = 0; j < tmp_value.GetSize(); ++j) 789 value_string.Printf ("%s ", tmp_value.GetStringAtIndex (j)); 790 } 791 792 if (! parent_prefix.empty()) 793 result_stream.Printf ("%s.%s (%s) = '%s'\n", prefix, var_name.AsCString(), 794 UserSettingsController::GetTypeString (entry.var_type), value_string.GetData()); 795 } 796 } 797 798 void 799 UserSettingsController::GetAllPendingSettingValues (StreamString &result_stream) 800 { 801 std::map<std::string, lldb::InstanceSettingsSP>::iterator pos; 802 803 std::string parent_prefix; 804 BuildParentPrefix (parent_prefix); 805 const char *prefix = parent_prefix.c_str(); 806 807 for (pos = m_pending_settings.begin(); pos != m_pending_settings.end(); ++pos) 808 { 809 std::string tmp_name = pos->first; 810 lldb::InstanceSettingsSP settings_sp = pos->second; 811 812 const ConstString instance_name (tmp_name.c_str()); 813 814 for (int i = 0; i < m_settings.instance_settings.size(); ++i) 815 { 816 SettingEntry &entry = m_settings.instance_settings[i]; 817 ConstString var_name (entry.var_name); 818 StringList tmp_value; 819 settings_sp->GetInstanceSettingsValue (entry, var_name, tmp_value, NULL); 820 821 StreamString value_str; 822 823 if (tmp_value.GetSize() == 0) 824 value_str.Printf (""); 825 else if (tmp_value.GetSize() == 1) 826 value_str.Printf ("%s", tmp_value.GetStringAtIndex (0)); 827 else 828 { 829 for (int j = 0; j < tmp_value.GetSize(); ++j) 830 value_str.Printf ("%s ", tmp_value.GetStringAtIndex (j)); 831 } 832 833 if (parent_prefix.length() > 0) 834 { 835 result_stream.Printf ("%s.%s.%s (%s) = '%s' [pending]\n", prefix, instance_name.AsCString(), 836 var_name.AsCString(), UserSettingsController::GetTypeString (entry.var_type), 837 value_str.GetData()); 838 } 839 else 840 { 841 result_stream.Printf ("%s (%s) = '%s' [pending]\n", var_name.AsCString(), 842 UserSettingsController::GetTypeString (entry.var_type), 843 value_str.GetData()); 844 } 845 } 846 } 847 } 848 849 InstanceSettings * 850 UserSettingsController::FindSettingsForInstance (const ConstString &instance_name) 851 { 852 std::string instance_name_str (instance_name.AsCString()); 853 std::map<std::string, InstanceSettings *>::iterator pos; 854 855 pos = m_live_settings.find (instance_name_str); 856 if (pos != m_live_settings.end ()) 857 { 858 InstanceSettings *settings = pos->second; 859 return settings; 860 } 861 862 return NULL; 863 } 864 865 void 866 UserSettingsController::GetAllInstanceVariableValues (CommandInterpreter &interpreter, 867 StreamString &result_stream) 868 { 869 std::map<std::string, InstanceSettings *>::iterator pos; 870 std::string parent_prefix; 871 BuildParentPrefix (parent_prefix); 872 const char *prefix = parent_prefix.c_str(); 873 StreamString description; 874 875 for (pos = m_live_settings.begin(); pos != m_live_settings.end(); ++pos) 876 { 877 std::string instance_name = pos->first; 878 InstanceSettings *settings = pos->second; 879 880 for (int i = 0; i < m_settings.instance_settings.size(); ++i) 881 { 882 SettingEntry &entry = m_settings.instance_settings[i]; 883 const ConstString var_name (entry.var_name); 884 StringList tmp_value; 885 settings->GetInstanceSettingsValue (entry, var_name, tmp_value, NULL); 886 StreamString tmp_value_str; 887 888 if (tmp_value.GetSize() == 0) 889 tmp_value_str.Printf (""); 890 else if (tmp_value.GetSize() == 1) 891 tmp_value_str.Printf ("%s", tmp_value.GetStringAtIndex (0)); 892 else 893 { 894 for (int j = 0; j < tmp_value.GetSize(); ++j) 895 tmp_value_str.Printf ("%s ",tmp_value.GetStringAtIndex (j)); 896 } 897 898 description.Clear(); 899 if (parent_prefix.length() > 0) 900 { 901 description.Printf ("%s.%s.%s (%s) = '%s'", prefix, instance_name.c_str(), var_name.AsCString(), 902 UserSettingsController::GetTypeString (entry.var_type), 903 tmp_value_str.GetData()); 904 } 905 else 906 { 907 description.Printf ("%s (%s) = '%s'", var_name.AsCString(), 908 UserSettingsController::GetTypeString (entry.var_type), tmp_value_str.GetData()); 909 } 910 result_stream.Printf ("%s\n", description.GetData()); 911 } 912 } 913 } 914 915 void 916 UserSettingsController::OverrideAllInstances (const ConstString &var_name, 917 const char *value, 918 lldb::VarSetOperationType op, 919 const char *index_value, 920 Error &err) 921 { 922 std::map<std::string, InstanceSettings *>::iterator pos; 923 StreamString description; 924 925 for (pos = m_live_settings.begin(); pos != m_live_settings.end(); ++pos) 926 { 927 InstanceSettings *settings = pos->second; 928 StreamString tmp_name; 929 tmp_name.Printf ("[%s]", settings->GetInstanceName().AsCString()); 930 const ConstString instance_name (tmp_name.GetData()); 931 const SettingEntry *entry = GetInstanceEntry (var_name); 932 settings->UpdateInstanceSettingsVariable (var_name, index_value, value, instance_name, *entry, op, err, false); 933 934 } 935 } 936 937 void 938 UserSettingsController::RegisterInstanceSettings (InstanceSettings *instance_settings) 939 { 940 Mutex::Locker locker (m_live_settings_mutex); 941 StreamString tmp_name; 942 tmp_name.Printf ("[%s]", instance_settings->GetInstanceName().AsCString()); 943 const ConstString instance_name (tmp_name.GetData()); 944 std::string instance_name_str (instance_name.AsCString()); 945 if (instance_name_str.compare (InstanceSettings::GetDefaultName().AsCString()) != 0) 946 m_live_settings[instance_name_str] = instance_settings; 947 } 948 949 void 950 UserSettingsController::UnregisterInstanceSettings (InstanceSettings *instance) 951 { 952 Mutex::Locker locker (m_live_settings_mutex); 953 StreamString tmp_name; 954 tmp_name.Printf ("[%s]", instance->GetInstanceName().AsCString()); 955 std::string instance_name (tmp_name.GetData()); 956 957 std::map <std::string, InstanceSettings *>::iterator pos; 958 959 pos = m_live_settings.find (instance_name); 960 if (pos != m_live_settings.end()) 961 m_live_settings.erase (pos); 962 } 963 964 void 965 UserSettingsController::CreateSettingsVector (const SettingEntry *table, 966 bool global) 967 { 968 int i = 0; 969 while (table[i].var_name != NULL) 970 { 971 const SettingEntry &table_entry = table[i]; 972 ConstString const_var_name (table_entry.var_name); 973 SettingEntry new_entry; 974 975 new_entry = table_entry; 976 new_entry.var_name = const_var_name.AsCString(); 977 978 if (global) 979 m_settings.global_settings.push_back (new_entry); 980 else 981 m_settings.instance_settings.push_back (new_entry); 982 983 ++i; 984 } 985 } 986 987 //---------------------------------------------------------------------- 988 // UserSettingsController static methods 989 //---------------------------------------------------------------------- 990 991 int 992 FindMaxNameLength (std::vector<SettingEntry> table) 993 { 994 int max_length = 1; 995 996 for (int i = 0; i < table.size(); ++i) 997 { 998 int len = strlen (table[i].var_name); 999 if (len > max_length) 1000 max_length = len; 1001 } 1002 1003 return max_length; 1004 } 1005 1006 const char * 1007 UserSettingsController::GetTypeString (lldb::SettableVariableType var_type) 1008 { 1009 switch (var_type) 1010 { 1011 case lldb::eSetVarTypeInt: 1012 return "int"; 1013 case lldb::eSetVarTypeBool: 1014 return "boolean"; 1015 case lldb::eSetVarTypeString: 1016 return "string"; 1017 case lldb::eSetVarTypeArray: 1018 return "array"; 1019 case lldb::eSetVarTypeDictionary: 1020 return "dictionary"; 1021 case lldb::eSetVarTypeEnum: 1022 return "enum"; 1023 case lldb::eSetVarTypeNone: 1024 return "no type"; 1025 } 1026 1027 return ""; 1028 } 1029 1030 void 1031 UserSettingsController::PrintEnumValues (const lldb::OptionEnumValueElement *enum_values, Stream &str) 1032 { 1033 int i = 0; 1034 while (enum_values[i].string_value != NULL) 1035 { 1036 str.Printf ("%s ", enum_values[i].string_value); 1037 ++i; 1038 } 1039 1040 } 1041 1042 void 1043 UserSettingsController::FindAllSettingsDescriptions (CommandInterpreter &interpreter, 1044 lldb::UserSettingsControllerSP root, 1045 std::string ¤t_prefix, 1046 StreamString &result_stream, 1047 Error &err) 1048 { 1049 // Write out current prefix line. 1050 StreamString prefix_line; 1051 StreamString description; 1052 uint32_t max_len; 1053 int num_entries = root->m_settings.global_settings.size(); 1054 1055 max_len = FindMaxNameLength (root->m_settings.global_settings); 1056 1057 if (! current_prefix.empty()) 1058 result_stream.Printf ("\n'%s' variables:\n\n", current_prefix.c_str()); 1059 else 1060 result_stream.Printf ("\nTop level variables:\n\n"); 1061 1062 if (num_entries > 0) 1063 { 1064 // Write out all "global" variables. 1065 for (int i = 0; i < num_entries; ++i) 1066 { 1067 SettingEntry entry = root->m_settings.global_settings[i]; 1068 description.Clear(); 1069 if (entry.var_type == lldb::eSetVarTypeEnum) 1070 { 1071 StreamString enum_values_str; 1072 UserSettingsController::PrintEnumValues (entry.enum_values, enum_values_str); 1073 description.Printf ("[static, enum] %s. Valid values: {%s} (default: '%s')", entry.description, 1074 enum_values_str.GetData(), entry.enum_values[0].string_value); 1075 } 1076 else if (entry.default_value != NULL) 1077 description.Printf ("[static, %s] %s (default: '%s')", GetTypeString (entry.var_type), 1078 entry.description, entry.default_value); 1079 1080 else 1081 description.Printf ("[static, %s] %s (default: '')", GetTypeString (entry.var_type), 1082 entry.description); 1083 interpreter.OutputFormattedHelpText (result_stream, entry.var_name, "--", description.GetData(), 1084 max_len); 1085 } 1086 } 1087 1088 num_entries = root->m_settings.instance_settings.size(); 1089 max_len = FindMaxNameLength (root->m_settings.instance_settings); 1090 1091 if (num_entries > 0) 1092 { 1093 // Write out all instance variables. 1094 for (int i = 0; i < num_entries; ++i) 1095 { 1096 SettingEntry entry = root->m_settings.instance_settings[i]; 1097 description.Clear(); 1098 if (entry.var_type == lldb::eSetVarTypeEnum) 1099 { 1100 StreamString enum_values_str; 1101 UserSettingsController::PrintEnumValues (entry.enum_values, enum_values_str); 1102 description.Printf ("[instance, enum] %s. Valid values: {%s} (default: '%s')", entry.description, 1103 enum_values_str.GetData(), entry.enum_values[0].string_value); 1104 } 1105 else if (entry.default_value != NULL) 1106 description.Printf ("[instance, %s] %s (default: '%s')", GetTypeString (entry.var_type), 1107 entry.description, entry.default_value); 1108 else 1109 description.Printf ("[instance, %s] %s (default: '')", GetTypeString (entry.var_type), 1110 entry.description); 1111 interpreter.OutputFormattedHelpText (result_stream, entry.var_name, "--", description.GetData(), 1112 max_len); 1113 } 1114 1115 } 1116 1117 // Now, recurse across all children. 1118 int num_children = root->GetNumChildren(); 1119 for (int i = 0; i < num_children; ++i) 1120 { 1121 lldb::UserSettingsControllerSP child = root->GetChildAtIndex (i); 1122 1123 if (child) 1124 { 1125 ConstString child_prefix = child->GetLevelName(); 1126 StreamString new_prefix; 1127 if (! current_prefix.empty()) 1128 new_prefix.Printf ("%s.%s", current_prefix.c_str(), child_prefix.AsCString()); 1129 else 1130 new_prefix.Printf ("%s", child_prefix.AsCString()); 1131 std::string new_prefix_str = new_prefix.GetData(); 1132 UserSettingsController::FindAllSettingsDescriptions (interpreter, child, new_prefix_str, result_stream, 1133 err); 1134 } 1135 } 1136 } 1137 1138 void 1139 UserSettingsController::FindSettingsDescriptions (CommandInterpreter &interpreter, 1140 lldb::UserSettingsControllerSP root, 1141 std::string ¤t_prefix, 1142 const char *search_name, 1143 StreamString &result_stream, 1144 Error &err) 1145 { 1146 Args names = UserSettingsController::BreakNameIntoPieces (search_name); 1147 int num_pieces = names.GetArgumentCount (); 1148 1149 if (num_pieces == 0) 1150 return; 1151 1152 if (root->GetLevelName().GetLength() > 0) 1153 { 1154 ConstString prefix (names.GetArgumentAtIndex (0)); 1155 if (prefix != root->GetLevelName()) 1156 { 1157 std::string parent_prefix; 1158 root->BuildParentPrefix (parent_prefix); 1159 err.SetErrorStringWithFormat ("Cannot find match for '%s.%s'\n", parent_prefix.c_str(), 1160 prefix.AsCString()); 1161 return; 1162 } 1163 else 1164 { 1165 names.Shift(); 1166 --num_pieces; 1167 } 1168 } 1169 1170 // If there's nothing left then dump all global and instance descriptions for this root. 1171 if (num_pieces == 0) 1172 { 1173 StreamString prefix_line; 1174 StreamString description; 1175 uint32_t max_len; 1176 int num_entries = root->m_settings.global_settings.size(); 1177 1178 max_len = FindMaxNameLength (root->m_settings.global_settings); 1179 1180 result_stream.Printf ("\n'%s' variables:\n\n", search_name); 1181 1182 if (num_entries > 0) 1183 { 1184 // Write out all "global" variables. 1185 for (int i = 0; i < num_entries; ++i) 1186 { 1187 SettingEntry entry = root->m_settings.global_settings[i]; 1188 description.Clear(); 1189 if (entry.var_type == lldb::eSetVarTypeEnum) 1190 { 1191 StreamString enum_values_str; 1192 UserSettingsController::PrintEnumValues (entry.enum_values, enum_values_str); 1193 description.Printf ("[static, enum] %s. Valid values: {%s} (default: '%s')", entry.description, 1194 enum_values_str.GetData(), entry.enum_values[0].string_value); 1195 } 1196 else if (entry.default_value != NULL) 1197 description.Printf ("[static, %s] %s (default: '%s')", GetTypeString (entry.var_type), 1198 entry.description, entry.default_value); 1199 else 1200 description.Printf ("[static, %s] %s (default: '')", GetTypeString (entry.var_type), 1201 entry.description); 1202 interpreter.OutputFormattedHelpText (result_stream, entry.var_name, "--", description.GetData(), 1203 max_len); 1204 } 1205 } 1206 1207 num_entries = root->m_settings.instance_settings.size(); 1208 max_len = FindMaxNameLength (root->m_settings.instance_settings); 1209 1210 if (num_entries > 0) 1211 { 1212 // Write out all instance variables. 1213 for (int i = 0; i < num_entries; ++i) 1214 { 1215 SettingEntry entry = root->m_settings.instance_settings[i]; 1216 description.Clear(); 1217 if (entry.var_type == lldb::eSetVarTypeEnum) 1218 { 1219 StreamString enum_values_str; 1220 UserSettingsController::PrintEnumValues (entry.enum_values, enum_values_str); 1221 description.Printf ("[instance, enum] %s. Valid values: {%s} (default: '%s')", entry.description, 1222 enum_values_str.GetData(), entry.enum_values[0].string_value); 1223 } 1224 else if (entry.default_value != NULL) 1225 description.Printf ("[instance, %s] %s (default: '%s')", GetTypeString (entry.var_type), 1226 entry.description, entry.default_value); 1227 else 1228 description.Printf ("[instance, %s] %s (default: '')", GetTypeString (entry.var_type), 1229 entry.description); 1230 interpreter.OutputFormattedHelpText (result_stream, entry.var_name, "--", description.GetData(), 1231 max_len); 1232 } 1233 } 1234 } 1235 else if (num_pieces == 1) 1236 { 1237 ConstString var_name (names.GetArgumentAtIndex (0)); 1238 bool is_global = false; 1239 1240 const SettingEntry *setting_entry = root->GetGlobalEntry (var_name); 1241 1242 if (setting_entry == NULL) 1243 setting_entry = root->GetInstanceEntry (var_name); 1244 else 1245 is_global = true; 1246 1247 // Check to see if it is a global or instance variable name. 1248 if (setting_entry != NULL) 1249 { 1250 StreamString description; 1251 if (setting_entry->var_type == lldb::eSetVarTypeEnum) 1252 { 1253 StreamString enum_values_str; 1254 UserSettingsController::PrintEnumValues (setting_entry->enum_values, enum_values_str); 1255 description.Printf ("[%s, enum] %s. Valid values: {%s} (default: '%s')", 1256 (is_global ? "static" : "instance"), 1257 setting_entry->description, 1258 enum_values_str.GetData(), setting_entry->enum_values[0].string_value); 1259 } 1260 else if (setting_entry->default_value != NULL) 1261 description.Printf ("[%s, %s] %s (default: '%s')", 1262 (is_global ? "static" : "instance"), 1263 GetTypeString (setting_entry->var_type), 1264 setting_entry->description, setting_entry->default_value); 1265 else 1266 description.Printf ("[%s, %s] %s (default: '')", 1267 (is_global ? "static" : "instance"), 1268 GetTypeString (setting_entry->var_type), 1269 setting_entry->description); 1270 interpreter.OutputFormattedHelpText (result_stream, setting_entry->var_name, "--", description.GetData(), 1271 var_name.GetLength()); 1272 } 1273 else 1274 { 1275 // It must be a child name. 1276 int num_children = root->GetNumChildren(); 1277 bool found = false; 1278 for (int i = 0; i < num_children && !found; ++i) 1279 { 1280 lldb::UserSettingsControllerSP child = root->GetChildAtIndex (i); 1281 if (child) 1282 { 1283 ConstString child_prefix = child->GetLevelName(); 1284 if (child_prefix == var_name) 1285 { 1286 found = true; 1287 UserSettingsController::FindSettingsDescriptions (interpreter, child, current_prefix, 1288 var_name.AsCString(), result_stream, err); 1289 } 1290 } 1291 } 1292 if (!found) 1293 { 1294 std::string parent_prefix; 1295 root->BuildParentPrefix (parent_prefix); 1296 err.SetErrorStringWithFormat ("Cannot find match for '%s.%s'\n", parent_prefix.c_str(), search_name); 1297 return; 1298 } 1299 } 1300 } 1301 else 1302 { 1303 // It must be a child name; find the child and call this function recursively on child. 1304 ConstString child_name (names.GetArgumentAtIndex (0)); 1305 1306 StreamString rest_of_search_name; 1307 for (int i = 0; i < num_pieces; ++i) 1308 { 1309 rest_of_search_name.Printf ("%s", names.GetArgumentAtIndex (i)); 1310 if ((i + 1) < num_pieces) 1311 rest_of_search_name.Printf ("."); 1312 } 1313 1314 int num_children = root->GetNumChildren(); 1315 bool found = false; 1316 for (int i = 0; i < num_children && !found; ++i) 1317 { 1318 lldb::UserSettingsControllerSP child = root->GetChildAtIndex (i); 1319 if (child) 1320 { 1321 ConstString child_prefix = child->GetLevelName(); 1322 if (child_prefix == child_name) 1323 { 1324 found = true; 1325 UserSettingsController::FindSettingsDescriptions (interpreter, child, current_prefix, 1326 rest_of_search_name.GetData(), result_stream, 1327 err); 1328 } 1329 } 1330 } 1331 if (!found) 1332 { 1333 std::string parent_prefix; 1334 root->BuildParentPrefix (parent_prefix); 1335 err.SetErrorStringWithFormat ("Cannot find match for '%s.%s'\n", parent_prefix.c_str(), search_name); 1336 return; 1337 } 1338 } 1339 } 1340 1341 void 1342 UserSettingsController::GetAllVariableValues (CommandInterpreter &interpreter, 1343 lldb::UserSettingsControllerSP root, 1344 std::string ¤t_prefix, 1345 StreamString &result_stream, 1346 Error &err) 1347 { 1348 StreamString description; 1349 int num_entries = root->m_settings.global_settings.size(); 1350 lldb::SettableVariableType var_type; 1351 1352 1353 for (int i = 0; i < num_entries; ++i) 1354 { 1355 StreamString full_var_name; 1356 SettingEntry entry = root->m_settings.global_settings[i]; 1357 if (! current_prefix.empty()) 1358 full_var_name.Printf ("%s.%s", current_prefix.c_str(), entry.var_name); 1359 else 1360 full_var_name.Printf ("%s", entry.var_name); 1361 StringList value = root->GetVariable (full_var_name.GetData(), var_type, 1362 interpreter.GetDebugger().GetInstanceName().AsCString(), err); 1363 description.Clear(); 1364 if (value.GetSize() == 1) 1365 description.Printf ("%s (%s) = '%s'", full_var_name.GetData(), GetTypeString (entry.var_type), 1366 value.GetStringAtIndex (0)); 1367 else 1368 { 1369 description.Printf ("%s (%s) = '", full_var_name.GetData(), GetTypeString (entry.var_type)); 1370 for (int j = 0; j < value.GetSize(); ++j) 1371 description.Printf ("%s ", value.GetStringAtIndex (j)); 1372 description.Printf ("'"); 1373 } 1374 1375 result_stream.Printf ("%s\n", description.GetData()); 1376 } 1377 1378 root->GetAllInstanceVariableValues (interpreter, result_stream); 1379 root->GetAllPendingSettingValues (result_stream); 1380 if (root->GetLevelName().GetLength() > 0) // Don't bother with default values for Debugger level. 1381 root->GetAllDefaultSettingValues (result_stream); 1382 1383 1384 // Now, recurse across all children. 1385 int num_children = root->GetNumChildren(); 1386 for (int i = 0; i < num_children; ++i) 1387 { 1388 lldb::UserSettingsControllerSP child = root->GetChildAtIndex (i); 1389 1390 if (child) 1391 { 1392 ConstString child_prefix = child->GetLevelName(); 1393 StreamString new_prefix; 1394 if (! current_prefix.empty()) 1395 new_prefix.Printf ("%s.%s", current_prefix.c_str(), child_prefix.AsCString()); 1396 else 1397 new_prefix.Printf ("%s", child_prefix.AsCString()); 1398 std::string new_prefix_str = new_prefix.GetData(); 1399 UserSettingsController::GetAllVariableValues (interpreter, child, new_prefix_str, result_stream, 1400 err); 1401 } 1402 } 1403 1404 } 1405 1406 Args 1407 UserSettingsController::BreakNameIntoPieces (const char *full_dot_name) 1408 { 1409 Args return_value; 1410 std::string name_string (full_dot_name); 1411 bool done = false; 1412 1413 std::string piece; 1414 std::string remainder (full_dot_name); 1415 1416 while (!done) 1417 { 1418 size_t idx = remainder.find_first_of ('.'); 1419 piece = remainder.substr (0, idx); 1420 return_value.AppendArgument (piece.c_str()); 1421 if (idx != std::string::npos) 1422 remainder = remainder.substr (idx+1); 1423 else 1424 done = true; 1425 } 1426 1427 return return_value; 1428 } 1429 1430 bool 1431 UserSettingsController::IsLiveInstance (const std::string &instance_name) 1432 { 1433 std::map<std::string, InstanceSettings *>::iterator pos; 1434 1435 pos = m_live_settings.find (instance_name); 1436 if (pos != m_live_settings.end()) 1437 return true; 1438 1439 return false; 1440 } 1441 1442 int 1443 UserSettingsController::CompleteSettingsValue (lldb::UserSettingsControllerSP root_settings, 1444 const char *full_dot_name, 1445 const char *partial_value, 1446 bool &word_complete, 1447 StringList &matches) 1448 { 1449 Args names = UserSettingsController::BreakNameIntoPieces (full_dot_name); 1450 int num_pieces = names.GetArgumentCount(); 1451 word_complete = true; 1452 1453 ConstString root_level = root_settings->GetLevelName(); 1454 int num_extra_levels = num_pieces - 2; 1455 if ((num_extra_levels > 0) 1456 && root_level.GetLength() > 0) 1457 { 1458 ConstString current_level (names.GetArgumentAtIndex (0)); 1459 if (current_level == root_level) 1460 { 1461 names.Shift(); 1462 --num_extra_levels; 1463 } 1464 else 1465 return 0; 1466 } 1467 1468 for (int i = 0; i < num_extra_levels; ++i) 1469 { 1470 ConstString child_level (names.GetArgumentAtIndex (0)); 1471 bool found = false; 1472 int num_children = root_settings->GetNumChildren(); 1473 for (int j = 0; j < num_children && !found; ++j) 1474 { 1475 if (root_settings->GetChildAtIndex (j)->GetLevelName() == child_level) 1476 { 1477 found = true; 1478 root_settings = root_settings->GetChildAtIndex (j); 1479 names.Shift(); 1480 } 1481 } 1482 if (!found) 1483 return 0; 1484 } 1485 1486 if (names.GetArgumentCount() != 2) 1487 return 0; 1488 1489 std::string next_name (names.GetArgumentAtIndex (0)); 1490 int len = next_name.length(); 1491 names.Shift(); 1492 1493 if ((next_name[0] == '[') && (next_name[len-1] == ']')) 1494 { 1495 // 'next_name' is instance name. Instance names are irrelevent here. 1496 } 1497 else 1498 { 1499 // 'next_name' is child name. 1500 bool found = false; 1501 int num_children = root_settings->GetNumChildren(); 1502 ConstString child_level (next_name.c_str()); 1503 for (int j = 0; j < num_children && !found; ++j) 1504 { 1505 if (root_settings->GetChildAtIndex (j)->GetLevelName() == child_level) 1506 { 1507 found = true; 1508 root_settings = root_settings->GetChildAtIndex (j); 1509 } 1510 } 1511 if (!found) 1512 return 0; 1513 } 1514 1515 ConstString var_name (names.GetArgumentAtIndex(0)); 1516 const SettingEntry *entry = root_settings->GetGlobalEntry (var_name); 1517 if (entry == NULL) 1518 entry = root_settings->GetInstanceEntry (var_name); 1519 1520 if (entry == NULL) 1521 return 0; 1522 1523 if (entry->var_type == lldb::eSetVarTypeBool) 1524 return UserSettingsController::BooleanMatches (partial_value, word_complete, matches); 1525 else if (entry->var_type == lldb::eSetVarTypeEnum) 1526 return UserSettingsController::EnumMatches (partial_value, entry->enum_values, word_complete, matches); 1527 else 1528 return 0; 1529 } 1530 1531 int 1532 UserSettingsController::BooleanMatches (const char *partial_value, 1533 bool &word_complete, 1534 StringList &matches) 1535 { 1536 static const std::string true_string ("true"); 1537 static const std::string false_string ("false"); 1538 1539 if (partial_value == NULL) 1540 { 1541 matches.AppendString ("true"); 1542 matches.AppendString ("false"); 1543 } 1544 else 1545 { 1546 int partial_len = strlen (partial_value); 1547 1548 if ((partial_len <= true_string.length()) 1549 && (true_string.find (partial_value) == 0)) 1550 matches.AppendString ("true"); 1551 else if ((partial_len <= false_string.length()) 1552 && (false_string.find (partial_value) == 0)) 1553 matches.AppendString ("false"); 1554 } 1555 1556 word_complete = false; 1557 if (matches.GetSize() == 1) 1558 word_complete = true; 1559 1560 return matches.GetSize(); 1561 } 1562 1563 int 1564 UserSettingsController::EnumMatches (const char *partial_value, 1565 lldb::OptionEnumValueElement *enum_values, 1566 bool &word_complete, 1567 StringList &matches) 1568 { 1569 int len = (partial_value != NULL) ? strlen (partial_value) : 0; 1570 1571 int i = 0; 1572 while (enum_values[i].string_value != NULL) 1573 { 1574 if (len == 0) 1575 matches.AppendString (enum_values[i].string_value); 1576 else 1577 { 1578 std::string tmp_value (enum_values[i].string_value); 1579 if ((len <= tmp_value.length()) 1580 && tmp_value.find (partial_value) == 0) 1581 matches.AppendString (enum_values[i].string_value); 1582 } 1583 ++i; 1584 } 1585 1586 word_complete = false; 1587 if (matches.GetSize() == 1) 1588 word_complete = true; 1589 1590 return matches.GetSize(); 1591 } 1592 1593 int 1594 UserSettingsController::CompleteSettingsNames (lldb::UserSettingsControllerSP root_settings, 1595 Args &partial_setting_name_pieces, 1596 bool &word_complete, 1597 StringList &matches) 1598 { 1599 int num_matches = 0; 1600 int num_name_pieces = partial_setting_name_pieces.GetArgumentCount(); 1601 1602 if (num_name_pieces > 1) 1603 { 1604 // There are at least two pieces, perhaps with multiple level names preceding them. 1605 // First traverse all the extra levels, until we have exactly two pieces left. 1606 1607 int num_extra_levels = num_name_pieces - 2; 1608 1609 // Deal with current level first. 1610 1611 ConstString root_level = root_settings->GetLevelName(); 1612 if ((num_extra_levels > 0) 1613 && (root_level.GetLength() > 0)) 1614 { 1615 ConstString current_level (partial_setting_name_pieces.GetArgumentAtIndex (0)); 1616 if (current_level == root_level) 1617 { 1618 partial_setting_name_pieces.Shift(); 1619 --num_extra_levels; 1620 } 1621 else 1622 return 0; // The current level did not match the name pieces; something is wrong, so return immediately 1623 1624 } 1625 1626 for (int i = 0; i < num_extra_levels; ++i) 1627 { 1628 ConstString child_level (partial_setting_name_pieces.GetArgumentAtIndex (0)); 1629 bool found = false; 1630 int num_children = root_settings->GetNumChildren(); 1631 for (int j = 0; j < num_children && !found; ++j) 1632 { 1633 if (root_settings->GetChildAtIndex (j)->GetLevelName() == child_level) 1634 { 1635 found = true; 1636 root_settings = root_settings->GetChildAtIndex (j); 1637 partial_setting_name_pieces.Shift(); 1638 } 1639 } 1640 if (! found) 1641 { 1642 return 0; // Unable to find a matching child level name; something is wrong, so return immediately. 1643 } 1644 } 1645 1646 // Now there should be exactly two name pieces left. If not there is an error, so return immediately 1647 1648 if (partial_setting_name_pieces.GetArgumentCount() != 2) 1649 return 0; 1650 1651 std::string next_name (partial_setting_name_pieces.GetArgumentAtIndex (0)); 1652 int len = next_name.length(); 1653 partial_setting_name_pieces.Shift(); 1654 1655 if ((next_name[0] == '[') && (next_name[len-1] == ']')) 1656 { 1657 // 'next_name' is an instance name. The last name piece must be a non-empty partial match against an 1658 // instance_name, assuming 'next_name' is valid. 1659 1660 if (root_settings->IsLiveInstance (next_name)) 1661 { 1662 std::string complete_prefix; 1663 root_settings->BuildParentPrefix (complete_prefix); 1664 1665 num_matches = root_settings->InstanceVariableMatches(partial_setting_name_pieces.GetArgumentAtIndex(0), 1666 complete_prefix, 1667 next_name.c_str(), 1668 matches); 1669 word_complete = true; 1670 if (num_matches > 1) 1671 word_complete = false; 1672 1673 return num_matches; 1674 } 1675 else 1676 return 0; // Invalid instance_name 1677 } 1678 else 1679 { 1680 // 'next_name' must be a child name. Find the correct child and pass the remaining piece to be resolved. 1681 bool found = false; 1682 int num_children = root_settings->GetNumChildren(); 1683 ConstString child_level (next_name.c_str()); 1684 for (int i = 0; i < num_children; ++i) 1685 { 1686 if (root_settings->GetChildAtIndex (i)->GetLevelName() == child_level) 1687 { 1688 found = true; 1689 return UserSettingsController::CompleteSettingsNames (root_settings->GetChildAtIndex (i), 1690 partial_setting_name_pieces, 1691 word_complete, matches); 1692 } 1693 } 1694 if (!found) 1695 return 0; 1696 } 1697 } 1698 else if (num_name_pieces == 1) 1699 { 1700 std::string complete_prefix; 1701 root_settings->BuildParentPrefix (complete_prefix); 1702 1703 word_complete = true; 1704 std::string name (partial_setting_name_pieces.GetArgumentAtIndex (0)); 1705 1706 if (name[0] == '[') 1707 { 1708 // It's a partial instance name. 1709 1710 num_matches = root_settings->LiveInstanceMatches (name.c_str(), complete_prefix, word_complete, matches); 1711 } 1712 else 1713 { 1714 // It could be anything *except* an instance name... 1715 1716 num_matches = root_settings->GlobalVariableMatches (name.c_str(), complete_prefix, matches); 1717 num_matches += root_settings->InstanceVariableMatches (name.c_str(), complete_prefix, NULL, matches); 1718 num_matches += root_settings->ChildMatches (name.c_str(), complete_prefix, word_complete, matches); 1719 } 1720 1721 if (num_matches > 1) 1722 word_complete = false; 1723 1724 return num_matches; 1725 } 1726 else 1727 { 1728 // We have a user settings controller with a blank partial string. Return everything possible at this level. 1729 1730 std::string complete_prefix; 1731 root_settings->BuildParentPrefix (complete_prefix); 1732 num_matches = root_settings->GlobalVariableMatches (NULL, complete_prefix, matches); 1733 num_matches += root_settings->InstanceVariableMatches (NULL, complete_prefix, NULL, matches); 1734 num_matches += root_settings->LiveInstanceMatches (NULL, complete_prefix, word_complete, matches); 1735 num_matches += root_settings->ChildMatches (NULL, complete_prefix, word_complete, matches); 1736 word_complete = false; 1737 return num_matches; 1738 } 1739 1740 return num_matches; 1741 } 1742 1743 int 1744 UserSettingsController::GlobalVariableMatches (const char *partial_name, 1745 const std::string &complete_prefix, 1746 StringList &matches) 1747 { 1748 int partial_len = (partial_name != NULL) ? strlen (partial_name) : 0; 1749 int num_matches = 0; 1750 1751 for (size_t i = 0; i < m_settings.global_settings.size(); ++i) 1752 { 1753 SettingEntry &entry = m_settings.global_settings[i]; 1754 std::string var_name (entry.var_name); 1755 if ((partial_len == 0) 1756 || ((partial_len <= var_name.length()) 1757 && (var_name.find (partial_name) == 0))) 1758 { 1759 StreamString match_name; 1760 if (complete_prefix.length() > 0) 1761 { 1762 match_name.Printf ("%s.%s", complete_prefix.c_str(), var_name.c_str()); 1763 matches.AppendString (match_name.GetData()); 1764 } 1765 else 1766 matches.AppendString (var_name.c_str()); 1767 ++num_matches; 1768 } 1769 } 1770 return num_matches; 1771 } 1772 1773 int 1774 UserSettingsController::InstanceVariableMatches (const char *partial_name, 1775 const std::string &complete_prefix, 1776 const char *instance_name, 1777 StringList &matches) 1778 { 1779 int partial_len = (partial_name != NULL) ? strlen (partial_name) : 0; 1780 int num_matches = 0; 1781 1782 for (size_t i = 0; i < m_settings.instance_settings.size(); ++i) 1783 { 1784 SettingEntry &entry = m_settings.instance_settings[i]; 1785 std::string var_name (entry.var_name); 1786 if ((partial_len == 0) 1787 || ((partial_len <= var_name.length()) 1788 && (var_name.find (partial_name) == 0))) 1789 { 1790 StreamString match_name; 1791 if (complete_prefix.length() > 0) 1792 { 1793 if (instance_name != NULL) 1794 match_name.Printf ("%s.%s.%s", complete_prefix.c_str(), instance_name, var_name.c_str()); 1795 else 1796 match_name.Printf ("%s.%s", complete_prefix.c_str(), var_name.c_str()); 1797 1798 matches.AppendString (match_name.GetData()); 1799 } 1800 else 1801 { 1802 if (instance_name != NULL) 1803 { 1804 match_name.Printf ("%s.%s", instance_name, var_name.c_str()); 1805 matches.AppendString (match_name.GetData()); 1806 } 1807 else 1808 matches.AppendString (var_name.c_str()); 1809 } 1810 ++num_matches; 1811 } 1812 } 1813 return num_matches; 1814 } 1815 1816 int 1817 UserSettingsController::LiveInstanceMatches (const char *partial_name, 1818 const std::string &complete_prefix, 1819 bool &word_complete, 1820 StringList &matches) 1821 { 1822 int partial_len = (partial_name != NULL) ? strlen (partial_name) : 0; 1823 int num_matches = 0; 1824 1825 std::map<std::string, InstanceSettings*>::iterator pos; 1826 for (pos = m_live_settings.begin(); pos != m_live_settings.end(); ++pos) 1827 { 1828 std::string instance_name = pos->first; 1829 if ((partial_len == 0) 1830 || ((partial_len <= instance_name.length()) 1831 && (instance_name.find (partial_name) == 0))) 1832 { 1833 StreamString match_name; 1834 if (complete_prefix.length() > 0) 1835 match_name.Printf ("%s.%s.", complete_prefix.c_str(), instance_name.c_str()); 1836 else 1837 match_name.Printf ("%s.", instance_name.c_str()); 1838 matches.AppendString (match_name.GetData()); 1839 ++num_matches; 1840 } 1841 } 1842 1843 if (num_matches > 0) 1844 word_complete = false; 1845 1846 return num_matches; 1847 } 1848 1849 int 1850 UserSettingsController::ChildMatches (const char *partial_name, 1851 const std::string &complete_prefix, 1852 bool &word_complete, 1853 StringList &matches) 1854 { 1855 int partial_len = (partial_name != NULL) ? strlen (partial_name) : 0; 1856 int num_children = GetNumChildren(); 1857 int num_matches = 0; 1858 for (int i = 0; i < num_children; ++i) 1859 { 1860 std::string child_name (GetChildAtIndex(i)->GetLevelName().AsCString()); 1861 StreamString match_name; 1862 if ((partial_len == 0) 1863 || ((partial_len <= child_name.length()) 1864 && (child_name.find (partial_name) == 0))) 1865 { 1866 if (complete_prefix.length() > 0) 1867 match_name.Printf ("%s.%s.", complete_prefix.c_str(), child_name.c_str()); 1868 else 1869 match_name.Printf ("%s.", child_name.c_str()); 1870 matches.AppendString (match_name.GetData()); 1871 ++num_matches; 1872 } 1873 } 1874 1875 if (num_matches > 0) 1876 word_complete = false; 1877 1878 return num_matches; 1879 } 1880 1881 void 1882 UserSettingsController::VerifyOperationForType (lldb::SettableVariableType var_type, 1883 lldb::VarSetOperationType op, 1884 const ConstString &var_name, 1885 Error &err) 1886 { 1887 if (op == lldb::eVarSetOperationAssign) 1888 return; 1889 1890 1891 if (op == lldb::eVarSetOperationInvalid) 1892 { 1893 err.SetErrorString ("Invalid 'settings ' subcommand operation.\n"); 1894 return; 1895 } 1896 1897 switch (op) 1898 { 1899 case lldb::eVarSetOperationInsertBefore: 1900 case lldb::eVarSetOperationInsertAfter: 1901 if (var_type != lldb::eSetVarTypeArray) 1902 err.SetErrorString ("Invalid operation: This operation can only be performed on array variables.\n"); 1903 break; 1904 case lldb::eVarSetOperationReplace: 1905 case lldb::eVarSetOperationRemove: 1906 if ((var_type != lldb::eSetVarTypeArray) 1907 && (var_type != lldb::eSetVarTypeDictionary)) 1908 err.SetErrorString ("Invalid operation: This operation can only be performed on array or dictionary" 1909 " variables.\n"); 1910 break; 1911 case lldb::eVarSetOperationAppend: 1912 case lldb::eVarSetOperationClear: 1913 if ((var_type != lldb::eSetVarTypeArray) 1914 && (var_type != lldb::eSetVarTypeDictionary) 1915 && (var_type != lldb::eSetVarTypeString)) 1916 err.SetErrorString ("Invalid operation: This operation can only be performed on array, dictionary " 1917 "or string variables.\n"); 1918 break; 1919 default: 1920 break; 1921 } 1922 1923 return; 1924 } 1925 1926 void 1927 UserSettingsController::UpdateStringVariable (lldb::VarSetOperationType op, 1928 std::string &string_var, 1929 const char *new_value, 1930 Error &err) 1931 { 1932 if (op == lldb::eVarSetOperationAssign) 1933 string_var = new_value; 1934 else if (op == lldb::eVarSetOperationAppend) 1935 string_var.append (new_value); 1936 else if (op == lldb::eVarSetOperationClear) 1937 string_var.clear(); 1938 else 1939 err.SetErrorString ("Unrecognized operation. Cannot update value.\n"); 1940 } 1941 1942 void 1943 UserSettingsController::UpdateBooleanVariable (lldb::VarSetOperationType op, 1944 bool &bool_var, 1945 const char *new_value, 1946 Error &err) 1947 { 1948 if (op != lldb::eVarSetOperationAssign) 1949 err.SetErrorString ("Invalid operation for Boolean variable. Cannot update value.\n"); 1950 1951 1952 if ((new_value == NULL) 1953 || (new_value[0] == '\0')) 1954 err.SetErrorString ("Invalid value. Cannot perform update.\n"); 1955 1956 std::string bool_val_str (new_value); 1957 1958 std::transform (bool_val_str.begin(), bool_val_str.end(), bool_val_str.begin(), ::tolower); 1959 1960 if (bool_val_str == "true") 1961 bool_var = true; 1962 else if (bool_val_str == "false") 1963 bool_var = false; 1964 } 1965 1966 void 1967 UserSettingsController::UpdateStringArrayVariable (lldb::VarSetOperationType op, 1968 const char *index_value, 1969 Args &array_var, 1970 const char *new_value, 1971 Error &err) 1972 { 1973 int index = -1; 1974 bool valid_index = true; 1975 1976 if (index_value != NULL) 1977 { 1978 for (int i = 0; i < strlen(index_value); ++i) 1979 if (!isdigit (index_value[i])) 1980 { 1981 valid_index = false; 1982 err.SetErrorStringWithFormat ("'%s' is not a valid integer index. Cannot update array value.\n", 1983 index_value); 1984 } 1985 1986 if (valid_index) 1987 index = atoi (index_value); 1988 1989 if (index < 0 1990 || index >= array_var.GetArgumentCount()) 1991 { 1992 valid_index = false; 1993 err.SetErrorStringWithFormat ("%d is outside the bounds of the specified array variable. " 1994 "Cannot update array value.\n", index); 1995 } 1996 } 1997 1998 switch (op) 1999 { 2000 case lldb::eVarSetOperationAssign: 2001 array_var.SetCommandString (new_value); 2002 break; 2003 case lldb::eVarSetOperationReplace: 2004 { 2005 if (valid_index) 2006 array_var.ReplaceArgumentAtIndex (index, new_value); 2007 break; 2008 } 2009 case lldb::eVarSetOperationInsertBefore: 2010 case lldb::eVarSetOperationInsertAfter: 2011 { 2012 if (valid_index) 2013 { 2014 Args new_array (new_value); 2015 if (op == lldb::eVarSetOperationInsertAfter) 2016 ++index; 2017 for (int i = 0; i < new_array.GetArgumentCount(); ++i) 2018 array_var.InsertArgumentAtIndex (index, new_array.GetArgumentAtIndex (i)); 2019 } 2020 break; 2021 } 2022 case lldb::eVarSetOperationRemove: 2023 { 2024 if (valid_index) 2025 array_var.DeleteArgumentAtIndex (index); 2026 break; 2027 } 2028 case lldb::eVarSetOperationAppend: 2029 { 2030 Args new_array (new_value); 2031 array_var.AppendArguments (new_array); 2032 break; 2033 } 2034 case lldb::eVarSetOperationClear: 2035 array_var.Clear(); 2036 break; 2037 default: 2038 err.SetErrorString ("Unrecognized operation. Cannot update value.\n"); 2039 break; 2040 } 2041 } 2042 2043 void 2044 UserSettingsController::UpdateDictionaryVariable (lldb::VarSetOperationType op, 2045 const char *index_value, 2046 std::map<std::string, std::string> &dictionary, 2047 const char *new_value, 2048 Error &err) 2049 { 2050 switch (op) 2051 { 2052 case lldb::eVarSetOperationReplace: 2053 if (index_value != NULL) 2054 { 2055 std::string key (index_value); 2056 std::map<std::string, std::string>::iterator pos; 2057 2058 pos = dictionary.find (key); 2059 if (pos != dictionary.end()) 2060 dictionary[key] = new_value; 2061 else 2062 err.SetErrorStringWithFormat ("'%s' is not an existing key; cannot replace value.\n", index_value); 2063 } 2064 else 2065 err.SetErrorString ("'settings replace' requires a key for dictionary variables. No key supplied.\n"); 2066 break; 2067 case lldb::eVarSetOperationRemove: 2068 if (index_value != NULL) 2069 { 2070 std::string key (index_value); 2071 dictionary.erase (key); 2072 } 2073 else 2074 err.SetErrorString ("'settings remove' requires a key for dictionary variables. No key supplied.\n"); 2075 break; 2076 case lldb::eVarSetOperationClear: 2077 dictionary.clear (); 2078 break; 2079 case lldb::eVarSetOperationAppend: 2080 case lldb::eVarSetOperationAssign: 2081 { 2082 // Clear the dictionary if it's an assign with new_value as NULL. 2083 if (new_value == NULL && op == lldb::eVarSetOperationAssign) 2084 { 2085 dictionary.clear (); 2086 break; 2087 } 2088 Args args (new_value); 2089 size_t num_args = args.GetArgumentCount(); 2090 for (size_t i = 0; i < num_args; ++i) 2091 { 2092 std::string tmp_arg = args.GetArgumentAtIndex (i); 2093 size_t eq_sign = tmp_arg.find ('='); 2094 if (eq_sign != std::string::npos) 2095 { 2096 if (eq_sign > 4) 2097 { 2098 std::string tmp_key = tmp_arg.substr (0, eq_sign); 2099 std::string real_value = tmp_arg.substr (eq_sign+1); 2100 if ((tmp_key[0] == '[') 2101 && (tmp_key[1] == '"') 2102 && (tmp_key[eq_sign-2] == '"') 2103 && (tmp_key[eq_sign-1] == ']')) 2104 { 2105 std::string real_key = tmp_key.substr (2, eq_sign-4); 2106 dictionary[real_key] = real_value; 2107 } 2108 else 2109 err.SetErrorString ("Invalid key format for dictionary assignment. " 2110 "Expected '[\"<key>\"]'\n"); 2111 } 2112 else 2113 err.SetErrorString ("Invalid key format for dictionary assignment. " 2114 "Expected '[\"<key>\"]'\n"); 2115 } 2116 else 2117 err.SetErrorString ("Invalid format for dictionary value. Expected '[\"<key>\"]=<value>'\n"); 2118 } 2119 } 2120 break; 2121 case lldb::eVarSetOperationInsertBefore: 2122 case lldb::eVarSetOperationInsertAfter: 2123 err.SetErrorString ("Specified operation cannot be performed on dictionary variables.\n"); 2124 break; 2125 default: 2126 err.SetErrorString ("Unrecognized operation.\n"); 2127 break; 2128 } 2129 } 2130 2131 const char * 2132 UserSettingsController::EnumToString (const lldb::OptionEnumValueElement *enum_values, 2133 int value) 2134 { 2135 int i = 0; 2136 while (enum_values[i].string_value != NULL) 2137 { 2138 if (enum_values[i].value == value) 2139 return enum_values[i].string_value; 2140 ++i; 2141 } 2142 2143 return "Invalid enumeration value"; 2144 } 2145 2146 2147 void 2148 UserSettingsController::UpdateEnumVariable (lldb::OptionEnumValueElement *enum_values, 2149 int *enum_var, 2150 const char *new_value, 2151 Error &err) 2152 { 2153 bool found_one; 2154 2155 *enum_var = Args::StringToOptionEnum (new_value, enum_values, enum_values[0].value, &found_one); 2156 2157 if (!found_one) 2158 err.SetErrorString ("Invalid enumeration value; cannot update variable.\n"); 2159 } 2160 2161 void 2162 UserSettingsController::RenameInstanceSettings (const char *old_name, const char *new_name) 2163 { 2164 Mutex::Locker live_mutex (m_live_settings_mutex); 2165 Mutex::Locker pending_mutex (m_pending_settings_mutex); 2166 std::string old_name_key (old_name); 2167 std::string new_name_key (new_name); 2168 2169 // First, find the live instance settings for the old_name. If they don't exist in the live settings 2170 // list, then this is not a setting that can be renamed. 2171 2172 if ((old_name_key[0] != '[') || (old_name_key[old_name_key.size() -1] != ']')) 2173 { 2174 StreamString tmp_str; 2175 tmp_str.Printf ("[%s]", old_name); 2176 old_name_key = tmp_str.GetData(); 2177 } 2178 2179 if ((new_name_key[0] != '[') || (new_name_key[new_name_key.size() -1] != ']')) 2180 { 2181 StreamString tmp_str; 2182 tmp_str.Printf ("[%s]", new_name); 2183 new_name_key = tmp_str.GetData(); 2184 } 2185 2186 if (old_name_key.compare (new_name_key) == 0) 2187 return; 2188 2189 size_t len = new_name_key.length(); 2190 std::string stripped_new_name = new_name_key.substr (1, len-2); // new name without the '[ ]' 2191 2192 std::map<std::string, InstanceSettings *>::iterator pos; 2193 2194 pos = m_live_settings.find (old_name_key); 2195 if (pos != m_live_settings.end()) 2196 { 2197 InstanceSettings *live_settings = pos->second; 2198 2199 // Rename the settings. 2200 live_settings->ChangeInstanceName (stripped_new_name); 2201 2202 // Now see if there are any pending settings for the new name; if so, copy them into live_settings. 2203 std::map<std::string, lldb::InstanceSettingsSP>::iterator pending_pos; 2204 pending_pos = m_pending_settings.find (new_name_key); 2205 if (pending_pos != m_pending_settings.end()) 2206 { 2207 lldb::InstanceSettingsSP pending_settings_sp = pending_pos->second; 2208 live_settings->CopyInstanceSettings (pending_settings_sp, false); 2209 } 2210 2211 // Erase the old entry (under the old name) from live settings. 2212 m_live_settings.erase (pos); 2213 2214 // Add the new entry, with the new name, into live settings. 2215 m_live_settings[new_name_key] = live_settings; 2216 } 2217 } 2218 2219 //---------------------------------------------------------------------- 2220 // class InstanceSettings 2221 //---------------------------------------------------------------------- 2222 2223 InstanceSettings::InstanceSettings (UserSettingsController &owner, const char *instance_name, bool live_instance) : 2224 m_owner (owner), 2225 m_instance_name (instance_name) 2226 { 2227 if ((m_instance_name != InstanceSettings::GetDefaultName()) 2228 && (m_instance_name != InstanceSettings::InvalidName()) 2229 && live_instance) 2230 m_owner.RegisterInstanceSettings (this); 2231 } 2232 2233 InstanceSettings::~InstanceSettings () 2234 { 2235 if (m_instance_name != InstanceSettings::GetDefaultName()) 2236 m_owner.UnregisterInstanceSettings (this); 2237 } 2238 2239 const ConstString & 2240 InstanceSettings::GetDefaultName () 2241 { 2242 static const ConstString g_default_settings_name ("[DEFAULT]"); 2243 2244 return g_default_settings_name; 2245 } 2246 2247 const ConstString & 2248 InstanceSettings::InvalidName () 2249 { 2250 static const ConstString g_invalid_name ("Invalid instance name"); 2251 2252 return g_invalid_name; 2253 } 2254 2255 void 2256 InstanceSettings::ChangeInstanceName (const std::string &new_instance_name) 2257 { 2258 m_instance_name.SetCString (new_instance_name.c_str()); 2259 } 2260 2261 2262