diff options
Diffstat (limited to 'lldb')
-rw-r--r-- | lldb/include/lldb/Interpreter/CommandInterpreter.h | 3 | ||||
-rw-r--r-- | lldb/include/lldb/Utility/AnsiTerminal.h | 86 | ||||
-rw-r--r-- | lldb/include/lldb/Utility/SharedCluster.h | 2 | ||||
-rw-r--r-- | lldb/lldb.xcodeproj/project.pbxproj | 4 | ||||
-rw-r--r-- | lldb/lldb.xcodeproj/xcshareddata/xcschemes/lldb-tool.xcscheme | 2 | ||||
-rw-r--r-- | lldb/source/Core/Debugger.cpp | 210 | ||||
-rw-r--r-- | lldb/source/Interpreter/CommandInterpreter.cpp | 121 |
7 files changed, 425 insertions, 3 deletions
diff --git a/lldb/include/lldb/Interpreter/CommandInterpreter.h b/lldb/include/lldb/Interpreter/CommandInterpreter.h index 5930f2192b0..2473813a81a 100644 --- a/lldb/include/lldb/Interpreter/CommandInterpreter.h +++ b/lldb/include/lldb/Interpreter/CommandInterpreter.h @@ -455,6 +455,9 @@ protected: GetCommandSP (const char *cmd, bool include_aliases = true, bool exact = true, StringList *matches = NULL); private: + + Error + PreprocessCommand (std::string &command); Debugger &m_debugger; // The debugger session that this interpreter is associated with ExecutionContext m_exe_ctx; // The current execution context to use when handling commands diff --git a/lldb/include/lldb/Utility/AnsiTerminal.h b/lldb/include/lldb/Utility/AnsiTerminal.h new file mode 100644 index 00000000000..cf0d9f0ecf7 --- /dev/null +++ b/lldb/include/lldb/Utility/AnsiTerminal.h @@ -0,0 +1,86 @@ +//===---------------------AnsiTerminal.h ------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + + + +#define ANSI_FG_COLOR_BLACK 30 +#define ANSI_FG_COLOR_RED 31 +#define ANSI_FG_COLOR_GREEN 32 +#define ANSI_FG_COLOR_YELLOW 33 +#define ANSI_FG_COLOR_BLUE 34 +#define ANSI_FG_COLOR_PURPLE 35 +#define ANSI_FG_COLOR_CYAN 36 +#define ANSI_FG_COLOR_WHITE 37 + +#define ANSI_BG_COLOR_BLACK 40 +#define ANSI_BG_COLOR_RED 41 +#define ANSI_BG_COLOR_GREEN 42 +#define ANSI_BG_COLOR_YELLOW 44 +#define ANSI_BG_COLOR_BLUE 44 +#define ANSI_BG_COLOR_PURPLE 45 +#define ANSI_BG_COLOR_CYAN 46 +#define ANSI_BG_COLOR_WHITE 47 + +#define ANSI_SPECIAL_FRAMED 51 +#define ANSI_SPECIAL_ENCIRCLED 52 + +#define ANSI_CTRL_NORMAL 0 +#define ANSI_CTRL_BOLD 1 +#define ANSI_CTRL_FAINT 2 +#define ANSI_CTRL_ITALIC 3 +#define ANSI_CTRL_UNDERLINE 4 +#define ANSI_CTRL_SLOW_BLINK 5 +#define ANSI_CTRL_FAST_BLINK 6 +#define ANSI_CTRL_IMAGE_NEGATIVE 7 +#define ANSI_CTRL_CONCEAL 8 +#define ANSI_CTRL_CROSSED_OUT 9 + +#define ANSI_ESC_START "\033[" +#define ANSI_ESC_END "m" + +#define ANSI_1_CTRL(ctrl1) "\033["##ctrl1 ANSI_ESC_END +#define ANSI_2_CTRL(ctrl1,ctrl2) "\033["##ctrl1";"##ctrl2 ANSI_ESC_END + +namespace lldb_utility { + + namespace ansi { + const char *k_escape_start = "\033["; + const char *k_escape_end = "m"; + + const char *k_fg_black = "30"; + const char *k_fg_red = "31"; + const char *k_fg_green = "32"; + const char *k_fg_yellow = "33"; + const char *k_fg_blue = "34"; + const char *k_fg_purple = "35"; + const char *k_fg_cyan = "36"; + const char *k_fg_white = "37"; + + const char *k_bg_black = "40"; + const char *k_bg_red = "41"; + const char *k_bg_green = "42"; + const char *k_bg_yellow = "43"; + const char *k_bg_blue = "44"; + const char *k_bg_purple = "45"; + const char *k_bg_cyan = "46"; + const char *k_bg_white = "47"; + + const char *k_ctrl_normal = "0"; + const char *k_ctrl_bold = "1"; + const char *k_ctrl_faint = "2"; + const char *k_ctrl_italic = "3"; + const char *k_ctrl_underline = "4"; + const char *k_ctrl_slow_blink = "5"; + const char *k_ctrl_fast_blink = "6"; + const char *k_ctrl_negative = "7"; + const char *k_ctrl_conceal = "8"; + const char *k_ctrl_crossed_out = "9"; + + } +} diff --git a/lldb/include/lldb/Utility/SharedCluster.h b/lldb/include/lldb/Utility/SharedCluster.h index 75e360d7aa0..735f0c7ae97 100644 --- a/lldb/include/lldb/Utility/SharedCluster.h +++ b/lldb/include/lldb/Utility/SharedCluster.h @@ -1,4 +1,4 @@ -//===---------------------SharedCluster.h --------------------------*- C++ -*-===// +//===------------------SharedCluster.h --------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // diff --git a/lldb/lldb.xcodeproj/project.pbxproj b/lldb/lldb.xcodeproj/project.pbxproj index 66bfbf297c2..666ee999feb 100644 --- a/lldb/lldb.xcodeproj/project.pbxproj +++ b/lldb/lldb.xcodeproj/project.pbxproj @@ -358,6 +358,7 @@ 26BD407F135D2AE000237D80 /* FileLineResolver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BD407E135D2ADF00237D80 /* FileLineResolver.cpp */; }; 26C72C94124322890068DC16 /* SBStream.h in Headers */ = {isa = PBXBuildFile; fileRef = 26C72C93124322890068DC16 /* SBStream.h */; settings = {ATTRIBUTES = (Public, ); }; }; 26C72C961243229A0068DC16 /* SBStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C72C951243229A0068DC16 /* SBStream.cpp */; }; + 26CF992514428766001E4138 /* AnsiTerminal.h in Headers */ = {isa = PBXBuildFile; fileRef = 26CF992414428766001E4138 /* AnsiTerminal.h */; }; 26D265A2136B40EE002EEE45 /* SharingPtr.h in Headers */ = {isa = PBXBuildFile; fileRef = 261B5A5311C3F2AD00AABD0A /* SharingPtr.h */; settings = {ATTRIBUTES = (Public, ); }; }; 26D265BC136B4269002EEE45 /* lldb-public.h in Headers */ = {isa = PBXBuildFile; fileRef = 26651A14133BEC76005B64B7 /* lldb-public.h */; settings = {ATTRIBUTES = (Public, ); }; }; 26D5E15F135BAEA2006EA0A7 /* OptionGroupArchitecture.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26D5E15E135BAEA2006EA0A7 /* OptionGroupArchitecture.cpp */; }; @@ -1067,6 +1068,7 @@ 26C72C951243229A0068DC16 /* SBStream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SBStream.cpp; path = source/API/SBStream.cpp; sourceTree = "<group>"; }; 26C81CA411335651004BDC5A /* UUID.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = UUID.h; path = include/lldb/Core/UUID.h; sourceTree = "<group>"; }; 26C81CA511335651004BDC5A /* UUID.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = UUID.cpp; path = source/Core/UUID.cpp; sourceTree = "<group>"; }; + 26CF992414428766001E4138 /* AnsiTerminal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AnsiTerminal.h; path = include/lldb/Utility/AnsiTerminal.h; sourceTree = "<group>"; }; 26D0DD5010FE554D00271C65 /* BreakpointResolverAddress.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BreakpointResolverAddress.h; path = include/lldb/Breakpoint/BreakpointResolverAddress.h; sourceTree = "<group>"; }; 26D0DD5110FE554D00271C65 /* BreakpointResolverFileLine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BreakpointResolverFileLine.h; path = include/lldb/Breakpoint/BreakpointResolverFileLine.h; sourceTree = "<group>"; }; 26D0DD5210FE554D00271C65 /* BreakpointResolverName.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BreakpointResolverName.h; path = include/lldb/Breakpoint/BreakpointResolverName.h; sourceTree = "<group>"; }; @@ -1943,6 +1945,7 @@ 2682F168115ED9C800CCFF99 /* Utility */ = { isa = PBXGroup; children = ( + 26CF992414428766001E4138 /* AnsiTerminal.h */, 264723A511FA076E00DE380C /* CleanUp.h */, 94611EAF13CCA363003A22AF /* RefCounter.h */, 94611EB113CCA4A4003A22AF /* RefCounter.cpp */, @@ -2893,6 +2896,7 @@ 496B015B1406DEB100F830D5 /* IRInterpreter.h in Headers */, 2682100D143A59AE004BCF2D /* MappedHash.h in Headers */, 2626B6AE143E1BEA00EF935C /* RangeMap.h in Headers */, + 26CF992514428766001E4138 /* AnsiTerminal.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/lldb/lldb.xcodeproj/xcshareddata/xcschemes/lldb-tool.xcscheme b/lldb/lldb.xcodeproj/xcshareddata/xcschemes/lldb-tool.xcscheme index 38703790882..6e12c06c956 100644 --- a/lldb/lldb.xcodeproj/xcshareddata/xcschemes/lldb-tool.xcscheme +++ b/lldb/lldb.xcodeproj/xcshareddata/xcschemes/lldb-tool.xcscheme @@ -86,7 +86,7 @@ launchStyle = "0" useCustomWorkingDirectory = "NO" customWorkingDirectory = "/Volumes/work/gclayton/Documents/devb/attach" - buildConfiguration = "Release" + buildConfiguration = "Debug" ignoresPersistentStateOnLaunch = "YES" debugDocumentVersioning = "YES" allowLocationSimulation = "YES"> diff --git a/lldb/source/Core/Debugger.cpp b/lldb/source/Core/Debugger.cpp index 583c1caf0f9..c27559c3f5e 100644 --- a/lldb/source/Core/Debugger.cpp +++ b/lldb/source/Core/Debugger.cpp @@ -31,7 +31,7 @@ #include "lldb/Target/RegisterContext.h" #include "lldb/Target/StopInfo.h" #include "lldb/Target/Thread.h" - +#include "lldb/Utility/AnsiTerminal.h" using namespace lldb; using namespace lldb_private; @@ -1303,6 +1303,214 @@ Debugger::FormatPrompt format_addr = *addr; } } + else if (::strncmp (var_name_begin, "ansi.", strlen("ansi.")) == 0) + { + var_success = true; + var_name_begin += strlen("ansi."); // Skip the "ansi." + if (::strncmp (var_name_begin, "fg.", strlen("fg.")) == 0) + { + var_name_begin += strlen("fg."); // Skip the "fg." + if (::strncmp (var_name_begin, "black}", strlen("black}")) == 0) + { + s.Printf ("%s%s%s", + lldb_utility::ansi::k_escape_start, + lldb_utility::ansi::k_fg_black, + lldb_utility::ansi::k_escape_end); + } + else if (::strncmp (var_name_begin, "red}", strlen("red}")) == 0) + { + s.Printf ("%s%s%s", + lldb_utility::ansi::k_escape_start, + lldb_utility::ansi::k_fg_red, + lldb_utility::ansi::k_escape_end); + } + else if (::strncmp (var_name_begin, "green}", strlen("green}")) == 0) + { + s.Printf ("%s%s%s", + lldb_utility::ansi::k_escape_start, + lldb_utility::ansi::k_fg_green, + lldb_utility::ansi::k_escape_end); + } + else if (::strncmp (var_name_begin, "yellow}", strlen("yellow}")) == 0) + { + s.Printf ("%s%s%s", + lldb_utility::ansi::k_escape_start, + lldb_utility::ansi::k_fg_yellow, + lldb_utility::ansi::k_escape_end); + } + else if (::strncmp (var_name_begin, "blue}", strlen("blue}")) == 0) + { + s.Printf ("%s%s%s", + lldb_utility::ansi::k_escape_start, + lldb_utility::ansi::k_fg_blue, + lldb_utility::ansi::k_escape_end); + } + else if (::strncmp (var_name_begin, "purple}", strlen("purple}")) == 0) + { + s.Printf ("%s%s%s", + lldb_utility::ansi::k_escape_start, + lldb_utility::ansi::k_fg_purple, + lldb_utility::ansi::k_escape_end); + } + else if (::strncmp (var_name_begin, "cyan}", strlen("cyan}")) == 0) + { + s.Printf ("%s%s%s", + lldb_utility::ansi::k_escape_start, + lldb_utility::ansi::k_fg_cyan, + lldb_utility::ansi::k_escape_end); + } + else if (::strncmp (var_name_begin, "white}", strlen("white}")) == 0) + { + s.Printf ("%s%s%s", + lldb_utility::ansi::k_escape_start, + lldb_utility::ansi::k_fg_white, + lldb_utility::ansi::k_escape_end); + } + else + { + var_success = false; + } + } + else if (::strncmp (var_name_begin, "bg.", strlen("bg.")) == 0) + { + var_name_begin += strlen("bg."); // Skip the "bg." + if (::strncmp (var_name_begin, "black}", strlen("black}")) == 0) + { + s.Printf ("%s%s%s", + lldb_utility::ansi::k_escape_start, + lldb_utility::ansi::k_bg_black, + lldb_utility::ansi::k_escape_end); + } + else if (::strncmp (var_name_begin, "red}", strlen("red}")) == 0) + { + s.Printf ("%s%s%s", + lldb_utility::ansi::k_escape_start, + lldb_utility::ansi::k_bg_red, + lldb_utility::ansi::k_escape_end); + } + else if (::strncmp (var_name_begin, "green}", strlen("green}")) == 0) + { + s.Printf ("%s%s%s", + lldb_utility::ansi::k_escape_start, + lldb_utility::ansi::k_bg_green, + lldb_utility::ansi::k_escape_end); + } + else if (::strncmp (var_name_begin, "yellow}", strlen("yellow}")) == 0) + { + s.Printf ("%s%s%s", + lldb_utility::ansi::k_escape_start, + lldb_utility::ansi::k_bg_yellow, + lldb_utility::ansi::k_escape_end); + } + else if (::strncmp (var_name_begin, "blue}", strlen("blue}")) == 0) + { + s.Printf ("%s%s%s", + lldb_utility::ansi::k_escape_start, + lldb_utility::ansi::k_bg_blue, + lldb_utility::ansi::k_escape_end); + } + else if (::strncmp (var_name_begin, "purple}", strlen("purple}")) == 0) + { + s.Printf ("%s%s%s", + lldb_utility::ansi::k_escape_start, + lldb_utility::ansi::k_bg_purple, + lldb_utility::ansi::k_escape_end); + } + else if (::strncmp (var_name_begin, "cyan}", strlen("cyan}")) == 0) + { + s.Printf ("%s%s%s", + lldb_utility::ansi::k_escape_start, + lldb_utility::ansi::k_bg_cyan, + lldb_utility::ansi::k_escape_end); + } + else if (::strncmp (var_name_begin, "white}", strlen("white}")) == 0) + { + s.Printf ("%s%s%s", + lldb_utility::ansi::k_escape_start, + lldb_utility::ansi::k_bg_white, + lldb_utility::ansi::k_escape_end); + } + else + { + var_success = false; + } + } + else if (::strncmp (var_name_begin, "normal}", strlen ("normal}")) == 0) + { + s.Printf ("%s%s%s", + lldb_utility::ansi::k_escape_start, + lldb_utility::ansi::k_ctrl_normal, + lldb_utility::ansi::k_escape_end); + } + else if (::strncmp (var_name_begin, "bold}", strlen("bold}")) == 0) + { + s.Printf ("%s%s%s", + lldb_utility::ansi::k_escape_start, + lldb_utility::ansi::k_ctrl_bold, + lldb_utility::ansi::k_escape_end); + } + else if (::strncmp (var_name_begin, "faint}", strlen("faint}")) == 0) + { + s.Printf ("%s%s%s", + lldb_utility::ansi::k_escape_start, + lldb_utility::ansi::k_ctrl_faint, + lldb_utility::ansi::k_escape_end); + } + else if (::strncmp (var_name_begin, "italic}", strlen("italic}")) == 0) + { + s.Printf ("%s%s%s", + lldb_utility::ansi::k_escape_start, + lldb_utility::ansi::k_ctrl_italic, + lldb_utility::ansi::k_escape_end); + } + else if (::strncmp (var_name_begin, "underline}", strlen("underline}")) == 0) + { + s.Printf ("%s%s%s", + lldb_utility::ansi::k_escape_start, + lldb_utility::ansi::k_ctrl_underline, + lldb_utility::ansi::k_escape_end); + } + else if (::strncmp (var_name_begin, "slow-blink}", strlen("slow-blink}")) == 0) + { + s.Printf ("%s%s%s", + lldb_utility::ansi::k_escape_start, + lldb_utility::ansi::k_ctrl_slow_blink, + lldb_utility::ansi::k_escape_end); + } + else if (::strncmp (var_name_begin, "fast-blink}", strlen("fast-blink}")) == 0) + { + s.Printf ("%s%s%s", + lldb_utility::ansi::k_escape_start, + lldb_utility::ansi::k_ctrl_fast_blink, + lldb_utility::ansi::k_escape_end); + } + else if (::strncmp (var_name_begin, "negative}", strlen("negative}")) == 0) + { + s.Printf ("%s%s%s", + lldb_utility::ansi::k_escape_start, + lldb_utility::ansi::k_ctrl_negative, + lldb_utility::ansi::k_escape_end); + } + else if (::strncmp (var_name_begin, "conceal}", strlen("conceal}")) == 0) + { + s.Printf ("%s%s%s", + lldb_utility::ansi::k_escape_start, + lldb_utility::ansi::k_ctrl_conceal, + lldb_utility::ansi::k_escape_end); + + } + else if (::strncmp (var_name_begin, "crossed-out}", strlen("crossed-out}")) == 0) + { + s.Printf ("%s%s%s", + lldb_utility::ansi::k_escape_start, + lldb_utility::ansi::k_ctrl_crossed_out, + lldb_utility::ansi::k_escape_end); + } + else + { + var_success = false; + } + } break; case 'p': diff --git a/lldb/source/Interpreter/CommandInterpreter.cpp b/lldb/source/Interpreter/CommandInterpreter.cpp index 26d3b82d4be..38c3d7e2107 100644 --- a/lldb/source/Interpreter/CommandInterpreter.cpp +++ b/lldb/source/Interpreter/CommandInterpreter.cpp @@ -947,6 +947,118 @@ CommandInterpreter::BuildAliasResult (const char *alias_name, std::string &raw_i } } +Error +CommandInterpreter::PreprocessCommand (std::string &command) +{ + // The command preprocessor needs to do things to the command + // line before any parsing of arguments or anything else is done. + // The only current stuff that gets proprocessed is anyting enclosed + // in backtick ('`') characters is evaluated as an expression and + // the result of the expression must be a scalar that can be substituted + // into the command. An example would be: + // (lldb) memory read `$rsp + 20` + Error error; // Error for any expressions that might not evaluate + size_t start_backtick; + size_t pos = 0; + while ((start_backtick = command.find ('`', pos)) != std::string::npos) + { + if (start_backtick > 0 && command[start_backtick-1] == '\\') + { + // The backtick was preceeded by a '\' character, remove the slash + // and don't treat the backtick as the start of an expression + command.erase(start_backtick-1, 1); + // No need to add one to start_backtick since we just deleted a char + pos = start_backtick; + } + else + { + const size_t expr_content_start = start_backtick + 1; + const size_t end_backtick = command.find ('`', expr_content_start); + if (end_backtick == std::string::npos) + return error; + else if (end_backtick == expr_content_start) + { + // Empty expression (two backticks in a row) + command.erase (start_backtick, 2); + } + else + { + std::string expr_str (command, expr_content_start, end_backtick - expr_content_start); + + Target *target = m_exe_ctx.GetTargetPtr(); + if (target) + { + const bool unwind_on_error = true; + const bool keep_in_memory = false; + ValueObjectSP expr_result_valobj_sp; + ExecutionResults expr_result = target->EvaluateExpression (expr_str.c_str(), + m_exe_ctx.GetFramePtr(), + eExecutionPolicyOnlyWhenNeeded, + unwind_on_error, keep_in_memory, + eNoDynamicValues, + expr_result_valobj_sp); + if (expr_result == eExecutionCompleted) + { + Scalar scalar; + if (expr_result_valobj_sp->ResolveValue (scalar)) + { + command.erase (start_backtick, end_backtick - start_backtick + 1); + StreamString value_strm; + const bool show_type = false; + scalar.GetValue (&value_strm, show_type); + size_t value_string_size = value_strm.GetSize(); + if (value_string_size) + { + command.insert (start_backtick, value_strm.GetData(), value_string_size); + pos = start_backtick + value_string_size; + continue; + } + else + { + error.SetErrorStringWithFormat("expression value didn't result in a scalar value for the expression '%s'", expr_str.c_str()); + } + } + else + { + error.SetErrorStringWithFormat("expression value didn't result in a scalar value for the expression '%s'", expr_str.c_str()); + } + } + else + { + if (expr_result_valobj_sp) + error = expr_result_valobj_sp->GetError(); + if (error.Success()) + { + + switch (expr_result) + { + case eExecutionSetupError: + error.SetErrorStringWithFormat("expression setup error for the expression '%s'", expr_str.c_str()); + break; + case eExecutionCompleted: + break; + case eExecutionDiscarded: + error.SetErrorStringWithFormat("expression discarded for the expression '%s'", expr_str.c_str()); + break; + case eExecutionInterrupted: + error.SetErrorStringWithFormat("expression interrupted for the expression '%s'", expr_str.c_str()); + break; + case eExecutionTimedOut: + error.SetErrorStringWithFormat("expression timed out for the expression '%s'", expr_str.c_str()); + break; + } + } + } + } + } + if (error.Fail()) + break; + } + } + return error; +} + + bool CommandInterpreter::HandleCommand (const char *command_line, bool add_to_history, @@ -1045,6 +1157,15 @@ CommandInterpreter::HandleCommand (const char *command_line, return true; } + + Error error (PreprocessCommand (command_string)); + + if (error.Fail()) + { + result.AppendError (error.AsCString()); + result.SetStatus(eReturnStatusFailed); + return false; + } // Phase 1. // Before we do ANY kind of argument processing, etc. we need to figure out what the real/final command object |