This is a very large commit that completely re-does the way lldb
handles user settable internal variables (the equivalent of set/show
variables in gdb).  In addition to the basic infrastructure (most of
which is defined in UserSettingsController.{h,cpp}, there are examples
of two classes that have been set up to contain user settable
variables (the Debugger and Process classes).  The 'settings' command
has been modified to be a command-subcommand structure, and the 'set',
'show' and 'append' commands have been moved into this sub-commabnd
structure.  The old StateVariable class has been completely replaced
by this, and the state variable dictionary has been removed from the
Command Interpreter.  Places that formerly accessed the state variable
mechanism have been modified to access the variables in this new
structure instead (checking the term-width; getting/checking the
prompt; etc.)

Variables are attached to classes; there are two basic "flavors" of
variables that can be set: "global" variables (static/class-wide), and
"instance" variables (one per instance of the class).  The whole thing
has been set up so that any global or instance variable can be set at
any time (e.g. on start up, in your .lldbinit file), whether or not
any instances actually exist (there's a whole pending and default
values mechanism to help deal with that).




git-svn-id: https://llvm.org/svn/llvm-project/llvdb/trunk@113041 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Interpreter/CommandInterpreter.cpp b/source/Interpreter/CommandInterpreter.cpp
index 2b4155d..3c9a748 100644
--- a/source/Interpreter/CommandInterpreter.cpp
+++ b/source/Interpreter/CommandInterpreter.cpp
@@ -12,7 +12,6 @@
 #include <getopt.h>
 #include <stdlib.h>
 
-#include "../Commands/CommandObjectAppend.h"
 #include "../Commands/CommandObjectApropos.h"
 #include "../Commands/CommandObjectArgs.h"
 #include "../Commands/CommandObjectBreakpoint.h"
@@ -30,9 +29,7 @@
 #include "lldb/Interpreter/CommandObjectRegexCommand.h"
 #include "../Commands/CommandObjectRegister.h"
 #include "CommandObjectScript.h"
-#include "../Commands/CommandObjectSet.h"
 #include "../Commands/CommandObjectSettings.h"
-#include "../Commands/CommandObjectShow.h"
 #include "../Commands/CommandObjectSource.h"
 #include "../Commands/CommandObjectCommands.h"
 #include "../Commands/CommandObjectSyntax.h"
@@ -61,9 +58,13 @@
 ) :
     Broadcaster ("CommandInterpreter"),
     m_debugger (debugger),
-    m_script_language (script_language),
     m_synchronous_execution (synchronous_execution)
 {
+    const char *dbg_name = debugger.GetInstanceName().AsCString();
+    std::string lang_name = ScriptInterpreter::LanguageToString (script_language);
+    StreamString var_name;
+    var_name.Printf ("[%s].script-lang", dbg_name);
+    debugger.GetSettingsController()->SetVariable (var_name.GetData(), lang_name.c_str(), lldb::eVarSetOperationAssign, false);
 }
 
 void
@@ -75,8 +76,6 @@
 
     LoadCommandDictionary ();
 
-    InitializeVariables ();
-
     // Set up some initial aliases.
     result.Clear(); HandleCommand ("command alias q        quit", false, result);
     result.Clear(); HandleCommand ("command alias run      process launch", false, result);
@@ -98,72 +97,6 @@
     result.Clear(); HandleCommand ("command alias list     source list", false, result);
 }
 
