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"
153df9a8dfSCaroline Tice #include "lldb/Core/Stream.h"
163df9a8dfSCaroline Tice #include "lldb/Core/StreamString.h"
173df9a8dfSCaroline Tice #include "lldb/Interpreter/CommandInterpreter.h"
183df9a8dfSCaroline Tice 
193df9a8dfSCaroline Tice using namespace lldb_private;
203df9a8dfSCaroline Tice 
213df9a8dfSCaroline Tice UserSettingsController::UserSettingsController (const char *level_name,
223df9a8dfSCaroline Tice                                                 const lldb::UserSettingsControllerSP &parent) :
233df9a8dfSCaroline Tice     m_default_settings (),
243df9a8dfSCaroline Tice     m_settings (),
253df9a8dfSCaroline Tice     m_children (),
263df9a8dfSCaroline Tice     m_pending_settings (),
273df9a8dfSCaroline Tice     m_live_settings (),
283df9a8dfSCaroline Tice     m_children_mutex (Mutex::eMutexTypeNormal),
293df9a8dfSCaroline Tice     m_pending_settings_mutex (Mutex::eMutexTypeNormal),
303df9a8dfSCaroline Tice     m_live_settings_mutex (Mutex::eMutexTypeNormal)
313df9a8dfSCaroline Tice {
323df9a8dfSCaroline Tice     m_settings.parent = parent;
333df9a8dfSCaroline Tice     m_settings.level_name.SetCString (level_name);
343df9a8dfSCaroline Tice }
353df9a8dfSCaroline Tice 
363df9a8dfSCaroline Tice UserSettingsController::~UserSettingsController ()
373df9a8dfSCaroline Tice {
383df9a8dfSCaroline Tice     m_live_settings.clear();
393df9a8dfSCaroline Tice }
403df9a8dfSCaroline Tice 
413df9a8dfSCaroline Tice void
423df9a8dfSCaroline Tice UserSettingsController::InitializeGlobalVariables ()
433df9a8dfSCaroline Tice {
443df9a8dfSCaroline Tice     static bool global_initialized = false;
453df9a8dfSCaroline Tice     int num_entries;
463df9a8dfSCaroline Tice     const char *prefix = GetLevelName().AsCString();
473df9a8dfSCaroline Tice 
483df9a8dfSCaroline Tice     if (! global_initialized)
493df9a8dfSCaroline Tice     {
503df9a8dfSCaroline Tice         num_entries = m_settings.global_settings.size();
513df9a8dfSCaroline Tice         for (int i = 0; i < num_entries; ++i)
523df9a8dfSCaroline Tice         {
533df9a8dfSCaroline Tice             SettingEntry &entry = m_settings.global_settings[i];
543df9a8dfSCaroline Tice             if (entry.default_value != NULL)
553df9a8dfSCaroline Tice             {
563df9a8dfSCaroline Tice                 StreamString full_name;
573df9a8dfSCaroline Tice                 if (prefix[0] != '\0')
583df9a8dfSCaroline Tice                     full_name.Printf ("%s.%s", prefix, entry.var_name);
593df9a8dfSCaroline Tice                 else
603df9a8dfSCaroline Tice                     full_name.Printf ("%s", entry.var_name);
613df9a8dfSCaroline Tice                 SetVariable (full_name.GetData(), entry.default_value, lldb::eVarSetOperationAssign, false);
623df9a8dfSCaroline Tice             }
633df9a8dfSCaroline Tice             else if ((entry.var_type == lldb::eSetVarTypeEnum)
643df9a8dfSCaroline Tice                      && (entry.enum_values != NULL))
653df9a8dfSCaroline Tice             {
663df9a8dfSCaroline Tice                 StreamString full_name;
673df9a8dfSCaroline Tice                 if (prefix[0] != '\0')
683df9a8dfSCaroline Tice                     full_name.Printf ("%s.%s", prefix, entry.var_name);
693df9a8dfSCaroline Tice                 else
703df9a8dfSCaroline Tice                     full_name.Printf ("%s", entry.var_name);
713df9a8dfSCaroline Tice                 SetVariable (full_name.GetData(), entry.enum_values[0].string_value, lldb::eVarSetOperationAssign,
723df9a8dfSCaroline Tice                              false);
733df9a8dfSCaroline Tice             }
743df9a8dfSCaroline Tice         }
753df9a8dfSCaroline Tice         global_initialized = true;
763df9a8dfSCaroline Tice     }
773df9a8dfSCaroline Tice }
783df9a8dfSCaroline Tice 
793df9a8dfSCaroline Tice const lldb::UserSettingsControllerSP &
803df9a8dfSCaroline Tice UserSettingsController::GetParent ()
813df9a8dfSCaroline Tice {
823df9a8dfSCaroline Tice     return m_settings.parent;
833df9a8dfSCaroline Tice }
843df9a8dfSCaroline Tice 
853df9a8dfSCaroline Tice void
863df9a8dfSCaroline Tice UserSettingsController::RegisterChild (const lldb::UserSettingsControllerSP &child)
873df9a8dfSCaroline Tice {
883df9a8dfSCaroline Tice     Mutex::Locker locker (m_children_mutex);
893df9a8dfSCaroline Tice 
903df9a8dfSCaroline Tice     // Verify child is not already in m_children.
913df9a8dfSCaroline Tice     size_t num_children = m_children.size();
923df9a8dfSCaroline Tice     bool found = false;
933df9a8dfSCaroline Tice     for (size_t i = 0; i < num_children; ++i)
943df9a8dfSCaroline Tice       {
953df9a8dfSCaroline Tice 	if (m_children[i].get() == child.get())
963df9a8dfSCaroline Tice     	    found = true;
973df9a8dfSCaroline Tice       }
983df9a8dfSCaroline Tice 
993df9a8dfSCaroline Tice     // Add child to m_children.
1003df9a8dfSCaroline Tice     if (! found)
1013df9a8dfSCaroline Tice         m_children.push_back (child);
1023df9a8dfSCaroline Tice }
1033df9a8dfSCaroline Tice 
1043df9a8dfSCaroline Tice const ConstString &
1053df9a8dfSCaroline Tice UserSettingsController::GetLevelName ()
1063df9a8dfSCaroline Tice {
1073df9a8dfSCaroline Tice     return m_settings.level_name;
1083df9a8dfSCaroline Tice }
1093df9a8dfSCaroline Tice 
1103df9a8dfSCaroline Tice size_t
1113df9a8dfSCaroline Tice UserSettingsController::GetNumChildren ()
1123df9a8dfSCaroline Tice {
1133df9a8dfSCaroline Tice     return m_children.size();
1143df9a8dfSCaroline Tice }
1153df9a8dfSCaroline Tice 
1163df9a8dfSCaroline Tice const lldb::UserSettingsControllerSP
1173df9a8dfSCaroline Tice UserSettingsController::GetChildAtIndex (size_t index)
1183df9a8dfSCaroline Tice {
1193df9a8dfSCaroline Tice     if (index < m_children.size())
1203df9a8dfSCaroline Tice         return m_children[index];
1213df9a8dfSCaroline Tice 
1223df9a8dfSCaroline Tice     lldb::UserSettingsControllerSP dummy_value;
1233df9a8dfSCaroline Tice 
1243df9a8dfSCaroline Tice     return dummy_value;
1253df9a8dfSCaroline Tice }
1263df9a8dfSCaroline Tice 
1273df9a8dfSCaroline Tice const SettingEntry *
1283df9a8dfSCaroline Tice UserSettingsController::GetGlobalEntry (const ConstString &var_name)
1293df9a8dfSCaroline Tice {
1303df9a8dfSCaroline Tice 
1313df9a8dfSCaroline Tice     for (int i = 0; i < m_settings.global_settings.size(); ++i)
1323df9a8dfSCaroline Tice     {
1333df9a8dfSCaroline Tice         SettingEntry &entry = m_settings.global_settings[i];
1343df9a8dfSCaroline Tice         ConstString entry_name (entry.var_name);
1353df9a8dfSCaroline Tice         if (entry_name == var_name)
1363df9a8dfSCaroline Tice             return &entry;
1373df9a8dfSCaroline Tice     }
1383df9a8dfSCaroline Tice 
1393df9a8dfSCaroline Tice     return NULL;
1403df9a8dfSCaroline Tice }
1413df9a8dfSCaroline Tice 
1423df9a8dfSCaroline Tice const SettingEntry *
1433df9a8dfSCaroline Tice UserSettingsController::GetInstanceEntry (const ConstString &const_var_name)
1443df9a8dfSCaroline Tice {
1453df9a8dfSCaroline Tice 
1463df9a8dfSCaroline Tice     for (int i = 0; i < m_settings.instance_settings.size(); ++i)
1473df9a8dfSCaroline Tice     {
1483df9a8dfSCaroline Tice         SettingEntry &entry = m_settings.instance_settings[i];
1493df9a8dfSCaroline Tice         ConstString entry_name (entry.var_name);
1503df9a8dfSCaroline Tice         if (entry_name == const_var_name)
1513df9a8dfSCaroline Tice             return &entry;
1523df9a8dfSCaroline Tice     }
1533df9a8dfSCaroline Tice 
1543df9a8dfSCaroline Tice     return NULL;
1553df9a8dfSCaroline Tice }
1563df9a8dfSCaroline Tice 
1573df9a8dfSCaroline Tice void
1583df9a8dfSCaroline Tice UserSettingsController::BuildParentPrefix (std::string &parent_prefix)
1593df9a8dfSCaroline Tice {
1603df9a8dfSCaroline Tice     lldb::UserSettingsControllerSP parent = GetParent();
1613df9a8dfSCaroline Tice     if (parent.get() != NULL)
1623df9a8dfSCaroline Tice     {
1633df9a8dfSCaroline Tice         parent->BuildParentPrefix (parent_prefix);
1643df9a8dfSCaroline Tice         if (parent_prefix.length() > 0)
1653df9a8dfSCaroline Tice             parent_prefix.append (".");
1663df9a8dfSCaroline Tice     }
1673df9a8dfSCaroline Tice     parent_prefix.append (GetLevelName().AsCString());
1683df9a8dfSCaroline Tice }
1693df9a8dfSCaroline Tice 
1703df9a8dfSCaroline Tice void
1713df9a8dfSCaroline Tice UserSettingsController::RemoveChild (const lldb::UserSettingsControllerSP &child)
1723df9a8dfSCaroline Tice {
1733df9a8dfSCaroline Tice     Mutex::Locker locker (m_children_mutex);
1743df9a8dfSCaroline Tice     std::vector<lldb::UserSettingsControllerSP>::iterator pos, end = m_children.end();
1753df9a8dfSCaroline Tice 
1763df9a8dfSCaroline Tice    for (pos = m_children.begin(); pos != end; ++pos)
1773df9a8dfSCaroline Tice    {
1783df9a8dfSCaroline Tice       lldb::UserSettingsControllerSP entry = *pos;
1793df9a8dfSCaroline Tice       if (entry == child)
1803df9a8dfSCaroline Tice       {
1813df9a8dfSCaroline Tice           m_children.erase (pos);
1823df9a8dfSCaroline Tice           break;
1833df9a8dfSCaroline Tice       }
1843df9a8dfSCaroline Tice    }
1853df9a8dfSCaroline Tice }
1863df9a8dfSCaroline Tice 
1873df9a8dfSCaroline Tice Error
1883df9a8dfSCaroline Tice UserSettingsController::SetVariable (const char *full_dot_name,
1893df9a8dfSCaroline Tice                                      const char *value,
1903df9a8dfSCaroline Tice                                      const lldb::VarSetOperationType op,
1913df9a8dfSCaroline Tice                                      const bool override,
1923df9a8dfSCaroline Tice                                      const char *index_value)
1933df9a8dfSCaroline Tice {
1943df9a8dfSCaroline Tice     Error err;
1953df9a8dfSCaroline Tice     ConstString const_var_name;
1963df9a8dfSCaroline Tice     const ConstString &default_name = InstanceSettings::GetDefaultName();
1973df9a8dfSCaroline Tice 
1983df9a8dfSCaroline Tice     Args names = UserSettingsController::BreakNameIntoPieces (full_dot_name);
1993df9a8dfSCaroline Tice     int num_pieces = names.GetArgumentCount();
2003df9a8dfSCaroline Tice 
2013df9a8dfSCaroline Tice     if (num_pieces < 1)
2023df9a8dfSCaroline Tice     {
2033df9a8dfSCaroline Tice         err.SetErrorStringWithFormat ("'%s' is not a valid variable name; cannot assign value.\n", full_dot_name);
2043df9a8dfSCaroline Tice         return err;
2053df9a8dfSCaroline Tice     }
2063df9a8dfSCaroline Tice 
2073df9a8dfSCaroline Tice     ConstString prefix (names.GetArgumentAtIndex (0));
2083df9a8dfSCaroline Tice 
2093df9a8dfSCaroline Tice     if ((prefix == m_settings.level_name)
2103df9a8dfSCaroline Tice         || (m_settings.level_name.GetLength() == 0))
2113df9a8dfSCaroline Tice     {
2123df9a8dfSCaroline Tice 
2133df9a8dfSCaroline Tice         if (prefix == m_settings.level_name)
2143df9a8dfSCaroline Tice         {
2153df9a8dfSCaroline Tice             names.Shift ();
2163df9a8dfSCaroline Tice             num_pieces = names.GetArgumentCount();
2173df9a8dfSCaroline Tice         }
2183df9a8dfSCaroline Tice 
2193df9a8dfSCaroline Tice         if (num_pieces == 0)
2203df9a8dfSCaroline Tice         {
2213df9a8dfSCaroline Tice             err.SetErrorString ("No variable name specified; cannot assign value.\n");
2223df9a8dfSCaroline Tice             return err;
2233df9a8dfSCaroline Tice         }
2243df9a8dfSCaroline Tice         else if (num_pieces == 1)
2253df9a8dfSCaroline Tice         {
2263df9a8dfSCaroline Tice 
2273df9a8dfSCaroline Tice             // Must be one of the class-wide settings.
2283df9a8dfSCaroline Tice 
2293df9a8dfSCaroline Tice             const_var_name.SetCString (names.GetArgumentAtIndex (0));
2303df9a8dfSCaroline Tice             const SettingEntry *entry = GetGlobalEntry (const_var_name);
2313df9a8dfSCaroline Tice             if (entry)
2323df9a8dfSCaroline Tice             {
2333df9a8dfSCaroline Tice                 UserSettingsController::VerifyOperationForType (entry->var_type, op, const_var_name, err);
2343df9a8dfSCaroline Tice 
2353df9a8dfSCaroline Tice                 if (err.Fail())
2363df9a8dfSCaroline Tice                     return err;
2373df9a8dfSCaroline Tice 
2383df9a8dfSCaroline Tice                 if ((value == NULL || value[0] == '\0')
2393df9a8dfSCaroline Tice                     && (op == lldb::eVarSetOperationAssign))
2403df9a8dfSCaroline Tice                 {
2413df9a8dfSCaroline Tice                     if (entry->var_type != lldb::eSetVarTypeEnum)
2423df9a8dfSCaroline Tice                         value = entry->default_value;
2433df9a8dfSCaroline Tice                     else
2443df9a8dfSCaroline Tice                         value = entry->enum_values[0].string_value;
2453df9a8dfSCaroline Tice                 }
2463df9a8dfSCaroline Tice                 UpdateGlobalVariable (const_var_name, index_value, value, *entry, op, err);
2473df9a8dfSCaroline Tice             }
2483df9a8dfSCaroline Tice             else
2493df9a8dfSCaroline Tice             {
2503df9a8dfSCaroline Tice                 // MIGHT be instance variable, to be for ALL instances.
2513df9a8dfSCaroline Tice 
2523df9a8dfSCaroline Tice                 entry = GetInstanceEntry (const_var_name);
2533df9a8dfSCaroline Tice                 if (entry == NULL)
2543df9a8dfSCaroline Tice                 {
2553df9a8dfSCaroline Tice                     err.SetErrorStringWithFormat ("Unable to find variable '%s.%s'; cannot assign value.\n",
2563df9a8dfSCaroline Tice                                                   prefix.AsCString(), const_var_name.AsCString());
2573df9a8dfSCaroline Tice                     return err;
2583df9a8dfSCaroline Tice                 }
2593df9a8dfSCaroline Tice                 else
2603df9a8dfSCaroline Tice                 {
2613df9a8dfSCaroline Tice                     UserSettingsController::VerifyOperationForType (entry->var_type, op, const_var_name, err);
2623df9a8dfSCaroline Tice 
2633df9a8dfSCaroline Tice                     if (err.Fail())
2643df9a8dfSCaroline Tice                         return err;
2653df9a8dfSCaroline Tice 
2663df9a8dfSCaroline Tice                     if ((value == NULL || value[0] == '\0')
2673df9a8dfSCaroline Tice                         && (op == lldb::eVarSetOperationAssign))
2683df9a8dfSCaroline Tice                     {
2693df9a8dfSCaroline Tice                         if (entry->var_type != lldb::eSetVarTypeEnum)
2703df9a8dfSCaroline Tice                             value = entry->default_value;
2713df9a8dfSCaroline Tice                         else
2723df9a8dfSCaroline Tice                             value = entry->enum_values[0].string_value;
2733df9a8dfSCaroline Tice                     }
2743df9a8dfSCaroline Tice 
2753df9a8dfSCaroline Tice                     m_default_settings->UpdateInstanceSettingsVariable (const_var_name, index_value, value,
2763df9a8dfSCaroline Tice                                                                         default_name, *entry, op, err, true);
2773df9a8dfSCaroline Tice                     if (override)
2783df9a8dfSCaroline Tice                     {
2793df9a8dfSCaroline Tice                         OverrideAllInstances (const_var_name, value, op, index_value, err);
2803df9a8dfSCaroline Tice 
2813df9a8dfSCaroline Tice                         // Update all pending records as well.
2823df9a8dfSCaroline Tice                         std::map<std::string, lldb::InstanceSettingsSP>::iterator pos, end = m_pending_settings.end();
2833df9a8dfSCaroline Tice                         for (pos = m_pending_settings.begin(); pos != end; end++)
2843df9a8dfSCaroline Tice                         {
2853df9a8dfSCaroline Tice                             const ConstString instance_name (pos->first.c_str());
2863df9a8dfSCaroline Tice                             lldb::InstanceSettingsSP setting_sp = pos->second;
2873df9a8dfSCaroline Tice                             setting_sp->UpdateInstanceSettingsVariable (const_var_name, index_value, value,
2883df9a8dfSCaroline Tice                                                                         instance_name, *entry, op, err, true);
2893df9a8dfSCaroline Tice                         }
2903df9a8dfSCaroline Tice                     }
2913df9a8dfSCaroline Tice                 }
2923df9a8dfSCaroline Tice             }
2933df9a8dfSCaroline Tice         }
2943df9a8dfSCaroline Tice         else
2953df9a8dfSCaroline Tice         {
2963df9a8dfSCaroline Tice             // Either a child's setting or an instance setting.
2973df9a8dfSCaroline Tice 
2983df9a8dfSCaroline Tice             if (names.GetArgumentAtIndex(0)[0] == '[')
2993df9a8dfSCaroline Tice             {
3003df9a8dfSCaroline Tice                 // An instance setting.  Supposedly.
3013df9a8dfSCaroline Tice 
3023df9a8dfSCaroline Tice                 ConstString instance_name (names.GetArgumentAtIndex (0));
3033df9a8dfSCaroline Tice 
3043df9a8dfSCaroline Tice                 // First verify that there is only one more name.
3053df9a8dfSCaroline Tice 
3063df9a8dfSCaroline Tice                 names.Shift();
3073df9a8dfSCaroline Tice 
3083df9a8dfSCaroline Tice                 if (names.GetArgumentCount() != 1)
3093df9a8dfSCaroline Tice                 {
3103df9a8dfSCaroline Tice                     err.SetErrorStringWithFormat ("Invalid variable name format '%s'; cannot assign value.\n",
3113df9a8dfSCaroline Tice                                                   full_dot_name);
3123df9a8dfSCaroline Tice                     return err;
3133df9a8dfSCaroline Tice                 }
3143df9a8dfSCaroline Tice 
3153df9a8dfSCaroline Tice                 // Next verify that it is a valid instance setting name.
3163df9a8dfSCaroline Tice 
3173df9a8dfSCaroline Tice                 const_var_name.SetCString (names.GetArgumentAtIndex (0));
3183df9a8dfSCaroline Tice                 const SettingEntry *entry = GetInstanceEntry (const_var_name);
3193df9a8dfSCaroline Tice 
3203df9a8dfSCaroline Tice                 if (entry == NULL)
3213df9a8dfSCaroline Tice                 {
3223df9a8dfSCaroline Tice                     err.SetErrorStringWithFormat ("Unknown instance variable '%s'; cannot assign value.\n",
3233df9a8dfSCaroline Tice                                                   const_var_name.AsCString());
3243df9a8dfSCaroline Tice                     return err;
3253df9a8dfSCaroline Tice                 }
3263df9a8dfSCaroline Tice 
3273df9a8dfSCaroline Tice                 UserSettingsController::VerifyOperationForType (entry->var_type, op, const_var_name, err);
3283df9a8dfSCaroline Tice 
3293df9a8dfSCaroline Tice                 if (err.Fail())
3303df9a8dfSCaroline Tice                     return err;
3313df9a8dfSCaroline Tice 
3323df9a8dfSCaroline Tice                 if ((value == NULL || value[0] == '\0')
3333df9a8dfSCaroline Tice                     && (op == lldb::eVarSetOperationAssign))
3343df9a8dfSCaroline Tice                 {
3353df9a8dfSCaroline Tice                     if (entry->var_type != lldb::eSetVarTypeEnum)
3363df9a8dfSCaroline Tice                         value = entry->default_value;
3373df9a8dfSCaroline Tice                     else
3383df9a8dfSCaroline Tice                         value = entry->enum_values[0].string_value;
3393df9a8dfSCaroline Tice                 }
3403df9a8dfSCaroline Tice 
3413df9a8dfSCaroline Tice                 // Now look for existing instance with given instance name; if not found, find or create pending
3423df9a8dfSCaroline Tice                 // setting for instance with given name.
3433df9a8dfSCaroline Tice 
3443df9a8dfSCaroline Tice                 InstanceSettings *current_settings = FindSettingsForInstance (instance_name);
3453df9a8dfSCaroline Tice 
3463df9a8dfSCaroline Tice                 if (current_settings != NULL)
3473df9a8dfSCaroline Tice                 {
3483df9a8dfSCaroline Tice                     current_settings->UpdateInstanceSettingsVariable (const_var_name, index_value, value,
3493df9a8dfSCaroline Tice                                                                       instance_name, *entry, op, err, false);
3503df9a8dfSCaroline Tice 
3513df9a8dfSCaroline Tice                 }
3523df9a8dfSCaroline Tice                 else
3533df9a8dfSCaroline Tice                 {
3543df9a8dfSCaroline Tice                     // Instance does not currently exist; make or update a pending setting for it.
3553df9a8dfSCaroline Tice                     lldb::InstanceSettingsSP current_settings_sp = PendingSettingsForInstance (instance_name);
3563df9a8dfSCaroline Tice 
3573df9a8dfSCaroline Tice                     // Now we have a settings record, update it appropriately.
3583df9a8dfSCaroline Tice 
3593df9a8dfSCaroline Tice                     current_settings_sp->UpdateInstanceSettingsVariable (const_var_name, index_value, value,
3603df9a8dfSCaroline Tice                                                                          instance_name, *entry, op, err, true);
3613df9a8dfSCaroline Tice 
3623df9a8dfSCaroline Tice                     {   // Scope for mutex.
3633df9a8dfSCaroline Tice                         Mutex::Locker locker (m_pending_settings_mutex);
3643df9a8dfSCaroline Tice                         m_pending_settings[instance_name.AsCString()] = current_settings_sp;
3653df9a8dfSCaroline Tice                     }
3663df9a8dfSCaroline Tice 
3673df9a8dfSCaroline Tice                     if (override)
3683df9a8dfSCaroline Tice                     {
3693df9a8dfSCaroline Tice                         OverrideAllInstances (const_var_name, value, op, index_value, err);
3703df9a8dfSCaroline Tice 
3713df9a8dfSCaroline Tice                         // Update all pending records as well.
3723df9a8dfSCaroline Tice                         std::map<std::string, lldb::InstanceSettingsSP>::iterator pos;
3733df9a8dfSCaroline Tice                         std::map<std::string, lldb::InstanceSettingsSP>::iterator end = m_pending_settings.end();
3743df9a8dfSCaroline Tice                         for (pos = m_pending_settings.begin(); pos != end; end++)
3753df9a8dfSCaroline Tice                         {
3763df9a8dfSCaroline Tice                             const ConstString tmp_inst_name (pos->first.c_str());
3773df9a8dfSCaroline Tice                             lldb::InstanceSettingsSP setting_sp = pos->second;
3783df9a8dfSCaroline Tice                             setting_sp->UpdateInstanceSettingsVariable (const_var_name, index_value, value,
3793df9a8dfSCaroline Tice                                                                         tmp_inst_name, *entry, op, err, true);
3803df9a8dfSCaroline Tice                         }
3813df9a8dfSCaroline Tice                     }
3823df9a8dfSCaroline Tice                 }
3833df9a8dfSCaroline Tice             }
3843df9a8dfSCaroline Tice             else
3853df9a8dfSCaroline Tice             {
3863df9a8dfSCaroline Tice                 // A child setting.
3873df9a8dfSCaroline Tice                 lldb::UserSettingsControllerSP child;
3883df9a8dfSCaroline Tice                 ConstString child_prefix (names.GetArgumentAtIndex (0));
3893df9a8dfSCaroline Tice                 int num_children = GetNumChildren();
3903df9a8dfSCaroline Tice                 bool found = false;
3913df9a8dfSCaroline Tice                 for (int i = 0; i < num_children && !found; ++i)
3923df9a8dfSCaroline Tice                 {
3933df9a8dfSCaroline Tice                     child = GetChildAtIndex (i);
3943df9a8dfSCaroline Tice                     ConstString current_prefix = child->GetLevelName();
3953df9a8dfSCaroline Tice                     if (current_prefix == child_prefix)
3963df9a8dfSCaroline Tice                     {
3973df9a8dfSCaroline Tice                         found = true;
3983df9a8dfSCaroline Tice                         std::string new_name;
3993df9a8dfSCaroline Tice                         for (int j = 0; j < names.GetArgumentCount(); ++j)
4003df9a8dfSCaroline Tice                         {
4013df9a8dfSCaroline Tice                             if (j > 0)
4023df9a8dfSCaroline Tice                                 new_name += '.';
4033df9a8dfSCaroline Tice                             new_name += names.GetArgumentAtIndex (j);
4043df9a8dfSCaroline Tice                         }
4053df9a8dfSCaroline Tice                         return child->SetVariable (new_name.c_str(), value, op, override, index_value);
4063df9a8dfSCaroline Tice                     }
4073df9a8dfSCaroline Tice                 }
4083df9a8dfSCaroline Tice                 if (!found)
4093df9a8dfSCaroline Tice                 {
4103df9a8dfSCaroline Tice                     err.SetErrorStringWithFormat ("Unable to find variable '%s'; cannot assign value.\n",
4113df9a8dfSCaroline Tice                                                   full_dot_name);
4123df9a8dfSCaroline Tice                     return err;
4133df9a8dfSCaroline Tice                 }
4143df9a8dfSCaroline Tice             }
4153df9a8dfSCaroline Tice         }
4163df9a8dfSCaroline Tice     }
4173df9a8dfSCaroline Tice     else
4183df9a8dfSCaroline Tice     {
4193df9a8dfSCaroline Tice         err.SetErrorStringWithFormat ("'%s' is not a valid level name; was expecting '%s'. Cannot assign value.\n",
4203df9a8dfSCaroline Tice                                       prefix.AsCString(), m_settings.level_name.AsCString());
4213df9a8dfSCaroline Tice     }
4223df9a8dfSCaroline Tice 
4233df9a8dfSCaroline Tice     return err;
4243df9a8dfSCaroline Tice }
4253df9a8dfSCaroline Tice 
4263df9a8dfSCaroline Tice StringList
4273df9a8dfSCaroline Tice UserSettingsController::GetVariable (const char *full_dot_name, lldb::SettableVariableType &var_type)
4283df9a8dfSCaroline Tice {
4293df9a8dfSCaroline Tice     Args names = UserSettingsController::BreakNameIntoPieces (full_dot_name);
4303df9a8dfSCaroline Tice     ConstString const_var_name;
4313df9a8dfSCaroline Tice     StringList value;
4323df9a8dfSCaroline Tice 
4333df9a8dfSCaroline Tice     int num_pieces = names.GetArgumentCount();
4343df9a8dfSCaroline Tice 
4353df9a8dfSCaroline Tice     ConstString prefix (names.GetArgumentAtIndex (0));
4363df9a8dfSCaroline Tice     const_var_name.SetCString (names.GetArgumentAtIndex (num_pieces - 1));
4373df9a8dfSCaroline Tice 
4383df9a8dfSCaroline Tice     const SettingEntry *global_entry = GetGlobalEntry (const_var_name);
4393df9a8dfSCaroline Tice     const SettingEntry *instance_entry = GetInstanceEntry (const_var_name);
4403df9a8dfSCaroline Tice 
4413df9a8dfSCaroline Tice     if ((prefix != m_settings.level_name)
4423df9a8dfSCaroline Tice         && (m_settings.level_name.GetLength () > 0))
4433df9a8dfSCaroline Tice     {
4443df9a8dfSCaroline Tice         value.AppendString ("Invalid variable name");
4453df9a8dfSCaroline Tice         return value;
4463df9a8dfSCaroline Tice     }
4473df9a8dfSCaroline Tice 
4483df9a8dfSCaroline Tice     // prefix name matched; remove it from names.
4493df9a8dfSCaroline Tice     if (m_settings.level_name.GetLength() > 0)
4503df9a8dfSCaroline Tice         names.Shift();
4513df9a8dfSCaroline Tice 
4523df9a8dfSCaroline Tice     // Should we pass this off to a child?  If there is more than one name piece left, and the next name piece
4533df9a8dfSCaroline Tice     // matches a child prefix, then yes.
4543df9a8dfSCaroline Tice 
4553df9a8dfSCaroline Tice     lldb::UserSettingsControllerSP child;
4563df9a8dfSCaroline Tice     if (names.GetArgumentCount() > 1)
4573df9a8dfSCaroline Tice     {
4583df9a8dfSCaroline Tice         ConstString child_prefix (names.GetArgumentAtIndex (0));
4593df9a8dfSCaroline Tice         bool found = false;
4603df9a8dfSCaroline Tice         for (int i = 0; i < m_children.size() && !found; ++i)
4613df9a8dfSCaroline Tice         {
4623df9a8dfSCaroline Tice             if (child_prefix == m_children[i]->GetLevelName())
4633df9a8dfSCaroline Tice             {
4643df9a8dfSCaroline Tice                 found = true;
4653df9a8dfSCaroline Tice                 child = m_children[i];
4663df9a8dfSCaroline Tice                 std::string new_name;
4673df9a8dfSCaroline Tice                 for (int j = 0; j < names.GetArgumentCount(); ++j)
4683df9a8dfSCaroline Tice                 {
4693df9a8dfSCaroline Tice                     if (j > 0)
4703df9a8dfSCaroline Tice                         new_name += '.';
4713df9a8dfSCaroline Tice                     new_name += names.GetArgumentAtIndex (j);
4723df9a8dfSCaroline Tice                 }
4733df9a8dfSCaroline Tice                 return child->GetVariable (new_name.c_str(), var_type);
4743df9a8dfSCaroline Tice             }
4753df9a8dfSCaroline Tice         }
4763df9a8dfSCaroline Tice 
4773df9a8dfSCaroline Tice         if (!found)
4783df9a8dfSCaroline Tice         {
4793df9a8dfSCaroline Tice             // Cannot be handled by a child, because name did not match any child prefixes.
4803df9a8dfSCaroline Tice             // Cannot be a class-wide variable because there are too many name pieces.
4813df9a8dfSCaroline Tice 
4823df9a8dfSCaroline Tice             if (instance_entry != NULL)
4833df9a8dfSCaroline Tice             {
4843df9a8dfSCaroline Tice                 var_type = instance_entry->var_type;
4853df9a8dfSCaroline Tice                 ConstString instance_name (names.GetArgumentAtIndex (0));
4863df9a8dfSCaroline Tice                 InstanceSettings *current_settings = FindSettingsForInstance (instance_name);
4873df9a8dfSCaroline Tice 
4883df9a8dfSCaroline Tice                 if (current_settings != NULL)
4893df9a8dfSCaroline Tice                 {
4903df9a8dfSCaroline Tice                     current_settings->GetInstanceSettingsValue (*instance_entry, const_var_name, value);
4913df9a8dfSCaroline Tice                 }
4923df9a8dfSCaroline Tice                 else
4933df9a8dfSCaroline Tice                 {
4943df9a8dfSCaroline Tice                     // Look for instance name setting in pending settings.
4953df9a8dfSCaroline Tice 
4963df9a8dfSCaroline Tice                     std::string inst_name_str = instance_name.AsCString();
4973df9a8dfSCaroline Tice                     std::map<std::string, lldb::InstanceSettingsSP>::iterator pos;
4983df9a8dfSCaroline Tice 
4993df9a8dfSCaroline Tice                     pos = m_pending_settings.find (inst_name_str);
5003df9a8dfSCaroline Tice                     if (pos != m_pending_settings.end())
5013df9a8dfSCaroline Tice                     {
5023df9a8dfSCaroline Tice                         lldb::InstanceSettingsSP settings_sp = pos->second;
5033df9a8dfSCaroline Tice                         settings_sp->GetInstanceSettingsValue (*instance_entry, const_var_name,  value);
5043df9a8dfSCaroline Tice                     }
5053df9a8dfSCaroline Tice                     else
5063df9a8dfSCaroline Tice                     {
5073df9a8dfSCaroline Tice                         // No valid instance name; assume they want the default settings.
5083df9a8dfSCaroline Tice                         m_default_settings->GetInstanceSettingsValue (*instance_entry, const_var_name, value);
5093df9a8dfSCaroline Tice                     }
5103df9a8dfSCaroline Tice                 }
5113df9a8dfSCaroline Tice             }
5123df9a8dfSCaroline Tice             else
5133df9a8dfSCaroline Tice                 value.AppendString ("Invalid variable name");
5143df9a8dfSCaroline Tice         }
5153df9a8dfSCaroline Tice     }
5163df9a8dfSCaroline Tice     else
5173df9a8dfSCaroline Tice     {
5183df9a8dfSCaroline Tice         // Only one name left.  It must belong to the current level, or be an error.
5193df9a8dfSCaroline Tice         if ((global_entry == NULL)
5203df9a8dfSCaroline Tice             && (instance_entry == NULL))
5213df9a8dfSCaroline Tice         {
5223df9a8dfSCaroline Tice             value.AppendString ("Invalid variable name");
5233df9a8dfSCaroline Tice         }
5243df9a8dfSCaroline Tice         else if (global_entry)
5253df9a8dfSCaroline Tice         {
5263df9a8dfSCaroline Tice             var_type = global_entry->var_type;
5273df9a8dfSCaroline Tice             GetGlobalSettingsValue (const_var_name, value);
5283df9a8dfSCaroline Tice         }
5293df9a8dfSCaroline Tice         else if (instance_entry)
5303df9a8dfSCaroline Tice         {
5313df9a8dfSCaroline Tice             var_type = instance_entry->var_type;
5323df9a8dfSCaroline Tice             m_default_settings->GetInstanceSettingsValue  (*instance_entry, const_var_name, value);
5333df9a8dfSCaroline Tice         }
5343df9a8dfSCaroline Tice     }
5353df9a8dfSCaroline Tice 
5363df9a8dfSCaroline Tice     return value;
5373df9a8dfSCaroline Tice }
5383df9a8dfSCaroline Tice 
5393df9a8dfSCaroline Tice void
5403df9a8dfSCaroline Tice UserSettingsController::RemovePendingSettings (const ConstString &instance_name)
5413df9a8dfSCaroline Tice {
5423df9a8dfSCaroline Tice     std::map<std::string, lldb::InstanceSettingsSP>::iterator pos;
5433df9a8dfSCaroline Tice     std::string instance_name_str (instance_name.AsCString());
5443df9a8dfSCaroline Tice     Mutex::Locker locker (m_pending_settings_mutex);
5453df9a8dfSCaroline Tice 
5463df9a8dfSCaroline Tice     m_pending_settings.erase (instance_name_str);
5473df9a8dfSCaroline Tice }
5483df9a8dfSCaroline Tice 
5493df9a8dfSCaroline Tice const lldb::InstanceSettingsSP &
5503df9a8dfSCaroline Tice UserSettingsController::FindPendingSettings (const ConstString &instance_name)
5513df9a8dfSCaroline Tice {
5523df9a8dfSCaroline Tice     std::map<std::string, lldb::InstanceSettingsSP>::iterator pos;
5533df9a8dfSCaroline Tice     std::string instance_name_str (instance_name.AsCString());
5543df9a8dfSCaroline Tice 
5553df9a8dfSCaroline Tice     {   // Scope for mutex.
5563df9a8dfSCaroline Tice         Mutex::Locker locker (m_pending_settings_mutex);
5573df9a8dfSCaroline Tice 
5583df9a8dfSCaroline Tice         pos = m_pending_settings.find (instance_name_str);
5593df9a8dfSCaroline Tice         if (pos != m_pending_settings.end())
5603df9a8dfSCaroline Tice             return pos->second;
5613df9a8dfSCaroline Tice     }
5623df9a8dfSCaroline Tice 
5633df9a8dfSCaroline Tice     return m_default_settings;
5643df9a8dfSCaroline Tice }
5653df9a8dfSCaroline Tice 
5663df9a8dfSCaroline Tice void
5673df9a8dfSCaroline Tice UserSettingsController::CreateDefaultInstanceSettings ()
5683df9a8dfSCaroline Tice {
5693df9a8dfSCaroline Tice     Error err;
5703df9a8dfSCaroline Tice     const ConstString &default_name = InstanceSettings::GetDefaultName();
5713df9a8dfSCaroline Tice     for (int i = 0; i < m_settings.instance_settings.size(); ++i)
5723df9a8dfSCaroline Tice     {
5733df9a8dfSCaroline Tice         SettingEntry &entry = m_settings.instance_settings[i];
5743df9a8dfSCaroline Tice         ConstString var_name (entry.var_name);
5753df9a8dfSCaroline Tice         const char *value = entry.default_value;
5763df9a8dfSCaroline Tice 
5773df9a8dfSCaroline Tice         if (entry.var_type == lldb::eSetVarTypeEnum)
5783df9a8dfSCaroline Tice             value = entry.enum_values[0].string_value;
5793df9a8dfSCaroline Tice 
5803df9a8dfSCaroline Tice         m_default_settings->UpdateInstanceSettingsVariable (var_name, NULL, value, default_name, entry,
5813df9a8dfSCaroline Tice                                                             lldb::eVarSetOperationAssign, err, true);
5823df9a8dfSCaroline Tice     }
5833df9a8dfSCaroline Tice }
5843df9a8dfSCaroline Tice 
5853df9a8dfSCaroline Tice void
5863df9a8dfSCaroline Tice UserSettingsController::CopyDefaultSettings (const lldb::InstanceSettingsSP &actual_settings,
5873df9a8dfSCaroline Tice                                              const ConstString &instance_name,
5883df9a8dfSCaroline Tice                                              bool pending)
5893df9a8dfSCaroline Tice {
5903df9a8dfSCaroline Tice     Error err;
5913df9a8dfSCaroline Tice     for (int i = 0; i < m_settings.instance_settings.size(); ++i)
5923df9a8dfSCaroline Tice     {
5933df9a8dfSCaroline Tice         SettingEntry &entry = m_settings.instance_settings[i];
5943df9a8dfSCaroline Tice         ConstString var_name (entry.var_name);
5953df9a8dfSCaroline Tice         StringList value;
5963df9a8dfSCaroline Tice         m_default_settings->GetInstanceSettingsValue (entry, var_name, value);
5973df9a8dfSCaroline Tice 
5983df9a8dfSCaroline Tice         std::string value_str;
5993df9a8dfSCaroline Tice         if (value.GetSize() == 1)
6003df9a8dfSCaroline Tice             value_str.append (value.GetStringAtIndex (0));
6013df9a8dfSCaroline Tice         else if (value.GetSize() > 1)
6023df9a8dfSCaroline Tice         {
6033df9a8dfSCaroline Tice             for (int j = 0; j < value.GetSize(); ++j)
6043df9a8dfSCaroline Tice             {
6053df9a8dfSCaroline Tice                 if (j > 0)
6063df9a8dfSCaroline Tice                     value_str.append (" ");
6073df9a8dfSCaroline Tice               value_str.append (value.GetStringAtIndex (j));
6083df9a8dfSCaroline Tice             }
6093df9a8dfSCaroline Tice         }
6103df9a8dfSCaroline Tice 
6113df9a8dfSCaroline Tice         actual_settings->UpdateInstanceSettingsVariable (var_name, NULL, value_str.c_str(), instance_name, entry,
6123df9a8dfSCaroline Tice                                                          lldb::eVarSetOperationAssign, err, pending);
6133df9a8dfSCaroline Tice 
6143df9a8dfSCaroline Tice     }
6153df9a8dfSCaroline Tice }
6163df9a8dfSCaroline Tice 
6173df9a8dfSCaroline Tice lldb::InstanceSettingsSP
6183df9a8dfSCaroline Tice UserSettingsController::PendingSettingsForInstance (const ConstString &instance_name)
6193df9a8dfSCaroline Tice {
6203df9a8dfSCaroline Tice     std::string name_str (instance_name.AsCString());
6213df9a8dfSCaroline Tice     std::map<std::string, lldb::InstanceSettingsSP>::iterator pos;
6223df9a8dfSCaroline Tice     Mutex::Locker locker (m_pending_settings_mutex);
6233df9a8dfSCaroline Tice 
6243df9a8dfSCaroline Tice     pos = m_pending_settings.find (name_str);
6253df9a8dfSCaroline Tice     if (pos != m_pending_settings.end())
6263df9a8dfSCaroline Tice       {
6273df9a8dfSCaroline Tice         lldb::InstanceSettingsSP settings_sp = pos->second;
6283df9a8dfSCaroline Tice         return settings_sp;
6293df9a8dfSCaroline Tice       }
6303df9a8dfSCaroline Tice     else
6313df9a8dfSCaroline Tice       {
6323df9a8dfSCaroline Tice         lldb::InstanceSettingsSP default_settings_sp =
6333df9a8dfSCaroline Tice                                                    m_pending_settings[InstanceSettings::GetDefaultName().AsCString()];
6343df9a8dfSCaroline Tice         lldb::InstanceSettingsSP new_settings_sp = CreateNewInstanceSettings ();
6353df9a8dfSCaroline Tice         CopyDefaultSettings (new_settings_sp, instance_name, true);
6363df9a8dfSCaroline Tice         m_pending_settings[name_str] = new_settings_sp;
6373df9a8dfSCaroline Tice         return new_settings_sp;
6383df9a8dfSCaroline Tice       }
6393df9a8dfSCaroline Tice 
6403df9a8dfSCaroline Tice     // Should never reach this line.
6413df9a8dfSCaroline Tice 
6423df9a8dfSCaroline Tice     lldb::InstanceSettingsSP dummy;
6433df9a8dfSCaroline Tice 
6443df9a8dfSCaroline Tice     return dummy;
6453df9a8dfSCaroline Tice }
6463df9a8dfSCaroline Tice 
6473df9a8dfSCaroline Tice void
6483df9a8dfSCaroline Tice UserSettingsController::GetAllDefaultSettingValues (StreamString &result_stream)
6493df9a8dfSCaroline Tice {
6503df9a8dfSCaroline Tice     std::string parent_prefix;
6513df9a8dfSCaroline Tice     BuildParentPrefix (parent_prefix);
6523df9a8dfSCaroline Tice     const char *prefix = parent_prefix.c_str();
6533df9a8dfSCaroline Tice 
6543df9a8dfSCaroline Tice     for (int i = 0; i < m_settings.instance_settings.size(); ++i)
6553df9a8dfSCaroline Tice     {
6563df9a8dfSCaroline Tice         SettingEntry &entry = m_settings.instance_settings[i];
6573df9a8dfSCaroline Tice         ConstString var_name (entry.var_name);
6583df9a8dfSCaroline Tice         StringList tmp_value;
6593df9a8dfSCaroline Tice         m_default_settings->GetInstanceSettingsValue (entry, var_name, tmp_value);
6603df9a8dfSCaroline Tice 
6613df9a8dfSCaroline Tice         StreamString value_string;
6623df9a8dfSCaroline Tice 
6633df9a8dfSCaroline Tice         if (tmp_value.GetSize() == 1)
6643df9a8dfSCaroline Tice             value_string.Printf ("%s", tmp_value.GetStringAtIndex (0));
6653df9a8dfSCaroline Tice         else
6663df9a8dfSCaroline Tice         {
6673df9a8dfSCaroline Tice             for (int j = 0; j < tmp_value.GetSize(); ++j)
6683df9a8dfSCaroline Tice                 value_string.Printf ("%s ", tmp_value.GetStringAtIndex (j));
6693df9a8dfSCaroline Tice         }
6703df9a8dfSCaroline Tice 
6713df9a8dfSCaroline Tice         if (! parent_prefix.empty()) // May need to test size() > 0
6723df9a8dfSCaroline Tice             result_stream.Printf ("%s.[DEFAULT].%s (%s) = '%s'\n", prefix, var_name.AsCString(),
6733df9a8dfSCaroline Tice                                   UserSettingsController::GetTypeString (entry.var_type), value_string.GetData());
6743df9a8dfSCaroline Tice         else
6753df9a8dfSCaroline Tice             result_stream.Printf ("[DEFAULT].%s (%s) = '%s'\n", var_name.AsCString(),
6763df9a8dfSCaroline Tice                                   UserSettingsController::GetTypeString (entry.var_type), value_string.GetData());
6773df9a8dfSCaroline Tice     }
6783df9a8dfSCaroline Tice }
6793df9a8dfSCaroline Tice 
6803df9a8dfSCaroline Tice void
6813df9a8dfSCaroline Tice UserSettingsController::GetAllPendingSettingValues (StreamString &result_stream)
6823df9a8dfSCaroline Tice {
6833df9a8dfSCaroline Tice     //StreamString description;
6843df9a8dfSCaroline Tice     std::map<std::string, lldb::InstanceSettingsSP>::iterator pos;
6853df9a8dfSCaroline Tice 
6863df9a8dfSCaroline Tice     std::string parent_prefix;
6873df9a8dfSCaroline Tice     BuildParentPrefix (parent_prefix);
6883df9a8dfSCaroline Tice     const char *prefix = parent_prefix.c_str();
6893df9a8dfSCaroline Tice 
6903df9a8dfSCaroline Tice     for (pos = m_pending_settings.begin(); pos != m_pending_settings.end(); ++pos)
6913df9a8dfSCaroline Tice     {
6923df9a8dfSCaroline Tice         std::string tmp_name = pos->first;
6933df9a8dfSCaroline Tice         lldb::InstanceSettingsSP settings_sp = pos->second;
6943df9a8dfSCaroline Tice 
6953df9a8dfSCaroline Tice         const ConstString instance_name (tmp_name.c_str());
6963df9a8dfSCaroline Tice 
6973df9a8dfSCaroline Tice         for (int i = 0; i < m_settings.instance_settings.size(); ++i)
6983df9a8dfSCaroline Tice         {
6993df9a8dfSCaroline Tice             SettingEntry &entry = m_settings.instance_settings[i];
7003df9a8dfSCaroline Tice             ConstString var_name (entry.var_name);
7013df9a8dfSCaroline Tice             StringList tmp_value;
7023df9a8dfSCaroline Tice             settings_sp->GetInstanceSettingsValue (entry, var_name, tmp_value);
7033df9a8dfSCaroline Tice 
7043df9a8dfSCaroline Tice             StreamString value_str;
7053df9a8dfSCaroline Tice 
7063df9a8dfSCaroline Tice             if (tmp_value.GetSize() == 0)
7073df9a8dfSCaroline Tice                 break;
7083df9a8dfSCaroline Tice             if (tmp_value.GetSize() == 1)
7093df9a8dfSCaroline Tice                 value_str.Printf ("%s", tmp_value.GetStringAtIndex (0));
7103df9a8dfSCaroline Tice             else
7113df9a8dfSCaroline Tice             {
7123df9a8dfSCaroline Tice                 for (int j = 0; j < tmp_value.GetSize(); ++j)
7133df9a8dfSCaroline Tice                     value_str.Printf  ("%s ", tmp_value.GetStringAtIndex (j));
7143df9a8dfSCaroline Tice             }
7153df9a8dfSCaroline Tice 
7163df9a8dfSCaroline Tice             if (parent_prefix.length() > 0)
7173df9a8dfSCaroline Tice             {
7183df9a8dfSCaroline Tice                 result_stream.Printf ("%s.%s.%s (%s) = '%s' [pending]\n", prefix, instance_name.AsCString(),
7193df9a8dfSCaroline Tice                                       var_name.AsCString(), UserSettingsController::GetTypeString (entry.var_type),
7203df9a8dfSCaroline Tice                                       value_str.GetData());
7213df9a8dfSCaroline Tice             }
7223df9a8dfSCaroline Tice             else
7233df9a8dfSCaroline Tice             {
7243df9a8dfSCaroline Tice                 result_stream.Printf ("%s (%s) = '%s' [pending]\n", var_name.AsCString(),
7253df9a8dfSCaroline Tice                                       UserSettingsController::GetTypeString (entry.var_type),
7263df9a8dfSCaroline Tice                                       value_str.GetData());
7273df9a8dfSCaroline Tice             }
7283df9a8dfSCaroline Tice         }
7293df9a8dfSCaroline Tice     }
7303df9a8dfSCaroline Tice }
7313df9a8dfSCaroline Tice 
7323df9a8dfSCaroline Tice InstanceSettings *
7333df9a8dfSCaroline Tice UserSettingsController::FindSettingsForInstance (const ConstString &instance_name)
7343df9a8dfSCaroline Tice {
7353df9a8dfSCaroline Tice     std::string instance_name_str (instance_name.AsCString());
7363df9a8dfSCaroline Tice     std::map<std::string, InstanceSettings *>::iterator pos;
7373df9a8dfSCaroline Tice 
7383df9a8dfSCaroline Tice     pos = m_live_settings.find (instance_name_str);
7393df9a8dfSCaroline Tice     if (pos != m_live_settings.end ())
7403df9a8dfSCaroline Tice       {
7413df9a8dfSCaroline Tice         InstanceSettings *settings = pos->second;
7423df9a8dfSCaroline Tice         return settings;
7433df9a8dfSCaroline Tice       }
7443df9a8dfSCaroline Tice 
7453df9a8dfSCaroline Tice     return NULL;
7463df9a8dfSCaroline Tice }
7473df9a8dfSCaroline Tice 
7483df9a8dfSCaroline Tice void
7493df9a8dfSCaroline Tice UserSettingsController::GetAllInstanceVariableValues (CommandInterpreter &interpreter,
7503df9a8dfSCaroline Tice                                                       StreamString &result_stream)
7513df9a8dfSCaroline Tice {
7523df9a8dfSCaroline Tice     std::map<std::string, InstanceSettings *>::iterator pos;
7533df9a8dfSCaroline Tice     std::string parent_prefix;
7543df9a8dfSCaroline Tice     BuildParentPrefix (parent_prefix);
7553df9a8dfSCaroline Tice     const char *prefix = parent_prefix.c_str();
7563df9a8dfSCaroline Tice     StreamString description;
7573df9a8dfSCaroline Tice 
7583df9a8dfSCaroline Tice     for (pos = m_live_settings.begin(); pos != m_live_settings.end(); ++pos)
7593df9a8dfSCaroline Tice     {
7603df9a8dfSCaroline Tice         std::string instance_name = pos->first;
7613df9a8dfSCaroline Tice         InstanceSettings *settings = pos->second;
7623df9a8dfSCaroline Tice 
7633df9a8dfSCaroline Tice         for (int i = 0; i < m_settings.instance_settings.size(); ++i)
7643df9a8dfSCaroline Tice         {
7653df9a8dfSCaroline Tice             SettingEntry &entry = m_settings.instance_settings[i];
7663df9a8dfSCaroline Tice             const ConstString var_name (entry.var_name);
7673df9a8dfSCaroline Tice             StringList tmp_value;
7683df9a8dfSCaroline Tice             settings->GetInstanceSettingsValue (entry, var_name, tmp_value);
7693df9a8dfSCaroline Tice             StreamString tmp_value_str;
7703df9a8dfSCaroline Tice 
7713df9a8dfSCaroline Tice             if (tmp_value.GetSize() == 0)
7723df9a8dfSCaroline Tice                 break;
7733df9a8dfSCaroline Tice 
7743df9a8dfSCaroline Tice             if (tmp_value.GetSize() == 1)
7753df9a8dfSCaroline Tice                 tmp_value_str.Printf ("%s", tmp_value.GetStringAtIndex (0));
7763df9a8dfSCaroline Tice             else
7773df9a8dfSCaroline Tice             {
7783df9a8dfSCaroline Tice                 for (int j = 0; j < tmp_value.GetSize(); ++j)
7793df9a8dfSCaroline Tice                     tmp_value_str.Printf ("%s ",tmp_value.GetStringAtIndex (j));
7803df9a8dfSCaroline Tice             }
7813df9a8dfSCaroline Tice 
7823df9a8dfSCaroline Tice             description.Clear();
7833df9a8dfSCaroline Tice             if (parent_prefix.length() > 0)
7843df9a8dfSCaroline Tice             {
7853df9a8dfSCaroline Tice                 description.Printf ("%s.%s.%s (%s) = '%s'", prefix, instance_name.c_str(), var_name.AsCString(),
7863df9a8dfSCaroline Tice                                     UserSettingsController::GetTypeString (entry.var_type),
7873df9a8dfSCaroline Tice                                     tmp_value_str.GetData());
7883df9a8dfSCaroline Tice             }
7893df9a8dfSCaroline Tice             else
7903df9a8dfSCaroline Tice             {
7913df9a8dfSCaroline Tice                 description.Printf ("%s (%s) = '%s'", var_name.AsCString(),
7923df9a8dfSCaroline Tice                                     UserSettingsController::GetTypeString (entry.var_type), tmp_value_str.GetData());
7933df9a8dfSCaroline Tice             }
7943df9a8dfSCaroline Tice             result_stream.Printf ("%s\n", description.GetData());
7953df9a8dfSCaroline Tice         }
7963df9a8dfSCaroline Tice     }
7973df9a8dfSCaroline Tice }
7983df9a8dfSCaroline Tice 
7993df9a8dfSCaroline Tice void
8003df9a8dfSCaroline Tice UserSettingsController::OverrideAllInstances (const ConstString &var_name,
8013df9a8dfSCaroline Tice                                               const char *value,
8023df9a8dfSCaroline Tice                                               lldb::VarSetOperationType op,
8033df9a8dfSCaroline Tice                                               const char *index_value,
8043df9a8dfSCaroline Tice                                               Error &err)
8053df9a8dfSCaroline Tice {
8063df9a8dfSCaroline Tice     std::map<std::string, InstanceSettings *>::iterator pos;
8073df9a8dfSCaroline Tice     StreamString description;
8083df9a8dfSCaroline Tice 
8093df9a8dfSCaroline Tice     for (pos = m_live_settings.begin(); pos != m_live_settings.end(); ++pos)
8103df9a8dfSCaroline Tice     {
8113df9a8dfSCaroline Tice         InstanceSettings *settings = pos->second;
8123df9a8dfSCaroline Tice         StreamString tmp_name;
8133df9a8dfSCaroline Tice         tmp_name.Printf ("[%s]", settings->GetInstanceName().AsCString());
8143df9a8dfSCaroline Tice         const ConstString instance_name (tmp_name.GetData());
8153df9a8dfSCaroline Tice         const SettingEntry *entry = GetInstanceEntry (var_name);
8163df9a8dfSCaroline Tice         settings->UpdateInstanceSettingsVariable (var_name, index_value, value, instance_name, *entry, op, err, false);
8173df9a8dfSCaroline Tice 
8183df9a8dfSCaroline Tice     }
8193df9a8dfSCaroline Tice }
8203df9a8dfSCaroline Tice 
8213df9a8dfSCaroline Tice void
8223df9a8dfSCaroline Tice UserSettingsController::RegisterInstanceSettings (InstanceSettings *instance_settings)
8233df9a8dfSCaroline Tice {
8243df9a8dfSCaroline Tice     Mutex::Locker locker (m_live_settings_mutex);
8253df9a8dfSCaroline Tice     StreamString tmp_name;
8263df9a8dfSCaroline Tice     tmp_name.Printf ("[%s]", instance_settings->GetInstanceName().AsCString());
8273df9a8dfSCaroline Tice     const ConstString instance_name (tmp_name.GetData());
8283df9a8dfSCaroline Tice     std::string instance_name_str (instance_name.AsCString());
8293df9a8dfSCaroline Tice     if (instance_name_str.compare (InstanceSettings::GetDefaultName().AsCString()) != 0)
8303df9a8dfSCaroline Tice         m_live_settings[instance_name_str] = instance_settings;
8313df9a8dfSCaroline Tice }
8323df9a8dfSCaroline Tice 
8333df9a8dfSCaroline Tice void
8343df9a8dfSCaroline Tice UserSettingsController::UnregisterInstanceSettings (InstanceSettings *instance)
8353df9a8dfSCaroline Tice {
8363df9a8dfSCaroline Tice     Mutex::Locker locker (m_live_settings_mutex);
8373df9a8dfSCaroline Tice     StreamString tmp_name;
8383df9a8dfSCaroline Tice     tmp_name.Printf ("[%s]", instance->GetInstanceName().AsCString());
8393df9a8dfSCaroline Tice     std::string instance_name (tmp_name.GetData());
8403df9a8dfSCaroline Tice 
8413df9a8dfSCaroline Tice     std::map <std::string, InstanceSettings *>::iterator pos;
8423df9a8dfSCaroline Tice 
8433df9a8dfSCaroline Tice     pos = m_live_settings.find (instance_name);
8443df9a8dfSCaroline Tice     if (pos != m_live_settings.end())
8453df9a8dfSCaroline Tice         m_live_settings.erase (pos);
8463df9a8dfSCaroline Tice }
8473df9a8dfSCaroline Tice 
8483df9a8dfSCaroline Tice void
8493df9a8dfSCaroline Tice UserSettingsController::CreateSettingsVector (const SettingEntry *table,
8503df9a8dfSCaroline Tice                                               bool global)
8513df9a8dfSCaroline Tice {
8523df9a8dfSCaroline Tice     int i = 0;
8533df9a8dfSCaroline Tice     while (table[i].var_name != NULL)
8543df9a8dfSCaroline Tice     {
8553df9a8dfSCaroline Tice         const SettingEntry &table_entry = table[i];
8563df9a8dfSCaroline Tice         ConstString const_var_name (table_entry.var_name);
8573df9a8dfSCaroline Tice         SettingEntry new_entry;
8583df9a8dfSCaroline Tice 
8593df9a8dfSCaroline Tice         new_entry = table_entry;
8603df9a8dfSCaroline Tice         new_entry.var_name = const_var_name.AsCString();
8613df9a8dfSCaroline Tice 
8623df9a8dfSCaroline Tice         if (global)
8633df9a8dfSCaroline Tice             m_settings.global_settings.push_back (new_entry);
8643df9a8dfSCaroline Tice         else
8653df9a8dfSCaroline Tice             m_settings.instance_settings.push_back (new_entry);
8663df9a8dfSCaroline Tice 
8673df9a8dfSCaroline Tice         ++i;
8683df9a8dfSCaroline Tice     }
8693df9a8dfSCaroline Tice }
8703df9a8dfSCaroline Tice 
8713df9a8dfSCaroline Tice //----------------------------------------------------------------------
8723df9a8dfSCaroline Tice // UserSettingsController static methods
8733df9a8dfSCaroline Tice //----------------------------------------------------------------------
8743df9a8dfSCaroline Tice 
8753df9a8dfSCaroline Tice int
8763df9a8dfSCaroline Tice FindMaxNameLength (std::vector<SettingEntry> table)
8773df9a8dfSCaroline Tice {
8783df9a8dfSCaroline Tice     int max_length = 1;
8793df9a8dfSCaroline Tice 
8803df9a8dfSCaroline Tice     for (int i = 0; i < table.size(); ++i)
8813df9a8dfSCaroline Tice     {
8823df9a8dfSCaroline Tice         int len = strlen (table[i].var_name);
8833df9a8dfSCaroline Tice         if (len > max_length)
8843df9a8dfSCaroline Tice             max_length = len;
8853df9a8dfSCaroline Tice     }
8863df9a8dfSCaroline Tice 
8873df9a8dfSCaroline Tice     return max_length;
8883df9a8dfSCaroline Tice }
8893df9a8dfSCaroline Tice 
8903df9a8dfSCaroline Tice const char *
8913df9a8dfSCaroline Tice UserSettingsController::GetTypeString (lldb::SettableVariableType var_type)
8923df9a8dfSCaroline Tice {
8933df9a8dfSCaroline Tice     switch (var_type)
8943df9a8dfSCaroline Tice     {
8953df9a8dfSCaroline Tice         case lldb::eSetVarTypeInt:
8963df9a8dfSCaroline Tice             return "int";
8973df9a8dfSCaroline Tice         case lldb::eSetVarTypeBool:
8983df9a8dfSCaroline Tice             return "boolean";
8993df9a8dfSCaroline Tice         case lldb::eSetVarTypeString:
9003df9a8dfSCaroline Tice             return "string";
9013df9a8dfSCaroline Tice         case lldb::eSetVarTypeArray:
9023df9a8dfSCaroline Tice             return "array";
9033df9a8dfSCaroline Tice         case lldb::eSetVarTypeDictionary:
9043df9a8dfSCaroline Tice             return "dictionary";
9053df9a8dfSCaroline Tice         case lldb::eSetVarTypeEnum:
9063df9a8dfSCaroline Tice             return "enum";
9073df9a8dfSCaroline Tice         case lldb::eSetVarTypeNone:
9083df9a8dfSCaroline Tice             return "no type";
9093df9a8dfSCaroline Tice     }
9103df9a8dfSCaroline Tice 
9113df9a8dfSCaroline Tice     return "";
9123df9a8dfSCaroline Tice }
9133df9a8dfSCaroline Tice 
9143df9a8dfSCaroline Tice void
9153df9a8dfSCaroline Tice UserSettingsController::PrintEnumValues (const lldb::OptionEnumValueElement *enum_values, Stream &str)
9163df9a8dfSCaroline Tice {
9173df9a8dfSCaroline Tice     int i = 0;
9183df9a8dfSCaroline Tice     while (enum_values[i].string_value != NULL)
9193df9a8dfSCaroline Tice     {
9203df9a8dfSCaroline Tice         str.Printf ("%s ", enum_values[i].string_value);
9213df9a8dfSCaroline Tice         ++i;
9223df9a8dfSCaroline Tice     }
9233df9a8dfSCaroline Tice 
9243df9a8dfSCaroline Tice }
9253df9a8dfSCaroline Tice 
9263df9a8dfSCaroline Tice void
9273df9a8dfSCaroline Tice UserSettingsController::FindAllSettingsDescriptions (CommandInterpreter &interpreter,
9283df9a8dfSCaroline Tice                                                      lldb::UserSettingsControllerSP root,
9293df9a8dfSCaroline Tice                                                      std::string &current_prefix,
9303df9a8dfSCaroline Tice                                                      StreamString &result_stream,
9313df9a8dfSCaroline Tice                                                      Error &err)
9323df9a8dfSCaroline Tice {
9333df9a8dfSCaroline Tice     // Write out current prefix line.
9343df9a8dfSCaroline Tice     StreamString prefix_line;
9353df9a8dfSCaroline Tice     StreamString description;
9363df9a8dfSCaroline Tice     uint32_t max_len;
9373df9a8dfSCaroline Tice     int num_entries = root->m_settings.global_settings.size();
9383df9a8dfSCaroline Tice 
9393df9a8dfSCaroline Tice     max_len = FindMaxNameLength (root->m_settings.global_settings);
9403df9a8dfSCaroline Tice 
9413df9a8dfSCaroline Tice     if (! current_prefix.empty())
9423df9a8dfSCaroline Tice         result_stream.Printf ("\n'%s' variables:\n\n", current_prefix.c_str());
9433df9a8dfSCaroline Tice     else
9443df9a8dfSCaroline Tice         result_stream.Printf ("\nTop level variables:\n\n");
9453df9a8dfSCaroline Tice 
9463df9a8dfSCaroline Tice     if (num_entries > 0)
9473df9a8dfSCaroline Tice     {
9483df9a8dfSCaroline Tice         // Write out all "global" variables.
9493df9a8dfSCaroline Tice         for (int i = 0; i < num_entries; ++i)
9503df9a8dfSCaroline Tice         {
9513df9a8dfSCaroline Tice             SettingEntry entry = root->m_settings.global_settings[i];
9523df9a8dfSCaroline Tice             description.Clear();
9533df9a8dfSCaroline Tice             if (entry.var_type == lldb::eSetVarTypeEnum)
9543df9a8dfSCaroline Tice             {
9553df9a8dfSCaroline Tice                 StreamString enum_values_str;
9563df9a8dfSCaroline Tice                 UserSettingsController::PrintEnumValues (entry.enum_values, enum_values_str);
9573df9a8dfSCaroline Tice                 description.Printf ("[static, enum] %s.  Valid values: {%s}  (default: '%s')", entry.description,
9583df9a8dfSCaroline Tice                                     enum_values_str.GetData(), entry.enum_values[0].string_value);
9593df9a8dfSCaroline Tice             }
9603df9a8dfSCaroline Tice             else if (entry.default_value != NULL)
9613df9a8dfSCaroline Tice                 description.Printf ("[static, %s] %s (default: '%s')", GetTypeString (entry.var_type),
9623df9a8dfSCaroline Tice                                     entry.description, entry.default_value);
9633df9a8dfSCaroline Tice 
9643df9a8dfSCaroline Tice             else
9653df9a8dfSCaroline Tice                 description.Printf ("[static, %s] %s (default: '')", GetTypeString (entry.var_type),
9663df9a8dfSCaroline Tice                                     entry.description);
9673df9a8dfSCaroline Tice             interpreter.OutputFormattedHelpText (result_stream, entry.var_name, "--", description.GetData(),
9683df9a8dfSCaroline Tice                                                  max_len);
9693df9a8dfSCaroline Tice         }
9703df9a8dfSCaroline Tice     }
9713df9a8dfSCaroline Tice 
9723df9a8dfSCaroline Tice     num_entries = root->m_settings.instance_settings.size();
9733df9a8dfSCaroline Tice     max_len = FindMaxNameLength (root->m_settings.instance_settings);
9743df9a8dfSCaroline Tice 
9753df9a8dfSCaroline Tice     if (num_entries > 0)
9763df9a8dfSCaroline Tice     {
9773df9a8dfSCaroline Tice         // Write out all instance variables.
9783df9a8dfSCaroline Tice         for (int i = 0; i < num_entries; ++i)
9793df9a8dfSCaroline Tice         {
9803df9a8dfSCaroline Tice             SettingEntry entry = root->m_settings.instance_settings[i];
9813df9a8dfSCaroline Tice             description.Clear();
9823df9a8dfSCaroline Tice             if (entry.var_type == lldb::eSetVarTypeEnum)
9833df9a8dfSCaroline Tice             {
9843df9a8dfSCaroline Tice                 StreamString enum_values_str;
9853df9a8dfSCaroline Tice                 UserSettingsController::PrintEnumValues (entry.enum_values, enum_values_str);
9863df9a8dfSCaroline Tice                 description.Printf ("[instance, enum] %s.  Valid values: {%s} (default: '%s')", entry.description,
9873df9a8dfSCaroline Tice                                     enum_values_str.GetData(), entry.enum_values[0].string_value);
9883df9a8dfSCaroline Tice             }
9893df9a8dfSCaroline Tice             else if (entry.default_value != NULL)
9903df9a8dfSCaroline Tice                 description.Printf ("[instance, %s] %s (default: '%s')", GetTypeString (entry.var_type),
9913df9a8dfSCaroline Tice                                     entry.description, entry.default_value);
9923df9a8dfSCaroline Tice             else
9933df9a8dfSCaroline Tice                 description.Printf ("[instance, %s] %s (default: '')", GetTypeString (entry.var_type),
9943df9a8dfSCaroline Tice                                     entry.description);
9953df9a8dfSCaroline Tice             interpreter.OutputFormattedHelpText (result_stream, entry.var_name, "--", description.GetData(),
9963df9a8dfSCaroline Tice                                                  max_len);
9973df9a8dfSCaroline Tice         }
9983df9a8dfSCaroline Tice 
9993df9a8dfSCaroline Tice     }
10003df9a8dfSCaroline Tice 
10013df9a8dfSCaroline Tice     // Now, recurse across all children.
10023df9a8dfSCaroline Tice     int num_children = root->GetNumChildren();
10033df9a8dfSCaroline Tice     for (int i = 0; i < num_children; ++i)
10043df9a8dfSCaroline Tice     {
10053df9a8dfSCaroline Tice         lldb::UserSettingsControllerSP child = root->GetChildAtIndex (i);
10063df9a8dfSCaroline Tice 
10073df9a8dfSCaroline Tice         if (child)
10083df9a8dfSCaroline Tice         {
10093df9a8dfSCaroline Tice             ConstString child_prefix = child->GetLevelName();
10103df9a8dfSCaroline Tice             StreamString new_prefix;
10113df9a8dfSCaroline Tice             if (! current_prefix.empty() ) // May need to see if size() > 0
10123df9a8dfSCaroline Tice                 new_prefix.Printf ("%s.%s", current_prefix.c_str(), child_prefix.AsCString());
10133df9a8dfSCaroline Tice             else
10143df9a8dfSCaroline Tice                 new_prefix.Printf ("%s", child_prefix.AsCString());
10153df9a8dfSCaroline Tice             std::string new_prefix_str = new_prefix.GetData();
10163df9a8dfSCaroline Tice             UserSettingsController::FindAllSettingsDescriptions (interpreter, child, new_prefix_str, result_stream,
10173df9a8dfSCaroline Tice                                                                  err);
10183df9a8dfSCaroline Tice         }
10193df9a8dfSCaroline Tice     }
10203df9a8dfSCaroline Tice }
10213df9a8dfSCaroline Tice 
10223df9a8dfSCaroline Tice void
10233df9a8dfSCaroline Tice UserSettingsController::GetAllVariableValues (CommandInterpreter &interpreter,
10243df9a8dfSCaroline Tice                                               lldb::UserSettingsControllerSP root,
10253df9a8dfSCaroline Tice                                               std::string &current_prefix,
10263df9a8dfSCaroline Tice                                               StreamString &result_stream,
10273df9a8dfSCaroline Tice                                               Error &err)
10283df9a8dfSCaroline Tice {
10293df9a8dfSCaroline Tice     StreamString description;
10303df9a8dfSCaroline Tice     int num_entries = root->m_settings.global_settings.size();
10313df9a8dfSCaroline Tice     lldb::SettableVariableType var_type;
10323df9a8dfSCaroline Tice 
10333df9a8dfSCaroline Tice 
10343df9a8dfSCaroline Tice     for (int i = 0; i < num_entries; ++i)
10353df9a8dfSCaroline Tice     {
10363df9a8dfSCaroline Tice         StreamString full_var_name;
10373df9a8dfSCaroline Tice         SettingEntry entry = root->m_settings.global_settings[i];
10383df9a8dfSCaroline Tice         if (! current_prefix.empty())  // May need to see if size() > 0
10393df9a8dfSCaroline Tice             full_var_name.Printf ("%s.%s", current_prefix.c_str(), entry.var_name);
10403df9a8dfSCaroline Tice         else
10413df9a8dfSCaroline Tice             full_var_name.Printf ("%s", entry.var_name);
10423df9a8dfSCaroline Tice         StringList value = root->GetVariable (full_var_name.GetData(), var_type);
10433df9a8dfSCaroline Tice         description.Clear();
10443df9a8dfSCaroline Tice         if (value.GetSize() == 1)
1045*49e2737eSCaroline Tice             description.Printf ("%s (%s) = '%s'", full_var_name.GetData(), GetTypeString (entry.var_type),
10463df9a8dfSCaroline Tice                                 value.GetStringAtIndex (0));
10473df9a8dfSCaroline Tice         else
10483df9a8dfSCaroline Tice         {
1049*49e2737eSCaroline Tice             description.Printf ("%s (%s) = '", full_var_name.GetData(), GetTypeString (entry.var_type));
10503df9a8dfSCaroline Tice             for (int j = 0; j < value.GetSize(); ++j)
10513df9a8dfSCaroline Tice                 description.Printf ("%s ", value.GetStringAtIndex (j));
1052*49e2737eSCaroline Tice             description.Printf ("'");
10533df9a8dfSCaroline Tice         }
10543df9a8dfSCaroline Tice 
10553df9a8dfSCaroline Tice         result_stream.Printf ("%s\n", description.GetData());
10563df9a8dfSCaroline Tice     }
10573df9a8dfSCaroline Tice 
10583df9a8dfSCaroline Tice     root->GetAllInstanceVariableValues (interpreter, result_stream);
10593df9a8dfSCaroline Tice     root->GetAllPendingSettingValues (result_stream);
10603df9a8dfSCaroline Tice     root->GetAllDefaultSettingValues (result_stream);
10613df9a8dfSCaroline Tice 
10623df9a8dfSCaroline Tice 
10633df9a8dfSCaroline Tice     // Now, recurse across all children.
10643df9a8dfSCaroline Tice     int num_children = root->GetNumChildren();
10653df9a8dfSCaroline Tice     for (int i = 0; i < num_children; ++i)
10663df9a8dfSCaroline Tice     {
10673df9a8dfSCaroline Tice         lldb::UserSettingsControllerSP child = root->GetChildAtIndex (i);
10683df9a8dfSCaroline Tice 
10693df9a8dfSCaroline Tice         if (child)
10703df9a8dfSCaroline Tice         {
10713df9a8dfSCaroline Tice             ConstString child_prefix = child->GetLevelName();
10723df9a8dfSCaroline Tice             StreamString new_prefix;
10733df9a8dfSCaroline Tice             if (! current_prefix.empty()) // May need to see if size() > 0
10743df9a8dfSCaroline Tice                 new_prefix.Printf ("%s.%s", current_prefix.c_str(), child_prefix.AsCString());
10753df9a8dfSCaroline Tice             else
10763df9a8dfSCaroline Tice                 new_prefix.Printf ("%s", child_prefix.AsCString());
10773df9a8dfSCaroline Tice             std::string new_prefix_str = new_prefix.GetData();
10783df9a8dfSCaroline Tice             UserSettingsController::GetAllVariableValues (interpreter, child, new_prefix_str, result_stream,
10793df9a8dfSCaroline Tice                                                           err);
10803df9a8dfSCaroline Tice         }
10813df9a8dfSCaroline Tice     }
10823df9a8dfSCaroline Tice 
10833df9a8dfSCaroline Tice }
10843df9a8dfSCaroline Tice 
10853df9a8dfSCaroline Tice Args
10863df9a8dfSCaroline Tice UserSettingsController::BreakNameIntoPieces (const char *full_dot_name)
10873df9a8dfSCaroline Tice {
10883df9a8dfSCaroline Tice     Args return_value;
10893df9a8dfSCaroline Tice     std::string name_string (full_dot_name);
10903df9a8dfSCaroline Tice     bool done = false;
10913df9a8dfSCaroline Tice 
10923df9a8dfSCaroline Tice     std::string piece;
10933df9a8dfSCaroline Tice     std::string remainder (full_dot_name);
10943df9a8dfSCaroline Tice 
10953df9a8dfSCaroline Tice     while (!done)
10963df9a8dfSCaroline Tice     {
10973df9a8dfSCaroline Tice         size_t idx = remainder.find_first_of ('.');
10983df9a8dfSCaroline Tice         piece = remainder.substr (0, idx);
10993df9a8dfSCaroline Tice         return_value.AppendArgument (piece.c_str());
11003df9a8dfSCaroline Tice         if (idx != std::string::npos)
11013df9a8dfSCaroline Tice             remainder = remainder.substr (idx+1);
11023df9a8dfSCaroline Tice         else
11033df9a8dfSCaroline Tice             done = true;
11043df9a8dfSCaroline Tice     }
11053df9a8dfSCaroline Tice 
11063df9a8dfSCaroline Tice     return return_value;
11073df9a8dfSCaroline Tice }
11083df9a8dfSCaroline Tice 
11093df9a8dfSCaroline Tice bool
11103df9a8dfSCaroline Tice UserSettingsController::IsLiveInstance (const std::string &instance_name)
11113df9a8dfSCaroline Tice {
11123df9a8dfSCaroline Tice     std::map<std::string, InstanceSettings *>::iterator pos;
11133df9a8dfSCaroline Tice 
11143df9a8dfSCaroline Tice     pos = m_live_settings.find (instance_name);
11153df9a8dfSCaroline Tice     if (pos != m_live_settings.end())
11163df9a8dfSCaroline Tice         return true;
11173df9a8dfSCaroline Tice 
11183df9a8dfSCaroline Tice     return false;
11193df9a8dfSCaroline Tice }
11203df9a8dfSCaroline Tice 
11213df9a8dfSCaroline Tice int
11223df9a8dfSCaroline Tice UserSettingsController::CompleteSettingsValue (lldb::UserSettingsControllerSP root_settings,
11233df9a8dfSCaroline Tice                                                const char *full_dot_name,
11243df9a8dfSCaroline Tice                                                const char *partial_value,
11253df9a8dfSCaroline Tice                                                bool &word_complete,
11263df9a8dfSCaroline Tice                                                StringList &matches)
11273df9a8dfSCaroline Tice {
11283df9a8dfSCaroline Tice     Args names = UserSettingsController::BreakNameIntoPieces (full_dot_name);
11293df9a8dfSCaroline Tice     int num_pieces = names.GetArgumentCount();
11303df9a8dfSCaroline Tice     word_complete = true;
11313df9a8dfSCaroline Tice 
11323df9a8dfSCaroline Tice     ConstString root_level = root_settings->GetLevelName();
11333df9a8dfSCaroline Tice     int num_extra_levels = num_pieces - 2;
11343df9a8dfSCaroline Tice     if ((num_extra_levels > 0)
11353df9a8dfSCaroline Tice         && root_level.GetLength() > 0)
11363df9a8dfSCaroline Tice     {
11373df9a8dfSCaroline Tice         ConstString current_level (names.GetArgumentAtIndex (0));
11383df9a8dfSCaroline Tice         if (current_level == root_level)
11393df9a8dfSCaroline Tice         {
11403df9a8dfSCaroline Tice             names.Shift();
11413df9a8dfSCaroline Tice             --num_extra_levels;
11423df9a8dfSCaroline Tice         }
11433df9a8dfSCaroline Tice         else
11443df9a8dfSCaroline Tice             return 0;
11453df9a8dfSCaroline Tice     }
11463df9a8dfSCaroline Tice 
11473df9a8dfSCaroline Tice     for (int i = 0; i < num_extra_levels; ++i)
11483df9a8dfSCaroline Tice     {
11493df9a8dfSCaroline Tice         ConstString child_level (names.GetArgumentAtIndex (0));
11503df9a8dfSCaroline Tice         bool found = false;
11513df9a8dfSCaroline Tice         int num_children = root_settings->GetNumChildren();
11523df9a8dfSCaroline Tice         for (int j = 0; j < num_children && !found; ++j)
11533df9a8dfSCaroline Tice         {
11543df9a8dfSCaroline Tice             if (root_settings->GetChildAtIndex (j)->GetLevelName() == child_level)
11553df9a8dfSCaroline Tice             {
11563df9a8dfSCaroline Tice                 found = true;
11573df9a8dfSCaroline Tice                 root_settings = root_settings->GetChildAtIndex (j);
11583df9a8dfSCaroline Tice                 names.Shift();
11593df9a8dfSCaroline Tice             }
11603df9a8dfSCaroline Tice         }
11613df9a8dfSCaroline Tice         if (!found)
11623df9a8dfSCaroline Tice             return 0;
11633df9a8dfSCaroline Tice     }
11643df9a8dfSCaroline Tice 
11653df9a8dfSCaroline Tice     if (names.GetArgumentCount() != 2)
11663df9a8dfSCaroline Tice         return 0;
11673df9a8dfSCaroline Tice 
11683df9a8dfSCaroline Tice     std::string next_name (names.GetArgumentAtIndex (0));
11693df9a8dfSCaroline Tice     int len = next_name.length();
11703df9a8dfSCaroline Tice     names.Shift();
11713df9a8dfSCaroline Tice 
11723df9a8dfSCaroline Tice     if ((next_name[0] == '[') && (next_name[len-1] == ']'))
11733df9a8dfSCaroline Tice     {
11743df9a8dfSCaroline Tice         // 'next_name' is instance name.  Instance names are irrelevent here.
11753df9a8dfSCaroline Tice     }
11763df9a8dfSCaroline Tice     else
11773df9a8dfSCaroline Tice     {
11783df9a8dfSCaroline Tice         // 'next_name' is child name.
11793df9a8dfSCaroline Tice         bool found = false;
11803df9a8dfSCaroline Tice         int num_children = root_settings->GetNumChildren();
11813df9a8dfSCaroline Tice         ConstString child_level (next_name.c_str());
11823df9a8dfSCaroline Tice         for (int j = 0; j < num_children && !found; ++j)
11833df9a8dfSCaroline Tice         {
11843df9a8dfSCaroline Tice             if (root_settings->GetChildAtIndex (j)->GetLevelName() == child_level)
11853df9a8dfSCaroline Tice             {
11863df9a8dfSCaroline Tice                 found = true;
11873df9a8dfSCaroline Tice                 root_settings = root_settings->GetChildAtIndex (j);
11883df9a8dfSCaroline Tice             }
11893df9a8dfSCaroline Tice         }
11903df9a8dfSCaroline Tice         if (!found)
11913df9a8dfSCaroline Tice             return 0;
11923df9a8dfSCaroline Tice     }
11933df9a8dfSCaroline Tice 
11943df9a8dfSCaroline Tice     ConstString var_name (names.GetArgumentAtIndex(0));
11953df9a8dfSCaroline Tice     const SettingEntry *entry = root_settings->GetGlobalEntry (var_name);
11963df9a8dfSCaroline Tice     if (entry == NULL)
11973df9a8dfSCaroline Tice         entry = root_settings->GetInstanceEntry (var_name);
11983df9a8dfSCaroline Tice 
11993df9a8dfSCaroline Tice     if (entry == NULL)
12003df9a8dfSCaroline Tice         return 0;
12013df9a8dfSCaroline Tice 
12023df9a8dfSCaroline Tice     if (entry->var_type == lldb::eSetVarTypeBool)
12033df9a8dfSCaroline Tice         return UserSettingsController::BooleanMatches (partial_value, word_complete, matches);
12043df9a8dfSCaroline Tice     else if (entry->var_type == lldb::eSetVarTypeEnum)
12053df9a8dfSCaroline Tice         return UserSettingsController::EnumMatches (partial_value, entry->enum_values, word_complete, matches);
12063df9a8dfSCaroline Tice     else
12073df9a8dfSCaroline Tice         return 0;
12083df9a8dfSCaroline Tice }
12093df9a8dfSCaroline Tice 
12103df9a8dfSCaroline Tice int
12113df9a8dfSCaroline Tice UserSettingsController::BooleanMatches (const char *partial_value,
12123df9a8dfSCaroline Tice                                         bool &word_complete,
12133df9a8dfSCaroline Tice                                         StringList &matches)
12143df9a8dfSCaroline Tice {
12153df9a8dfSCaroline Tice     static const std::string true_string ("true");
12163df9a8dfSCaroline Tice     static const std::string false_string ("false");
12173df9a8dfSCaroline Tice 
12183df9a8dfSCaroline Tice     if (partial_value == NULL)
12193df9a8dfSCaroline Tice     {
12203df9a8dfSCaroline Tice         matches.AppendString ("true");
12213df9a8dfSCaroline Tice         matches.AppendString ("false");
12223df9a8dfSCaroline Tice     }
12233df9a8dfSCaroline Tice     else
12243df9a8dfSCaroline Tice     {
12253df9a8dfSCaroline Tice         int partial_len = strlen (partial_value);
12263df9a8dfSCaroline Tice 
12273df9a8dfSCaroline Tice         if ((partial_len <= true_string.length())
12283df9a8dfSCaroline Tice             && (true_string.find (partial_value) == 0))
12293df9a8dfSCaroline Tice             matches.AppendString ("true");
12303df9a8dfSCaroline Tice         else if ((partial_len <= false_string.length())
12313df9a8dfSCaroline Tice                  && (false_string.find (partial_value) == 0))
12323df9a8dfSCaroline Tice             matches.AppendString ("false");
12333df9a8dfSCaroline Tice     }
12343df9a8dfSCaroline Tice 
12353df9a8dfSCaroline Tice     word_complete = false;
12363df9a8dfSCaroline Tice     if (matches.GetSize() == 1)
12373df9a8dfSCaroline Tice         word_complete = true;
12383df9a8dfSCaroline Tice 
12393df9a8dfSCaroline Tice     return matches.GetSize();
12403df9a8dfSCaroline Tice }
12413df9a8dfSCaroline Tice 
12423df9a8dfSCaroline Tice int
12433df9a8dfSCaroline Tice UserSettingsController::EnumMatches (const char *partial_value,
12443df9a8dfSCaroline Tice                                      lldb::OptionEnumValueElement *enum_values,
12453df9a8dfSCaroline Tice                                      bool &word_complete,
12463df9a8dfSCaroline Tice                                      StringList &matches)
12473df9a8dfSCaroline Tice {
12483df9a8dfSCaroline Tice     int len = (partial_value != NULL) ? strlen (partial_value) : 0;
12493df9a8dfSCaroline Tice 
12503df9a8dfSCaroline Tice     int i = 0;
12513df9a8dfSCaroline Tice     while (enum_values[i].string_value != NULL)
12523df9a8dfSCaroline Tice     {
12533df9a8dfSCaroline Tice         if (len == 0)
12543df9a8dfSCaroline Tice             matches.AppendString (enum_values[i].string_value);
12553df9a8dfSCaroline Tice         else
12563df9a8dfSCaroline Tice         {
12573df9a8dfSCaroline Tice             std::string tmp_value (enum_values[i].string_value);
12583df9a8dfSCaroline Tice             if ((len <= tmp_value.length())
12593df9a8dfSCaroline Tice                 && tmp_value.find (partial_value) == 0)
12603df9a8dfSCaroline Tice               matches.AppendString (enum_values[i].string_value);
12613df9a8dfSCaroline Tice         }
12623df9a8dfSCaroline Tice         ++i;
12633df9a8dfSCaroline Tice     }
12643df9a8dfSCaroline Tice 
12653df9a8dfSCaroline Tice     word_complete = false;
12663df9a8dfSCaroline Tice     if (matches.GetSize() == 1)
12673df9a8dfSCaroline Tice       word_complete = true;
12683df9a8dfSCaroline Tice 
12693df9a8dfSCaroline Tice     return matches.GetSize();
12703df9a8dfSCaroline Tice }
12713df9a8dfSCaroline Tice 
12723df9a8dfSCaroline Tice int
12733df9a8dfSCaroline Tice UserSettingsController::CompleteSettingsNames (lldb::UserSettingsControllerSP root_settings,
12743df9a8dfSCaroline Tice                                                Args &partial_setting_name_pieces,
12753df9a8dfSCaroline Tice                                                bool &word_complete,
12763df9a8dfSCaroline Tice                                                StringList &matches)
12773df9a8dfSCaroline Tice {
12783df9a8dfSCaroline Tice     int num_matches = 0;
12793df9a8dfSCaroline Tice     int num_name_pieces = partial_setting_name_pieces.GetArgumentCount();
12803df9a8dfSCaroline Tice 
12813df9a8dfSCaroline Tice     if (num_name_pieces > 1)
12823df9a8dfSCaroline Tice     {
12833df9a8dfSCaroline Tice         // There are at least two pieces, perhaps with multiple level names preceding them.
12843df9a8dfSCaroline Tice         // First traverse all the extra levels, until we have exactly two pieces left.
12853df9a8dfSCaroline Tice 
12863df9a8dfSCaroline Tice         int num_extra_levels = num_name_pieces - 2;
12873df9a8dfSCaroline Tice 
12883df9a8dfSCaroline Tice         // Deal with current level first.
12893df9a8dfSCaroline Tice 
12903df9a8dfSCaroline Tice         ConstString root_level = root_settings->GetLevelName();
12913df9a8dfSCaroline Tice         if ((num_extra_levels > 0)
12923df9a8dfSCaroline Tice             && (root_level.GetLength() > 0))
12933df9a8dfSCaroline Tice         {
12943df9a8dfSCaroline Tice             ConstString current_level (partial_setting_name_pieces.GetArgumentAtIndex (0));
12953df9a8dfSCaroline Tice             if (current_level == root_level)
12963df9a8dfSCaroline Tice             {
12973df9a8dfSCaroline Tice                 partial_setting_name_pieces.Shift();
12983df9a8dfSCaroline Tice                 --num_extra_levels;
12993df9a8dfSCaroline Tice             }
13003df9a8dfSCaroline Tice             else
13013df9a8dfSCaroline Tice                 return 0; // The current level did not match the name pieces; something is wrong, so return immediately
13023df9a8dfSCaroline Tice 
13033df9a8dfSCaroline Tice         }
13043df9a8dfSCaroline Tice 
13053df9a8dfSCaroline Tice         for (int i = 0; i < num_extra_levels; ++i)
13063df9a8dfSCaroline Tice         {
13073df9a8dfSCaroline Tice             ConstString child_level (partial_setting_name_pieces.GetArgumentAtIndex (0));
13083df9a8dfSCaroline Tice             bool found = false;
13093df9a8dfSCaroline Tice             int num_children = root_settings->GetNumChildren();
13103df9a8dfSCaroline Tice             for (int j = 0; j < num_children && !found; ++j)
13113df9a8dfSCaroline Tice             {
13123df9a8dfSCaroline Tice                 if (root_settings->GetChildAtIndex (j)->GetLevelName() == child_level)
13133df9a8dfSCaroline Tice                 {
13143df9a8dfSCaroline Tice                     found = true;
13153df9a8dfSCaroline Tice                     root_settings = root_settings->GetChildAtIndex (j);
13163df9a8dfSCaroline Tice                     partial_setting_name_pieces.Shift();
13173df9a8dfSCaroline Tice                 }
13183df9a8dfSCaroline Tice             }
13193df9a8dfSCaroline Tice             if (! found)
13203df9a8dfSCaroline Tice             {
13213df9a8dfSCaroline Tice                 return 0; // Unable to find a matching child level name; something is wrong, so return immediately.
13223df9a8dfSCaroline Tice             }
13233df9a8dfSCaroline Tice         }
13243df9a8dfSCaroline Tice 
13253df9a8dfSCaroline Tice         // Now there should be exactly two name pieces left.  If not there is an error, so return immediately
13263df9a8dfSCaroline Tice 
13273df9a8dfSCaroline Tice         if (partial_setting_name_pieces.GetArgumentCount() != 2)
13283df9a8dfSCaroline Tice             return 0;
13293df9a8dfSCaroline Tice 
13303df9a8dfSCaroline Tice         std::string next_name (partial_setting_name_pieces.GetArgumentAtIndex (0));
13313df9a8dfSCaroline Tice         int len = next_name.length();
13323df9a8dfSCaroline Tice         partial_setting_name_pieces.Shift();
13333df9a8dfSCaroline Tice 
13343df9a8dfSCaroline Tice         if ((next_name[0] == '[') && (next_name[len-1] == ']'))
13353df9a8dfSCaroline Tice         {
13363df9a8dfSCaroline Tice             // 'next_name' is an instance name.  The last name piece must be a non-empty partial match against an
13373df9a8dfSCaroline Tice             // instance_name, assuming 'next_name' is valid.
13383df9a8dfSCaroline Tice 
13393df9a8dfSCaroline Tice             if (root_settings->IsLiveInstance (next_name))
13403df9a8dfSCaroline Tice             {
13413df9a8dfSCaroline Tice                 std::string complete_prefix;
13423df9a8dfSCaroline Tice                 root_settings->BuildParentPrefix (complete_prefix);
13433df9a8dfSCaroline Tice 
13443df9a8dfSCaroline Tice                 num_matches = root_settings->InstanceVariableMatches(partial_setting_name_pieces.GetArgumentAtIndex(0),
13453df9a8dfSCaroline Tice                                                                      complete_prefix,
13463df9a8dfSCaroline Tice                                                                      next_name.c_str(),
13473df9a8dfSCaroline Tice                                                                      matches);
13483df9a8dfSCaroline Tice                 word_complete = true;
13493df9a8dfSCaroline Tice                 if (num_matches > 1)
13503df9a8dfSCaroline Tice                     word_complete = false;
13513df9a8dfSCaroline Tice 
13523df9a8dfSCaroline Tice                 return num_matches;
13533df9a8dfSCaroline Tice             }
13543df9a8dfSCaroline Tice             else
13553df9a8dfSCaroline Tice                 return 0;   // Invalid instance_name
13563df9a8dfSCaroline Tice         }
13573df9a8dfSCaroline Tice         else
13583df9a8dfSCaroline Tice         {
13593df9a8dfSCaroline Tice             // 'next_name' must be a child name.  Find the correct child and pass the remaining piece to be resolved.
13603df9a8dfSCaroline Tice             bool found = false;
13613df9a8dfSCaroline Tice             int num_children = root_settings->GetNumChildren();
13623df9a8dfSCaroline Tice             ConstString child_level (next_name.c_str());
13633df9a8dfSCaroline Tice             for (int i = 0; i < num_children; ++i)
13643df9a8dfSCaroline Tice             {
13653df9a8dfSCaroline Tice                 if (root_settings->GetChildAtIndex (i)->GetLevelName() == child_level)
13663df9a8dfSCaroline Tice                 {
13673df9a8dfSCaroline Tice                     found = true;
13683df9a8dfSCaroline Tice                     return UserSettingsController::CompleteSettingsNames (root_settings->GetChildAtIndex (i),
13693df9a8dfSCaroline Tice                                                                           partial_setting_name_pieces,
13703df9a8dfSCaroline Tice                                                                           word_complete, matches);
13713df9a8dfSCaroline Tice                 }
13723df9a8dfSCaroline Tice             }
13733df9a8dfSCaroline Tice             if (!found)
13743df9a8dfSCaroline Tice                 return 0;
13753df9a8dfSCaroline Tice         }
13763df9a8dfSCaroline Tice     }
13773df9a8dfSCaroline Tice     else if (num_name_pieces == 1)
13783df9a8dfSCaroline Tice     {
13793df9a8dfSCaroline Tice         std::string complete_prefix;
13803df9a8dfSCaroline Tice         root_settings->BuildParentPrefix (complete_prefix);
13813df9a8dfSCaroline Tice 
13823df9a8dfSCaroline Tice         word_complete = true;
13833df9a8dfSCaroline Tice         std::string name (partial_setting_name_pieces.GetArgumentAtIndex (0));
13843df9a8dfSCaroline Tice 
13853df9a8dfSCaroline Tice         if (name[0] == '[')
13863df9a8dfSCaroline Tice         {
13873df9a8dfSCaroline Tice             // It's a partial instance name.
13883df9a8dfSCaroline Tice 
13893df9a8dfSCaroline Tice             num_matches = root_settings->LiveInstanceMatches (name.c_str(), complete_prefix, word_complete, matches);
13903df9a8dfSCaroline Tice         }
13913df9a8dfSCaroline Tice         else
13923df9a8dfSCaroline Tice         {
13933df9a8dfSCaroline Tice             // It could be anything *except* an instance name...
13943df9a8dfSCaroline Tice 
13953df9a8dfSCaroline Tice             num_matches = root_settings->GlobalVariableMatches (name.c_str(), complete_prefix, matches);
13963df9a8dfSCaroline Tice             num_matches += root_settings->InstanceVariableMatches (name.c_str(), complete_prefix, NULL, matches);
13973df9a8dfSCaroline Tice             num_matches += root_settings->ChildMatches (name.c_str(), complete_prefix, word_complete, matches);
13983df9a8dfSCaroline Tice         }
13993df9a8dfSCaroline Tice 
14003df9a8dfSCaroline Tice         if (num_matches > 1)
14013df9a8dfSCaroline Tice             word_complete = false;
14023df9a8dfSCaroline Tice 
14033df9a8dfSCaroline Tice         return num_matches;
14043df9a8dfSCaroline Tice     }
14053df9a8dfSCaroline Tice     else
14063df9a8dfSCaroline Tice     {
14073df9a8dfSCaroline Tice         // We have a user settings controller with a blank partial string.  Return everything possible at this level.
14083df9a8dfSCaroline Tice 
14093df9a8dfSCaroline Tice         std::string complete_prefix;
14103df9a8dfSCaroline Tice         root_settings->BuildParentPrefix (complete_prefix);
14113df9a8dfSCaroline Tice         num_matches = root_settings->GlobalVariableMatches (NULL, complete_prefix, matches);
14123df9a8dfSCaroline Tice         num_matches += root_settings->InstanceVariableMatches (NULL, complete_prefix, NULL, matches);
14133df9a8dfSCaroline Tice         num_matches += root_settings->LiveInstanceMatches (NULL, complete_prefix, word_complete, matches);
14143df9a8dfSCaroline Tice         num_matches += root_settings->ChildMatches (NULL, complete_prefix, word_complete, matches);
14153df9a8dfSCaroline Tice         word_complete = false;
14163df9a8dfSCaroline Tice         return num_matches;
14173df9a8dfSCaroline Tice     }
14183df9a8dfSCaroline Tice 
14193df9a8dfSCaroline Tice     return num_matches;
14203df9a8dfSCaroline Tice }
14213df9a8dfSCaroline Tice 
14223df9a8dfSCaroline Tice int
14233df9a8dfSCaroline Tice UserSettingsController::GlobalVariableMatches (const char *partial_name,
14243df9a8dfSCaroline Tice                                                const std::string &complete_prefix,
14253df9a8dfSCaroline Tice                                                StringList &matches)
14263df9a8dfSCaroline Tice {
14273df9a8dfSCaroline Tice     int partial_len = (partial_name != NULL) ? strlen (partial_name) : 0;
14283df9a8dfSCaroline Tice     int num_matches = 0;
14293df9a8dfSCaroline Tice 
14303df9a8dfSCaroline Tice     for (size_t i = 0; i < m_settings.global_settings.size(); ++i)
14313df9a8dfSCaroline Tice     {
14323df9a8dfSCaroline Tice         SettingEntry &entry = m_settings.global_settings[i];
14333df9a8dfSCaroline Tice         std::string var_name (entry.var_name);
14343df9a8dfSCaroline Tice         if ((partial_len == 0)
14353df9a8dfSCaroline Tice             || ((partial_len <= var_name.length())
14363df9a8dfSCaroline Tice                 && (var_name.find (partial_name) == 0)))
14373df9a8dfSCaroline Tice         {
14383df9a8dfSCaroline Tice             StreamString match_name;
14393df9a8dfSCaroline Tice             if (complete_prefix.length() > 0)
14403df9a8dfSCaroline Tice             {
14413df9a8dfSCaroline Tice                 match_name.Printf ("%s.%s", complete_prefix.c_str(), var_name.c_str());
14423df9a8dfSCaroline Tice                 matches.AppendString (match_name.GetData());
14433df9a8dfSCaroline Tice             }
14443df9a8dfSCaroline Tice             else
14453df9a8dfSCaroline Tice                 matches.AppendString (var_name.c_str());
14463df9a8dfSCaroline Tice             ++num_matches;
14473df9a8dfSCaroline Tice         }
14483df9a8dfSCaroline Tice     }
14493df9a8dfSCaroline Tice     return num_matches;
14503df9a8dfSCaroline Tice }
14513df9a8dfSCaroline Tice 
14523df9a8dfSCaroline Tice int
14533df9a8dfSCaroline Tice UserSettingsController::InstanceVariableMatches (const char *partial_name,
14543df9a8dfSCaroline Tice                                                  const std::string &complete_prefix,
14553df9a8dfSCaroline Tice                                                  const char *instance_name,
14563df9a8dfSCaroline Tice                                                  StringList &matches)
14573df9a8dfSCaroline Tice {
14583df9a8dfSCaroline Tice     int partial_len = (partial_name != NULL) ? strlen (partial_name) : 0;
14593df9a8dfSCaroline Tice     int num_matches = 0;
14603df9a8dfSCaroline Tice 
14613df9a8dfSCaroline Tice     for (size_t i = 0; i < m_settings.instance_settings.size(); ++i)
14623df9a8dfSCaroline Tice     {
14633df9a8dfSCaroline Tice         SettingEntry &entry = m_settings.instance_settings[i];
14643df9a8dfSCaroline Tice         std::string var_name (entry.var_name);
14653df9a8dfSCaroline Tice         if ((partial_len == 0)
14663df9a8dfSCaroline Tice             || ((partial_len <= var_name.length())
14673df9a8dfSCaroline Tice                 && (var_name.find (partial_name) == 0)))
14683df9a8dfSCaroline Tice         {
14693df9a8dfSCaroline Tice             StreamString match_name;
14703df9a8dfSCaroline Tice             if (complete_prefix.length() > 0)
14713df9a8dfSCaroline Tice             {
14723df9a8dfSCaroline Tice                 if (instance_name != NULL)
14733df9a8dfSCaroline Tice                     match_name.Printf ("%s.%s.%s", complete_prefix.c_str(), instance_name, var_name.c_str());
14743df9a8dfSCaroline Tice                 else
14753df9a8dfSCaroline Tice                     match_name.Printf ("%s.%s", complete_prefix.c_str(), var_name.c_str());
14763df9a8dfSCaroline Tice 
14773df9a8dfSCaroline Tice                 matches.AppendString (match_name.GetData());
14783df9a8dfSCaroline Tice             }
14793df9a8dfSCaroline Tice             else
14803df9a8dfSCaroline Tice             {
14813df9a8dfSCaroline Tice                 if (instance_name != NULL)
14823df9a8dfSCaroline Tice                 {
14833df9a8dfSCaroline Tice                     match_name.Printf ("%s.%s", instance_name, var_name.c_str());
14843df9a8dfSCaroline Tice                     matches.AppendString (match_name.GetData());
14853df9a8dfSCaroline Tice                 }
14863df9a8dfSCaroline Tice                 else
14873df9a8dfSCaroline Tice                     matches.AppendString (var_name.c_str());
14883df9a8dfSCaroline Tice             }
14893df9a8dfSCaroline Tice             ++num_matches;
14903df9a8dfSCaroline Tice         }
14913df9a8dfSCaroline Tice     }
14923df9a8dfSCaroline Tice     return num_matches;
14933df9a8dfSCaroline Tice }
14943df9a8dfSCaroline Tice 
14953df9a8dfSCaroline Tice int
14963df9a8dfSCaroline Tice UserSettingsController::LiveInstanceMatches (const char *partial_name,
14973df9a8dfSCaroline Tice                                              const std::string &complete_prefix,
14983df9a8dfSCaroline Tice                                              bool &word_complete,
14993df9a8dfSCaroline Tice                                              StringList &matches)
15003df9a8dfSCaroline Tice {
15013df9a8dfSCaroline Tice     int partial_len = (partial_name != NULL) ? strlen (partial_name) : 0;
15023df9a8dfSCaroline Tice     int num_matches = 0;
15033df9a8dfSCaroline Tice 
15043df9a8dfSCaroline Tice     std::map<std::string, InstanceSettings*>::iterator pos;
15053df9a8dfSCaroline Tice     for (pos = m_live_settings.begin(); pos != m_live_settings.end(); ++pos)
15063df9a8dfSCaroline Tice     {
15073df9a8dfSCaroline Tice         std::string instance_name = pos->first;
15083df9a8dfSCaroline Tice         if ((partial_len == 0)
15093df9a8dfSCaroline Tice             || ((partial_len <= instance_name.length())
15103df9a8dfSCaroline Tice                 && (instance_name.find (partial_name) == 0)))
15113df9a8dfSCaroline Tice         {
15123df9a8dfSCaroline Tice             StreamString match_name;
15133df9a8dfSCaroline Tice             if (complete_prefix.length() > 0)
15143df9a8dfSCaroline Tice                 match_name.Printf ("%s.%s.", complete_prefix.c_str(), instance_name.c_str());
15153df9a8dfSCaroline Tice             else
15163df9a8dfSCaroline Tice                 match_name.Printf ("%s.", instance_name.c_str());
15173df9a8dfSCaroline Tice             matches.AppendString (match_name.GetData());
15183df9a8dfSCaroline Tice             ++num_matches;
15193df9a8dfSCaroline Tice         }
15203df9a8dfSCaroline Tice     }
15213df9a8dfSCaroline Tice 
15223df9a8dfSCaroline Tice     if (num_matches > 0)
15233df9a8dfSCaroline Tice         word_complete = false;
15243df9a8dfSCaroline Tice 
15253df9a8dfSCaroline Tice     return num_matches;
15263df9a8dfSCaroline Tice }
15273df9a8dfSCaroline Tice 
15283df9a8dfSCaroline Tice int
15293df9a8dfSCaroline Tice UserSettingsController::ChildMatches (const char *partial_name,
15303df9a8dfSCaroline Tice                                       const std::string &complete_prefix,
15313df9a8dfSCaroline Tice                                       bool &word_complete,
15323df9a8dfSCaroline Tice                                       StringList &matches)
15333df9a8dfSCaroline Tice {
15343df9a8dfSCaroline Tice     int partial_len = (partial_name != NULL) ? strlen (partial_name) : 0;
15353df9a8dfSCaroline Tice     int num_children = GetNumChildren();
15363df9a8dfSCaroline Tice     int num_matches = 0;
15373df9a8dfSCaroline Tice     for (int i = 0; i < num_children; ++i)
15383df9a8dfSCaroline Tice     {
15393df9a8dfSCaroline Tice         std::string child_name (GetChildAtIndex(i)->GetLevelName().AsCString());
15403df9a8dfSCaroline Tice         StreamString match_name;
15413df9a8dfSCaroline Tice         if ((partial_len == 0)
15423df9a8dfSCaroline Tice           || ((partial_len <= child_name.length())
15433df9a8dfSCaroline Tice               && (child_name.find (partial_name) == 0)))
15443df9a8dfSCaroline Tice         {
15453df9a8dfSCaroline Tice             if (complete_prefix.length() > 0)
15463df9a8dfSCaroline Tice                 match_name.Printf ("%s.%s.", complete_prefix.c_str(), child_name.c_str());
15473df9a8dfSCaroline Tice             else
15483df9a8dfSCaroline Tice                 match_name.Printf ("%s.", child_name.c_str());
15493df9a8dfSCaroline Tice             matches.AppendString (match_name.GetData());
15503df9a8dfSCaroline Tice             ++num_matches;
15513df9a8dfSCaroline Tice         }
15523df9a8dfSCaroline Tice     }
15533df9a8dfSCaroline Tice 
15543df9a8dfSCaroline Tice     if (num_matches > 0)
15553df9a8dfSCaroline Tice         word_complete = false;
15563df9a8dfSCaroline Tice 
15573df9a8dfSCaroline Tice     return num_matches;
15583df9a8dfSCaroline Tice }
15593df9a8dfSCaroline Tice 
15603df9a8dfSCaroline Tice void
15613df9a8dfSCaroline Tice UserSettingsController::VerifyOperationForType (lldb::SettableVariableType var_type,
15623df9a8dfSCaroline Tice                                                 lldb::VarSetOperationType op,
15633df9a8dfSCaroline Tice                                                 const ConstString &var_name,
15643df9a8dfSCaroline Tice                                                 Error &err)
15653df9a8dfSCaroline Tice {
15663df9a8dfSCaroline Tice     if (op == lldb::eVarSetOperationAssign)
15673df9a8dfSCaroline Tice         return;
15683df9a8dfSCaroline Tice 
15693df9a8dfSCaroline Tice 
15703df9a8dfSCaroline Tice     if (op == lldb::eVarSetOperationInvalid)
15713df9a8dfSCaroline Tice     {
15723df9a8dfSCaroline Tice         err.SetErrorString ("Invalid 'settings ' subcommand operation.\n");
15733df9a8dfSCaroline Tice         return;
15743df9a8dfSCaroline Tice     }
15753df9a8dfSCaroline Tice 
15763df9a8dfSCaroline Tice     switch (op)
15773df9a8dfSCaroline Tice     {
15783df9a8dfSCaroline Tice         case lldb::eVarSetOperationInsertBefore:
15793df9a8dfSCaroline Tice         case lldb::eVarSetOperationInsertAfter:
15803df9a8dfSCaroline Tice             if (var_type != lldb::eSetVarTypeArray)
15813df9a8dfSCaroline Tice                 err.SetErrorString ("Invalid operation:  This operation can only be performed on array variables.\n");
15823df9a8dfSCaroline Tice             break;
15833df9a8dfSCaroline Tice         case lldb::eVarSetOperationReplace:
15843df9a8dfSCaroline Tice         case lldb::eVarSetOperationRemove:
15853df9a8dfSCaroline Tice             if ((var_type != lldb::eSetVarTypeArray)
15863df9a8dfSCaroline Tice                 && (var_type != lldb::eSetVarTypeDictionary))
15873df9a8dfSCaroline Tice                 err.SetErrorString ("Invalid operation:  This operation can only be performed on array or dictionary"
15883df9a8dfSCaroline Tice                                     " variables.\n");
15893df9a8dfSCaroline Tice             break;
15903df9a8dfSCaroline Tice         case lldb::eVarSetOperationAppend:
15913df9a8dfSCaroline Tice         case lldb::eVarSetOperationClear:
15923df9a8dfSCaroline Tice             if ((var_type != lldb::eSetVarTypeArray)
15933df9a8dfSCaroline Tice                 && (var_type != lldb::eSetVarTypeDictionary)
15943df9a8dfSCaroline Tice                 && (var_type != lldb::eSetVarTypeString))
15953df9a8dfSCaroline Tice                 err.SetErrorString ("Invalid operation:  This operation can only be performed on array, dictionary "
15963df9a8dfSCaroline Tice                                     "or string variables.\n");
15973df9a8dfSCaroline Tice             break;
15983df9a8dfSCaroline Tice         default:
15993df9a8dfSCaroline Tice             break;
16003df9a8dfSCaroline Tice     }
16013df9a8dfSCaroline Tice 
16023df9a8dfSCaroline Tice     return;
16033df9a8dfSCaroline Tice }
16043df9a8dfSCaroline Tice 
16053df9a8dfSCaroline Tice void
16063df9a8dfSCaroline Tice UserSettingsController::UpdateStringVariable (lldb::VarSetOperationType op,
16073df9a8dfSCaroline Tice                                               std::string &string_var,
16083df9a8dfSCaroline Tice                                               const char *new_value,
16093df9a8dfSCaroline Tice                                               Error &err)
16103df9a8dfSCaroline Tice {
16113df9a8dfSCaroline Tice     if (op == lldb::eVarSetOperationAssign)
16123df9a8dfSCaroline Tice         string_var = new_value;
16133df9a8dfSCaroline Tice     else if (op == lldb::eVarSetOperationAppend)
16143df9a8dfSCaroline Tice         string_var.append (new_value);
16153df9a8dfSCaroline Tice     else if (op == lldb::eVarSetOperationClear)
16163df9a8dfSCaroline Tice         string_var.clear();
16173df9a8dfSCaroline Tice     else
16183df9a8dfSCaroline Tice         err.SetErrorString ("Unrecognized operation. Cannot update value.\n");
16193df9a8dfSCaroline Tice }
16203df9a8dfSCaroline Tice 
16213df9a8dfSCaroline Tice void
16223df9a8dfSCaroline Tice UserSettingsController::UpdateBooleanVariable (lldb::VarSetOperationType op,
16233df9a8dfSCaroline Tice                                                bool &bool_var,
16243df9a8dfSCaroline Tice                                                const char *new_value,
16253df9a8dfSCaroline Tice                                                Error &err)
16263df9a8dfSCaroline Tice {
16273df9a8dfSCaroline Tice     if (op != lldb::eVarSetOperationAssign)
16283df9a8dfSCaroline Tice         err.SetErrorString ("Invalid operation for Boolean variable.  Cannot update value.\n");
16293df9a8dfSCaroline Tice 
16303df9a8dfSCaroline Tice 
16313df9a8dfSCaroline Tice     if ((new_value == NULL)
16323df9a8dfSCaroline Tice         || (new_value[0] == '\0'))
16333df9a8dfSCaroline Tice       err.SetErrorString ("Invalid value.  Cannot perform update.\n");
16343df9a8dfSCaroline Tice 
16353df9a8dfSCaroline Tice     std::string bool_val_str (new_value);
16363df9a8dfSCaroline Tice 
16373df9a8dfSCaroline Tice     std::transform (bool_val_str.begin(), bool_val_str.end(), bool_val_str.begin(), ::tolower);
16383df9a8dfSCaroline Tice 
16393df9a8dfSCaroline Tice     if (bool_val_str == "true")
16403df9a8dfSCaroline Tice         bool_var = true;
16413df9a8dfSCaroline Tice     else if (bool_val_str == "false")
16423df9a8dfSCaroline Tice         bool_var = false;
16433df9a8dfSCaroline Tice }
16443df9a8dfSCaroline Tice 
16453df9a8dfSCaroline Tice void
16463df9a8dfSCaroline Tice UserSettingsController::UpdateStringArrayVariable (lldb::VarSetOperationType op,
16473df9a8dfSCaroline Tice                                                    const char *index_value,
16483df9a8dfSCaroline Tice                                                    Args &array_var,
16493df9a8dfSCaroline Tice                                                    const char *new_value,
16503df9a8dfSCaroline Tice                                                    Error &err)
16513df9a8dfSCaroline Tice {
16523df9a8dfSCaroline Tice     int index = -1;
16533df9a8dfSCaroline Tice     bool valid_index = true;
16543df9a8dfSCaroline Tice 
16553df9a8dfSCaroline Tice     if (index_value != NULL)
16563df9a8dfSCaroline Tice     {
16573df9a8dfSCaroline Tice         for (int i = 0; i < strlen(index_value); ++i)
16583df9a8dfSCaroline Tice             if (!isdigit (index_value[i]))
16593df9a8dfSCaroline Tice             {
16603df9a8dfSCaroline Tice                 valid_index = false;
16613df9a8dfSCaroline Tice                 err.SetErrorStringWithFormat ("'%s' is not a valid integer index. Cannot update array value.\n",
16623df9a8dfSCaroline Tice                                               index_value);
16633df9a8dfSCaroline Tice             }
16643df9a8dfSCaroline Tice 
16653df9a8dfSCaroline Tice         if (valid_index)
16663df9a8dfSCaroline Tice             index = atoi (index_value);
16673df9a8dfSCaroline Tice 
16683df9a8dfSCaroline Tice         if (index < 0
16693df9a8dfSCaroline Tice             || index >= array_var.GetArgumentCount())
16703df9a8dfSCaroline Tice         {
16713df9a8dfSCaroline Tice             valid_index = false;
16723df9a8dfSCaroline Tice             err.SetErrorStringWithFormat ("%d is outside the bounds of the specified array variable. "
16733df9a8dfSCaroline Tice                                           "Cannot update array value.\n", index);
16743df9a8dfSCaroline Tice         }
16753df9a8dfSCaroline Tice     }
16763df9a8dfSCaroline Tice 
16773df9a8dfSCaroline Tice     switch (op)
16783df9a8dfSCaroline Tice     {
16793df9a8dfSCaroline Tice         case lldb::eVarSetOperationAssign:
16803df9a8dfSCaroline Tice             array_var.SetCommandString (new_value);
16813df9a8dfSCaroline Tice             break;
16823df9a8dfSCaroline Tice         case lldb::eVarSetOperationReplace:
16833df9a8dfSCaroline Tice         {
16843df9a8dfSCaroline Tice             if (valid_index)
16853df9a8dfSCaroline Tice                 array_var.ReplaceArgumentAtIndex (index, new_value);
16863df9a8dfSCaroline Tice             break;
16873df9a8dfSCaroline Tice         }
16883df9a8dfSCaroline Tice         case lldb::eVarSetOperationInsertBefore:
16893df9a8dfSCaroline Tice         case lldb::eVarSetOperationInsertAfter:
16903df9a8dfSCaroline Tice         {
16913df9a8dfSCaroline Tice             if (valid_index)
16923df9a8dfSCaroline Tice             {
16933df9a8dfSCaroline Tice                 Args new_array (new_value);
16943df9a8dfSCaroline Tice                 if (op == lldb::eVarSetOperationInsertAfter)
16953df9a8dfSCaroline Tice                     ++index;
16963df9a8dfSCaroline Tice                 for (int i = 0; i < new_array.GetArgumentCount(); ++i)
16973df9a8dfSCaroline Tice                     array_var.InsertArgumentAtIndex (index, new_array.GetArgumentAtIndex (i));
16983df9a8dfSCaroline Tice             }
16993df9a8dfSCaroline Tice             break;
17003df9a8dfSCaroline Tice         }
17013df9a8dfSCaroline Tice         case lldb::eVarSetOperationRemove:
17023df9a8dfSCaroline Tice         {
17033df9a8dfSCaroline Tice             if (valid_index)
17043df9a8dfSCaroline Tice                 array_var.DeleteArgumentAtIndex (index);
17053df9a8dfSCaroline Tice             break;
17063df9a8dfSCaroline Tice         }
17073df9a8dfSCaroline Tice         case lldb::eVarSetOperationAppend:
17083df9a8dfSCaroline Tice         {
17093df9a8dfSCaroline Tice             Args new_array (new_value);
17103df9a8dfSCaroline Tice             array_var.AppendArguments (new_array);
17113df9a8dfSCaroline Tice             break;
17123df9a8dfSCaroline Tice         }
17133df9a8dfSCaroline Tice         case lldb::eVarSetOperationClear:
17143df9a8dfSCaroline Tice             array_var.Clear();
17153df9a8dfSCaroline Tice             break;
17163df9a8dfSCaroline Tice         default:
17173df9a8dfSCaroline Tice             err.SetErrorString ("Unrecognized operation. Cannot update value.\n");
17183df9a8dfSCaroline Tice             break;
17193df9a8dfSCaroline Tice     }
17203df9a8dfSCaroline Tice }
17213df9a8dfSCaroline Tice 
17223df9a8dfSCaroline Tice void
17233df9a8dfSCaroline Tice UserSettingsController::UpdateDictionaryVariable (lldb::VarSetOperationType op,
17243df9a8dfSCaroline Tice                                                   const char *index_value,
17253df9a8dfSCaroline Tice                                                   std::map<std::string, std::string> &dictionary,
17263df9a8dfSCaroline Tice                                                   const char *new_value,
17273df9a8dfSCaroline Tice                                                   Error &err)
17283df9a8dfSCaroline Tice {
17293df9a8dfSCaroline Tice     switch (op)
17303df9a8dfSCaroline Tice     {
17313df9a8dfSCaroline Tice         case lldb::eVarSetOperationReplace:
17323df9a8dfSCaroline Tice             if (index_value != NULL)
17333df9a8dfSCaroline Tice             {
17343df9a8dfSCaroline Tice                 std::string key (index_value);
17353df9a8dfSCaroline Tice                 std::map<std::string, std::string>::iterator pos;
17363df9a8dfSCaroline Tice 
17373df9a8dfSCaroline Tice                 pos = dictionary.find (key);
17383df9a8dfSCaroline Tice                 if (pos != dictionary.end())
17393df9a8dfSCaroline Tice                     dictionary[key] = new_value;
17403df9a8dfSCaroline Tice                 else
17413df9a8dfSCaroline Tice                     err.SetErrorStringWithFormat ("'%s' is not an existing key; cannot replace value.\n", index_value);
17423df9a8dfSCaroline Tice             }
17433df9a8dfSCaroline Tice             else
17443df9a8dfSCaroline Tice                 err.SetErrorString ("'settings replace' requires a key for dictionary variables. No key supplied.\n");
17453df9a8dfSCaroline Tice             break;
17463df9a8dfSCaroline Tice         case lldb::eVarSetOperationRemove:
17473df9a8dfSCaroline Tice             if (index_value != NULL)
17483df9a8dfSCaroline Tice             {
17493df9a8dfSCaroline Tice                 std::string key (index_value);
17503df9a8dfSCaroline Tice                 dictionary.erase (key);
17513df9a8dfSCaroline Tice             }
17523df9a8dfSCaroline Tice             else
17533df9a8dfSCaroline Tice                 err.SetErrorString ("'settings remove' requires a key for dictionary variables. No key supplied.\n");
17543df9a8dfSCaroline Tice             break;
17553df9a8dfSCaroline Tice         case lldb::eVarSetOperationClear:
17563df9a8dfSCaroline Tice             dictionary.clear ();
17573df9a8dfSCaroline Tice             break;
17583df9a8dfSCaroline Tice         case lldb::eVarSetOperationAppend:
17593df9a8dfSCaroline Tice         case lldb::eVarSetOperationAssign:
17603df9a8dfSCaroline Tice             {
17613df9a8dfSCaroline Tice                 Args args (new_value);
17623df9a8dfSCaroline Tice                 size_t num_args = args.GetArgumentCount();
17633df9a8dfSCaroline Tice                 for (size_t i = 0; i < num_args; ++i)
17643df9a8dfSCaroline Tice                 {
17653df9a8dfSCaroline Tice                     std::string tmp_arg = args.GetArgumentAtIndex (i);
17663df9a8dfSCaroline Tice                     size_t eq_sign = tmp_arg.find ('=');
17673df9a8dfSCaroline Tice                     if (eq_sign != std::string::npos)
17683df9a8dfSCaroline Tice                     {
17693df9a8dfSCaroline Tice                         if (eq_sign > 4)
17703df9a8dfSCaroline Tice                         {
17713df9a8dfSCaroline Tice                             std::string tmp_key = tmp_arg.substr (0, eq_sign);
17723df9a8dfSCaroline Tice                             std::string real_value = tmp_arg.substr (eq_sign+1);
17733df9a8dfSCaroline Tice                             if ((tmp_key[0] == '[')
17743df9a8dfSCaroline Tice                                 && (tmp_key[1] == '"')
17753df9a8dfSCaroline Tice                                 && (tmp_key[eq_sign-2] == '"')
17763df9a8dfSCaroline Tice                                 && (tmp_key[eq_sign-1] == ']'))
17773df9a8dfSCaroline Tice                               {
17783df9a8dfSCaroline Tice                                 std::string real_key = tmp_key.substr (2, eq_sign-4);
17793df9a8dfSCaroline Tice                                 dictionary[real_key] = real_value;
17803df9a8dfSCaroline Tice                               }
17813df9a8dfSCaroline Tice                             else
17823df9a8dfSCaroline Tice                                 err.SetErrorString ("Invalid key format for dictionary assignment.  "
17833df9a8dfSCaroline Tice                                                     "Expected '[\"<key>\"]'\n");
17843df9a8dfSCaroline Tice                         }
17853df9a8dfSCaroline Tice                         else
17863df9a8dfSCaroline Tice                             err.SetErrorString ("Invalid key format for dictionary assignment.  "
17873df9a8dfSCaroline Tice                                                 "Expected '[\"<key>\"]'\n");
17883df9a8dfSCaroline Tice                     }
17893df9a8dfSCaroline Tice                     else
17903df9a8dfSCaroline Tice                         err.SetErrorString ("Invalid format for dictionary value.  Expected '[\"<key>\"]=<value>'\n");
17913df9a8dfSCaroline Tice                 }
17923df9a8dfSCaroline Tice             }
17933df9a8dfSCaroline Tice             break;
17943df9a8dfSCaroline Tice         case lldb::eVarSetOperationInsertBefore:
17953df9a8dfSCaroline Tice         case lldb::eVarSetOperationInsertAfter:
17963df9a8dfSCaroline Tice             err.SetErrorString ("Specified operation cannot be performed on dictionary variables.\n");
17973df9a8dfSCaroline Tice             break;
17983df9a8dfSCaroline Tice         default:
17993df9a8dfSCaroline Tice             err.SetErrorString ("Unrecognized operation.\n");
18003df9a8dfSCaroline Tice             break;
18013df9a8dfSCaroline Tice     }
18023df9a8dfSCaroline Tice }
18033df9a8dfSCaroline Tice 
18043df9a8dfSCaroline Tice const char *
18053df9a8dfSCaroline Tice UserSettingsController::EnumToString (const lldb::OptionEnumValueElement *enum_values,
18063df9a8dfSCaroline Tice                                       int value)
18073df9a8dfSCaroline Tice {
18083df9a8dfSCaroline Tice     int i = 0;
18093df9a8dfSCaroline Tice     while (enum_values[i].string_value != NULL)
18103df9a8dfSCaroline Tice     {
18113df9a8dfSCaroline Tice         if (enum_values[i].value == value)
18123df9a8dfSCaroline Tice             return enum_values[i].string_value;
18133df9a8dfSCaroline Tice         ++i;
18143df9a8dfSCaroline Tice     }
18153df9a8dfSCaroline Tice 
18163df9a8dfSCaroline Tice     return "Invalid enumeration value";
18173df9a8dfSCaroline Tice }
18183df9a8dfSCaroline Tice 
18193df9a8dfSCaroline Tice 
18203df9a8dfSCaroline Tice void
18213df9a8dfSCaroline Tice UserSettingsController::UpdateEnumVariable (lldb::OptionEnumValueElement *enum_values,
18223df9a8dfSCaroline Tice                                             int *enum_var,
18233df9a8dfSCaroline Tice                                             const char *new_value,
18243df9a8dfSCaroline Tice                                             Error &err)
18253df9a8dfSCaroline Tice {
18263df9a8dfSCaroline Tice     bool found_one;
18273df9a8dfSCaroline Tice 
18283df9a8dfSCaroline Tice     *enum_var = Args::StringToOptionEnum (new_value, enum_values, enum_values[0].value, &found_one);
18293df9a8dfSCaroline Tice 
18303df9a8dfSCaroline Tice     if (!found_one)
18313df9a8dfSCaroline Tice         err.SetErrorString ("Invalid enumeration value; cannot update variable.\n");
18323df9a8dfSCaroline Tice }
18333df9a8dfSCaroline Tice 
18343df9a8dfSCaroline Tice //----------------------------------------------------------------------
18353df9a8dfSCaroline Tice // class InstanceSettings
18363df9a8dfSCaroline Tice //----------------------------------------------------------------------
18373df9a8dfSCaroline Tice 
18383df9a8dfSCaroline Tice InstanceSettings::InstanceSettings (UserSettingsController &owner, const char *instance_name) :
18393df9a8dfSCaroline Tice     m_owner (owner),
18403df9a8dfSCaroline Tice     m_instance_name (instance_name)
18413df9a8dfSCaroline Tice {
18423df9a8dfSCaroline Tice     if (m_instance_name != InstanceSettings::GetDefaultName())
18433df9a8dfSCaroline Tice         m_owner.RegisterInstanceSettings (this);
18443df9a8dfSCaroline Tice }
18453df9a8dfSCaroline Tice 
18463df9a8dfSCaroline Tice InstanceSettings::~InstanceSettings ()
18473df9a8dfSCaroline Tice {
18483df9a8dfSCaroline Tice     if (m_instance_name != InstanceSettings::GetDefaultName())
18493df9a8dfSCaroline Tice         m_owner.UnregisterInstanceSettings (this);
18503df9a8dfSCaroline Tice }
18513df9a8dfSCaroline Tice 
18523df9a8dfSCaroline Tice const ConstString &
18533df9a8dfSCaroline Tice InstanceSettings::GetDefaultName ()
18543df9a8dfSCaroline Tice {
18553df9a8dfSCaroline Tice     static const ConstString g_default_settings_name ("[DEFAULT]");
18563df9a8dfSCaroline Tice 
18573df9a8dfSCaroline Tice     return g_default_settings_name;
18583df9a8dfSCaroline Tice }
1859