diff options
-rw-r--r-- | lldb/include/lldb/Core/Debugger.h | 6 | ||||
-rw-r--r-- | lldb/include/lldb/Interpreter/Args.h | 19 | ||||
-rw-r--r-- | lldb/include/lldb/Interpreter/OptionValueProperties.h | 5 | ||||
-rw-r--r-- | lldb/include/lldb/Interpreter/OptionValueString.h | 28 | ||||
-rw-r--r-- | lldb/source/Core/Debugger.cpp | 23 | ||||
-rw-r--r-- | lldb/source/Interpreter/Args.cpp | 134 | ||||
-rw-r--r-- | lldb/source/Interpreter/CommandReturnObject.cpp | 7 | ||||
-rw-r--r-- | lldb/source/Interpreter/OptionValueProperties.cpp | 10 | ||||
-rw-r--r-- | lldb/source/Interpreter/OptionValueString.cpp | 39 | ||||
-rw-r--r-- | lldb/source/Interpreter/Property.cpp | 9 | ||||
-rw-r--r-- | lldb/source/Interpreter/ScriptInterpreterPython.cpp | 10 |
11 files changed, 270 insertions, 20 deletions
diff --git a/lldb/include/lldb/Core/Debugger.h b/lldb/include/lldb/Core/Debugger.h index 88443877b5b..11392c438dc 100644 --- a/lldb/include/lldb/Core/Debugger.h +++ b/lldb/include/lldb/Core/Debugger.h @@ -262,6 +262,12 @@ public: eStopDisassemblyTypeAlways }; + virtual Error + SetPropertyValue (const ExecutionContext *exe_ctx, + VarSetOperationType op, + const char *property_path, + const char *value); + bool GetAutoConfirm () const; diff --git a/lldb/include/lldb/Interpreter/Args.h b/lldb/include/lldb/Interpreter/Args.h index ca1b23bd941..61f267bd989 100644 --- a/lldb/include/lldb/Interpreter/Args.h +++ b/lldb/include/lldb/Interpreter/Args.h @@ -411,6 +411,25 @@ public: static const char * GetShellSafeArgument (const char *unsafe_arg, std::string &safe_arg); + // EncodeEscapeSequences will change the textual representation of common + // escape sequences like "\n" (two characters) into a single '\n'. It does + // this for all of the supported escaped sequences and for the \0ooo (octal) + // and \xXX (hex). The resulting "dst" string will contain the character + // versions of all supported escape sequences. The common supported escape + // sequences are: "\a", "\b", "\f", "\n", "\r", "\t", "\v", "\'", "\"", "\\". + + static void + EncodeEscapeSequences (const char *src, std::string &dst); + + // ExpandEscapeSequences will change a string of possibly non-printable + // characters and expand them into text. So '\n' will turn into two chracters + // like "\n" which is suitable for human reading. When a character is not + // printable and isn't one of the common in escape sequences listed in the + // help for EncodeEscapeSequences, then it will be encoded as octal. Printable + // characters are left alone. + static void + ExpandEscapedCharacters (const char *src, std::string &dst); + // This one isn't really relevant to Arguments per se, but we're using the Args as a // general strings container, so... void diff --git a/lldb/include/lldb/Interpreter/OptionValueProperties.h b/lldb/include/lldb/Interpreter/OptionValueProperties.h index e19c09ceff6..f6eab43ee24 100644 --- a/lldb/include/lldb/Interpreter/OptionValueProperties.h +++ b/lldb/include/lldb/Interpreter/OptionValueProperties.h @@ -210,7 +210,10 @@ public: bool SetPropertyAtIndexAsString (const ExecutionContext *exe_ctx, uint32_t idx, const char *new_value); - + + OptionValueString * + GetPropertyAtIndexAsOptionValueString (const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const; + OptionValueFileSpec * GetPropertyAtIndexAsOptionValueFileSpec (const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const; diff --git a/lldb/include/lldb/Interpreter/OptionValueString.h b/lldb/include/lldb/Interpreter/OptionValueString.h index 263ab78e966..0ecb406343d 100644 --- a/lldb/include/lldb/Interpreter/OptionValueString.h +++ b/lldb/include/lldb/Interpreter/OptionValueString.h @@ -16,6 +16,7 @@ // Other libraries and framework includes // Project includes +#include "lldb/Core/Flags.h" #include "lldb/Interpreter/OptionValue.h" namespace lldb_private { @@ -23,17 +24,24 @@ namespace lldb_private { class OptionValueString : public OptionValue { public: + enum Options + { + eOptionEncodeCharacterEscapeSequences = (1u << 0) + }; + OptionValueString () : OptionValue(), m_current_value (), - m_default_value () + m_default_value (), + m_options() { } OptionValueString (const char *value) : OptionValue(), m_current_value (), - m_default_value () + m_default_value (), + m_options() { if (value && value[0]) { @@ -46,7 +54,8 @@ public: const char *default_value) : OptionValue(), m_current_value (), - m_default_value () + m_default_value (), + m_options() { if (current_value && current_value[0]) m_current_value.assign (current_value); @@ -90,6 +99,18 @@ public: //--------------------------------------------------------------------- // Subclass specific functions //--------------------------------------------------------------------- + + Flags & + GetOptions () + { + return m_options; + } + + const Flags & + GetOptions () const + { + return m_options; + } const char * operator = (const char *value) @@ -154,6 +175,7 @@ public: protected: std::string m_current_value; std::string m_default_value; + Flags m_options; }; } // namespace lldb_private diff --git a/lldb/source/Core/Debugger.cpp b/lldb/source/Core/Debugger.cpp index 57f63e8f454..6cbe90c675d 100644 --- a/lldb/source/Core/Debugger.cpp +++ b/lldb/source/Core/Debugger.cpp @@ -112,7 +112,7 @@ g_properties[] = { "auto-confirm", OptionValue::eTypeBoolean, true, false, NULL, NULL, "If true all confirmation prompts will receive their default reply." }, { "frame-format", OptionValue::eTypeString , true, 0 , DEFAULT_FRAME_FORMAT, NULL, "The default frame format string to use when displaying stack frame information for threads." }, { "notify-void", OptionValue::eTypeBoolean, true, false, NULL, NULL, "Notify the user explicitly if an expression returns void (default: false)." }, -{ "prompt", OptionValue::eTypeString , true, 0 , "(lldb) ", NULL, "The debugger command line prompt displayed for the user." }, +{ "prompt", OptionValue::eTypeString , true, OptionValueString::eOptionEncodeCharacterEscapeSequences, "(lldb) ", NULL, "The debugger command line prompt displayed for the user." }, { "script-lang", OptionValue::eTypeEnum , true, eScriptLanguagePython, NULL, g_language_enumerators, "The script language to be used for evaluating user-written scripts." }, { "stop-disassembly-count", OptionValue::eTypeSInt64 , true, 4 , NULL, NULL, "The number of disassembly lines to show when displaying a stopped context." }, { "stop-disassembly-display", OptionValue::eTypeEnum , true, Debugger::eStopDisassemblyTypeNoSource, NULL, g_show_disassembly_enum_values, "Control when to display disassembly when displaying a stopped context." }, @@ -152,6 +152,27 @@ enum // return m_properties_sp->GetThreadFormat(); //} // + + +Error +Debugger::SetPropertyValue (const ExecutionContext *exe_ctx, + VarSetOperationType op, + const char *property_path, + const char *value) +{ + Error error (Properties::SetPropertyValue (exe_ctx, op, property_path, value)); + if (error.Success()) + { + if (strcmp(property_path, g_properties[ePropertyPrompt].name) == 0) + { + const char *new_prompt = GetPrompt(); + EventSP prompt_change_event_sp (new Event(CommandInterpreter::eBroadcastBitResetPrompt, new EventDataBytes (new_prompt))); + GetCommandInterpreter().BroadcastEvent (prompt_change_event_sp); + } + } + return error; +} + bool Debugger::GetAutoConfirm () const { diff --git a/lldb/source/Interpreter/Args.cpp b/lldb/source/Interpreter/Args.cpp index 63bcb8785b3..bb9ed8df07d 100644 --- a/lldb/source/Interpreter/Args.cpp +++ b/lldb/source/Interpreter/Args.cpp @@ -1528,3 +1528,137 @@ Args::ParseArgsForCompletion } } + +void +Args::EncodeEscapeSequences (const char *src, std::string &dst) +{ + dst.clear(); + if (src) + { + for (const char *p = src; *p != '\0'; ++p) + { + size_t non_special_chars = ::strcspn (p, "\\"); + if (non_special_chars > 0) + { + dst.append(p, non_special_chars); + p += non_special_chars; + if (*p == '\0') + break; + } + + if (*p == '\\') + { + ++p; // skip the slash + switch (*p) + { + case 'a' : dst.append(1, '\a'); break; + case 'b' : dst.append(1, '\b'); break; + case 'f' : dst.append(1, '\f'); break; + case 'n' : dst.append(1, '\n'); break; + case 'r' : dst.append(1, '\r'); break; + case 't' : dst.append(1, '\t'); break; + case 'v' : dst.append(1, '\v'); break; + case '\\': dst.append(1, '\\'); break; + case '\'': dst.append(1, '\''); break; + case '"' : dst.append(1, '"'); break; + case '0' : + // 1 to 3 octal chars + { + // Make a string that can hold onto the initial zero char, + // up to 3 octal digits, and a terminating NULL. + char oct_str[5] = { '\0', '\0', '\0', '\0', '\0' }; + + int i; + for (i=0; (p[i] >= '0' && p[i] <= '7') && i<4; ++i) + oct_str[i] = p[i]; + + // We don't want to consume the last octal character since + // the main for loop will do this for us, so we advance p by + // one less than i (even if i is zero) + p += i - 1; + unsigned long octal_value = ::strtoul (oct_str, NULL, 8); + if (octal_value <= UINT8_MAX) + { + const char octal_char = octal_value; + dst.append(1, octal_char); + } + } + break; + + case 'x': + // hex number in the format + if (isxdigit(p[1])) + { + ++p; // Skip the 'x' + + // Make a string that can hold onto two hex chars plus a + // NULL terminator + char hex_str[3] = { *p, '\0', '\0' }; + if (isxdigit(p[1])) + { + ++p; // Skip the first of the two hex chars + hex_str[1] = *p; + } + + unsigned long hex_value = strtoul (hex_str, NULL, 16); + if (hex_value <= UINT8_MAX) + dst.append (1, (char)hex_value); + } + else + { + dst.append(1, 'x'); + } + break; + + default: + // Just desensitize any other character by just printing what + // came after the '\' + dst.append(1, *p); + break; + + } + } + } + } +} + + +void +Args::ExpandEscapedCharacters (const char *src, std::string &dst) +{ + dst.clear(); + if (src) + { + for (const char *p = src; *p != '\0'; ++p) + { + if (isprint(*p)) + dst.append(1, *p); + else + { + switch (*p) + { + case '\a': dst.append("\\a"); break; + case '\b': dst.append("\\b"); break; + case '\f': dst.append("\\f"); break; + case '\n': dst.append("\\n"); break; + case '\r': dst.append("\\r"); break; + case '\t': dst.append("\\t"); break; + case '\v': dst.append("\\v"); break; + case '\'': dst.append("\\'"); break; + case '"': dst.append("\\\""); break; + case '\\': dst.append("\\\\"); break; + default: + { + // Just encode as octal + dst.append("\\0"); + char octal_str[32]; + snprintf(octal_str, sizeof(octal_str), "%o", *p); + dst.append(octal_str); + } + break; + } + } + } + } +} + diff --git a/lldb/source/Interpreter/CommandReturnObject.cpp b/lldb/source/Interpreter/CommandReturnObject.cpp index ddb783bca57..896ad2b7e84 100644 --- a/lldb/source/Interpreter/CommandReturnObject.cpp +++ b/lldb/source/Interpreter/CommandReturnObject.cpp @@ -106,11 +106,12 @@ CommandReturnObject::AppendWarningWithFormat (const char *format, ...) void CommandReturnObject::AppendMessage (const char *in_string, int len) { - if (!in_string) + if (!in_string || len == 0) return; if (len < 0) - len = ::strlen (in_string); - GetOutputStream().Printf("%*.*s\n", len, len, in_string); + GetOutputStream().Printf("%s\n", in_string); + else + GetOutputStream().Printf("%*.*s\n", len, len, in_string); } void diff --git a/lldb/source/Interpreter/OptionValueProperties.cpp b/lldb/source/Interpreter/OptionValueProperties.cpp index 304ce6299ed..607a93212a9 100644 --- a/lldb/source/Interpreter/OptionValueProperties.cpp +++ b/lldb/source/Interpreter/OptionValueProperties.cpp @@ -526,6 +526,16 @@ OptionValueProperties::SetPropertyAtIndexAsString (const ExecutionContext *exe_c return false; } +OptionValueString * +OptionValueProperties::GetPropertyAtIndexAsOptionValueString (const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const +{ + OptionValueSP value_sp(GetPropertyValueAtIndex (exe_ctx, will_modify, idx)); + if (value_sp) + return value_sp->GetAsString(); + return NULL; +} + + uint64_t OptionValueProperties::GetPropertyAtIndexAsUInt64 (const ExecutionContext *exe_ctx, uint32_t idx, uint64_t fail_value) const { diff --git a/lldb/source/Interpreter/OptionValueString.cpp b/lldb/source/Interpreter/OptionValueString.cpp index 35ab8c8f7ce..696e62b78e7 100644 --- a/lldb/source/Interpreter/OptionValueString.cpp +++ b/lldb/source/Interpreter/OptionValueString.cpp @@ -14,6 +14,7 @@ // Other libraries and framework includes // Project includes #include "lldb/Core/Stream.h" +#include "lldb/Interpreter/Args.h" using namespace lldb; using namespace lldb_private; @@ -29,10 +30,22 @@ OptionValueString::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uin strm.PutCString (" = "); if (!m_current_value.empty() || m_value_was_set) { - if (dump_mask & eDumpOptionRaw) - strm.Printf ("%s", m_current_value.c_str()); + if (m_options.Test (eOptionEncodeCharacterEscapeSequences)) + { + std::string expanded_escape_value; + Args::ExpandEscapedCharacters(m_current_value.c_str(), expanded_escape_value); + if (dump_mask & eDumpOptionRaw) + strm.Printf ("%s", expanded_escape_value.c_str()); + else + strm.Printf ("\"%s\"", expanded_escape_value.c_str()); + } else - strm.Printf ("\"%s\"", m_current_value.c_str()); + { + if (dump_mask & eDumpOptionRaw) + strm.Printf ("%s", m_current_value.c_str()); + else + strm.Printf ("\"%s\"", m_current_value.c_str()); + } } } } @@ -53,7 +66,16 @@ OptionValueString::SetValueFromCString (const char *value_cstr, case eVarSetOperationAppend: if (value_cstr && value_cstr[0]) - m_current_value += value_cstr; + { + if (m_options.Test (eOptionEncodeCharacterEscapeSequences)) + { + std::string str; + Args::EncodeEscapeSequences (value_cstr, str); + m_current_value += str; + } + else + m_current_value += value_cstr; + } break; case eVarSetOperationClear: @@ -63,7 +85,14 @@ OptionValueString::SetValueFromCString (const char *value_cstr, case eVarSetOperationReplace: case eVarSetOperationAssign: m_value_was_set = true; - SetCurrentValue (value_cstr); + if (m_options.Test (eOptionEncodeCharacterEscapeSequences)) + { + Args::EncodeEscapeSequences (value_cstr, m_current_value); + } + else + { + SetCurrentValue (value_cstr); + } break; } return error; diff --git a/lldb/source/Interpreter/Property.cpp b/lldb/source/Interpreter/Property.cpp index 7e7dc010997..d2bf1e1fe98 100644 --- a/lldb/source/Interpreter/Property.cpp +++ b/lldb/source/Interpreter/Property.cpp @@ -154,9 +154,14 @@ Property::Property (const PropertyDefinition &definition) : break; case OptionValue::eTypeString: - // "definition.default_uint_value" is not used for a OptionValueFileSpecList + // "definition.default_uint_value" can contain the string option flags OR'ed together // "definition.default_cstr_value" can contain a default string value - m_value_sp.reset (new OptionValueString(definition.default_cstr_value)); + { + OptionValueString *string_value = new OptionValueString(definition.default_cstr_value); + if (definition.default_uint_value != 0) + string_value->GetOptions().Reset(definition.default_uint_value); + m_value_sp.reset (string_value); + } break; } } diff --git a/lldb/source/Interpreter/ScriptInterpreterPython.cpp b/lldb/source/Interpreter/ScriptInterpreterPython.cpp index 97cf7f866d6..fec70e301cc 100644 --- a/lldb/source/Interpreter/ScriptInterpreterPython.cpp +++ b/lldb/source/Interpreter/ScriptInterpreterPython.cpp @@ -376,11 +376,11 @@ ScriptInterpreterPython::PythonInputReaderManager::InputReaderCallback break; case eInputReaderReactivate: - { - ScriptInterpreterPython::Locker locker(script_interpreter, - ScriptInterpreterPython::Locker::AcquireLock | ScriptInterpreterPython::Locker::InitSession, - ScriptInterpreterPython::Locker::FreeAcquiredLock); - } +// { +// ScriptInterpreterPython::Locker locker(script_interpreter, +// ScriptInterpreterPython::Locker::AcquireLock | ScriptInterpreterPython::Locker::InitSession, +// ScriptInterpreterPython::Locker::FreeAcquiredLock); +// } break; case eInputReaderAsynchronousOutputWritten: |