-void
-CommandInterpreter::InitializeVariables ()
-{
-    Timer scoped_timer (__PRETTY_FUNCTION__, __PRETTY_FUNCTION__);
-
-    m_variables["prompt"] =
-            StateVariableSP (new StateVariable ("prompt",
-                                                "(lldb) ",
-                                                false,
-                                                "The debugger prompt displayed for the user.",
-                                                StateVariable::BroadcastPromptChange));
-
-    m_variables["run-args"] =
-            StateVariableSP (new StateVariable ("run-args",
-                                                (Args*)NULL,
-                                                "An argument list containing the arguments to be passed to the executable when it is launched."));
-
-
-    m_variables["env-vars"] =
-            StateVariableSP (new StateVariable ("env-vars",
-                                                (Args*)NULL,
-                                                "A list of strings containing the environment variables to be passed to the executable's environment."));
-
-    m_variables["input-path"] =
-            StateVariableSP (new StateVariable ("input-path",
-                                                "/dev/stdin",
-                                                false,
-                                                "The file/path to be used by the executable program for reading its input."));
-
-    m_variables["output-path"] =
-            StateVariableSP (new StateVariable ( "output-path",
-                                                "/dev/stdout",
-                                                false,
-                                                "The file/path to be used by the executable program for writing its output."));
-
-    m_variables["error-path"] =
-            StateVariableSP (new StateVariable ("error-path",
-                                                "/dev/stderr",
-                                                false,
-                                                "The file/path to be used by the executable program for writing its error messages."));
-
-    m_variables["arch"] =
-        StateVariableSP (new StateVariable ("arch",
-                                            "",
-                                            false,
-                                            "The architecture to be used for running the executable (e.g. i386, x86_64, etc)."));
-
-    m_variables["script-lang"] =
-        StateVariableSP (new StateVariable ("script-lang",
-                                            "Python",
-                                            false,
-                                            "The script language to be used for evaluating user-written scripts.",
-                                            StateVariable::VerifyScriptLanguage));
-
-    m_variables["term-width"] =
-    StateVariableSP (new StateVariable ("term-width",
-                                         80,
-                                        "The maximum number of columns to use for displaying text."));
-    
-    m_variables["disable-aslr"] =
-    StateVariableSP (new StateVariable ("disable-aslr",
-                                        1,
-                                        "Disable Address Space Layout Randomization (ASLR)."));
-    
-}
-
 const char *
 CommandInterpreter::ProcessEmbeddedScriptCommands (const char *arg)
 {
@@ -201,7 +134,16 @@
 
     // Non-CommandObjectCrossref commands can now be created.
 
-    m_command_dict["append"]    = CommandObjectSP (new CommandObjectAppend ());
+    lldb::ScriptLanguage script_language;
+    lldb::SettableVariableType var_type = lldb::eSetVarTypeString;
+    StringList value;
+    const char *dbg_name = GetDebugger().GetInstanceName().AsCString();
+    StreamString var_name;
+    var_name.Printf ("[%s].script-lang", dbg_name);
+    value = Debugger::GetSettingsController()->GetVariable (var_name.GetData(), var_type);
+    bool success;
+    script_language = Args::StringToScriptLanguage (value.GetStringAtIndex(0), lldb::eScriptLanguageDefault, &success);
+    
     m_command_dict["apropos"]   = CommandObjectSP (new CommandObjectApropos ());
     m_command_dict["breakpoint"]= CommandObjectSP (new CommandObjectMultiwordBreakpoint (*this));
     //m_command_dict["call"]      = CommandObjectSP (new CommandObjectCall ());
@@ -217,10 +159,8 @@
     m_command_dict["process"]   = CommandObjectSP (new CommandObjectMultiwordProcess (*this));
     m_command_dict["quit"]      = CommandObjectSP (new CommandObjectQuit ());
     m_command_dict["register"]  = CommandObjectSP (new CommandObjectRegister (*this));
-    m_command_dict["script"]    = CommandObjectSP (new CommandObjectScript (m_script_language));
-    m_command_dict["set"]       = CommandObjectSP (new CommandObjectSet ());
-    m_command_dict["settings"]  = CommandObjectSP (new CommandObjectSettings ());
-    m_command_dict["show"]      = CommandObjectSP (new CommandObjectShow ());
+    m_command_dict["script"]    = CommandObjectSP (new CommandObjectScript (script_language));
+    m_command_dict["settings"]  = CommandObjectSP (new CommandObjectMultiwordSettings (*this));
     m_command_dict["source"]    = CommandObjectSP (new CommandObjectMultiwordSource (*this));
     m_command_dict["target"]    = CommandObjectSP (new CommandObjectMultiwordTarget (*this));
     m_command_dict["thread"]    = CommandObjectSP (new CommandObjectMultiwordThread (*this));
@@ -448,15 +388,6 @@
     return false;
 }
 
