13df9a8dfSCaroline Tice //====-- UserSettingsController.cpp ------------------------------*- C++ -*-===// 23df9a8dfSCaroline Tice // 33df9a8dfSCaroline Tice // The LLVM Compiler Infrastructure 43df9a8dfSCaroline Tice // 53df9a8dfSCaroline Tice // This file is distributed under the University of Illinois Open Source 63df9a8dfSCaroline Tice // License. See LICENSE.TXT for details. 73df9a8dfSCaroline Tice // 83df9a8dfSCaroline Tice //===----------------------------------------------------------------------===// 93df9a8dfSCaroline Tice 103df9a8dfSCaroline Tice #include <string.h> 113df9a8dfSCaroline Tice #include <algorithm> 123df9a8dfSCaroline Tice 133df9a8dfSCaroline Tice #include "lldb/Core/UserSettingsController.h" 143df9a8dfSCaroline Tice #include "lldb/Core/Error.h" 156ad07dd9SGreg Clayton #include "lldb/Core/RegularExpression.h" 163df9a8dfSCaroline Tice #include "lldb/Core/Stream.h" 173df9a8dfSCaroline Tice #include "lldb/Core/StreamString.h" 183df9a8dfSCaroline Tice #include "lldb/Interpreter/CommandInterpreter.h" 193df9a8dfSCaroline Tice 20*bfe5f3bfSGreg Clayton using namespace lldb; 213df9a8dfSCaroline Tice using namespace lldb_private; 223df9a8dfSCaroline Tice 23*bfe5f3bfSGreg Clayton static void 24*bfe5f3bfSGreg Clayton DumpSettingEntry (CommandInterpreter &interpreter, 25*bfe5f3bfSGreg Clayton StreamString &result_stream, 26*bfe5f3bfSGreg Clayton const uint32_t max_len, 27*bfe5f3bfSGreg Clayton const SettingEntry &entry) 28*bfe5f3bfSGreg Clayton { 29*bfe5f3bfSGreg Clayton StreamString description; 30*bfe5f3bfSGreg Clayton 31*bfe5f3bfSGreg Clayton if (entry.description) 32*bfe5f3bfSGreg Clayton description.Printf ("%s", entry.description); 33*bfe5f3bfSGreg Clayton 34*bfe5f3bfSGreg Clayton if (entry.default_value && entry.default_value[0]) 35*bfe5f3bfSGreg Clayton description.Printf (" (default: %s)", entry.default_value); 36*bfe5f3bfSGreg Clayton 37*bfe5f3bfSGreg Clayton interpreter.OutputFormattedHelpText (result_stream, 38*bfe5f3bfSGreg Clayton entry.var_name, 39*bfe5f3bfSGreg Clayton "--", 40*bfe5f3bfSGreg Clayton description.GetData(), 41*bfe5f3bfSGreg Clayton max_len); 42*bfe5f3bfSGreg Clayton 43*bfe5f3bfSGreg Clayton if (entry.enum_values && entry.enum_values[0].string_value) 44*bfe5f3bfSGreg Clayton { 45*bfe5f3bfSGreg Clayton interpreter.OutputFormattedHelpText (result_stream, 46*bfe5f3bfSGreg Clayton "", 47*bfe5f3bfSGreg Clayton " ", 48*bfe5f3bfSGreg Clayton "Enumeration values:", 49*bfe5f3bfSGreg Clayton max_len); 50*bfe5f3bfSGreg Clayton for (uint32_t enum_idx=0; entry.enum_values[enum_idx].string_value != NULL; ++enum_idx) 51*bfe5f3bfSGreg Clayton { 52*bfe5f3bfSGreg Clayton description.Clear(); 53*bfe5f3bfSGreg Clayton if (entry.enum_values[enum_idx].usage) 54*bfe5f3bfSGreg Clayton description.Printf ("%s = %s", 55*bfe5f3bfSGreg Clayton entry.enum_values[enum_idx].string_value, 56*bfe5f3bfSGreg Clayton entry.enum_values[enum_idx].usage); 57*bfe5f3bfSGreg Clayton else 58*bfe5f3bfSGreg Clayton description.Printf ("%s", entry.enum_values[enum_idx].string_value); 59*bfe5f3bfSGreg Clayton interpreter.OutputFormattedHelpText (result_stream, 60*bfe5f3bfSGreg Clayton "", 61*bfe5f3bfSGreg Clayton " ", 62*bfe5f3bfSGreg Clayton description.GetData(), 63*bfe5f3bfSGreg Clayton max_len); 64*bfe5f3bfSGreg Clayton } 65*bfe5f3bfSGreg Clayton } 66*bfe5f3bfSGreg Clayton } 67*bfe5f3bfSGreg Clayton 683df9a8dfSCaroline Tice UserSettingsController::UserSettingsController (const char *level_name, 69*bfe5f3bfSGreg Clayton const UserSettingsControllerSP &parent) : 703df9a8dfSCaroline Tice m_default_settings (), 713df9a8dfSCaroline Tice m_settings (), 723df9a8dfSCaroline Tice m_children (), 733df9a8dfSCaroline Tice m_pending_settings (), 743df9a8dfSCaroline Tice m_live_settings (), 753df9a8dfSCaroline Tice m_children_mutex (Mutex::eMutexTypeNormal), 76a767c9a3SJim Ingham m_pending_settings_mutex (Mutex::eMutexTypeRecursive), 77a767c9a3SJim Ingham m_live_settings_mutex (Mutex::eMutexTypeRecursive) 783df9a8dfSCaroline Tice { 793df9a8dfSCaroline Tice m_settings.parent = parent; 803df9a8dfSCaroline Tice m_settings.level_name.SetCString (level_name); 813df9a8dfSCaroline Tice } 823df9a8dfSCaroline Tice 833df9a8dfSCaroline Tice UserSettingsController::~UserSettingsController () 843df9a8dfSCaroline Tice { 853df9a8dfSCaroline Tice m_live_settings.clear(); 863df9a8dfSCaroline Tice } 873df9a8dfSCaroline Tice 8895852755SJim Ingham bool 891b654882SGreg Clayton UserSettingsController::SetGlobalVariable 901b654882SGreg Clayton ( 911b654882SGreg Clayton const ConstString &var_name, 921b654882SGreg Clayton const char *index_value, 931b654882SGreg Clayton const char *value, 941b654882SGreg Clayton const SettingEntry &entry, 95*bfe5f3bfSGreg Clayton const VarSetOperationType op, 961b654882SGreg Clayton Error &err 971b654882SGreg Clayton ) 981b654882SGreg Clayton { 991b654882SGreg Clayton err.SetErrorString ("UserSettingsController has no global settings"); 1001b654882SGreg Clayton return false; 1011b654882SGreg Clayton } 1021b654882SGreg Clayton 1031b654882SGreg Clayton bool 1041b654882SGreg Clayton UserSettingsController::GetGlobalVariable 1051b654882SGreg Clayton ( 1061b654882SGreg Clayton const ConstString &var_name, 107daccaa9eSCaroline Tice StringList &value, 108daccaa9eSCaroline Tice Error &err 1091b654882SGreg Clayton ) 1101b654882SGreg Clayton { 1111b654882SGreg Clayton return false; 1121b654882SGreg Clayton } 1131b654882SGreg Clayton 1141b654882SGreg Clayton bool 115*bfe5f3bfSGreg Clayton UserSettingsController::InitializeSettingsController (UserSettingsControllerSP &controller_sp, 11695852755SJim Ingham SettingEntry *global_settings, 11795852755SJim Ingham SettingEntry *instance_settings) 11895852755SJim Ingham { 119*bfe5f3bfSGreg Clayton const UserSettingsControllerSP &parent = controller_sp->GetParent (); 12095852755SJim Ingham if (parent) 12195852755SJim Ingham parent->RegisterChild (controller_sp); 12295852755SJim Ingham 12395852755SJim Ingham controller_sp->CreateSettingsVector (global_settings, true); 12495852755SJim Ingham controller_sp->CreateSettingsVector (instance_settings, false); 12595852755SJim Ingham 12695852755SJim Ingham controller_sp->InitializeGlobalVariables (); 12795852755SJim Ingham controller_sp->CreateDefaultInstanceSettings (); 12895852755SJim Ingham 12995852755SJim Ingham return true; 13095852755SJim Ingham } 13195852755SJim Ingham 13295852755SJim Ingham void 133*bfe5f3bfSGreg Clayton UserSettingsController::FinalizeSettingsController (UserSettingsControllerSP &controller_sp) 13495852755SJim Ingham { 135*bfe5f3bfSGreg Clayton const UserSettingsControllerSP &parent = controller_sp->GetParent (); 13695852755SJim Ingham if (parent) 13795852755SJim Ingham parent->RemoveChild (controller_sp); 13895852755SJim Ingham } 13995852755SJim Ingham 1403df9a8dfSCaroline Tice void 1413df9a8dfSCaroline Tice UserSettingsController::InitializeGlobalVariables () 1423df9a8dfSCaroline Tice { 1433df9a8dfSCaroline Tice int num_entries; 1443df9a8dfSCaroline Tice const char *prefix = GetLevelName().AsCString(); 1453df9a8dfSCaroline Tice 1463df9a8dfSCaroline Tice num_entries = m_settings.global_settings.size(); 1473df9a8dfSCaroline Tice for (int i = 0; i < num_entries; ++i) 1483df9a8dfSCaroline Tice { 149*bfe5f3bfSGreg Clayton const SettingEntry &entry = m_settings.global_settings[i]; 1503df9a8dfSCaroline Tice if (entry.default_value != NULL) 1513df9a8dfSCaroline Tice { 1523df9a8dfSCaroline Tice StreamString full_name; 1533df9a8dfSCaroline Tice if (prefix[0] != '\0') 1543df9a8dfSCaroline Tice full_name.Printf ("%s.%s", prefix, entry.var_name); 1553df9a8dfSCaroline Tice else 1563df9a8dfSCaroline Tice full_name.Printf ("%s", entry.var_name); 157*bfe5f3bfSGreg Clayton SetVariable (full_name.GetData(), entry.default_value, eVarSetOperationAssign, false, ""); 1583df9a8dfSCaroline Tice } 1593df9a8dfSCaroline Tice } 1603df9a8dfSCaroline Tice } 1613df9a8dfSCaroline Tice 162*bfe5f3bfSGreg Clayton const UserSettingsControllerSP & 1633df9a8dfSCaroline Tice UserSettingsController::GetParent () 1643df9a8dfSCaroline Tice { 1653df9a8dfSCaroline Tice return m_settings.parent; 1663df9a8dfSCaroline Tice } 1673df9a8dfSCaroline Tice 1683df9a8dfSCaroline Tice void 169*bfe5f3bfSGreg Clayton UserSettingsController::RegisterChild (const UserSettingsControllerSP &child) 1703df9a8dfSCaroline Tice { 1713df9a8dfSCaroline Tice Mutex::Locker locker (m_children_mutex); 1723df9a8dfSCaroline Tice 1733df9a8dfSCaroline Tice // Verify child is not already in m_children. 1743df9a8dfSCaroline Tice size_t num_children = m_children.size(); 1753df9a8dfSCaroline Tice bool found = false; 1763df9a8dfSCaroline Tice for (size_t i = 0; i < num_children; ++i) 1773df9a8dfSCaroline Tice { 1783df9a8dfSCaroline Tice if (m_children[i].get() == child.get()) 1793df9a8dfSCaroline Tice found = true; 1803df9a8dfSCaroline Tice } 1813df9a8dfSCaroline Tice 1823df9a8dfSCaroline Tice // Add child to m_children. 1833df9a8dfSCaroline Tice if (! found) 1843df9a8dfSCaroline Tice m_children.push_back (child); 1853df9a8dfSCaroline Tice } 1863df9a8dfSCaroline Tice 1873df9a8dfSCaroline Tice const ConstString & 1883df9a8dfSCaroline Tice UserSettingsController::GetLevelName () 1893df9a8dfSCaroline Tice { 1903df9a8dfSCaroline Tice return m_settings.level_name; 1913df9a8dfSCaroline Tice } 1923df9a8dfSCaroline Tice 1933df9a8dfSCaroline Tice size_t 1943df9a8dfSCaroline Tice UserSettingsController::GetNumChildren () 1953df9a8dfSCaroline Tice { 1963df9a8dfSCaroline Tice return m_children.size(); 1973df9a8dfSCaroline Tice } 1983df9a8dfSCaroline Tice 199*bfe5f3bfSGreg Clayton const UserSettingsControllerSP 2003df9a8dfSCaroline Tice UserSettingsController::GetChildAtIndex (size_t index) 2013df9a8dfSCaroline Tice { 2023df9a8dfSCaroline Tice if (index < m_children.size()) 2033df9a8dfSCaroline Tice return m_children[index]; 2043df9a8dfSCaroline Tice 205*bfe5f3bfSGreg Clayton UserSettingsControllerSP dummy_value; 2063df9a8dfSCaroline Tice 2073df9a8dfSCaroline Tice return dummy_value; 2083df9a8dfSCaroline Tice } 2093df9a8dfSCaroline Tice 2103df9a8dfSCaroline Tice const SettingEntry * 2113df9a8dfSCaroline Tice UserSettingsController::GetGlobalEntry (const ConstString &var_name) 2123df9a8dfSCaroline Tice { 2133df9a8dfSCaroline Tice 2143df9a8dfSCaroline Tice for (int i = 0; i < m_settings.global_settings.size(); ++i) 2153df9a8dfSCaroline Tice { 216*bfe5f3bfSGreg Clayton const SettingEntry &entry = m_settings.global_settings[i]; 2173df9a8dfSCaroline Tice ConstString entry_name (entry.var_name); 2183df9a8dfSCaroline Tice if (entry_name == var_name) 2193df9a8dfSCaroline Tice return &entry; 2203df9a8dfSCaroline Tice } 2213df9a8dfSCaroline Tice 2223df9a8dfSCaroline Tice return NULL; 2233df9a8dfSCaroline Tice } 2243df9a8dfSCaroline Tice 2253df9a8dfSCaroline Tice const SettingEntry * 2263df9a8dfSCaroline Tice UserSettingsController::GetInstanceEntry (const ConstString &const_var_name) 2273df9a8dfSCaroline Tice { 2283df9a8dfSCaroline Tice 2293df9a8dfSCaroline Tice for (int i = 0; i < m_settings.instance_settings.size(); ++i) 2303df9a8dfSCaroline Tice { 2313df9a8dfSCaroline Tice SettingEntry &entry = m_settings.instance_settings[i]; 2323df9a8dfSCaroline Tice ConstString entry_name (entry.var_name); 2333df9a8dfSCaroline Tice if (entry_name == const_var_name) 2343df9a8dfSCaroline Tice return &entry; 2353df9a8dfSCaroline Tice } 2363df9a8dfSCaroline Tice 2373df9a8dfSCaroline Tice return NULL; 2383df9a8dfSCaroline Tice } 2393df9a8dfSCaroline Tice 2403df9a8dfSCaroline Tice void 2413df9a8dfSCaroline Tice UserSettingsController::BuildParentPrefix (std::string &parent_prefix) 2423df9a8dfSCaroline Tice { 243*bfe5f3bfSGreg Clayton UserSettingsControllerSP parent = GetParent(); 2443df9a8dfSCaroline Tice if (parent.get() != NULL) 2453df9a8dfSCaroline Tice { 2463df9a8dfSCaroline Tice parent->BuildParentPrefix (parent_prefix); 2473df9a8dfSCaroline Tice if (parent_prefix.length() > 0) 2483df9a8dfSCaroline Tice parent_prefix.append ("."); 2493df9a8dfSCaroline Tice } 2503df9a8dfSCaroline Tice parent_prefix.append (GetLevelName().AsCString()); 2513df9a8dfSCaroline Tice } 2523df9a8dfSCaroline Tice 2533df9a8dfSCaroline Tice void 254*bfe5f3bfSGreg Clayton UserSettingsController::RemoveChild (const UserSettingsControllerSP &child) 2553df9a8dfSCaroline Tice { 2563df9a8dfSCaroline Tice Mutex::Locker locker (m_children_mutex); 257*bfe5f3bfSGreg Clayton std::vector<UserSettingsControllerSP>::iterator pos, end = m_children.end(); 2583df9a8dfSCaroline Tice 2593df9a8dfSCaroline Tice for (pos = m_children.begin(); pos != end; ++pos) 2603df9a8dfSCaroline Tice { 261*bfe5f3bfSGreg Clayton UserSettingsControllerSP entry = *pos; 2623df9a8dfSCaroline Tice if (entry == child) 2633df9a8dfSCaroline Tice { 2643df9a8dfSCaroline Tice m_children.erase (pos); 2653df9a8dfSCaroline Tice break; 2663df9a8dfSCaroline Tice } 2673df9a8dfSCaroline Tice } 2683df9a8dfSCaroline Tice } 2693df9a8dfSCaroline Tice 2703df9a8dfSCaroline Tice Error 2713df9a8dfSCaroline Tice UserSettingsController::SetVariable (const char *full_dot_name, 2723df9a8dfSCaroline Tice const char *value, 273*bfe5f3bfSGreg Clayton const VarSetOperationType op, 2743df9a8dfSCaroline Tice const bool override, 275101c7c20SCaroline Tice const char *debugger_instance_name, 2763df9a8dfSCaroline Tice const char *index_value) 2773df9a8dfSCaroline Tice { 2783df9a8dfSCaroline Tice Error err; 2793df9a8dfSCaroline Tice ConstString const_var_name; 2803df9a8dfSCaroline Tice const ConstString &default_name = InstanceSettings::GetDefaultName(); 2813df9a8dfSCaroline Tice 2823df9a8dfSCaroline Tice Args names = UserSettingsController::BreakNameIntoPieces (full_dot_name); 2833df9a8dfSCaroline Tice int num_pieces = names.GetArgumentCount(); 2843df9a8dfSCaroline Tice 2853df9a8dfSCaroline Tice if (num_pieces < 1) 2863df9a8dfSCaroline Tice { 2873df9a8dfSCaroline Tice err.SetErrorStringWithFormat ("'%s' is not a valid variable name; cannot assign value.\n", full_dot_name); 2883df9a8dfSCaroline Tice return err; 2893df9a8dfSCaroline Tice } 2903df9a8dfSCaroline Tice 2913df9a8dfSCaroline Tice ConstString prefix (names.GetArgumentAtIndex (0)); 2923df9a8dfSCaroline Tice 2933df9a8dfSCaroline Tice if ((prefix == m_settings.level_name) 2943df9a8dfSCaroline Tice || (m_settings.level_name.GetLength() == 0)) 2953df9a8dfSCaroline Tice { 2963df9a8dfSCaroline Tice 2973df9a8dfSCaroline Tice if (prefix == m_settings.level_name) 2983df9a8dfSCaroline Tice { 2993df9a8dfSCaroline Tice names.Shift (); 3003df9a8dfSCaroline Tice num_pieces = names.GetArgumentCount(); 3013df9a8dfSCaroline Tice } 3023df9a8dfSCaroline Tice 3033df9a8dfSCaroline Tice if (num_pieces == 0) 3043df9a8dfSCaroline Tice { 3053df9a8dfSCaroline Tice err.SetErrorString ("No variable name specified; cannot assign value.\n"); 3063df9a8dfSCaroline Tice return err; 3073df9a8dfSCaroline Tice } 3083df9a8dfSCaroline Tice else if (num_pieces == 1) 3093df9a8dfSCaroline Tice { 3103df9a8dfSCaroline Tice 3113df9a8dfSCaroline Tice // Must be one of the class-wide settings. 3123df9a8dfSCaroline Tice 3133df9a8dfSCaroline Tice const_var_name.SetCString (names.GetArgumentAtIndex (0)); 3143df9a8dfSCaroline Tice const SettingEntry *entry = GetGlobalEntry (const_var_name); 3153df9a8dfSCaroline Tice if (entry) 3163df9a8dfSCaroline Tice { 3173df9a8dfSCaroline Tice UserSettingsController::VerifyOperationForType (entry->var_type, op, const_var_name, err); 3183df9a8dfSCaroline Tice 3193df9a8dfSCaroline Tice if (err.Fail()) 3203df9a8dfSCaroline Tice return err; 3213df9a8dfSCaroline Tice 3223df9a8dfSCaroline Tice if ((value == NULL || value[0] == '\0') 323*bfe5f3bfSGreg Clayton && (op == eVarSetOperationAssign)) 3243df9a8dfSCaroline Tice { 325*bfe5f3bfSGreg Clayton if (entry->var_type != eSetVarTypeEnum) 3263df9a8dfSCaroline Tice value = entry->default_value; 3273df9a8dfSCaroline Tice else 3283df9a8dfSCaroline Tice value = entry->enum_values[0].string_value; 3293df9a8dfSCaroline Tice } 3301b654882SGreg Clayton SetGlobalVariable (const_var_name, index_value, value, *entry, op, err); 3313df9a8dfSCaroline Tice } 3323df9a8dfSCaroline Tice else 3333df9a8dfSCaroline Tice { 3343df9a8dfSCaroline Tice // MIGHT be instance variable, to be for ALL instances. 3353df9a8dfSCaroline Tice 3363df9a8dfSCaroline Tice entry = GetInstanceEntry (const_var_name); 3373df9a8dfSCaroline Tice if (entry == NULL) 3383df9a8dfSCaroline Tice { 3393df9a8dfSCaroline Tice err.SetErrorStringWithFormat ("Unable to find variable '%s.%s'; cannot assign value.\n", 3403df9a8dfSCaroline Tice prefix.AsCString(), const_var_name.AsCString()); 3413df9a8dfSCaroline Tice return err; 3423df9a8dfSCaroline Tice } 3433df9a8dfSCaroline Tice else 3443df9a8dfSCaroline Tice { 3453df9a8dfSCaroline Tice UserSettingsController::VerifyOperationForType (entry->var_type, op, const_var_name, err); 3463df9a8dfSCaroline Tice 3473df9a8dfSCaroline Tice if (err.Fail()) 3483df9a8dfSCaroline Tice return err; 3493df9a8dfSCaroline Tice 3503df9a8dfSCaroline Tice if ((value == NULL || value[0] == '\0') 351*bfe5f3bfSGreg Clayton && (op == eVarSetOperationAssign)) 3523df9a8dfSCaroline Tice { 353*bfe5f3bfSGreg Clayton if (entry->var_type != eSetVarTypeEnum) 3543df9a8dfSCaroline Tice value = entry->default_value; 3553df9a8dfSCaroline Tice else 3563df9a8dfSCaroline Tice value = entry->enum_values[0].string_value; 3573df9a8dfSCaroline Tice } 3583df9a8dfSCaroline Tice 359101c7c20SCaroline Tice if ((m_settings.level_name.GetLength() > 0) 360101c7c20SCaroline Tice || strlen (debugger_instance_name) == 0) 361101c7c20SCaroline Tice { 362101c7c20SCaroline Tice // Set the default settings 3633df9a8dfSCaroline Tice m_default_settings->UpdateInstanceSettingsVariable (const_var_name, index_value, value, 3643df9a8dfSCaroline Tice default_name, *entry, op, err, true); 365101c7c20SCaroline Tice } 366101c7c20SCaroline Tice else 367101c7c20SCaroline Tice { 368101c7c20SCaroline Tice // We're at the Debugger level; find the correct debugger instance and set those settings 369101c7c20SCaroline Tice StreamString tmp_name; 370101c7c20SCaroline Tice if (debugger_instance_name[0] != '[') 371101c7c20SCaroline Tice tmp_name.Printf ("[%s]", debugger_instance_name); 372101c7c20SCaroline Tice else 373101c7c20SCaroline Tice tmp_name.Printf ("%s", debugger_instance_name); 374101c7c20SCaroline Tice ConstString dbg_name (tmp_name.GetData()); 375101c7c20SCaroline Tice InstanceSettings *dbg_settings = FindSettingsForInstance (dbg_name); 376101c7c20SCaroline Tice if (dbg_settings) 377101c7c20SCaroline Tice dbg_settings->UpdateInstanceSettingsVariable (const_var_name, index_value, value, dbg_name, 378101c7c20SCaroline Tice *entry, op, err, false); 379101c7c20SCaroline Tice } 380101c7c20SCaroline Tice 3813df9a8dfSCaroline Tice if (override) 3823df9a8dfSCaroline Tice { 3833df9a8dfSCaroline Tice OverrideAllInstances (const_var_name, value, op, index_value, err); 3843df9a8dfSCaroline Tice 3853df9a8dfSCaroline Tice // Update all pending records as well. 386*bfe5f3bfSGreg Clayton // std::map<std::string, InstanceSettingsSP>::iterator pos, end = m_pending_settings.end(); 3871559a46bSCaroline Tice // for (pos = m_pending_settings.begin(); pos != end; end++) 3881559a46bSCaroline Tice // { 3891559a46bSCaroline Tice // const ConstString instance_name (pos->first.c_str()); 390*bfe5f3bfSGreg Clayton // InstanceSettingsSP setting_sp = pos->second; 3911559a46bSCaroline Tice // setting_sp->UpdateInstanceSettingsVariable (const_var_name, index_value, value, 3921559a46bSCaroline Tice // instance_name, *entry, op, err, true); 3931559a46bSCaroline Tice // } 3943df9a8dfSCaroline Tice } 3953df9a8dfSCaroline Tice } 3963df9a8dfSCaroline Tice } 3973df9a8dfSCaroline Tice } 3983df9a8dfSCaroline Tice else 3993df9a8dfSCaroline Tice { 4003df9a8dfSCaroline Tice // Either a child's setting or an instance setting. 4013df9a8dfSCaroline Tice 4023df9a8dfSCaroline Tice if (names.GetArgumentAtIndex(0)[0] == '[') 4033df9a8dfSCaroline Tice { 4043df9a8dfSCaroline Tice // An instance setting. Supposedly. 4053df9a8dfSCaroline Tice 4063df9a8dfSCaroline Tice ConstString instance_name (names.GetArgumentAtIndex (0)); 4073df9a8dfSCaroline Tice 4083df9a8dfSCaroline Tice // First verify that there is only one more name. 4093df9a8dfSCaroline Tice 4103df9a8dfSCaroline Tice names.Shift(); 4113df9a8dfSCaroline Tice 4123df9a8dfSCaroline Tice if (names.GetArgumentCount() != 1) 4133df9a8dfSCaroline Tice { 4143df9a8dfSCaroline Tice err.SetErrorStringWithFormat ("Invalid variable name format '%s'; cannot assign value.\n", 4153df9a8dfSCaroline Tice full_dot_name); 4163df9a8dfSCaroline Tice return err; 4173df9a8dfSCaroline Tice } 4183df9a8dfSCaroline Tice 4193df9a8dfSCaroline Tice // Next verify that it is a valid instance setting name. 4203df9a8dfSCaroline Tice 4213df9a8dfSCaroline Tice const_var_name.SetCString (names.GetArgumentAtIndex (0)); 4223df9a8dfSCaroline Tice const SettingEntry *entry = GetInstanceEntry (const_var_name); 4233df9a8dfSCaroline Tice 4243df9a8dfSCaroline Tice if (entry == NULL) 4253df9a8dfSCaroline Tice { 4263df9a8dfSCaroline Tice err.SetErrorStringWithFormat ("Unknown instance variable '%s'; cannot assign value.\n", 4273df9a8dfSCaroline Tice const_var_name.AsCString()); 4283df9a8dfSCaroline Tice return err; 4293df9a8dfSCaroline Tice } 4303df9a8dfSCaroline Tice 4313df9a8dfSCaroline Tice UserSettingsController::VerifyOperationForType (entry->var_type, op, const_var_name, err); 4323df9a8dfSCaroline Tice 4333df9a8dfSCaroline Tice if (err.Fail()) 4343df9a8dfSCaroline Tice return err; 4353df9a8dfSCaroline Tice 4363df9a8dfSCaroline Tice if ((value == NULL || value[0] == '\0') 437*bfe5f3bfSGreg Clayton && (op == eVarSetOperationAssign)) 4383df9a8dfSCaroline Tice { 439*bfe5f3bfSGreg Clayton if (entry->var_type != eSetVarTypeEnum) 4403df9a8dfSCaroline Tice value = entry->default_value; 4413df9a8dfSCaroline Tice else 4423df9a8dfSCaroline Tice value = entry->enum_values[0].string_value; 4433df9a8dfSCaroline Tice } 4443df9a8dfSCaroline Tice 4453df9a8dfSCaroline Tice // Now look for existing instance with given instance name; if not found, find or create pending 4463df9a8dfSCaroline Tice // setting for instance with given name. 4473df9a8dfSCaroline Tice 4483df9a8dfSCaroline Tice InstanceSettings *current_settings = FindSettingsForInstance (instance_name); 4493df9a8dfSCaroline Tice 4503df9a8dfSCaroline Tice if (current_settings != NULL) 4513df9a8dfSCaroline Tice { 4523df9a8dfSCaroline Tice current_settings->UpdateInstanceSettingsVariable (const_var_name, index_value, value, 4533df9a8dfSCaroline Tice instance_name, *entry, op, err, false); 4543df9a8dfSCaroline Tice 4553df9a8dfSCaroline Tice } 4563df9a8dfSCaroline Tice else 4573df9a8dfSCaroline Tice { 4583df9a8dfSCaroline Tice // Instance does not currently exist; make or update a pending setting for it. 459*bfe5f3bfSGreg Clayton InstanceSettingsSP current_settings_sp = PendingSettingsForInstance (instance_name); 4603df9a8dfSCaroline Tice 4613df9a8dfSCaroline Tice // Now we have a settings record, update it appropriately. 4623df9a8dfSCaroline Tice 4633df9a8dfSCaroline Tice current_settings_sp->UpdateInstanceSettingsVariable (const_var_name, index_value, value, 4643df9a8dfSCaroline Tice instance_name, *entry, op, err, true); 4653df9a8dfSCaroline Tice 4663df9a8dfSCaroline Tice { // Scope for mutex. 4673df9a8dfSCaroline Tice Mutex::Locker locker (m_pending_settings_mutex); 4683df9a8dfSCaroline Tice m_pending_settings[instance_name.AsCString()] = current_settings_sp; 4693df9a8dfSCaroline Tice } 4703df9a8dfSCaroline Tice 4713df9a8dfSCaroline Tice if (override) 4723df9a8dfSCaroline Tice { 4733df9a8dfSCaroline Tice OverrideAllInstances (const_var_name, value, op, index_value, err); 4743df9a8dfSCaroline Tice 4753df9a8dfSCaroline Tice // Update all pending records as well. 476*bfe5f3bfSGreg Clayton std::map<std::string, InstanceSettingsSP>::iterator pos; 477*bfe5f3bfSGreg Clayton std::map<std::string, InstanceSettingsSP>::iterator end = m_pending_settings.end(); 4783df9a8dfSCaroline Tice for (pos = m_pending_settings.begin(); pos != end; end++) 4793df9a8dfSCaroline Tice { 4803df9a8dfSCaroline Tice const ConstString tmp_inst_name (pos->first.c_str()); 481*bfe5f3bfSGreg Clayton InstanceSettingsSP setting_sp = pos->second; 4823df9a8dfSCaroline Tice setting_sp->UpdateInstanceSettingsVariable (const_var_name, index_value, value, 4833df9a8dfSCaroline Tice tmp_inst_name, *entry, op, err, true); 4843df9a8dfSCaroline Tice } 4853df9a8dfSCaroline Tice } 4863df9a8dfSCaroline Tice } 4873df9a8dfSCaroline Tice } 4883df9a8dfSCaroline Tice else 4893df9a8dfSCaroline Tice { 4903df9a8dfSCaroline Tice // A child setting. 491*bfe5f3bfSGreg Clayton UserSettingsControllerSP child; 4923df9a8dfSCaroline Tice ConstString child_prefix (names.GetArgumentAtIndex (0)); 4933df9a8dfSCaroline Tice int num_children = GetNumChildren(); 4943df9a8dfSCaroline Tice bool found = false; 4953df9a8dfSCaroline Tice for (int i = 0; i < num_children && !found; ++i) 4963df9a8dfSCaroline Tice { 4973df9a8dfSCaroline Tice child = GetChildAtIndex (i); 4983df9a8dfSCaroline Tice ConstString current_prefix = child->GetLevelName(); 4993df9a8dfSCaroline Tice if (current_prefix == child_prefix) 5003df9a8dfSCaroline Tice { 5013df9a8dfSCaroline Tice found = true; 5023df9a8dfSCaroline Tice std::string new_name; 5033df9a8dfSCaroline Tice for (int j = 0; j < names.GetArgumentCount(); ++j) 5043df9a8dfSCaroline Tice { 5053df9a8dfSCaroline Tice if (j > 0) 5063df9a8dfSCaroline Tice new_name += '.'; 5073df9a8dfSCaroline Tice new_name += names.GetArgumentAtIndex (j); 5083df9a8dfSCaroline Tice } 509101c7c20SCaroline Tice return child->SetVariable (new_name.c_str(), value, op, override, debugger_instance_name, 510101c7c20SCaroline Tice index_value); 5113df9a8dfSCaroline Tice } 5123df9a8dfSCaroline Tice } 5133df9a8dfSCaroline Tice if (!found) 5143df9a8dfSCaroline Tice { 5153df9a8dfSCaroline Tice err.SetErrorStringWithFormat ("Unable to find variable '%s'; cannot assign value.\n", 5163df9a8dfSCaroline Tice full_dot_name); 5173df9a8dfSCaroline Tice return err; 5183df9a8dfSCaroline Tice } 5193df9a8dfSCaroline Tice } 5203df9a8dfSCaroline Tice } 5213df9a8dfSCaroline Tice } 5223df9a8dfSCaroline Tice else 5233df9a8dfSCaroline Tice { 5243df9a8dfSCaroline Tice err.SetErrorStringWithFormat ("'%s' is not a valid level name; was expecting '%s'. Cannot assign value.\n", 5253df9a8dfSCaroline Tice prefix.AsCString(), m_settings.level_name.AsCString()); 5263df9a8dfSCaroline Tice } 5273df9a8dfSCaroline Tice 5283df9a8dfSCaroline Tice return err; 5293df9a8dfSCaroline Tice } 5303df9a8dfSCaroline Tice 5313df9a8dfSCaroline Tice StringList 5321b654882SGreg Clayton UserSettingsController::GetVariable 5331b654882SGreg Clayton ( 5341b654882SGreg Clayton const char *full_dot_name, 535*bfe5f3bfSGreg Clayton SettableVariableType &var_type, 536daccaa9eSCaroline Tice const char *debugger_instance_name, 537daccaa9eSCaroline Tice Error &err 5381b654882SGreg Clayton ) 5393df9a8dfSCaroline Tice { 5403df9a8dfSCaroline Tice Args names = UserSettingsController::BreakNameIntoPieces (full_dot_name); 5413df9a8dfSCaroline Tice ConstString const_var_name; 5423df9a8dfSCaroline Tice StringList value; 5433df9a8dfSCaroline Tice 5443df9a8dfSCaroline Tice int num_pieces = names.GetArgumentCount(); 5453df9a8dfSCaroline Tice 5463df9a8dfSCaroline Tice ConstString prefix (names.GetArgumentAtIndex (0)); 5473df9a8dfSCaroline Tice const_var_name.SetCString (names.GetArgumentAtIndex (num_pieces - 1)); 5483df9a8dfSCaroline Tice 5493df9a8dfSCaroline Tice const SettingEntry *global_entry = GetGlobalEntry (const_var_name); 5503df9a8dfSCaroline Tice const SettingEntry *instance_entry = GetInstanceEntry (const_var_name); 5513df9a8dfSCaroline Tice 5523df9a8dfSCaroline Tice if ((prefix != m_settings.level_name) 5533df9a8dfSCaroline Tice && (m_settings.level_name.GetLength () > 0)) 5543df9a8dfSCaroline Tice { 555daccaa9eSCaroline Tice err.SetErrorString ("Invalid variable name"); 5563df9a8dfSCaroline Tice return value; 5573df9a8dfSCaroline Tice } 5583df9a8dfSCaroline Tice 5593df9a8dfSCaroline Tice // prefix name matched; remove it from names. 5603df9a8dfSCaroline Tice if (m_settings.level_name.GetLength() > 0) 5613df9a8dfSCaroline Tice names.Shift(); 5623df9a8dfSCaroline Tice 5633df9a8dfSCaroline Tice // Should we pass this off to a child? If there is more than one name piece left, and the next name piece 5643df9a8dfSCaroline Tice // matches a child prefix, then yes. 5653df9a8dfSCaroline Tice 566*bfe5f3bfSGreg Clayton UserSettingsControllerSP child; 5673df9a8dfSCaroline Tice if (names.GetArgumentCount() > 1) 5683df9a8dfSCaroline Tice { 5693df9a8dfSCaroline Tice ConstString child_prefix (names.GetArgumentAtIndex (0)); 5703df9a8dfSCaroline Tice bool found = false; 5713df9a8dfSCaroline Tice for (int i = 0; i < m_children.size() && !found; ++i) 5723df9a8dfSCaroline Tice { 5733df9a8dfSCaroline Tice if (child_prefix == m_children[i]->GetLevelName()) 5743df9a8dfSCaroline Tice { 5753df9a8dfSCaroline Tice found = true; 5763df9a8dfSCaroline Tice child = m_children[i]; 5773df9a8dfSCaroline Tice std::string new_name; 5783df9a8dfSCaroline Tice for (int j = 0; j < names.GetArgumentCount(); ++j) 5793df9a8dfSCaroline Tice { 5803df9a8dfSCaroline Tice if (j > 0) 5813df9a8dfSCaroline Tice new_name += '.'; 5823df9a8dfSCaroline Tice new_name += names.GetArgumentAtIndex (j); 5833df9a8dfSCaroline Tice } 584daccaa9eSCaroline Tice return child->GetVariable (new_name.c_str(), var_type, debugger_instance_name, err); 5853df9a8dfSCaroline Tice } 5863df9a8dfSCaroline Tice } 5873df9a8dfSCaroline Tice 5883df9a8dfSCaroline Tice if (!found) 5893df9a8dfSCaroline Tice { 5903df9a8dfSCaroline Tice // Cannot be handled by a child, because name did not match any child prefixes. 5913df9a8dfSCaroline Tice // Cannot be a class-wide variable because there are too many name pieces. 5923df9a8dfSCaroline Tice 5933df9a8dfSCaroline Tice if (instance_entry != NULL) 5943df9a8dfSCaroline Tice { 5953df9a8dfSCaroline Tice var_type = instance_entry->var_type; 5963df9a8dfSCaroline Tice ConstString instance_name (names.GetArgumentAtIndex (0)); 5973df9a8dfSCaroline Tice InstanceSettings *current_settings = FindSettingsForInstance (instance_name); 5983df9a8dfSCaroline Tice 5993df9a8dfSCaroline Tice if (current_settings != NULL) 6003df9a8dfSCaroline Tice { 60112cecd74SCaroline Tice current_settings->GetInstanceSettingsValue (*instance_entry, const_var_name, value, &err); 6023df9a8dfSCaroline Tice } 6033df9a8dfSCaroline Tice else 6043df9a8dfSCaroline Tice { 6053df9a8dfSCaroline Tice // Look for instance name setting in pending settings. 6063df9a8dfSCaroline Tice 6073df9a8dfSCaroline Tice std::string inst_name_str = instance_name.AsCString(); 608*bfe5f3bfSGreg Clayton std::map<std::string, InstanceSettingsSP>::iterator pos; 6093df9a8dfSCaroline Tice 6103df9a8dfSCaroline Tice pos = m_pending_settings.find (inst_name_str); 6113df9a8dfSCaroline Tice if (pos != m_pending_settings.end()) 6123df9a8dfSCaroline Tice { 613*bfe5f3bfSGreg Clayton InstanceSettingsSP settings_sp = pos->second; 61412cecd74SCaroline Tice settings_sp->GetInstanceSettingsValue (*instance_entry, const_var_name, value, &err); 6153df9a8dfSCaroline Tice } 6163df9a8dfSCaroline Tice else 6173df9a8dfSCaroline Tice { 618101c7c20SCaroline Tice if (m_settings.level_name.GetLength() > 0) 619101c7c20SCaroline Tice { 6203df9a8dfSCaroline Tice // No valid instance name; assume they want the default settings. 62112cecd74SCaroline Tice m_default_settings->GetInstanceSettingsValue (*instance_entry, const_var_name, value, &err); 6223df9a8dfSCaroline Tice } 623101c7c20SCaroline Tice else 624101c7c20SCaroline Tice { 625101c7c20SCaroline Tice // We're at the Debugger level; use the debugger's instance settings. 626101c7c20SCaroline Tice StreamString tmp_name; 627101c7c20SCaroline Tice if (debugger_instance_name[0] != '[') 628101c7c20SCaroline Tice tmp_name.Printf ("[%s]", debugger_instance_name); 629101c7c20SCaroline Tice else 630101c7c20SCaroline Tice tmp_name.Printf ("%s", debugger_instance_name); 631101c7c20SCaroline Tice ConstString dbg_name (debugger_instance_name); 632101c7c20SCaroline Tice InstanceSettings *dbg_settings = FindSettingsForInstance (dbg_name); 633101c7c20SCaroline Tice if (dbg_settings) 63412cecd74SCaroline Tice dbg_settings->GetInstanceSettingsValue (*instance_entry, const_var_name, value, &err); 635101c7c20SCaroline Tice } 636101c7c20SCaroline Tice } 6373df9a8dfSCaroline Tice } 6383df9a8dfSCaroline Tice } 6393df9a8dfSCaroline Tice else 640daccaa9eSCaroline Tice err.SetErrorString ("Invalid variable name"); 6413df9a8dfSCaroline Tice } 6423df9a8dfSCaroline Tice } 6433df9a8dfSCaroline Tice else 6443df9a8dfSCaroline Tice { 6453df9a8dfSCaroline Tice // Only one name left. It must belong to the current level, or be an error. 6463df9a8dfSCaroline Tice if ((global_entry == NULL) 6473df9a8dfSCaroline Tice && (instance_entry == NULL)) 6483df9a8dfSCaroline Tice { 649daccaa9eSCaroline Tice err.SetErrorString ("Invalid variable name"); 6503df9a8dfSCaroline Tice } 6513df9a8dfSCaroline Tice else if (global_entry) 6523df9a8dfSCaroline Tice { 6533df9a8dfSCaroline Tice var_type = global_entry->var_type; 654daccaa9eSCaroline Tice GetGlobalVariable (const_var_name, value, err); 6553df9a8dfSCaroline Tice } 6563df9a8dfSCaroline Tice else if (instance_entry) 6573df9a8dfSCaroline Tice { 6583df9a8dfSCaroline Tice var_type = instance_entry->var_type; 659101c7c20SCaroline Tice if (m_settings.level_name.GetLength() > 0) 66012cecd74SCaroline Tice m_default_settings->GetInstanceSettingsValue (*instance_entry, const_var_name, value, &err); 661101c7c20SCaroline Tice else 662101c7c20SCaroline Tice { 663101c7c20SCaroline Tice // We're at the Debugger level; use the debugger's instance settings. 664101c7c20SCaroline Tice StreamString tmp_name; 665101c7c20SCaroline Tice if (debugger_instance_name[0] != '[') 666101c7c20SCaroline Tice tmp_name.Printf ("[%s]", debugger_instance_name); 667101c7c20SCaroline Tice else 668101c7c20SCaroline Tice tmp_name.Printf ("%s", debugger_instance_name); 669101c7c20SCaroline Tice ConstString dbg_name (tmp_name.GetData()); 670101c7c20SCaroline Tice InstanceSettings *dbg_settings = FindSettingsForInstance (dbg_name); 671101c7c20SCaroline Tice if (dbg_settings) 67212cecd74SCaroline Tice dbg_settings->GetInstanceSettingsValue (*instance_entry, const_var_name, value, &err); 673101c7c20SCaroline Tice } 6743df9a8dfSCaroline Tice } 6753df9a8dfSCaroline Tice } 6763df9a8dfSCaroline Tice 6773df9a8dfSCaroline Tice return value; 6783df9a8dfSCaroline Tice } 6793df9a8dfSCaroline Tice 6803df9a8dfSCaroline Tice void 6813df9a8dfSCaroline Tice UserSettingsController::RemovePendingSettings (const ConstString &instance_name) 6823df9a8dfSCaroline Tice { 68391123da2SCaroline Tice StreamString tmp_name; 68491123da2SCaroline Tice 68591123da2SCaroline Tice // Add surrounding brackets to instance name if not already present. 68691123da2SCaroline Tice 68791123da2SCaroline Tice if (instance_name.AsCString()[0] != '[') 68891123da2SCaroline Tice tmp_name.Printf ("[%s]", instance_name.AsCString()); 68991123da2SCaroline Tice else 69091123da2SCaroline Tice tmp_name.Printf ("%s", instance_name.AsCString()); 69191123da2SCaroline Tice 69291123da2SCaroline Tice std::string instance_name_str (tmp_name.GetData()); 693*bfe5f3bfSGreg Clayton std::map<std::string, InstanceSettingsSP>::iterator pos; 6943df9a8dfSCaroline Tice Mutex::Locker locker (m_pending_settings_mutex); 6953df9a8dfSCaroline Tice 6963df9a8dfSCaroline Tice m_pending_settings.erase (instance_name_str); 6973df9a8dfSCaroline Tice } 6983df9a8dfSCaroline Tice 699*bfe5f3bfSGreg Clayton const InstanceSettingsSP & 7003df9a8dfSCaroline Tice UserSettingsController::FindPendingSettings (const ConstString &instance_name) 7013df9a8dfSCaroline Tice { 702*bfe5f3bfSGreg Clayton std::map<std::string, InstanceSettingsSP>::iterator pos; 70391123da2SCaroline Tice StreamString tmp_name; 70491123da2SCaroline Tice 70591123da2SCaroline Tice // Add surrounding brackets to instance name if not already present. 70691123da2SCaroline Tice 70791123da2SCaroline Tice if (instance_name.AsCString()[0] != '[') 70891123da2SCaroline Tice tmp_name.Printf ("[%s]", instance_name.AsCString()); 70991123da2SCaroline Tice else 71091123da2SCaroline Tice tmp_name.Printf ("%s", instance_name.AsCString()); 71191123da2SCaroline Tice 71291123da2SCaroline Tice std::string instance_name_str (tmp_name.GetData()); // Need std::string for std::map look-up 7133df9a8dfSCaroline Tice 7143df9a8dfSCaroline Tice { // Scope for mutex. 7153df9a8dfSCaroline Tice Mutex::Locker locker (m_pending_settings_mutex); 7163df9a8dfSCaroline Tice 7173df9a8dfSCaroline Tice pos = m_pending_settings.find (instance_name_str); 7183df9a8dfSCaroline Tice if (pos != m_pending_settings.end()) 7193df9a8dfSCaroline Tice return pos->second; 7203df9a8dfSCaroline Tice } 7213df9a8dfSCaroline Tice 7223df9a8dfSCaroline Tice return m_default_settings; 7233df9a8dfSCaroline Tice } 7243df9a8dfSCaroline Tice 7253df9a8dfSCaroline Tice void 7263df9a8dfSCaroline Tice UserSettingsController::CreateDefaultInstanceSettings () 7273df9a8dfSCaroline Tice { 7283df9a8dfSCaroline Tice Error err; 7293df9a8dfSCaroline Tice const ConstString &default_name = InstanceSettings::GetDefaultName(); 7303df9a8dfSCaroline Tice for (int i = 0; i < m_settings.instance_settings.size(); ++i) 7313df9a8dfSCaroline Tice { 7323df9a8dfSCaroline Tice SettingEntry &entry = m_settings.instance_settings[i]; 7333df9a8dfSCaroline Tice ConstString var_name (entry.var_name); 7343df9a8dfSCaroline Tice const char *value = entry.default_value; 7353df9a8dfSCaroline Tice 736*bfe5f3bfSGreg Clayton if (entry.var_type == eSetVarTypeEnum) 7373df9a8dfSCaroline Tice value = entry.enum_values[0].string_value; 7383df9a8dfSCaroline Tice 7393df9a8dfSCaroline Tice m_default_settings->UpdateInstanceSettingsVariable (var_name, NULL, value, default_name, entry, 740*bfe5f3bfSGreg Clayton eVarSetOperationAssign, err, true); 7413df9a8dfSCaroline Tice } 7423df9a8dfSCaroline Tice } 7433df9a8dfSCaroline Tice 7443df9a8dfSCaroline Tice void 745*bfe5f3bfSGreg Clayton UserSettingsController::CopyDefaultSettings (const InstanceSettingsSP &actual_settings, 7463df9a8dfSCaroline Tice const ConstString &instance_name, 7473df9a8dfSCaroline Tice bool pending) 7483df9a8dfSCaroline Tice { 7493df9a8dfSCaroline Tice Error err; 7503df9a8dfSCaroline Tice for (int i = 0; i < m_settings.instance_settings.size(); ++i) 7513df9a8dfSCaroline Tice { 7523df9a8dfSCaroline Tice SettingEntry &entry = m_settings.instance_settings[i]; 7533df9a8dfSCaroline Tice ConstString var_name (entry.var_name); 7543df9a8dfSCaroline Tice StringList value; 75512cecd74SCaroline Tice m_default_settings->GetInstanceSettingsValue (entry, var_name, value, NULL); 7563df9a8dfSCaroline Tice 7573df9a8dfSCaroline Tice std::string value_str; 7583df9a8dfSCaroline Tice if (value.GetSize() == 1) 7593df9a8dfSCaroline Tice value_str.append (value.GetStringAtIndex (0)); 7603df9a8dfSCaroline Tice else if (value.GetSize() > 1) 7613df9a8dfSCaroline Tice { 7623df9a8dfSCaroline Tice for (int j = 0; j < value.GetSize(); ++j) 7633df9a8dfSCaroline Tice { 7643df9a8dfSCaroline Tice if (j > 0) 7653df9a8dfSCaroline Tice value_str.append (" "); 7663df9a8dfSCaroline Tice value_str.append (value.GetStringAtIndex (j)); 7673df9a8dfSCaroline Tice } 7683df9a8dfSCaroline Tice } 7693df9a8dfSCaroline Tice 7703df9a8dfSCaroline Tice actual_settings->UpdateInstanceSettingsVariable (var_name, NULL, value_str.c_str(), instance_name, entry, 771*bfe5f3bfSGreg Clayton eVarSetOperationAssign, err, pending); 7723df9a8dfSCaroline Tice 7733df9a8dfSCaroline Tice } 7743df9a8dfSCaroline Tice } 7753df9a8dfSCaroline Tice 776*bfe5f3bfSGreg Clayton InstanceSettingsSP 7773df9a8dfSCaroline Tice UserSettingsController::PendingSettingsForInstance (const ConstString &instance_name) 7783df9a8dfSCaroline Tice { 7793df9a8dfSCaroline Tice std::string name_str (instance_name.AsCString()); 780*bfe5f3bfSGreg Clayton std::map<std::string, InstanceSettingsSP>::iterator pos; 7813df9a8dfSCaroline Tice Mutex::Locker locker (m_pending_settings_mutex); 7823df9a8dfSCaroline Tice 7833df9a8dfSCaroline Tice pos = m_pending_settings.find (name_str); 7843df9a8dfSCaroline Tice if (pos != m_pending_settings.end()) 7853df9a8dfSCaroline Tice { 786*bfe5f3bfSGreg Clayton InstanceSettingsSP settings_sp = pos->second; 7873df9a8dfSCaroline Tice return settings_sp; 7883df9a8dfSCaroline Tice } 7893df9a8dfSCaroline Tice else 7903df9a8dfSCaroline Tice { 791*bfe5f3bfSGreg Clayton InstanceSettingsSP new_settings_sp = CreateInstanceSettings (instance_name.AsCString()); 7923df9a8dfSCaroline Tice CopyDefaultSettings (new_settings_sp, instance_name, true); 7933df9a8dfSCaroline Tice m_pending_settings[name_str] = new_settings_sp; 7943df9a8dfSCaroline Tice return new_settings_sp; 7953df9a8dfSCaroline Tice } 7963df9a8dfSCaroline Tice 7973df9a8dfSCaroline Tice // Should never reach this line. 7983df9a8dfSCaroline Tice 799*bfe5f3bfSGreg Clayton InstanceSettingsSP dummy; 8003df9a8dfSCaroline Tice 8013df9a8dfSCaroline Tice return dummy; 8023df9a8dfSCaroline Tice } 8033df9a8dfSCaroline Tice 8043df9a8dfSCaroline Tice void 8053df9a8dfSCaroline Tice UserSettingsController::GetAllDefaultSettingValues (StreamString &result_stream) 8063df9a8dfSCaroline Tice { 8073df9a8dfSCaroline Tice std::string parent_prefix; 8083df9a8dfSCaroline Tice BuildParentPrefix (parent_prefix); 8093df9a8dfSCaroline Tice const char *prefix = parent_prefix.c_str(); 8103df9a8dfSCaroline Tice 8113df9a8dfSCaroline Tice for (int i = 0; i < m_settings.instance_settings.size(); ++i) 8123df9a8dfSCaroline Tice { 8133df9a8dfSCaroline Tice SettingEntry &entry = m_settings.instance_settings[i]; 8143df9a8dfSCaroline Tice ConstString var_name (entry.var_name); 8153df9a8dfSCaroline Tice StringList tmp_value; 81612cecd74SCaroline Tice m_default_settings->GetInstanceSettingsValue (entry, var_name, tmp_value, NULL); 8173df9a8dfSCaroline Tice 8183df9a8dfSCaroline Tice StreamString value_string; 8192d5289d6SCaroline Tice bool multi_value = false; 8203df9a8dfSCaroline Tice 8213df9a8dfSCaroline Tice if (tmp_value.GetSize() == 1) 8223df9a8dfSCaroline Tice value_string.Printf ("%s", tmp_value.GetStringAtIndex (0)); 8233df9a8dfSCaroline Tice else 8243df9a8dfSCaroline Tice { 8253df9a8dfSCaroline Tice for (int j = 0; j < tmp_value.GetSize(); ++j) 8262d5289d6SCaroline Tice { 827*bfe5f3bfSGreg Clayton if (entry.var_type == eSetVarTypeArray) 8282d5289d6SCaroline Tice value_string.Printf ("\n [%d]: '%s'", j, tmp_value.GetStringAtIndex (j)); 829*bfe5f3bfSGreg Clayton else if (entry.var_type == eSetVarTypeDictionary) 8302d5289d6SCaroline Tice value_string.Printf ("\n '%s'", tmp_value.GetStringAtIndex (j)); 8312d5289d6SCaroline Tice } 8322d5289d6SCaroline Tice multi_value = true; 8333df9a8dfSCaroline Tice } 8343df9a8dfSCaroline Tice 835ded2fa39SCaroline Tice if (! parent_prefix.empty()) 8362d5289d6SCaroline Tice { 8372d5289d6SCaroline Tice if (multi_value) 8382d5289d6SCaroline Tice result_stream.Printf ("%s.%s (%s):%s\n", prefix, var_name.AsCString(), 8392d5289d6SCaroline Tice UserSettingsController::GetTypeString (entry.var_type), value_string.GetData()); 8402d5289d6SCaroline Tice else 841ded2fa39SCaroline Tice result_stream.Printf ("%s.%s (%s) = '%s'\n", prefix, var_name.AsCString(), 8423df9a8dfSCaroline Tice UserSettingsController::GetTypeString (entry.var_type), value_string.GetData()); 8433df9a8dfSCaroline Tice } 8443df9a8dfSCaroline Tice } 8452d5289d6SCaroline Tice } 8463df9a8dfSCaroline Tice 8473df9a8dfSCaroline Tice void 8483df9a8dfSCaroline Tice UserSettingsController::GetAllPendingSettingValues (StreamString &result_stream) 8493df9a8dfSCaroline Tice { 850*bfe5f3bfSGreg Clayton std::map<std::string, InstanceSettingsSP>::iterator pos; 8513df9a8dfSCaroline Tice 8523df9a8dfSCaroline Tice std::string parent_prefix; 8533df9a8dfSCaroline Tice BuildParentPrefix (parent_prefix); 8543df9a8dfSCaroline Tice const char *prefix = parent_prefix.c_str(); 8553df9a8dfSCaroline Tice 8563df9a8dfSCaroline Tice for (pos = m_pending_settings.begin(); pos != m_pending_settings.end(); ++pos) 8573df9a8dfSCaroline Tice { 8583df9a8dfSCaroline Tice std::string tmp_name = pos->first; 859*bfe5f3bfSGreg Clayton InstanceSettingsSP settings_sp = pos->second; 8603df9a8dfSCaroline Tice 8613df9a8dfSCaroline Tice const ConstString instance_name (tmp_name.c_str()); 8623df9a8dfSCaroline Tice 8633df9a8dfSCaroline Tice for (int i = 0; i < m_settings.instance_settings.size(); ++i) 8643df9a8dfSCaroline Tice { 8653df9a8dfSCaroline Tice SettingEntry &entry = m_settings.instance_settings[i]; 8663df9a8dfSCaroline Tice ConstString var_name (entry.var_name); 8673df9a8dfSCaroline Tice StringList tmp_value; 86812cecd74SCaroline Tice settings_sp->GetInstanceSettingsValue (entry, var_name, tmp_value, NULL); 8693df9a8dfSCaroline Tice 8703df9a8dfSCaroline Tice StreamString value_str; 8713df9a8dfSCaroline Tice 8723df9a8dfSCaroline Tice if (tmp_value.GetSize() == 0) 873ded2fa39SCaroline Tice value_str.Printf (""); 874ded2fa39SCaroline Tice else if (tmp_value.GetSize() == 1) 8753df9a8dfSCaroline Tice value_str.Printf ("%s", tmp_value.GetStringAtIndex (0)); 8763df9a8dfSCaroline Tice else 8773df9a8dfSCaroline Tice { 8783df9a8dfSCaroline Tice for (int j = 0; j < tmp_value.GetSize(); ++j) 8793df9a8dfSCaroline Tice value_str.Printf ("%s ", tmp_value.GetStringAtIndex (j)); 8803df9a8dfSCaroline Tice } 8813df9a8dfSCaroline Tice 8823df9a8dfSCaroline Tice if (parent_prefix.length() > 0) 8833df9a8dfSCaroline Tice { 8843df9a8dfSCaroline Tice result_stream.Printf ("%s.%s.%s (%s) = '%s' [pending]\n", prefix, instance_name.AsCString(), 8853df9a8dfSCaroline Tice var_name.AsCString(), UserSettingsController::GetTypeString (entry.var_type), 8863df9a8dfSCaroline Tice value_str.GetData()); 8873df9a8dfSCaroline Tice } 8883df9a8dfSCaroline Tice else 8893df9a8dfSCaroline Tice { 8903df9a8dfSCaroline Tice result_stream.Printf ("%s (%s) = '%s' [pending]\n", var_name.AsCString(), 8913df9a8dfSCaroline Tice UserSettingsController::GetTypeString (entry.var_type), 8923df9a8dfSCaroline Tice value_str.GetData()); 8933df9a8dfSCaroline Tice } 8943df9a8dfSCaroline Tice } 8953df9a8dfSCaroline Tice } 8963df9a8dfSCaroline Tice } 8973df9a8dfSCaroline Tice 8983df9a8dfSCaroline Tice InstanceSettings * 8993df9a8dfSCaroline Tice UserSettingsController::FindSettingsForInstance (const ConstString &instance_name) 9003df9a8dfSCaroline Tice { 9013df9a8dfSCaroline Tice std::string instance_name_str (instance_name.AsCString()); 9023df9a8dfSCaroline Tice std::map<std::string, InstanceSettings *>::iterator pos; 9033df9a8dfSCaroline Tice 9043df9a8dfSCaroline Tice pos = m_live_settings.find (instance_name_str); 9053df9a8dfSCaroline Tice if (pos != m_live_settings.end ()) 9063df9a8dfSCaroline Tice { 9073df9a8dfSCaroline Tice InstanceSettings *settings = pos->second; 9083df9a8dfSCaroline Tice return settings; 9093df9a8dfSCaroline Tice } 9103df9a8dfSCaroline Tice 9113df9a8dfSCaroline Tice return NULL; 9123df9a8dfSCaroline Tice } 9133df9a8dfSCaroline Tice 9143df9a8dfSCaroline Tice void 9153df9a8dfSCaroline Tice UserSettingsController::GetAllInstanceVariableValues (CommandInterpreter &interpreter, 9163df9a8dfSCaroline Tice StreamString &result_stream) 9173df9a8dfSCaroline Tice { 9183df9a8dfSCaroline Tice std::map<std::string, InstanceSettings *>::iterator pos; 9193df9a8dfSCaroline Tice std::string parent_prefix; 9203df9a8dfSCaroline Tice BuildParentPrefix (parent_prefix); 9213df9a8dfSCaroline Tice const char *prefix = parent_prefix.c_str(); 9223df9a8dfSCaroline Tice StreamString description; 9233df9a8dfSCaroline Tice 9243df9a8dfSCaroline Tice for (pos = m_live_settings.begin(); pos != m_live_settings.end(); ++pos) 9253df9a8dfSCaroline Tice { 9263df9a8dfSCaroline Tice std::string instance_name = pos->first; 9273df9a8dfSCaroline Tice InstanceSettings *settings = pos->second; 9283df9a8dfSCaroline Tice 9293df9a8dfSCaroline Tice for (int i = 0; i < m_settings.instance_settings.size(); ++i) 9303df9a8dfSCaroline Tice { 9313df9a8dfSCaroline Tice SettingEntry &entry = m_settings.instance_settings[i]; 9323df9a8dfSCaroline Tice const ConstString var_name (entry.var_name); 9333df9a8dfSCaroline Tice StringList tmp_value; 93412cecd74SCaroline Tice settings->GetInstanceSettingsValue (entry, var_name, tmp_value, NULL); 9353df9a8dfSCaroline Tice StreamString tmp_value_str; 9363df9a8dfSCaroline Tice 9373df9a8dfSCaroline Tice if (tmp_value.GetSize() == 0) 938ded2fa39SCaroline Tice tmp_value_str.Printf (""); 939ded2fa39SCaroline Tice else if (tmp_value.GetSize() == 1) 9403df9a8dfSCaroline Tice tmp_value_str.Printf ("%s", tmp_value.GetStringAtIndex (0)); 9413df9a8dfSCaroline Tice else 9423df9a8dfSCaroline Tice { 9433df9a8dfSCaroline Tice for (int j = 0; j < tmp_value.GetSize(); ++j) 9443df9a8dfSCaroline Tice tmp_value_str.Printf ("%s ",tmp_value.GetStringAtIndex (j)); 9453df9a8dfSCaroline Tice } 9463df9a8dfSCaroline Tice 9473df9a8dfSCaroline Tice description.Clear(); 9483df9a8dfSCaroline Tice if (parent_prefix.length() > 0) 9493df9a8dfSCaroline Tice { 9503df9a8dfSCaroline Tice description.Printf ("%s.%s.%s (%s) = '%s'", prefix, instance_name.c_str(), var_name.AsCString(), 9513df9a8dfSCaroline Tice UserSettingsController::GetTypeString (entry.var_type), 9523df9a8dfSCaroline Tice tmp_value_str.GetData()); 9533df9a8dfSCaroline Tice } 9543df9a8dfSCaroline Tice else 9553df9a8dfSCaroline Tice { 9563df9a8dfSCaroline Tice description.Printf ("%s (%s) = '%s'", var_name.AsCString(), 9573df9a8dfSCaroline Tice UserSettingsController::GetTypeString (entry.var_type), tmp_value_str.GetData()); 9583df9a8dfSCaroline Tice } 9593df9a8dfSCaroline Tice result_stream.Printf ("%s\n", description.GetData()); 9603df9a8dfSCaroline Tice } 9613df9a8dfSCaroline Tice } 9623df9a8dfSCaroline Tice } 9633df9a8dfSCaroline Tice 9643df9a8dfSCaroline Tice void 9653df9a8dfSCaroline Tice UserSettingsController::OverrideAllInstances (const ConstString &var_name, 9663df9a8dfSCaroline Tice const char *value, 967*bfe5f3bfSGreg Clayton VarSetOperationType op, 9683df9a8dfSCaroline Tice const char *index_value, 9693df9a8dfSCaroline Tice Error &err) 9703df9a8dfSCaroline Tice { 9713df9a8dfSCaroline Tice std::map<std::string, InstanceSettings *>::iterator pos; 9723df9a8dfSCaroline Tice StreamString description; 9733df9a8dfSCaroline Tice 9743df9a8dfSCaroline Tice for (pos = m_live_settings.begin(); pos != m_live_settings.end(); ++pos) 9753df9a8dfSCaroline Tice { 9763df9a8dfSCaroline Tice InstanceSettings *settings = pos->second; 9773df9a8dfSCaroline Tice StreamString tmp_name; 9783df9a8dfSCaroline Tice tmp_name.Printf ("[%s]", settings->GetInstanceName().AsCString()); 9793df9a8dfSCaroline Tice const ConstString instance_name (tmp_name.GetData()); 9803df9a8dfSCaroline Tice const SettingEntry *entry = GetInstanceEntry (var_name); 9813df9a8dfSCaroline Tice settings->UpdateInstanceSettingsVariable (var_name, index_value, value, instance_name, *entry, op, err, false); 9823df9a8dfSCaroline Tice 9833df9a8dfSCaroline Tice } 9843df9a8dfSCaroline Tice } 9853df9a8dfSCaroline Tice 9863df9a8dfSCaroline Tice void 9873df9a8dfSCaroline Tice UserSettingsController::RegisterInstanceSettings (InstanceSettings *instance_settings) 9883df9a8dfSCaroline Tice { 9893df9a8dfSCaroline Tice Mutex::Locker locker (m_live_settings_mutex); 9903df9a8dfSCaroline Tice StreamString tmp_name; 9913df9a8dfSCaroline Tice tmp_name.Printf ("[%s]", instance_settings->GetInstanceName().AsCString()); 9923df9a8dfSCaroline Tice const ConstString instance_name (tmp_name.GetData()); 9933df9a8dfSCaroline Tice std::string instance_name_str (instance_name.AsCString()); 9943df9a8dfSCaroline Tice if (instance_name_str.compare (InstanceSettings::GetDefaultName().AsCString()) != 0) 9953df9a8dfSCaroline Tice m_live_settings[instance_name_str] = instance_settings; 9963df9a8dfSCaroline Tice } 9973df9a8dfSCaroline Tice 9983df9a8dfSCaroline Tice void 9993df9a8dfSCaroline Tice UserSettingsController::UnregisterInstanceSettings (InstanceSettings *instance) 10003df9a8dfSCaroline Tice { 10013df9a8dfSCaroline Tice Mutex::Locker locker (m_live_settings_mutex); 10023df9a8dfSCaroline Tice StreamString tmp_name; 10033df9a8dfSCaroline Tice tmp_name.Printf ("[%s]", instance->GetInstanceName().AsCString()); 10043df9a8dfSCaroline Tice std::string instance_name (tmp_name.GetData()); 10053df9a8dfSCaroline Tice 10063df9a8dfSCaroline Tice std::map <std::string, InstanceSettings *>::iterator pos; 10073df9a8dfSCaroline Tice 10083df9a8dfSCaroline Tice pos = m_live_settings.find (instance_name); 10093df9a8dfSCaroline Tice if (pos != m_live_settings.end()) 10103df9a8dfSCaroline Tice m_live_settings.erase (pos); 10113df9a8dfSCaroline Tice } 10123df9a8dfSCaroline Tice 10133df9a8dfSCaroline Tice void 10143df9a8dfSCaroline Tice UserSettingsController::CreateSettingsVector (const SettingEntry *table, 10153df9a8dfSCaroline Tice bool global) 10163df9a8dfSCaroline Tice { 10173df9a8dfSCaroline Tice int i = 0; 10183df9a8dfSCaroline Tice while (table[i].var_name != NULL) 10193df9a8dfSCaroline Tice { 10203df9a8dfSCaroline Tice const SettingEntry &table_entry = table[i]; 10213df9a8dfSCaroline Tice ConstString const_var_name (table_entry.var_name); 10223df9a8dfSCaroline Tice SettingEntry new_entry; 10233df9a8dfSCaroline Tice 10243df9a8dfSCaroline Tice new_entry = table_entry; 10253df9a8dfSCaroline Tice new_entry.var_name = const_var_name.AsCString(); 10263df9a8dfSCaroline Tice 10273df9a8dfSCaroline Tice if (global) 10283df9a8dfSCaroline Tice m_settings.global_settings.push_back (new_entry); 10293df9a8dfSCaroline Tice else 10303df9a8dfSCaroline Tice m_settings.instance_settings.push_back (new_entry); 10313df9a8dfSCaroline Tice 10323df9a8dfSCaroline Tice ++i; 10333df9a8dfSCaroline Tice } 10343df9a8dfSCaroline Tice } 10353df9a8dfSCaroline Tice 10363df9a8dfSCaroline Tice //---------------------------------------------------------------------- 10373df9a8dfSCaroline Tice // UserSettingsController static methods 10383df9a8dfSCaroline Tice //---------------------------------------------------------------------- 10393df9a8dfSCaroline Tice 10403df9a8dfSCaroline Tice int 10413df9a8dfSCaroline Tice FindMaxNameLength (std::vector<SettingEntry> table) 10423df9a8dfSCaroline Tice { 10433df9a8dfSCaroline Tice int max_length = 1; 10443df9a8dfSCaroline Tice 10453df9a8dfSCaroline Tice for (int i = 0; i < table.size(); ++i) 10463df9a8dfSCaroline Tice { 10473df9a8dfSCaroline Tice int len = strlen (table[i].var_name); 10483df9a8dfSCaroline Tice if (len > max_length) 10493df9a8dfSCaroline Tice max_length = len; 10503df9a8dfSCaroline Tice } 10513df9a8dfSCaroline Tice 10523df9a8dfSCaroline Tice return max_length; 10533df9a8dfSCaroline Tice } 10543df9a8dfSCaroline Tice 10553df9a8dfSCaroline Tice const char * 1056*bfe5f3bfSGreg Clayton UserSettingsController::GetTypeString (SettableVariableType var_type) 10573df9a8dfSCaroline Tice { 10583df9a8dfSCaroline Tice switch (var_type) 10593df9a8dfSCaroline Tice { 1060*bfe5f3bfSGreg Clayton case eSetVarTypeInt: 10613df9a8dfSCaroline Tice return "int"; 1062*bfe5f3bfSGreg Clayton case eSetVarTypeBoolean: 10633df9a8dfSCaroline Tice return "boolean"; 1064*bfe5f3bfSGreg Clayton case eSetVarTypeString: 10653df9a8dfSCaroline Tice return "string"; 1066*bfe5f3bfSGreg Clayton case eSetVarTypeArray: 10673df9a8dfSCaroline Tice return "array"; 1068*bfe5f3bfSGreg Clayton case eSetVarTypeDictionary: 10693df9a8dfSCaroline Tice return "dictionary"; 1070*bfe5f3bfSGreg Clayton case eSetVarTypeEnum: 10713df9a8dfSCaroline Tice return "enum"; 1072*bfe5f3bfSGreg Clayton case eSetVarTypeNone: 10733df9a8dfSCaroline Tice return "no type"; 10743df9a8dfSCaroline Tice } 10753df9a8dfSCaroline Tice 10763df9a8dfSCaroline Tice return ""; 10773df9a8dfSCaroline Tice } 10783df9a8dfSCaroline Tice 10793df9a8dfSCaroline Tice void 1080*bfe5f3bfSGreg Clayton UserSettingsController::PrintEnumValues (const OptionEnumValueElement *enum_values, Stream &str) 10813df9a8dfSCaroline Tice { 10823df9a8dfSCaroline Tice int i = 0; 10833df9a8dfSCaroline Tice while (enum_values[i].string_value != NULL) 10843df9a8dfSCaroline Tice { 10853df9a8dfSCaroline Tice str.Printf ("%s ", enum_values[i].string_value); 10863df9a8dfSCaroline Tice ++i; 10873df9a8dfSCaroline Tice } 10883df9a8dfSCaroline Tice 10893df9a8dfSCaroline Tice } 10903df9a8dfSCaroline Tice 10913df9a8dfSCaroline Tice void 10923df9a8dfSCaroline Tice UserSettingsController::FindAllSettingsDescriptions (CommandInterpreter &interpreter, 1093*bfe5f3bfSGreg Clayton UserSettingsControllerSP root, 10943df9a8dfSCaroline Tice std::string ¤t_prefix, 10953df9a8dfSCaroline Tice StreamString &result_stream, 10963df9a8dfSCaroline Tice Error &err) 10973df9a8dfSCaroline Tice { 10983df9a8dfSCaroline Tice // Write out current prefix line. 10993df9a8dfSCaroline Tice StreamString prefix_line; 11003df9a8dfSCaroline Tice StreamString description; 1101*bfe5f3bfSGreg Clayton uint32_t max_len = FindMaxNameLength (root->m_settings.global_settings); 11023df9a8dfSCaroline Tice int num_entries = root->m_settings.global_settings.size(); 11033df9a8dfSCaroline Tice 11043df9a8dfSCaroline Tice if (! current_prefix.empty()) 11053df9a8dfSCaroline Tice result_stream.Printf ("\n'%s' variables:\n\n", current_prefix.c_str()); 11063df9a8dfSCaroline Tice else 11073df9a8dfSCaroline Tice result_stream.Printf ("\nTop level variables:\n\n"); 11083df9a8dfSCaroline Tice 11093df9a8dfSCaroline Tice if (num_entries > 0) 11103df9a8dfSCaroline Tice { 11113df9a8dfSCaroline Tice // Write out all "global" variables. 11123df9a8dfSCaroline Tice for (int i = 0; i < num_entries; ++i) 11133df9a8dfSCaroline Tice { 1114*bfe5f3bfSGreg Clayton DumpSettingEntry (interpreter, result_stream, max_len, root->m_settings.global_settings[i]); 11153df9a8dfSCaroline Tice } 11163df9a8dfSCaroline Tice } 11173df9a8dfSCaroline Tice 11183df9a8dfSCaroline Tice num_entries = root->m_settings.instance_settings.size(); 11193df9a8dfSCaroline Tice max_len = FindMaxNameLength (root->m_settings.instance_settings); 11203df9a8dfSCaroline Tice 11213df9a8dfSCaroline Tice if (num_entries > 0) 11223df9a8dfSCaroline Tice { 11233df9a8dfSCaroline Tice // Write out all instance variables. 11243df9a8dfSCaroline Tice for (int i = 0; i < num_entries; ++i) 11253df9a8dfSCaroline Tice { 1126*bfe5f3bfSGreg Clayton DumpSettingEntry (interpreter, result_stream, max_len, root->m_settings.instance_settings[i]); 11273df9a8dfSCaroline Tice } 11283df9a8dfSCaroline Tice } 11293df9a8dfSCaroline Tice 11303df9a8dfSCaroline Tice // Now, recurse across all children. 11313df9a8dfSCaroline Tice int num_children = root->GetNumChildren(); 11323df9a8dfSCaroline Tice for (int i = 0; i < num_children; ++i) 11333df9a8dfSCaroline Tice { 1134*bfe5f3bfSGreg Clayton UserSettingsControllerSP child = root->GetChildAtIndex (i); 11353df9a8dfSCaroline Tice 11363df9a8dfSCaroline Tice if (child) 11373df9a8dfSCaroline Tice { 11383df9a8dfSCaroline Tice ConstString child_prefix = child->GetLevelName(); 11393df9a8dfSCaroline Tice StreamString new_prefix; 1140ded2fa39SCaroline Tice if (! current_prefix.empty()) 11413df9a8dfSCaroline Tice new_prefix.Printf ("%s.%s", current_prefix.c_str(), child_prefix.AsCString()); 11423df9a8dfSCaroline Tice else 11433df9a8dfSCaroline Tice new_prefix.Printf ("%s", child_prefix.AsCString()); 11443df9a8dfSCaroline Tice std::string new_prefix_str = new_prefix.GetData(); 1145*bfe5f3bfSGreg Clayton UserSettingsController::FindAllSettingsDescriptions (interpreter, 1146*bfe5f3bfSGreg Clayton child, 1147*bfe5f3bfSGreg Clayton new_prefix_str, 1148*bfe5f3bfSGreg Clayton result_stream, 11493df9a8dfSCaroline Tice err); 11503df9a8dfSCaroline Tice } 11513df9a8dfSCaroline Tice } 11523df9a8dfSCaroline Tice } 11533df9a8dfSCaroline Tice 11543df9a8dfSCaroline Tice void 11557d9edf67SCaroline Tice UserSettingsController::FindSettingsDescriptions (CommandInterpreter &interpreter, 1156*bfe5f3bfSGreg Clayton UserSettingsControllerSP root, 11577d9edf67SCaroline Tice std::string ¤t_prefix, 11587d9edf67SCaroline Tice const char *search_name, 11597d9edf67SCaroline Tice StreamString &result_stream, 11607d9edf67SCaroline Tice Error &err) 11617d9edf67SCaroline Tice { 11627d9edf67SCaroline Tice Args names = UserSettingsController::BreakNameIntoPieces (search_name); 11637d9edf67SCaroline Tice int num_pieces = names.GetArgumentCount (); 11647d9edf67SCaroline Tice 11657d9edf67SCaroline Tice if (num_pieces == 0) 11667d9edf67SCaroline Tice return; 11677d9edf67SCaroline Tice 11687d9edf67SCaroline Tice if (root->GetLevelName().GetLength() > 0) 11697d9edf67SCaroline Tice { 11707d9edf67SCaroline Tice ConstString prefix (names.GetArgumentAtIndex (0)); 11717d9edf67SCaroline Tice if (prefix != root->GetLevelName()) 11727d9edf67SCaroline Tice { 11737d9edf67SCaroline Tice std::string parent_prefix; 11747d9edf67SCaroline Tice root->BuildParentPrefix (parent_prefix); 11757d9edf67SCaroline Tice err.SetErrorStringWithFormat ("Cannot find match for '%s.%s'\n", parent_prefix.c_str(), 11767d9edf67SCaroline Tice prefix.AsCString()); 11777d9edf67SCaroline Tice return; 11787d9edf67SCaroline Tice } 11797d9edf67SCaroline Tice else 11807d9edf67SCaroline Tice { 11817d9edf67SCaroline Tice names.Shift(); 11827d9edf67SCaroline Tice --num_pieces; 11837d9edf67SCaroline Tice } 11847d9edf67SCaroline Tice } 11857d9edf67SCaroline Tice 11867d9edf67SCaroline Tice // If there's nothing left then dump all global and instance descriptions for this root. 11877d9edf67SCaroline Tice if (num_pieces == 0) 11887d9edf67SCaroline Tice { 11897d9edf67SCaroline Tice StreamString prefix_line; 11907d9edf67SCaroline Tice StreamString description; 11917d9edf67SCaroline Tice uint32_t max_len; 11927d9edf67SCaroline Tice int num_entries = root->m_settings.global_settings.size(); 11937d9edf67SCaroline Tice 11947d9edf67SCaroline Tice max_len = FindMaxNameLength (root->m_settings.global_settings); 11957d9edf67SCaroline Tice 11967d9edf67SCaroline Tice result_stream.Printf ("\n'%s' variables:\n\n", search_name); 11977d9edf67SCaroline Tice 11987d9edf67SCaroline Tice if (num_entries > 0) 11997d9edf67SCaroline Tice { 12007d9edf67SCaroline Tice // Write out all "global" variables. 12017d9edf67SCaroline Tice for (int i = 0; i < num_entries; ++i) 12027d9edf67SCaroline Tice { 1203*bfe5f3bfSGreg Clayton DumpSettingEntry (interpreter, result_stream, max_len, root->m_settings.global_settings[i]); 12047d9edf67SCaroline Tice } 12057d9edf67SCaroline Tice } 12067d9edf67SCaroline Tice 12077d9edf67SCaroline Tice num_entries = root->m_settings.instance_settings.size(); 12087d9edf67SCaroline Tice max_len = FindMaxNameLength (root->m_settings.instance_settings); 12097d9edf67SCaroline Tice 12107d9edf67SCaroline Tice if (num_entries > 0) 12117d9edf67SCaroline Tice { 12127d9edf67SCaroline Tice // Write out all instance variables. 12137d9edf67SCaroline Tice for (int i = 0; i < num_entries; ++i) 12147d9edf67SCaroline Tice { 1215*bfe5f3bfSGreg Clayton DumpSettingEntry (interpreter, result_stream, max_len, root->m_settings.instance_settings[i]); 12167d9edf67SCaroline Tice } 12177d9edf67SCaroline Tice } 12187d9edf67SCaroline Tice } 12197d9edf67SCaroline Tice else if (num_pieces == 1) 12207d9edf67SCaroline Tice { 12217d9edf67SCaroline Tice ConstString var_name (names.GetArgumentAtIndex (0)); 12227d9edf67SCaroline Tice bool is_global = false; 12237d9edf67SCaroline Tice 12247d9edf67SCaroline Tice const SettingEntry *setting_entry = root->GetGlobalEntry (var_name); 12257d9edf67SCaroline Tice 12267d9edf67SCaroline Tice if (setting_entry == NULL) 12277d9edf67SCaroline Tice setting_entry = root->GetInstanceEntry (var_name); 12287d9edf67SCaroline Tice else 12297d9edf67SCaroline Tice is_global = true; 12307d9edf67SCaroline Tice 12317d9edf67SCaroline Tice // Check to see if it is a global or instance variable name. 12327d9edf67SCaroline Tice if (setting_entry != NULL) 12337d9edf67SCaroline Tice { 1234*bfe5f3bfSGreg Clayton DumpSettingEntry (interpreter, result_stream, var_name.GetLength(), *setting_entry); 12357d9edf67SCaroline Tice } 12367d9edf67SCaroline Tice else 12377d9edf67SCaroline Tice { 12387d9edf67SCaroline Tice // It must be a child name. 12397d9edf67SCaroline Tice int num_children = root->GetNumChildren(); 12407d9edf67SCaroline Tice bool found = false; 12417d9edf67SCaroline Tice for (int i = 0; i < num_children && !found; ++i) 12427d9edf67SCaroline Tice { 1243*bfe5f3bfSGreg Clayton UserSettingsControllerSP child = root->GetChildAtIndex (i); 12447d9edf67SCaroline Tice if (child) 12457d9edf67SCaroline Tice { 12467d9edf67SCaroline Tice ConstString child_prefix = child->GetLevelName(); 12477d9edf67SCaroline Tice if (child_prefix == var_name) 12487d9edf67SCaroline Tice { 12497d9edf67SCaroline Tice found = true; 1250*bfe5f3bfSGreg Clayton UserSettingsController::FindSettingsDescriptions (interpreter, 1251*bfe5f3bfSGreg Clayton child, 1252*bfe5f3bfSGreg Clayton current_prefix, 1253*bfe5f3bfSGreg Clayton var_name.AsCString(), 1254*bfe5f3bfSGreg Clayton result_stream, 1255*bfe5f3bfSGreg Clayton err); 12567d9edf67SCaroline Tice } 12577d9edf67SCaroline Tice } 12587d9edf67SCaroline Tice } 12597d9edf67SCaroline Tice if (!found) 12607d9edf67SCaroline Tice { 12617d9edf67SCaroline Tice std::string parent_prefix; 12627d9edf67SCaroline Tice root->BuildParentPrefix (parent_prefix); 12637d9edf67SCaroline Tice err.SetErrorStringWithFormat ("Cannot find match for '%s.%s'\n", parent_prefix.c_str(), search_name); 12647d9edf67SCaroline Tice return; 12657d9edf67SCaroline Tice } 12667d9edf67SCaroline Tice } 12677d9edf67SCaroline Tice } 12687d9edf67SCaroline Tice else 12697d9edf67SCaroline Tice { 12707d9edf67SCaroline Tice // It must be a child name; find the child and call this function recursively on child. 12717d9edf67SCaroline Tice ConstString child_name (names.GetArgumentAtIndex (0)); 12727d9edf67SCaroline Tice 12737d9edf67SCaroline Tice StreamString rest_of_search_name; 12747d9edf67SCaroline Tice for (int i = 0; i < num_pieces; ++i) 12757d9edf67SCaroline Tice { 12767d9edf67SCaroline Tice rest_of_search_name.Printf ("%s", names.GetArgumentAtIndex (i)); 12777d9edf67SCaroline Tice if ((i + 1) < num_pieces) 12787d9edf67SCaroline Tice rest_of_search_name.Printf ("."); 12797d9edf67SCaroline Tice } 12807d9edf67SCaroline Tice 12817d9edf67SCaroline Tice int num_children = root->GetNumChildren(); 12827d9edf67SCaroline Tice bool found = false; 12837d9edf67SCaroline Tice for (int i = 0; i < num_children && !found; ++i) 12847d9edf67SCaroline Tice { 1285*bfe5f3bfSGreg Clayton UserSettingsControllerSP child = root->GetChildAtIndex (i); 12867d9edf67SCaroline Tice if (child) 12877d9edf67SCaroline Tice { 12887d9edf67SCaroline Tice ConstString child_prefix = child->GetLevelName(); 12897d9edf67SCaroline Tice if (child_prefix == child_name) 12907d9edf67SCaroline Tice { 12917d9edf67SCaroline Tice found = true; 12927d9edf67SCaroline Tice UserSettingsController::FindSettingsDescriptions (interpreter, child, current_prefix, 12937d9edf67SCaroline Tice rest_of_search_name.GetData(), result_stream, 12947d9edf67SCaroline Tice err); 12957d9edf67SCaroline Tice } 12967d9edf67SCaroline Tice } 12977d9edf67SCaroline Tice } 12987d9edf67SCaroline Tice if (!found) 12997d9edf67SCaroline Tice { 13007d9edf67SCaroline Tice std::string parent_prefix; 13017d9edf67SCaroline Tice root->BuildParentPrefix (parent_prefix); 13027d9edf67SCaroline Tice err.SetErrorStringWithFormat ("Cannot find match for '%s.%s'\n", parent_prefix.c_str(), search_name); 13037d9edf67SCaroline Tice return; 13047d9edf67SCaroline Tice } 13057d9edf67SCaroline Tice } 13067d9edf67SCaroline Tice } 13077d9edf67SCaroline Tice 13087d9edf67SCaroline Tice void 130973fd2728SCaroline Tice UserSettingsController::SearchAllSettingsDescriptions (CommandInterpreter &interpreter, 1310*bfe5f3bfSGreg Clayton UserSettingsControllerSP root, 131173fd2728SCaroline Tice std::string ¤t_prefix, 131273fd2728SCaroline Tice const char *search_word, 131373fd2728SCaroline Tice StreamString &result_stream) 131473fd2728SCaroline Tice { 131573fd2728SCaroline Tice if ((search_word == NULL) || (strlen (search_word) == 0)) 131673fd2728SCaroline Tice return; 131773fd2728SCaroline Tice 131873fd2728SCaroline Tice int num_entries = root->m_settings.global_settings.size(); 131973fd2728SCaroline Tice 132073fd2728SCaroline Tice if (num_entries > 0) 132173fd2728SCaroline Tice { 132273fd2728SCaroline Tice for (int i = 0; i < num_entries; ++i) 132373fd2728SCaroline Tice { 1324*bfe5f3bfSGreg Clayton const SettingEntry &entry = root->m_settings.global_settings[i]; 132573fd2728SCaroline Tice if (strcasestr (entry.description, search_word) != NULL) 132673fd2728SCaroline Tice { 132773fd2728SCaroline Tice StreamString var_name; 132873fd2728SCaroline Tice if (current_prefix.size() > 0) 132973fd2728SCaroline Tice var_name.Printf ("%s.%s", current_prefix.c_str(), entry.var_name); 133073fd2728SCaroline Tice else 133173fd2728SCaroline Tice var_name.Printf ("%s", entry.var_name); 133273fd2728SCaroline Tice interpreter.OutputFormattedHelpText (result_stream, var_name.GetData(), "--", entry.description, 133373fd2728SCaroline Tice var_name.GetSize()); 133473fd2728SCaroline Tice } 133573fd2728SCaroline Tice } 133673fd2728SCaroline Tice } 133773fd2728SCaroline Tice 133873fd2728SCaroline Tice num_entries = root->m_settings.instance_settings.size(); 133973fd2728SCaroline Tice if (num_entries > 0) 134073fd2728SCaroline Tice { 134173fd2728SCaroline Tice for (int i = 0; i < num_entries; ++i) 134273fd2728SCaroline Tice { 134373fd2728SCaroline Tice SettingEntry &entry = root->m_settings.instance_settings[i]; 134473fd2728SCaroline Tice if (strcasestr (entry.description, search_word) != NULL) 134573fd2728SCaroline Tice { 134673fd2728SCaroline Tice StreamString var_name; 134773fd2728SCaroline Tice if (current_prefix.size() > 0) 134873fd2728SCaroline Tice var_name.Printf ("%s.%s", current_prefix.c_str(), entry.var_name); 134973fd2728SCaroline Tice else 135073fd2728SCaroline Tice var_name.Printf ("%s", entry.var_name); 135173fd2728SCaroline Tice interpreter.OutputFormattedHelpText (result_stream, var_name.GetData(), "--", entry.description, 135273fd2728SCaroline Tice var_name.GetSize()); 135373fd2728SCaroline Tice } 135473fd2728SCaroline Tice } 135573fd2728SCaroline Tice } 135673fd2728SCaroline Tice 135773fd2728SCaroline Tice int num_children = root->GetNumChildren (); 135873fd2728SCaroline Tice for (int i = 0; i < num_children; ++i) 135973fd2728SCaroline Tice { 1360*bfe5f3bfSGreg Clayton UserSettingsControllerSP child = root->GetChildAtIndex (i); 136173fd2728SCaroline Tice 136273fd2728SCaroline Tice if (child) 136373fd2728SCaroline Tice { 136473fd2728SCaroline Tice ConstString child_prefix = child->GetLevelName(); 136573fd2728SCaroline Tice StreamString new_prefix; 136673fd2728SCaroline Tice if (! current_prefix.empty()) 136773fd2728SCaroline Tice new_prefix.Printf ("%s.%s", current_prefix.c_str(), child_prefix.AsCString()); 136873fd2728SCaroline Tice else 136973fd2728SCaroline Tice new_prefix.Printf ("%s", child_prefix.AsCString()); 137073fd2728SCaroline Tice std::string new_prefix_str = new_prefix.GetData(); 137173fd2728SCaroline Tice UserSettingsController::SearchAllSettingsDescriptions (interpreter, child, new_prefix_str, search_word, 137273fd2728SCaroline Tice result_stream); 137373fd2728SCaroline Tice } 137473fd2728SCaroline Tice } 137573fd2728SCaroline Tice } 137673fd2728SCaroline Tice 137773fd2728SCaroline Tice void 13783df9a8dfSCaroline Tice UserSettingsController::GetAllVariableValues (CommandInterpreter &interpreter, 1379*bfe5f3bfSGreg Clayton UserSettingsControllerSP root, 13803df9a8dfSCaroline Tice std::string ¤t_prefix, 13813df9a8dfSCaroline Tice StreamString &result_stream, 13823df9a8dfSCaroline Tice Error &err) 13833df9a8dfSCaroline Tice { 13843df9a8dfSCaroline Tice StreamString description; 13853df9a8dfSCaroline Tice int num_entries = root->m_settings.global_settings.size(); 1386*bfe5f3bfSGreg Clayton SettableVariableType var_type; 13873df9a8dfSCaroline Tice 13883df9a8dfSCaroline Tice 13893df9a8dfSCaroline Tice for (int i = 0; i < num_entries; ++i) 13903df9a8dfSCaroline Tice { 13913df9a8dfSCaroline Tice StreamString full_var_name; 1392*bfe5f3bfSGreg Clayton const SettingEntry &entry = root->m_settings.global_settings[i]; 1393ded2fa39SCaroline Tice if (! current_prefix.empty()) 13943df9a8dfSCaroline Tice full_var_name.Printf ("%s.%s", current_prefix.c_str(), entry.var_name); 13953df9a8dfSCaroline Tice else 13963df9a8dfSCaroline Tice full_var_name.Printf ("%s", entry.var_name); 1397101c7c20SCaroline Tice StringList value = root->GetVariable (full_var_name.GetData(), var_type, 1398daccaa9eSCaroline Tice interpreter.GetDebugger().GetInstanceName().AsCString(), err); 13993df9a8dfSCaroline Tice description.Clear(); 14003df9a8dfSCaroline Tice if (value.GetSize() == 1) 140149e2737eSCaroline Tice description.Printf ("%s (%s) = '%s'", full_var_name.GetData(), GetTypeString (entry.var_type), 14023df9a8dfSCaroline Tice value.GetStringAtIndex (0)); 14033df9a8dfSCaroline Tice else 14043df9a8dfSCaroline Tice { 14052d5289d6SCaroline Tice description.Printf ("%s (%s):\n", full_var_name.GetData(), GetTypeString (entry.var_type)); 14063df9a8dfSCaroline Tice for (int j = 0; j < value.GetSize(); ++j) 1407*bfe5f3bfSGreg Clayton if (entry.var_type == eSetVarTypeArray) 14082d5289d6SCaroline Tice description.Printf (" [%d]: '%s'\n", j, value.GetStringAtIndex (j)); 1409*bfe5f3bfSGreg Clayton else if (entry.var_type == eSetVarTypeDictionary) 14102d5289d6SCaroline Tice description.Printf (" '%s'\n", value.GetStringAtIndex (j)); 14113df9a8dfSCaroline Tice } 14123df9a8dfSCaroline Tice 14133df9a8dfSCaroline Tice result_stream.Printf ("%s\n", description.GetData()); 14143df9a8dfSCaroline Tice } 14153df9a8dfSCaroline Tice 14163df9a8dfSCaroline Tice root->GetAllInstanceVariableValues (interpreter, result_stream); 14173df9a8dfSCaroline Tice root->GetAllPendingSettingValues (result_stream); 1418101c7c20SCaroline Tice if (root->GetLevelName().GetLength() > 0) // Don't bother with default values for Debugger level. 14193df9a8dfSCaroline Tice root->GetAllDefaultSettingValues (result_stream); 14203df9a8dfSCaroline Tice 14213df9a8dfSCaroline Tice 14223df9a8dfSCaroline Tice // Now, recurse across all children. 14233df9a8dfSCaroline Tice int num_children = root->GetNumChildren(); 14243df9a8dfSCaroline Tice for (int i = 0; i < num_children; ++i) 14253df9a8dfSCaroline Tice { 1426*bfe5f3bfSGreg Clayton UserSettingsControllerSP child = root->GetChildAtIndex (i); 14273df9a8dfSCaroline Tice 14283df9a8dfSCaroline Tice if (child) 14293df9a8dfSCaroline Tice { 14303df9a8dfSCaroline Tice ConstString child_prefix = child->GetLevelName(); 14313df9a8dfSCaroline Tice StreamString new_prefix; 1432ded2fa39SCaroline Tice if (! current_prefix.empty()) 14333df9a8dfSCaroline Tice new_prefix.Printf ("%s.%s", current_prefix.c_str(), child_prefix.AsCString()); 14343df9a8dfSCaroline Tice else 14353df9a8dfSCaroline Tice new_prefix.Printf ("%s", child_prefix.AsCString()); 14363df9a8dfSCaroline Tice std::string new_prefix_str = new_prefix.GetData(); 14373df9a8dfSCaroline Tice UserSettingsController::GetAllVariableValues (interpreter, child, new_prefix_str, result_stream, 14383df9a8dfSCaroline Tice err); 14393df9a8dfSCaroline Tice } 14403df9a8dfSCaroline Tice } 14413df9a8dfSCaroline Tice 14423df9a8dfSCaroline Tice } 14433df9a8dfSCaroline Tice 14443df9a8dfSCaroline Tice Args 14453df9a8dfSCaroline Tice UserSettingsController::BreakNameIntoPieces (const char *full_dot_name) 14463df9a8dfSCaroline Tice { 14473df9a8dfSCaroline Tice Args return_value; 14483df9a8dfSCaroline Tice std::string name_string (full_dot_name); 14493df9a8dfSCaroline Tice bool done = false; 14503df9a8dfSCaroline Tice 14513df9a8dfSCaroline Tice std::string piece; 14523df9a8dfSCaroline Tice std::string remainder (full_dot_name); 14533df9a8dfSCaroline Tice 14543df9a8dfSCaroline Tice while (!done) 14553df9a8dfSCaroline Tice { 14563df9a8dfSCaroline Tice size_t idx = remainder.find_first_of ('.'); 14573df9a8dfSCaroline Tice piece = remainder.substr (0, idx); 14583df9a8dfSCaroline Tice return_value.AppendArgument (piece.c_str()); 14593df9a8dfSCaroline Tice if (idx != std::string::npos) 14603df9a8dfSCaroline Tice remainder = remainder.substr (idx+1); 14613df9a8dfSCaroline Tice else 14623df9a8dfSCaroline Tice done = true; 14633df9a8dfSCaroline Tice } 14643df9a8dfSCaroline Tice 14653df9a8dfSCaroline Tice return return_value; 14663df9a8dfSCaroline Tice } 14673df9a8dfSCaroline Tice 14683df9a8dfSCaroline Tice bool 14693df9a8dfSCaroline Tice UserSettingsController::IsLiveInstance (const std::string &instance_name) 14703df9a8dfSCaroline Tice { 14713df9a8dfSCaroline Tice std::map<std::string, InstanceSettings *>::iterator pos; 14723df9a8dfSCaroline Tice 14733df9a8dfSCaroline Tice pos = m_live_settings.find (instance_name); 14743df9a8dfSCaroline Tice if (pos != m_live_settings.end()) 14753df9a8dfSCaroline Tice return true; 14763df9a8dfSCaroline Tice 14773df9a8dfSCaroline Tice return false; 14783df9a8dfSCaroline Tice } 14793df9a8dfSCaroline Tice 14803df9a8dfSCaroline Tice int 1481*bfe5f3bfSGreg Clayton UserSettingsController::CompleteSettingsValue (UserSettingsControllerSP root_settings, 14823df9a8dfSCaroline Tice const char *full_dot_name, 14833df9a8dfSCaroline Tice const char *partial_value, 14843df9a8dfSCaroline Tice bool &word_complete, 14853df9a8dfSCaroline Tice StringList &matches) 14863df9a8dfSCaroline Tice { 14873df9a8dfSCaroline Tice Args names = UserSettingsController::BreakNameIntoPieces (full_dot_name); 14883df9a8dfSCaroline Tice int num_pieces = names.GetArgumentCount(); 14893df9a8dfSCaroline Tice word_complete = true; 14903df9a8dfSCaroline Tice 14913df9a8dfSCaroline Tice ConstString root_level = root_settings->GetLevelName(); 14923df9a8dfSCaroline Tice int num_extra_levels = num_pieces - 2; 14933df9a8dfSCaroline Tice if ((num_extra_levels > 0) 14943df9a8dfSCaroline Tice && root_level.GetLength() > 0) 14953df9a8dfSCaroline Tice { 14963df9a8dfSCaroline Tice ConstString current_level (names.GetArgumentAtIndex (0)); 14973df9a8dfSCaroline Tice if (current_level == root_level) 14983df9a8dfSCaroline Tice { 14993df9a8dfSCaroline Tice names.Shift(); 15003df9a8dfSCaroline Tice --num_extra_levels; 15013df9a8dfSCaroline Tice } 15023df9a8dfSCaroline Tice else 15033df9a8dfSCaroline Tice return 0; 15043df9a8dfSCaroline Tice } 15053df9a8dfSCaroline Tice 15063df9a8dfSCaroline Tice for (int i = 0; i < num_extra_levels; ++i) 15073df9a8dfSCaroline Tice { 15083df9a8dfSCaroline Tice ConstString child_level (names.GetArgumentAtIndex (0)); 15093df9a8dfSCaroline Tice bool found = false; 15103df9a8dfSCaroline Tice int num_children = root_settings->GetNumChildren(); 15113df9a8dfSCaroline Tice for (int j = 0; j < num_children && !found; ++j) 15123df9a8dfSCaroline Tice { 15133df9a8dfSCaroline Tice if (root_settings->GetChildAtIndex (j)->GetLevelName() == child_level) 15143df9a8dfSCaroline Tice { 15153df9a8dfSCaroline Tice found = true; 15163df9a8dfSCaroline Tice root_settings = root_settings->GetChildAtIndex (j); 15173df9a8dfSCaroline Tice names.Shift(); 15183df9a8dfSCaroline Tice } 15193df9a8dfSCaroline Tice } 15203df9a8dfSCaroline Tice if (!found) 15213df9a8dfSCaroline Tice return 0; 15223df9a8dfSCaroline Tice } 15233df9a8dfSCaroline Tice 15243df9a8dfSCaroline Tice if (names.GetArgumentCount() != 2) 15253df9a8dfSCaroline Tice return 0; 15263df9a8dfSCaroline Tice 15273df9a8dfSCaroline Tice std::string next_name (names.GetArgumentAtIndex (0)); 15283df9a8dfSCaroline Tice int len = next_name.length(); 15293df9a8dfSCaroline Tice names.Shift(); 15303df9a8dfSCaroline Tice 15313df9a8dfSCaroline Tice if ((next_name[0] == '[') && (next_name[len-1] == ']')) 15323df9a8dfSCaroline Tice { 15333df9a8dfSCaroline Tice // 'next_name' is instance name. Instance names are irrelevent here. 15343df9a8dfSCaroline Tice } 15353df9a8dfSCaroline Tice else 15363df9a8dfSCaroline Tice { 15373df9a8dfSCaroline Tice // 'next_name' is child name. 15383df9a8dfSCaroline Tice bool found = false; 15393df9a8dfSCaroline Tice int num_children = root_settings->GetNumChildren(); 15403df9a8dfSCaroline Tice ConstString child_level (next_name.c_str()); 15413df9a8dfSCaroline Tice for (int j = 0; j < num_children && !found; ++j) 15423df9a8dfSCaroline Tice { 15433df9a8dfSCaroline Tice if (root_settings->GetChildAtIndex (j)->GetLevelName() == child_level) 15443df9a8dfSCaroline Tice { 15453df9a8dfSCaroline Tice found = true; 15463df9a8dfSCaroline Tice root_settings = root_settings->GetChildAtIndex (j); 15473df9a8dfSCaroline Tice } 15483df9a8dfSCaroline Tice } 15493df9a8dfSCaroline Tice if (!found) 15503df9a8dfSCaroline Tice return 0; 15513df9a8dfSCaroline Tice } 15523df9a8dfSCaroline Tice 15533df9a8dfSCaroline Tice ConstString var_name (names.GetArgumentAtIndex(0)); 15543df9a8dfSCaroline Tice const SettingEntry *entry = root_settings->GetGlobalEntry (var_name); 15553df9a8dfSCaroline Tice if (entry == NULL) 15563df9a8dfSCaroline Tice entry = root_settings->GetInstanceEntry (var_name); 15573df9a8dfSCaroline Tice 15583df9a8dfSCaroline Tice if (entry == NULL) 15593df9a8dfSCaroline Tice return 0; 15603df9a8dfSCaroline Tice 1561*bfe5f3bfSGreg Clayton if (entry->var_type == eSetVarTypeBoolean) 15623df9a8dfSCaroline Tice return UserSettingsController::BooleanMatches (partial_value, word_complete, matches); 1563*bfe5f3bfSGreg Clayton else if (entry->var_type == eSetVarTypeEnum) 15643df9a8dfSCaroline Tice return UserSettingsController::EnumMatches (partial_value, entry->enum_values, word_complete, matches); 15653df9a8dfSCaroline Tice else 15663df9a8dfSCaroline Tice return 0; 15673df9a8dfSCaroline Tice } 15683df9a8dfSCaroline Tice 15693df9a8dfSCaroline Tice int 15703df9a8dfSCaroline Tice UserSettingsController::BooleanMatches (const char *partial_value, 15713df9a8dfSCaroline Tice bool &word_complete, 15723df9a8dfSCaroline Tice StringList &matches) 15733df9a8dfSCaroline Tice { 15743df9a8dfSCaroline Tice static const std::string true_string ("true"); 15753df9a8dfSCaroline Tice static const std::string false_string ("false"); 15763df9a8dfSCaroline Tice 15773df9a8dfSCaroline Tice if (partial_value == NULL) 15783df9a8dfSCaroline Tice { 15793df9a8dfSCaroline Tice matches.AppendString ("true"); 15803df9a8dfSCaroline Tice matches.AppendString ("false"); 15813df9a8dfSCaroline Tice } 15823df9a8dfSCaroline Tice else 15833df9a8dfSCaroline Tice { 15843df9a8dfSCaroline Tice int partial_len = strlen (partial_value); 15853df9a8dfSCaroline Tice 15863df9a8dfSCaroline Tice if ((partial_len <= true_string.length()) 15873df9a8dfSCaroline Tice && (true_string.find (partial_value) == 0)) 15883df9a8dfSCaroline Tice matches.AppendString ("true"); 15893df9a8dfSCaroline Tice else if ((partial_len <= false_string.length()) 15903df9a8dfSCaroline Tice && (false_string.find (partial_value) == 0)) 15913df9a8dfSCaroline Tice matches.AppendString ("false"); 15923df9a8dfSCaroline Tice } 15933df9a8dfSCaroline Tice 15943df9a8dfSCaroline Tice word_complete = false; 15953df9a8dfSCaroline Tice if (matches.GetSize() == 1) 15963df9a8dfSCaroline Tice word_complete = true; 15973df9a8dfSCaroline Tice 15983df9a8dfSCaroline Tice return matches.GetSize(); 15993df9a8dfSCaroline Tice } 16003df9a8dfSCaroline Tice 16013df9a8dfSCaroline Tice int 16023df9a8dfSCaroline Tice UserSettingsController::EnumMatches (const char *partial_value, 1603*bfe5f3bfSGreg Clayton OptionEnumValueElement *enum_values, 16043df9a8dfSCaroline Tice bool &word_complete, 16053df9a8dfSCaroline Tice StringList &matches) 16063df9a8dfSCaroline Tice { 16073df9a8dfSCaroline Tice int len = (partial_value != NULL) ? strlen (partial_value) : 0; 16083df9a8dfSCaroline Tice 16093df9a8dfSCaroline Tice int i = 0; 16103df9a8dfSCaroline Tice while (enum_values[i].string_value != NULL) 16113df9a8dfSCaroline Tice { 16123df9a8dfSCaroline Tice if (len == 0) 16133df9a8dfSCaroline Tice matches.AppendString (enum_values[i].string_value); 16143df9a8dfSCaroline Tice else 16153df9a8dfSCaroline Tice { 16163df9a8dfSCaroline Tice std::string tmp_value (enum_values[i].string_value); 16173df9a8dfSCaroline Tice if ((len <= tmp_value.length()) 16183df9a8dfSCaroline Tice && tmp_value.find (partial_value) == 0) 16193df9a8dfSCaroline Tice matches.AppendString (enum_values[i].string_value); 16203df9a8dfSCaroline Tice } 16213df9a8dfSCaroline Tice ++i; 16223df9a8dfSCaroline Tice } 16233df9a8dfSCaroline Tice 16243df9a8dfSCaroline Tice word_complete = false; 16253df9a8dfSCaroline Tice if (matches.GetSize() == 1) 16263df9a8dfSCaroline Tice word_complete = true; 16273df9a8dfSCaroline Tice 16283df9a8dfSCaroline Tice return matches.GetSize(); 16293df9a8dfSCaroline Tice } 16303df9a8dfSCaroline Tice 16313df9a8dfSCaroline Tice int 1632*bfe5f3bfSGreg Clayton UserSettingsController::CompleteSettingsNames (UserSettingsControllerSP root_settings, 16333df9a8dfSCaroline Tice Args &partial_setting_name_pieces, 16343df9a8dfSCaroline Tice bool &word_complete, 16353df9a8dfSCaroline Tice StringList &matches) 16363df9a8dfSCaroline Tice { 16373df9a8dfSCaroline Tice int num_matches = 0; 16383df9a8dfSCaroline Tice int num_name_pieces = partial_setting_name_pieces.GetArgumentCount(); 16393df9a8dfSCaroline Tice 16403df9a8dfSCaroline Tice if (num_name_pieces > 1) 16413df9a8dfSCaroline Tice { 16423df9a8dfSCaroline Tice // There are at least two pieces, perhaps with multiple level names preceding them. 16433df9a8dfSCaroline Tice // First traverse all the extra levels, until we have exactly two pieces left. 16443df9a8dfSCaroline Tice 16453df9a8dfSCaroline Tice int num_extra_levels = num_name_pieces - 2; 16463df9a8dfSCaroline Tice 16473df9a8dfSCaroline Tice // Deal with current level first. 16483df9a8dfSCaroline Tice 16493df9a8dfSCaroline Tice ConstString root_level = root_settings->GetLevelName(); 16503df9a8dfSCaroline Tice if ((num_extra_levels > 0) 16513df9a8dfSCaroline Tice && (root_level.GetLength() > 0)) 16523df9a8dfSCaroline Tice { 16533df9a8dfSCaroline Tice ConstString current_level (partial_setting_name_pieces.GetArgumentAtIndex (0)); 16543df9a8dfSCaroline Tice if (current_level == root_level) 16553df9a8dfSCaroline Tice { 16563df9a8dfSCaroline Tice partial_setting_name_pieces.Shift(); 16573df9a8dfSCaroline Tice --num_extra_levels; 16583df9a8dfSCaroline Tice } 16593df9a8dfSCaroline Tice else 16603df9a8dfSCaroline Tice return 0; // The current level did not match the name pieces; something is wrong, so return immediately 16613df9a8dfSCaroline Tice 16623df9a8dfSCaroline Tice } 16633df9a8dfSCaroline Tice 16643df9a8dfSCaroline Tice for (int i = 0; i < num_extra_levels; ++i) 16653df9a8dfSCaroline Tice { 16663df9a8dfSCaroline Tice ConstString child_level (partial_setting_name_pieces.GetArgumentAtIndex (0)); 16673df9a8dfSCaroline Tice bool found = false; 16683df9a8dfSCaroline Tice int num_children = root_settings->GetNumChildren(); 16693df9a8dfSCaroline Tice for (int j = 0; j < num_children && !found; ++j) 16703df9a8dfSCaroline Tice { 16713df9a8dfSCaroline Tice if (root_settings->GetChildAtIndex (j)->GetLevelName() == child_level) 16723df9a8dfSCaroline Tice { 16733df9a8dfSCaroline Tice found = true; 16743df9a8dfSCaroline Tice root_settings = root_settings->GetChildAtIndex (j); 16753df9a8dfSCaroline Tice partial_setting_name_pieces.Shift(); 16763df9a8dfSCaroline Tice } 16773df9a8dfSCaroline Tice } 16783df9a8dfSCaroline Tice if (! found) 16793df9a8dfSCaroline Tice { 16803df9a8dfSCaroline Tice return 0; // Unable to find a matching child level name; something is wrong, so return immediately. 16813df9a8dfSCaroline Tice } 16823df9a8dfSCaroline Tice } 16833df9a8dfSCaroline Tice 16843df9a8dfSCaroline Tice // Now there should be exactly two name pieces left. If not there is an error, so return immediately 16853df9a8dfSCaroline Tice 16863df9a8dfSCaroline Tice if (partial_setting_name_pieces.GetArgumentCount() != 2) 16873df9a8dfSCaroline Tice return 0; 16883df9a8dfSCaroline Tice 16893df9a8dfSCaroline Tice std::string next_name (partial_setting_name_pieces.GetArgumentAtIndex (0)); 16903df9a8dfSCaroline Tice int len = next_name.length(); 16913df9a8dfSCaroline Tice partial_setting_name_pieces.Shift(); 16923df9a8dfSCaroline Tice 16933df9a8dfSCaroline Tice if ((next_name[0] == '[') && (next_name[len-1] == ']')) 16943df9a8dfSCaroline Tice { 16953df9a8dfSCaroline Tice // 'next_name' is an instance name. The last name piece must be a non-empty partial match against an 16963df9a8dfSCaroline Tice // instance_name, assuming 'next_name' is valid. 16973df9a8dfSCaroline Tice 16983df9a8dfSCaroline Tice if (root_settings->IsLiveInstance (next_name)) 16993df9a8dfSCaroline Tice { 17003df9a8dfSCaroline Tice std::string complete_prefix; 17013df9a8dfSCaroline Tice root_settings->BuildParentPrefix (complete_prefix); 17023df9a8dfSCaroline Tice 17033df9a8dfSCaroline Tice num_matches = root_settings->InstanceVariableMatches(partial_setting_name_pieces.GetArgumentAtIndex(0), 17043df9a8dfSCaroline Tice complete_prefix, 17053df9a8dfSCaroline Tice next_name.c_str(), 17063df9a8dfSCaroline Tice matches); 17073df9a8dfSCaroline Tice word_complete = true; 17083df9a8dfSCaroline Tice if (num_matches > 1) 17093df9a8dfSCaroline Tice word_complete = false; 17103df9a8dfSCaroline Tice 17113df9a8dfSCaroline Tice return num_matches; 17123df9a8dfSCaroline Tice } 17133df9a8dfSCaroline Tice else 17143df9a8dfSCaroline Tice return 0; // Invalid instance_name 17153df9a8dfSCaroline Tice } 17163df9a8dfSCaroline Tice else 17173df9a8dfSCaroline Tice { 17183df9a8dfSCaroline Tice // 'next_name' must be a child name. Find the correct child and pass the remaining piece to be resolved. 17193df9a8dfSCaroline Tice bool found = false; 17203df9a8dfSCaroline Tice int num_children = root_settings->GetNumChildren(); 17213df9a8dfSCaroline Tice ConstString child_level (next_name.c_str()); 17223df9a8dfSCaroline Tice for (int i = 0; i < num_children; ++i) 17233df9a8dfSCaroline Tice { 17243df9a8dfSCaroline Tice if (root_settings->GetChildAtIndex (i)->GetLevelName() == child_level) 17253df9a8dfSCaroline Tice { 17263df9a8dfSCaroline Tice found = true; 17273df9a8dfSCaroline Tice return UserSettingsController::CompleteSettingsNames (root_settings->GetChildAtIndex (i), 17283df9a8dfSCaroline Tice partial_setting_name_pieces, 17293df9a8dfSCaroline Tice word_complete, matches); 17303df9a8dfSCaroline Tice } 17313df9a8dfSCaroline Tice } 17323df9a8dfSCaroline Tice if (!found) 17333df9a8dfSCaroline Tice return 0; 17343df9a8dfSCaroline Tice } 17353df9a8dfSCaroline Tice } 17363df9a8dfSCaroline Tice else if (num_name_pieces == 1) 17373df9a8dfSCaroline Tice { 17383df9a8dfSCaroline Tice std::string complete_prefix; 17393df9a8dfSCaroline Tice root_settings->BuildParentPrefix (complete_prefix); 17403df9a8dfSCaroline Tice 17413df9a8dfSCaroline Tice word_complete = true; 17423df9a8dfSCaroline Tice std::string name (partial_setting_name_pieces.GetArgumentAtIndex (0)); 17433df9a8dfSCaroline Tice 17443df9a8dfSCaroline Tice if (name[0] == '[') 17453df9a8dfSCaroline Tice { 17463df9a8dfSCaroline Tice // It's a partial instance name. 17473df9a8dfSCaroline Tice 17483df9a8dfSCaroline Tice num_matches = root_settings->LiveInstanceMatches (name.c_str(), complete_prefix, word_complete, matches); 17493df9a8dfSCaroline Tice } 17503df9a8dfSCaroline Tice else 17513df9a8dfSCaroline Tice { 17523df9a8dfSCaroline Tice // It could be anything *except* an instance name... 17533df9a8dfSCaroline Tice 17543df9a8dfSCaroline Tice num_matches = root_settings->GlobalVariableMatches (name.c_str(), complete_prefix, matches); 17553df9a8dfSCaroline Tice num_matches += root_settings->InstanceVariableMatches (name.c_str(), complete_prefix, NULL, matches); 17563df9a8dfSCaroline Tice num_matches += root_settings->ChildMatches (name.c_str(), complete_prefix, word_complete, matches); 17573df9a8dfSCaroline Tice } 17583df9a8dfSCaroline Tice 17593df9a8dfSCaroline Tice if (num_matches > 1) 17603df9a8dfSCaroline Tice word_complete = false; 17613df9a8dfSCaroline Tice 17623df9a8dfSCaroline Tice return num_matches; 17633df9a8dfSCaroline Tice } 17643df9a8dfSCaroline Tice else 17653df9a8dfSCaroline Tice { 17663df9a8dfSCaroline Tice // We have a user settings controller with a blank partial string. Return everything possible at this level. 17673df9a8dfSCaroline Tice 17683df9a8dfSCaroline Tice std::string complete_prefix; 17693df9a8dfSCaroline Tice root_settings->BuildParentPrefix (complete_prefix); 17703df9a8dfSCaroline Tice num_matches = root_settings->GlobalVariableMatches (NULL, complete_prefix, matches); 17713df9a8dfSCaroline Tice num_matches += root_settings->InstanceVariableMatches (NULL, complete_prefix, NULL, matches); 17723df9a8dfSCaroline Tice num_matches += root_settings->LiveInstanceMatches (NULL, complete_prefix, word_complete, matches); 17733df9a8dfSCaroline Tice num_matches += root_settings->ChildMatches (NULL, complete_prefix, word_complete, matches); 17743df9a8dfSCaroline Tice word_complete = false; 17753df9a8dfSCaroline Tice return num_matches; 17763df9a8dfSCaroline Tice } 17773df9a8dfSCaroline Tice 17783df9a8dfSCaroline Tice return num_matches; 17793df9a8dfSCaroline Tice } 17803df9a8dfSCaroline Tice 17813df9a8dfSCaroline Tice int 17823df9a8dfSCaroline Tice UserSettingsController::GlobalVariableMatches (const char *partial_name, 17833df9a8dfSCaroline Tice const std::string &complete_prefix, 17843df9a8dfSCaroline Tice StringList &matches) 17853df9a8dfSCaroline Tice { 17863df9a8dfSCaroline Tice int partial_len = (partial_name != NULL) ? strlen (partial_name) : 0; 17873df9a8dfSCaroline Tice int num_matches = 0; 17883df9a8dfSCaroline Tice 17893df9a8dfSCaroline Tice for (size_t i = 0; i < m_settings.global_settings.size(); ++i) 17903df9a8dfSCaroline Tice { 1791*bfe5f3bfSGreg Clayton const SettingEntry &entry = m_settings.global_settings[i]; 17923df9a8dfSCaroline Tice std::string var_name (entry.var_name); 17933df9a8dfSCaroline Tice if ((partial_len == 0) 17943df9a8dfSCaroline Tice || ((partial_len <= var_name.length()) 17953df9a8dfSCaroline Tice && (var_name.find (partial_name) == 0))) 17963df9a8dfSCaroline Tice { 17973df9a8dfSCaroline Tice StreamString match_name; 17983df9a8dfSCaroline Tice if (complete_prefix.length() > 0) 17993df9a8dfSCaroline Tice { 18003df9a8dfSCaroline Tice match_name.Printf ("%s.%s", complete_prefix.c_str(), var_name.c_str()); 18013df9a8dfSCaroline Tice matches.AppendString (match_name.GetData()); 18023df9a8dfSCaroline Tice } 18033df9a8dfSCaroline Tice else 18043df9a8dfSCaroline Tice matches.AppendString (var_name.c_str()); 18053df9a8dfSCaroline Tice ++num_matches; 18063df9a8dfSCaroline Tice } 18073df9a8dfSCaroline Tice } 18083df9a8dfSCaroline Tice return num_matches; 18093df9a8dfSCaroline Tice } 18103df9a8dfSCaroline Tice 18113df9a8dfSCaroline Tice int 18123df9a8dfSCaroline Tice UserSettingsController::InstanceVariableMatches (const char *partial_name, 18133df9a8dfSCaroline Tice const std::string &complete_prefix, 18143df9a8dfSCaroline Tice const char *instance_name, 18153df9a8dfSCaroline Tice StringList &matches) 18163df9a8dfSCaroline Tice { 18173df9a8dfSCaroline Tice int partial_len = (partial_name != NULL) ? strlen (partial_name) : 0; 18183df9a8dfSCaroline Tice int num_matches = 0; 18193df9a8dfSCaroline Tice 18203df9a8dfSCaroline Tice for (size_t i = 0; i < m_settings.instance_settings.size(); ++i) 18213df9a8dfSCaroline Tice { 18223df9a8dfSCaroline Tice SettingEntry &entry = m_settings.instance_settings[i]; 18233df9a8dfSCaroline Tice std::string var_name (entry.var_name); 18243df9a8dfSCaroline Tice if ((partial_len == 0) 18253df9a8dfSCaroline Tice || ((partial_len <= var_name.length()) 18263df9a8dfSCaroline Tice && (var_name.find (partial_name) == 0))) 18273df9a8dfSCaroline Tice { 18283df9a8dfSCaroline Tice StreamString match_name; 18293df9a8dfSCaroline Tice if (complete_prefix.length() > 0) 18303df9a8dfSCaroline Tice { 18313df9a8dfSCaroline Tice if (instance_name != NULL) 18323df9a8dfSCaroline Tice match_name.Printf ("%s.%s.%s", complete_prefix.c_str(), instance_name, var_name.c_str()); 18333df9a8dfSCaroline Tice else 18343df9a8dfSCaroline Tice match_name.Printf ("%s.%s", complete_prefix.c_str(), var_name.c_str()); 18353df9a8dfSCaroline Tice 18363df9a8dfSCaroline Tice matches.AppendString (match_name.GetData()); 18373df9a8dfSCaroline Tice } 18383df9a8dfSCaroline Tice else 18393df9a8dfSCaroline Tice { 18403df9a8dfSCaroline Tice if (instance_name != NULL) 18413df9a8dfSCaroline Tice { 18423df9a8dfSCaroline Tice match_name.Printf ("%s.%s", instance_name, var_name.c_str()); 18433df9a8dfSCaroline Tice matches.AppendString (match_name.GetData()); 18443df9a8dfSCaroline Tice } 18453df9a8dfSCaroline Tice else 18463df9a8dfSCaroline Tice matches.AppendString (var_name.c_str()); 18473df9a8dfSCaroline Tice } 18483df9a8dfSCaroline Tice ++num_matches; 18493df9a8dfSCaroline Tice } 18503df9a8dfSCaroline Tice } 18513df9a8dfSCaroline Tice return num_matches; 18523df9a8dfSCaroline Tice } 18533df9a8dfSCaroline Tice 18543df9a8dfSCaroline Tice int 18553df9a8dfSCaroline Tice UserSettingsController::LiveInstanceMatches (const char *partial_name, 18563df9a8dfSCaroline Tice const std::string &complete_prefix, 18573df9a8dfSCaroline Tice bool &word_complete, 18583df9a8dfSCaroline Tice StringList &matches) 18593df9a8dfSCaroline Tice { 18603df9a8dfSCaroline Tice int partial_len = (partial_name != NULL) ? strlen (partial_name) : 0; 18613df9a8dfSCaroline Tice int num_matches = 0; 18623df9a8dfSCaroline Tice 18633df9a8dfSCaroline Tice std::map<std::string, InstanceSettings*>::iterator pos; 18643df9a8dfSCaroline Tice for (pos = m_live_settings.begin(); pos != m_live_settings.end(); ++pos) 18653df9a8dfSCaroline Tice { 18663df9a8dfSCaroline Tice std::string instance_name = pos->first; 18673df9a8dfSCaroline Tice if ((partial_len == 0) 18683df9a8dfSCaroline Tice || ((partial_len <= instance_name.length()) 18693df9a8dfSCaroline Tice && (instance_name.find (partial_name) == 0))) 18703df9a8dfSCaroline Tice { 18713df9a8dfSCaroline Tice StreamString match_name; 18723df9a8dfSCaroline Tice if (complete_prefix.length() > 0) 18733df9a8dfSCaroline Tice match_name.Printf ("%s.%s.", complete_prefix.c_str(), instance_name.c_str()); 18743df9a8dfSCaroline Tice else 18753df9a8dfSCaroline Tice match_name.Printf ("%s.", instance_name.c_str()); 18763df9a8dfSCaroline Tice matches.AppendString (match_name.GetData()); 18773df9a8dfSCaroline Tice ++num_matches; 18783df9a8dfSCaroline Tice } 18793df9a8dfSCaroline Tice } 18803df9a8dfSCaroline Tice 18813df9a8dfSCaroline Tice if (num_matches > 0) 18823df9a8dfSCaroline Tice word_complete = false; 18833df9a8dfSCaroline Tice 18843df9a8dfSCaroline Tice return num_matches; 18853df9a8dfSCaroline Tice } 18863df9a8dfSCaroline Tice 18873df9a8dfSCaroline Tice int 18883df9a8dfSCaroline Tice UserSettingsController::ChildMatches (const char *partial_name, 18893df9a8dfSCaroline Tice const std::string &complete_prefix, 18903df9a8dfSCaroline Tice bool &word_complete, 18913df9a8dfSCaroline Tice StringList &matches) 18923df9a8dfSCaroline Tice { 18933df9a8dfSCaroline Tice int partial_len = (partial_name != NULL) ? strlen (partial_name) : 0; 18943df9a8dfSCaroline Tice int num_children = GetNumChildren(); 18953df9a8dfSCaroline Tice int num_matches = 0; 18963df9a8dfSCaroline Tice for (int i = 0; i < num_children; ++i) 18973df9a8dfSCaroline Tice { 18983df9a8dfSCaroline Tice std::string child_name (GetChildAtIndex(i)->GetLevelName().AsCString()); 18993df9a8dfSCaroline Tice StreamString match_name; 19003df9a8dfSCaroline Tice if ((partial_len == 0) 19013df9a8dfSCaroline Tice || ((partial_len <= child_name.length()) 19023df9a8dfSCaroline Tice && (child_name.find (partial_name) == 0))) 19033df9a8dfSCaroline Tice { 19043df9a8dfSCaroline Tice if (complete_prefix.length() > 0) 19053df9a8dfSCaroline Tice match_name.Printf ("%s.%s.", complete_prefix.c_str(), child_name.c_str()); 19063df9a8dfSCaroline Tice else 19073df9a8dfSCaroline Tice match_name.Printf ("%s.", child_name.c_str()); 19083df9a8dfSCaroline Tice matches.AppendString (match_name.GetData()); 19093df9a8dfSCaroline Tice ++num_matches; 19103df9a8dfSCaroline Tice } 19113df9a8dfSCaroline Tice } 19123df9a8dfSCaroline Tice 19133df9a8dfSCaroline Tice if (num_matches > 0) 19143df9a8dfSCaroline Tice word_complete = false; 19153df9a8dfSCaroline Tice 19163df9a8dfSCaroline Tice return num_matches; 19173df9a8dfSCaroline Tice } 19183df9a8dfSCaroline Tice 19193df9a8dfSCaroline Tice void 1920*bfe5f3bfSGreg Clayton UserSettingsController::VerifyOperationForType (SettableVariableType var_type, 1921*bfe5f3bfSGreg Clayton VarSetOperationType op, 19223df9a8dfSCaroline Tice const ConstString &var_name, 19233df9a8dfSCaroline Tice Error &err) 19243df9a8dfSCaroline Tice { 1925*bfe5f3bfSGreg Clayton if (op == eVarSetOperationAssign) 19263df9a8dfSCaroline Tice return; 19273df9a8dfSCaroline Tice 19283df9a8dfSCaroline Tice 1929*bfe5f3bfSGreg Clayton if (op == eVarSetOperationInvalid) 19303df9a8dfSCaroline Tice { 19313df9a8dfSCaroline Tice err.SetErrorString ("Invalid 'settings ' subcommand operation.\n"); 19323df9a8dfSCaroline Tice return; 19333df9a8dfSCaroline Tice } 19343df9a8dfSCaroline Tice 19353df9a8dfSCaroline Tice switch (op) 19363df9a8dfSCaroline Tice { 1937*bfe5f3bfSGreg Clayton case eVarSetOperationInsertBefore: 1938*bfe5f3bfSGreg Clayton case eVarSetOperationInsertAfter: 1939*bfe5f3bfSGreg Clayton if (var_type != eSetVarTypeArray) 19403df9a8dfSCaroline Tice err.SetErrorString ("Invalid operation: This operation can only be performed on array variables.\n"); 19413df9a8dfSCaroline Tice break; 1942*bfe5f3bfSGreg Clayton case eVarSetOperationReplace: 1943*bfe5f3bfSGreg Clayton case eVarSetOperationRemove: 1944*bfe5f3bfSGreg Clayton if ((var_type != eSetVarTypeArray) 1945*bfe5f3bfSGreg Clayton && (var_type != eSetVarTypeDictionary)) 19463df9a8dfSCaroline Tice err.SetErrorString ("Invalid operation: This operation can only be performed on array or dictionary" 19473df9a8dfSCaroline Tice " variables.\n"); 19483df9a8dfSCaroline Tice break; 1949*bfe5f3bfSGreg Clayton case eVarSetOperationAppend: 1950*bfe5f3bfSGreg Clayton case eVarSetOperationClear: 1951*bfe5f3bfSGreg Clayton if ((var_type != eSetVarTypeArray) 1952*bfe5f3bfSGreg Clayton && (var_type != eSetVarTypeDictionary) 1953*bfe5f3bfSGreg Clayton && (var_type != eSetVarTypeString)) 19543df9a8dfSCaroline Tice err.SetErrorString ("Invalid operation: This operation can only be performed on array, dictionary " 19553df9a8dfSCaroline Tice "or string variables.\n"); 19563df9a8dfSCaroline Tice break; 19573df9a8dfSCaroline Tice default: 19583df9a8dfSCaroline Tice break; 19593df9a8dfSCaroline Tice } 19603df9a8dfSCaroline Tice 19613df9a8dfSCaroline Tice return; 19623df9a8dfSCaroline Tice } 19633df9a8dfSCaroline Tice 19643df9a8dfSCaroline Tice void 1965*bfe5f3bfSGreg Clayton UserSettingsController::UpdateStringVariable (VarSetOperationType op, 19663df9a8dfSCaroline Tice std::string &string_var, 19673df9a8dfSCaroline Tice const char *new_value, 19683df9a8dfSCaroline Tice Error &err) 19693df9a8dfSCaroline Tice { 1970*bfe5f3bfSGreg Clayton if (op == eVarSetOperationAssign) 1971bd82a5d2SGreg Clayton { 1972bd82a5d2SGreg Clayton if (new_value && new_value[0]) 1973bd82a5d2SGreg Clayton string_var.assign (new_value); 1974bd82a5d2SGreg Clayton else 1975bd82a5d2SGreg Clayton string_var.clear(); 1976bd82a5d2SGreg Clayton } 1977*bfe5f3bfSGreg Clayton else if (op == eVarSetOperationAppend) 1978bd82a5d2SGreg Clayton { 1979bd82a5d2SGreg Clayton if (new_value && new_value[0]) 19803df9a8dfSCaroline Tice string_var.append (new_value); 1981bd82a5d2SGreg Clayton } 1982*bfe5f3bfSGreg Clayton else if (op == eVarSetOperationClear) 19833df9a8dfSCaroline Tice string_var.clear(); 19843df9a8dfSCaroline Tice else 19853df9a8dfSCaroline Tice err.SetErrorString ("Unrecognized operation. Cannot update value.\n"); 19863df9a8dfSCaroline Tice } 19873df9a8dfSCaroline Tice 19883df9a8dfSCaroline Tice void 1989*bfe5f3bfSGreg Clayton UserSettingsController::UpdateBooleanVariable (VarSetOperationType op, 19903df9a8dfSCaroline Tice bool &bool_var, 19913df9a8dfSCaroline Tice const char *new_value, 19923df9a8dfSCaroline Tice Error &err) 19933df9a8dfSCaroline Tice { 1994*bfe5f3bfSGreg Clayton if (op != eVarSetOperationAssign) 19953df9a8dfSCaroline Tice err.SetErrorString ("Invalid operation for Boolean variable. Cannot update value.\n"); 19963df9a8dfSCaroline Tice 1997bd82a5d2SGreg Clayton if (new_value && new_value[0]) 1998bd82a5d2SGreg Clayton { 1999bd82a5d2SGreg Clayton if ((::strcasecmp(new_value, "true") == 0) || 2000bd82a5d2SGreg Clayton (::strcasecmp(new_value, "yes") == 0) || 2001bd82a5d2SGreg Clayton (::strcasecmp(new_value, "on") == 0) || 2002bd82a5d2SGreg Clayton (::strcasecmp(new_value, "1") == 0)) 2003bd82a5d2SGreg Clayton bool_var = true; 2004bd82a5d2SGreg Clayton else 2005bd82a5d2SGreg Clayton if ((::strcasecmp(new_value, "false") == 0) || 2006bd82a5d2SGreg Clayton (::strcasecmp(new_value, "no") == 0) || 2007bd82a5d2SGreg Clayton (::strcasecmp(new_value, "off") == 0) || 2008bd82a5d2SGreg Clayton (::strcasecmp(new_value, "0") == 0)) 2009bd82a5d2SGreg Clayton bool_var = false; 2010bd82a5d2SGreg Clayton else 2011bd82a5d2SGreg Clayton err.SetErrorStringWithFormat ("Invalid boolean value '%s'\n", new_value); 2012bd82a5d2SGreg Clayton } 2013bd82a5d2SGreg Clayton else 20143df9a8dfSCaroline Tice err.SetErrorString ("Invalid value. Cannot perform update.\n"); 20153df9a8dfSCaroline Tice 20163df9a8dfSCaroline Tice } 20173df9a8dfSCaroline Tice 20183df9a8dfSCaroline Tice void 2019*bfe5f3bfSGreg Clayton UserSettingsController::UpdateStringArrayVariable (VarSetOperationType op, 20203df9a8dfSCaroline Tice const char *index_value, 20213df9a8dfSCaroline Tice Args &array_var, 20223df9a8dfSCaroline Tice const char *new_value, 20233df9a8dfSCaroline Tice Error &err) 20243df9a8dfSCaroline Tice { 20253df9a8dfSCaroline Tice int index = -1; 20263df9a8dfSCaroline Tice bool valid_index = true; 20273df9a8dfSCaroline Tice 20283df9a8dfSCaroline Tice if (index_value != NULL) 20293df9a8dfSCaroline Tice { 20303df9a8dfSCaroline Tice for (int i = 0; i < strlen(index_value); ++i) 20313df9a8dfSCaroline Tice if (!isdigit (index_value[i])) 20323df9a8dfSCaroline Tice { 20333df9a8dfSCaroline Tice valid_index = false; 20343df9a8dfSCaroline Tice err.SetErrorStringWithFormat ("'%s' is not a valid integer index. Cannot update array value.\n", 20353df9a8dfSCaroline Tice index_value); 20363df9a8dfSCaroline Tice } 20373df9a8dfSCaroline Tice 20383df9a8dfSCaroline Tice if (valid_index) 20393df9a8dfSCaroline Tice index = atoi (index_value); 20403df9a8dfSCaroline Tice 20413df9a8dfSCaroline Tice if (index < 0 20423df9a8dfSCaroline Tice || index >= array_var.GetArgumentCount()) 20433df9a8dfSCaroline Tice { 20443df9a8dfSCaroline Tice valid_index = false; 20453df9a8dfSCaroline Tice err.SetErrorStringWithFormat ("%d is outside the bounds of the specified array variable. " 20463df9a8dfSCaroline Tice "Cannot update array value.\n", index); 20473df9a8dfSCaroline Tice } 20483df9a8dfSCaroline Tice } 20493df9a8dfSCaroline Tice 20503df9a8dfSCaroline Tice switch (op) 20513df9a8dfSCaroline Tice { 2052*bfe5f3bfSGreg Clayton case eVarSetOperationAssign: 20533df9a8dfSCaroline Tice array_var.SetCommandString (new_value); 20543df9a8dfSCaroline Tice break; 2055*bfe5f3bfSGreg Clayton case eVarSetOperationReplace: 20563df9a8dfSCaroline Tice { 20573df9a8dfSCaroline Tice if (valid_index) 20583df9a8dfSCaroline Tice array_var.ReplaceArgumentAtIndex (index, new_value); 20593df9a8dfSCaroline Tice break; 20603df9a8dfSCaroline Tice } 2061*bfe5f3bfSGreg Clayton case eVarSetOperationInsertBefore: 2062*bfe5f3bfSGreg Clayton case eVarSetOperationInsertAfter: 20633df9a8dfSCaroline Tice { 20643df9a8dfSCaroline Tice if (valid_index) 20653df9a8dfSCaroline Tice { 20663df9a8dfSCaroline Tice Args new_array (new_value); 2067*bfe5f3bfSGreg Clayton if (op == eVarSetOperationInsertAfter) 20683df9a8dfSCaroline Tice ++index; 20693df9a8dfSCaroline Tice for (int i = 0; i < new_array.GetArgumentCount(); ++i) 20703df9a8dfSCaroline Tice array_var.InsertArgumentAtIndex (index, new_array.GetArgumentAtIndex (i)); 20713df9a8dfSCaroline Tice } 20723df9a8dfSCaroline Tice break; 20733df9a8dfSCaroline Tice } 2074*bfe5f3bfSGreg Clayton case eVarSetOperationRemove: 20753df9a8dfSCaroline Tice { 20763df9a8dfSCaroline Tice if (valid_index) 20773df9a8dfSCaroline Tice array_var.DeleteArgumentAtIndex (index); 20783df9a8dfSCaroline Tice break; 20793df9a8dfSCaroline Tice } 2080*bfe5f3bfSGreg Clayton case eVarSetOperationAppend: 20813df9a8dfSCaroline Tice { 20823df9a8dfSCaroline Tice Args new_array (new_value); 20833df9a8dfSCaroline Tice array_var.AppendArguments (new_array); 20843df9a8dfSCaroline Tice break; 20853df9a8dfSCaroline Tice } 2086*bfe5f3bfSGreg Clayton case eVarSetOperationClear: 20873df9a8dfSCaroline Tice array_var.Clear(); 20883df9a8dfSCaroline Tice break; 20893df9a8dfSCaroline Tice default: 20903df9a8dfSCaroline Tice err.SetErrorString ("Unrecognized operation. Cannot update value.\n"); 20913df9a8dfSCaroline Tice break; 20923df9a8dfSCaroline Tice } 20933df9a8dfSCaroline Tice } 20943df9a8dfSCaroline Tice 20953df9a8dfSCaroline Tice void 2096*bfe5f3bfSGreg Clayton UserSettingsController::UpdateDictionaryVariable (VarSetOperationType op, 20973df9a8dfSCaroline Tice const char *index_value, 20983df9a8dfSCaroline Tice std::map<std::string, std::string> &dictionary, 20993df9a8dfSCaroline Tice const char *new_value, 21003df9a8dfSCaroline Tice Error &err) 21013df9a8dfSCaroline Tice { 21023df9a8dfSCaroline Tice switch (op) 21033df9a8dfSCaroline Tice { 2104*bfe5f3bfSGreg Clayton case eVarSetOperationReplace: 21053df9a8dfSCaroline Tice if (index_value != NULL) 21063df9a8dfSCaroline Tice { 21073df9a8dfSCaroline Tice std::string key (index_value); 21083df9a8dfSCaroline Tice std::map<std::string, std::string>::iterator pos; 21093df9a8dfSCaroline Tice 21103df9a8dfSCaroline Tice pos = dictionary.find (key); 21113df9a8dfSCaroline Tice if (pos != dictionary.end()) 21123df9a8dfSCaroline Tice dictionary[key] = new_value; 21133df9a8dfSCaroline Tice else 21143df9a8dfSCaroline Tice err.SetErrorStringWithFormat ("'%s' is not an existing key; cannot replace value.\n", index_value); 21153df9a8dfSCaroline Tice } 21163df9a8dfSCaroline Tice else 21173df9a8dfSCaroline Tice err.SetErrorString ("'settings replace' requires a key for dictionary variables. No key supplied.\n"); 21183df9a8dfSCaroline Tice break; 2119*bfe5f3bfSGreg Clayton case eVarSetOperationRemove: 21203df9a8dfSCaroline Tice if (index_value != NULL) 21213df9a8dfSCaroline Tice { 21223df9a8dfSCaroline Tice std::string key (index_value); 21233df9a8dfSCaroline Tice dictionary.erase (key); 21243df9a8dfSCaroline Tice } 21253df9a8dfSCaroline Tice else 21263df9a8dfSCaroline Tice err.SetErrorString ("'settings remove' requires a key for dictionary variables. No key supplied.\n"); 21273df9a8dfSCaroline Tice break; 2128*bfe5f3bfSGreg Clayton case eVarSetOperationClear: 21293df9a8dfSCaroline Tice dictionary.clear (); 21303df9a8dfSCaroline Tice break; 2131*bfe5f3bfSGreg Clayton case eVarSetOperationAppend: 2132*bfe5f3bfSGreg Clayton case eVarSetOperationAssign: 21333df9a8dfSCaroline Tice { 213473b4f711SJohnny Chen // Clear the dictionary if it's an assign with new_value as NULL. 2135*bfe5f3bfSGreg Clayton if (new_value == NULL && op == eVarSetOperationAssign) 213673b4f711SJohnny Chen { 213773b4f711SJohnny Chen dictionary.clear (); 213873b4f711SJohnny Chen break; 213973b4f711SJohnny Chen } 21403df9a8dfSCaroline Tice Args args (new_value); 21413df9a8dfSCaroline Tice size_t num_args = args.GetArgumentCount(); 21426ad07dd9SGreg Clayton RegularExpression regex("(\\[\"?)?" // Regex match 1 (optional key prefix of '["' pr '[') 21436ad07dd9SGreg Clayton "([A-Za-z_][A-Za-z_0-9]*)" // Regex match 2 (key string) 21446ad07dd9SGreg Clayton "(\"?\\])?" // Regex match 3 (optional key suffix of '"]' pr ']') 21456ad07dd9SGreg Clayton "=" // The equal sign that is required 21466ad07dd9SGreg Clayton "(.*)"); // Regex match 4 (value string) 21476ad07dd9SGreg Clayton std::string key, value; 21486ad07dd9SGreg Clayton 21493df9a8dfSCaroline Tice for (size_t i = 0; i < num_args; ++i) 21503df9a8dfSCaroline Tice { 21516ad07dd9SGreg Clayton const char *key_equal_value_arg = args.GetArgumentAtIndex (i); 21526ad07dd9SGreg Clayton // Execute the regular expression on each arg. 21536ad07dd9SGreg Clayton if (regex.Execute(key_equal_value_arg, 5)) 21543df9a8dfSCaroline Tice { 21556ad07dd9SGreg Clayton // The regular expression succeeded. The match at index 21566ad07dd9SGreg Clayton // zero will be the entire string that matched the entire 21576ad07dd9SGreg Clayton // regular expression. The match at index 1 - 4 will be 21586ad07dd9SGreg Clayton // as mentioned above by the creation of the regex pattern. 21596ad07dd9SGreg Clayton // Match index 2 is the key, match index 4 is the value. 21606ad07dd9SGreg Clayton regex.GetMatchAtIndex (key_equal_value_arg, 2, key); 21616ad07dd9SGreg Clayton regex.GetMatchAtIndex (key_equal_value_arg, 4, value); 21626ad07dd9SGreg Clayton dictionary[key] = value; 21633df9a8dfSCaroline Tice } 21643df9a8dfSCaroline Tice else 21656ad07dd9SGreg Clayton { 21666ad07dd9SGreg Clayton err.SetErrorString ("Invalid format for dictionary value. Expected one of '[\"<key>\"]=<value>', '[<key>]=<value>', or '<key>=<value>'\n"); 21673df9a8dfSCaroline Tice } 21683df9a8dfSCaroline Tice } 21693df9a8dfSCaroline Tice } 21703df9a8dfSCaroline Tice break; 2171*bfe5f3bfSGreg Clayton case eVarSetOperationInsertBefore: 2172*bfe5f3bfSGreg Clayton case eVarSetOperationInsertAfter: 21733df9a8dfSCaroline Tice err.SetErrorString ("Specified operation cannot be performed on dictionary variables.\n"); 21743df9a8dfSCaroline Tice break; 21753df9a8dfSCaroline Tice default: 21763df9a8dfSCaroline Tice err.SetErrorString ("Unrecognized operation.\n"); 21773df9a8dfSCaroline Tice break; 21783df9a8dfSCaroline Tice } 21793df9a8dfSCaroline Tice } 21803df9a8dfSCaroline Tice 21813df9a8dfSCaroline Tice const char * 2182*bfe5f3bfSGreg Clayton UserSettingsController::EnumToString (const OptionEnumValueElement *enum_values, 21833df9a8dfSCaroline Tice int value) 21843df9a8dfSCaroline Tice { 21853df9a8dfSCaroline Tice int i = 0; 21863df9a8dfSCaroline Tice while (enum_values[i].string_value != NULL) 21873df9a8dfSCaroline Tice { 21883df9a8dfSCaroline Tice if (enum_values[i].value == value) 21893df9a8dfSCaroline Tice return enum_values[i].string_value; 21903df9a8dfSCaroline Tice ++i; 21913df9a8dfSCaroline Tice } 21923df9a8dfSCaroline Tice 2193*bfe5f3bfSGreg Clayton return ""; 21943df9a8dfSCaroline Tice } 21953df9a8dfSCaroline Tice 21963df9a8dfSCaroline Tice 21973df9a8dfSCaroline Tice void 2198*bfe5f3bfSGreg Clayton UserSettingsController::UpdateEnumVariable (OptionEnumValueElement *enum_values, 21993df9a8dfSCaroline Tice int *enum_var, 22003df9a8dfSCaroline Tice const char *new_value, 22013df9a8dfSCaroline Tice Error &err) 22023df9a8dfSCaroline Tice { 22033df9a8dfSCaroline Tice bool found_one; 22043df9a8dfSCaroline Tice 22053df9a8dfSCaroline Tice *enum_var = Args::StringToOptionEnum (new_value, enum_values, enum_values[0].value, &found_one); 22063df9a8dfSCaroline Tice 22073df9a8dfSCaroline Tice if (!found_one) 22083df9a8dfSCaroline Tice err.SetErrorString ("Invalid enumeration value; cannot update variable.\n"); 22093df9a8dfSCaroline Tice } 22103df9a8dfSCaroline Tice 2211ded2fa39SCaroline Tice void 2212ded2fa39SCaroline Tice UserSettingsController::RenameInstanceSettings (const char *old_name, const char *new_name) 2213ded2fa39SCaroline Tice { 2214ded2fa39SCaroline Tice Mutex::Locker live_mutex (m_live_settings_mutex); 2215ded2fa39SCaroline Tice Mutex::Locker pending_mutex (m_pending_settings_mutex); 2216ded2fa39SCaroline Tice std::string old_name_key (old_name); 2217ded2fa39SCaroline Tice std::string new_name_key (new_name); 2218ded2fa39SCaroline Tice 2219ded2fa39SCaroline Tice // First, find the live instance settings for the old_name. If they don't exist in the live settings 2220ded2fa39SCaroline Tice // list, then this is not a setting that can be renamed. 2221ded2fa39SCaroline Tice 2222ded2fa39SCaroline Tice if ((old_name_key[0] != '[') || (old_name_key[old_name_key.size() -1] != ']')) 2223ded2fa39SCaroline Tice { 2224ded2fa39SCaroline Tice StreamString tmp_str; 2225ded2fa39SCaroline Tice tmp_str.Printf ("[%s]", old_name); 2226ded2fa39SCaroline Tice old_name_key = tmp_str.GetData(); 2227ded2fa39SCaroline Tice } 2228ded2fa39SCaroline Tice 2229ded2fa39SCaroline Tice if ((new_name_key[0] != '[') || (new_name_key[new_name_key.size() -1] != ']')) 2230ded2fa39SCaroline Tice { 2231ded2fa39SCaroline Tice StreamString tmp_str; 2232ded2fa39SCaroline Tice tmp_str.Printf ("[%s]", new_name); 2233ded2fa39SCaroline Tice new_name_key = tmp_str.GetData(); 2234ded2fa39SCaroline Tice } 2235ded2fa39SCaroline Tice 22361559a46bSCaroline Tice if (old_name_key.compare (new_name_key) == 0) 22371559a46bSCaroline Tice return; 22381559a46bSCaroline Tice 22391559a46bSCaroline Tice size_t len = new_name_key.length(); 22401559a46bSCaroline Tice std::string stripped_new_name = new_name_key.substr (1, len-2); // new name without the '[ ]' 22411559a46bSCaroline Tice 2242ded2fa39SCaroline Tice std::map<std::string, InstanceSettings *>::iterator pos; 2243ded2fa39SCaroline Tice 2244ded2fa39SCaroline Tice pos = m_live_settings.find (old_name_key); 2245ded2fa39SCaroline Tice if (pos != m_live_settings.end()) 2246ded2fa39SCaroline Tice { 2247ded2fa39SCaroline Tice InstanceSettings *live_settings = pos->second; 2248ded2fa39SCaroline Tice 2249ded2fa39SCaroline Tice // Rename the settings. 22501559a46bSCaroline Tice live_settings->ChangeInstanceName (stripped_new_name); 2251ded2fa39SCaroline Tice 2252ded2fa39SCaroline Tice // Now see if there are any pending settings for the new name; if so, copy them into live_settings. 2253*bfe5f3bfSGreg Clayton std::map<std::string, InstanceSettingsSP>::iterator pending_pos; 2254ded2fa39SCaroline Tice pending_pos = m_pending_settings.find (new_name_key); 2255ded2fa39SCaroline Tice if (pending_pos != m_pending_settings.end()) 2256ded2fa39SCaroline Tice { 2257*bfe5f3bfSGreg Clayton InstanceSettingsSP pending_settings_sp = pending_pos->second; 2258ded2fa39SCaroline Tice live_settings->CopyInstanceSettings (pending_settings_sp, false); 2259ded2fa39SCaroline Tice } 2260ded2fa39SCaroline Tice 2261ded2fa39SCaroline Tice // Erase the old entry (under the old name) from live settings. 2262ded2fa39SCaroline Tice m_live_settings.erase (pos); 2263ded2fa39SCaroline Tice 2264ded2fa39SCaroline Tice // Add the new entry, with the new name, into live settings. 2265ded2fa39SCaroline Tice m_live_settings[new_name_key] = live_settings; 2266ded2fa39SCaroline Tice } 2267ded2fa39SCaroline Tice } 2268ded2fa39SCaroline Tice 22693df9a8dfSCaroline Tice //---------------------------------------------------------------------- 22703df9a8dfSCaroline Tice // class InstanceSettings 22713df9a8dfSCaroline Tice //---------------------------------------------------------------------- 22723df9a8dfSCaroline Tice 227391123da2SCaroline Tice InstanceSettings::InstanceSettings (UserSettingsController &owner, const char *instance_name, bool live_instance) : 22743df9a8dfSCaroline Tice m_owner (owner), 22753df9a8dfSCaroline Tice m_instance_name (instance_name) 22763df9a8dfSCaroline Tice { 227791123da2SCaroline Tice if ((m_instance_name != InstanceSettings::GetDefaultName()) 22789e41c15dSCaroline Tice && (m_instance_name != InstanceSettings::InvalidName()) 227991123da2SCaroline Tice && live_instance) 22803df9a8dfSCaroline Tice m_owner.RegisterInstanceSettings (this); 22813df9a8dfSCaroline Tice } 22823df9a8dfSCaroline Tice 22833df9a8dfSCaroline Tice InstanceSettings::~InstanceSettings () 22843df9a8dfSCaroline Tice { 22853df9a8dfSCaroline Tice if (m_instance_name != InstanceSettings::GetDefaultName()) 22863df9a8dfSCaroline Tice m_owner.UnregisterInstanceSettings (this); 22873df9a8dfSCaroline Tice } 22883df9a8dfSCaroline Tice 22893df9a8dfSCaroline Tice const ConstString & 22903df9a8dfSCaroline Tice InstanceSettings::GetDefaultName () 22913df9a8dfSCaroline Tice { 22923df9a8dfSCaroline Tice static const ConstString g_default_settings_name ("[DEFAULT]"); 22933df9a8dfSCaroline Tice 22943df9a8dfSCaroline Tice return g_default_settings_name; 22953df9a8dfSCaroline Tice } 2296ded2fa39SCaroline Tice 22979e41c15dSCaroline Tice const ConstString & 22989e41c15dSCaroline Tice InstanceSettings::InvalidName () 22999e41c15dSCaroline Tice { 23009e41c15dSCaroline Tice static const ConstString g_invalid_name ("Invalid instance name"); 23019e41c15dSCaroline Tice 23029e41c15dSCaroline Tice return g_invalid_name; 23039e41c15dSCaroline Tice } 23049e41c15dSCaroline Tice 2305ded2fa39SCaroline Tice void 2306ded2fa39SCaroline Tice InstanceSettings::ChangeInstanceName (const std::string &new_instance_name) 2307ded2fa39SCaroline Tice { 2308ded2fa39SCaroline Tice m_instance_name.SetCString (new_instance_name.c_str()); 2309ded2fa39SCaroline Tice } 2310ded2fa39SCaroline Tice 2311ded2fa39SCaroline Tice 2312