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