summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lldb/include/lldb/Core/Debugger.h6
-rw-r--r--lldb/include/lldb/Interpreter/Args.h19
-rw-r--r--lldb/include/lldb/Interpreter/OptionValueProperties.h5
-rw-r--r--lldb/include/lldb/Interpreter/OptionValueString.h28
-rw-r--r--lldb/source/Core/Debugger.cpp23
-rw-r--r--lldb/source/Interpreter/Args.cpp134
-rw-r--r--lldb/source/Interpreter/CommandReturnObject.cpp7
-rw-r--r--lldb/source/Interpreter/OptionValueProperties.cpp10
-rw-r--r--lldb/source/Interpreter/OptionValueString.cpp39
-rw-r--r--lldb/source/Interpreter/Property.cpp9
-rw-r--r--lldb/source/Interpreter/ScriptInterpreterPython.cpp10
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:
OpenPOWER on IntegriCloud