-StateVariable *
-CommandInterpreter::GetStateVariable(const char *name)
-{
-    VariableMap::const_iterator pos = m_variables.find(name);
-    if (pos != m_variables.end())
-        return pos->second.get();
-    return NULL;
-}
-
 void
 CommandInterpreter::GetAliasHelp (const char *alias_name, const char *command_name, StreamString &help_string)
 {
@@ -556,33 +487,6 @@
     result.AppendMessage("For more information on any particular command, try 'help <command-name>'.");
 }
 
-void
-CommandInterpreter::ShowVariableValues (CommandReturnObject &result)
-{
-    result.AppendMessage ("Below is a list of all the debugger setting variables and their values:");
-
-    for (VariableMap::const_iterator pos = m_variables.begin(); pos != m_variables.end(); ++pos)
-    {
-        StateVariable *var = pos->second.get();
-        var->AppendVariableInformation (result);
-    }
-}
-
-void
-CommandInterpreter::ShowVariableHelp (CommandReturnObject &result)
-{
-    result.AppendMessage ("Below is a list of all the internal debugger variables that are settable:");
-    for (VariableMap::const_iterator pos = m_variables.begin(); pos != m_variables.end(); ++pos)
-    {
-        StateVariable *var = pos->second.get();
-        result.AppendMessageWithFormat ("    %s  --  %s \n", var->GetName(), var->GetHelp());
-    }
-}
-
-// Main entry point into the command_interpreter; this function takes a text
-// line containing a debugger command, with all its flags, options, etc,
-// parses the line and takes the appropriate actions.
-
 bool
 CommandInterpreter::HandleCommand 
 (
@@ -861,47 +765,6 @@
     return num_command_matches;
 }
 
-const Args *
-CommandInterpreter::GetProgramArguments ()
-{
-    if (! HasInterpreterVariables())
-        return NULL;
-
-    VariableMap::const_iterator pos = m_variables.find("run-args");
-    if (pos == m_variables.end())
-        return NULL;
-
-    StateVariable *var = pos->second.get();
-
-    if (var)
-        return &var->GetArgs();
-    return NULL;
-}
-
-const Args *
-CommandInterpreter::GetEnvironmentVariables ()
-{
-    if (! HasInterpreterVariables())
-        return NULL;
-
-    VariableMap::const_iterator pos = m_variables.find("env-vars");
-    if (pos == m_variables.end())
-        return NULL;
-
-    StateVariable *var = pos->second.get();
-    if (var)
-        return &var->GetArgs();
-    return NULL;
-}
-
-int
-CommandInterpreter::GetDisableASLR ()
-{
-    StateVariable *var = GetStateVariable ("disable-aslr");
-    int disable_aslr = var->GetIntValue();
-
-    return disable_aslr;
-}
 
 CommandInterpreter::~CommandInterpreter ()
 {
@@ -910,37 +773,20 @@
 const char *
 CommandInterpreter::GetPrompt ()
 {
-    VariableMap::iterator pos;
-
-    if (! HasInterpreterVariables())
-        return NULL;
-
-    pos = m_variables.find("prompt");
-    if (pos == m_variables.end())
-        return NULL;
-
-    StateVariable *var = pos->second.get();
-
-    return ((char *) var->GetStringValue());
+    lldb::SettableVariableType var_type;
+    const char *instance_name = GetDebugger().GetInstanceName().AsCString();
+    StreamString var_name;
+    var_name.Printf ("[%s].prompt", instance_name);
+    return Debugger::GetSettingsController()->GetVariable (var_name.GetData(), var_type).GetStringAtIndex(0);
 }
 
 void
 CommandInterpreter::SetPrompt (const char *new_prompt)
 {
-    VariableMap::iterator pos;
-    CommandReturnObject result;
-
-    if (! HasInterpreterVariables())
-        return;
-
-    pos = m_variables.find ("prompt");
-    if (pos == m_variables.end())
-        return;
-
-    StateVariable *var = pos->second.get();
-
-    if (var->VerifyValue (this, (void *) new_prompt, result))
-       var->SetStringValue (new_prompt);
+    const char *instance_name = GetDebugger().GetInstanceName().AsCString();
+    StreamString name_str;
+    name_str.Printf ("[%s].prompt", instance_name);
+    Debugger::GetSettingsController()->SetVariable (name_str.GetData(), new_prompt, lldb::eVarSetOperationAssign, false);
 }
 
 void
@@ -956,12 +802,6 @@
     }
 }
 
