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