diff options
37 files changed, 4668 insertions, 1233 deletions
diff --git a/lldb/include/lldb/API/SBCommandInterpreter.h b/lldb/include/lldb/API/SBCommandInterpreter.h index 5101a4cf1c3..d2e938719aa 100644 --- a/lldb/include/lldb/API/SBCommandInterpreter.h +++ b/lldb/include/lldb/API/SBCommandInterpreter.h @@ -42,8 +42,8 @@ public: lldb::SBBroadcaster GetBroadcaster (); - const char ** - GetEnvironmentVariables (); + //const char ** + //GetEnvironmentVariables (); bool HasCommands (); @@ -57,8 +57,8 @@ public: bool HasAliasOptions (); - bool - HasInterpreterVariables (); + //bool + //HasInterpreterVariables (); lldb::SBProcess GetProcess (); diff --git a/lldb/include/lldb/API/SBDebugger.h b/lldb/include/lldb/API/SBDebugger.h index 2ad6f0236df..5cc4c2c9285 100644 --- a/lldb/include/lldb/API/SBDebugger.h +++ b/lldb/include/lldb/API/SBDebugger.h @@ -145,6 +145,12 @@ public: static SBDebugger FindDebuggerWithID (int id); + lldb::SBError + SetInternalVariable (const char *var_name, const char *value); + + lldb::SBStringList + GetInternalVariableValue (const char *var_name); + private: #ifndef SWIG diff --git a/lldb/include/lldb/API/SBDefines.h b/lldb/include/lldb/API/SBDefines.h index ece7efdb43b..aaaa62458af 100644 --- a/lldb/include/lldb/API/SBDefines.h +++ b/lldb/include/lldb/API/SBDefines.h @@ -50,6 +50,7 @@ class SBListener; class SBModule; class SBProcess; class SBSourceManager; +class SBStringList; class SBSymbol; class SBSymbolContext; class SBStringList; diff --git a/lldb/include/lldb/API/SBError.h b/lldb/include/lldb/API/SBError.h index fcd9a929d13..12a4de1b1ef 100644 --- a/lldb/include/lldb/API/SBError.h +++ b/lldb/include/lldb/API/SBError.h @@ -67,6 +67,7 @@ public: protected: friend class SBArguments; + friend class SBDebugger; friend class SBCommunication; friend class SBHostOS; friend class SBInputReader; diff --git a/lldb/include/lldb/Core/Debugger.h b/lldb/include/lldb/Core/Debugger.h index 743e1798784..c434b7d422a 100644 --- a/lldb/include/lldb/Core/Debugger.h +++ b/lldb/include/lldb/Core/Debugger.h @@ -22,6 +22,7 @@ #include "lldb/Core/StreamFile.h" #include "lldb/Core/SourceManager.h" #include "lldb/Core/UserID.h" +#include "lldb/Core/UserSettingsController.h" #include "lldb/Target/ExecutionContext.h" #include "lldb/Target/TargetList.h" @@ -33,11 +34,112 @@ namespace lldb_private { /// /// Provides a global root objects for the debugger core. //---------------------------------------------------------------------- + + +class DebuggerInstanceSettings : public InstanceSettings +{ +public: + + DebuggerInstanceSettings (UserSettingsController &owner, const char *name = NULL); + + DebuggerInstanceSettings (const DebuggerInstanceSettings &rhs); + + virtual + ~DebuggerInstanceSettings (); + + DebuggerInstanceSettings& + operator= (const DebuggerInstanceSettings &rhs); + + void + UpdateInstanceSettingsVariable (const ConstString &var_name, + const char *index_value, + const char *value, + const ConstString &instance_name, + const SettingEntry &entry, + lldb::VarSetOperationType op, + Error &err, + bool pending); + + void + GetInstanceSettingsValue (const SettingEntry &entry, + const ConstString &var_name, + StringList &value); + +protected: + + void + CopyInstanceSettings (const lldb::InstanceSettingsSP &new_settings, + bool pending); + + bool + BroadcastPromptChange (const ConstString &instance_name, const char *new_prompt); + + const ConstString + CreateInstanceName (); + + const ConstString & + PromptVarName (); + + const ConstString & + ScriptLangVarName (); + +private: + + std::string m_prompt; + lldb::ScriptLanguage m_script_lang; +}; + + + class Debugger : - public UserID + public UserID, + public DebuggerInstanceSettings { public: + class DebuggerSettingsController : public UserSettingsController + { + public: + + DebuggerSettingsController (); + + virtual + ~DebuggerSettingsController (); + + void + UpdateGlobalVariable (const ConstString &var_name, + const char *index_value, + const char *value, + const SettingEntry &entry, + lldb::VarSetOperationType op, + Error&err); + + void + GetGlobalSettingsValue (const ConstString &var_name, + StringList &value); + + static SettingEntry global_settings_table[]; + static SettingEntry instance_settings_table[]; + + protected: + + lldb::InstanceSettingsSP + CreateNewInstanceSettings (); + + bool + ValidTermWidthValue (const char *value, Error err); + + private: + + // Class-wide settings. + int m_term_width; + + DISALLOW_COPY_AND_ASSIGN (DebuggerSettingsController); + }; + + static lldb::UserSettingsControllerSP & + GetSettingsController (bool finish = false); + static lldb::DebuggerSP CreateInstance (); @@ -137,7 +239,6 @@ public: return m_exe_ctx; } - void UpdateExecutionContext (ExecutionContext *override_context); @@ -158,6 +259,9 @@ public: return m_use_external_editor; } + static lldb::DebuggerSP + FindDebuggerWithInstanceName (const ConstString &instance_name); + protected: static void @@ -192,8 +296,6 @@ private: // debugger object Debugger (); - - DISALLOW_COPY_AND_ASSIGN (Debugger); }; diff --git a/lldb/include/lldb/Core/UserSettingsController.h b/lldb/include/lldb/Core/UserSettingsController.h new file mode 100644 index 00000000000..532e9c6cbd7 --- /dev/null +++ b/lldb/include/lldb/Core/UserSettingsController.h @@ -0,0 +1,380 @@ +//====-- UserSettingsController.h --------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_UserSettingsController_h_ +#define liblldb_UserSettingsController_h_ + +// C Includes +// C++ Includes + +#include <string> +#include <vector> + +// Other libraries and framework includes +// Project includes + +#include "lldb/lldb-private.h" +#include "lldb/Core/ConstString.h" +#include "lldb/Core/StringList.h" +#include "lldb/Core/Stream.h" +#include "lldb/Core/StreamString.h" +#include "lldb/Host/Mutex.h" + +namespace lldb_private { + +typedef struct +{ + const char *var_name; + lldb::SettableVariableType var_type; + const char *default_value; + lldb::OptionEnumValueElement *enum_values; + bool initialized; + bool hidden; + const char *description; //help text +} SettingEntry; + + +typedef struct +{ + lldb::UserSettingsControllerSP parent; + ConstString level_name; + std::vector<SettingEntry> global_settings; + std::vector<SettingEntry> instance_settings; +} UserSettingDefinition; + +class UserSettingsController +{ +public: + + UserSettingsController (const char *level_name, + const lldb::UserSettingsControllerSP &parent); + + virtual + ~UserSettingsController (); + + // Pure virtual functions, which all sub-classes must implement. + + virtual lldb::InstanceSettingsSP + CreateNewInstanceSettings () = 0; + + virtual void + UpdateGlobalVariable (const ConstString &var_name, + const char *index_value, + const char *value, + const SettingEntry &entry, + const lldb::VarSetOperationType op, + Error &err) = 0; + + virtual void + GetGlobalSettingsValue (const ConstString &var_name, + StringList &value) = 0; + + // End of pure virtual functions. + + Error + SetVariable (const char *full_dot_name, + const char *value, + const lldb::VarSetOperationType op, + const bool override, + const char *index_value = NULL); + + StringList + GetVariable (const char *full_dot_name, + lldb::SettableVariableType &var_type); + + const lldb::UserSettingsControllerSP & + GetParent (); + + const ConstString & + GetLevelName (); + + void + RegisterChild (const lldb::UserSettingsControllerSP &child); + + void + RemoveChild (const lldb::UserSettingsControllerSP &child); + + void + CreateSettingsVector (const SettingEntry *table, + const bool global); + + void + CreateDefaultInstanceSettings (); + + void + InitializeGlobalVariables (); + + const lldb::InstanceSettingsSP & + FindPendingSettings (const ConstString &instance_name); + + void + RemovePendingSettings (const ConstString &instance_name); + + void + RegisterInstanceSettings (InstanceSettings *instance_settings); + + void + UnregisterInstanceSettings (InstanceSettings *instance_settings); + + // ------------------------------------------------------------------------- + // Public static methods + // ------------------------------------------------------------------------- + + static void + FindAllSettingsDescriptions (CommandInterpreter &interpreter, + lldb::UserSettingsControllerSP root, + std::string ¤t_prefix, + StreamString &result_stream, + Error &err); + + static void + GetAllVariableValues (CommandInterpreter &interpreter, + lldb::UserSettingsControllerSP root, + std::string ¤t_prefix, + StreamString &result_stream, + Error &err); + + static int + CompleteSettingsNames (lldb::UserSettingsControllerSP root_settings, + Args &partial_setting_name_pieces, + bool &word_complete, + StringList &matches); + + static int + CompleteSettingsValue (lldb::UserSettingsControllerSP root_settings, + const char *full_dot_name, + const char *partial_value, + bool &word_complete, + StringList &matches); + + static Args + BreakNameIntoPieces (const char *full_dot_name); + + static const char * + GetTypeString (lldb::SettableVariableType var_type); + + + static const char * + EnumToString (const lldb::OptionEnumValueElement *enum_values, int value); + + static void + UpdateStringVariable (lldb::VarSetOperationType op, + std::string &string_var, + const char *new_value, + Error &err); + + + static void + UpdateBooleanVariable (lldb::VarSetOperationType op, + bool &bool_var, + const char *new_value, + Error &err); + + static void + UpdateStringArrayVariable (lldb::VarSetOperationType op, + const char *index_value, + Args &array_var, + const char *new_value, + Error &err); + + static void + UpdateDictionaryVariable (lldb::VarSetOperationType op, + const char *index_value, + std::map<std::string, std::string> &dictionary, + const char *new_value, + Error &err); + + static void + UpdateEnumVariable (lldb::OptionEnumValueElement *enum_values, + int *enum_var, + const char *new_value, + Error &err); + +protected: + + // ------------------------------------------------------------------------- + // Protected methods are declared below here. + // ------------------------------------------------------------------------- + + bool + IsLiveInstance (const std::string &instance_name); + + int + GlobalVariableMatches (const char *partial_name, + const std::string &complete_prefix, + StringList &matches); + + int + InstanceVariableMatches (const char *partial_name, + const std::string &complete_prefix, + const char *instance_name, + StringList &matches); + + int + LiveInstanceMatches (const char *partial_name, + const std::string &complete_prefix, + bool &word_complete, + StringList &matches); + + int + ChildMatches (const char *partial_name, + const std::string &complete_prefix, + bool &word_complete, + StringList &matches); + + + size_t + GetNumChildren (); + + const lldb::UserSettingsControllerSP + GetChildAtIndex (size_t index); + + + const SettingEntry * + GetGlobalEntry (const ConstString &var_name); + + const SettingEntry * + GetInstanceEntry (const ConstString &var_name); + + void + BuildParentPrefix (std::string &parent_prefix); + + + void + CopyDefaultSettings (const lldb::InstanceSettingsSP &new_settings, + const ConstString &instance_name, + bool pending); + + lldb::InstanceSettingsSP + PendingSettingsForInstance (const ConstString &instance_name); + + InstanceSettings * + FindSettingsForInstance (const ConstString &instance_name); + + void + GetAllPendingSettingValues (StreamString &result_stream); + + void + GetAllDefaultSettingValues (StreamString &result_stream); + + void + GetAllInstanceVariableValues (CommandInterpreter &interpreter, + StreamString &result_stream); + + void + OverrideAllInstances (const ConstString &var_name, + const char *value, + lldb::VarSetOperationType op, + const char *index_value, + Error &err); + + UserSettingDefinition & + GetControllerSettings () { return m_settings; } + + // ------------------------------------------------------------------------- + // Static protected methods are declared below here. + // ------------------------------------------------------------------------- + + static void + PrintEnumValues (const lldb::OptionEnumValueElement *enum_values, Stream &str); + + + static int + BooleanMatches (const char *partial_value, + bool &word_complete, + StringList &matches); + + static int + EnumMatches (const char *partial_value, + lldb::OptionEnumValueElement *enum_values, + bool &word_complete, + StringList &matches); + + static void + VerifyOperationForType (lldb::SettableVariableType var_type, + lldb::VarSetOperationType op, + const ConstString &var_name, + Error &err); + + // This is protected rather than private so that classes that inherit from UserSettingsController can access it. + + lldb::InstanceSettingsSP m_default_settings; + +private: + + UserSettingDefinition m_settings; + + std::vector<lldb::UserSettingsControllerSP> m_children; + std::map <std::string, lldb::InstanceSettingsSP> m_pending_settings; + std::map <std::string, InstanceSettings *> m_live_settings; // live settings should never be NULL (hence 'live') + + mutable Mutex m_children_mutex; + mutable Mutex m_pending_settings_mutex; + mutable Mutex m_live_settings_mutex; + + DISALLOW_COPY_AND_ASSIGN (UserSettingsController); +}; + +class InstanceSettings +{ +public: + + InstanceSettings (UserSettingsController &owner, const char *instance_name); + + InstanceSettings (const InstanceSettings &rhs); + + virtual + ~InstanceSettings (); + + InstanceSettings& + operator= (const InstanceSettings &rhs); + + // Begin Pure Virtual Functions + + virtual void + UpdateInstanceSettingsVariable (const ConstString &var_name, + const char *index_value, + const char *value, + const ConstString &instance_name, + const SettingEntry &entry, + lldb::VarSetOperationType op, + Error &err, + bool pending) = 0; + + virtual void + GetInstanceSettingsValue (const SettingEntry &entry, + const ConstString &var_name, + StringList &value) = 0; + + virtual void + CopyInstanceSettings (const lldb::InstanceSettingsSP &new_settings, + bool pending) = 0; + + virtual const ConstString + CreateInstanceName () = 0; + + // End Pure Virtual Functions + + const ConstString & + GetInstanceName () { return m_instance_name; } + + static const ConstString & + GetDefaultName (); + +protected: + + UserSettingsController &m_owner; + const ConstString m_instance_name; +}; + + + +} // namespace lldb_private + +#endif // liblldb_UserSettingsController_h_ diff --git a/lldb/include/lldb/Interpreter/CommandCompletions.h b/lldb/include/lldb/Interpreter/CommandCompletions.h index 377e2c9ad58..11e7346f4b5 100644 --- a/lldb/include/lldb/Interpreter/CommandCompletions.h +++ b/lldb/include/lldb/Interpreter/CommandCompletions.h @@ -44,7 +44,8 @@ public: eDiskDirectoryCompletion = (1 << 2), eSymbolCompletion = (1 << 3), eModuleCompletion = (1 << 4), - eCustomCompletion = (1 << 5) // This item serves two purposes. It is the last element in the enum, + eSettingsNameCompletion = (1 << 5), + eCustomCompletion = (1 << 6) // This item serves two purposes. It is the last element in the enum, // so you can add custom enums starting from here in your Option class. // Also if you & in this bit the base code will not process the option. @@ -112,6 +113,15 @@ public: bool &word_complete, lldb_private::StringList &matches); + static int + SettingsNames (CommandInterpreter &interpreter, + const char *partial_file_name, + int match_start_point, + int max_return_elements, + SearchFilter *searcher, + bool &word_complete, + lldb_private::StringList &matches); + //---------------------------------------------------------------------- // The Completer class is a convenient base class for building searchers // that go along with the SearchFilter passed to the standard Completer diff --git a/lldb/include/lldb/Interpreter/CommandInterpreter.h b/lldb/include/lldb/Interpreter/CommandInterpreter.h index 77c0c77bfda..458f9020f36 100644 --- a/lldb/include/lldb/Interpreter/CommandInterpreter.h +++ b/lldb/include/lldb/Interpreter/CommandInterpreter.h @@ -20,7 +20,6 @@ #include "lldb/Core/Log.h" #include "lldb/Interpreter/CommandObject.h" #include "lldb/Interpreter/ScriptInterpreter.h" -#include "lldb/Interpreter/StateVariable.h" #include "lldb/Core/Event.h" #include "lldb/Interpreter/Args.h" #include "lldb/Core/StringList.h" @@ -30,7 +29,6 @@ namespace lldb_private { class CommandInterpreter : public Broadcaster { public: - typedef std::map<std::string, lldb::StateVariableSP> VariableMap; typedef std::map<std::string, OptionArgVectorSP> OptionArgMap; enum @@ -59,9 +57,6 @@ public: CommandObject * GetCommandObject (const char *cmd, StringList *matches = NULL); - StateVariable * - GetStateVariable(const char *name); - bool CommandExists (const char *cmd); @@ -148,27 +143,12 @@ public: const char *help_text, uint32_t max_word_len); - void - ShowVariableValues (CommandReturnObject &result); - - void - ShowVariableHelp (CommandReturnObject &result); - Debugger & GetDebugger () { return m_debugger; } - const Args * - GetProgramArguments (); - - const Args * - GetEnvironmentVariables (); - - int - GetDisableASLR (); - const char * ProcessEmbeddedScriptCommands (const char *arg); @@ -185,9 +165,6 @@ public: Initialize (); void - InitializeVariables (); - - void CrossRegisterCommand (const char * dest_cmd, const char * object_type); void @@ -206,9 +183,6 @@ public: bool HasAliasOptions (); - bool - HasInterpreterVariables (); - void BuildAliasCommandArgs (CommandObject *alias_cmd_obj, const char *alias_name, Args &cmd_args, CommandReturnObject &result); @@ -255,12 +229,10 @@ protected: private: Debugger &m_debugger; // The debugger session that this interpreter is associated with - lldb::ScriptLanguage m_script_language; bool m_synchronous_execution; CommandObject::CommandMap m_command_dict; // Stores basic built-in commands (they cannot be deleted, removed or overwritten). CommandObject::CommandMap m_alias_dict; // Stores user aliases/abbreviations for commands CommandObject::CommandMap m_user_dict; // Stores user-defined commands - VariableMap m_variables; OptionArgMap m_alias_options; // Stores any options (with or without arguments) that go with any alias. std::vector<std::string> m_command_history; std::string m_repeat_command; // Stores the command that will be executed for an empty command string. diff --git a/lldb/include/lldb/Interpreter/ScriptInterpreter.h b/lldb/include/lldb/Interpreter/ScriptInterpreter.h index dda2b97b06a..77b046f4a28 100644 --- a/lldb/include/lldb/Interpreter/ScriptInterpreter.h +++ b/lldb/include/lldb/Interpreter/ScriptInterpreter.h @@ -86,6 +86,9 @@ public: CommandInterpreter * GetCommandInterpreter (); + static std::string + LanguageToString (lldb::ScriptLanguage); + private: lldb::ScriptLanguage m_script_lang; diff --git a/lldb/include/lldb/Interpreter/StateVariable.h b/lldb/include/lldb/Interpreter/StateVariable.h deleted file mode 100644 index 65118c07abb..00000000000 --- a/lldb/include/lldb/Interpreter/StateVariable.h +++ /dev/null @@ -1,145 +0,0 @@ -//===-- StateVariable.h -----------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef liblldb_InterpreterStateVariable_h_ -#define liblldb_InterpreterStateVariable_h_ - -// C Includes -// C++ Includes -#include <string> -// Other libraries and framework includes -// Project includes -#include "lldb/lldb-private.h" -#include "lldb/Interpreter/Args.h" - -namespace lldb_private { - -class StateVariable -{ -public: - - // NOTE: If you add more types to this enumeration list, you need to check for them and "do the right thing" - // in CommandObjectSet::Execute. - typedef enum - { - eTypeBoolean, - eTypeInteger, - eTypeString, - eTypeStringArray - } Type; - - - typedef bool (*Callback) (CommandInterpreter *, - void *, - CommandReturnObject &); - - StateVariable (const char *name, - const char *value, - bool can_append = false, - const char *help_text = "", - Callback func_ptr = NULL); - - StateVariable (const char *name, - bool value, - const char *help_text = "", - Callback func_ptr = NULL); - - StateVariable (const char *name, - int value, - const char *help_text = "", - Callback func_ptr = NULL); - - StateVariable (const char *name, - const Args *value, - const char *help_text = "", - Callback func_ptr = NULL); - - virtual - ~StateVariable (); - - - const char * - GetName () const; - - Type - GetType () const; - - int - GetIntValue () const; - - bool - GetBoolValue () const; - - const char * - GetStringValue () const; - - Args & - GetArgs (); - - const Args & - GetArgs () const; - - const char * - GetHelp () const; - - void - SetHelp (const char *); - - void - AppendVariableInformation (CommandReturnObject &result); - - void - SetStringValue (const char *); - - void - SetIntValue (int); - - void - SetBoolValue (bool); - - void - ArrayAppendValue (const char *); - - void - ArrayClearValues (); - - void - AppendStringValue (const char *new_string); - - bool - VerifyValue (CommandInterpreter *interpreter, - void *data, - CommandReturnObject &result); - - bool - HasVerifyFunction (); - - static bool - VerifyScriptLanguage (CommandInterpreter *interpreter, - void *data, - CommandReturnObject &result); - - static bool - BroadcastPromptChange (CommandInterpreter *interpreter, - void *data, - CommandReturnObject &result); - -private: - std::string m_name; - Type m_type; - int m_int_value; - Args m_string_values; - std::string m_help_text; - Callback m_verification_func_ptr; -}; - - -} // namespace lldb_private - -#endif // liblldb_InterpreterStateVariable_h_ diff --git a/lldb/include/lldb/Target/Process.h b/lldb/include/lldb/Target/Process.h index d8e86370ae8..366799d59bb 100644 --- a/lldb/include/lldb/Target/Process.h +++ b/lldb/include/lldb/Target/Process.h @@ -17,6 +17,8 @@ // Other libraries and framework includes // Project includes #include "lldb/lldb-private.h" +#include "lldb/Interpreter/Args.h" +#include "lldb/Interpreter/Options.h" #include "lldb/Core/Broadcaster.h" #include "lldb/Core/Error.h" #include "lldb/Core/Event.h" @@ -24,6 +26,7 @@ #include "lldb/Core/ThreadSafeValue.h" #include "lldb/Core/ThreadSafeSTLMap.h" #include "lldb/Core/PluginInterface.h" +#include "lldb/Core/UserSettingsController.h" #include "lldb/Breakpoint/BreakpointSiteList.h" #include "lldb/Expression/ClangPersistentVariables.h" #include "lldb/Expression/IRDynamicChecks.h" @@ -34,6 +37,80 @@ namespace lldb_private { +class ProcessInstanceSettings : public InstanceSettings +{ +public: + + ProcessInstanceSettings (UserSettingsController &owner, const char *name = NULL); + + ProcessInstanceSettings (const ProcessInstanceSettings &rhs); + + virtual + ~ProcessInstanceSettings (); + + ProcessInstanceSettings& + operator= (const ProcessInstanceSettings &rhs); + + + void + UpdateInstanceSettingsVariable (const ConstString &var_name, + const char *index_value, + const char *value, + const ConstString &instance_name, + const SettingEntry &entry, + lldb::VarSetOperationType op, + Error &err, + bool pending); + + void + GetInstanceSettingsValue (const SettingEntry &entry, + const ConstString &var_name, + StringList &value); + + +protected: + + void + CopyInstanceSettings (const lldb::InstanceSettingsSP &new_settings, + bool pending); + + const ConstString + CreateInstanceName (); + + const ConstString & + RunArgsVarName (); + + const ConstString & + EnvVarsVarName (); + + const ConstString & + InputPathVarName (); + + const ConstString & + OutputPathVarName (); + + const ConstString & + ErrorPathVarName (); + + const ConstString & + PluginVarName (); + + const ConstString & + DisableASLRVarName(); + + +private: + + Args m_run_args; + std::map<std::string, std::string> m_env_vars; + std::string m_input_path; + std::string m_output_path; + std::string m_error_path; + lldb::ProcessPlugins m_plugin; + bool m_disable_aslr; +}; + + //---------------------------------------------------------------------- /// @class Process Process.h "lldb/Target/Process.h" /// @brief A plug-in interface definition class for debugging a process. @@ -42,7 +119,8 @@ class Process : public UserID, public Broadcaster, public ExecutionContextScope, - public PluginInterface + public PluginInterface, + public ProcessInstanceSettings { friend class ThreadList; @@ -145,8 +223,50 @@ public: DISALLOW_COPY_AND_ASSIGN (ProcessEventData); }; + + class ProcessSettingsController : public UserSettingsController + { + public: + + ProcessSettingsController (); + + virtual + ~ProcessSettingsController (); + + void + UpdateGlobalVariable (const ConstString &var_name, + const char *index_value, + const char *value, + const SettingEntry &entry, + lldb::VarSetOperationType op, + Error&err); + + void + GetGlobalSettingsValue (const ConstString &var_name, + StringList &value); + + static SettingEntry global_settings_table[]; + static SettingEntry instance_settings_table[]; + + protected: + + lldb::InstanceSettingsSP + CreateNewInstanceSettings (); + + static lldb::OptionEnumValueElement g_plugins[]; + + private: + + // Class-wide settings. + + DISALLOW_COPY_AND_ASSIGN (ProcessSettingsController); + }; + #endif + static lldb::UserSettingsControllerSP + GetSettingsController (bool finish = false); + //------------------------------------------------------------------ /// Construct with a shared pointer to a target, and the Process listener. //------------------------------------------------------------------ @@ -1478,12 +1598,13 @@ protected: size_t WriteMemoryPrivate (lldb::addr_t addr, const void *buf, size_t size, Error &error); - + private: //------------------------------------------------------------------ // For Process only //------------------------------------------------------------------ void ControlPrivateStateThread (uint32_t signal); + DISALLOW_COPY_AND_ASSIGN (Process); }; diff --git a/lldb/include/lldb/lldb-enumerations.h b/lldb/include/lldb/lldb-enumerations.h index 3fa2362acf6..39a385d553e 100644 --- a/lldb/include/lldb/lldb-enumerations.h +++ b/lldb/include/lldb/lldb-enumerations.h @@ -478,6 +478,40 @@ typedef enum AccessType eAccessPackage } AccessType; +//---------------------------------------------------------------------- +/// Settable state variable types. +/// +//---------------------------------------------------------------------- + +typedef enum SettableVariableType +{ + eSetVarTypeInt, + eSetVarTypeBool, + eSetVarTypeString, + eSetVarTypeArray, + eSetVarTypeDictionary, + eSetVarTypeEnum, + eSetVarTypeNone +} SettableVariableType; + +typedef enum VarSetOperationType +{ + eVarSetOperationReplace, + eVarSetOperationInsertBefore, + eVarSetOperationInsertAfter, + eVarSetOperationRemove, + eVarSetOperationAppend, + eVarSetOperationClear, + eVarSetOperationAssign, + eVarSetOperationInvalid +} VarSetOperationType; + +typedef enum ProcessPlugins +{ + eMacosx, + eRemoteDebugger +} ProcessPlugins; + } // namespace lldb diff --git a/lldb/include/lldb/lldb-forward-rtti.h b/lldb/include/lldb/lldb-forward-rtti.h index aca620c5ed8..83069c8db55 100644 --- a/lldb/include/lldb/lldb-forward-rtti.h +++ b/lldb/include/lldb/lldb-forward-rtti.h @@ -39,6 +39,7 @@ namespace lldb { typedef SharedPtr<lldb_private::Function>::Type FunctionSP; typedef SharedPtr<lldb_private::InlineFunctionInfo>::Type InlineFunctionInfoSP; typedef SharedPtr<lldb_private::InputReader>::Type InputReaderSP; + typedef SharedPtr<lldb_private::InstanceSettings>::Type InstanceSettingsSP; typedef SharedPtr<lldb_private::LineTable>::Type LineTableSP; typedef SharedPtr<lldb_private::Listener>::Type ListenerSP; typedef SharedPtr<lldb_private::Log>::Type LogSP; @@ -50,7 +51,6 @@ namespace lldb { typedef SharedPtr<lldb_private::SearchFilter>::Type SearchFilterSP; typedef SharedPtr<lldb_private::StackFrame>::Type StackFrameSP; typedef SharedPtr<lldb_private::StackFrameList>::Type StackFrameListSP; - typedef SharedPtr<lldb_private::StateVariable>::Type StateVariableSP; typedef SharedPtr<lldb_private::StopInfo>::Type StopInfoSP; typedef SharedPtr<lldb_private::StoppointLocation>::Type StoppointLocationSP; typedef SharedPtr<lldb_private::Stream>::Type StreamSP; @@ -59,6 +59,7 @@ namespace lldb { typedef SharedPtr<lldb_private::Thread>::Type ThreadSP; typedef SharedPtr<lldb_private::ThreadPlan>::Type ThreadPlanSP; typedef SharedPtr<lldb_private::Type>::Type TypeSP; + typedef SharedPtr<lldb_private::UserSettingsController>::Type UserSettingsControllerSP; typedef SharedPtr<lldb_private::ValueObject>::Type ValueObjectSP; typedef SharedPtr<lldb_private::Variable>::Type VariableSP; typedef SharedPtr<lldb_private::VariableList>::Type VariableListSP; diff --git a/lldb/include/lldb/lldb-forward.h b/lldb/include/lldb/lldb-forward.h index 01a94178942..d80ebb43c10 100644 --- a/lldb/include/lldb/lldb-forward.h +++ b/lldb/include/lldb/lldb-forward.h @@ -72,6 +72,7 @@ class Function; class FunctionInfo; class InlineFunctionInfo; class InputReader; +class InstanceSettings; struct LineEntry; class LineTable; class Listener; @@ -101,7 +102,6 @@ class SourceManager; class StackFrame; class StackFrameList; class StackID; -class StateVariable; class StopInfo; class Stoppoint; class StoppointCallbackContext; @@ -134,6 +134,7 @@ class TimeValue; class Type; class TypeList; class Unwind; +class UserSettingsController; class UUID; class VMRange; class Value; diff --git a/lldb/lldb.xcodeproj/project.pbxproj b/lldb/lldb.xcodeproj/project.pbxproj index 12db609d48d..e04a0c47f05 100644 --- a/lldb/lldb.xcodeproj/project.pbxproj +++ b/lldb/lldb.xcodeproj/project.pbxproj @@ -83,7 +83,6 @@ 26D5B07211B07550009A862E /* Stoppoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7E1610F1B83100F91463 /* Stoppoint.cpp */; }; 26D5B07311B07550009A862E /* StoppointLocation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7E1710F1B83100F91463 /* StoppointLocation.cpp */; }; 26D5B07411B07550009A862E /* WatchpointLocation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7E1810F1B83100F91463 /* WatchpointLocation.cpp */; }; - 26D5B07611B07550009A862E /* CommandObjectAppend.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7E2B10F1B84700F91463 /* CommandObjectAppend.cpp */; }; 26D5B07711B07550009A862E /* CommandObjectBreakpoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7E2D10F1B84700F91463 /* CommandObjectBreakpoint.cpp */; }; 26D5B07911B07550009A862E /* CommandObjectDisassemble.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7E3010F1B84700F91463 /* CommandObjectDisassemble.cpp */; }; 26D5B07A11B07550009A862E /* CommandObjectExpression.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7E3110F1B84700F91463 /* CommandObjectExpression.cpp */; }; @@ -95,9 +94,7 @@ 26D5B08111B07550009A862E /* CommandObjectQuit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7E3910F1B84700F91463 /* CommandObjectQuit.cpp */; }; 26D5B08211B07550009A862E /* CommandObjectRegister.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7E3B10F1B84700F91463 /* CommandObjectRegister.cpp */; }; 26D5B08311B07550009A862E /* CommandObjectScript.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7E3D10F1B84700F91463 /* CommandObjectScript.cpp */; }; - 26D5B08511B07550009A862E /* CommandObjectSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7E3F10F1B84700F91463 /* CommandObjectSet.cpp */; }; 26D5B08611B07550009A862E /* CommandObjectSettings.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7E4010F1B84700F91463 /* CommandObjectSettings.cpp */; }; - 26D5B08711B07550009A862E /* CommandObjectShow.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7E4110F1B84700F91463 /* CommandObjectShow.cpp */; }; 26D5B08811B07550009A862E /* CommandObjectSource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7E4210F1B84700F91463 /* CommandObjectSource.cpp */; }; 26D5B08B11B07550009A862E /* CommandObjectSyntax.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7E4510F1B84700F91463 /* CommandObjectSyntax.cpp */; }; 26D5B08C11B07550009A862E /* CommandObjectThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7E4610F1B84700F91463 /* CommandObjectThread.cpp */; }; @@ -162,7 +159,6 @@ 26D5B0CB11B07550009A862E /* CommandInterpreter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7F0810F1B8DD00F91463 /* CommandInterpreter.cpp */; }; 26D5B0CC11B07550009A862E /* CommandObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7F0910F1B8DD00F91463 /* CommandObject.cpp */; }; 26D5B0CD11B07550009A862E /* CommandReturnObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7F0A10F1B8DD00F91463 /* CommandReturnObject.cpp */; }; - 26D5B0CE11B07550009A862E /* StateVariable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7F0B10F1B8DD00F91463 /* StateVariable.cpp */; }; 26D5B0CF11B07550009A862E /* ScriptInterpreterPython.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7F0C10F1B8DD00F91463 /* ScriptInterpreterPython.cpp */; }; 26D5B0D011B07550009A862E /* Block.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7F1310F1B8EC00F91463 /* Block.cpp */; }; 26D5B0D111B07550009A862E /* ClangASTContext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7F1410F1B8EC00F91463 /* ClangASTContext.cpp */; settings = {COMPILER_FLAGS = "-fno-rtti"; }; }; @@ -364,6 +360,8 @@ 9A357673116E7B6400E8ED2F /* SBStringList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9A357672116E7B6400E8ED2F /* SBStringList.cpp */; }; 9A3576A8116E9AB700E8ED2F /* SBHostOS.h in Headers */ = {isa = PBXBuildFile; fileRef = 9A3576A7116E9AB700E8ED2F /* SBHostOS.h */; settings = {ATTRIBUTES = (Public, ); }; }; 9A3576AA116E9AC700E8ED2F /* SBHostOS.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9A3576A9116E9AC700E8ED2F /* SBHostOS.cpp */; }; + 9A4633DB11F65D8600955CE1 /* UserSettingsController.h in Headers */ = {isa = PBXBuildFile; fileRef = 9A4633DA11F65D8600955CE1 /* UserSettingsController.h */; }; + 9A4633DD11F65D9A00955CE1 /* UserSettingsController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9A4633DC11F65D9A00955CE1 /* UserSettingsController.cpp */; }; 9AA69DA61188F52100D753A0 /* PseudoTerminal.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2682F16A115EDA0D00CCFF99 /* PseudoTerminal.cpp */; }; 9AA69DAF118A023300D753A0 /* SBInputReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 9AA69DAE118A023300D753A0 /* SBInputReader.h */; settings = {ATTRIBUTES = (Public, ); }; }; 9AA69DB1118A024600D753A0 /* SBInputReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9AA69DB0118A024600D753A0 /* SBInputReader.cpp */; }; @@ -613,7 +611,6 @@ 26BC7CFA10F1B71400F91463 /* Stoppoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Stoppoint.h; path = include/lldb/Breakpoint/Stoppoint.h; sourceTree = "<group>"; }; 26BC7CFB10F1B71400F91463 /* StoppointLocation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StoppointLocation.h; path = include/lldb/Breakpoint/StoppointLocation.h; sourceTree = "<group>"; }; 26BC7CFC10F1B71400F91463 /* WatchpointLocation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WatchpointLocation.h; path = include/lldb/Breakpoint/WatchpointLocation.h; sourceTree = "<group>"; }; - 26BC7D1210F1B76300F91463 /* CommandObjectAppend.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommandObjectAppend.h; path = source/Commands/CommandObjectAppend.h; sourceTree = "<group>"; }; 26BC7D1410F1B76300F91463 /* CommandObjectBreakpoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommandObjectBreakpoint.h; path = source/Commands/CommandObjectBreakpoint.h; sourceTree = "<group>"; }; 26BC7D1710F1B76300F91463 /* CommandObjectDisassemble.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommandObjectDisassemble.h; path = source/Commands/CommandObjectDisassemble.h; sourceTree = "<group>"; }; 26BC7D1810F1B76300F91463 /* CommandObjectExpression.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommandObjectExpression.h; path = source/Commands/CommandObjectExpression.h; sourceTree = "<group>"; }; @@ -625,9 +622,7 @@ 26BC7D2010F1B76300F91463 /* CommandObjectQuit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommandObjectQuit.h; path = source/Commands/CommandObjectQuit.h; sourceTree = "<group>"; }; 26BC7D2210F1B76300F91463 /* CommandObjectRegister.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommandObjectRegister.h; path = source/Commands/CommandObjectRegister.h; sourceTree = "<group>"; }; 26BC7D2410F1B76300F91463 /* CommandObjectScript.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommandObjectScript.h; path = source/Interpreter/CommandObjectScript.h; sourceTree = "<group>"; }; - 26BC7D2610F1B76300F91463 /* CommandObjectSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommandObjectSet.h; path = source/Commands/CommandObjectSet.h; sourceTree = "<group>"; }; 26BC7D2710F1B76300F91463 /* CommandObjectSettings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommandObjectSettings.h; path = source/Commands/CommandObjectSettings.h; sourceTree = "<group>"; }; - 26BC7D2810F1B76300F91463 /* CommandObjectShow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommandObjectShow.h; path = source/Commands/CommandObjectShow.h; sourceTree = "<group>"; }; 26BC7D2910F1B76300F91463 /* CommandObjectSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommandObjectSource.h; path = source/Commands/CommandObjectSource.h; sourceTree = "<group>"; }; 26BC7D2C10F1B76300F91463 /* CommandObjectSyntax.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommandObjectSyntax.h; path = source/Commands/CommandObjectSyntax.h; sourceTree = "<group>"; }; 26BC7D2D10F1B76300F91463 /* CommandObjectThread.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommandObjectThread.h; path = source/Commands/CommandObjectThread.h; sourceTree = "<group>"; }; @@ -695,7 +690,6 @@ 26BC7DE410F1B7F900F91463 /* CommandReturnObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommandReturnObject.h; path = include/lldb/Interpreter/CommandReturnObject.h; sourceTree = "<group>"; }; 26BC7DE510F1B7F900F91463 /* ScriptInterpreter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ScriptInterpreter.h; path = include/lldb/Interpreter/ScriptInterpreter.h; sourceTree = "<group>"; }; 26BC7DE610F1B7F900F91463 /* ScriptInterpreterPython.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ScriptInterpreterPython.h; path = include/lldb/Interpreter/ScriptInterpreterPython.h; sourceTree = "<group>"; }; - 26BC7DE710F1B7F900F91463 /* StateVariable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StateVariable.h; path = include/lldb/Interpreter/StateVariable.h; sourceTree = "<group>"; }; 26BC7DF110F1B81A00F91463 /* DynamicLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DynamicLoader.h; path = include/lldb/Target/DynamicLoader.h; sourceTree = "<group>"; }; 26BC7DF210F1B81A00F91463 /* ExecutionContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ExecutionContext.h; path = include/lldb/Target/ExecutionContext.h; sourceTree = "<group>"; }; 26BC7DF310F1B81A00F91463 /* Process.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Process.h; path = include/lldb/Target/Process.h; sourceTree = "<group>"; }; @@ -724,7 +718,6 @@ 26BC7E1610F1B83100F91463 /* Stoppoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Stoppoint.cpp; path = source/Breakpoint/Stoppoint.cpp; sourceTree = "<group>"; }; 26BC7E1710F1B83100F91463 /* StoppointLocation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = StoppointLocation.cpp; path = source/Breakpoint/StoppointLocation.cpp; sourceTree = "<group>"; }; 26BC7E1810F1B83100F91463 /* WatchpointLocation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = WatchpointLocation.cpp; path = source/Breakpoint/WatchpointLocation.cpp; sourceTree = "<group>"; }; - 26BC7E2B10F1B84700F91463 /* CommandObjectAppend.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandObjectAppend.cpp; path = source/Commands/CommandObjectAppend.cpp; sourceTree = "<group>"; }; 26BC7E2D10F1B84700F91463 /* CommandObjectBreakpoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandObjectBreakpoint.cpp; path = source/Commands/CommandObjectBreakpoint.cpp; sourceTree = "<group>"; }; 26BC7E3010F1B84700F91463 /* CommandObjectDisassemble.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandObjectDisassemble.cpp; path = source/Commands/CommandObjectDisassemble.cpp; sourceTree = "<group>"; }; 26BC7E3110F1B84700F91463 /* CommandObjectExpression.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandObjectExpression.cpp; path = source/Commands/CommandObjectExpression.cpp; sourceTree = "<group>"; }; @@ -736,9 +729,7 @@ 26BC7E3910F1B84700F91463 /* CommandObjectQuit.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandObjectQuit.cpp; path = source/Commands/CommandObjectQuit.cpp; sourceTree = "<group>"; }; 26BC7E3B10F1B84700F91463 /* CommandObjectRegister.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandObjectRegister.cpp; path = source/Commands/CommandObjectRegister.cpp; sourceTree = "<group>"; }; 26BC7E3D10F1B84700F91463 /* CommandObjectScript.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandObjectScript.cpp; path = source/Interpreter/CommandObjectScript.cpp; sourceTree = "<group>"; }; - 26BC7E3F10F1B84700F91463 /* CommandObjectSet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandObjectSet.cpp; path = source/Commands/CommandObjectSet.cpp; sourceTree = "<group>"; }; 26BC7E4010F1B84700F91463 /* CommandObjectSettings.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandObjectSettings.cpp; path = source/Commands/CommandObjectSettings.cpp; sourceTree = "<group>"; }; - 26BC7E4110F1B84700F91463 /* CommandObjectShow.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandObjectShow.cpp; path = source/Commands/CommandObjectShow.cpp; sourceTree = "<group>"; }; 26BC7E4210F1B84700F91463 /* CommandObjectSource.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandObjectSource.cpp; path = source/Commands/CommandObjectSource.cpp; sourceTree = "<group>"; }; 26BC7E4510F1B84700F91463 /* CommandObjectSyntax.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandObjectSyntax.cpp; path = source/Commands/CommandObjectSyntax.cpp; sourceTree = "<group>"; }; 26BC7E4610F1B84700F91463 /* CommandObjectThread.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandObjectThread.cpp; path = source/Commands/CommandObjectThread.cpp; sourceTree = "<group>"; }; @@ -811,7 +802,6 @@ 26BC7F0810F1B8DD00F91463 /* CommandInterpreter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandInterpreter.cpp; path = source/Interpreter/CommandInterpreter.cpp; sourceTree = "<group>"; }; 26BC7F0910F1B8DD00F91463 /* CommandObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandObject.cpp; path = source/Interpreter/CommandObject.cpp; sourceTree = "<group>"; }; 26BC7F0A10F1B8DD00F91463 /* CommandReturnObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandReturnObject.cpp; path = source/Interpreter/CommandReturnObject.cpp; sourceTree = "<group>"; }; - 26BC7F0B10F1B8DD00F91463 /* StateVariable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = StateVariable.cpp; path = source/Interpreter/StateVariable.cpp; sourceTree = "<group>"; }; 26BC7F0C10F1B8DD00F91463 /* ScriptInterpreterPython.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ScriptInterpreterPython.cpp; path = source/Interpreter/ScriptInterpreterPython.cpp; sourceTree = "<group>"; }; 26BC7F1310F1B8EC00F91463 /* Block.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Block.cpp; path = source/Symbol/Block.cpp; sourceTree = "<group>"; }; 26BC7F1410F1B8EC00F91463 /* ClangASTContext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ClangASTContext.cpp; path = source/Symbol/ClangASTContext.cpp; sourceTree = "<group>"; }; @@ -1012,6 +1002,8 @@ 9A3576A9116E9AC700E8ED2F /* SBHostOS.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SBHostOS.cpp; path = source/API/SBHostOS.cpp; sourceTree = "<group>"; }; 9A42976111861A9F00FE05CD /* CommandObjectBreakpointCommand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommandObjectBreakpointCommand.h; path = source/Commands/CommandObjectBreakpointCommand.h; sourceTree = "<group>"; }; 9A42976211861AA600FE05CD /* CommandObjectBreakpointCommand.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandObjectBreakpointCommand.cpp; path = source/Commands/CommandObjectBreakpointCommand.cpp; sourceTree = "<group>"; }; + 9A4633DA11F65D8600955CE1 /* UserSettingsController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = UserSettingsController.h; path = include/lldb/Core/UserSettingsController.h; sourceTree = "<group>"; }; + 9A4633DC11F65D9A00955CE1 /* UserSettingsController.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = UserSettingsController.cpp; path = source/Core/UserSettingsController.cpp; sourceTree = "<group>"; }; 9A633FE7112DCE3C001A7E43 /* SBFrame.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SBFrame.cpp; path = source/API/SBFrame.cpp; sourceTree = "<group>"; }; 9A633FE8112DCE3C001A7E43 /* SBFrame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SBFrame.h; path = include/lldb/API/SBFrame.h; sourceTree = "<group>"; }; 9A82010B10FFB49800182560 /* ScriptInterpreter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ScriptInterpreter.cpp; path = source/Interpreter/ScriptInterpreter.cpp; sourceTree = "<group>"; }; @@ -1669,6 +1661,8 @@ 268A813F115B19D000F645B0 /* UniqueCStringMap.h */, 26BC7D8010F1B77400F91463 /* UserID.h */, 26BC7E9810F1B85900F91463 /* UserID.cpp */, + 9A4633DA11F65D8600955CE1 /* UserSettingsController.h */, + 9A4633DC11F65D9A00955CE1 /* UserSettingsController.cpp */, 26C81CA411335651004BDC5A /* UUID.h */, 26C81CA511335651004BDC5A /* UUID.cpp */, 26BC7D8110F1B77400F91463 /* Value.h */, @@ -1783,8 +1777,6 @@ 26BC7D0D10F1B71D00F91463 /* Commands */ = { isa = PBXGroup; children = ( - 26BC7D1210F1B76300F91463 /* CommandObjectAppend.h */, - 26BC7E2B10F1B84700F91463 /* CommandObjectAppend.cpp */, 4CA9637A11B6E99A00780E28 /* CommandObjectApropos.h */, 4CA9637911B6E99A00780E28 /* CommandObjectApropos.cpp */, 499F381E11A5B3F300F5CE02 /* CommandObjectArgs.h */, @@ -1821,12 +1813,8 @@ 26BC7E3B10F1B84700F91463 /* CommandObjectRegister.cpp */, 26BC7D2410F1B76300F91463 /* CommandObjectScript.h */, 26BC7E3D10F1B84700F91463 /* CommandObjectScript.cpp */, - 26BC7D2610F1B76300F91463 /* CommandObjectSet.h */, - 26BC7E3F10F1B84700F91463 /* CommandObjectSet.cpp */, 26BC7D2710F1B76300F91463 /* CommandObjectSettings.h */, 26BC7E4010F1B84700F91463 /* CommandObjectSettings.cpp */, - 26BC7D2810F1B76300F91463 /* CommandObjectShow.h */, - 26BC7E4110F1B84700F91463 /* CommandObjectShow.cpp */, 26BC7D2910F1B76300F91463 /* CommandObjectSource.h */, 26BC7E4210F1B84700F91463 /* CommandObjectSource.cpp */, 26BC7D2C10F1B76300F91463 /* CommandObjectSyntax.h */, @@ -1921,8 +1909,6 @@ 9A2771FC1135A37500E6ADB6 /* ScriptInterpreterNone.cpp */, 26BC7DE610F1B7F900F91463 /* ScriptInterpreterPython.h */, 26BC7F0C10F1B8DD00F91463 /* ScriptInterpreterPython.cpp */, - 26BC7DE710F1B7F900F91463 /* StateVariable.h */, - 26BC7F0B10F1B8DD00F91463 /* StateVariable.cpp */, ); name = Interpreter; sourceTree = "<group>"; @@ -2230,6 +2216,7 @@ 49307AB211DEA4F20081F992 /* IRForTarget.h in Headers */, 4C5DBBC911E3FEC60035160F /* CommandObjectCommands.h in Headers */, 26D27CA011ED3A4E0024D721 /* ELFHeader.h in Headers */, + 9A4633DB11F65D8600955CE1 /* UserSettingsController.h in Headers */, 49E45FAA11F660DC008F7B28 /* ClangASTType.h in Headers */, 49BB309611F79450001A4197 /* TaggedASTType.h in Headers */, 264723A611FA076E00DE380C /* CleanUp.h in Headers */, @@ -2427,7 +2414,6 @@ 26D5B07211B07550009A862E /* Stoppoint.cpp in Sources */, 26D5B07311B07550009A862E /* StoppointLocation.cpp in Sources */, 26D5B07411B07550009A862E /* WatchpointLocation.cpp in Sources */, - 26D5B07611B07550009A862E /* CommandObjectAppend.cpp in Sources */, 26D5B07711B07550009A862E /* CommandObjectBreakpoint.cpp in Sources */, 26D5B07911B07550009A862E /* CommandObjectDisassemble.cpp in Sources */, 26D5B07A11B07550009A862E /* CommandObjectExpression.cpp in Sources */, @@ -2439,9 +2425,7 @@ 26D5B08111B07550009A862E /* CommandObjectQuit.cpp in Sources */, 26D5B08211B07550009A862E /* CommandObjectRegister.cpp in Sources */, 26D5B08311B07550009A862E /* CommandObjectScript.cpp in Sources */, - 26D5B08511B07550009A862E /* CommandObjectSet.cpp in Sources */, 26D5B08611B07550009A862E /* CommandObjectSettings.cpp in Sources */, - 26D5B08711B07550009A862E /* CommandObjectShow.cpp in Sources */, 26D5B08811B07550009A862E /* CommandObjectSource.cpp in Sources */, 26D5B08B11B07550009A862E /* CommandObjectSyntax.cpp in Sources */, 26D5B08C11B07550009A862E /* CommandObjectThread.cpp in Sources */, @@ -2506,7 +2490,6 @@ 26D5B0CB11B07550009A862E /* CommandInterpreter.cpp in Sources */, 26D5B0CC11B07550009A862E /* CommandObject.cpp in Sources */, 26D5B0CD11B07550009A862E /* CommandReturnObject.cpp in Sources */, - 26D5B0CE11B07550009A862E /* StateVariable.cpp in Sources */, 26D5B0CF11B07550009A862E /* ScriptInterpreterPython.cpp in Sources */, 26D5B0D011B07550009A862E /* Block.cpp in Sources */, 26D5B0D111B07550009A862E /* ClangASTContext.cpp in Sources */, @@ -2688,6 +2671,7 @@ 49307AAE11DEA4D90081F992 /* IRForTarget.cpp in Sources */, 4C5DBBC811E3FEC60035160F /* CommandObjectCommands.cpp in Sources */, 26D27C9F11ED3A4E0024D721 /* ELFHeader.cpp in Sources */, + 9A4633DD11F65D9A00955CE1 /* UserSettingsController.cpp in Sources */, 49E45FAF11F660FE008F7B28 /* ClangASTType.cpp in Sources */, 2615DB871208A9E40021781D /* StopInfo.cpp in Sources */, 2615DBCA1208B5FC0021781D /* StopInfoMachException.cpp in Sources */, diff --git a/lldb/source/API/SBCommandInterpreter.cpp b/lldb/source/API/SBCommandInterpreter.cpp index b2cb639284a..c40d7cc37e5 100644 --- a/lldb/source/API/SBCommandInterpreter.cpp +++ b/lldb/source/API/SBCommandInterpreter.cpp @@ -107,17 +107,17 @@ SBCommandInterpreter::HandleCompletion (const char *current_line, return num_completions; } -const char ** -SBCommandInterpreter::GetEnvironmentVariables () -{ - if (m_opaque_ptr) - { - const Args *env_vars = m_opaque_ptr->GetEnvironmentVariables(); - if (env_vars) - return env_vars->GetConstArgumentVector (); - } - return NULL; -} +//const char ** +//SBCommandInterpreter::GetEnvironmentVariables () +//{ +// if (m_opaque_ptr) +// { +// //const Args *env_vars = m_opaque_ptr->GetEnvironmentVariables(); +// //if (env_vars) +// // return env_vars->GetConstArgumentVector (); +// } +// return NULL; +//} bool SBCommandInterpreter::HasCommands () @@ -151,13 +151,13 @@ SBCommandInterpreter::HasAliasOptions () return false; } -bool -SBCommandInterpreter::HasInterpreterVariables () -{ - if (m_opaque_ptr) - return m_opaque_ptr->HasInterpreterVariables (); - return false; -} +//bool +//SBCommandInterpreter::HasInterpreterVariables () +//{ +// if (m_opaque_ptr) +// return m_opaque_ptr->HasInterpreterVariables (); +// return false; +//} SBProcess SBCommandInterpreter::GetProcess () diff --git a/lldb/source/API/SBDebugger.cpp b/lldb/source/API/SBDebugger.cpp index fe2b99a2dc2..7af39038c9b 100644 --- a/lldb/source/API/SBDebugger.cpp +++ b/lldb/source/API/SBDebugger.cpp @@ -22,11 +22,12 @@ #include "lldb/API/SBCommandReturnObject.h" #include "lldb/API/SBEvent.h" #include "lldb/API/SBFrame.h" -#include "lldb/API/SBTarget.h" +#include "lldb/API/SBInputReader.h" #include "lldb/API/SBProcess.h" -#include "lldb/API/SBThread.h" #include "lldb/API/SBSourceManager.h" -#include "lldb/API/SBInputReader.h" +#include "lldb/API/SBStringList.h" +#include "lldb/API/SBTarget.h" +#include "lldb/API/SBThread.h" using namespace lldb; using namespace lldb_private; @@ -564,6 +565,32 @@ SBDebugger::FindDebuggerWithID (int id) return sb_debugger; } +SBError +SBDebugger::SetInternalVariable (const char *var_name, const char *value) +{ + lldb::UserSettingsControllerSP root_settings_controller = lldb_private::Debugger::GetSettingsController(); + + Error err = root_settings_controller->SetVariable (var_name, value, lldb::eVarSetOperationAssign, false); + SBError sb_error; + sb_error.SetError (err); + + return sb_error; +} + +lldb::SBStringList +SBDebugger::GetInternalVariableValue (const char *var_name) +{ + SBStringList ret_value; + lldb::UserSettingsControllerSP root_settings_controller = lldb_private::Debugger::GetSettingsController(); + + lldb::SettableVariableType var_type; + StringList value = root_settings_controller->GetVariable (var_name, var_type); + for (int i = 0; i < value.GetSize(); ++i) + ret_value.AppendString (value.GetStringAtIndex(i)); + + return ret_value; +} + bool SBDebugger::SetUseExternalEditor (bool value) { @@ -582,4 +609,3 @@ SBDebugger::UseExternalEditor () return false; } - diff --git a/lldb/source/Commands/CommandCompletions.cpp b/lldb/source/Commands/CommandCompletions.cpp index 77e9ac8c8f2..42275cb982d 100644 --- a/lldb/source/Commands/CommandCompletions.cpp +++ b/lldb/source/Commands/CommandCompletions.cpp @@ -38,6 +38,7 @@ CommandCompletions::g_common_completions[] = {eDiskDirectoryCompletion, CommandCompletions::DiskDirectories}, {eSymbolCompletion, CommandCompletions::Symbols}, {eModuleCompletion, CommandCompletions::Modules}, + {eSettingsNameCompletion, CommandCompletions::SettingsNames}, {eNoCompletion, NULL} // This one has to be last in the list. }; @@ -410,6 +411,26 @@ CommandCompletions::Symbols return matches.GetSize(); } +int +CommandCompletions::SettingsNames (CommandInterpreter &interpreter, + const char *partial_setting_name, + int match_start_point, + int max_return_elements, + SearchFilter *searcher, + bool &word_complete, + StringList &matches) +{ + lldb::UserSettingsControllerSP root_settings = Debugger::GetSettingsController(); + Args partial_setting_name_pieces = UserSettingsController::BreakNameIntoPieces (partial_setting_name); + + return UserSettingsController::CompleteSettingsNames (root_settings, + partial_setting_name_pieces, + word_complete, + matches); + + //return matches.GetSize(); +} + CommandCompletions::Completer::Completer ( CommandInterpreter &interpreter, @@ -687,6 +708,3 @@ CommandCompletions::ModuleCompleter::DoCompletion (SearchFilter *filter) filter->Search (*this); return m_matches.GetSize(); } - - - diff --git a/lldb/source/Commands/CommandObjectAppend.cpp b/lldb/source/Commands/CommandObjectAppend.cpp deleted file mode 100644 index 89d5cee71e4..00000000000 --- a/lldb/source/Commands/CommandObjectAppend.cpp +++ /dev/null @@ -1,94 +0,0 @@ -//===-- CommandObjectAppend.cpp ---------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "CommandObjectAppend.h" - -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes -#include "lldb/Interpreter/CommandInterpreter.h" -#include "lldb/Interpreter/CommandReturnObject.h" - -using namespace lldb; -using namespace lldb_private; - -//----------------------------------------------------------------------------- -// CommandObjectAppend -//----------------------------------------------------------------------------- - -CommandObjectAppend::CommandObjectAppend () : - CommandObject ("append", - "Allows the user to append a value to a single debugger setting variable, for settings that are of list types. Type 'settings' to see a list of debugger setting variables", - "append <var-name> <value-string>") -{ -} - -CommandObjectAppend::~CommandObjectAppend () -{ -} - -bool -CommandObjectAppend::Execute -( - CommandInterpreter &interpreter, - Args& command, - CommandReturnObject &result -) -{ - CommandInterpreter::VariableMap::iterator pos; - - const int argc = command.GetArgumentCount(); - if (argc < 2) - { - result.AppendError ("'append' requires at least two arguments"); - result.SetStatus (eReturnStatusFailed); - return false; - } - - const char *var_name = command.GetArgumentAtIndex(0); - command.Shift(); - - - if (var_name == NULL || var_name[0] == '\0') - { - result.AppendError ("'set' command requires a valid variable name. No value supplied"); - result.SetStatus (eReturnStatusFailed); - } - else - { - StateVariable *var = interpreter.GetStateVariable(var_name); - if (var == NULL) - { - result.AppendErrorWithFormat ("'%s' is not a settable internal variable.\n", var_name); - result.SetStatus (eReturnStatusFailed); - } - else - { - if (var->GetType() == StateVariable::eTypeString) - { - for (size_t i = 0; i < command.GetArgumentCount(); ++i) - var->AppendStringValue (command.GetArgumentAtIndex(i)); - result.SetStatus (eReturnStatusSuccessFinishNoResult); - } - else if (var->GetType() == StateVariable::eTypeStringArray) - { - var->GetArgs().AppendArguments (command); - result.SetStatus (eReturnStatusSuccessFinishNoResult); - } - else - { - result.AppendErrorWithFormat ("Values cannot be appended to variable '%s'. Try 'set' instead.\n", var_name); - result.SetStatus (eReturnStatusFailed); - } - } - } - return result.Succeeded(); -} - diff --git a/lldb/source/Commands/CommandObjectAppend.h b/lldb/source/Commands/CommandObjectAppend.h deleted file mode 100644 index 6b2ab9d3888..00000000000 --- a/lldb/source/Commands/CommandObjectAppend.h +++ /dev/null @@ -1,42 +0,0 @@ -//===-- CommandObjectAppend.h -----------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef liblldb_CommandObjectAppend_h_ -#define liblldb_CommandObjectAppend_h_ - -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes -#include "lldb/Interpreter/CommandObject.h" - -namespace lldb_private { -//----------------------------------------------------------------------------- -// CommandObjectAppend -//----------------------------------------------------------------------------- - -class CommandObjectAppend : public CommandObject -{ -public: - CommandObjectAppend (); - - virtual - ~CommandObjectAppend (); - - virtual bool - Execute (CommandInterpreter &interpreter, - Args& command, - CommandReturnObject &result); - - -}; - -} // namespace lldb_private - -#endif // liblldb_CommandObjectAppend_h_ diff --git a/lldb/source/Commands/CommandObjectHelp.cpp b/lldb/source/Commands/CommandObjectHelp.cpp index 4bf8a30edba..cf80cd484f1 100644 --- a/lldb/source/Commands/CommandObjectHelp.cpp +++ b/lldb/source/Commands/CommandObjectHelp.cpp @@ -94,7 +94,7 @@ CommandObjectHelp::Execute (CommandInterpreter &interpreter, Args& command, Comm Stream &output_strm = result.GetOutputStream(); if (sub_cmd_obj->GetOptions() != NULL) { - output_strm.Printf ("%s\n", sub_cmd_obj->GetHelp()); + interpreter.OutputFormattedHelpText (output_strm, "", "", sub_cmd_obj->GetHelp(), 1); output_strm.Printf ("\nSyntax: %s\n", sub_cmd_obj->GetSyntax()); sub_cmd_obj->GetOptions()->GenerateOptionUsage (output_strm, sub_cmd_obj); const char *long_help = sub_cmd_obj->GetHelpLong(); @@ -104,7 +104,7 @@ CommandObjectHelp::Execute (CommandInterpreter &interpreter, Args& command, Comm } else if (sub_cmd_obj->IsMultiwordObject()) { - output_strm.Printf ("%s\n", sub_cmd_obj->GetHelp()); + interpreter.OutputFormattedHelpText (output_strm, "", "", sub_cmd_obj->GetHelp(), 1); ((CommandObjectMultiword *) sub_cmd_obj)->GenerateHelpText (interpreter, result); } else @@ -112,9 +112,9 @@ CommandObjectHelp::Execute (CommandInterpreter &interpreter, Args& command, Comm const char *long_help = sub_cmd_obj->GetHelpLong(); if ((long_help != NULL) && (strlen (long_help) > 0)) - output_strm.Printf ("%s", long_help); + interpreter.OutputFormattedHelpText (output_strm, "", "", sub_cmd_obj->GetHelpLong(), 1); else - output_strm.Printf ("%s\n", sub_cmd_obj->GetHelp()); + interpreter.OutputFormattedHelpText (output_strm, "", "", sub_cmd_obj->GetHelp(), 1); output_strm.Printf ("\nSyntax: %s\n", sub_cmd_obj->GetSyntax()); } } diff --git a/lldb/source/Commands/CommandObjectProcess.cpp b/lldb/source/Commands/CommandObjectProcess.cpp index 73386b4fe17..3ca9e80a7e7 100644 --- a/lldb/source/Commands/CommandObjectProcess.cpp +++ b/lldb/source/Commands/CommandObjectProcess.cpp @@ -161,11 +161,44 @@ public: process = target->CreateProcess (interpreter.GetDebugger().GetListener(), plugin_name).get(); - const Args *environment = interpreter.GetEnvironmentVariables(); - const Args *run_args = interpreter.GetProgramArguments(); - uint32_t launch_flags = eLaunchFlagNone; - if (interpreter.GetDisableASLR()) - launch_flags |= eLaunchFlagDisableASLR; + const char *process_name = process->GetInstanceName().AsCString(); + StreamString run_args_var_name; + StreamString env_vars_var_name; + StreamString disable_aslr_var_name; + lldb::SettableVariableType var_type; + + Args *run_args = NULL; + run_args_var_name.Printf ("process.[%s].run-args", process_name); + StringList run_args_value = Debugger::GetSettingsController()->GetVariable (run_args_var_name.GetData(), + var_type); + if (run_args_value.GetSize() > 0) + { + run_args = new Args; + for (int i = 0; i < run_args_value.GetSize(); ++i) + run_args->AppendArgument (run_args_value.GetStringAtIndex (i)); + } + + Args *environment = NULL; + env_vars_var_name.Printf ("process.[%s].env-vars", process_name); + StringList env_vars_value = Debugger::GetSettingsController()->GetVariable (env_vars_var_name.GetData(), + var_type); + if (env_vars_value.GetSize() > 0) + { + environment = new Args; + for (int i = 0; i < env_vars_value.GetSize(); ++i) + environment->AppendArgument (env_vars_value.GetStringAtIndex (i)); + } + + uint32_t launch_flags = eLaunchFlagNone; + disable_aslr_var_name.Printf ("process.[%s].disable-aslr", process_name); + StringList disable_aslr_value = Debugger::GetSettingsController()->GetVariable(disable_aslr_var_name.GetData(), + var_type); + if (disable_aslr_value.GetSize() > 0) + { + if (strcmp (disable_aslr_value.GetStringAtIndex(0), "true") == 0) + launch_flags |= eLaunchFlagDisableASLR; + + } // There are two possible sources of args to be passed to the process upon launching: Those the user // typed at the run command (launch_args); or those the user pre-set in the run-args variable (run_args). @@ -179,12 +212,9 @@ public: else { // launch-args was not empty; use that, AND re-set run-args to contains launch-args values. - StateVariable *run_args_var = interpreter.GetStateVariable ("run-args"); - if (run_args_var != NULL) - { - run_args_var->ArrayClearValues(); - run_args_var->GetArgs().AppendArguments (launch_args); - } + std::string new_run_args; + launch_args.GetCommandString (new_run_args); + Debugger::GetSettingsController()->SetVariable (run_args_var_name.GetData(), new_run_args.c_str(), lldb::eVarSetOperationAssign, false); } diff --git a/lldb/source/Commands/CommandObjectSet.cpp b/lldb/source/Commands/CommandObjectSet.cpp deleted file mode 100644 index 89f154a083e..00000000000 --- a/lldb/source/Commands/CommandObjectSet.cpp +++ /dev/null @@ -1,152 +0,0 @@ -//===-- CommandObjectSet.cpp ------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "CommandObjectSet.h" - -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes -#include "lldb/Interpreter/CommandInterpreter.h" -#include "lldb/Interpreter/CommandReturnObject.h" - -using namespace lldb; -using namespace lldb_private; - -//------------------------------------------------------------------------- -// CommandObjectSet -//------------------------------------------------------------------------- - -CommandObjectSet::CommandObjectSet () : - CommandObject ("set", - "Allows the user to set or change the value of a single debugger setting variable.", - "set <setting_name> <value>") -{ -} - -CommandObjectSet::~CommandObjectSet() -{ -} - - -bool -CommandObjectSet::Execute -( - CommandInterpreter &interpreter, - Args& command, - CommandReturnObject &result -) -{ - CommandInterpreter::VariableMap::iterator pos; - - const int argc = command.GetArgumentCount(); - - if (argc < 1) - { - result.AppendError ("'set' takes at least two arguments"); - result.SetStatus (eReturnStatusFailed); - return false; - } - - const char *var_name = command.GetArgumentAtIndex(0); - const char *var_value = command.GetArgumentAtIndex(1); - - if (var_name == NULL || var_name[0] == '\0') - { - result.AppendError ("'set' command requires a valid variable name; No value supplied"); - result.SetStatus (eReturnStatusFailed); - } - else if (var_value == NULL || var_value[0] == '\0') - { - // No value given: Check to see if we're trying to clear an array. - StateVariable *var = interpreter.GetStateVariable (var_name); - if (var != NULL - && var->GetType() == StateVariable::eTypeStringArray) - { - var->ArrayClearValues(); - result.SetStatus (eReturnStatusSuccessFinishNoResult); - } - else - { - result.AppendError ("'set' command requires a valid variable value; No value supplied"); - result.SetStatus (eReturnStatusFailed); - } - } - else - { - StateVariable *var = interpreter.GetStateVariable(var_name); - if (var == NULL) - { - result.AppendErrorWithFormat ("'%s' is not a settable internal variable.\n", var_name); - result.SetStatus (eReturnStatusFailed); - } - else - { - result.SetStatus (eReturnStatusSuccessFinishNoResult); - if (var->GetType() == StateVariable::eTypeBoolean) - { - bool success = false; - bool new_value = Args::StringToBoolean (var_value, false, &success); - - if (success) - { - result.SetStatus(eReturnStatusSuccessFinishResult); - if (!var->HasVerifyFunction() || var->VerifyValue (&interpreter, (void *) &new_value, result)) - var->SetBoolValue (new_value); - } - else - { - result.AppendErrorWithFormat ("Invalid boolean string '%s'.\n", var_value); - result.SetStatus (eReturnStatusFailed); - } - } - else if (var->GetType() == StateVariable::eTypeInteger) - { - bool success = false; - int new_value = Args::StringToSInt32(var_value, -1, 0, &success); - - if (success) - { - result.SetStatus(eReturnStatusSuccessFinishResult); - if (!var->HasVerifyFunction() || var->VerifyValue (&interpreter, (void *) &new_value, result)) - var->SetIntValue (new_value); - } - else - { - result.AppendErrorWithFormat ("Invalid boolean string '%s'.\n", var_value); - result.SetStatus (eReturnStatusFailed); - } - } - else if (var->GetType() == StateVariable::eTypeString) - { - if (!var->HasVerifyFunction() || var->VerifyValue (&interpreter, (void *) var_value, result)) - var->SetStringValue (var_value); - } - else if (var->GetType() == StateVariable::eTypeStringArray) - { - if (var_value == NULL || var_value[0] == '\0') - var->ArrayClearValues (); - else - { - command.Shift(); // shift off variable name - var->ArrayClearValues(); // clear the old values - var->GetArgs().AppendArguments (command); // set the new values. - } - } - else - { - result.AppendErrorWithFormat ("Variable '%s' has unrecognized type.\n", - var->GetName()); - result.SetStatus (eReturnStatusFailed); - } - } - } - return result.Succeeded(); -} - diff --git a/lldb/source/Commands/CommandObjectSet.h b/lldb/source/Commands/CommandObjectSet.h deleted file mode 100644 index 8e4d81f8d42..00000000000 --- a/lldb/source/Commands/CommandObjectSet.h +++ /dev/null @@ -1,43 +0,0 @@ -//===-- CommandObjectSet.h --------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef liblldb_CommandObjectSet_h_ -#define liblldb_CommandObjectSet_h_ - -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes -#include "lldb/Interpreter/CommandObject.h" - -namespace lldb_private { - -//------------------------------------------------------------------------- -// CommandObjectSet -//------------------------------------------------------------------------- - -class CommandObjectSet : public CommandObject -{ -public: - - CommandObjectSet (); - - virtual - ~CommandObjectSet (); - - virtual bool - Execute (CommandInterpreter &interpreter, - Args& command, - CommandReturnObject &result); - -}; - -} // namespace lldb_private - -#endif // liblldb_CommandObjectSet_h_ diff --git a/lldb/source/Commands/CommandObjectSettings.cpp b/lldb/source/Commands/CommandObjectSettings.cpp index 3b75c870a34..a4a3643d7bf 100644 --- a/lldb/source/Commands/CommandObjectSettings.cpp +++ b/lldb/source/Commands/CommandObjectSettings.cpp @@ -15,47 +15,998 @@ // Project includes #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandReturnObject.h" +#include "lldb/Interpreter/CommandCompletions.h" using namespace lldb; using namespace lldb_private; //------------------------------------------------------------------------- -// CommandObjectSettings +// CommandObjectMultiwordSettings //------------------------------------------------------------------------- -CommandObjectSettings::CommandObjectSettings () : - CommandObject ("settings", - "Lists the debugger settings variables available to the user to 'set' or 'show'.", - "settings") +CommandObjectMultiwordSettings::CommandObjectMultiwordSettings (CommandInterpreter &interpreter) : + CommandObjectMultiword ("settings", + "A set of commands for manipulating internal settable debugger variables.", + "settings <command> [<command-options>]") { + bool status; + + CommandObjectSP set_command_object (new CommandObjectSettingsSet ()); + CommandObjectSP show_command_object (new CommandObjectSettingsShow ()); + CommandObjectSP list_command_object (new CommandObjectSettingsList ()); + CommandObjectSP remove_command_object (new CommandObjectSettingsRemove ()); + CommandObjectSP replace_command_object (new CommandObjectSettingsReplace ()); + CommandObjectSP insert_before_command_object (new CommandObjectSettingsInsertBefore ()); + CommandObjectSP insert_after_command_object (new CommandObjectSettingsInsertAfter()); + CommandObjectSP append_command_object (new CommandObjectSettingsAppend()); + CommandObjectSP clear_command_object (new CommandObjectSettingsClear()); + + status = LoadSubCommand (interpreter, "set", set_command_object); + status = LoadSubCommand (interpreter, "show", show_command_object); + status = LoadSubCommand (interpreter, "list", list_command_object); + status = LoadSubCommand (interpreter, "remove", remove_command_object); + status = LoadSubCommand (interpreter, "replace", replace_command_object); + status = LoadSubCommand (interpreter, "insert-before", insert_before_command_object); + status = LoadSubCommand (interpreter, "insert-after", insert_after_command_object); + status = LoadSubCommand (interpreter, "append", append_command_object); + status = LoadSubCommand (interpreter, "clear", clear_command_object); +} + +CommandObjectMultiwordSettings::~CommandObjectMultiwordSettings () +{ +} + +//------------------------------------------------------------------------- +// CommandObjectSettingsSet +//------------------------------------------------------------------------- + +CommandObjectSettingsSet::CommandObjectSettingsSet () : + CommandObject ("settings set", + "Allows the user to set or change the value of a single debugger setting variable.", + "settings set [<cmd-options>] <setting-variable-name> <value>"), + m_options () +{ +} + +CommandObjectSettingsSet::~CommandObjectSettingsSet() +{ +} + + +bool +CommandObjectSettingsSet::Execute (CommandInterpreter &interpreter, + Args& command, + CommandReturnObject &result) +{ + UserSettingsControllerSP root_settings = Debugger::GetSettingsController (); + + const int argc = command.GetArgumentCount (); + + if (argc < 2) + { + result.AppendError ("'settings set' takes more arguments"); + result.SetStatus (eReturnStatusFailed); + return false; + } + + const char *var_name = command.GetArgumentAtIndex (0); + std::string var_name_string; + if ((var_name == NULL) || (var_name[0] == '\0')) + { + result.AppendError ("'settings set' command requires a valid variable name; No value supplied"); + result.SetStatus (eReturnStatusFailed); + return false; + } + + var_name_string = var_name; + command.Shift(); + + const char *var_value; + std::string value_string; + + command.GetCommandString (value_string); + var_value = value_string.c_str(); + + if (!m_options.m_reset + && var_value == NULL) + { + result.AppendError ("'settings set' command requires a valid variable value unless using '--reset' option;" + " No value supplied"); + result.SetStatus (eReturnStatusFailed); + } + else + { + Error err = root_settings->SetVariable (var_name_string.c_str(), var_value, lldb::eVarSetOperationAssign, + m_options.m_override); + if (err.Fail ()) + { + result.AppendError (err.AsCString()); + result.SetStatus (eReturnStatusFailed); + } + else + result.SetStatus (eReturnStatusSuccessFinishNoResult); + } + + return result.Succeeded(); +} + +int +CommandObjectSettingsSet::HandleArgumentCompletion (CommandInterpreter &interpreter, + Args &input, + int &cursor_index, + int &cursor_char_position, + OptionElementVector &opt_element_vector, + int match_start_point, + int max_return_elements, + bool &word_complete, + StringList &matches) +{ + std::string completion_str (input.GetArgumentAtIndex (cursor_index)); + completion_str.erase (cursor_char_position); + + // Attempting to complete variable name + if (cursor_index == 1) + CommandCompletions::InvokeCommonCompletionCallbacks (interpreter, + CommandCompletions::eSettingsNameCompletion, + completion_str.c_str(), + match_start_point, + max_return_elements, + NULL, + word_complete, + matches); + + // Attempting to complete value + if ((cursor_index == 2) // Partly into the variable's value + || (cursor_index == 1 // Or at the end of a completed valid variable name + && matches.GetSize() == 1 + && completion_str.compare (matches.GetStringAtIndex(0)) == 0)) + { + matches.Clear(); + lldb::UserSettingsControllerSP root_settings = Debugger::GetSettingsController(); + if (cursor_index == 1) + { + // The user is at the end of the variable name, which is complete and valid. + UserSettingsController::CompleteSettingsValue (root_settings, + input.GetArgumentAtIndex (1), // variable name + NULL, // empty value string + word_complete, + matches); + } + else + { + // The user is partly into the variable value. + UserSettingsController::CompleteSettingsValue (root_settings, + input.GetArgumentAtIndex (1), // variable name + completion_str.c_str(), // partial value string + word_complete, + matches); + } + } + + return matches.GetSize(); +} + +//------------------------------------------------------------------------- +// CommandObjectSettingsSet::CommandOptions +//------------------------------------------------------------------------- + +CommandObjectSettingsSet::CommandOptions::CommandOptions () : + Options (), + m_override (false), + m_reset (false) +{ +} + +CommandObjectSettingsSet::CommandOptions::~CommandOptions () +{ +} + +lldb::OptionDefinition +CommandObjectSettingsSet::CommandOptions::g_option_table[] = +{ + { LLDB_OPT_SET_1, false, "override", 'o', no_argument, NULL, NULL, NULL, "Causes already existing instances and pending settings to use this new value. This option only makes sense when setting default values." }, + + { LLDB_OPT_SET_2, false, "reset", 'r', no_argument, NULL, NULL, NULL, "Causes value to be reset to the original default for this variable. No value needs to be specified when this option is used." }, +}; + +const lldb::OptionDefinition* +CommandObjectSettingsSet::CommandOptions::GetDefinitions () +{ + return g_option_table; +} + +Error +CommandObjectSettingsSet::CommandOptions::SetOptionValue (int option_idx, const char *option_arg) +{ + Error error; + char short_option = (char) m_getopt_table[option_idx].val; + + switch (short_option) + { + case 'o': + m_override = true; + break; + case 'r': + m_reset = true; + break; + default: + error.SetErrorStringWithFormat ("Unrecognized options '%c'.\n", short_option); + break; + } + + return error; +} + +void +CommandObjectSettingsSet::CommandOptions::ResetOptionValues () +{ + Options::ResetOptionValues (); + + m_override = false; + m_reset = false; +} + +Options * +CommandObjectSettingsSet::GetOptions () +{ + return &m_options; +} + + +//------------------------------------------------------------------------- +// CommandObjectSettingsShow -- Show current values +//------------------------------------------------------------------------- + +CommandObjectSettingsShow::CommandObjectSettingsShow () : + CommandObject ("settings show", + "Allows the user to see a single internal debugger setting variable and its value, or lists them all.", + "settings show [<setting-variable-name>]") +{ +} + +CommandObjectSettingsShow::~CommandObjectSettingsShow() +{ +} + + +bool +CommandObjectSettingsShow::Execute (CommandInterpreter &interpreter, + Args& command, + CommandReturnObject &result) +{ + UserSettingsControllerSP root_settings = Debugger::GetSettingsController (); + std::string current_prefix = root_settings->GetLevelName().AsCString(); + + Error err; + + if (command.GetArgumentCount()) + { + // The user requested to see the value of a particular variable. + lldb::SettableVariableType var_type; + const char *variable_name = command.GetArgumentAtIndex (0); + StringList value = root_settings->GetVariable (variable_name, var_type); + + if (value.GetSize() == 0) + { + result.AppendErrorWithFormat ("Unable to find variable named '%s'. " + "Try 'show' to see all variable values.\n", variable_name); + result.SetStatus (eReturnStatusFailed); + + } + else + { + char *type_name = (char *) ""; + if (var_type != eSetVarTypeNone) + { + StreamString tmp_str; + tmp_str.Printf (" (%s)", UserSettingsController::GetTypeString (var_type)); + type_name = (char *) tmp_str.GetData(); + } + + if (value.GetSize() == 1) + result.AppendMessageWithFormat ("%s%s = '%s'\n", variable_name, type_name, value.GetStringAtIndex (0)); + else + { + result.AppendMessageWithFormat ("%s%s:\n", variable_name, type_name); + for (int i = 0; i < value.GetSize(); ++i) + { + result.AppendMessageWithFormat (" [%d]: '%s'\n", i, value.GetStringAtIndex (i)); + } + } + result.SetStatus (eReturnStatusSuccessFinishNoResult); + } + } + else + { + UserSettingsController::GetAllVariableValues (interpreter, root_settings, current_prefix, + result.GetOutputStream(), err); + if (err.Fail ()) + { + result.AppendError (err.AsCString()); + result.SetStatus (eReturnStatusFailed); + } + else + { + result.SetStatus (eReturnStatusSuccessFinishNoResult); + } + } + + return result.Succeeded(); } -CommandObjectSettings::~CommandObjectSettings() +int +CommandObjectSettingsShow::HandleArgumentCompletion (CommandInterpreter &interpreter, + Args &input, + int &cursor_index, + int &cursor_char_position, + OptionElementVector &opt_element_vector, + int match_start_point, + int max_return_elements, + bool &word_complete, + StringList &matches) +{ + std::string completion_str (input.GetArgumentAtIndex (cursor_index)); + completion_str.erase (cursor_char_position); + + CommandCompletions::InvokeCommonCompletionCallbacks (interpreter, + CommandCompletions::eSettingsNameCompletion, + completion_str.c_str(), + match_start_point, + max_return_elements, + NULL, + word_complete, + matches); + return matches.GetSize(); +} + +//------------------------------------------------------------------------- +// CommandObjectSettingsList +//------------------------------------------------------------------------- + +CommandObjectSettingsList::CommandObjectSettingsList () : + CommandObject ("settings list", + "Lists the internal debugger settings variables available to the user to 'set' or 'show'.", + "settings list") +{ +} + +CommandObjectSettingsList::~CommandObjectSettingsList() { } bool -CommandObjectSettings::Execute -( - CommandInterpreter &interpreter, - Args& command, - CommandReturnObject &result -) +CommandObjectSettingsList::Execute (CommandInterpreter &interpreter, + Args& command, + CommandReturnObject &result) { - CommandInterpreter::VariableMap::iterator pos; + UserSettingsControllerSP root_settings = Debugger::GetSettingsController (); + std::string current_prefix = root_settings->GetLevelName().AsCString(); + + Error err; + + UserSettingsController::FindAllSettingsDescriptions (interpreter, root_settings, current_prefix, + result.GetOutputStream(), err); - if (command.GetArgumentCount() != 0) + if (err.Fail ()) { - result.AppendError ("'settings' does not take any arguments"); + result.AppendError (err.AsCString()); result.SetStatus (eReturnStatusFailed); } else { - interpreter.ShowVariableHelp (result); result.SetStatus (eReturnStatusSuccessFinishNoResult); } return result.Succeeded(); } +//------------------------------------------------------------------------- +// CommandObjectSettingsRemove +//------------------------------------------------------------------------- + +CommandObjectSettingsRemove::CommandObjectSettingsRemove () : + CommandObject ("settings remove", + "Removes the specified element from an internal debugger settings array or dictionary variable.", + "settings remove <setting-variable-name> [<index>|\"key\"]") +{ +} + +CommandObjectSettingsRemove::~CommandObjectSettingsRemove () +{ +} + +bool +CommandObjectSettingsRemove::Execute (CommandInterpreter &interpreter, + Args& command, + CommandReturnObject &result) +{ + UserSettingsControllerSP root_settings = Debugger::GetSettingsController (); + + const int argc = command.GetArgumentCount (); + + if (argc != 2) + { + result.AppendError ("'settings remove' takes two arguments"); + result.SetStatus (eReturnStatusFailed); + return false; + } + + const char *var_name = command.GetArgumentAtIndex (0); + std::string var_name_string; + if ((var_name == NULL) || (var_name[0] == '\0')) + { + result.AppendError ("'settings remove' command requires a valid variable name; No value supplied"); + result.SetStatus (eReturnStatusFailed); + return false; + } + + var_name_string = var_name; + command.Shift(); + + const char *index_value = command.GetArgumentAtIndex (0); + std::string index_value_string; + if ((index_value == NULL) || (index_value[0] == '\0')) + { + result.AppendError ("'settings remove' command requires an index or key value; no value supplied"); + result.SetStatus (eReturnStatusFailed); + return false; + } + + index_value_string = index_value; + + Error err = root_settings->SetVariable (var_name_string.c_str(), NULL, lldb::eVarSetOperationRemove, + false, index_value_string.c_str()); + if (err.Fail ()) + { + result.AppendError (err.AsCString()); + result.SetStatus (eReturnStatusFailed); + } + else + result.SetStatus (eReturnStatusSuccessFinishNoResult); + + return result.Succeeded(); +} + +int +CommandObjectSettingsRemove::HandleArgumentCompletion (CommandInterpreter &interpreter, + Args &input, + int &cursor_index, + int &cursor_char_position, + OptionElementVector &opt_element_vector, + int match_start_point, + int max_return_elements, + bool &word_complete, + StringList &matches) +{ + std::string completion_str (input.GetArgumentAtIndex (cursor_index)); + completion_str.erase (cursor_char_position); + + // Attempting to complete variable name + if (cursor_index < 2) + CommandCompletions::InvokeCommonCompletionCallbacks (interpreter, + CommandCompletions::eSettingsNameCompletion, + completion_str.c_str(), + match_start_point, + max_return_elements, + NULL, + word_complete, + matches); + + return matches.GetSize(); +} + +//------------------------------------------------------------------------- +// CommandObjectSettingsReplace +//------------------------------------------------------------------------- + +CommandObjectSettingsReplace::CommandObjectSettingsReplace () : + CommandObject ("settings replace", + "Replaces the specified element from an internal debugger settings array or dictionary variable.", + "settings replace <setting-variable-name> [<index>|\"<key>\"] <new-value>") +{ +} + +CommandObjectSettingsReplace::~CommandObjectSettingsReplace () +{ +} + +bool +CommandObjectSettingsReplace::Execute (CommandInterpreter &interpreter, + Args& command, + CommandReturnObject &result) +{ + UserSettingsControllerSP root_settings = Debugger::GetSettingsController (); + + const int argc = command.GetArgumentCount (); + + if (argc < 3) + { + result.AppendError ("'settings replace' takes more arguments"); + result.SetStatus (eReturnStatusFailed); + return false; + } + + const char *var_name = command.GetArgumentAtIndex (0); + std::string var_name_string; + if ((var_name == NULL) || (var_name[0] == '\0')) + { + result.AppendError ("'settings replace' command requires a valid variable name; No value supplied"); + result.SetStatus (eReturnStatusFailed); + return false; + } + + var_name_string = var_name; + command.Shift(); + + const char *index_value = command.GetArgumentAtIndex (0); + std::string index_value_string; + if ((index_value == NULL) || (index_value[0] == '\0')) + { + result.AppendError ("'settings insert-before' command requires an index value; no value supplied"); + result.SetStatus (eReturnStatusFailed); + return false; + } + + index_value_string = index_value; + command.Shift(); + + const char *var_value; + std::string value_string; + + command.GetCommandString (value_string); + var_value = value_string.c_str(); + + if ((var_value == NULL) || (var_value[0] == '\0')) + { + result.AppendError ("'settings replace' command requires a valid variable value; no value supplied"); + result.SetStatus (eReturnStatusFailed); + } + else + { + Error err = root_settings->SetVariable (var_name_string.c_str(), var_value, lldb::eVarSetOperationReplace, + false, index_value_string.c_str()); + if (err.Fail ()) + { + result.AppendError (err.AsCString()); + result.SetStatus (eReturnStatusFailed); + } + else + result.SetStatus (eReturnStatusSuccessFinishNoResult); + } + + return result.Succeeded(); +} + +int +CommandObjectSettingsReplace::HandleArgumentCompletion (CommandInterpreter &interpreter, + Args &input, + int &cursor_index, + int &cursor_char_position, + OptionElementVector &opt_element_vector, + int match_start_point, + int max_return_elements, + bool &word_complete, + StringList &matches) +{ + std::string completion_str (input.GetArgumentAtIndex (cursor_index)); + completion_str.erase (cursor_char_position); + + // Attempting to complete variable name + if (cursor_index < 2) + CommandCompletions::InvokeCommonCompletionCallbacks (interpreter, + CommandCompletions::eSettingsNameCompletion, + completion_str.c_str(), + match_start_point, + max_return_elements, + NULL, + word_complete, + matches); + + return matches.GetSize(); +} + +//------------------------------------------------------------------------- +// CommandObjectSettingsInsertBefore +//------------------------------------------------------------------------- + +CommandObjectSettingsInsertBefore::CommandObjectSettingsInsertBefore () : + CommandObject ("settings insert-before", + "Inserts value(s) into an internal debugger settings array variable, immediately before the specified element.", + "settings insert-before <setting-variable-name> [<index>] <new-value>") +{ +} + +CommandObjectSettingsInsertBefore::~CommandObjectSettingsInsertBefore () +{ +} + +bool +CommandObjectSettingsInsertBefore::Execute (CommandInterpreter &interpreter, + Args& command, + CommandReturnObject &result) +{ + UserSettingsControllerSP root_settings = Debugger::GetSettingsController (); + + const int argc = command.GetArgumentCount (); + + if (argc < 3) + { + result.AppendError ("'settings insert-before' takes more arguments"); + result.SetStatus (eReturnStatusFailed); + return false; + } + + const char *var_name = command.GetArgumentAtIndex (0); + std::string var_name_string; + if ((var_name == NULL) || (var_name[0] == '\0')) + { + result.AppendError ("'settings insert-before' command requires a valid variable name; No value supplied"); + result.SetStatus (eReturnStatusFailed); + return false; + } + + var_name_string = var_name; + command.Shift(); + + const char *index_value = command.GetArgumentAtIndex (0); + std::string index_value_string; + if ((index_value == NULL) || (index_value[0] == '\0')) + { + result.AppendError ("'settings insert-before' command requires an index value; no value supplied"); + result.SetStatus (eReturnStatusFailed); + return false; + } + + index_value_string = index_value; + command.Shift(); + + const char *var_value; + std::string value_string; + + command.GetCommandString (value_string); + var_value = value_string.c_str(); + + if ((var_value == NULL) || (var_value[0] == '\0')) + { + result.AppendError ("'settings insert-before' command requires a valid variable value;" + " No value supplied"); + result.SetStatus (eReturnStatusFailed); + } + else + { + Error err = root_settings->SetVariable (var_name_string.c_str(), var_value, lldb::eVarSetOperationInsertBefore, + false, index_value_string.c_str()); + if (err.Fail ()) + { + result.AppendError (err.AsCString()); + result.SetStatus (eReturnStatusFailed); + } + else + result.SetStatus (eReturnStatusSuccessFinishNoResult); + } + + return result.Succeeded(); +} + + +int +CommandObjectSettingsInsertBefore::HandleArgumentCompletion (CommandInterpreter &interpreter, + Args &input, + int &cursor_index, + int &cursor_char_position, + OptionElementVector &opt_element_vector, + int match_start_point, + int max_return_elements, + bool &word_complete, + StringList &matches) +{ + std::string completion_str (input.GetArgumentAtIndex (cursor_index)); + completion_str.erase (cursor_char_position); + + // Attempting to complete variable name + if (cursor_index < 2) + CommandCompletions::InvokeCommonCompletionCallbacks (interpreter, + CommandCompletions::eSettingsNameCompletion, + completion_str.c_str(), + match_start_point, + max_return_elements, + NULL, + word_complete, + matches); + + return matches.GetSize(); +} + +//------------------------------------------------------------------------- +// CommandObjectSettingInsertAfter +//------------------------------------------------------------------------- + +CommandObjectSettingsInsertAfter::CommandObjectSettingsInsertAfter () : + CommandObject ("settings insert-after", + "Inserts value(s) into an internal debugger settings array variable, immediately after the specified element.", + "settings insert-after <setting-variable-name> [<index>] <new-value>") +{ +} + +CommandObjectSettingsInsertAfter::~CommandObjectSettingsInsertAfter () +{ +} + +bool +CommandObjectSettingsInsertAfter::Execute (CommandInterpreter &interpreter, + Args& command, + CommandReturnObject &result) +{ + UserSettingsControllerSP root_settings = Debugger::GetSettingsController (); + + const int argc = command.GetArgumentCount (); + + if (argc < 3) + { + result.AppendError ("'settings insert-after' takes more arguments"); + result.SetStatus (eReturnStatusFailed); + return false; + } + + const char *var_name = command.GetArgumentAtIndex (0); + std::string var_name_string; + if ((var_name == NULL) || (var_name[0] == '\0')) + { + result.AppendError ("'settings insert-after' command requires a valid variable name; No value supplied"); + result.SetStatus (eReturnStatusFailed); + return false; + } + + var_name_string = var_name; + command.Shift(); + + const char *index_value = command.GetArgumentAtIndex (0); + std::string index_value_string; + if ((index_value == NULL) || (index_value[0] == '\0')) + { + result.AppendError ("'settings insert-after' command requires an index value; no value supplied"); + result.SetStatus (eReturnStatusFailed); + return false; + } + + index_value_string = index_value; + command.Shift(); + + const char *var_value; + std::string value_string; + + command.GetCommandString (value_string); + var_value = value_string.c_str(); + + if ((var_value == NULL) || (var_value[0] == '\0')) + { + result.AppendError ("'settings insert-after' command requires a valid variable value;" + " No value supplied"); + result.SetStatus (eReturnStatusFailed); + } + else + { + Error err = root_settings->SetVariable (var_name_string.c_str(), var_value, lldb::eVarSetOperationInsertAfter, + false, index_value_string.c_str()); + if (err.Fail ()) + { + result.AppendError (err.AsCString()); + result.SetStatus (eReturnStatusFailed); + } + else + result.SetStatus (eReturnStatusSuccessFinishNoResult); + } + + return result.Succeeded(); +} + + +int +CommandObjectSettingsInsertAfter::HandleArgumentCompletion (CommandInterpreter &interpreter, + Args &input, + int &cursor_index, + int &cursor_char_position, + OptionElementVector &opt_element_vector, + int match_start_point, + int max_return_elements, + bool &word_complete, + StringList &matches) +{ + std::string completion_str (input.GetArgumentAtIndex (cursor_index)); + completion_str.erase (cursor_char_position); + + // Attempting to complete variable name + if (cursor_index < 2) + CommandCompletions::InvokeCommonCompletionCallbacks (interpreter, + CommandCompletions::eSettingsNameCompletion, + completion_str.c_str(), + match_start_point, + max_return_elements, + NULL, + word_complete, + matches); + + return matches.GetSize(); +} + +//------------------------------------------------------------------------- +// CommandObjectSettingsAppend +//------------------------------------------------------------------------- + +CommandObjectSettingsAppend::CommandObjectSettingsAppend () : + CommandObject ("settings append", + "Appends new value to the end of an internal debugger settings array, dictionary or string variable.", + "settings append <setting-variable-name> <new-value>") +{ +} + +CommandObjectSettingsAppend::~CommandObjectSettingsAppend () +{ +} + +bool +CommandObjectSettingsAppend::Execute (CommandInterpreter &interpreter, + Args& command, + CommandReturnObject &result) +{ + UserSettingsControllerSP root_settings = Debugger::GetSettingsController (); + + const int argc = command.GetArgumentCount (); + + if (argc < 2) + { + result.AppendError ("'settings append' takes more arguments"); + result.SetStatus (eReturnStatusFailed); + return false; + } + + const char *var_name = command.GetArgumentAtIndex (0); + std::string var_name_string; + if ((var_name == NULL) || (var_name[0] == '\0')) + { + result.AppendError ("'settings append' command requires a valid variable name; No value supplied"); + result.SetStatus (eReturnStatusFailed); + return false; + } + + var_name_string = var_name; + command.Shift(); + + const char *var_value; + std::string value_string; + + command.GetCommandString (value_string); + var_value = value_string.c_str(); + + if ((var_value == NULL) || (var_value[0] == '\0')) + { + result.AppendError ("'settings append' command requires a valid variable value;" + " No value supplied"); + result.SetStatus (eReturnStatusFailed); + } + else + { + Error err = root_settings->SetVariable (var_name_string.c_str(), var_value, lldb::eVarSetOperationAppend, + false); + if (err.Fail ()) + { + result.AppendError (err.AsCString()); + result.SetStatus (eReturnStatusFailed); + } + else + result.SetStatus (eReturnStatusSuccessFinishNoResult); + } + + return result.Succeeded(); +} + + +int +CommandObjectSettingsAppend::HandleArgumentCompletion (CommandInterpreter &interpreter, + Args &input, + int &cursor_index, + int &cursor_char_position, + OptionElementVector &opt_element_vector, + int match_start_point, + int max_return_elements, + bool &word_complete, + StringList &matches) +{ + std::string completion_str (input.GetArgumentAtIndex (cursor_index)); + completion_str.erase (cursor_char_position); + + // Attempting to complete variable name + if (cursor_index < 2) + CommandCompletions::InvokeCommonCompletionCallbacks (interpreter, + CommandCompletions::eSettingsNameCompletion, + completion_str.c_str(), + match_start_point, + max_return_elements, + NULL, + word_complete, + matches); + + return matches.GetSize(); +} + +//------------------------------------------------------------------------- +// CommandObjectSettingsClear +//------------------------------------------------------------------------- + +CommandObjectSettingsClear::CommandObjectSettingsClear () : + CommandObject ("settings clear", + "Erases all the contents of an internal debugger settings variables; only valid for variables with clearable types, i.e. strings, arrays or dictionaries.", + "settings clear") +{ +} + +CommandObjectSettingsClear::~CommandObjectSettingsClear () +{ +} + +bool +CommandObjectSettingsClear::Execute (CommandInterpreter &interpreter, + Args& command, + CommandReturnObject &result) +{ + UserSettingsControllerSP root_settings = Debugger::GetSettingsController (); + + const int argc = command.GetArgumentCount (); + + if (argc != 1) + { + result.AppendError ("'setttings clear' takes exactly one argument"); + result.SetStatus (eReturnStatusFailed); + return false; + } + + const char *var_name = command.GetArgumentAtIndex (0); + if ((var_name == NULL) || (var_name[0] == '\0')) + { + result.AppendError ("'settings clear' command requires a valid variable name; No value supplied"); + result.SetStatus (eReturnStatusFailed); + return false; + } + + Error err = root_settings->SetVariable (var_name, NULL, lldb::eVarSetOperationClear, false); + + if (err.Fail ()) + { + result.AppendError (err.AsCString()); + result.SetStatus (eReturnStatusFailed); + } + else + result.SetStatus (eReturnStatusSuccessFinishNoResult); + + return result.Succeeded(); +} + + +int +CommandObjectSettingsClear::HandleArgumentCompletion (CommandInterpreter &interpreter, + Args &input, + int &cursor_index, + int &cursor_char_position, + OptionElementVector &opt_element_vector, + int match_start_point, + int max_return_elements, + bool &word_complete, + StringList &matches) +{ + std::string completion_str (input.GetArgumentAtIndex (cursor_index)); + completion_str.erase (cursor_char_position); + + // Attempting to complete variable name + if (cursor_index < 2) + CommandCompletions::InvokeCommonCompletionCallbacks (interpreter, + CommandCompletions::eSettingsNameCompletion, + completion_str.c_str(), + match_start_point, + max_return_elements, + NULL, + word_complete, + matches); + + return matches.GetSize(); +} diff --git a/lldb/source/Commands/CommandObjectSettings.h b/lldb/source/Commands/CommandObjectSettings.h index 4159b8b03b6..0bfb3caff3c 100644 --- a/lldb/source/Commands/CommandObjectSettings.h +++ b/lldb/source/Commands/CommandObjectSettings.h @@ -15,27 +15,327 @@ // Other libraries and framework includes // Project includes #include "lldb/Interpreter/CommandObject.h" +#include "lldb/Interpreter/CommandObjectMultiword.h" +#include "lldb/Interpreter/Options.h" + namespace lldb_private { //------------------------------------------------------------------------- -// CommandObjectSettings +// CommandObjectMultiwordSettings +//------------------------------------------------------------------------- + +class CommandObjectMultiwordSettings : public CommandObjectMultiword +{ +public: + + CommandObjectMultiwordSettings (CommandInterpreter &interpreter); + + virtual + ~CommandObjectMultiwordSettings (); + +}; + +//------------------------------------------------------------------------- +// CommandObjectSettingsSet +//------------------------------------------------------------------------- + +class CommandObjectSettingsSet : public CommandObject +{ +public: + CommandObjectSettingsSet (); + + virtual + ~CommandObjectSettingsSet (); + + virtual bool + Execute (CommandInterpreter &interpreter, + Args& command, + CommandReturnObject &result); + + virtual Options * + GetOptions (); + + class CommandOptions : public Options + { + public: + + CommandOptions (); + + virtual + ~CommandOptions (); + + virtual Error + SetOptionValue (int option_idx, const char *option_arg); + + void + ResetOptionValues (); + + const lldb::OptionDefinition* + GetDefinitions (); + + // Options table: Required for subclasses of Options. + + static lldb::OptionDefinition g_option_table[]; + + // Instance variables to hold the values for command options. + + bool m_override; + bool m_reset; + + }; + + virtual int + HandleArgumentCompletion (CommandInterpreter &interpreter, + Args &input, + int &cursor_index, + int &cursor_char_position, + OptionElementVector &opt_element_vector, + int match_start_point, + int max_return_elements, + bool &word_complete, + StringList &matches); + +private: + CommandOptions m_options; +}; + +//------------------------------------------------------------------------- +// CommandObjectSettingsShow -- Show current values //------------------------------------------------------------------------- -class CommandObjectSettings : public CommandObject +class CommandObjectSettingsShow : public CommandObject { public: + CommandObjectSettingsShow (); + + virtual + ~CommandObjectSettingsShow (); + + virtual bool + Execute (CommandInterpreter &interpreter, + Args& command, + CommandReturnObject &result); + + + virtual int + HandleArgumentCompletion (CommandInterpreter &interpreter, + Args &input, + int &cursor_index, + int &cursor_char_position, + OptionElementVector &opt_element_vector, + int match_start_point, + int max_return_elements, + bool &word_complete, + StringList &matches); + +private: +}; + +//------------------------------------------------------------------------- +// CommandObjectSettingsList -- List settable variables +//------------------------------------------------------------------------- + +class CommandObjectSettingsList : public CommandObject +{ +public: + CommandObjectSettingsList (); + + virtual + ~CommandObjectSettingsList (); + + virtual bool + Execute (CommandInterpreter &interpreter, + Args& command, + CommandReturnObject &result); + +private: +}; - CommandObjectSettings (); +//------------------------------------------------------------------------- +// CommandObjectSettingsRemove +//------------------------------------------------------------------------- + +class CommandObjectSettingsRemove : public CommandObject +{ +public: + CommandObjectSettingsRemove (); virtual - ~CommandObjectSettings (); + ~CommandObjectSettingsRemove (); virtual bool Execute (CommandInterpreter &interpreter, Args& command, CommandReturnObject &result); + virtual int + HandleArgumentCompletion (CommandInterpreter &interpreter, + Args &input, + int &cursor_index, + int &cursor_char_position, + OptionElementVector &opt_element_vector, + int match_start_point, + int max_return_elements, + bool &word_complete, + StringList &matches); + +private: +}; + +//------------------------------------------------------------------------- +// CommandObjectSettingsReplace +//------------------------------------------------------------------------- + +class CommandObjectSettingsReplace : public CommandObject +{ +public: + CommandObjectSettingsReplace (); + + virtual + ~CommandObjectSettingsReplace (); + + virtual bool + Execute (CommandInterpreter &interpreter, + Args& command, + CommandReturnObject &result); + + virtual int + HandleArgumentCompletion (CommandInterpreter &interpreter, + Args &input, + int &cursor_index, + int &cursor_char_position, + OptionElementVector &opt_element_vector, + int match_start_point, + int max_return_elements, + bool &word_complete, + StringList &matches); + +private: +}; + +//------------------------------------------------------------------------- +// CommandObjectSettingsInsertBefore +//------------------------------------------------------------------------- + +class CommandObjectSettingsInsertBefore : public CommandObject +{ +public: + CommandObjectSettingsInsertBefore (); + + virtual + ~CommandObjectSettingsInsertBefore (); + + virtual bool + Execute (CommandInterpreter &interpreter, + Args& command, + CommandReturnObject &result); + + virtual int + HandleArgumentCompletion (CommandInterpreter &interpreter, + Args &input, + int &cursor_index, + int &cursor_char_position, + OptionElementVector &opt_element_vector, + int match_start_point, + int max_return_elements, + bool &word_complete, + StringList &matches); + +private: +}; + +//------------------------------------------------------------------------- +// CommandObjectSettingInsertAfter +//------------------------------------------------------------------------- + +class CommandObjectSettingsInsertAfter : public CommandObject +{ +public: + CommandObjectSettingsInsertAfter (); + + virtual + ~CommandObjectSettingsInsertAfter (); + + virtual bool + Execute (CommandInterpreter &interpreter, + Args& command, + CommandReturnObject &result); + + virtual int + HandleArgumentCompletion (CommandInterpreter &interpreter, + Args &input, + int &cursor_index, + int &cursor_char_position, + OptionElementVector &opt_element_vector, + int match_start_point, + int max_return_elements, + bool &word_complete, + StringList &matches); + +private: +}; + +//------------------------------------------------------------------------- +// CommandObjectSettingsAppend +//------------------------------------------------------------------------- + +class CommandObjectSettingsAppend : public CommandObject +{ +public: + CommandObjectSettingsAppend (); + + virtual + ~CommandObjectSettingsAppend (); + + virtual bool + Execute (CommandInterpreter &interpreter, + Args& command, + CommandReturnObject &result); + + virtual int + HandleArgumentCompletion (CommandInterpreter &interpreter, + Args &input, + int &cursor_index, + int &cursor_char_position, + OptionElementVector &opt_element_vector, + int match_start_point, + int max_return_elements, + bool &word_complete, + StringList &matches); + +private: +}; + +//------------------------------------------------------------------------- +// CommandObjectSettingsClear +//------------------------------------------------------------------------- + +class CommandObjectSettingsClear : public CommandObject +{ +public: + CommandObjectSettingsClear (); + + virtual + ~CommandObjectSettingsClear (); + + virtual bool + Execute (CommandInterpreter &interpreter, + Args& command, + CommandReturnObject &result); + + virtual int + HandleArgumentCompletion (CommandInterpreter &interpreter, + Args &input, + int &cursor_index, + int &cursor_char_position, + OptionElementVector &opt_element_vector, + int match_start_point, + int max_return_elements, + bool &word_complete, + StringList &matches); + +private: }; } // namespace lldb_private diff --git a/lldb/source/Commands/CommandObjectShow.cpp b/lldb/source/Commands/CommandObjectShow.cpp deleted file mode 100644 index 4acbf66d548..00000000000 --- a/lldb/source/Commands/CommandObjectShow.cpp +++ /dev/null @@ -1,73 +0,0 @@ -//===-- CommandObjectShow.cpp -----------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "CommandObjectShow.h" - -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes -#include "lldb/Interpreter/CommandInterpreter.h" -#include "lldb/Interpreter/CommandReturnObject.h" - -using namespace lldb; -using namespace lldb_private; - -//------------------------------------------------------------------------- -// CommandObjectShow -//------------------------------------------------------------------------- - -CommandObjectShow::CommandObjectShow () : - CommandObject ("show", - "Allows the user to see a single debugger setting variable and its value, or lists them all.", - "show [<setting-variable-name>]") -{ -} - -CommandObjectShow::~CommandObjectShow() -{ -} - - -bool -CommandObjectShow::Execute -( - CommandInterpreter &interpreter, - Args& command, - CommandReturnObject &result -) -{ - CommandInterpreter::VariableMap::iterator pos; - - if (command.GetArgumentCount()) - { - // The user requested to see the value of a particular variable. - - const char *var_name = command.GetArgumentAtIndex(0); - StateVariable *var = interpreter.GetStateVariable(var_name); - if (var) - { - var->AppendVariableInformation (result); - result.SetStatus (eReturnStatusSuccessFinishNoResult); - } - else - { - result.AppendErrorWithFormat ("Unrecognized variable '%s'; cannot do 'show' command.\n", var_name); - result.SetStatus (eReturnStatusFailed); - } - } - else - { - // The user didn't specify a particular variable, so show the values of all of them. - interpreter.ShowVariableValues(result); - result.SetStatus (eReturnStatusSuccessFinishNoResult); - } - - return result.Succeeded(); -} diff --git a/lldb/source/Commands/CommandObjectShow.h b/lldb/source/Commands/CommandObjectShow.h deleted file mode 100644 index a51cd4d6516..00000000000 --- a/lldb/source/Commands/CommandObjectShow.h +++ /dev/null @@ -1,43 +0,0 @@ -//===-- CommandObjectShow.h -------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef liblldb_CommandObjectShow_h_ -#define liblldb_CommandObjectShow_h_ - -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes -#include "lldb/Interpreter/CommandObject.h" - -namespace lldb_private { - -//------------------------------------------------------------------------- -// CommandObjectShow -//------------------------------------------------------------------------- - -class CommandObjectShow : public CommandObject -{ -public: - - CommandObjectShow (); - - virtual - ~CommandObjectShow (); - - virtual bool - Execute (CommandInterpreter &interpreter, - Args& command, - CommandReturnObject &result); - -}; - -} // namespace lldb_private - -#endif // liblldb_CommandObjectShow_h_ diff --git a/lldb/source/Core/Debugger.cpp b/lldb/source/Core/Debugger.cpp index 1cdd7ad4d87..9ccd2c16612 100644 --- a/lldb/source/Core/Debugger.cpp +++ b/lldb/source/Core/Debugger.cpp @@ -98,6 +98,25 @@ Debugger::GetSP () return debugger_sp; } +lldb::DebuggerSP +Debugger::FindDebuggerWithInstanceName (const ConstString &instance_name) +{ + lldb::DebuggerSP debugger_sp; + + Mutex::Locker locker (GetDebuggerListMutex ()); + DebuggerList &debugger_list = GetDebuggerList(); + DebuggerList::iterator pos, end = debugger_list.end(); + + for (pos = debugger_list.begin(); pos != end; ++pos) + { + if ((*pos).get()->m_instance_name == instance_name) + { + debugger_sp = *pos; + break; + } + } + return debugger_sp; +} TargetSP Debugger::FindTargetWithProcessID (lldb::pid_t pid) @@ -118,6 +137,7 @@ Debugger::FindTargetWithProcessID (lldb::pid_t pid) Debugger::Debugger () : UserID (g_unique_id++), + DebuggerInstanceSettings (*(Debugger::GetSettingsController().get())), m_input_comm("debugger.input"), m_input_file (), m_output_file (), @@ -513,3 +533,324 @@ Debugger::FindDebuggerWithID (lldb::user_id_t id) } return debugger_sp; } + +lldb::UserSettingsControllerSP & +Debugger::GetSettingsController (bool finish) +{ + static lldb::UserSettingsControllerSP g_settings_controller (new DebuggerSettingsController); + static bool initialized = false; + + if (!initialized) + { + UserSettingsControllerSP parent = g_settings_controller->GetParent(); + if (parent) + parent->RegisterChild (g_settings_controller); + + g_settings_controller->CreateSettingsVector (Debugger::DebuggerSettingsController::global_settings_table, + true); + g_settings_controller->CreateSettingsVector (Debugger::DebuggerSettingsController::instance_settings_table, + false); + + g_settings_controller->InitializeGlobalVariables (); + g_settings_controller->CreateDefaultInstanceSettings (); + initialized = true; + } + + if (finish) + { + UserSettingsControllerSP parent = g_settings_controller->GetParent(); + if (parent) + parent->RemoveChild (g_settings_controller); + g_settings_controller.reset(); + } + return g_settings_controller; +} + +//-------------------------------------------------- +// class Debugger::DebuggerSettingsController +//-------------------------------------------------- + +Debugger::DebuggerSettingsController::DebuggerSettingsController () : + UserSettingsController ("", lldb::UserSettingsControllerSP()), + m_term_width (80) +{ + m_default_settings.reset (new DebuggerInstanceSettings (*this, InstanceSettings::GetDefaultName().AsCString())); +} + +Debugger::DebuggerSettingsController::~DebuggerSettingsController () +{ +} + + +lldb::InstanceSettingsSP +Debugger::DebuggerSettingsController::CreateNewInstanceSettings () +{ + DebuggerInstanceSettings *new_settings = new DebuggerInstanceSettings (*(Debugger::GetSettingsController().get())); + lldb::InstanceSettingsSP new_settings_sp (new_settings); + return new_settings_sp; +} + +bool +Debugger::DebuggerSettingsController::ValidTermWidthValue (const char *value, Error err) +{ + bool valid = true; + + // Verify we have a value string. + if (value == NULL + || strlen (value) == 0) + { + valid = false; + err.SetErrorString ("Missing value. Can't set terminal width without a value.\n"); + } + + // Verify the string consists entirely of digits. + if (valid) + { + int len = strlen (value); + for (int i = 0; i < len; ++i) + if (! isdigit (value[i])) + { + valid = false; + err.SetErrorStringWithFormat ("'%s' is not a valid representation of an integer.\n", value); + } + } + + // Verify the term-width is 'reasonable' (e.g. 10 <= width <= 250). + if (valid) + { + int width = atoi (value); + if (width < 10 + || width > 250) + { + valid = false; + err.SetErrorString ("Invalid term-width value; value must be between 10 and 250.\n"); + } + } + + return valid; +} + + +//-------------------------------------------------- +// class DebuggerInstanceSettings +//-------------------------------------------------- + +DebuggerInstanceSettings::DebuggerInstanceSettings (UserSettingsController &owner, const char *name) : + InstanceSettings (owner, (name == NULL ? CreateInstanceName ().AsCString() : name)), + m_prompt (), + m_script_lang () +{ + if (name == NULL) + { + const lldb::InstanceSettingsSP &pending_settings = m_owner.FindPendingSettings (m_instance_name); + CopyInstanceSettings (pending_settings, false); + m_owner.RemovePendingSettings (m_instance_name); + } +} + +DebuggerInstanceSettings::DebuggerInstanceSettings (const DebuggerInstanceSettings &rhs) : + InstanceSettings (*(Debugger::GetSettingsController().get()), CreateInstanceName ().AsCString()), + m_prompt (rhs.m_prompt), + m_script_lang (rhs.m_script_lang) +{ + const lldb::InstanceSettingsSP &pending_settings = m_owner.FindPendingSettings (m_instance_name); + CopyInstanceSettings (pending_settings, false); + m_owner.RemovePendingSettings (m_instance_name); +} + +DebuggerInstanceSettings::~DebuggerInstanceSettings () +{ +} + +DebuggerInstanceSettings& +DebuggerInstanceSettings::operator= (const DebuggerInstanceSettings &rhs) +{ + if (this != &rhs) + { + m_prompt = rhs.m_prompt; + m_script_lang = rhs.m_script_lang; + } + + return *this; +} + +void +DebuggerInstanceSettings::UpdateInstanceSettingsVariable (const ConstString &var_name, + const char *index_value, + const char *value, + const ConstString &instance_name, + const SettingEntry &entry, + lldb::VarSetOperationType op, + Error &err, + bool pending) +{ + if (var_name == PromptVarName()) + { + UserSettingsController::UpdateStringVariable (op, m_prompt, value, err); + if (!pending) + { + BroadcastPromptChange (instance_name, m_prompt.c_str()); + } + } + else if (var_name == ScriptLangVarName()) + { + bool success; + m_script_lang = Args::StringToScriptLanguage (value, eScriptLanguageDefault, + &success); + } +} + +void +Debugger::DebuggerSettingsController::UpdateGlobalVariable (const ConstString &var_name, + const char *index_value, + const char *value, + const SettingEntry &entry, + lldb::VarSetOperationType op, + Error &err) +{ + static ConstString term_width_name ("term-width"); + + if (var_name == term_width_name) + { + if (ValidTermWidthValue (value, err)) + { + m_term_width = atoi (value); + } + } +} + +void +DebuggerInstanceSettings::GetInstanceSettingsValue (const SettingEntry &entry, + const ConstString &var_name, + StringList &value) +{ + if (var_name == PromptVarName()) + { + value.AppendString (m_prompt.c_str()); + + } + else if (var_name == ScriptLangVarName()) + { + value.AppendString (ScriptInterpreter::LanguageToString (m_script_lang).c_str()); + } +} + +void +DebuggerInstanceSettings::CopyInstanceSettings (const lldb::InstanceSettingsSP &new_settings, + bool pending) +{ + if (new_settings.get() == NULL) + return; + + DebuggerInstanceSettings *new_debugger_settings = (DebuggerInstanceSettings *) new_settings.get(); + + m_prompt = new_debugger_settings->m_prompt; + if (!pending) + BroadcastPromptChange (m_instance_name, m_prompt.c_str()); + + m_script_lang = new_debugger_settings->m_script_lang; +} + +void +Debugger::DebuggerSettingsController::GetGlobalSettingsValue (const ConstString &var_name, + StringList &value) +{ + static ConstString term_width_name ("term-width"); + + if (var_name == term_width_name) + { + StreamString width_str; + width_str.Printf ("%d", m_term_width); + value.AppendString (width_str.GetData()); + } +} + +bool +DebuggerInstanceSettings::BroadcastPromptChange (const ConstString &instance_name, const char *new_prompt) +{ + std::string tmp_prompt; + + if (new_prompt != NULL) + { + tmp_prompt = new_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(" "); + } + EventSP new_event_sp; + new_event_sp.reset (new Event(CommandInterpreter::eBroadcastBitResetPrompt, + new EventDataBytes (tmp_prompt.c_str()))); + + if (instance_name.GetLength() != 0) + { + // Set prompt for a particular instance. + Debugger *dbg = Debugger::FindDebuggerWithInstanceName (instance_name).get(); + if (dbg != NULL) + { + dbg->GetCommandInterpreter().BroadcastEvent (new_event_sp); + } + } + + return true; +} + +const ConstString +DebuggerInstanceSettings::CreateInstanceName () +{ + static int instance_count = 1; + StreamString sstr; + + sstr.Printf ("debugger_%d", instance_count); + ++instance_count; + + const ConstString ret_val (sstr.GetData()); + + return ret_val; +} + +const ConstString & +DebuggerInstanceSettings::PromptVarName () +{ + static ConstString prompt_var_name ("prompt"); + + return prompt_var_name; +} + +const ConstString & +DebuggerInstanceSettings::ScriptLangVarName () +{ + static ConstString script_lang_var_name ("script-lang"); + + return script_lang_var_name; +} + +//-------------------------------------------------- +// DebuggerSettingsController Variable Tables +//-------------------------------------------------- + + +SettingEntry +Debugger::DebuggerSettingsController::global_settings_table[] = +{ + //{ "var-name", var-type, "default", enum-table, init'd, hidden, "help-text"}, + { "term-width" , eSetVarTypeInt, "80" , NULL, false , false , "The maximum number of columns to use for displaying text." }, + { NULL, eSetVarTypeNone, NULL, NULL, 0, 0, NULL } +}; + + + +SettingEntry +Debugger::DebuggerSettingsController::instance_settings_table[] = +{ + //{ "var-name", var-type , "default", enum-table, init'd, hidden, "help-text"}, + { "script-lang" , eSetVarTypeString, "python", NULL, false, false, "The script language to be used for evaluating user-written scripts." }, + { "prompt" , eSetVarTypeString, "(lldb)", NULL, false, false, "The debugger command line prompt displayed for the user." }, + { NULL, eSetVarTypeNone, NULL, NULL, 0, 0, NULL } +}; diff --git a/lldb/source/Core/UserSettingsController.cpp b/lldb/source/Core/UserSettingsController.cpp new file mode 100644 index 00000000000..554ea76bedd --- /dev/null +++ b/lldb/source/Core/UserSettingsController.cpp @@ -0,0 +1,1857 @@ +//====-- UserSettingsController.cpp ------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include <string.h> +#include <algorithm> + +#include "lldb/Core/UserSettingsController.h" +#include "lldb/Core/Error.h" +#include "lldb/Core/Stream.h" +#include "lldb/Core/StreamString.h" +#include "lldb/Interpreter/CommandInterpreter.h" + +using namespace lldb_private; + +UserSettingsController::UserSettingsController (const char *level_name, + const lldb::UserSettingsControllerSP &parent) : + m_default_settings (), + m_settings (), + m_children (), + m_pending_settings (), + m_live_settings (), + m_children_mutex (Mutex::eMutexTypeNormal), + m_pending_settings_mutex (Mutex::eMutexTypeNormal), + m_live_settings_mutex (Mutex::eMutexTypeNormal) +{ + m_settings.parent = parent; + m_settings.level_name.SetCString (level_name); +} + +UserSettingsController::~UserSettingsController () +{ + m_live_settings.clear(); +} + +void +UserSettingsController::InitializeGlobalVariables () +{ + static bool global_initialized = false; + int num_entries; + const char *prefix = GetLevelName().AsCString(); + + if (! global_initialized) + { + num_entries = m_settings.global_settings.size(); + for (int i = 0; i < num_entries; ++i) + { + SettingEntry &entry = m_settings.global_settings[i]; + if (entry.default_value != NULL) + { + StreamString full_name; + if (prefix[0] != '\0') + full_name.Printf ("%s.%s", prefix, entry.var_name); + else + full_name.Printf ("%s", entry.var_name); + SetVariable (full_name.GetData(), entry.default_value, lldb::eVarSetOperationAssign, false); + } + else if ((entry.var_type == lldb::eSetVarTypeEnum) + && (entry.enum_values != NULL)) + { + StreamString full_name; + if (prefix[0] != '\0') + full_name.Printf ("%s.%s", prefix, entry.var_name); + else + full_name.Printf ("%s", entry.var_name); + SetVariable (full_name.GetData(), entry.enum_values[0].string_value, lldb::eVarSetOperationAssign, + false); + } + } + global_initialized = true; + } +} + +const lldb::UserSettingsControllerSP & +UserSettingsController::GetParent () +{ + return m_settings.parent; +} + +void +UserSettingsController::RegisterChild (const lldb::UserSettingsControllerSP &child) +{ + Mutex::Locker locker (m_children_mutex); + + // Verify child is not already in m_children. + size_t num_children = m_children.size(); + bool found = false; + for (size_t i = 0; i < num_children; ++i) + { + if (m_children[i].get() == child.get()) + found = true; + } + + // Add child to m_children. + if (! found) + m_children.push_back (child); +} + +const ConstString & +UserSettingsController::GetLevelName () +{ + return m_settings.level_name; +} + +size_t +UserSettingsController::GetNumChildren () +{ + return m_children.size(); +} + +const lldb::UserSettingsControllerSP +UserSettingsController::GetChildAtIndex (size_t index) +{ + if (index < m_children.size()) + return m_children[index]; + + lldb::UserSettingsControllerSP dummy_value; + + return dummy_value; +} + +const SettingEntry * +UserSettingsController::GetGlobalEntry (const ConstString &var_name) +{ + + for (int i = 0; i < m_settings.global_settings.size(); ++i) + { + SettingEntry &entry = m_settings.global_settings[i]; + ConstString entry_name (entry.var_name); + if (entry_name == var_name) + return &entry; + } + + return NULL; +} + +const SettingEntry * +UserSettingsController::GetInstanceEntry (const ConstString &const_var_name) +{ + + for (int i = 0; i < m_settings.instance_settings.size(); ++i) + { + SettingEntry &entry = m_settings.instance_settings[i]; + ConstString entry_name (entry.var_name); + if (entry_name == const_var_name) + return &entry; + } + + return NULL; +} + +void +UserSettingsController::BuildParentPrefix (std::string &parent_prefix) +{ + lldb::UserSettingsControllerSP parent = GetParent(); + if (parent.get() != NULL) + { + parent->BuildParentPrefix (parent_prefix); + if (parent_prefix.length() > 0) + parent_prefix.append ("."); + } + parent_prefix.append (GetLevelName().AsCString()); +} + +void +UserSettingsController::RemoveChild (const lldb::UserSettingsControllerSP &child) +{ + Mutex::Locker locker (m_children_mutex); + std::vector<lldb::UserSettingsControllerSP>::iterator pos, end = m_children.end(); + + for (pos = m_children.begin(); pos != end; ++pos) + { + lldb::UserSettingsControllerSP entry = *pos; + if (entry == child) + { + m_children.erase (pos); + break; + } + } +} + +Error +UserSettingsController::SetVariable (const char *full_dot_name, + const char *value, + const lldb::VarSetOperationType op, + const bool override, + const char *index_value) +{ + Error err; + ConstString const_var_name; + const ConstString &default_name = InstanceSettings::GetDefaultName(); + + Args names = UserSettingsController::BreakNameIntoPieces (full_dot_name); + int num_pieces = names.GetArgumentCount(); + + if (num_pieces < 1) + { + err.SetErrorStringWithFormat ("'%s' is not a valid variable name; cannot assign value.\n", full_dot_name); + return err; + } + + ConstString prefix (names.GetArgumentAtIndex (0)); + + if ((prefix == m_settings.level_name) + || (m_settings.level_name.GetLength() == 0)) + { + + if (prefix == m_settings.level_name) + { + names.Shift (); + num_pieces = names.GetArgumentCount(); + } + + if (num_pieces == 0) + { + err.SetErrorString ("No variable name specified; cannot assign value.\n"); + return err; + } + else if (num_pieces == 1) + { + + // Must be one of the class-wide settings. + + const_var_name.SetCString (names.GetArgumentAtIndex (0)); + const SettingEntry *entry = GetGlobalEntry (const_var_name); + if (entry) + { + UserSettingsController::VerifyOperationForType (entry->var_type, op, const_var_name, err); + + if (err.Fail()) + return err; + + if ((value == NULL || value[0] == '\0') + && (op == lldb::eVarSetOperationAssign)) + { + if (entry->var_type != lldb::eSetVarTypeEnum) + value = entry->default_value; + else + value = entry->enum_values[0].string_value; + } + UpdateGlobalVariable (const_var_name, index_value, value, *entry, op, err); + } + else + { + // MIGHT be instance variable, to be for ALL instances. + + entry = GetInstanceEntry (const_var_name); + if (entry == NULL) + { + err.SetErrorStringWithFormat ("Unable to find variable '%s.%s'; cannot assign value.\n", + prefix.AsCString(), const_var_name.AsCString()); + return err; + } + else + { + UserSettingsController::VerifyOperationForType (entry->var_type, op, const_var_name, err); + + if (err.Fail()) + return err; + + if ((value == NULL || value[0] == '\0') + && (op == lldb::eVarSetOperationAssign)) + { + if (entry->var_type != lldb::eSetVarTypeEnum) + value = entry->default_value; + else + value = entry->enum_values[0].string_value; + } + + m_default_settings->UpdateInstanceSettingsVariable (const_var_name, index_value, value, + default_name, *entry, op, err, true); + if (override) + { + OverrideAllInstances (const_var_name, value, op, index_value, err); + + // Update all pending records as well. + std::map<std::string, lldb::InstanceSettingsSP>::iterator pos, end = m_pending_settings.end(); + for (pos = m_pending_settings.begin(); pos != end; end++) + { + const ConstString instance_name (pos->first.c_str()); + lldb::InstanceSettingsSP setting_sp = pos->second; + setting_sp->UpdateInstanceSettingsVariable (const_var_name, index_value, value, + instance_name, *entry, op, err, true); + } + } + } + } + } + else + { + // Either a child's setting or an instance setting. + + if (names.GetArgumentAtIndex(0)[0] == '[') + { + // An instance setting. Supposedly. + + ConstString instance_name (names.GetArgumentAtIndex (0)); + + // First verify that there is only one more name. + + names.Shift(); + + if (names.GetArgumentCount() != 1) + { + err.SetErrorStringWithFormat ("Invalid variable name format '%s'; cannot assign value.\n", + full_dot_name); + return err; + } + + // Next verify that it is a valid instance setting name. + + const_var_name.SetCString (names.GetArgumentAtIndex (0)); + const SettingEntry *entry = GetInstanceEntry (const_var_name); + + if (entry == NULL) + { + err.SetErrorStringWithFormat ("Unknown instance variable '%s'; cannot assign value.\n", + const_var_name.AsCString()); + return err; + } + + UserSettingsController::VerifyOperationForType (entry->var_type, op, const_var_name, err); + + if (err.Fail()) + return err; + + if ((value == NULL || value[0] == '\0') + && (op == lldb::eVarSetOperationAssign)) + { + if (entry->var_type != lldb::eSetVarTypeEnum) + value = entry->default_value; + else + value = entry->enum_values[0].string_value; + } + + // Now look for existing instance with given instance name; if not found, find or create pending + // setting for instance with given name. + + InstanceSettings *current_settings = FindSettingsForInstance (instance_name); + + if (current_settings != NULL) + { + current_settings->UpdateInstanceSettingsVariable (const_var_name, index_value, value, + instance_name, *entry, op, err, false); + + } + else + { + // Instance does not currently exist; make or update a pending setting for it. + lldb::InstanceSettingsSP current_settings_sp = PendingSettingsForInstance (instance_name); + + // Now we have a settings record, update it appropriately. + + current_settings_sp->UpdateInstanceSettingsVariable (const_var_name, index_value, value, + instance_name, *entry, op, err, true); + + { // Scope for mutex. + Mutex::Locker locker (m_pending_settings_mutex); + m_pending_settings[instance_name.AsCString()] = current_settings_sp; + } + + if (override) + { + OverrideAllInstances (const_var_name, value, op, index_value, err); + + // Update all pending records as well. + std::map<std::string, lldb::InstanceSettingsSP>::iterator pos; + std::map<std::string, lldb::InstanceSettingsSP>::iterator end = m_pending_settings.end(); + for (pos = m_pending_settings.begin(); pos != end; end++) + { + const ConstString tmp_inst_name (pos->first.c_str()); + lldb::InstanceSettingsSP setting_sp = pos->second; + setting_sp->UpdateInstanceSettingsVariable (const_var_name, index_value, value, + tmp_inst_name, *entry, op, err, true); + } + } + } + } + else + { + // A child setting. + lldb::UserSettingsControllerSP child; + ConstString child_prefix (names.GetArgumentAtIndex (0)); + int num_children = GetNumChildren(); + bool found = false; + for (int i = 0; i < num_children && !found; ++i) + { + child = GetChildAtIndex (i); + ConstString current_prefix = child->GetLevelName(); + if (current_prefix == child_prefix) + { + found = true; + std::string new_name; + for (int j = 0; j < names.GetArgumentCount(); ++j) + { + if (j > 0) + new_name += '.'; + new_name += names.GetArgumentAtIndex (j); + } + return child->SetVariable (new_name.c_str(), value, op, override, index_value); + } + } + if (!found) + { + err.SetErrorStringWithFormat ("Unable to find variable '%s'; cannot assign value.\n", + full_dot_name); + return err; + } + } + } + } + else + { + err.SetErrorStringWithFormat ("'%s' is not a valid level name; was expecting '%s'. Cannot assign value.\n", + prefix.AsCString(), m_settings.level_name.AsCString()); + } + + return err; +} + +StringList +UserSettingsController::GetVariable (const char *full_dot_name, lldb::SettableVariableType &var_type) +{ + Args names = UserSettingsController::BreakNameIntoPieces (full_dot_name); + ConstString const_var_name; + StringList value; + + int num_pieces = names.GetArgumentCount(); + + ConstString prefix (names.GetArgumentAtIndex (0)); + const_var_name.SetCString (names.GetArgumentAtIndex (num_pieces - 1)); + + const SettingEntry *global_entry = GetGlobalEntry (const_var_name); + const SettingEntry *instance_entry = GetInstanceEntry (const_var_name); + + if ((prefix != m_settings.level_name) + && (m_settings.level_name.GetLength () > 0)) + { + value.AppendString ("Invalid variable name"); + return value; + } + + // prefix name matched; remove it from names. + if (m_settings.level_name.GetLength() > 0) + names.Shift(); + + // Should we pass this off to a child? If there is more than one name piece left, and the next name piece + // matches a child prefix, then yes. + + lldb::UserSettingsControllerSP child; + if (names.GetArgumentCount() > 1) + { + ConstString child_prefix (names.GetArgumentAtIndex (0)); + bool found = false; + for (int i = 0; i < m_children.size() && !found; ++i) + { + if (child_prefix == m_children[i]->GetLevelName()) + { + found = true; + child = m_children[i]; + std::string new_name; + for (int j = 0; j < names.GetArgumentCount(); ++j) + { + if (j > 0) + new_name += '.'; + new_name += names.GetArgumentAtIndex (j); + } + return child->GetVariable (new_name.c_str(), var_type); + } + } + + if (!found) + { + // Cannot be handled by a child, because name did not match any child prefixes. + // Cannot be a class-wide variable because there are too many name pieces. + + if (instance_entry != NULL) + { + var_type = instance_entry->var_type; + ConstString instance_name (names.GetArgumentAtIndex (0)); + InstanceSettings *current_settings = FindSettingsForInstance (instance_name); + + if (current_settings != NULL) + { + current_settings->GetInstanceSettingsValue (*instance_entry, const_var_name, value); + } + else + { + // Look for instance name setting in pending settings. + + std::string inst_name_str = instance_name.AsCString(); + std::map<std::string, lldb::InstanceSettingsSP>::iterator pos; + + pos = m_pending_settings.find (inst_name_str); + if (pos != m_pending_settings.end()) + { + lldb::InstanceSettingsSP settings_sp = pos->second; + settings_sp->GetInstanceSettingsValue (*instance_entry, const_var_name, value); + } + else + { + // No valid instance name; assume they want the default settings. + m_default_settings->GetInstanceSettingsValue (*instance_entry, const_var_name, value); + } + } + } + else + value.AppendString ("Invalid variable name"); + } + } + else + { + // Only one name left. It must belong to the current level, or be an error. + if ((global_entry == NULL) + && (instance_entry == NULL)) + { + value.AppendString ("Invalid variable name"); + } + else if (global_entry) + { + var_type = global_entry->var_type; + GetGlobalSettingsValue (const_var_name, value); + } + else if (instance_entry) + { + var_type = instance_entry->var_type; + m_default_settings->GetInstanceSettingsValue (*instance_entry, const_var_name, value); + } + } + + return value; +} + +void +UserSettingsController::RemovePendingSettings (const ConstString &instance_name) +{ + std::map<std::string, lldb::InstanceSettingsSP>::iterator pos; + std::string instance_name_str (instance_name.AsCString()); + Mutex::Locker locker (m_pending_settings_mutex); + + m_pending_settings.erase (instance_name_str); +} + +const lldb::InstanceSettingsSP & +UserSettingsController::FindPendingSettings (const ConstString &instance_name) +{ + std::map<std::string, lldb::InstanceSettingsSP>::iterator pos; + std::string instance_name_str (instance_name.AsCString()); + + { // Scope for mutex. + Mutex::Locker locker (m_pending_settings_mutex); + + pos = m_pending_settings.find (instance_name_str); + if (pos != m_pending_settings.end()) + return pos->second; + } + + return m_default_settings; +} + +void +UserSettingsController::CreateDefaultInstanceSettings () +{ + Error err; + const ConstString &default_name = InstanceSettings::GetDefaultName(); + for (int i = 0; i < m_settings.instance_settings.size(); ++i) + { + SettingEntry &entry = m_settings.instance_settings[i]; + ConstString var_name (entry.var_name); + const char *value = entry.default_value; + + if (entry.var_type == lldb::eSetVarTypeEnum) + value = entry.enum_values[0].string_value; + + m_default_settings->UpdateInstanceSettingsVariable (var_name, NULL, value, default_name, entry, + lldb::eVarSetOperationAssign, err, true); + } +} + +void +UserSettingsController::CopyDefaultSettings (const lldb::InstanceSettingsSP &actual_settings, + const ConstString &instance_name, + bool pending) +{ + Error err; + for (int i = 0; i < m_settings.instance_settings.size(); ++i) + { + SettingEntry &entry = m_settings.instance_settings[i]; + ConstString var_name (entry.var_name); + StringList value; + m_default_settings->GetInstanceSettingsValue (entry, var_name, value); + + std::string value_str; + if (value.GetSize() == 1) + value_str.append (value.GetStringAtIndex (0)); + else if (value.GetSize() > 1) + { + for (int j = 0; j < value.GetSize(); ++j) + { + if (j > 0) + value_str.append (" "); + value_str.append (value.GetStringAtIndex (j)); + } + } + + actual_settings->UpdateInstanceSettingsVariable (var_name, NULL, value_str.c_str(), instance_name, entry, + lldb::eVarSetOperationAssign, err, pending); + + } +} + +lldb::InstanceSettingsSP +UserSettingsController::PendingSettingsForInstance (const ConstString &instance_name) +{ + std::string name_str (instance_name.AsCString()); + std::map<std::string, lldb::InstanceSettingsSP>::iterator pos; + Mutex::Locker locker (m_pending_settings_mutex); + + pos = m_pending_settings.find (name_str); + if (pos != m_pending_settings.end()) + { + lldb::InstanceSettingsSP settings_sp = pos->second; + return settings_sp; + } + else + { + lldb::InstanceSettingsSP default_settings_sp = + m_pending_settings[InstanceSettings::GetDefaultName().AsCString()]; + lldb::InstanceSettingsSP new_settings_sp = CreateNewInstanceSettings (); + CopyDefaultSettings (new_settings_sp, instance_name, true); + m_pending_settings[name_str] = new_settings_sp; + return new_settings_sp; + } + + // Should never reach this line. + + lldb::InstanceSettingsSP dummy; + + return dummy; +} + +void +UserSettingsController::GetAllDefaultSettingValues (StreamString &result_stream) +{ + std::string parent_prefix; + BuildParentPrefix (parent_prefix); + const char *prefix = parent_prefix.c_str(); + + for (int i = 0; i < m_settings.instance_settings.size(); ++i) + { + SettingEntry &entry = m_settings.instance_settings[i]; + ConstString var_name (entry.var_name); + StringList tmp_value; + m_default_settings->GetInstanceSettingsValue (entry, var_name, tmp_value); + + StreamString value_string; + + if (tmp_value.GetSize() == 1) + value_string.Printf ("%s", tmp_value.GetStringAtIndex (0)); + else + { + for (int j = 0; j < tmp_value.GetSize(); ++j) + value_string.Printf ("%s ", tmp_value.GetStringAtIndex (j)); + } + + if (! parent_prefix.empty()) // May need to test size() > 0 + result_stream.Printf ("%s.[DEFAULT].%s (%s) = '%s'\n", prefix, var_name.AsCString(), + UserSettingsController::GetTypeString (entry.var_type), value_string.GetData()); + else + result_stream.Printf ("[DEFAULT].%s (%s) = '%s'\n", var_name.AsCString(), + UserSettingsController::GetTypeString (entry.var_type), value_string.GetData()); + } +} + +void +UserSettingsController::GetAllPendingSettingValues (StreamString &result_stream) +{ + //StreamString description; + std::map<std::string, lldb::InstanceSettingsSP>::iterator pos; + + std::string parent_prefix; + BuildParentPrefix (parent_prefix); + const char *prefix = parent_prefix.c_str(); + + for (pos = m_pending_settings.begin(); pos != m_pending_settings.end(); ++pos) + { + std::string tmp_name = pos->first; + lldb::InstanceSettingsSP settings_sp = pos->second; + + const ConstString instance_name (tmp_name.c_str()); + + for (int i = 0; i < m_settings.instance_settings.size(); ++i) + { + SettingEntry &entry = m_settings.instance_settings[i]; + ConstString var_name (entry.var_name); + StringList tmp_value; + settings_sp->GetInstanceSettingsValue (entry, var_name, tmp_value); + + StreamString value_str; + + if (tmp_value.GetSize() == 0) + break; + if (tmp_value.GetSize() == 1) + value_str.Printf ("%s", tmp_value.GetStringAtIndex (0)); + else + { + for (int j = 0; j < tmp_value.GetSize(); ++j) + value_str.Printf ("%s ", tmp_value.GetStringAtIndex (j)); + } + + if (parent_prefix.length() > 0) + { + result_stream.Printf ("%s.%s.%s (%s) = '%s' [pending]\n", prefix, instance_name.AsCString(), + var_name.AsCString(), UserSettingsController::GetTypeString (entry.var_type), + value_str.GetData()); + } + else + { + result_stream.Printf ("%s (%s) = '%s' [pending]\n", var_name.AsCString(), + UserSettingsController::GetTypeString (entry.var_type), + value_str.GetData()); + } + } + } +} + +InstanceSettings * +UserSettingsController::FindSettingsForInstance (const ConstString &instance_name) +{ + std::string instance_name_str (instance_name.AsCString()); + std::map<std::string, InstanceSettings *>::iterator pos; + + pos = m_live_settings.find (instance_name_str); + if (pos != m_live_settings.end ()) + { + InstanceSettings *settings = pos->second; + return settings; + } + + return NULL; +} + +void +UserSettingsController::GetAllInstanceVariableValues (CommandInterpreter &interpreter, + StreamString &result_stream) +{ + std::map<std::string, InstanceSettings *>::iterator pos; + std::string parent_prefix; + BuildParentPrefix (parent_prefix); + const char *prefix = parent_prefix.c_str(); + StreamString description; + + for (pos = m_live_settings.begin(); pos != m_live_settings.end(); ++pos) + { + std::string instance_name = pos->first; + InstanceSettings *settings = pos->second; + + for (int i = 0; i < m_settings.instance_settings.size(); ++i) + { + SettingEntry &entry = m_settings.instance_settings[i]; + const ConstString var_name (entry.var_name); + StringList tmp_value; + settings->GetInstanceSettingsValue (entry, var_name, tmp_value); + StreamString tmp_value_str; + + if (tmp_value.GetSize() == 0) + break; + + if (tmp_value.GetSize() == 1) + tmp_value_str.Printf ("%s", tmp_value.GetStringAtIndex (0)); + else + { + for (int j = 0; j < tmp_value.GetSize(); ++j) + tmp_value_str.Printf ("%s ",tmp_value.GetStringAtIndex (j)); + } + + description.Clear(); + if (parent_prefix.length() > 0) + { + description.Printf ("%s.%s.%s (%s) = '%s'", prefix, instance_name.c_str(), var_name.AsCString(), + UserSettingsController::GetTypeString (entry.var_type), + tmp_value_str.GetData()); + } + else + { + description.Printf ("%s (%s) = '%s'", var_name.AsCString(), + UserSettingsController::GetTypeString (entry.var_type), tmp_value_str.GetData()); + } + result_stream.Printf ("%s\n", description.GetData()); + } + } +} + +void +UserSettingsController::OverrideAllInstances (const ConstString &var_name, + const char *value, + lldb::VarSetOperationType op, + const char *index_value, + Error &err) +{ + std::map<std::string, InstanceSettings *>::iterator pos; + StreamString description; + + for (pos = m_live_settings.begin(); pos != m_live_settings.end(); ++pos) + { + InstanceSettings *settings = pos->second; + StreamString tmp_name; + tmp_name.Printf ("[%s]", settings->GetInstanceName().AsCString()); + const ConstString instance_name (tmp_name.GetData()); + const SettingEntry *entry = GetInstanceEntry (var_name); + settings->UpdateInstanceSettingsVariable (var_name, index_value, value, instance_name, *entry, op, err, false); + + } +} + +void +UserSettingsController::RegisterInstanceSettings (InstanceSettings *instance_settings) +{ + Mutex::Locker locker (m_live_settings_mutex); + StreamString tmp_name; + tmp_name.Printf ("[%s]", instance_settings->GetInstanceName().AsCString()); + const ConstString instance_name (tmp_name.GetData()); + std::string instance_name_str (instance_name.AsCString()); + if (instance_name_str.compare (InstanceSettings::GetDefaultName().AsCString()) != 0) + m_live_settings[instance_name_str] = instance_settings; +} + +void +UserSettingsController::UnregisterInstanceSettings (InstanceSettings *instance) +{ + Mutex::Locker locker (m_live_settings_mutex); + StreamString tmp_name; + tmp_name.Printf ("[%s]", instance->GetInstanceName().AsCString()); + std::string instance_name (tmp_name.GetData()); + + std::map <std::string, InstanceSettings *>::iterator pos; + + pos = m_live_settings.find (instance_name); + if (pos != m_live_settings.end()) + m_live_settings.erase (pos); +} + +void +UserSettingsController::CreateSettingsVector (const SettingEntry *table, + bool global) +{ + int i = 0; + while (table[i].var_name != NULL) + { + const SettingEntry &table_entry = table[i]; + ConstString const_var_name (table_entry.var_name); + SettingEntry new_entry; + + new_entry = table_entry; + new_entry.var_name = const_var_name.AsCString(); + + if (global) + m_settings.global_settings.push_back (new_entry); + else + m_settings.instance_settings.push_back (new_entry); + + ++i; + } +} + +//---------------------------------------------------------------------- +// UserSettingsController static methods +//---------------------------------------------------------------------- + +int +FindMaxNameLength (std::vector<SettingEntry> table) +{ + int max_length = 1; + + for (int i = 0; i < table.size(); ++i) + { + int len = strlen (table[i].var_name); + if (len > max_length) + max_length = len; + } + + return max_length; +} + +const char * +UserSettingsController::GetTypeString (lldb::SettableVariableType var_type) +{ + switch (var_type) + { + case lldb::eSetVarTypeInt: + return "int"; + case lldb::eSetVarTypeBool: + return "boolean"; + case lldb::eSetVarTypeString: + return "string"; + case lldb::eSetVarTypeArray: + return "array"; + case lldb::eSetVarTypeDictionary: + return "dictionary"; + case lldb::eSetVarTypeEnum: + return "enum"; + case lldb::eSetVarTypeNone: + return "no type"; + } + + return ""; +} + +void +UserSettingsController::PrintEnumValues (const lldb::OptionEnumValueElement *enum_values, Stream &str) +{ + int i = 0; + while (enum_values[i].string_value != NULL) + { + str.Printf ("%s ", enum_values[i].string_value); + ++i; + } + +} + +void +UserSettingsController::FindAllSettingsDescriptions (CommandInterpreter &interpreter, + lldb::UserSettingsControllerSP root, + std::string ¤t_prefix, + StreamString &result_stream, + Error &err) +{ + // Write out current prefix line. + StreamString prefix_line; + StreamString description; + uint32_t max_len; + int num_entries = root->m_settings.global_settings.size(); + + max_len = FindMaxNameLength (root->m_settings.global_settings); + + if (! current_prefix.empty()) + result_stream.Printf ("\n'%s' variables:\n\n", current_prefix.c_str()); + else + result_stream.Printf ("\nTop level variables:\n\n"); + + if (num_entries > 0) + { + // Write out all "global" variables. + for (int i = 0; i < num_entries; ++i) + { + SettingEntry entry = root->m_settings.global_settings[i]; + description.Clear(); + if (entry.var_type == lldb::eSetVarTypeEnum) + { + StreamString enum_values_str; + UserSettingsController::PrintEnumValues (entry.enum_values, enum_values_str); + description.Printf ("[static, enum] %s. Valid values: {%s} (default: '%s')", entry.description, + enum_values_str.GetData(), entry.enum_values[0].string_value); + } + else if (entry.default_value != NULL) + description.Printf ("[static, %s] %s (default: '%s')", GetTypeString (entry.var_type), + entry.description, entry.default_value); + + else + description.Printf ("[static, %s] %s (default: '')", GetTypeString (entry.var_type), + entry.description); + interpreter.OutputFormattedHelpText (result_stream, entry.var_name, "--", description.GetData(), + max_len); + } + } + + num_entries = root->m_settings.instance_settings.size(); + max_len = FindMaxNameLength (root->m_settings.instance_settings); + + if (num_entries > 0) + { + // Write out all instance variables. + for (int i = 0; i < num_entries; ++i) + { + SettingEntry entry = root->m_settings.instance_settings[i]; + description.Clear(); + if (entry.var_type == lldb::eSetVarTypeEnum) + { + StreamString enum_values_str; + UserSettingsController::PrintEnumValues (entry.enum_values, enum_values_str); + description.Printf ("[instance, enum] %s. Valid values: {%s} (default: '%s')", entry.description, + enum_values_str.GetData(), entry.enum_values[0].string_value); + } + else if (entry.default_value != NULL) + description.Printf ("[instance, %s] %s (default: '%s')", GetTypeString (entry.var_type), + entry.description, entry.default_value); + else + description.Printf ("[instance, %s] %s (default: '')", GetTypeString (entry.var_type), + entry.description); + interpreter.OutputFormattedHelpText (result_stream, entry.var_name, "--", description.GetData(), + max_len); + } + + } + + // Now, recurse across all children. + int num_children = root->GetNumChildren(); + for (int i = 0; i < num_children; ++i) + { + lldb::UserSettingsControllerSP child = root->GetChildAtIndex (i); + + if (child) + { + ConstString child_prefix = child->GetLevelName(); + StreamString new_prefix; + if (! current_prefix.empty() ) // May need to see if size() > 0 + new_prefix.Printf ("%s.%s", current_prefix.c_str(), child_prefix.AsCString()); + else + new_prefix.Printf ("%s", child_prefix.AsCString()); + std::string new_prefix_str = new_prefix.GetData(); + UserSettingsController::FindAllSettingsDescriptions (interpreter, child, new_prefix_str, result_stream, + err); + } + } +} + +void +UserSettingsController::GetAllVariableValues (CommandInterpreter &interpreter, + lldb::UserSettingsControllerSP root, + std::string ¤t_prefix, + StreamString &result_stream, + Error &err) +{ + StreamString description; + int num_entries = root->m_settings.global_settings.size(); + lldb::SettableVariableType var_type; + + + for (int i = 0; i < num_entries; ++i) + { + StreamString full_var_name; + SettingEntry entry = root->m_settings.global_settings[i]; + if (! current_prefix.empty()) // May need to see if size() > 0 + full_var_name.Printf ("%s.%s", current_prefix.c_str(), entry.var_name); + else + full_var_name.Printf ("%s", entry.var_name); + StringList value = root->GetVariable (full_var_name.GetData(), var_type); + description.Clear(); + if (value.GetSize() == 1) + description.Printf ("%s (%s) = %s", full_var_name.GetData(), GetTypeString (entry.var_type), + value.GetStringAtIndex (0)); + else + { + description.Printf ("%s (%s) = ", full_var_name.GetData(), GetTypeString (entry.var_type)); + for (int j = 0; j < value.GetSize(); ++j) + description.Printf ("%s ", value.GetStringAtIndex (j)); + } + + result_stream.Printf ("%s\n", description.GetData()); + } + + root->GetAllInstanceVariableValues (interpreter, result_stream); + root->GetAllPendingSettingValues (result_stream); + root->GetAllDefaultSettingValues (result_stream); + + + // Now, recurse across all children. + int num_children = root->GetNumChildren(); + for (int i = 0; i < num_children; ++i) + { + lldb::UserSettingsControllerSP child = root->GetChildAtIndex (i); + + if (child) + { + ConstString child_prefix = child->GetLevelName(); + StreamString new_prefix; + if (! current_prefix.empty()) // May need to see if size() > 0 + new_prefix.Printf ("%s.%s", current_prefix.c_str(), child_prefix.AsCString()); + else + new_prefix.Printf ("%s", child_prefix.AsCString()); + std::string new_prefix_str = new_prefix.GetData(); + UserSettingsController::GetAllVariableValues (interpreter, child, new_prefix_str, result_stream, + err); + } + } + +} + +Args +UserSettingsController::BreakNameIntoPieces (const char *full_dot_name) +{ + Args return_value; + std::string name_string (full_dot_name); + bool done = false; + + std::string piece; + std::string remainder (full_dot_name); + + while (!done) + { + size_t idx = remainder.find_first_of ('.'); + piece = remainder.substr (0, idx); + return_value.AppendArgument (piece.c_str()); + if (idx != std::string::npos) + remainder = remainder.substr (idx+1); + else + done = true; + } + + return return_value; +} + +bool +UserSettingsController::IsLiveInstance (const std::string &instance_name) +{ + std::map<std::string, InstanceSettings *>::iterator pos; + + pos = m_live_settings.find (instance_name); + if (pos != m_live_settings.end()) + return true; + + return false; +} + +int +UserSettingsController::CompleteSettingsValue (lldb::UserSettingsControllerSP root_settings, + const char *full_dot_name, + const char *partial_value, + bool &word_complete, + StringList &matches) +{ + Args names = UserSettingsController::BreakNameIntoPieces (full_dot_name); + int num_pieces = names.GetArgumentCount(); + word_complete = true; + + ConstString root_level = root_settings->GetLevelName(); + int num_extra_levels = num_pieces - 2; + if ((num_extra_levels > 0) + && root_level.GetLength() > 0) + { + ConstString current_level (names.GetArgumentAtIndex (0)); + if (current_level == root_level) + { + names.Shift(); + --num_extra_levels; + } + else + return 0; + } + + for (int i = 0; i < num_extra_levels; ++i) + { + ConstString child_level (names.GetArgumentAtIndex (0)); + bool found = false; + int num_children = root_settings->GetNumChildren(); + for (int j = 0; j < num_children && !found; ++j) + { + if (root_settings->GetChildAtIndex (j)->GetLevelName() == child_level) + { + found = true; + root_settings = root_settings->GetChildAtIndex (j); + names.Shift(); + } + } + if (!found) + return 0; + } + + if (names.GetArgumentCount() != 2) + return 0; + + std::string next_name (names.GetArgumentAtIndex (0)); + int len = next_name.length(); + names.Shift(); + + if ((next_name[0] == '[') && (next_name[len-1] == ']')) + { + // 'next_name' is instance name. Instance names are irrelevent here. + } + else + { + // 'next_name' is child name. + bool found = false; + int num_children = root_settings->GetNumChildren(); + ConstString child_level (next_name.c_str()); + for (int j = 0; j < num_children && !found; ++j) + { + if (root_settings->GetChildAtIndex (j)->GetLevelName() == child_level) + { + found = true; + root_settings = root_settings->GetChildAtIndex (j); + } + } + if (!found) + return 0; + } + + ConstString var_name (names.GetArgumentAtIndex(0)); + const SettingEntry *entry = root_settings->GetGlobalEntry (var_name); + if (entry == NULL) + entry = root_settings->GetInstanceEntry (var_name); + + if (entry == NULL) + return 0; + + if (entry->var_type == lldb::eSetVarTypeBool) + return UserSettingsController::BooleanMatches (partial_value, word_complete, matches); + else if (entry->var_type == lldb::eSetVarTypeEnum) + return UserSettingsController::EnumMatches (partial_value, entry->enum_values, word_complete, matches); + else + return 0; +} + +int +UserSettingsController::BooleanMatches (const char *partial_value, + bool &word_complete, + StringList &matches) +{ + static const std::string true_string ("true"); + static const std::string false_string ("false"); + + if (partial_value == NULL) + { + matches.AppendString ("true"); + matches.AppendString ("false"); + } + else + { + int partial_len = strlen (partial_value); + + if ((partial_len <= true_string.length()) + && (true_string.find (partial_value) == 0)) + matches.AppendString ("true"); + else if ((partial_len <= false_string.length()) + && (false_string.find (partial_value) == 0)) + matches.AppendString ("false"); + } + + word_complete = false; + if (matches.GetSize() == 1) + word_complete = true; + + return matches.GetSize(); +} + +int +UserSettingsController::EnumMatches (const char *partial_value, + lldb::OptionEnumValueElement *enum_values, + bool &word_complete, + StringList &matches) +{ + int len = (partial_value != NULL) ? strlen (partial_value) : 0; + + int i = 0; + while (enum_values[i].string_value != NULL) + { + if (len == 0) + matches.AppendString (enum_values[i].string_value); + else + { + std::string tmp_value (enum_values[i].string_value); + if ((len <= tmp_value.length()) + && tmp_value.find (partial_value) == 0) + matches.AppendString (enum_values[i].string_value); + } + ++i; + } + + word_complete = false; + if (matches.GetSize() == 1) + word_complete = true; + + return matches.GetSize(); +} + +int +UserSettingsController::CompleteSettingsNames (lldb::UserSettingsControllerSP root_settings, + Args &partial_setting_name_pieces, + bool &word_complete, + StringList &matches) +{ + int num_matches = 0; + int num_name_pieces = partial_setting_name_pieces.GetArgumentCount(); + + if (num_name_pieces > 1) + { + // There are at least two pieces, perhaps with multiple level names preceding them. + // First traverse all the extra levels, until we have exactly two pieces left. + + int num_extra_levels = num_name_pieces - 2; + + // Deal with current level first. + + ConstString root_level = root_settings->GetLevelName(); + if ((num_extra_levels > 0) + && (root_level.GetLength() > 0)) + { + ConstString current_level (partial_setting_name_pieces.GetArgumentAtIndex (0)); + if (current_level == root_level) + { + partial_setting_name_pieces.Shift(); + --num_extra_levels; + } + else + return 0; // The current level did not match the name pieces; something is wrong, so return immediately + + } + + for (int i = 0; i < num_extra_levels; ++i) + { + ConstString child_level (partial_setting_name_pieces.GetArgumentAtIndex (0)); + bool found = false; + int num_children = root_settings->GetNumChildren(); + for (int j = 0; j < num_children && !found; ++j) + { + if (root_settings->GetChildAtIndex (j)->GetLevelName() == child_level) + { + found = true; + root_settings = root_settings->GetChildAtIndex (j); + partial_setting_name_pieces.Shift(); + } + } + if (! found) + { + return 0; // Unable to find a matching child level name; something is wrong, so return immediately. + } + } + + // Now there should be exactly two name pieces left. If not there is an error, so return immediately + + if (partial_setting_name_pieces.GetArgumentCount() != 2) + return 0; + + std::string next_name (partial_setting_name_pieces.GetArgumentAtIndex (0)); + int len = next_name.length(); + partial_setting_name_pieces.Shift(); + + if ((next_name[0] == '[') && (next_name[len-1] == ']')) + { + // 'next_name' is an instance name. The last name piece must be a non-empty partial match against an + // instance_name, assuming 'next_name' is valid. + + if (root_settings->IsLiveInstance (next_name)) + { + std::string complete_prefix; + root_settings->BuildParentPrefix (complete_prefix); + + num_matches = root_settings->InstanceVariableMatches(partial_setting_name_pieces.GetArgumentAtIndex(0), + complete_prefix, + next_name.c_str(), + matches); + word_complete = true; + if (num_matches > 1) + word_complete = false; + + return num_matches; + } + else + return 0; // Invalid instance_name + } + else + { + // 'next_name' must be a child name. Find the correct child and pass the remaining piece to be resolved. + bool found = false; + int num_children = root_settings->GetNumChildren(); + ConstString child_level (next_name.c_str()); + for (int i = 0; i < num_children; ++i) + { + if (root_settings->GetChildAtIndex (i)->GetLevelName() == child_level) + { + found = true; + return UserSettingsController::CompleteSettingsNames (root_settings->GetChildAtIndex (i), + partial_setting_name_pieces, + word_complete, matches); + } + } + if (!found) + return 0; + } + } + else if (num_name_pieces == 1) + { + std::string complete_prefix; + root_settings->BuildParentPrefix (complete_prefix); + + word_complete = true; + std::string name (partial_setting_name_pieces.GetArgumentAtIndex (0)); + + if (name[0] == '[') + { + // It's a partial instance name. + + num_matches = root_settings->LiveInstanceMatches (name.c_str(), complete_prefix, word_complete, matches); + } + else + { + // It could be anything *except* an instance name... + + num_matches = root_settings->GlobalVariableMatches (name.c_str(), complete_prefix, matches); + num_matches += root_settings->InstanceVariableMatches (name.c_str(), complete_prefix, NULL, matches); + num_matches += root_settings->ChildMatches (name.c_str(), complete_prefix, word_complete, matches); + } + + if (num_matches > 1) + word_complete = false; + + return num_matches; + } + else + { + // We have a user settings controller with a blank partial string. Return everything possible at this level. + + std::string complete_prefix; + root_settings->BuildParentPrefix (complete_prefix); + num_matches = root_settings->GlobalVariableMatches (NULL, complete_prefix, matches); + num_matches += root_settings->InstanceVariableMatches (NULL, complete_prefix, NULL, matches); + num_matches += root_settings->LiveInstanceMatches (NULL, complete_prefix, word_complete, matches); + num_matches += root_settings->ChildMatches (NULL, complete_prefix, word_complete, matches); + word_complete = false; + return num_matches; + } + + return num_matches; +} + +int +UserSettingsController::GlobalVariableMatches (const char *partial_name, + const std::string &complete_prefix, + StringList &matches) +{ + int partial_len = (partial_name != NULL) ? strlen (partial_name) : 0; + int num_matches = 0; + + for (size_t i = 0; i < m_settings.global_settings.size(); ++i) + { + SettingEntry &entry = m_settings.global_settings[i]; + std::string var_name (entry.var_name); + if ((partial_len == 0) + || ((partial_len <= var_name.length()) + && (var_name.find (partial_name) == 0))) + { + StreamString match_name; + if (complete_prefix.length() > 0) + { + match_name.Printf ("%s.%s", complete_prefix.c_str(), var_name.c_str()); + matches.AppendString (match_name.GetData()); + } + else + matches.AppendString (var_name.c_str()); + ++num_matches; + } + } + return num_matches; +} + +int +UserSettingsController::InstanceVariableMatches (const char *partial_name, + const std::string &complete_prefix, + const char *instance_name, + StringList &matches) +{ + int partial_len = (partial_name != NULL) ? strlen (partial_name) : 0; + int num_matches = 0; + + for (size_t i = 0; i < m_settings.instance_settings.size(); ++i) + { + SettingEntry &entry = m_settings.instance_settings[i]; + std::string var_name (entry.var_name); + if ((partial_len == 0) + || ((partial_len <= var_name.length()) + && (var_name.find (partial_name) == 0))) + { + StreamString match_name; + if (complete_prefix.length() > 0) + { + if (instance_name != NULL) + match_name.Printf ("%s.%s.%s", complete_prefix.c_str(), instance_name, var_name.c_str()); + else + match_name.Printf ("%s.%s", complete_prefix.c_str(), var_name.c_str()); + + matches.AppendString (match_name.GetData()); + } + else + { + if (instance_name != NULL) + { + match_name.Printf ("%s.%s", instance_name, var_name.c_str()); + matches.AppendString (match_name.GetData()); + } + else + matches.AppendString (var_name.c_str()); + } + ++num_matches; + } + } + return num_matches; +} + +int +UserSettingsController::LiveInstanceMatches (const char *partial_name, + const std::string &complete_prefix, + bool &word_complete, + StringList &matches) +{ + int partial_len = (partial_name != NULL) ? strlen (partial_name) : 0; + int num_matches = 0; + + std::map<std::string, InstanceSettings*>::iterator pos; + for (pos = m_live_settings.begin(); pos != m_live_settings.end(); ++pos) + { + std::string instance_name = pos->first; + if ((partial_len == 0) + || ((partial_len <= instance_name.length()) + && (instance_name.find (partial_name) == 0))) + { + StreamString match_name; + if (complete_prefix.length() > 0) + match_name.Printf ("%s.%s.", complete_prefix.c_str(), instance_name.c_str()); + else + match_name.Printf ("%s.", instance_name.c_str()); + matches.AppendString (match_name.GetData()); + ++num_matches; + } + } + + if (num_matches > 0) + word_complete = false; + + return num_matches; +} + +int +UserSettingsController::ChildMatches (const char *partial_name, + const std::string &complete_prefix, + bool &word_complete, + StringList &matches) +{ + int partial_len = (partial_name != NULL) ? strlen (partial_name) : 0; + int num_children = GetNumChildren(); + int num_matches = 0; + for (int i = 0; i < num_children; ++i) + { + std::string child_name (GetChildAtIndex(i)->GetLevelName().AsCString()); + StreamString match_name; + if ((partial_len == 0) + || ((partial_len <= child_name.length()) + && (child_name.find (partial_name) == 0))) + { + if (complete_prefix.length() > 0) + match_name.Printf ("%s.%s.", complete_prefix.c_str(), child_name.c_str()); + else + match_name.Printf ("%s.", child_name.c_str()); + matches.AppendString (match_name.GetData()); + ++num_matches; + } + } + + if (num_matches > 0) + word_complete = false; + + return num_matches; +} + +void +UserSettingsController::VerifyOperationForType (lldb::SettableVariableType var_type, + lldb::VarSetOperationType op, + const ConstString &var_name, + Error &err) +{ + if (op == lldb::eVarSetOperationAssign) + return; + + + if (op == lldb::eVarSetOperationInvalid) + { + err.SetErrorString ("Invalid 'settings ' subcommand operation.\n"); + return; + } + + switch (op) + { + case lldb::eVarSetOperationInsertBefore: + case lldb::eVarSetOperationInsertAfter: + if (var_type != lldb::eSetVarTypeArray) + err.SetErrorString ("Invalid operation: This operation can only be performed on array variables.\n"); + break; + case lldb::eVarSetOperationReplace: + case lldb::eVarSetOperationRemove: + if ((var_type != lldb::eSetVarTypeArray) + && (var_type != lldb::eSetVarTypeDictionary)) + err.SetErrorString ("Invalid operation: This operation can only be performed on array or dictionary" + " variables.\n"); + break; + case lldb::eVarSetOperationAppend: + case lldb::eVarSetOperationClear: + if ((var_type != lldb::eSetVarTypeArray) + && (var_type != lldb::eSetVarTypeDictionary) + && (var_type != lldb::eSetVarTypeString)) + err.SetErrorString ("Invalid operation: This operation can only be performed on array, dictionary " + "or string variables.\n"); + break; + default: + break; + } + + return; +} + +void +UserSettingsController::UpdateStringVariable (lldb::VarSetOperationType op, + std::string &string_var, + const char *new_value, + Error &err) +{ + if (op == lldb::eVarSetOperationAssign) + string_var = new_value; + else if (op == lldb::eVarSetOperationAppend) + string_var.append (new_value); + else if (op == lldb::eVarSetOperationClear) + string_var.clear(); + else + err.SetErrorString ("Unrecognized operation. Cannot update value.\n"); +} + +void +UserSettingsController::UpdateBooleanVariable (lldb::VarSetOperationType op, + bool &bool_var, + const char *new_value, + Error &err) +{ + if (op != lldb::eVarSetOperationAssign) + err.SetErrorString ("Invalid operation for Boolean variable. Cannot update value.\n"); + + + if ((new_value == NULL) + || (new_value[0] == '\0')) + err.SetErrorString ("Invalid value. Cannot perform update.\n"); + + std::string bool_val_str (new_value); + + std::transform (bool_val_str.begin(), bool_val_str.end(), bool_val_str.begin(), ::tolower); + + if (bool_val_str == "true") + bool_var = true; + else if (bool_val_str == "false") + bool_var = false; +} + +void +UserSettingsController::UpdateStringArrayVariable (lldb::VarSetOperationType op, + const char *index_value, + Args &array_var, + const char *new_value, + Error &err) +{ + int index = -1; + bool valid_index = true; + + if (index_value != NULL) + { + for (int i = 0; i < strlen(index_value); ++i) + if (!isdigit (index_value[i])) + { + valid_index = false; + err.SetErrorStringWithFormat ("'%s' is not a valid integer index. Cannot update array value.\n", + index_value); + } + + if (valid_index) + index = atoi (index_value); + + if (index < 0 + || index >= array_var.GetArgumentCount()) + { + valid_index = false; + err.SetErrorStringWithFormat ("%d is outside the bounds of the specified array variable. " + "Cannot update array value.\n", index); + } + } + + switch (op) + { + case lldb::eVarSetOperationAssign: + array_var.SetCommandString (new_value); + break; + case lldb::eVarSetOperationReplace: + { + if (valid_index) + array_var.ReplaceArgumentAtIndex (index, new_value); + break; + } + case lldb::eVarSetOperationInsertBefore: + case lldb::eVarSetOperationInsertAfter: + { + if (valid_index) + { + Args new_array (new_value); + if (op == lldb::eVarSetOperationInsertAfter) + ++index; + for (int i = 0; i < new_array.GetArgumentCount(); ++i) + array_var.InsertArgumentAtIndex (index, new_array.GetArgumentAtIndex (i)); + } + break; + } + case lldb::eVarSetOperationRemove: + { + if (valid_index) + array_var.DeleteArgumentAtIndex (index); + break; + } + case lldb::eVarSetOperationAppend: + { + Args new_array (new_value); + array_var.AppendArguments (new_array); + break; + } + case lldb::eVarSetOperationClear: + array_var.Clear(); + break; + default: + err.SetErrorString ("Unrecognized operation. Cannot update value.\n"); + break; + } +} + +void +UserSettingsController::UpdateDictionaryVariable (lldb::VarSetOperationType op, + const char *index_value, + std::map<std::string, std::string> &dictionary, + const char *new_value, + Error &err) +{ + switch (op) + { + case lldb::eVarSetOperationReplace: + if (index_value != NULL) + { + std::string key (index_value); + std::map<std::string, std::string>::iterator pos; + + pos = dictionary.find (key); + if (pos != dictionary.end()) + dictionary[key] = new_value; + else + err.SetErrorStringWithFormat ("'%s' is not an existing key; cannot replace value.\n", index_value); + } + else + err.SetErrorString ("'settings replace' requires a key for dictionary variables. No key supplied.\n"); + break; + case lldb::eVarSetOperationRemove: + if (index_value != NULL) + { + std::string key (index_value); + dictionary.erase (key); + } + else + err.SetErrorString ("'settings remove' requires a key for dictionary variables. No key supplied.\n"); + break; + case lldb::eVarSetOperationClear: + dictionary.clear (); + break; + case lldb::eVarSetOperationAppend: + case lldb::eVarSetOperationAssign: + { + Args args (new_value); + size_t num_args = args.GetArgumentCount(); + for (size_t i = 0; i < num_args; ++i) + { + std::string tmp_arg = args.GetArgumentAtIndex (i); + size_t eq_sign = tmp_arg.find ('='); + if (eq_sign != std::string::npos) + { + if (eq_sign > 4) + { + std::string tmp_key = tmp_arg.substr (0, eq_sign); + std::string real_value = tmp_arg.substr (eq_sign+1); + if ((tmp_key[0] == '[') + && (tmp_key[1] == '"') + && (tmp_key[eq_sign-2] == '"') + && (tmp_key[eq_sign-1] == ']')) + { + std::string real_key = tmp_key.substr (2, eq_sign-4); + dictionary[real_key] = real_value; + } + else + err.SetErrorString ("Invalid key format for dictionary assignment. " + "Expected '[\"<key>\"]'\n"); + } + else + err.SetErrorString ("Invalid key format for dictionary assignment. " + "Expected '[\"<key>\"]'\n"); + } + else + err.SetErrorString ("Invalid format for dictionary value. Expected '[\"<key>\"]=<value>'\n"); + } + } + break; + case lldb::eVarSetOperationInsertBefore: + case lldb::eVarSetOperationInsertAfter: + err.SetErrorString ("Specified operation cannot be performed on dictionary variables.\n"); + break; + default: + err.SetErrorString ("Unrecognized operation.\n"); + break; + } +} + +const char * +UserSettingsController::EnumToString (const lldb::OptionEnumValueElement *enum_values, + int value) +{ + int i = 0; + while (enum_values[i].string_value != NULL) + { + if (enum_values[i].value == value) + return enum_values[i].string_value; + ++i; + } + + return "Invalid enumeration value"; +} + + +void +UserSettingsController::UpdateEnumVariable (lldb::OptionEnumValueElement *enum_values, + int *enum_var, + const char *new_value, + Error &err) +{ + bool found_one; + + *enum_var = Args::StringToOptionEnum (new_value, enum_values, enum_values[0].value, &found_one); + + if (!found_one) + err.SetErrorString ("Invalid enumeration value; cannot update variable.\n"); +} + +//---------------------------------------------------------------------- +// class InstanceSettings +//---------------------------------------------------------------------- + +InstanceSettings::InstanceSettings (UserSettingsController &owner, const char *instance_name) : + m_owner (owner), + m_instance_name (instance_name) +{ + if (m_instance_name != InstanceSettings::GetDefaultName()) + m_owner.RegisterInstanceSettings (this); +} + +InstanceSettings::~InstanceSettings () +{ + if (m_instance_name != InstanceSettings::GetDefaultName()) + m_owner.UnregisterInstanceSettings (this); +} + +const ConstString & +InstanceSettings::GetDefaultName () +{ + static const ConstString g_default_settings_name ("[DEFAULT]"); + + return g_default_settings_name; +} diff --git a/lldb/source/Interpreter/CommandInterpreter.cpp b/lldb/source/Interpreter/CommandInterpreter.cpp index 2b4155d4923..3c9a748b64a 100644 --- a/lldb/source/Interpreter/CommandInterpreter.cpp +++ b/lldb/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 @@ CommandInterpreter::CommandInterpreter ) : 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 @@ CommandInterpreter::Initialize () 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 @@ CommandInterpreter::Initialize () 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 @@ CommandInterpreter::LoadCommandDictionary () // 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 @@ CommandInterpreter::LoadCommandDictionary () 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 @@ CommandInterpreter::RemoveUser (const char *alias_name) 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 @@ CommandInterpreter::GetHelp (CommandReturnObject &result) 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 @@ CommandInterpreter::HandleCompletion (const char *current_line, 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 @@ CommandInterpreter::~CommandInterpreter () 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 @@ CommandInterpreter::CrossRegisterCommand (const char * dest_cmd, const char * ob } } -void -CommandInterpreter::SetScriptLanguage (ScriptLanguage lang) -{ - m_script_language = lang; -} - OptionArgVectorSP CommandInterpreter::GetAliasOptions (const char *alias_name) { @@ -1020,12 +860,6 @@ CommandInterpreter::HasAliasOptions () return (!m_alias_options.empty()); } -bool -CommandInterpreter::HasInterpreterVariables () -{ - return (!m_variables.empty()); -} - void CommandInterpreter::BuildAliasCommandArgs ( @@ -1201,8 +1035,10 @@ CommandInterpreter::OutputFormattedHelpText (Stream &strm, 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/lldb/source/Interpreter/Options.cpp b/lldb/source/Interpreter/Options.cpp index 097bd45c3a8..60ab1202853 100644 --- a/lldb/source/Interpreter/Options.cpp +++ b/lldb/source/Interpreter/Options.cpp @@ -364,7 +364,13 @@ Options::GenerateOptionUsage 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/lldb/source/Interpreter/ScriptInterpreter.cpp b/lldb/source/Interpreter/ScriptInterpreter.cpp index 9c5c086bfa3..e4b5634258a 100644 --- a/lldb/source/Interpreter/ScriptInterpreter.cpp +++ b/lldb/source/Interpreter/ScriptInterpreter.cpp @@ -63,4 +63,21 @@ ScriptInterpreter::CollectDataForBreakpointCommandCallback 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/lldb/source/Interpreter/StateVariable.cpp b/lldb/source/Interpreter/StateVariable.cpp deleted file mode 100644 index ae84e1ba5a9..00000000000 --- a/lldb/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; -} - diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp index 986e44dba74..4a6e26953e7 100644 --- a/lldb/source/Target/Process.cpp +++ b/lldb/source/Target/Process.cpp @@ -18,6 +18,7 @@ #include "lldb/Core/Log.h" #include "lldb/Core/PluginManager.h" #include "lldb/Core/State.h" +#include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Host/Host.h" #include "lldb/Target/ABI.h" #include "lldb/Target/RegisterContext.h" @@ -63,6 +64,7 @@ Process::FindPlugin (Target &target, const char *plugin_name, Listener &listener Process::Process(Target &target, Listener &listener) : UserID (LLDB_INVALID_PROCESS_ID), Broadcaster ("Process"), + ProcessInstanceSettings (*(Process::GetSettingsController().get())), m_target (target), m_section_load_info (), m_public_state (eStateUnloaded), @@ -1919,4 +1921,345 @@ Process::GetArchSpecForExistingProcess (const char *process_name) return Host::GetArchSpecForExistingProcess (process_name); } +lldb::UserSettingsControllerSP +Process::GetSettingsController (bool finish) +{ + static UserSettingsControllerSP g_settings_controller (new ProcessSettingsController); + static bool initialized = false; + + if (!initialized) + { + const lldb::UserSettingsControllerSP &parent = g_settings_controller->GetParent (); + if (parent) + parent->RegisterChild (g_settings_controller); + + g_settings_controller->CreateSettingsVector (Process::ProcessSettingsController::global_settings_table, + true); + g_settings_controller->CreateSettingsVector (Process::ProcessSettingsController::instance_settings_table, + false); + + g_settings_controller->InitializeGlobalVariables (); + g_settings_controller->CreateDefaultInstanceSettings (); + initialized = true; + } + + if (finish) + { + const lldb::UserSettingsControllerSP &parent = g_settings_controller->GetParent (); + if (parent) + parent->RemoveChild (g_settings_controller); + g_settings_controller.reset(); + } + + return g_settings_controller; +} + +//-------------------------------------------------------------- +// class Process::ProcessSettingsController +//-------------------------------------------------------------- + +Process::ProcessSettingsController::ProcessSettingsController () : + UserSettingsController ("process", Debugger::GetSettingsController()) +{ + m_default_settings.reset (new ProcessInstanceSettings (*this, InstanceSettings::GetDefaultName().AsCString())); +} + +Process::ProcessSettingsController::~ProcessSettingsController () +{ +} + +lldb::InstanceSettingsSP +Process::ProcessSettingsController::CreateNewInstanceSettings () +{ + ProcessInstanceSettings *new_settings = new ProcessInstanceSettings (*(Process::GetSettingsController().get())); + lldb::InstanceSettingsSP new_settings_sp (new_settings); + return new_settings_sp; +} + +//-------------------------------------------------------------- +// class ProcessInstanceSettings +//-------------------------------------------------------------- + +ProcessInstanceSettings::ProcessInstanceSettings (UserSettingsController &owner, const char *name) : + InstanceSettings (owner, (name == NULL ? CreateInstanceName().AsCString() : name)), + m_run_args (), + m_env_vars (), + m_input_path (), + m_output_path (), + m_error_path (), + m_plugin (), + m_disable_aslr (true) +{ + if (m_instance_name != InstanceSettings::GetDefaultName()) + { + const lldb::InstanceSettingsSP &pending_settings = m_owner.FindPendingSettings (m_instance_name); + CopyInstanceSettings (pending_settings,false); + m_owner.RemovePendingSettings (m_instance_name); + } +} + +ProcessInstanceSettings::ProcessInstanceSettings (const ProcessInstanceSettings &rhs) : + InstanceSettings (*(Process::GetSettingsController().get()), CreateInstanceName().AsCString()), + m_run_args (rhs.m_run_args), + m_env_vars (rhs.m_env_vars), + m_input_path (rhs.m_input_path), + m_output_path (rhs.m_output_path), + m_error_path (rhs.m_error_path), + m_plugin (rhs.m_plugin), + m_disable_aslr (rhs.m_disable_aslr) +{ + if (m_instance_name != InstanceSettings::GetDefaultName()) + { + const lldb::InstanceSettingsSP &pending_settings = m_owner.FindPendingSettings (m_instance_name); + CopyInstanceSettings (pending_settings,false); + m_owner.RemovePendingSettings (m_instance_name); + } +} + +ProcessInstanceSettings::~ProcessInstanceSettings () +{ +} + +ProcessInstanceSettings& +ProcessInstanceSettings::operator= (const ProcessInstanceSettings &rhs) +{ + if (this != &rhs) + { + m_run_args = rhs.m_run_args; + m_env_vars = rhs.m_env_vars; + m_input_path = rhs.m_input_path; + m_output_path = rhs.m_output_path; + m_error_path = rhs.m_error_path; + m_plugin = rhs.m_plugin; + m_disable_aslr = rhs.m_disable_aslr; + } + + return *this; +} + + +void +ProcessInstanceSettings::UpdateInstanceSettingsVariable (const ConstString &var_name, + const char *index_value, + const char *value, + const ConstString &instance_name, + const SettingEntry &entry, + lldb::VarSetOperationType op, + Error &err, + bool pending) +{ + if (var_name == RunArgsVarName()) + UserSettingsController::UpdateStringArrayVariable (op, index_value, m_run_args, value, err); + else if (var_name == EnvVarsVarName()) + UserSettingsController::UpdateDictionaryVariable (op, index_value, m_env_vars, value, err); + else if (var_name == InputPathVarName()) + UserSettingsController::UpdateStringVariable (op, m_input_path, value, err); + else if (var_name == OutputPathVarName()) + UserSettingsController::UpdateStringVariable (op, m_output_path, value, err); + else if (var_name == ErrorPathVarName()) + UserSettingsController::UpdateStringVariable (op, m_error_path, value, err); + else if (var_name == PluginVarName()) + UserSettingsController::UpdateEnumVariable (entry.enum_values, (int *) &m_plugin, value, err); + else if (var_name == DisableASLRVarName()) + UserSettingsController::UpdateBooleanVariable (op, m_disable_aslr, value, err); +} + +void +ProcessInstanceSettings::CopyInstanceSettings (const lldb::InstanceSettingsSP &new_settings, + bool pending) +{ + if (new_settings.get() == NULL) + return; + + ProcessInstanceSettings *new_process_settings = (ProcessInstanceSettings *) new_settings.get(); + + m_run_args = new_process_settings->m_run_args; + m_env_vars = new_process_settings->m_env_vars; + m_input_path = new_process_settings->m_input_path; + m_output_path = new_process_settings->m_output_path; + m_error_path = new_process_settings->m_error_path; + m_plugin = new_process_settings->m_plugin; + m_disable_aslr = new_process_settings->m_disable_aslr; +} + +void +Process::ProcessSettingsController::UpdateGlobalVariable (const ConstString &var_name, + const char *index_value, + const char *value, + const SettingEntry &entry, + lldb::VarSetOperationType op, + Error&err) +{ + // Currently 'process' does not have any global settings. +} + + +void +ProcessInstanceSettings::GetInstanceSettingsValue (const SettingEntry &entry, + const ConstString &var_name, + StringList &value) +{ + if (var_name == RunArgsVarName()) + { + if (m_run_args.GetArgumentCount() > 0) + for (int i = 0; i < m_run_args.GetArgumentCount(); ++i) + value.AppendString (m_run_args.GetArgumentAtIndex (i)); + else + value.AppendString (""); + } + else if (var_name == EnvVarsVarName()) + { + if (m_env_vars.size() > 0) + { + std::map<std::string, std::string>::iterator pos; + for (pos = m_env_vars.begin(); pos != m_env_vars.end(); ++pos) + { + StreamString value_str; + value_str.Printf ("%s=%s", pos->first.c_str(), pos->second.c_str()); + value.AppendString (value_str.GetData()); + } + } + else + value.AppendString (""); + } + else if (var_name == InputPathVarName()) + { + value.AppendString (m_input_path.c_str()); + } + else if (var_name == OutputPathVarName()) + { + value.AppendString (m_output_path.c_str()); + } + else if (var_name == ErrorPathVarName()) + { + value.AppendString (m_error_path.c_str()); + } + else if (var_name == PluginVarName()) + { + value.AppendString (UserSettingsController::EnumToString (entry.enum_values, (int) m_plugin)); + } + else if (var_name == DisableASLRVarName()) + { + if (m_disable_aslr) + value.AppendString ("true"); + else + value.AppendString ("false"); + } + else + value.AppendString ("unrecognized variable name"); +} + +void +Process::ProcessSettingsController::GetGlobalSettingsValue (const ConstString &var_name, + StringList &value) +{ + // Currently 'process' does not have any global settings. +} + +const ConstString +ProcessInstanceSettings::CreateInstanceName () +{ + static int instance_count = 1; + StreamString sstr; + + sstr.Printf ("process_%d", instance_count); + ++instance_count; + + const ConstString ret_val (sstr.GetData()); + return ret_val; +} + +const ConstString & +ProcessInstanceSettings::RunArgsVarName () +{ + static ConstString run_args_var_name ("run-args"); + + return run_args_var_name; +} + +const ConstString & +ProcessInstanceSettings::EnvVarsVarName () +{ + static ConstString env_vars_var_name ("env-vars"); + + return env_vars_var_name; +} + +const ConstString & +ProcessInstanceSettings::InputPathVarName () +{ + static ConstString input_path_var_name ("input-path"); + + return input_path_var_name; +} + +const ConstString & +ProcessInstanceSettings::OutputPathVarName () +{ + static ConstString output_path_var_name ("output_path"); + + return output_path_var_name; +} + +const ConstString & +ProcessInstanceSettings::ErrorPathVarName () +{ + static ConstString error_path_var_name ("error_path"); + + return error_path_var_name; +} + +const ConstString & +ProcessInstanceSettings::PluginVarName () +{ + static ConstString plugin_var_name ("plugin"); + + return plugin_var_name; +} + + +const ConstString & +ProcessInstanceSettings::DisableASLRVarName () +{ + static ConstString disable_aslr_var_name ("disable-aslr"); + + return disable_aslr_var_name; +} + + +//-------------------------------------------------- +// ProcessSettingsController Variable Tables +//-------------------------------------------------- + +SettingEntry +Process::ProcessSettingsController::global_settings_table[] = +{ + //{ "var-name", var-type , "default", enum-table, init'd, hidden, "help-text"}, + { NULL, eSetVarTypeNone, NULL, NULL, 0, 0, NULL } +}; + + +lldb::OptionEnumValueElement +Process::ProcessSettingsController::g_plugins[] = +{ + { eMacosx, "macosx", "Use the Mac OS X plugin" }, + { eRemoteDebugger, "remote_debugger" , "Use the remote debugger plugin" }, + { 0, NULL, NULL } +}; + +SettingEntry +Process::ProcessSettingsController::instance_settings_table[] = +{ + //{ "var-name", var-type, "default", enum-table, init'd, hidden, "help-text"}, + { "run-args", eSetVarTypeArray, NULL, NULL, false, false, "A list containing all the arguments to be passed to the executable when it is run." }, + { "env-vars", eSetVarTypeDictionary, NULL, NULL, false, false, "A list of all the environment variables to be passed to the executable's environment, and their values." }, + { "input-path", eSetVarTypeString, "/dev/stdin", NULL, false, false, "The file/path to be used by the executable program for reading its input." }, + { "output-path", eSetVarTypeString, "/dev/stdout", NULL, false, false, "The file/path to be used by the executable program for writing its output." }, + { "error-path", eSetVarTypeString, "/dev/stderr", NULL, false, false, "The file/path to be used by the executable program for writings its error messages." }, + { "plugin", eSetVarTypeEnum, NULL , g_plugins, false, false, "The plugin to be used to run the process." }, + { "disable-aslr", eSetVarTypeBool, "true", NULL, false, false, "Disable Address Space Layout Randomization (ASLR)" }, + { NULL, eSetVarTypeNone, NULL, NULL, 0, 0, NULL } +}; + + diff --git a/lldb/source/lldb.cpp b/lldb/source/lldb.cpp index dc64ded9753..30892d64623 100644 --- a/lldb/source/lldb.cpp +++ b/lldb/source/lldb.cpp @@ -74,6 +74,8 @@ lldb_private::Initialize () ProcessMacOSX::Initialize(); SymbolVendorMacOSX::Initialize(); #endif + Debugger::GetSettingsController (false); + Process::GetSettingsController (false); #ifdef __linux__ ProcessLinux::Initialize(); @@ -107,6 +109,9 @@ lldb_private::Terminate () SymbolVendorMacOSX::Terminate(); #endif + Process::GetSettingsController (true); + Debugger::GetSettingsController (true); + #ifdef __linux__ ProcessLinux::Terminate(); #endif diff --git a/lldb/tools/driver/Driver.cpp b/lldb/tools/driver/Driver.cpp index 0816781889c..3dcb9e4529f 100644 --- a/lldb/tools/driver/Driver.cpp +++ b/lldb/tools/driver/Driver.cpp @@ -1087,7 +1087,8 @@ Driver::MainLoop () { char buffer[25]; - sprintf (buffer, "set term-width %d", window_size.ws_col); + if (window_size.ws_col > 0) + sprintf (buffer, "settings set term-width %d", window_size.ws_col); m_debugger.HandleCommand ((const char *) buffer); } |