-void
-CommandInterpreter::SetScriptLanguage (ScriptLanguage lang)
-{
-    m_script_language = lang;
-}
-
 OptionArgVectorSP
 CommandInterpreter::GetAliasOptions (const char *alias_name)
 {
@@ -1020,12 +860,6 @@
     return (!m_alias_options.empty());
 }
 
-bool
-CommandInterpreter::HasInterpreterVariables ()
-{
-    return (!m_variables.empty());
-}
-
 void
 CommandInterpreter::BuildAliasCommandArgs
 (
@@ -1201,8 +1035,10 @@
                                              const char *help_text,
                                              uint32_t max_word_len)
 {
-    StateVariable *var = GetStateVariable ("term-width");
-    int max_columns = var->GetIntValue();
+    lldb::SettableVariableType var_type;
+    const char *width_value = 
+                            Debugger::GetSettingsController()->GetVariable ("term-width", var_type).GetStringAtIndex(0);
+    int max_columns = atoi (width_value);
     // Sanity check max_columns, to cope with emacs shell mode with TERM=dumb
     // (0 rows; 0 columns;).
     if (max_columns <= 0) max_columns = 80;
diff --git a/source/Interpreter/Options.cpp b/source/Interpreter/Options.cpp
index 097bd45..60ab120 100644
--- a/source/Interpreter/Options.cpp
+++ b/source/Interpreter/Options.cpp
@@ -364,7 +364,13 @@
     CommandObject *cmd,
     const char *program_name)
 {
-    uint32_t screen_width = 80;
+    lldb::SettableVariableType var_type;
+    const char *screen_width_str = 
+                            Debugger::GetSettingsController()->GetVariable ("term-width", var_type).GetStringAtIndex(0);
+    uint32_t screen_width = atoi (screen_width_str);
+    if (screen_width == 0)
+        screen_width = 80;
+
     const lldb::OptionDefinition *full_options_table = GetDefinitions();
     const uint32_t save_indent_level = strm.GetIndentLevel();
     const char *name;
diff --git a/source/Interpreter/ScriptInterpreter.cpp b/source/Interpreter/ScriptInterpreter.cpp
index 9c5c086..e4b5634 100644
--- a/source/Interpreter/ScriptInterpreter.cpp
+++ b/source/Interpreter/ScriptInterpreter.cpp
@@ -63,4 +63,21 @@
     result.AppendError ("ScriptInterpreter::GetScriptCommands(StringList &) is not implemented.");
 }
 
