Hi clayborg, jingham, This enables Windows to specify paths with backslashes unquoted and fixes many tests as a result. We don't always have control over what type of slashes a path built in python has. For example if os.join() is used it will use backslashes. or if os.path.separator is used. So it's important to be able to have unquoted paths on Windows.
http://reviews.llvm.org/D6943 Files: include/lldb/Core/UserSettingsController.h include/lldb/Interpreter/CommandInterpreter.h include/lldb/Interpreter/OptionValueProperties.h source/Core/Debugger.cpp source/Core/UserSettingsController.cpp source/Interpreter/Args.cpp source/Interpreter/CommandInterpreter.cpp source/Interpreter/OptionValueProperties.cpp source/Interpreter/Property.cpp EMAIL PREFERENCES http://reviews.llvm.org/settings/panel/emailpreferences/
Index: include/lldb/Core/UserSettingsController.h =================================================================== --- include/lldb/Core/UserSettingsController.h +++ include/lldb/Core/UserSettingsController.h @@ -46,6 +46,9 @@ ~Properties() { } + + virtual void + Initialize(const PropertyDefinition *definitions); virtual lldb::OptionValuePropertiesSP GetValueProperties () const Index: include/lldb/Interpreter/CommandInterpreter.h =================================================================== --- include/lldb/Interpreter/CommandInterpreter.h +++ include/lldb/Interpreter/CommandInterpreter.h @@ -195,7 +195,6 @@ class CommandInterpreter : public Broadcaster, - public Properties, public IOHandlerDelegate { public: @@ -449,6 +448,18 @@ const char *help_text, uint32_t max_word_len); + Properties & + GetProperties () + { + return m_properties; + } + + static Properties & + GetGlobalProperties() + { + return m_global_properties; + } + Debugger & GetDebugger () { @@ -619,6 +630,9 @@ bool GetStopCmdSourceOnError () const; + static char + GetEscapeCharacter(); + uint32_t GetNumErrors() const { @@ -676,6 +690,8 @@ Error PreprocessCommand (std::string &command); + Properties m_properties; // The non-global CommandInterpreter properties. + static Properties m_global_properties; // The global CommandInterpreter properties. Debugger &m_debugger; // The debugger session that this interpreter is associated with ExecutionContextRef m_exe_ctx_ref; // The current execution context to use when handling commands bool m_synchronous_execution; Index: include/lldb/Interpreter/OptionValueProperties.h =================================================================== --- include/lldb/Interpreter/OptionValueProperties.h +++ include/lldb/Interpreter/OptionValueProperties.h @@ -181,7 +181,13 @@ bool SetPropertyAtIndexAsBoolean (const ExecutionContext *exe_ctx, uint32_t idx, bool new_value); - + + char + GetPropertyAtIndexAsChar (const ExecutionContext *exe_ctx, uint32_t idx, char fail_value) const; + + bool + SetPropertyAtIndexAsChar (const ExecutionContext *exe_ctx, uint32_t idx, char new_value); + OptionValueDictionary * GetPropertyAtIndexAsOptionValueDictionary (const ExecutionContext *exe_ctx, uint32_t idx) const; Index: source/Core/Debugger.cpp =================================================================== --- source/Core/Debugger.cpp +++ source/Core/Debugger.cpp @@ -167,7 +167,7 @@ ePropertyUseExternalEditor, ePropertyUseColor, ePropertyAutoOneLineSummaries, - ePropertyEscapeNonPrintables + ePropertyEscapeNonPrintables, }; Debugger::LoadPluginCallbackType Debugger::g_load_plugin_callback = NULL; @@ -382,6 +382,7 @@ return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, true); } + #pragma mark Debugger //const DebuggerPropertiesSP & @@ -679,16 +680,21 @@ m_collection_sp->Initialize (g_properties); m_collection_sp->AppendProperty (ConstString("target"), - ConstString("Settings specify to debugging targets."), + ConstString("Settings specific to debugging targets."), true, Target::GetGlobalProperties()->GetValueProperties()); if (m_command_interpreter_ap.get()) { m_collection_sp->AppendProperty (ConstString("interpreter"), - ConstString("Settings specify to the debugger's command interpreter."), + ConstString("Settings specific to the debugger's command interpreter."), true, - m_command_interpreter_ap->GetValueProperties()); + m_command_interpreter_ap->GetProperties().GetValueProperties()); } + m_collection_sp->AppendProperty (ConstString("interpreter-global"), + ConstString("Settings for all command interpreters."), + true, + CommandInterpreter::GetGlobalProperties().GetValueProperties()); + OptionValueSInt64 *term_width = m_collection_sp->GetPropertyAtIndexAsOptionValueSInt64 (NULL, ePropertyTerminalWidth); term_width->SetMinimumValue(10); term_width->SetMaximumValue(1024); Index: source/Core/UserSettingsController.cpp =================================================================== --- source/Core/UserSettingsController.cpp +++ source/Core/UserSettingsController.cpp @@ -23,6 +23,11 @@ using namespace lldb; using namespace lldb_private; +void +Properties::Initialize(const PropertyDefinition *definitions) +{ + m_collection_sp->Initialize(definitions); +} lldb::OptionValueSP Properties::GetPropertyValue (const ExecutionContext *exe_ctx, Index: source/Interpreter/Args.cpp =================================================================== --- source/Interpreter/Args.cpp +++ source/Interpreter/Args.cpp @@ -166,7 +166,8 @@ if (command && command[0]) { static const char *k_space_separators = " \t"; - static const char *k_space_separators_with_slash_and_quotes = " \t \\'\""; + std::string space_separators_with_escape_and_quotes(" \t'\""); + space_separators_with_escape_and_quotes.push_back(CommandInterpreter::GetEscapeCharacter()); const char *arg_end = nullptr; const char *arg_pos; for (arg_pos = command; @@ -202,12 +203,38 @@ do { - arg_end = ::strcspn (arg_pos, k_space_separators_with_slash_and_quotes) + arg_pos; + arg_end = ::strcspn (arg_pos, space_separators_with_escape_and_quotes.c_str()) + arg_pos; switch (arg_end[0]) { default: - assert (!"Unhandled case statement, we must handle this..."); + if (arg_end[0] == CommandInterpreter::GetEscapeCharacter()) + { + switch (arg_end[1]) + { + case '\0': + arg.append (arg_piece_start); + ++arg_end; + arg_complete = true; + break; + + default: + if (quote_char == '\0') + { + arg.append (arg_piece_start, arg_end - arg_piece_start); + if (arg_end[1] != '\0') + { + arg.append (arg_end + 1, 1); + arg_pos = arg_end + 2; + arg_piece_start = arg_pos; + } + } + else + arg_pos = arg_end + 2; + break; + } + } + break; case '\0': @@ -217,33 +244,6 @@ arg_complete = true; break; - case '\\': - // Backslash character - switch (arg_end[1]) - { - case '\0': - arg.append (arg_piece_start); - ++arg_end; - arg_complete = true; - break; - - default: - if (quote_char == '\0') - { - arg.append (arg_piece_start, arg_end - arg_piece_start); - if (arg_end[1] != '\0') - { - arg.append (arg_end + 1, 1); - arg_pos = arg_end + 2; - arg_piece_start = arg_pos; - } - } - else - arg_pos = arg_end + 2; - break; - } - break; - case '"': case '\'': case '`': Index: source/Interpreter/CommandInterpreter.cpp =================================================================== --- source/Interpreter/CommandInterpreter.cpp +++ source/Interpreter/CommandInterpreter.cpp @@ -77,23 +77,44 @@ using namespace lldb; using namespace lldb_private; +#if defined(_WIN32) +#define DEFAULT_ESCAPE_CHARACTER '#' +#else +#define DEFAULT_ESCAPE_CHARACTER '\\' +#endif + static PropertyDefinition g_properties[] = { - { "expand-regex-aliases", OptionValue::eTypeBoolean, true, false, nullptr, nullptr, "If true, regular expression alias commands will show the expanded command that will be executed. This can be used to debug new regular expression alias commands." }, - { "prompt-on-quit", OptionValue::eTypeBoolean, true, true, nullptr, nullptr, "If true, LLDB will prompt you before quitting if there are any live processes being debugged. If false, LLDB will quit without asking in any case." }, - { "stop-command-source-on-error", OptionValue::eTypeBoolean, true, true, nullptr, nullptr, "If true, LLDB will stop running a 'command source' script upon encountering an error." }, + { "expand-regex-aliases", OptionValue::eTypeBoolean, false, false, nullptr, nullptr, "If true, regular expression alias commands will show the expanded command that will be executed. This can be used to debug new regular expression alias commands." }, + { "prompt-on-quit", OptionValue::eTypeBoolean, false, true, nullptr, nullptr, "If true, LLDB will prompt you before quitting if there are any live processes being debugged. If false, LLDB will quit without asking in any case." }, + { "stop-command-source-on-error", OptionValue::eTypeBoolean, false, true, nullptr, nullptr, "If true, LLDB will stop running a 'command source' script upon encountering an error." }, + { nullptr , OptionValue::eTypeInvalid, true, 0 , nullptr, nullptr, nullptr } +}; + +static PropertyDefinition +g_global_properties[] = +{ + { "escape-character", OptionValue::eTypeChar, true, DEFAULT_ESCAPE_CHARACTER, nullptr, nullptr, "The character LLDB will recognize as an escape character while parsing command arguments" }, { nullptr , OptionValue::eTypeInvalid, true, 0 , nullptr, nullptr, nullptr } }; enum { ePropertyExpandRegexAliases = 0, ePropertyPromptOnQuit = 1, - ePropertyStopCmdSourceOnError = 2 + ePropertyStopCmdSourceOnError = 2, +}; + +enum +{ + eGlobalPropertyEscapeCharacter = 0, }; +Properties CommandInterpreter::m_global_properties(OptionValuePropertiesSP(new OptionValueProperties(ConstString("interpreter-global")))); + + ConstString & CommandInterpreter::GetStaticBroadcasterClass () { @@ -108,7 +129,6 @@ bool synchronous_execution ) : Broadcaster (&debugger, "lldb.command-interpreter"), - Properties(OptionValuePropertiesSP(new OptionValueProperties(ConstString("interpreter")))), IOHandlerDelegate (IOHandlerDelegate::Completion::LLDBCommand), m_debugger (debugger), m_synchronous_execution (synchronous_execution), @@ -122,36 +142,45 @@ m_command_source_depth (0), m_num_errors(0), m_quit_requested(false), - m_stopped_for_crash(false) - + m_stopped_for_crash(false), + m_properties(OptionValuePropertiesSP(new OptionValueProperties(ConstString("interpreter")))) { debugger.SetScriptLanguage (script_language); SetEventName (eBroadcastBitThreadShouldExit, "thread-should-exit"); SetEventName (eBroadcastBitResetPrompt, "reset-prompt"); SetEventName (eBroadcastBitQuitCommandReceived, "quit"); CheckInWithManager (); - m_collection_sp->Initialize (g_properties); + m_properties.Initialize(g_properties); + m_global_properties.Initialize(g_global_properties); } bool CommandInterpreter::GetExpandRegexAliases () const { const uint32_t idx = ePropertyExpandRegexAliases; - return m_collection_sp->GetPropertyAtIndexAsBoolean (nullptr, idx, g_properties[idx].default_uint_value != 0); + return m_properties.GetValueProperties()->GetPropertyAtIndexAsBoolean (nullptr, idx, g_properties[idx].default_uint_value != 0); } bool CommandInterpreter::GetPromptOnQuit () const { const uint32_t idx = ePropertyPromptOnQuit; - return m_collection_sp->GetPropertyAtIndexAsBoolean (nullptr, idx, g_properties[idx].default_uint_value != 0); + return m_properties.GetValueProperties()->GetPropertyAtIndexAsBoolean (nullptr, idx, g_properties[idx].default_uint_value != 0); } bool CommandInterpreter::GetStopCmdSourceOnError () const { const uint32_t idx = ePropertyStopCmdSourceOnError; - return m_collection_sp->GetPropertyAtIndexAsBoolean (nullptr, idx, g_properties[idx].default_uint_value != 0); + return m_properties.GetValueProperties()->GetPropertyAtIndexAsBoolean (nullptr, idx, g_properties[idx].default_uint_value != 0); +} + +char +CommandInterpreter::GetEscapeCharacter() +{ + const uint32_t idx = eGlobalPropertyEscapeCharacter; + lldb::OptionValuePropertiesSP value_props = m_global_properties.GetValueProperties(); + return value_props->GetPropertyAtIndexAsChar(NULL, idx, static_cast<char>(g_global_properties[idx].default_uint_value)); } void Index: source/Interpreter/OptionValueProperties.cpp =================================================================== --- source/Interpreter/OptionValueProperties.cpp +++ source/Interpreter/OptionValueProperties.cpp @@ -376,6 +376,35 @@ return false; } +char +OptionValueProperties::GetPropertyAtIndexAsChar (const ExecutionContext *exe_ctx, uint32_t idx, char fail_value) const +{ + const Property *property = GetPropertyAtIndex (exe_ctx, false, idx); + if (property) + { + OptionValue *value = property->GetValue().get(); + if (value) + return value->GetCharValue(fail_value); + } + return fail_value; +} + +bool +OptionValueProperties::SetPropertyAtIndexAsChar(const ExecutionContext *exe_ctx, uint32_t idx, char new_value) +{ + const Property *property = GetPropertyAtIndex (exe_ctx, true, idx); + if (property) + { + OptionValue *value = property->GetValue().get(); + if (value) + { + value->SetCharValue(new_value); + return true; + } + } + return false; +} + OptionValueDictionary * OptionValueProperties::GetPropertyAtIndexAsOptionValueDictionary (const ExecutionContext *exe_ctx, uint32_t idx) const { Index: source/Interpreter/Property.cpp =================================================================== --- source/Interpreter/Property.cpp +++ source/Interpreter/Property.cpp @@ -62,7 +62,7 @@ break; case OptionValue::eTypeChar: - m_value_sp.reset(new OptionValueChar(Args::StringToChar(definition.default_cstr_value, '\0', nullptr))); + m_value_sp.reset(new OptionValueChar(static_cast<char>(definition.default_uint_value))); break; case OptionValue::eTypeDictionary:
_______________________________________________ lldb-commits mailing list lldb-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/lldb-commits