+std::string
+ScriptInterpreter::LanguageToString (lldb::ScriptLanguage language)
+{
+    std::string return_value;
 
+    switch (language)
+    {
+        case eScriptLanguageNone:
+            return_value = "None";
+            break;
+        case eScriptLanguagePython:
+            return_value = "Python";
+            break;
+        
+    }
+
+    return return_value;
+}
diff --git a/source/Interpreter/StateVariable.cpp b/source/Interpreter/StateVariable.cpp
deleted file mode 100644
index ae84e1b..0000000
--- a/source/Interpreter/StateVariable.cpp
+++ /dev/null
@@ -1,320 +0,0 @@
-//===-- StateVariable.cpp ---------------------------------------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "lldb/Interpreter/CommandReturnObject.h"
-#include "lldb/Interpreter/CommandInterpreter.h"
-
-
-#include "lldb/Interpreter/StateVariable.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-// Variables with integer values.
-
-StateVariable::StateVariable
-(
-    const char *name,
-    int value,
-    const char *help,
-    Callback func_ptr
-) :
-    m_name (name),
-    m_type (eTypeInteger),
-    m_help_text (help),
-    m_verification_func_ptr (func_ptr)
-{
-    m_int_value = value;
-}
-
-// Variables with boolean values.
-
-StateVariable::StateVariable
-(
-    const char *name,
-    bool value,
-    const char *help,
-    Callback func_ptr
- ) :
-    m_name (name),
-    m_type (eTypeBoolean),
-    m_help_text (help),
-    m_verification_func_ptr (func_ptr)
-{
-    m_int_value = value;
-}
-
-// Variables with string values.
-
-StateVariable::StateVariable
-(
-    const char *name,
-    const char *value,
-    bool can_append,
-    const char *help,
-    Callback func_ptr
- ) :
-    m_name (name),
-    m_type (eTypeString),
-    m_int_value (0),
-    m_string_values (),
-    m_help_text (help),
-    m_verification_func_ptr (func_ptr)
-{
-    m_string_values.AppendArgument(value);
-}
-
-// Variables with array of strings values.
-
-StateVariable::StateVariable
-(
-    const char *name,
-    const Args *args,
-    const char *help,
-    Callback func_ptr
- ) :
-    m_name (name),
-    m_type (eTypeStringArray),
-    m_string_values(),
-    m_help_text (help),
-    m_verification_func_ptr (func_ptr)
-{
-    if (args)
-        m_string_values = *args;
-}
-
-StateVariable::~StateVariable ()
-{
-}
-
-const char *
-StateVariable::GetName () const
-{
-    return m_name.c_str();
-}
-
-StateVariable::Type
-StateVariable::GetType () const
-{
-    return m_type;
-}
-
-int
-StateVariable::GetIntValue () const
-{
-    return m_int_value;
-}
-
-bool
-StateVariable::GetBoolValue () const
-{
-    return m_int_value;
-}
-
-const char *
-StateVariable::GetStringValue () const
-{
-    return m_string_values.GetArgumentAtIndex(0);
-}
-
-const Args &
-StateVariable::GetArgs () const
-{
-    return m_string_values;
-}
-
-Args &
-StateVariable::GetArgs ()
-{
-    return m_string_values;
-}
-
-const char *
-StateVariable::GetHelp () const
-{
-    return m_help_text.c_str();
-}
-
-void
-StateVariable::SetHelp (const char *help)
-{
-    m_help_text = help;
-}
-
-void
-StateVariable::AppendVariableInformation (CommandReturnObject &result)
-{
-    switch (m_type)
-    {
-    case eTypeBoolean:
-        if (m_int_value)
-            result.AppendMessageWithFormat ("    %s (bool) = True\n", m_name.c_str());
-        else
-            result.AppendMessageWithFormat ("    %s (bool) = False\n", m_name.c_str());
-        break;
-
-    case eTypeInteger:
-        result.AppendMessageWithFormat ("    %s (int)  = %d\n", m_name.c_str(), m_int_value);
-        break;
-
-    case eTypeString:
-        {
-            const char *cstr = m_string_values.GetArgumentAtIndex(0);
-            if (cstr && cstr[0])
-                result.AppendMessageWithFormat ("    %s (str)  = '%s'\n", m_name.c_str(), cstr);
-            else
-                result.AppendMessageWithFormat ("    %s (str)  = <no value>\n", m_name.c_str());
-        }
-        break;
-
-    case eTypeStringArray:
-        {
-            const size_t argc = m_string_values.GetArgumentCount();
-            result.AppendMessageWithFormat ("    %s (string vector):\n", m_name.c_str());
-            for (size_t i = 0; i < argc; ++i)
-                result.AppendMessageWithFormat ("      [%d] %s\n", i, m_string_values.GetArgumentAtIndex(i));
-        }
-        break;
-
-    default:
-        break;
-    }
-}
-
-void
-StateVariable::SetStringValue (const char *new_value)
-{
-    if (m_string_values.GetArgumentCount() > 0)
-        m_string_values.ReplaceArgumentAtIndex(0, new_value);
-    else
-        m_string_values.AppendArgument(new_value);
-}
-
-void
-StateVariable::SetIntValue (int new_value)
-{
-    m_int_value = new_value;
-}
-
-void
-StateVariable::SetBoolValue (bool new_value)
-{
-    m_int_value = new_value;
-}
-
-void
-StateVariable::AppendStringValue (const char *cstr)
-{
-    if (cstr && cstr[0])
-    {
-        if (m_string_values.GetArgumentCount() == 0)
-        {
-            m_string_values.AppendArgument(cstr);
-        }
-        else
-        {
-            const char *curr_arg = m_string_values.GetArgumentAtIndex(0);
-            if (curr_arg != NULL)
-            {
-                std::string new_arg_str(curr_arg);
-                new_arg_str += " ";
-                new_arg_str += cstr;
-                m_string_values.ReplaceArgumentAtIndex(0, new_arg_str.c_str());
-            }
-            else
-            {
-                m_string_values.ReplaceArgumentAtIndex(0, cstr);
-            }
-        }
-    }
-}
-
-bool
-StateVariable::VerifyValue (CommandInterpreter *interpreter, void *data, CommandReturnObject &result)
-{
-    return (*m_verification_func_ptr) (interpreter, data, result);
-}
-
-//void
-//StateVariable::SetArrayValue (STLStringArray &new_value)
-//{
-//    m_string_values.AppendArgument.append(cstr);
-//
-//    if (m_array_value != NULL)
-//    {
-//      if (m_array_value->size() > 0)
-//      {
-//          m_array_value->clear();
-//      }
-//    }
-//    else
-//        m_array_value = new STLStringArray;
-//
-//    for (int i = 0; i < new_value.size(); ++i)
-//        m_array_value->push_back (new_value[i]);
-//}
-//
-
-void
-StateVariable::ArrayClearValues ()
-{
-    m_string_values.Clear();
-}
-
-
-void
-StateVariable::ArrayAppendValue (const char *cstr)
-{
-    m_string_values.AppendArgument(cstr);
-}
-
-
-bool
-StateVariable::HasVerifyFunction ()
-{
-    return (m_verification_func_ptr != NULL);
-}
-
-// Verification functions for various command interpreter variables.
-
-bool
-StateVariable::VerifyScriptLanguage (CommandInterpreter *interpreter, void *data, CommandReturnObject &result)
-{
-    bool valid_lang = true;
-    interpreter->SetScriptLanguage (Args::StringToScriptLanguage((char *) data, eScriptLanguageDefault, &valid_lang));
-    return valid_lang;
-}
-
-bool
-StateVariable::BroadcastPromptChange (CommandInterpreter *interpreter, void *data, CommandReturnObject &result)
-{
-    char *prompt = (char *) data;
-    if (prompt != NULL)
-    {
-        std::string tmp_prompt = prompt ;
-        int len = tmp_prompt.size();
-        if (len > 1
-            && (tmp_prompt[0] == '\'' || tmp_prompt[0] == '"')
-            && (tmp_prompt[len-1] == tmp_prompt[0]))
-        {
-            tmp_prompt = tmp_prompt.substr(1,len-2);
-        }
-        len = tmp_prompt.size();
-        if (tmp_prompt[len-1] != ' ')
-            tmp_prompt.append(" ");
-        strcpy (prompt, tmp_prompt.c_str());
-        data = (void *) prompt;
-    }
-    EventSP new_event_sp;
-    new_event_sp.reset (new Event(CommandInterpreter::eBroadcastBitResetPrompt, new EventDataBytes (prompt)));
-    interpreter->BroadcastEvent (new_event_sp);
-
-    return true;
-}
-