aboutsummaryrefslogtreecommitdiff
path: root/source/Interpreter
diff options
context:
space:
mode:
Diffstat (limited to 'source/Interpreter')
-rw-r--r--source/Interpreter/Args.cpp385
-rw-r--r--source/Interpreter/CommandInterpreter.cpp475
-rw-r--r--source/Interpreter/CommandObject.cpp70
-rw-r--r--source/Interpreter/CommandObjectRegexCommand.cpp2
-rw-r--r--source/Interpreter/CommandObjectScript.cpp2
-rw-r--r--source/Interpreter/OptionGroupBoolean.cpp2
-rw-r--r--source/Interpreter/OptionGroupFile.cpp4
-rw-r--r--source/Interpreter/OptionGroupFormat.cpp8
-rw-r--r--source/Interpreter/OptionGroupOutputFile.cpp4
-rw-r--r--source/Interpreter/OptionGroupPlatform.cpp2
-rw-r--r--source/Interpreter/OptionGroupString.cpp2
-rw-r--r--source/Interpreter/OptionGroupUInt64.cpp2
-rw-r--r--source/Interpreter/OptionGroupUUID.cpp2
-rw-r--r--source/Interpreter/OptionGroupValueObjectDisplay.cpp2
-rw-r--r--source/Interpreter/OptionGroupVariable.cpp2
-rw-r--r--source/Interpreter/OptionGroupWatchpoint.cpp4
-rw-r--r--source/Interpreter/OptionValue.cpp43
-rw-r--r--source/Interpreter/OptionValueArch.cpp19
-rw-r--r--source/Interpreter/OptionValueArray.cpp12
-rw-r--r--source/Interpreter/OptionValueBoolean.cpp13
-rw-r--r--source/Interpreter/OptionValueChar.cpp8
-rw-r--r--source/Interpreter/OptionValueDictionary.cpp22
-rw-r--r--source/Interpreter/OptionValueEnumeration.cpp15
-rw-r--r--source/Interpreter/OptionValueFileSpec.cpp46
-rw-r--r--source/Interpreter/OptionValueFileSpecLIst.cpp6
-rw-r--r--source/Interpreter/OptionValueFormat.cpp8
-rw-r--r--source/Interpreter/OptionValueFormatEntity.cpp30
-rw-r--r--source/Interpreter/OptionValueLanguage.cpp73
-rw-r--r--source/Interpreter/OptionValuePathMappings.cpp6
-rw-r--r--source/Interpreter/OptionValueProperties.cpp6
-rw-r--r--source/Interpreter/OptionValueRegex.cpp6
-rw-r--r--source/Interpreter/OptionValueSInt64.cpp11
-rw-r--r--source/Interpreter/OptionValueString.cpp32
-rw-r--r--source/Interpreter/OptionValueUInt64.cpp11
-rw-r--r--source/Interpreter/OptionValueUUID.cpp10
-rw-r--r--source/Interpreter/Options.cpp4
-rw-r--r--source/Interpreter/Property.cpp27
-rw-r--r--source/Interpreter/PythonDataObjects.cpp143
-rw-r--r--source/Interpreter/ScriptInterpreter.cpp57
-rw-r--r--source/Interpreter/ScriptInterpreterNone.cpp2
-rw-r--r--source/Interpreter/ScriptInterpreterPython.cpp864
41 files changed, 1436 insertions, 1006 deletions
diff --git a/source/Interpreter/Args.cpp b/source/Interpreter/Args.cpp
index 4f0219fb858b..2258c26e6c39 100644
--- a/source/Interpreter/Args.cpp
+++ b/source/Interpreter/Args.cpp
@@ -7,8 +7,6 @@
//
//===----------------------------------------------------------------------===//
-#include "lldb/lldb-python.h"
-
// C Includes
#include <cstdlib>
// C++ Includes
@@ -33,25 +31,15 @@ using namespace lldb_private;
//----------------------------------------------------------------------
// Args constructor
//----------------------------------------------------------------------
-Args::Args (const char *command) :
+Args::Args (llvm::StringRef command) :
m_args(),
m_argv(),
m_args_quote_char()
{
- if (command)
- SetCommandString (command);
+ SetCommandString (command);
}
-Args::Args (const char *command, size_t len) :
- m_args(),
- m_argv(),
- m_args_quote_char()
-{
- if (command && len)
- SetCommandString (command, len);
-}
-
//----------------------------------------------------------------------
// We have to be very careful on the copy constructor of this class
// to make sure we copy all of the string values, but we can't copy the
@@ -146,214 +134,158 @@ Args::GetQuotedCommandString (std::string &command) const
return argc > 0;
}
-void
-Args::SetCommandString (const char *command, size_t len)
+// A helper function for argument parsing.
+// Parses the initial part of the first argument using normal double quote rules:
+// backslash escapes the double quote and itself. The parsed string is appended to the second
+// argument. The function returns the unparsed portion of the string, starting at the closing
+// quote.
+static llvm::StringRef
+ParseDoubleQuotes(llvm::StringRef quoted, std::string &result)
{
- // Use std::string to make sure we get a NULL terminated string we can use
- // as "command" could point to a string within a large string....
- std::string null_terminated_command(command, len);
- SetCommandString(null_terminated_command.c_str());
+ // Inside double quotes, '\' and '"' are special.
+ static const char *k_escapable_characters = "\"\\";
+ while (true)
+ {
+ // Skip over over regular characters and append them.
+ size_t regular = quoted.find_first_of(k_escapable_characters);
+ result += quoted.substr(0, regular);
+ quoted = quoted.substr(regular);
+
+ // If we have reached the end of string or the closing quote, we're done.
+ if (quoted.empty() || quoted.front() == '"')
+ break;
+
+ // We have found a backslash.
+ quoted = quoted.drop_front();
+
+ if (quoted.empty())
+ {
+ // A lone backslash at the end of string, let's just append it.
+ result += '\\';
+ break;
+ }
+
+ // If the character after the backslash is not a whitelisted escapable character, we
+ // leave the character sequence untouched.
+ if (strchr(k_escapable_characters, quoted.front()) == nullptr)
+ result += '\\';
+
+ result += quoted.front();
+ quoted = quoted.drop_front();
+ }
+
+ return quoted;
}
-void
-Args::SetCommandString (const char *command)
+// A helper function for SetCommandString.
+// Parses a single argument from the command string, processing quotes and backslashes in a
+// shell-like manner. The parsed argument is appended to the m_args array. The function returns
+// the unparsed portion of the string, starting at the first unqouted, unescaped whitespace
+// character.
+llvm::StringRef
+Args::ParseSingleArgument(llvm::StringRef command)
{
- m_args.clear();
- m_argv.clear();
- m_args_quote_char.clear();
-
- if (command && command[0])
+ // Argument can be split into multiple discontiguous pieces,
+ // for example:
+ // "Hello ""World"
+ // this would result in a single argument "Hello World" (without/
+ // the quotes) since the quotes would be removed and there is
+ // not space between the strings.
+
+ std::string arg;
+
+ // Since we can have multiple quotes that form a single command
+ // in a command like: "Hello "world'!' (which will make a single
+ // argument "Hello world!") we remember the first quote character
+ // we encounter and use that for the quote character.
+ char first_quote_char = '\0';
+
+ bool arg_complete = false;
+ do
{
- static const char *k_space_separators = " \t";
- static const char *k_escapable_characters = " \t\\'\"";
- const char *arg_end = nullptr;
- const char *arg_pos;
- for (arg_pos = command;
- arg_pos && arg_pos[0];
- arg_pos = arg_end)
+ // Skip over over regular characters and append them.
+ size_t regular = command.find_first_of(" \t\"'`\\");
+ arg += command.substr(0, regular);
+ command = command.substr(regular);
+
+ if (command.empty())
+ break;
+
+ char special = command.front();
+ command = command.drop_front();
+ switch (special)
{
- // Skip any leading space separators
- const char *arg_start = ::strspn (arg_pos, k_space_separators) + arg_pos;
-
- // If there were only space separators to the end of the line, then
- // we're done.
- if (*arg_start == '\0')
+ case '\\':
+ if (command.empty())
+ {
+ arg += '\\';
break;
+ }
- // Arguments can be split into multiple discontiguous pieces,
- // for example:
- // "Hello ""World"
- // this would result in a single argument "Hello World" (without/
- // the quotes) since the quotes would be removed and there is
- // not space between the strings. So we need to keep track of the
- // current start of each argument piece in "arg_piece_start"
- const char *arg_piece_start = arg_start;
- arg_pos = arg_piece_start;
-
- std::string arg;
- // Since we can have multiple quotes that form a single command
- // in a command like: "Hello "world'!' (which will make a single
- // argument "Hello world!") we remember the first quote character
- // we encounter and use that for the quote character.
- char first_quote_char = '\0';
- char quote_char = '\0';
- bool arg_complete = false;
-
- do
- {
- arg_end = ::strcspn (arg_pos, k_escapable_characters) + arg_pos;
+ // If the character after the backslash is not a whitelisted escapable character, we
+ // leave the character sequence untouched.
+ if (strchr(" \t\\'\"`", command.front()) == nullptr)
+ arg += '\\';
- switch (arg_end[0])
- {
- default:
- assert (!"Unhandled case statement, we must handle this...");
- break;
+ arg += command.front();
+ command = command.drop_front();
- case '\0':
- // End of C string
- if (arg_piece_start && arg_piece_start[0])
- arg.append (arg_piece_start);
- 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:
- // Only consider this two-character sequence an escape sequence if we're unquoted and
- // the character after the backslash is a whitelisted escapable character. Otherwise
- // leave the character sequence untouched.
- if (quote_char == '\0' && (nullptr != strchr(k_escapable_characters, arg_end[1])))
- {
- arg.append (arg_piece_start, arg_end - arg_piece_start);
- 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 '`':
- // Quote characters
- if (quote_char)
- {
- // We found a quote character while inside a quoted
- // character argument. If it matches our current quote
- // character, this ends the effect of the quotes. If it
- // doesn't we ignore it.
- if (quote_char == arg_end[0])
- {
- arg.append (arg_piece_start, arg_end - arg_piece_start);
- // Clear the quote character and let parsing
- // continue (we need to watch for things like:
- // "Hello ""World"
- // "Hello "World
- // "Hello "'World'
- // All of which will result in a single argument "Hello World"
- quote_char = '\0'; // Note that we are no longer inside quotes
- arg_pos = arg_end + 1; // Skip the quote character
- arg_piece_start = arg_pos; // Note we are starting from later in the string
- }
- else
- {
- // different quote, skip it and keep going
- arg_pos = arg_end + 1;
- }
- }
- else
- {
- // We found the start of a quote scope.
- // Make sure there isn't a string that precedes
- // the start of a quote scope like:
- // Hello" World"
- // If so, then add the "Hello" to the arg
- if (arg_end > arg_piece_start)
- arg.append (arg_piece_start, arg_end - arg_piece_start);
-
- // Enter into a quote scope
- quote_char = arg_end[0];
-
- if (first_quote_char == '\0')
- first_quote_char = quote_char;
+ break;
- arg_pos = arg_end;
- ++arg_pos; // Skip the quote character
- arg_piece_start = arg_pos; // Note we are starting from later in the string
-
- // Skip till the next quote character
- const char *end_quote = ::strchr (arg_piece_start, quote_char);
- while (end_quote && end_quote[-1] == '\\')
- {
- // Don't skip the quote character if it is
- // preceded by a '\' character
- end_quote = ::strchr (end_quote + 1, quote_char);
- }
-
- if (end_quote)
- {
- if (end_quote > arg_piece_start)
- arg.append (arg_piece_start, end_quote - arg_piece_start);
+ case ' ':
+ case '\t':
+ // We are not inside any quotes, we just found a space after an
+ // argument. We are done.
+ arg_complete = true;
+ break;
- // If the next character is a space or the end of
- // string, this argument is complete...
- if (end_quote[1] == ' ' || end_quote[1] == '\t' || end_quote[1] == '\0')
- {
- arg_complete = true;
- arg_end = end_quote + 1;
- }
- else
- {
- arg_pos = end_quote + 1;
- arg_piece_start = arg_pos;
- }
- quote_char = '\0';
- }
- else
- {
- // Consume the rest of the string as there was no terminating quote
- arg.append(arg_piece_start);
- arg_end = arg_piece_start + strlen(arg_piece_start);
- arg_complete = true;
- }
- }
- break;
+ case '"':
+ case '\'':
+ case '`':
+ // We found the start of a quote scope.
+ if (first_quote_char == '\0')
+ first_quote_char = special;
- case ' ':
- case '\t':
- if (quote_char)
- {
- // We are currently processing a quoted character and found
- // a space character, skip any spaces and keep trying to find
- // the end of the argument.
- arg_pos = ::strspn (arg_end, k_space_separators) + arg_end;
- }
- else
- {
- // We are not inside any quotes, we just found a space after an
- // argument
- if (arg_end > arg_piece_start)
- arg.append (arg_piece_start, arg_end - arg_piece_start);
- arg_complete = true;
- }
- break;
- }
- } while (!arg_complete);
+ if (special == '"')
+ command = ParseDoubleQuotes(command, arg);
+ else
+ {
+ // For single quotes, we simply skip ahead to the matching quote character
+ // (or the end of the string).
+ size_t quoted = command.find(special);
+ arg += command.substr(0, quoted);
+ command = command.substr(quoted);
+ }
- m_args.push_back(arg);
- m_args_quote_char.push_back (first_quote_char);
+ // If we found a closing quote, skip it.
+ if (! command.empty())
+ command = command.drop_front();
+
+ break;
}
- UpdateArgvFromArgs();
+ } while (!arg_complete);
+
+ m_args.push_back(arg);
+ m_args_quote_char.push_back (first_quote_char);
+ return command;
+}
+
+void
+Args::SetCommandString (llvm::StringRef command)
+{
+ m_args.clear();
+ m_argv.clear();
+ m_args_quote_char.clear();
+
+ static const char *k_space_separators = " \t";
+ command = command.ltrim(k_space_separators);
+ while (!command.empty())
+ {
+ command = ParseSingleArgument(command);
+ command = command.ltrim(k_space_separators);
}
+
+ UpdateArgvFromArgs();
}
void
@@ -478,7 +410,8 @@ Args::AppendArguments (const Args &rhs)
{
const size_t rhs_argc = rhs.GetArgumentCount();
for (size_t i=0; i<rhs_argc; ++i)
- AppendArgument(rhs.GetArgumentAtIndex(i));
+ AppendArgument(rhs.GetArgumentAtIndex(i),
+ rhs.GetArgumentQuoteCharAtIndex(i));
}
void
@@ -870,26 +803,24 @@ Args::StripSpaces (std::string &s, bool leading, bool trailing, bool return_null
bool
Args::StringToBoolean (const char *s, bool fail_value, bool *success_ptr)
{
- if (s && s[0])
+ llvm::StringRef ref = llvm::StringRef(s).trim();
+ if (ref.equals_lower("false") ||
+ ref.equals_lower("off") ||
+ ref.equals_lower("no") ||
+ ref.equals_lower("0"))
{
- if (::strcasecmp (s, "false") == 0 ||
- ::strcasecmp (s, "off") == 0 ||
- ::strcasecmp (s, "no") == 0 ||
- ::strcmp (s, "0") == 0)
- {
- if (success_ptr)
- *success_ptr = true;
- return false;
- }
- else
- if (::strcasecmp (s, "true") == 0 ||
- ::strcasecmp (s, "on") == 0 ||
- ::strcasecmp (s, "yes") == 0 ||
- ::strcmp (s, "1") == 0)
- {
- if (success_ptr) *success_ptr = true;
- return true;
- }
+ if (success_ptr)
+ *success_ptr = true;
+ return false;
+ }
+ else
+ if (ref.equals_lower("true") ||
+ ref.equals_lower("on") ||
+ ref.equals_lower("yes") ||
+ ref.equals_lower("1"))
+ {
+ if (success_ptr) *success_ptr = true;
+ return true;
}
if (success_ptr) *success_ptr = false;
return fail_value;
@@ -1205,7 +1136,7 @@ Args::IsPositionalArgument (const char *arg)
return false;
bool is_positional = true;
- char *cptr = (char *) arg;
+ const char *cptr = arg;
if (cptr[0] == '%')
{
diff --git a/source/Interpreter/CommandInterpreter.cpp b/source/Interpreter/CommandInterpreter.cpp
index 6318b80a29ed..1da541b8c00f 100644
--- a/source/Interpreter/CommandInterpreter.cpp
+++ b/source/Interpreter/CommandInterpreter.cpp
@@ -7,8 +7,6 @@
//
//===----------------------------------------------------------------------===//
-#include "lldb/lldb-python.h"
-
#include <string>
#include <vector>
#include <stdlib.h>
@@ -19,6 +17,7 @@
#include "../Commands/CommandObjectApropos.h"
#include "../Commands/CommandObjectArgs.h"
#include "../Commands/CommandObjectBreakpoint.h"
+#include "../Commands/CommandObjectBugreport.h"
#include "../Commands/CommandObjectDisassemble.h"
#include "../Commands/CommandObjectExpression.h"
#include "../Commands/CommandObjectFrame.h"
@@ -40,6 +39,7 @@
#include "../Commands/CommandObjectType.h"
#include "../Commands/CommandObjectVersion.h"
#include "../Commands/CommandObjectWatchpoint.h"
+#include "../Commands/CommandObjectLanguage.h"
#include "lldb/Core/Debugger.h"
@@ -60,6 +60,8 @@
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Interpreter/Options.h"
+#include "lldb/Interpreter/OptionValueProperties.h"
+#include "lldb/Interpreter/Property.h"
#include "lldb/Interpreter/ScriptInterpreterNone.h"
#include "lldb/Interpreter/ScriptInterpreterPython.h"
@@ -77,6 +79,7 @@
using namespace lldb;
using namespace lldb_private;
+static const char *k_white_space = " \t\v";
static PropertyDefinition
g_properties[] =
@@ -107,7 +110,7 @@ CommandInterpreter::CommandInterpreter
ScriptLanguage script_language,
bool synchronous_execution
) :
- Broadcaster (&debugger, "lldb.command-interpreter"),
+ Broadcaster (&debugger, CommandInterpreter::GetStaticBroadcasterClass().AsCString()),
Properties(OptionValuePropertiesSP(new OptionValueProperties(ConstString("interpreter")))),
IOHandlerDelegate (IOHandlerDelegate::Completion::LLDBCommand),
m_debugger (debugger),
@@ -147,6 +150,24 @@ CommandInterpreter::GetPromptOnQuit () const
return m_collection_sp->GetPropertyAtIndexAsBoolean (nullptr, idx, g_properties[idx].default_uint_value != 0);
}
+void
+CommandInterpreter::SetPromptOnQuit (bool b)
+{
+ const uint32_t idx = ePropertyPromptOnQuit;
+ m_collection_sp->SetPropertyAtIndexAsBoolean (nullptr, idx, b);
+}
+
+void
+CommandInterpreter::ResolveCommand(const char *command_line, CommandReturnObject &result)
+{
+ std::string command = command_line;
+ if (ResolveCommandImpl(command, result) != nullptr) {
+ result.AppendMessageWithFormat("%s", command.c_str());
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ }
+}
+
+
bool
CommandInterpreter::GetStopCmdSourceOnError () const
{
@@ -401,6 +422,7 @@ CommandInterpreter::LoadCommandDictionary ()
m_command_dict["apropos"] = CommandObjectSP (new CommandObjectApropos (*this));
m_command_dict["breakpoint"]= CommandObjectSP (new CommandObjectMultiwordBreakpoint (*this));
+ m_command_dict["bugreport"] = CommandObjectSP (new CommandObjectMultiwordBugreport (*this));
m_command_dict["command"] = CommandObjectSP (new CommandObjectMultiwordCommands (*this));
m_command_dict["disassemble"] = CommandObjectSP (new CommandObjectDisassemble (*this));
m_command_dict["expression"]= CommandObjectSP (new CommandObjectExpression (*this));
@@ -422,6 +444,7 @@ CommandInterpreter::LoadCommandDictionary ()
m_command_dict["type"] = CommandObjectSP (new CommandObjectType (*this));
m_command_dict["version"] = CommandObjectSP (new CommandObjectVersion (*this));
m_command_dict["watchpoint"]= CommandObjectSP (new CommandObjectMultiwordWatchpoint (*this));
+ m_command_dict["language"] = CommandObjectSP (new CommandObjectLanguage(*this));
const char *break_regexes[][2] = {{"^(.*[^[:space:]])[[:space:]]*:[[:space:]]*([[:digit:]]+)[[:space:]]*$", "breakpoint set --file '%1' --line %2"},
{"^/([^/]+)/$", "breakpoint set --source-pattern-regexp '%1'"},
@@ -438,8 +461,14 @@ CommandInterpreter::LoadCommandDictionary ()
std::unique_ptr<CommandObjectRegexCommand>
break_regex_cmd_ap(new CommandObjectRegexCommand (*this,
"_regexp-break",
- "Set a breakpoint using a regular expression to specify the location, where <linenum> is in decimal and <address> is in hex.",
- "_regexp-break [<filename>:<linenum>]\n_regexp-break [<linenum>]\n_regexp-break [<address>]\n_regexp-break <...>",
+ "Set a breakpoint using a regular expression to specify the location, where <linenum> is in decimal and <address> is in hex.\n",
+ "\n_regexp-break <filename>:<linenum> # _regexp-break main.c:12 // Break on line 12 of main.c\n"
+ "_regexp-break <linenum> # _regexp-break 12 // Break on line 12 of current file\n"
+ "_regexp-break <address> # _regexp-break 0x1234000 // Break on address 0x1234000\n"
+ "_regexp-break <name> # _regexp-break main // Break in 'main' after the prologue\n"
+ "_regexp-break &<name> # _regexp-break &main // Break on the first instruction in 'main'\n"
+ "_regexp-break <module>`<name> # _regexp-break libc.so`malloc // Break in 'malloc' only in the 'libc.so' shared library\n"
+ "_regexp-break /<source-regex>/ # _regexp-break /break here/ // Break on all lines that match the regular expression 'break here' in the current file.\n",
2,
CommandCompletions::eSymbolCompletion |
CommandCompletions::eSourceFileCompletion,
@@ -1243,8 +1272,7 @@ CommandInterpreter::GetCommandObjectForCommand (std::string &command_string)
// eventually be invoked by the given command line.
CommandObject *cmd_obj = nullptr;
- std::string white_space (" \t\v");
- size_t start = command_string.find_first_not_of (white_space);
+ size_t start = command_string.find_first_not_of (k_white_space);
size_t end = 0;
bool done = false;
while (!done)
@@ -1252,7 +1280,7 @@ CommandInterpreter::GetCommandObjectForCommand (std::string &command_string)
if (start != std::string::npos)
{
// Get the next word from command_string.
- end = command_string.find_first_of (white_space, start);
+ end = command_string.find_first_of (k_white_space, start);
if (end == std::string::npos)
end = command_string.size();
std::string cmd_word = command_string.substr (start, end - start);
@@ -1267,7 +1295,7 @@ CommandInterpreter::GetCommandObjectForCommand (std::string &command_string)
CommandObject *sub_cmd_obj = cmd_obj->GetSubcommandObject (cmd_word.c_str());
if (sub_cmd_obj)
cmd_obj = sub_cmd_obj;
- else // cmd_word was not a valid sub-command word, so we are donee
+ else // cmd_word was not a valid sub-command word, so we are done
done = true;
}
else
@@ -1281,7 +1309,7 @@ CommandInterpreter::GetCommandObjectForCommand (std::string &command_string)
if (!cmd_obj || !cmd_obj->IsMultiwordObject() || end >= command_string.size())
done = true;
else
- start = command_string.find_first_not_of (white_space, end);
+ start = command_string.find_first_not_of (k_white_space, end);
}
else
// Unable to find any more words.
@@ -1296,7 +1324,6 @@ CommandInterpreter::GetCommandObjectForCommand (std::string &command_string)
return cmd_obj;
}
-static const char *k_white_space = " \t\v";
static const char *k_valid_command_chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_";
static void
StripLeadingSpaces (std::string &s)
@@ -1412,7 +1439,7 @@ CommandInterpreter::BuildAliasResult (const char *alias_name,
CommandReturnObject &result)
{
CommandObject *alias_cmd_obj = nullptr;
- Args cmd_args (raw_input_string.c_str());
+ Args cmd_args (raw_input_string);
alias_cmd_obj = GetCommandObject (alias_name);
StreamString result_str;
@@ -1442,10 +1469,10 @@ CommandInterpreter::BuildAliasResult (const char *alias_name,
else
{
result_str.Printf (" %s", option.c_str());
- if (value_type != OptionParser::eOptionalArgument)
- result_str.Printf (" ");
- if (value.compare ("<OptionParser::eNoArgument>") != 0)
+ if (value_type != OptionParser::eNoArgument)
{
+ if (value_type != OptionParser::eOptionalArgument)
+ result_str.Printf (" ");
int index = GetOptionArgumentPosition (value.c_str());
if (index == 0)
result_str.Printf ("%s", value.c_str());
@@ -1456,7 +1483,7 @@ CommandInterpreter::BuildAliasResult (const char *alias_name,
("Not enough arguments provided; you need at least %d arguments to use this alias.\n",
index);
result.SetStatus (eReturnStatusFailed);
- return alias_cmd_obj;
+ return nullptr;
}
else
{
@@ -1481,7 +1508,7 @@ 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
+ // The only current stuff that gets preprocessed is anything 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:
@@ -1493,7 +1520,7 @@ CommandInterpreter::PreprocessCommand (std::string &command)
{
if (start_backtick > 0 && command[start_backtick-1] == '\\')
{
- // The backtick was preceeded by a '\' character, remove the slash
+ // The backtick was preceded 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
@@ -1622,9 +1649,6 @@ CommandInterpreter::HandleCommand (const char *command_line,
{
- bool done = false;
- CommandObject *cmd_obj = nullptr;
- bool wants_raw_input = false;
std::string command_string (command_line);
std::string original_command_string (command_line);
@@ -1724,192 +1748,34 @@ CommandInterpreter::HandleCommand (const char *command_line,
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
- // is for the specified command, and whether or not it wants raw input. This gets complicated by the fact that
- // the user could have specified an alias, and in translating the alias there may also be command options and/or
- // even data (including raw text strings) that need to be found and inserted into the command line as part of
- // the translation. So this first step is plain look-up & replacement, resulting in three things: 1). the command
- // object whose Execute method will actually be called; 2). a revised command string, with all substitutions &
- // replacements taken care of; 3). whether or not the Execute function wants raw input or not.
-
- StreamString revised_command_line;
- size_t actual_cmd_name_len = 0;
- std::string next_word;
- StringList matches;
- while (!done)
- {
- char quote_char = '\0';
- std::string suffix;
- ExtractCommand (command_string, next_word, suffix, quote_char);
- if (cmd_obj == nullptr)
- {
- std::string full_name;
- if (GetAliasFullName(next_word.c_str(), full_name))
- {
- std::string alias_result;
- cmd_obj = BuildAliasResult (full_name.c_str(), command_string, alias_result, result);
- revised_command_line.Printf ("%s", alias_result.c_str());
- if (cmd_obj)
- {
- wants_raw_input = cmd_obj->WantsRawCommandString ();
- actual_cmd_name_len = strlen (cmd_obj->GetCommandName());
- }
- }
- else
- {
- cmd_obj = GetCommandObject (next_word.c_str(), &matches);
- if (cmd_obj)
- {
- actual_cmd_name_len += next_word.length();
- revised_command_line.Printf ("%s", next_word.c_str());
- wants_raw_input = cmd_obj->WantsRawCommandString ();
- }
- else
- {
- revised_command_line.Printf ("%s", next_word.c_str());
- }
- }
- }
- else
- {
- if (cmd_obj->IsMultiwordObject ())
- {
- CommandObject *sub_cmd_obj = cmd_obj->GetSubcommandObject (next_word.c_str());
- if (sub_cmd_obj)
- {
- actual_cmd_name_len += next_word.length() + 1;
- revised_command_line.Printf (" %s", next_word.c_str());
- cmd_obj = sub_cmd_obj;
- wants_raw_input = cmd_obj->WantsRawCommandString ();
- }
- else
- {
- if (quote_char)
- revised_command_line.Printf (" %c%s%s%c", quote_char, next_word.c_str(), suffix.c_str(), quote_char);
- else
- revised_command_line.Printf (" %s%s", next_word.c_str(), suffix.c_str());
- done = true;
- }
- }
- else
- {
- if (quote_char)
- revised_command_line.Printf (" %c%s%s%c", quote_char, next_word.c_str(), suffix.c_str(), quote_char);
- else
- revised_command_line.Printf (" %s%s", next_word.c_str(), suffix.c_str());
- done = true;
- }
- }
-
- if (cmd_obj == nullptr)
- {
- const size_t num_matches = matches.GetSize();
- if (matches.GetSize() > 1) {
- StreamString error_msg;
- error_msg.Printf ("Ambiguous command '%s'. Possible matches:\n", next_word.c_str());
-
- for (uint32_t i = 0; i < num_matches; ++i) {
- error_msg.Printf ("\t%s\n", matches.GetStringAtIndex(i));
- }
- result.AppendRawError (error_msg.GetString().c_str());
- } else {
- // We didn't have only one match, otherwise we wouldn't get here.
- assert(num_matches == 0);
- result.AppendErrorWithFormat ("'%s' is not a valid command.\n", next_word.c_str());
- }
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- if (cmd_obj->IsMultiwordObject ())
- {
- if (!suffix.empty())
- {
-
- result.AppendErrorWithFormat ("command '%s' did not recognize '%s%s%s' as valid (subcommand might be invalid).\n",
- cmd_obj->GetCommandName(),
- next_word.empty() ? "" : next_word.c_str(),
- next_word.empty() ? " -- " : " ",
- suffix.c_str());
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- }
- else
- {
- // If we found a normal command, we are done
- done = true;
- if (!suffix.empty())
- {
- switch (suffix[0])
- {
- case '/':
- // GDB format suffixes
- {
- Options *command_options = cmd_obj->GetOptions();
- if (command_options && command_options->SupportsLongOption("gdb-format"))
- {
- std::string gdb_format_option ("--gdb-format=");
- gdb_format_option += (suffix.c_str() + 1);
+ // Phase 1.
- bool inserted = false;
- std::string &cmd = revised_command_line.GetString();
- size_t arg_terminator_idx = FindArgumentTerminator (cmd);
- if (arg_terminator_idx != std::string::npos)
- {
- // Insert the gdb format option before the "--" that terminates options
- gdb_format_option.append(1,' ');
- cmd.insert(arg_terminator_idx, gdb_format_option);
- inserted = true;
- }
+ // Before we do ANY kind of argument processing, we need to figure out what
+ // the real/final command object is for the specified command. This gets
+ // complicated by the fact that the user could have specified an alias, and,
+ // in translating the alias, there may also be command options and/or even
+ // data (including raw text strings) that need to be found and inserted into
+ // the command line as part of the translation. So this first step is plain
+ // look-up and replacement, resulting in:
+ // 1. the command object whose Execute method will actually be called
+ // 2. a revised command string, with all substitutions and replacements
+ // taken care of
+ // From 1 above, we can determine whether the Execute function wants raw
+ // input or not.
+
+ CommandObject *cmd_obj = ResolveCommandImpl(command_string, result);
+
+ // Although the user may have abbreviated the command, the command_string now
+ // has the command expanded to the full name. For example, if the input
+ // was "br s -n main", command_string is now "breakpoint set -n main".
- if (!inserted)
- revised_command_line.Printf (" %s", gdb_format_option.c_str());
-
- if (wants_raw_input && FindArgumentTerminator(cmd) == std::string::npos)
- revised_command_line.PutCString (" --");
- }
- else
- {
- result.AppendErrorWithFormat ("the '%s' command doesn't support the --gdb-format option\n",
- cmd_obj->GetCommandName());
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- }
- break;
-
- default:
- result.AppendErrorWithFormat ("unknown command shorthand suffix: '%s'\n",
- suffix.c_str());
- result.SetStatus (eReturnStatusFailed);
- return false;
-
- }
- }
- }
- if (command_string.length() == 0)
- done = true;
-
- }
-
- if (!command_string.empty())
- revised_command_line.Printf (" %s", command_string.c_str());
-
- // End of Phase 1.
- // At this point cmd_obj should contain the CommandObject whose Execute method will be called, if the command
- // specified was valid; revised_command_line contains the complete command line (including command name(s)),
- // fully translated with all substitutions & translations taken care of (still in raw text format); and
- // wants_raw_input specifies whether the Execute method expects raw input or not.
-
-
if (log)
{
- log->Printf ("HandleCommand, cmd_obj : '%s'", cmd_obj ? cmd_obj->GetCommandName() : "<not found>");
- log->Printf ("HandleCommand, revised_command_line: '%s'", revised_command_line.GetData());
- log->Printf ("HandleCommand, wants_raw_input:'%s'", wants_raw_input ? "True" : "False");
+ log->Printf("HandleCommand, cmd_obj : '%s'", cmd_obj ? cmd_obj->GetCommandName() : "<not found>");
+ log->Printf("HandleCommand, (revised) command_string: '%s'", command_string.c_str());
+ const bool wants_raw_input = (cmd_obj != NULL) ? cmd_obj->WantsRawCommandString() : false;
+ log->Printf("HandleCommand, wants_raw_input:'%s'", wants_raw_input ? "True" : "False");
}
// Phase 2.
@@ -1920,7 +1786,7 @@ CommandInterpreter::HandleCommand (const char *command_line,
{
if (add_to_history)
{
- Args command_args (revised_command_line.GetData());
+ Args command_args (command_string);
const char *repeat_command = cmd_obj->GetRepeatCommand(command_args, 0);
if (repeat_command != nullptr)
m_repeat_command.assign(repeat_command);
@@ -1930,18 +1796,13 @@ CommandInterpreter::HandleCommand (const char *command_line,
m_command_history.AppendString (original_command_string);
}
- command_string = revised_command_line.GetData();
- std::string command_name (cmd_obj->GetCommandName());
std::string remainder;
+ const std::size_t actual_cmd_name_len = strlen (cmd_obj->GetCommandName());
if (actual_cmd_name_len < command_string.length())
- remainder = command_string.substr (actual_cmd_name_len); // Note: 'actual_cmd_name_len' may be considerably shorter
- // than cmd_obj->GetCommandName(), because name completion
- // allows users to enter short versions of the names,
- // e.g. 'br s' for 'breakpoint set'.
+ remainder = command_string.substr (actual_cmd_name_len);
// Remove any initial spaces
- std::string white_space (" \t\v");
- size_t pos = remainder.find_first_not_of (white_space);
+ size_t pos = remainder.find_first_not_of (k_white_space);
if (pos != 0 && pos != std::string::npos)
remainder.erase(0, pos);
@@ -1953,7 +1814,7 @@ CommandInterpreter::HandleCommand (const char *command_line,
else
{
// We didn't find the first command object, so complete the first argument.
- Args command_args (revised_command_line.GetData());
+ Args command_args (command_string);
StringList matches;
int num_matches;
int cursor_index = 0;
@@ -2082,8 +1943,8 @@ CommandInterpreter::HandleCompletion (const char *current_line,
// We parse the argument up to the cursor, so the last argument in parsed_line is
// the one containing the cursor, and the cursor is after the last character.
- Args parsed_line(current_line, last_char - current_line);
- Args partial_parsed_line(current_line, cursor - current_line);
+ Args parsed_line(llvm::StringRef(current_line, last_char - current_line));
+ Args partial_parsed_line(llvm::StringRef(current_line, cursor - current_line));
// Don't complete comments, and if the line we are completing is just the history repeat character,
// substitute the appropriate history line.
@@ -2386,7 +2247,7 @@ CommandInterpreter::BuildAliasCommandArgs (CommandObject *alias_cmd_obj,
}
cmd_args.Clear();
- cmd_args.SetArguments (new_args.GetArgumentCount(), (const char **) new_args.GetArgumentVector());
+ cmd_args.SetArguments (new_args.GetArgumentCount(), new_args.GetConstArgumentVector());
}
else
{
@@ -2397,7 +2258,7 @@ CommandInterpreter::BuildAliasCommandArgs (CommandObject *alias_cmd_obj,
if (wants_raw_input)
{
cmd_args.Clear();
- cmd_args.SetArguments (new_args.GetArgumentCount(), (const char **) new_args.GetArgumentVector());
+ cmd_args.SetArguments (new_args.GetArgumentCount(), new_args.GetConstArgumentVector());
}
return;
}
@@ -2413,7 +2274,7 @@ CommandInterpreter::GetOptionArgumentPosition (const char *in_string)
int position = 0; // Any string that isn't an argument position, i.e. '%' followed by an integer, gets a position
// of zero.
- char *cptr = (char *) in_string;
+ const char *cptr = in_string;
// Does it start with '%'
if (cptr[0] == '%')
@@ -3355,7 +3216,7 @@ CommandInterpreter::RunCommandInterpreter(bool auto_handle_events,
bool spawn_thread,
CommandInterpreterRunOptions &options)
{
- // Always re-create the command intepreter when we run it in case
+ // Always re-create the command interpreter when we run it in case
// any file handles have changed.
bool force_create = true;
m_debugger.PushIOHandler(GetIOHandler(force_create, &options));
@@ -3370,7 +3231,7 @@ CommandInterpreter::RunCommandInterpreter(bool auto_handle_events,
}
else
{
- m_debugger.ExecuteIOHanders();
+ m_debugger.ExecuteIOHandlers();
if (auto_handle_events)
m_debugger.StopEventHandlerThread();
@@ -3378,3 +3239,179 @@ CommandInterpreter::RunCommandInterpreter(bool auto_handle_events,
}
+CommandObject *
+CommandInterpreter::ResolveCommandImpl(std::string &command_line, CommandReturnObject &result)
+{
+ std::string scratch_command(command_line); // working copy so we don't modify command_line unless we succeed
+ CommandObject *cmd_obj = nullptr;
+ StreamString revised_command_line;
+ bool wants_raw_input = false;
+ size_t actual_cmd_name_len = 0;
+ std::string next_word;
+ StringList matches;
+ bool done = false;
+ while (!done)
+ {
+ char quote_char = '\0';
+ std::string suffix;
+ ExtractCommand(scratch_command, next_word, suffix, quote_char);
+ if (cmd_obj == nullptr)
+ {
+ std::string full_name;
+ if (GetAliasFullName(next_word.c_str(), full_name))
+ {
+ std::string alias_result;
+ cmd_obj = BuildAliasResult(full_name.c_str(), scratch_command, alias_result, result);
+ revised_command_line.Printf("%s", alias_result.c_str());
+ if (cmd_obj)
+ {
+ wants_raw_input = cmd_obj->WantsRawCommandString();
+ actual_cmd_name_len = strlen(cmd_obj->GetCommandName());
+ }
+ }
+ else
+ {
+ cmd_obj = GetCommandObject(next_word.c_str(), &matches);
+ if (cmd_obj)
+ {
+ actual_cmd_name_len += strlen(cmd_obj->GetCommandName());
+ revised_command_line.Printf("%s", cmd_obj->GetCommandName());
+ wants_raw_input = cmd_obj->WantsRawCommandString();
+ }
+ else
+ {
+ revised_command_line.Printf ("%s", next_word.c_str());
+ }
+ }
+ }
+ else
+ {
+ if (cmd_obj->IsMultiwordObject ())
+ {
+ CommandObject *sub_cmd_obj = cmd_obj->GetSubcommandObject(next_word.c_str());
+ if (sub_cmd_obj)
+ {
+ // The subcommand's name includes the parent command's name,
+ // so restart rather than append to the revised_command_line.
+ actual_cmd_name_len = strlen(sub_cmd_obj->GetCommandName()) + 1;
+ revised_command_line.Clear();
+ revised_command_line.Printf("%s", sub_cmd_obj->GetCommandName());
+ cmd_obj = sub_cmd_obj;
+ wants_raw_input = cmd_obj->WantsRawCommandString();
+ }
+ else
+ {
+ if (quote_char)
+ revised_command_line.Printf(" %c%s%s%c", quote_char, next_word.c_str(), suffix.c_str(), quote_char);
+ else
+ revised_command_line.Printf(" %s%s", next_word.c_str(), suffix.c_str());
+ done = true;
+ }
+ }
+ else
+ {
+ if (quote_char)
+ revised_command_line.Printf(" %c%s%s%c", quote_char, next_word.c_str(), suffix.c_str(), quote_char);
+ else
+ revised_command_line.Printf(" %s%s", next_word.c_str(), suffix.c_str());
+ done = true;
+ }
+ }
+
+ if (cmd_obj == nullptr)
+ {
+ const size_t num_matches = matches.GetSize();
+ if (matches.GetSize() > 1) {
+ StreamString error_msg;
+ error_msg.Printf("Ambiguous command '%s'. Possible matches:\n", next_word.c_str());
+
+ for (uint32_t i = 0; i < num_matches; ++i) {
+ error_msg.Printf("\t%s\n", matches.GetStringAtIndex(i));
+ }
+ result.AppendRawError(error_msg.GetString().c_str());
+ } else {
+ // We didn't have only one match, otherwise we wouldn't get here.
+ assert(num_matches == 0);
+ result.AppendErrorWithFormat("'%s' is not a valid command.\n", next_word.c_str());
+ }
+ result.SetStatus(eReturnStatusFailed);
+ return nullptr;
+ }
+
+ if (cmd_obj->IsMultiwordObject())
+ {
+ if (!suffix.empty())
+ {
+ result.AppendErrorWithFormat("command '%s' did not recognize '%s%s%s' as valid (subcommand might be invalid).\n",
+ cmd_obj->GetCommandName(),
+ next_word.empty() ? "" : next_word.c_str(),
+ next_word.empty() ? " -- " : " ",
+ suffix.c_str());
+ result.SetStatus(eReturnStatusFailed);
+ return nullptr;
+ }
+ }
+ else
+ {
+ // If we found a normal command, we are done
+ done = true;
+ if (!suffix.empty())
+ {
+ switch (suffix[0])
+ {
+ case '/':
+ // GDB format suffixes
+ {
+ Options *command_options = cmd_obj->GetOptions();
+ if (command_options && command_options->SupportsLongOption("gdb-format"))
+ {
+ std::string gdb_format_option("--gdb-format=");
+ gdb_format_option += (suffix.c_str() + 1);
+
+ bool inserted = false;
+ std::string &cmd = revised_command_line.GetString();
+ size_t arg_terminator_idx = FindArgumentTerminator(cmd);
+ if (arg_terminator_idx != std::string::npos)
+ {
+ // Insert the gdb format option before the "--" that terminates options
+ gdb_format_option.append(1,' ');
+ cmd.insert(arg_terminator_idx, gdb_format_option);
+ inserted = true;
+ }
+
+ if (!inserted)
+ revised_command_line.Printf(" %s", gdb_format_option.c_str());
+
+ if (wants_raw_input && FindArgumentTerminator(cmd) == std::string::npos)
+ revised_command_line.PutCString(" --");
+ }
+ else
+ {
+ result.AppendErrorWithFormat("the '%s' command doesn't support the --gdb-format option\n",
+ cmd_obj->GetCommandName());
+ result.SetStatus(eReturnStatusFailed);
+ return nullptr;
+ }
+ }
+ break;
+
+ default:
+ result.AppendErrorWithFormat("unknown command shorthand suffix: '%s'\n",
+ suffix.c_str());
+ result.SetStatus(eReturnStatusFailed);
+ return nullptr;
+ }
+ }
+ }
+ if (scratch_command.empty())
+ done = true;
+ }
+
+ if (!scratch_command.empty())
+ revised_command_line.Printf(" %s", scratch_command.c_str());
+
+ if (cmd_obj != NULL)
+ command_line = revised_command_line.GetData();
+
+ return cmd_obj;
+}
diff --git a/source/Interpreter/CommandObject.cpp b/source/Interpreter/CommandObject.cpp
index 753e720b0f6e..d67f76eba7b6 100644
--- a/source/Interpreter/CommandObject.cpp
+++ b/source/Interpreter/CommandObject.cpp
@@ -7,8 +7,6 @@
//
//===----------------------------------------------------------------------===//
-#include "lldb/lldb-python.h"
-
#include "lldb/Interpreter/CommandObject.h"
#include <string>
@@ -25,13 +23,12 @@
// FIXME: Make a separate file for the completers.
#include "lldb/Host/FileSpec.h"
#include "lldb/Core/FileSpecList.h"
+#include "lldb/DataFormatters/FormatManager.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
-#include "lldb/Interpreter/ScriptInterpreter.h"
-#include "lldb/Interpreter/ScriptInterpreterPython.h"
using namespace lldb;
using namespace lldb_private;
@@ -123,6 +120,12 @@ CommandObject::SetHelp (const char *cstr)
}
void
+CommandObject::SetHelp (std::string str)
+{
+ m_cmd_help_short = str;
+}
+
+void
CommandObject::SetHelpLong (const char *cstr)
{
m_cmd_help_long = cstr;
@@ -221,20 +224,20 @@ CommandObject::CheckRequirements (CommandReturnObject &result)
m_exe_ctx = m_interpreter.GetExecutionContext();
const uint32_t flags = GetFlags().Get();
- if (flags & (eFlagRequiresTarget |
- eFlagRequiresProcess |
- eFlagRequiresThread |
- eFlagRequiresFrame |
- eFlagTryTargetAPILock ))
+ if (flags & (eCommandRequiresTarget |
+ eCommandRequiresProcess |
+ eCommandRequiresThread |
+ eCommandRequiresFrame |
+ eCommandTryTargetAPILock ))
{
- if ((flags & eFlagRequiresTarget) && !m_exe_ctx.HasTargetScope())
+ if ((flags & eCommandRequiresTarget) && !m_exe_ctx.HasTargetScope())
{
result.AppendError (GetInvalidTargetDescription());
return false;
}
- if ((flags & eFlagRequiresProcess) && !m_exe_ctx.HasProcessScope())
+ if ((flags & eCommandRequiresProcess) && !m_exe_ctx.HasProcessScope())
{
if (!m_exe_ctx.HasTargetScope())
result.AppendError (GetInvalidTargetDescription());
@@ -243,7 +246,7 @@ CommandObject::CheckRequirements (CommandReturnObject &result)
return false;
}
- if ((flags & eFlagRequiresThread) && !m_exe_ctx.HasThreadScope())
+ if ((flags & eCommandRequiresThread) && !m_exe_ctx.HasThreadScope())
{
if (!m_exe_ctx.HasTargetScope())
result.AppendError (GetInvalidTargetDescription());
@@ -254,7 +257,7 @@ CommandObject::CheckRequirements (CommandReturnObject &result)
return false;
}
- if ((flags & eFlagRequiresFrame) && !m_exe_ctx.HasFrameScope())
+ if ((flags & eCommandRequiresFrame) && !m_exe_ctx.HasFrameScope())
{
if (!m_exe_ctx.HasTargetScope())
result.AppendError (GetInvalidTargetDescription());
@@ -267,13 +270,13 @@ CommandObject::CheckRequirements (CommandReturnObject &result)
return false;
}
- if ((flags & eFlagRequiresRegContext) && (m_exe_ctx.GetRegisterContext() == nullptr))
+ if ((flags & eCommandRequiresRegContext) && (m_exe_ctx.GetRegisterContext() == nullptr))
{
result.AppendError (GetInvalidRegContextDescription());
return false;
}
- if (flags & eFlagTryTargetAPILock)
+ if (flags & eCommandTryTargetAPILock)
{
Target *target = m_exe_ctx.GetTargetPtr();
if (target)
@@ -281,13 +284,13 @@ CommandObject::CheckRequirements (CommandReturnObject &result)
}
}
- if (GetFlags().AnySet (CommandObject::eFlagProcessMustBeLaunched | CommandObject::eFlagProcessMustBePaused))
+ if (GetFlags().AnySet (eCommandProcessMustBeLaunched | eCommandProcessMustBePaused))
{
Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
if (process == nullptr)
{
// A process that is not running is considered paused.
- if (GetFlags().Test(CommandObject::eFlagProcessMustBeLaunched))
+ if (GetFlags().Test(eCommandProcessMustBeLaunched))
{
result.AppendError ("Process must exist.");
result.SetStatus (eReturnStatusFailed);
@@ -311,7 +314,7 @@ CommandObject::CheckRequirements (CommandReturnObject &result)
case eStateDetached:
case eStateExited:
case eStateUnloaded:
- if (GetFlags().Test(CommandObject::eFlagProcessMustBeLaunched))
+ if (GetFlags().Test(eCommandProcessMustBeLaunched))
{
result.AppendError ("Process must be launched.");
result.SetStatus (eReturnStatusFailed);
@@ -321,7 +324,7 @@ CommandObject::CheckRequirements (CommandReturnObject &result)
case eStateRunning:
case eStateStepping:
- if (GetFlags().Test(CommandObject::eFlagProcessMustBePaused))
+ if (GetFlags().Test(eCommandProcessMustBePaused))
{
result.AppendError ("Process is running. Use 'process interrupt' to pause execution.");
result.SetStatus (eReturnStatusFailed);
@@ -499,14 +502,14 @@ CommandObject::GetArgumentEntryAtIndex (int idx)
return nullptr;
}
-CommandObject::ArgumentTableEntry *
+const CommandObject::ArgumentTableEntry *
CommandObject::FindArgumentDataByType (CommandArgumentType arg_type)
{
const ArgumentTableEntry *table = CommandObject::GetArgumentTable();
for (int i = 0; i < eArgTypeLastArg; ++i)
if (table[i].arg_type == arg_type)
- return (ArgumentTableEntry *) &(table[i]);
+ return &(table[i]);
return nullptr;
}
@@ -515,7 +518,7 @@ void
CommandObject::GetArgumentHelp (Stream &str, CommandArgumentType arg_type, CommandInterpreter &interpreter)
{
const ArgumentTableEntry* table = CommandObject::GetArgumentTable();
- ArgumentTableEntry *entry = (ArgumentTableEntry *) &(table[arg_type]);
+ const ArgumentTableEntry *entry = &(table[arg_type]);
// The table is *supposed* to be kept in arg_type order, but someone *could* have messed it up...
@@ -549,7 +552,7 @@ CommandObject::GetArgumentHelp (Stream &str, CommandArgumentType arg_type, Comma
const char *
CommandObject::GetArgumentName (CommandArgumentType arg_type)
{
- ArgumentTableEntry *entry = (ArgumentTableEntry *) &(CommandObject::GetArgumentTable()[arg_type]);
+ const ArgumentTableEntry *entry = &(CommandObject::GetArgumentTable()[arg_type]);
// The table is *supposed* to be kept in arg_type order, but someone *could* have messed it up...
@@ -843,12 +846,9 @@ LanguageTypeHelpTextCallback ()
StreamString sstr;
sstr << "One of the following languages:\n";
-
- for (unsigned int l = eLanguageTypeUnknown; l < eNumLanguageTypes; ++l)
- {
- sstr << " " << LanguageRuntime::GetNameForLanguageType(static_cast<LanguageType>(l)) << "\n";
- }
-
+
+ LanguageRuntime::PrintAllLanguages(sstr, " ", "\n");
+
sstr.Flush();
std::string data = sstr.GetString();
@@ -1020,18 +1020,15 @@ CommandObject::AddIDsArgumentData(CommandArgumentEntry &arg, CommandArgumentType
const char *
CommandObject::GetArgumentTypeAsCString (const lldb::CommandArgumentType arg_type)
{
- if (arg_type >=0 && arg_type < eArgTypeLastArg)
- return g_arguments_data[arg_type].arg_name;
- return nullptr;
-
+ assert(arg_type < eArgTypeLastArg && "Invalid argument type passed to GetArgumentTypeAsCString");
+ return g_arguments_data[arg_type].arg_name;
}
const char *
CommandObject::GetArgumentDescriptionAsCString (const lldb::CommandArgumentType arg_type)
{
- if (arg_type >=0 && arg_type < eArgTypeLastArg)
- return g_arguments_data[arg_type].help_text;
- return nullptr;
+ assert(arg_type < eArgTypeLastArg && "Invalid argument type passed to GetArgumentDescriptionAsCString");
+ return g_arguments_data[arg_type].help_text;
}
Target *
@@ -1192,6 +1189,7 @@ CommandObject::g_arguments_data[] =
{ eArgTypeThreadID, "thread-id", CommandCompletions::eNoCompletion, { nullptr, false }, "Thread ID number." },
{ eArgTypeThreadIndex, "thread-index", CommandCompletions::eNoCompletion, { nullptr, false }, "Index into the process' list of threads." },
{ eArgTypeThreadName, "thread-name", CommandCompletions::eNoCompletion, { nullptr, false }, "The thread's name." },
+ { eArgTypeTypeName, "type-name", CommandCompletions::eNoCompletion, { nullptr, false }, "A type name." },
{ eArgTypeUnsignedInteger, "unsigned-integer", CommandCompletions::eNoCompletion, { nullptr, false }, "An unsigned integer." },
{ eArgTypeUnixSignal, "unix-signal", CommandCompletions::eNoCompletion, { nullptr, false }, "A valid Unix signal name or number (e.g. SIGKILL, KILL or 9)." },
{ eArgTypeVarName, "variable-name", CommandCompletions::eNoCompletion, { nullptr, false }, "The name of a variable in your program." },
diff --git a/source/Interpreter/CommandObjectRegexCommand.cpp b/source/Interpreter/CommandObjectRegexCommand.cpp
index bde7f58b4cb0..1c3c3cdd5fdc 100644
--- a/source/Interpreter/CommandObjectRegexCommand.cpp
+++ b/source/Interpreter/CommandObjectRegexCommand.cpp
@@ -7,8 +7,6 @@
//
//===----------------------------------------------------------------------===//
-#include "lldb/lldb-python.h"
-
#include "lldb/Interpreter/CommandObjectRegexCommand.h"
// C Includes
diff --git a/source/Interpreter/CommandObjectScript.cpp b/source/Interpreter/CommandObjectScript.cpp
index 9c67e4253301..31e5311ab441 100644
--- a/source/Interpreter/CommandObjectScript.cpp
+++ b/source/Interpreter/CommandObjectScript.cpp
@@ -7,8 +7,6 @@
//
//===----------------------------------------------------------------------===//
-#include "lldb/lldb-python.h"
-
#include "CommandObjectScript.h"
// C Includes
diff --git a/source/Interpreter/OptionGroupBoolean.cpp b/source/Interpreter/OptionGroupBoolean.cpp
index 0c502cc364b4..6bd2743a6681 100644
--- a/source/Interpreter/OptionGroupBoolean.cpp
+++ b/source/Interpreter/OptionGroupBoolean.cpp
@@ -56,7 +56,7 @@ OptionGroupBoolean::SetOptionValue (CommandInterpreter &interpreter,
}
else
{
- error = m_value.SetValueFromCString (option_arg);
+ error = m_value.SetValueFromString (option_arg);
}
return error;
}
diff --git a/source/Interpreter/OptionGroupFile.cpp b/source/Interpreter/OptionGroupFile.cpp
index 9bfe8ddf0282..a4b56409698e 100644
--- a/source/Interpreter/OptionGroupFile.cpp
+++ b/source/Interpreter/OptionGroupFile.cpp
@@ -47,7 +47,7 @@ OptionGroupFile::SetOptionValue (CommandInterpreter &interpreter,
uint32_t option_idx,
const char *option_arg)
{
- Error error (m_file.SetValueFromCString (option_arg));
+ Error error (m_file.SetValueFromString (option_arg));
return error;
}
@@ -88,7 +88,7 @@ OptionGroupFileList::SetOptionValue (CommandInterpreter &interpreter,
uint32_t option_idx,
const char *option_arg)
{
- Error error (m_file_list.SetValueFromCString (option_arg));
+ Error error (m_file_list.SetValueFromString (option_arg));
return error;
}
diff --git a/source/Interpreter/OptionGroupFormat.cpp b/source/Interpreter/OptionGroupFormat.cpp
index 601a78458730..08ff262d5428 100644
--- a/source/Interpreter/OptionGroupFormat.cpp
+++ b/source/Interpreter/OptionGroupFormat.cpp
@@ -7,8 +7,6 @@
//
//===----------------------------------------------------------------------===//
-#include "lldb/lldb-python.h"
-
#include "lldb/Interpreter/OptionGroupFormat.h"
// C Includes
@@ -78,7 +76,7 @@ OptionGroupFormat::SetOptionValue (CommandInterpreter &interpreter,
switch (short_option)
{
case 'f':
- error = m_format.SetValueFromCString (option_arg);
+ error = m_format.SetValueFromString (option_arg);
break;
case 'c':
@@ -88,7 +86,7 @@ OptionGroupFormat::SetOptionValue (CommandInterpreter &interpreter,
}
else
{
- error = m_count.SetValueFromCString (option_arg);
+ error = m_count.SetValueFromString (option_arg);
if (m_count.GetCurrentValue() == 0)
error.SetErrorStringWithFormat("invalid --count option value '%s'", option_arg);
}
@@ -101,7 +99,7 @@ OptionGroupFormat::SetOptionValue (CommandInterpreter &interpreter,
}
else
{
- error = m_byte_size.SetValueFromCString (option_arg);
+ error = m_byte_size.SetValueFromString (option_arg);
if (m_byte_size.GetCurrentValue() == 0)
error.SetErrorStringWithFormat("invalid --size option value '%s'", option_arg);
}
diff --git a/source/Interpreter/OptionGroupOutputFile.cpp b/source/Interpreter/OptionGroupOutputFile.cpp
index ec9e166d2f05..e95cd35976ec 100644
--- a/source/Interpreter/OptionGroupOutputFile.cpp
+++ b/source/Interpreter/OptionGroupOutputFile.cpp
@@ -36,7 +36,7 @@ g_option_table[] =
{ LLDB_OPT_SET_1 , false, "outfile", 'o', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFilename , "Specify a path for capturing command output."},
{ LLDB_OPT_SET_1 , false, "append-outfile" , SHORT_OPTION_APND,
OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone ,
- "Append to the the file specified with '--outfile <path>'."},
+ "Append to the file specified with '--outfile <path>'."},
};
uint32_t
@@ -62,7 +62,7 @@ OptionGroupOutputFile::SetOptionValue (CommandInterpreter &interpreter,
switch (short_option)
{
case 'o':
- error = m_file.SetValueFromCString (option_arg);
+ error = m_file.SetValueFromString (option_arg);
break;
case SHORT_OPTION_APND:
diff --git a/source/Interpreter/OptionGroupPlatform.cpp b/source/Interpreter/OptionGroupPlatform.cpp
index 6bb36552d06b..6fa06d1eb8ed 100644
--- a/source/Interpreter/OptionGroupPlatform.cpp
+++ b/source/Interpreter/OptionGroupPlatform.cpp
@@ -7,8 +7,6 @@
//
//===----------------------------------------------------------------------===//
-#include "lldb/lldb-python.h"
-
#include "lldb/Interpreter/OptionGroupPlatform.h"
// C Includes
diff --git a/source/Interpreter/OptionGroupString.cpp b/source/Interpreter/OptionGroupString.cpp
index 9bc1c94d3a5a..e0291b154be2 100644
--- a/source/Interpreter/OptionGroupString.cpp
+++ b/source/Interpreter/OptionGroupString.cpp
@@ -48,7 +48,7 @@ OptionGroupString::SetOptionValue (CommandInterpreter &interpreter,
uint32_t option_idx,
const char *option_arg)
{
- Error error (m_value.SetValueFromCString (option_arg));
+ Error error (m_value.SetValueFromString (option_arg));
return error;
}
diff --git a/source/Interpreter/OptionGroupUInt64.cpp b/source/Interpreter/OptionGroupUInt64.cpp
index 440c2a740c26..a922ab255968 100644
--- a/source/Interpreter/OptionGroupUInt64.cpp
+++ b/source/Interpreter/OptionGroupUInt64.cpp
@@ -48,7 +48,7 @@ OptionGroupUInt64::SetOptionValue (CommandInterpreter &interpreter,
uint32_t option_idx,
const char *option_arg)
{
- Error error (m_value.SetValueFromCString (option_arg));
+ Error error (m_value.SetValueFromString (option_arg));
return error;
}
diff --git a/source/Interpreter/OptionGroupUUID.cpp b/source/Interpreter/OptionGroupUUID.cpp
index 43f7386c9ca6..609967a83e79 100644
--- a/source/Interpreter/OptionGroupUUID.cpp
+++ b/source/Interpreter/OptionGroupUUID.cpp
@@ -56,7 +56,7 @@ OptionGroupUUID::SetOptionValue (CommandInterpreter &interpreter,
switch (short_option)
{
case 'u':
- error = m_uuid.SetValueFromCString (option_arg);
+ error = m_uuid.SetValueFromString (option_arg);
if (error.Success())
m_uuid.SetOptionWasSet();
break;
diff --git a/source/Interpreter/OptionGroupValueObjectDisplay.cpp b/source/Interpreter/OptionGroupValueObjectDisplay.cpp
index 72d7ff597ab2..e5a5c004b2da 100644
--- a/source/Interpreter/OptionGroupValueObjectDisplay.cpp
+++ b/source/Interpreter/OptionGroupValueObjectDisplay.cpp
@@ -7,8 +7,6 @@
//
//===----------------------------------------------------------------------===//
-#include "lldb/lldb-python.h"
-
#include "lldb/Interpreter/OptionGroupValueObjectDisplay.h"
// C Includes
diff --git a/source/Interpreter/OptionGroupVariable.cpp b/source/Interpreter/OptionGroupVariable.cpp
index 05cf3f73bfed..092d60af9eb0 100644
--- a/source/Interpreter/OptionGroupVariable.cpp
+++ b/source/Interpreter/OptionGroupVariable.cpp
@@ -7,8 +7,6 @@
//
//===----------------------------------------------------------------------===//
-#include "lldb/lldb-python.h"
-
#include "lldb/Interpreter/OptionGroupVariable.h"
// C Includes
diff --git a/source/Interpreter/OptionGroupWatchpoint.cpp b/source/Interpreter/OptionGroupWatchpoint.cpp
index f4d8df1e6ba7..c6f4b8f8c8ea 100644
--- a/source/Interpreter/OptionGroupWatchpoint.cpp
+++ b/source/Interpreter/OptionGroupWatchpoint.cpp
@@ -41,7 +41,7 @@ static OptionDefinition
g_option_table[] =
{
{ LLDB_OPT_SET_1, false, "watch", 'w', OptionParser::eRequiredArgument, nullptr, g_watch_type, 0, eArgTypeWatchType, "Specify the type of watching to perform."},
- { LLDB_OPT_SET_1, false, "xsize", 'x', OptionParser::eRequiredArgument, nullptr, g_watch_size, 0, eArgTypeByteSize, "Number of bytes to use to watch a region."}
+ { LLDB_OPT_SET_1, false, "size", 's', OptionParser::eRequiredArgument, nullptr, g_watch_size, 0, eArgTypeByteSize, "Number of bytes to use to watch a region."}
};
@@ -87,7 +87,7 @@ OptionGroupWatchpoint::SetOptionValue (CommandInterpreter &interpreter,
}
break;
}
- case 'x':
+ case 's':
watch_size = (uint32_t) Args::StringToOptionEnum(option_arg, g_option_table[option_idx].enum_values, 0, error);
break;
diff --git a/source/Interpreter/OptionValue.cpp b/source/Interpreter/OptionValue.cpp
index 1e4ea23cc075..8f136a5b1c57 100644
--- a/source/Interpreter/OptionValue.cpp
+++ b/source/Interpreter/OptionValue.cpp
@@ -222,6 +222,22 @@ OptionValue::GetAsFormat () const
return nullptr;
}
+OptionValueLanguage *
+OptionValue::GetAsLanguage ()
+{
+ if (GetType () == OptionValue::eTypeLanguage)
+ return static_cast<OptionValueLanguage *>(this);
+ return NULL;
+}
+
+const OptionValueLanguage *
+OptionValue::GetAsLanguage () const
+{
+ if (GetType () == OptionValue::eTypeLanguage)
+ return static_cast<const OptionValueLanguage *>(this);
+ return NULL;
+}
+
OptionValueFormatEntity *
OptionValue::GetAsFormatEntity ()
{
@@ -468,6 +484,27 @@ OptionValue::SetFormatValue (lldb::Format new_value)
return false;
}
+lldb::LanguageType
+OptionValue::GetLanguageValue (lldb::LanguageType fail_value) const
+{
+ const OptionValueLanguage *option_value = GetAsLanguage ();
+ if (option_value)
+ return option_value->GetCurrentValue();
+ return fail_value;
+}
+
+bool
+OptionValue::SetLanguageValue (lldb::LanguageType new_language)
+{
+ OptionValueLanguage *option_value = GetAsLanguage ();
+ if (option_value)
+ {
+ option_value->SetCurrentValue(new_language);
+ return true;
+ }
+ return false;
+}
+
const FormatEntity::Entry *
OptionValue::GetFormatEntity () const
{
@@ -589,6 +626,7 @@ OptionValue::GetBuiltinTypeAsCString (Type t)
case eTypeFileSpecList: return "file-list";
case eTypeFormat: return "format";
case eTypeFormatEntity: return "format-string";
+ case eTypeLanguage: return "language";
case eTypePathMap: return "path-map";
case eTypeProperties: return "properties";
case eTypeRegex: return "regex";
@@ -615,6 +653,7 @@ OptionValue::CreateValueFromCStringForTypeMask (const char *value_cstr, uint32_t
case 1u << eTypeFileSpec: value_sp.reset(new OptionValueFileSpec()); break;
case 1u << eTypeFormat: value_sp.reset(new OptionValueFormat(eFormatInvalid)); break;
case 1u << eTypeFormatEntity: value_sp.reset(new OptionValueFormatEntity(NULL)); break;
+ case 1u << eTypeLanguage: value_sp.reset(new OptionValueLanguage(eLanguageTypeUnknown)); break;
case 1u << eTypeSInt64: value_sp.reset(new OptionValueSInt64()); break;
case 1u << eTypeString: value_sp.reset(new OptionValueString()); break;
case 1u << eTypeUInt64: value_sp.reset(new OptionValueUInt64()); break;
@@ -622,7 +661,7 @@ OptionValue::CreateValueFromCStringForTypeMask (const char *value_cstr, uint32_t
}
if (value_sp)
- error = value_sp->SetValueFromCString (value_cstr, eVarSetOperationAssign);
+ error = value_sp->SetValueFromString (value_cstr, eVarSetOperationAssign);
else
error.SetErrorString("unsupported type mask");
return value_sp;
@@ -664,7 +703,7 @@ OptionValue::AutoComplete (CommandInterpreter &interpreter,
}
Error
-OptionValue::SetValueFromCString (const char *value, VarSetOperationType op)
+OptionValue::SetValueFromString (llvm::StringRef value, VarSetOperationType op)
{
Error error;
switch (op)
diff --git a/source/Interpreter/OptionValueArch.cpp b/source/Interpreter/OptionValueArch.cpp
index 7df149234bda..0e1ca07afd2e 100644
--- a/source/Interpreter/OptionValueArch.cpp
+++ b/source/Interpreter/OptionValueArch.cpp
@@ -7,8 +7,6 @@
//
//===----------------------------------------------------------------------===//
-#include "lldb/lldb-python.h"
-
#include "lldb/Interpreter/OptionValueArch.h"
// C Includes
@@ -43,7 +41,7 @@ OptionValueArch::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint3
}
Error
-OptionValueArch::SetValueFromCString (const char *value_cstr, VarSetOperationType op)
+OptionValueArch::SetValueFromString (llvm::StringRef value, VarSetOperationType op)
{
Error error;
switch (op)
@@ -55,28 +53,23 @@ OptionValueArch::SetValueFromCString (const char *value_cstr, VarSetOperationTyp
case eVarSetOperationReplace:
case eVarSetOperationAssign:
- if (value_cstr && value_cstr[0])
{
- if (m_current_value.SetTriple (value_cstr))
+ std::string value_str = value.trim().str();
+ if (m_current_value.SetTriple (value_str.c_str()))
{
m_value_was_set = true;
NotifyValueChanged();
}
else
- error.SetErrorStringWithFormat("unsupported architecture '%s'", value_cstr);
- }
- else
- {
- error.SetErrorString("invalid value string");
+ error.SetErrorStringWithFormat("unsupported architecture '%s'", value_str.c_str());
+ break;
}
- break;
-
case eVarSetOperationInsertBefore:
case eVarSetOperationInsertAfter:
case eVarSetOperationRemove:
case eVarSetOperationAppend:
case eVarSetOperationInvalid:
- error = OptionValue::SetValueFromCString (value_cstr, op);
+ error = OptionValue::SetValueFromString (value, op);
break;
}
return error;
diff --git a/source/Interpreter/OptionValueArray.cpp b/source/Interpreter/OptionValueArray.cpp
index 86d49c9ba3b4..aabe457534d6 100644
--- a/source/Interpreter/OptionValueArray.cpp
+++ b/source/Interpreter/OptionValueArray.cpp
@@ -74,11 +74,13 @@ OptionValueArray::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint
}
Error
-OptionValueArray::SetValueFromCString (const char *value, VarSetOperationType op)
+OptionValueArray::SetValueFromString (llvm::StringRef value, VarSetOperationType op)
{
- Args args(value);
- NotifyValueChanged();
- return SetArgs (args, op);
+ Args args(value.str().c_str());
+ Error error = SetArgs (args, op);
+ if (error.Success())
+ NotifyValueChanged();
+ return error;
}
@@ -342,6 +344,8 @@ OptionValueArray::DeepCopy () const
{
OptionValueArray *copied_array = new OptionValueArray (m_type_mask, m_raw_value_dump);
lldb::OptionValueSP copied_value_sp(copied_array);
+ *static_cast<OptionValue *>(copied_array) = *this;
+ copied_array->m_callback = m_callback;
const uint32_t size = m_values.size();
for (uint32_t i = 0; i<size; ++i)
{
diff --git a/source/Interpreter/OptionValueBoolean.cpp b/source/Interpreter/OptionValueBoolean.cpp
index 71cc2afb98e1..dae1f4b7a76d 100644
--- a/source/Interpreter/OptionValueBoolean.cpp
+++ b/source/Interpreter/OptionValueBoolean.cpp
@@ -37,7 +37,7 @@ OptionValueBoolean::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, ui
}
Error
-OptionValueBoolean::SetValueFromCString (const char *value_cstr,
+OptionValueBoolean::SetValueFromString (llvm::StringRef value_str,
VarSetOperationType op)
{
Error error;
@@ -52,7 +52,7 @@ OptionValueBoolean::SetValueFromCString (const char *value_cstr,
case eVarSetOperationAssign:
{
bool success = false;
- bool value = Args::StringToBoolean(value_cstr, false, &success);
+ bool value = Args::StringToBoolean(value_str.str().c_str(), false, &success);
if (success)
{
m_value_was_set = true;
@@ -61,12 +61,11 @@ OptionValueBoolean::SetValueFromCString (const char *value_cstr,
}
else
{
- if (value_cstr == nullptr)
- error.SetErrorString ("invalid boolean string value: NULL");
- else if (value_cstr[0] == '\0')
+ if (value_str.size() == 0)
error.SetErrorString ("invalid boolean string value <empty>");
else
- error.SetErrorStringWithFormat ("invalid boolean string value: '%s'", value_cstr);
+ error.SetErrorStringWithFormat ("invalid boolean string value: '%s'",
+ value_str.str().c_str());
}
}
break;
@@ -76,7 +75,7 @@ OptionValueBoolean::SetValueFromCString (const char *value_cstr,
case eVarSetOperationRemove:
case eVarSetOperationAppend:
case eVarSetOperationInvalid:
- error = OptionValue::SetValueFromCString (value_cstr, op);
+ error = OptionValue::SetValueFromString (value_str, op);
break;
}
return error;
diff --git a/source/Interpreter/OptionValueChar.cpp b/source/Interpreter/OptionValueChar.cpp
index 7a0135314c81..b5ef1d346aea 100644
--- a/source/Interpreter/OptionValueChar.cpp
+++ b/source/Interpreter/OptionValueChar.cpp
@@ -39,7 +39,7 @@ OptionValueChar::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint3
}
Error
-OptionValueChar::SetValueFromCString (const char *value_cstr,
+OptionValueChar::SetValueFromString (llvm::StringRef value,
VarSetOperationType op)
{
Error error;
@@ -53,19 +53,19 @@ OptionValueChar::SetValueFromCString (const char *value_cstr,
case eVarSetOperationAssign:
{
bool success = false;
- char char_value = Args::StringToChar(value_cstr, '\0', &success);
+ char char_value = Args::StringToChar(value.str().c_str(), '\0', &success);
if (success)
{
m_current_value = char_value;
m_value_was_set = true;
}
else
- error.SetErrorStringWithFormat("'%s' cannot be longer than 1 character", value_cstr);
+ error.SetErrorStringWithFormat("'%s' cannot be longer than 1 character", value.str().c_str());
}
break;
default:
- error = OptionValue::SetValueFromCString (value_cstr, op);
+ error = OptionValue::SetValueFromString (value.str().c_str(), op);
break;
}
return error;
diff --git a/source/Interpreter/OptionValueDictionary.cpp b/source/Interpreter/OptionValueDictionary.cpp
index e5299f8cc390..24eeec3b3285 100644
--- a/source/Interpreter/OptionValueDictionary.cpp
+++ b/source/Interpreter/OptionValueDictionary.cpp
@@ -7,8 +7,6 @@
//
//===----------------------------------------------------------------------===//
-#include "lldb/lldb-python.h"
-
#include "lldb/Interpreter/OptionValueDictionary.h"
// C Includes
@@ -119,6 +117,12 @@ OptionValueDictionary::SetArgs (const Args &args, VarSetOperationType op)
llvm::StringRef key_and_value(args.GetArgumentAtIndex(i));
if (!key_and_value.empty())
{
+ if (key_and_value.find('=') == llvm::StringRef::npos)
+ {
+ error.SetErrorString("assign operation takes one or more key=value arguments");
+ return error;
+ }
+
std::pair<llvm::StringRef, llvm::StringRef> kvp(key_and_value.split('='));
llvm::StringRef key = kvp.first;
bool key_valid = false;
@@ -126,7 +130,7 @@ OptionValueDictionary::SetArgs (const Args &args, VarSetOperationType op)
{
if (key.front() == '[')
{
- // Key name starts with '[', so the the key value must be in single or double quotes like:
+ // Key name starts with '[', so the key value must be in single or double quotes like:
// ['<key>']
// ["<key>"]
if ((key.size() > 2) && (key.back() == ']'))
@@ -211,16 +215,16 @@ OptionValueDictionary::SetArgs (const Args &args, VarSetOperationType op)
case eVarSetOperationInsertBefore:
case eVarSetOperationInsertAfter:
case eVarSetOperationInvalid:
- error = OptionValue::SetValueFromCString (nullptr, op);
+ error = OptionValue::SetValueFromString (llvm::StringRef(), op);
break;
}
return error;
}
Error
-OptionValueDictionary::SetValueFromCString (const char *value_cstr, VarSetOperationType op)
+OptionValueDictionary::SetValueFromString (llvm::StringRef value, VarSetOperationType op)
{
- Args args(value_cstr);
+ Args args(value.str().c_str());
Error error = SetArgs (args, op);
if (error.Success())
NotifyValueChanged();
@@ -320,7 +324,7 @@ OptionValueDictionary::GetSubValue (const ExecutionContext *exe_ctx, const char
}
if (!value_sp && error.AsCString() == nullptr)
{
- error.SetErrorStringWithFormat ("invalid value path '%s', %s values only support '[<key>]' subvalues where <key> a string value optionally delimitted by single or double quotes",
+ error.SetErrorStringWithFormat ("invalid value path '%s', %s values only support '[<key>]' subvalues where <key> a string value optionally delimited by single or double quotes",
name,
GetTypeAsCString());
}
@@ -335,7 +339,7 @@ OptionValueDictionary::SetSubValue (const ExecutionContext *exe_ctx, VarSetOpera
const bool will_modify = true;
lldb::OptionValueSP value_sp (GetSubValue (exe_ctx, name, will_modify, error));
if (value_sp)
- error = value_sp->SetValueFromCString(value, op);
+ error = value_sp->SetValueFromString(value, op);
else
{
if (error.AsCString() == nullptr)
@@ -381,7 +385,7 @@ OptionValueDictionary::SetStringValueForKey (const ConstString &key,
return false;
if (pos->second->GetType() == OptionValue::eTypeString)
{
- pos->second->SetValueFromCString(value);
+ pos->second->SetValueFromString(value);
return true;
}
}
diff --git a/source/Interpreter/OptionValueEnumeration.cpp b/source/Interpreter/OptionValueEnumeration.cpp
index dbaeb185fa3a..0f163d1c4f74 100644
--- a/source/Interpreter/OptionValueEnumeration.cpp
+++ b/source/Interpreter/OptionValueEnumeration.cpp
@@ -55,7 +55,7 @@ OptionValueEnumeration::DumpValue (const ExecutionContext *exe_ctx, Stream &strm
}
Error
-OptionValueEnumeration::SetValueFromCString (const char *value, VarSetOperationType op)
+OptionValueEnumeration::SetValueFromString (llvm::StringRef value, VarSetOperationType op)
{
Error error;
switch (op)
@@ -67,9 +67,8 @@ OptionValueEnumeration::SetValueFromCString (const char *value, VarSetOperationT
case eVarSetOperationReplace:
case eVarSetOperationAssign:
- if (value && value[0])
{
- ConstString const_enumerator_name(value);
+ ConstString const_enumerator_name(value.trim());
const EnumerationMapEntry *enumerator_entry = m_enumerations.FindFirstValueForName (const_enumerator_name.GetCString());
if (enumerator_entry)
{
@@ -79,7 +78,7 @@ OptionValueEnumeration::SetValueFromCString (const char *value, VarSetOperationT
else
{
StreamString error_strm;
- error_strm.Printf("invalid enumeration value '%s'", value);
+ error_strm.Printf("invalid enumeration value '%s'", value.str().c_str());
const size_t count = m_enumerations.GetSize ();
if (count)
{
@@ -91,19 +90,15 @@ OptionValueEnumeration::SetValueFromCString (const char *value, VarSetOperationT
}
error.SetErrorString(error_strm.GetData());
}
+ break;
}
- else
- {
- error.SetErrorString("invalid enumeration value");
- }
- break;
case eVarSetOperationInsertBefore:
case eVarSetOperationInsertAfter:
case eVarSetOperationRemove:
case eVarSetOperationAppend:
case eVarSetOperationInvalid:
- error = OptionValue::SetValueFromCString (value, op);
+ error = OptionValue::SetValueFromString (value, op);
break;
}
return error;
diff --git a/source/Interpreter/OptionValueFileSpec.cpp b/source/Interpreter/OptionValueFileSpec.cpp
index 3f466985a83a..3a282f177fea 100644
--- a/source/Interpreter/OptionValueFileSpec.cpp
+++ b/source/Interpreter/OptionValueFileSpec.cpp
@@ -7,8 +7,6 @@
//
//===----------------------------------------------------------------------===//
-#include "lldb/lldb-python.h"
-
#include "lldb/Interpreter/OptionValueFileSpec.h"
// C Includes
@@ -24,31 +22,39 @@ using namespace lldb;
using namespace lldb_private;
-OptionValueFileSpec::OptionValueFileSpec () :
+OptionValueFileSpec::OptionValueFileSpec (bool resolve) :
OptionValue(),
m_current_value (),
m_default_value (),
m_data_sp(),
- m_completion_mask (CommandCompletions::eDiskFileCompletion)
+ m_data_mod_time (),
+ m_completion_mask (CommandCompletions::eDiskFileCompletion),
+ m_resolve (resolve)
{
}
-OptionValueFileSpec::OptionValueFileSpec (const FileSpec &value) :
+OptionValueFileSpec::OptionValueFileSpec (const FileSpec &value,
+ bool resolve) :
OptionValue(),
m_current_value (value),
m_default_value (value),
m_data_sp(),
- m_completion_mask (CommandCompletions::eDiskFileCompletion)
+ m_data_mod_time (),
+ m_completion_mask (CommandCompletions::eDiskFileCompletion),
+ m_resolve (resolve)
{
}
OptionValueFileSpec::OptionValueFileSpec (const FileSpec &current_value,
- const FileSpec &default_value) :
+ const FileSpec &default_value,
+ bool resolve) :
OptionValue(),
m_current_value (current_value),
m_default_value (default_value),
m_data_sp(),
- m_completion_mask (CommandCompletions::eDiskFileCompletion)
+ m_data_mod_time (),
+ m_completion_mask (CommandCompletions::eDiskFileCompletion),
+ m_resolve (resolve)
{
}
@@ -70,7 +76,7 @@ OptionValueFileSpec::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, u
}
Error
-OptionValueFileSpec::SetValueFromCString (const char *value_cstr,
+OptionValueFileSpec::SetValueFromString (llvm::StringRef value,
VarSetOperationType op)
{
Error error;
@@ -83,24 +89,18 @@ OptionValueFileSpec::SetValueFromCString (const char *value_cstr,
case eVarSetOperationReplace:
case eVarSetOperationAssign:
- if (value_cstr && value_cstr[0])
+ if (value.size() > 0)
{
// The setting value may have whitespace, double-quotes, or single-quotes around the file
// path to indicate that internal spaces are not word breaks. Strip off any ws & quotes
// from the start and end of the file path - we aren't doing any word // breaking here so
// the quoting is unnecessary. NB this will cause a problem if someone tries to specify
// a file path that legitimately begins or ends with a " or ' character, or whitespace.
- std::string filepath(value_cstr);
- auto prefix_chars_to_trim = filepath.find_first_not_of ("\"' \t");
- if (prefix_chars_to_trim != std::string::npos && prefix_chars_to_trim > 0)
- filepath.erase(0, prefix_chars_to_trim);
- auto suffix_chars_to_trim = filepath.find_last_not_of ("\"' \t");
- if (suffix_chars_to_trim != std::string::npos && suffix_chars_to_trim < filepath.size())
- filepath.erase (suffix_chars_to_trim + 1);
-
+ value = value.trim("\"' \t");
m_value_was_set = true;
- m_current_value.SetFile(filepath.c_str(), true);
+ m_current_value.SetFile(value.str().c_str(), m_resolve);
m_data_sp.reset();
+ m_data_mod_time.Clear();
NotifyValueChanged();
}
else
@@ -114,7 +114,7 @@ OptionValueFileSpec::SetValueFromCString (const char *value_cstr,
case eVarSetOperationRemove:
case eVarSetOperationAppend:
case eVarSetOperationInvalid:
- error = OptionValue::SetValueFromCString (value_cstr, op);
+ error = OptionValue::SetValueFromString (value, op);
break;
}
return error;
@@ -153,12 +153,16 @@ OptionValueFileSpec::AutoComplete (CommandInterpreter &interpreter,
const lldb::DataBufferSP &
OptionValueFileSpec::GetFileContents(bool null_terminate)
{
- if (!m_data_sp && m_current_value)
+ if (m_current_value)
{
+ const TimeValue file_mod_time = m_current_value.GetModificationTime();
+ if (m_data_sp && m_data_mod_time == file_mod_time)
+ return m_data_sp;
if (null_terminate)
m_data_sp = m_current_value.ReadFileContentsAsCString();
else
m_data_sp = m_current_value.ReadFileContents();
+ m_data_mod_time = file_mod_time;
}
return m_data_sp;
}
diff --git a/source/Interpreter/OptionValueFileSpecLIst.cpp b/source/Interpreter/OptionValueFileSpecLIst.cpp
index 0e696ca91db6..669d3ee33acc 100644
--- a/source/Interpreter/OptionValueFileSpecLIst.cpp
+++ b/source/Interpreter/OptionValueFileSpecLIst.cpp
@@ -42,10 +42,10 @@ OptionValueFileSpecList::DumpValue (const ExecutionContext *exe_ctx, Stream &str
}
Error
-OptionValueFileSpecList::SetValueFromCString (const char *value, VarSetOperationType op)
+OptionValueFileSpecList::SetValueFromString (llvm::StringRef value, VarSetOperationType op)
{
Error error;
- Args args(value);
+ Args args(value.str().c_str());
const size_t argc = args.GetArgumentCount();
switch (op)
@@ -174,7 +174,7 @@ OptionValueFileSpecList::SetValueFromCString (const char *value, VarSetOperation
break;
case eVarSetOperationInvalid:
- error = OptionValue::SetValueFromCString (value, op);
+ error = OptionValue::SetValueFromString (value, op);
break;
}
return error;
diff --git a/source/Interpreter/OptionValueFormat.cpp b/source/Interpreter/OptionValueFormat.cpp
index d91f10b0edeb..1d73d58ce8e1 100644
--- a/source/Interpreter/OptionValueFormat.cpp
+++ b/source/Interpreter/OptionValueFormat.cpp
@@ -7,8 +7,6 @@
//
//===----------------------------------------------------------------------===//
-#include "lldb/lldb-python.h"
-
#include "lldb/Interpreter/OptionValueFormat.h"
// C Includes
@@ -36,7 +34,7 @@ OptionValueFormat::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uin
}
Error
-OptionValueFormat::SetValueFromCString (const char *value_cstr, VarSetOperationType op)
+OptionValueFormat::SetValueFromString (llvm::StringRef value, VarSetOperationType op)
{
Error error;
switch (op)
@@ -50,7 +48,7 @@ OptionValueFormat::SetValueFromCString (const char *value_cstr, VarSetOperationT
case eVarSetOperationAssign:
{
Format new_format;
- error = Args::StringToFormat (value_cstr, new_format, nullptr);
+ error = Args::StringToFormat (value.str().c_str(), new_format, nullptr);
if (error.Success())
{
m_value_was_set = true;
@@ -65,7 +63,7 @@ OptionValueFormat::SetValueFromCString (const char *value_cstr, VarSetOperationT
case eVarSetOperationRemove:
case eVarSetOperationAppend:
case eVarSetOperationInvalid:
- error = OptionValue::SetValueFromCString (value_cstr, op);
+ error = OptionValue::SetValueFromString (value, op);
break;
}
return error;
diff --git a/source/Interpreter/OptionValueFormatEntity.cpp b/source/Interpreter/OptionValueFormatEntity.cpp
index fb8c682a03f8..66d8d8419ed8 100644
--- a/source/Interpreter/OptionValueFormatEntity.cpp
+++ b/source/Interpreter/OptionValueFormatEntity.cpp
@@ -7,8 +7,6 @@
//
//===----------------------------------------------------------------------===//
-#include "lldb/lldb-python.h"
-
#include "lldb/Interpreter/OptionValueFormatEntity.h"
// C Includes
@@ -67,8 +65,8 @@ OptionValueFormatEntity::DumpValue (const ExecutionContext *exe_ctx, Stream &str
}
Error
-OptionValueFormatEntity::SetValueFromCString (const char *value_cstr,
- VarSetOperationType op)
+OptionValueFormatEntity::SetValueFromString (llvm::StringRef value_str,
+ VarSetOperationType op)
{
Error error;
switch (op)
@@ -81,13 +79,31 @@ OptionValueFormatEntity::SetValueFromCString (const char *value_cstr,
case eVarSetOperationReplace:
case eVarSetOperationAssign:
{
+ // Check if the string starts with a quote character after removing leading and trailing spaces.
+ // If it does start with a quote character, make sure it ends with the same quote character
+ // and remove the quotes before we parse the format string. If the string doesn't start with
+ // a quote, leave the string alone and parse as is.
+ llvm::StringRef trimmed_value_str = value_str.trim();
+ if (!trimmed_value_str.empty())
+ {
+ const char first_char = trimmed_value_str[0];
+ if (first_char == '"' || first_char == '\'')
+ {
+ const size_t trimmed_len = trimmed_value_str.size();
+ if (trimmed_len == 1 || value_str[trimmed_len-1] != first_char)
+ {
+ error.SetErrorStringWithFormat("mismatched quotes");
+ return error;
+ }
+ value_str = trimmed_value_str.substr(1,trimmed_len-2);
+ }
+ }
FormatEntity::Entry entry;
- llvm::StringRef value_str(value_cstr);
error = FormatEntity::Parse(value_str, entry);
if (error.Success())
{
m_current_entry = std::move(entry);
- m_current_format = value_cstr;
+ m_current_format = value_str;
m_value_was_set = true;
NotifyValueChanged();
}
@@ -99,7 +115,7 @@ OptionValueFormatEntity::SetValueFromCString (const char *value_cstr,
case eVarSetOperationRemove:
case eVarSetOperationAppend:
case eVarSetOperationInvalid:
- error = OptionValue::SetValueFromCString (value_cstr, op);
+ error = OptionValue::SetValueFromString (value_str, op);
break;
}
return error;
diff --git a/source/Interpreter/OptionValueLanguage.cpp b/source/Interpreter/OptionValueLanguage.cpp
new file mode 100644
index 000000000000..fd46553dabde
--- /dev/null
+++ b/source/Interpreter/OptionValueLanguage.cpp
@@ -0,0 +1,73 @@
+//===-- OptionValueFormat.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/OptionValueLanguage.h"
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Core/Stream.h"
+#include "lldb/DataFormatters/FormatManager.h"
+#include "lldb/Interpreter/Args.h"
+#include "lldb/Target/LanguageRuntime.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+void
+OptionValueLanguage::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask)
+{
+ if (dump_mask & eDumpOptionType)
+ strm.Printf ("(%s)", GetTypeAsCString ());
+ if (dump_mask & eDumpOptionValue)
+ {
+ if (dump_mask & eDumpOptionType)
+ strm.PutCString (" = ");
+ strm.PutCString (LanguageRuntime::GetNameForLanguageType(m_current_value));
+ }
+}
+
+Error
+OptionValueLanguage::SetValueFromString (llvm::StringRef value, VarSetOperationType op)
+{
+ Error error;
+ switch (op)
+ {
+ case eVarSetOperationClear:
+ Clear();
+ break;
+
+ case eVarSetOperationReplace:
+ case eVarSetOperationAssign:
+ {
+ LanguageType new_type = LanguageRuntime::GetLanguageTypeFromString(value.data());
+ m_value_was_set = true;
+ m_current_value = new_type;
+ }
+ break;
+
+ case eVarSetOperationInsertBefore:
+ case eVarSetOperationInsertAfter:
+ case eVarSetOperationRemove:
+ case eVarSetOperationAppend:
+ case eVarSetOperationInvalid:
+ error = OptionValue::SetValueFromString(value, op);
+ break;
+ }
+ return error;
+}
+
+
+lldb::OptionValueSP
+OptionValueLanguage::DeepCopy () const
+{
+ return OptionValueSP(new OptionValueLanguage(*this));
+}
+
diff --git a/source/Interpreter/OptionValuePathMappings.cpp b/source/Interpreter/OptionValuePathMappings.cpp
index b1e714e97073..722d6a144279 100644
--- a/source/Interpreter/OptionValuePathMappings.cpp
+++ b/source/Interpreter/OptionValuePathMappings.cpp
@@ -34,10 +34,10 @@ OptionValuePathMappings::DumpValue (const ExecutionContext *exe_ctx, Stream &str
}
Error
-OptionValuePathMappings::SetValueFromCString (const char *value, VarSetOperationType op)
+OptionValuePathMappings::SetValueFromString (llvm::StringRef value, VarSetOperationType op)
{
Error error;
- Args args(value);
+ Args args(value.str().c_str());
const size_t argc = args.GetArgumentCount();
switch (op)
@@ -175,7 +175,7 @@ OptionValuePathMappings::SetValueFromCString (const char *value, VarSetOperation
break;
case eVarSetOperationInvalid:
- error = OptionValue::SetValueFromCString (value, op);
+ error = OptionValue::SetValueFromString (value, op);
break;
}
return error;
diff --git a/source/Interpreter/OptionValueProperties.cpp b/source/Interpreter/OptionValueProperties.cpp
index cf7abaa6ac25..e8d870a99cf8 100644
--- a/source/Interpreter/OptionValueProperties.cpp
+++ b/source/Interpreter/OptionValueProperties.cpp
@@ -226,7 +226,7 @@ OptionValueProperties::SetSubValue (const ExecutionContext *exe_ctx,
const bool will_modify = true;
lldb::OptionValueSP value_sp (GetSubValue (exe_ctx, name, will_modify, error));
if (value_sp)
- error = value_sp->SetValueFromCString(value, op);
+ error = value_sp->SetValueFromString(value ? llvm::StringRef(value) : llvm::StringRef(), op);
else
{
if (error.AsCString() == nullptr)
@@ -600,7 +600,7 @@ OptionValueProperties::Clear ()
Error
-OptionValueProperties::SetValueFromCString (const char *value, VarSetOperationType op)
+OptionValueProperties::SetValueFromString (llvm::StringRef value, VarSetOperationType op)
{
Error error;
@@ -619,7 +619,7 @@ OptionValueProperties::SetValueFromCString (const char *value, VarSetOperationTy
case eVarSetOperationInsertAfter:
case eVarSetOperationAppend:
case eVarSetOperationInvalid:
- error = OptionValue::SetValueFromCString (value, op);
+ error = OptionValue::SetValueFromString (value, op);
break;
}
diff --git a/source/Interpreter/OptionValueRegex.cpp b/source/Interpreter/OptionValueRegex.cpp
index fab462f0e704..ebe7ae2feb91 100644
--- a/source/Interpreter/OptionValueRegex.cpp
+++ b/source/Interpreter/OptionValueRegex.cpp
@@ -41,7 +41,7 @@ OptionValueRegex::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint
}
Error
-OptionValueRegex::SetValueFromCString (const char *value_cstr,
+OptionValueRegex::SetValueFromString (llvm::StringRef value,
VarSetOperationType op)
{
Error error;
@@ -52,7 +52,7 @@ OptionValueRegex::SetValueFromCString (const char *value_cstr,
case eVarSetOperationInsertAfter:
case eVarSetOperationRemove:
case eVarSetOperationAppend:
- error = OptionValue::SetValueFromCString (value_cstr, op);
+ error = OptionValue::SetValueFromString (value, op);
break;
case eVarSetOperationClear:
@@ -62,7 +62,7 @@ OptionValueRegex::SetValueFromCString (const char *value_cstr,
case eVarSetOperationReplace:
case eVarSetOperationAssign:
- if (m_regex.Compile (value_cstr))
+ if (m_regex.Compile (value.str().c_str()))
{
m_value_was_set = true;
NotifyValueChanged();
diff --git a/source/Interpreter/OptionValueSInt64.cpp b/source/Interpreter/OptionValueSInt64.cpp
index c69172921a6d..97cdf10b7c75 100644
--- a/source/Interpreter/OptionValueSInt64.cpp
+++ b/source/Interpreter/OptionValueSInt64.cpp
@@ -36,9 +36,8 @@ OptionValueSInt64::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uin
}
Error
-OptionValueSInt64::SetValueFromCString (const char *value_cstr, VarSetOperationType op)
+OptionValueSInt64::SetValueFromString (llvm::StringRef value_ref, VarSetOperationType op)
{
- //printf ("%p: SetValueFromCString (s=\"%s\", op=%i)\n", this, value_cstr, op);
Error error;
switch (op)
{
@@ -51,7 +50,8 @@ OptionValueSInt64::SetValueFromCString (const char *value_cstr, VarSetOperationT
case eVarSetOperationAssign:
{
bool success = false;
- int64_t value = StringConvert::ToSInt64 (value_cstr, 0, 0, &success);
+ std::string value_str = value_ref.trim().str();
+ int64_t value = StringConvert::ToSInt64 (value_str.c_str(), 0, 0, &success);
if (success)
{
if (value >= m_min_value && value <= m_max_value)
@@ -68,7 +68,8 @@ OptionValueSInt64::SetValueFromCString (const char *value_cstr, VarSetOperationT
}
else
{
- error.SetErrorStringWithFormat ("invalid int64_t string value: '%s'", value_cstr);
+ error.SetErrorStringWithFormat ("invalid int64_t string value: '%s'",
+ value_ref.str().c_str());
}
}
break;
@@ -78,7 +79,7 @@ OptionValueSInt64::SetValueFromCString (const char *value_cstr, VarSetOperationT
case eVarSetOperationRemove:
case eVarSetOperationAppend:
case eVarSetOperationInvalid:
- error = OptionValue::SetValueFromCString (value_cstr, op);
+ error = OptionValue::SetValueFromString (value_ref, op);
break;
}
return error;
diff --git a/source/Interpreter/OptionValueString.cpp b/source/Interpreter/OptionValueString.cpp
index a1b80d8fc4f6..63f006e643f9 100644
--- a/source/Interpreter/OptionValueString.cpp
+++ b/source/Interpreter/OptionValueString.cpp
@@ -51,30 +51,30 @@ OptionValueString::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uin
}
Error
-OptionValueString::SetValueFromCString (const char *value_cstr,
+OptionValueString::SetValueFromString (llvm::StringRef value,
VarSetOperationType op)
{
Error error;
- std::string value_str_no_quotes;
- if (value_cstr)
+ std::string value_str = value.str();
+ value = value.trim();
+ if (value.size() > 0)
{
- switch (value_cstr[0])
+ switch (value.front())
{
case '"':
case '\'':
{
- size_t len = strlen(value_cstr);
- if (len <= 1 || value_cstr[len-1] != value_cstr[0])
+ if (value.size() <= 1 || value.back() != value.front())
{
error.SetErrorString("mismatched quotes");
return error;
}
- value_str_no_quotes.assign (value_cstr + 1, len - 2);
- value_cstr = value_str_no_quotes.c_str();
+ value = value.drop_front().drop_back();
}
break;
}
+ value_str = value.str();
}
switch (op)
@@ -85,26 +85,26 @@ OptionValueString::SetValueFromCString (const char *value_cstr,
case eVarSetOperationRemove:
if (m_validator)
{
- error = m_validator(value_cstr,m_validator_baton);
+ error = m_validator(value_str.c_str(),m_validator_baton);
if (error.Fail())
return error;
}
- error = OptionValue::SetValueFromCString (value_cstr, op);
+ error = OptionValue::SetValueFromString (value, op);
break;
case eVarSetOperationAppend:
{
std::string new_value(m_current_value);
- if (value_cstr && value_cstr[0])
+ if (value.size() > 0)
{
if (m_options.Test (eOptionEncodeCharacterEscapeSequences))
{
std::string str;
- Args::EncodeEscapeSequences (value_cstr, str);
+ Args::EncodeEscapeSequences (value_str.c_str(), str);
new_value.append(str);
}
else
- new_value.append(value_cstr);
+ new_value.append(value);
}
if (m_validator)
{
@@ -126,18 +126,18 @@ OptionValueString::SetValueFromCString (const char *value_cstr,
case eVarSetOperationAssign:
if (m_validator)
{
- error = m_validator(value_cstr,m_validator_baton);
+ error = m_validator(value_str.c_str(), m_validator_baton);
if (error.Fail())
return error;
}
m_value_was_set = true;
if (m_options.Test (eOptionEncodeCharacterEscapeSequences))
{
- Args::EncodeEscapeSequences (value_cstr, m_current_value);
+ Args::EncodeEscapeSequences (value_str.c_str(), m_current_value);
}
else
{
- SetCurrentValue (value_cstr);
+ SetCurrentValue (value_str.c_str());
}
NotifyValueChanged();
break;
diff --git a/source/Interpreter/OptionValueUInt64.cpp b/source/Interpreter/OptionValueUInt64.cpp
index 48de433d36c1..b414802b963b 100644
--- a/source/Interpreter/OptionValueUInt64.cpp
+++ b/source/Interpreter/OptionValueUInt64.cpp
@@ -23,7 +23,7 @@ lldb::OptionValueSP
OptionValueUInt64::Create (const char *value_cstr, Error &error)
{
lldb::OptionValueSP value_sp (new OptionValueUInt64());
- error = value_sp->SetValueFromCString (value_cstr);
+ error = value_sp->SetValueFromString (value_cstr);
if (error.Fail())
value_sp.reset();
return value_sp;
@@ -44,7 +44,7 @@ OptionValueUInt64::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uin
}
Error
-OptionValueUInt64::SetValueFromCString (const char *value_cstr, VarSetOperationType op)
+OptionValueUInt64::SetValueFromString (llvm::StringRef value_ref, VarSetOperationType op)
{
Error error;
switch (op)
@@ -58,7 +58,8 @@ OptionValueUInt64::SetValueFromCString (const char *value_cstr, VarSetOperationT
case eVarSetOperationAssign:
{
bool success = false;
- uint64_t value = StringConvert::ToUInt64 (value_cstr, 0, 0, &success);
+ std::string value_str = value_ref.trim().str();
+ uint64_t value = StringConvert::ToUInt64 (value_str.c_str(), 0, 0, &success);
if (success)
{
m_value_was_set = true;
@@ -67,7 +68,7 @@ OptionValueUInt64::SetValueFromCString (const char *value_cstr, VarSetOperationT
}
else
{
- error.SetErrorStringWithFormat ("invalid uint64_t string value: '%s'", value_cstr);
+ error.SetErrorStringWithFormat ("invalid uint64_t string value: '%s'", value_str.c_str());
}
}
break;
@@ -77,7 +78,7 @@ OptionValueUInt64::SetValueFromCString (const char *value_cstr, VarSetOperationT
case eVarSetOperationRemove:
case eVarSetOperationAppend:
case eVarSetOperationInvalid:
- error = OptionValue::SetValueFromCString (value_cstr, op);
+ error = OptionValue::SetValueFromString (value_ref, op);
break;
}
return error;
diff --git a/source/Interpreter/OptionValueUUID.cpp b/source/Interpreter/OptionValueUUID.cpp
index c228cf6e415e..b16a9eb7e994 100644
--- a/source/Interpreter/OptionValueUUID.cpp
+++ b/source/Interpreter/OptionValueUUID.cpp
@@ -7,8 +7,6 @@
//
//===----------------------------------------------------------------------===//
-#include "lldb/lldb-python.h"
-
#include "lldb/Interpreter/OptionValueUUID.h"
// C Includes
@@ -37,7 +35,7 @@ OptionValueUUID::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint3
}
Error
-OptionValueUUID::SetValueFromCString (const char *value_cstr,
+OptionValueUUID::SetValueFromString (llvm::StringRef value,
VarSetOperationType op)
{
Error error;
@@ -51,8 +49,8 @@ OptionValueUUID::SetValueFromCString (const char *value_cstr,
case eVarSetOperationReplace:
case eVarSetOperationAssign:
{
- if (m_uuid.SetFromCString(value_cstr) == 0)
- error.SetErrorStringWithFormat ("invalid uuid string value '%s'", value_cstr);
+ if (m_uuid.SetFromCString(value.str().c_str()) == 0)
+ error.SetErrorStringWithFormat ("invalid uuid string value '%s'", value.str().c_str());
else
{
m_value_was_set = true;
@@ -66,7 +64,7 @@ OptionValueUUID::SetValueFromCString (const char *value_cstr,
case eVarSetOperationRemove:
case eVarSetOperationAppend:
case eVarSetOperationInvalid:
- error = OptionValue::SetValueFromCString (value_cstr, op);
+ error = OptionValue::SetValueFromString (value, op);
break;
}
return error;
diff --git a/source/Interpreter/Options.cpp b/source/Interpreter/Options.cpp
index a8766f5f8615..7f0e0abc03ea 100644
--- a/source/Interpreter/Options.cpp
+++ b/source/Interpreter/Options.cpp
@@ -7,8 +7,6 @@
//
//===----------------------------------------------------------------------===//
-#include "lldb/lldb-python.h"
-
#include "lldb/Interpreter/Options.h"
// C Includes
@@ -944,7 +942,7 @@ Options::HandleOptionArgumentCompletion
lldb::CommandArgumentType option_arg_type = opt_defs[opt_defs_index].argument_type;
if (option_arg_type != eArgTypeNone)
{
- CommandObject::ArgumentTableEntry *arg_entry = CommandObject::FindArgumentDataByType (opt_defs[opt_defs_index].argument_type);
+ const CommandObject::ArgumentTableEntry *arg_entry = CommandObject::FindArgumentDataByType (opt_defs[opt_defs_index].argument_type);
if (arg_entry)
completion_mask = arg_entry->completion_type;
}
diff --git a/source/Interpreter/Property.cpp b/source/Interpreter/Property.cpp
index 5679ef8dd3ba..077fcbc54cc3 100644
--- a/source/Interpreter/Property.cpp
+++ b/source/Interpreter/Property.cpp
@@ -7,8 +7,6 @@
//
//===----------------------------------------------------------------------===//
-#include "lldb/lldb-python.h"
-
#include "lldb/Interpreter/Property.h"
// C Includes
@@ -19,6 +17,7 @@
#include "lldb/Host/StringConvert.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/OptionValues.h"
+#include "lldb/Target/LanguageRuntime.h"
using namespace lldb;
using namespace lldb_private;
@@ -80,11 +79,11 @@ Property::Property (const PropertyDefinition &definition) :
m_value_sp.reset (enum_value);
if (definition.default_cstr_value)
{
- if (enum_value->SetValueFromCString(definition.default_cstr_value).Success())
+ if (enum_value->SetValueFromString(definition.default_cstr_value).Success())
{
enum_value->SetDefaultValue(enum_value->GetCurrentValue());
// Call Clear() since we don't want the value to appear as
- // having been set since we called SetValueFromCString() above.
+ // having been set since we called SetValueFromString() above.
// Clear will set the current value to the default and clear
// the boolean that says that the value has been set.
enum_value->Clear();
@@ -94,10 +93,13 @@ Property::Property (const PropertyDefinition &definition) :
break;
case OptionValue::eTypeFileSpec:
+ {
// "definition.default_uint_value" represents if the "definition.default_cstr_value" should
// be resolved or not
- m_value_sp.reset (new OptionValueFileSpec(FileSpec(definition.default_cstr_value, definition.default_uint_value != 0)));
+ const bool resolve = definition.default_uint_value != 0;
+ m_value_sp.reset (new OptionValueFileSpec(FileSpec(definition.default_cstr_value, resolve), resolve));
break;
+ }
case OptionValue::eTypeFileSpecList:
// "definition.default_uint_value" is not used for a OptionValue::eTypeFileSpecList
@@ -119,6 +121,21 @@ Property::Property (const PropertyDefinition &definition) :
}
break;
+ case OptionValue::eTypeLanguage:
+ // "definition.default_uint_value" is the default language enumeration value if
+ // "definition.default_cstr_value" is NULL, otherwise interpret
+ // "definition.default_cstr_value" as a string value that represents the default
+ // value.
+ {
+ LanguageType new_lang = eLanguageTypeUnknown;
+ if (definition.default_cstr_value)
+ LanguageRuntime::GetLanguageTypeFromString(definition.default_cstr_value);
+ else
+ new_lang = (LanguageType)definition.default_uint_value;
+ m_value_sp.reset (new OptionValueLanguage(new_lang));
+ }
+ break;
+
case OptionValue::eTypeFormatEntity:
// "definition.default_cstr_value" as a string value that represents the default
m_value_sp.reset (new OptionValueFormatEntity(definition.default_cstr_value));
diff --git a/source/Interpreter/PythonDataObjects.cpp b/source/Interpreter/PythonDataObjects.cpp
index 3ea6c0dbe3e5..a581a0b3601a 100644
--- a/source/Interpreter/PythonDataObjects.cpp
+++ b/source/Interpreter/PythonDataObjects.cpp
@@ -23,19 +23,20 @@
#include "lldb/Host/File.h"
#include "lldb/Interpreter/PythonDataObjects.h"
#include "lldb/Interpreter/ScriptInterpreter.h"
+#include "lldb/Interpreter/ScriptInterpreterPython.h"
using namespace lldb_private;
using namespace lldb;
+void
+StructuredPythonObject::Dump(Stream &s) const
+{
+ s << "Python Obj: 0x" << GetValue();
+}
+
//----------------------------------------------------------------------
// PythonObject
//----------------------------------------------------------------------
-PythonObject::PythonObject (const lldb::ScriptInterpreterObjectSP &script_object_sp) :
- m_py_obj (nullptr)
-{
- if (script_object_sp)
- Reset ((PyObject *)script_object_sp->GetObject());
-}
void
PythonObject::Dump (Stream &strm) const
@@ -62,6 +63,23 @@ PythonObject::Dump (Stream &strm) const
strm.PutCString ("NULL");
}
+PyObjectType
+PythonObject::GetObjectType() const
+{
+ if (IsNULLOrNone())
+ return PyObjectType::None;
+
+ if (PyList_Check(m_py_obj))
+ return PyObjectType::List;
+ if (PyDict_Check(m_py_obj))
+ return PyObjectType::Dictionary;
+ if (PyString_Check(m_py_obj))
+ return PyObjectType::String;
+ if (PyInt_Check(m_py_obj) || PyLong_Check(m_py_obj))
+ return PyObjectType::Integer;
+ return PyObjectType::Unknown;
+}
+
PythonString
PythonObject::Repr ()
{
@@ -90,6 +108,26 @@ PythonObject::IsNULLOrNone () const
return ((m_py_obj == nullptr) || (m_py_obj == Py_None));
}
+StructuredData::ObjectSP
+PythonObject::CreateStructuredObject() const
+{
+ switch (GetObjectType())
+ {
+ case PyObjectType::Dictionary:
+ return PythonDictionary(m_py_obj).CreateStructuredDictionary();
+ case PyObjectType::Integer:
+ return PythonInteger(m_py_obj).CreateStructuredInteger();
+ case PyObjectType::List:
+ return PythonList(m_py_obj).CreateStructuredArray();
+ case PyObjectType::String:
+ return PythonString(m_py_obj).CreateStructuredString();
+ case PyObjectType::None:
+ return StructuredData::ObjectSP();
+ default:
+ return StructuredData::ObjectSP(new StructuredPythonObject(m_py_obj));
+ }
+}
+
//----------------------------------------------------------------------
// PythonString
//----------------------------------------------------------------------
@@ -106,14 +144,12 @@ PythonString::PythonString (const PythonObject &object) :
Reset(object.get()); // Use "Reset()" to ensure that py_obj is a string
}
-PythonString::PythonString (const lldb::ScriptInterpreterObjectSP &script_object_sp) :
- PythonObject()
+PythonString::PythonString (llvm::StringRef string) :
+ PythonObject(PyString_FromStringAndSize(string.data(), string.size()))
{
- if (script_object_sp)
- Reset((PyObject *)script_object_sp->GetObject()); // Use "Reset()" to ensure that py_obj is a string
}
-PythonString::PythonString (const char* string) :
+PythonString::PythonString(const char *string) :
PythonObject(PyString_FromString(string))
{
}
@@ -137,12 +173,12 @@ PythonString::Reset (PyObject *py_obj)
return py_obj == nullptr;
}
-const char*
+llvm::StringRef
PythonString::GetString() const
{
if (m_py_obj)
- return PyString_AsString(m_py_obj);
- return nullptr;
+ return llvm::StringRef(PyString_AsString(m_py_obj), GetSize());
+ return llvm::StringRef();
}
size_t
@@ -154,9 +190,17 @@ PythonString::GetSize() const
}
void
-PythonString::SetString (const char* string)
+PythonString::SetString (llvm::StringRef string)
{
- PythonObject::Reset(PyString_FromString(string));
+ PythonObject::Reset(PyString_FromStringAndSize(string.data(), string.size()));
+}
+
+StructuredData::StringSP
+PythonString::CreateStructuredString() const
+{
+ StructuredData::StringSP result(new StructuredData::String);
+ result->SetValue(GetString());
+ return result;
}
//----------------------------------------------------------------------
@@ -175,13 +219,6 @@ PythonInteger::PythonInteger (const PythonObject &object) :
Reset(object.get()); // Use "Reset()" to ensure that py_obj is a integer type
}
-PythonInteger::PythonInteger (const lldb::ScriptInterpreterObjectSP &script_object_sp) :
- PythonObject()
-{
- if (script_object_sp)
- Reset((PyObject *)script_object_sp->GetObject()); // Use "Reset()" to ensure that py_obj is a string
-}
-
PythonInteger::PythonInteger (int64_t value) :
PythonObject()
{
@@ -207,7 +244,7 @@ PythonInteger::Reset (PyObject *py_obj)
}
int64_t
-PythonInteger::GetInteger()
+PythonInteger::GetInteger() const
{
if (m_py_obj)
{
@@ -225,6 +262,14 @@ PythonInteger::SetInteger (int64_t value)
PythonObject::Reset(PyLong_FromLongLong(value));
}
+StructuredData::IntegerSP
+PythonInteger::CreateStructuredInteger() const
+{
+ StructuredData::IntegerSP result(new StructuredData::Integer);
+ result->SetValue(GetInteger());
+ return result;
+}
+
//----------------------------------------------------------------------
// PythonList
//----------------------------------------------------------------------
@@ -252,13 +297,6 @@ PythonList::PythonList (const PythonObject &object) :
Reset(object.get()); // Use "Reset()" to ensure that py_obj is a list
}
-PythonList::PythonList (const lldb::ScriptInterpreterObjectSP &script_object_sp) :
- PythonObject()
-{
- if (script_object_sp)
- Reset((PyObject *)script_object_sp->GetObject()); // Use "Reset()" to ensure that py_obj is a list
-}
-
PythonList::~PythonList ()
{
}
@@ -274,7 +312,7 @@ PythonList::Reset (PyObject *py_obj)
}
uint32_t
-PythonList::GetSize()
+PythonList::GetSize() const
{
if (m_py_obj)
return PyList_GET_SIZE(m_py_obj);
@@ -282,7 +320,7 @@ PythonList::GetSize()
}
PythonObject
-PythonList::GetItemAtIndex (uint32_t index)
+PythonList::GetItemAtIndex(uint32_t index) const
{
if (m_py_obj)
return PythonObject(PyList_GetItem(m_py_obj, index));
@@ -303,6 +341,19 @@ PythonList::AppendItem (const PythonObject &object)
PyList_Append(m_py_obj, object.get());
}
+StructuredData::ArraySP
+PythonList::CreateStructuredArray() const
+{
+ StructuredData::ArraySP result(new StructuredData::Array);
+ uint32_t count = GetSize();
+ for (uint32_t i = 0; i < count; ++i)
+ {
+ PythonObject obj = GetItemAtIndex(i);
+ result->AddItem(obj.CreateStructuredObject());
+ }
+ return result;
+}
+
//----------------------------------------------------------------------
// PythonDictionary
//----------------------------------------------------------------------
@@ -325,13 +376,6 @@ PythonDictionary::PythonDictionary (const PythonObject &object) :
Reset(object.get()); // Use "Reset()" to ensure that py_obj is a dictionary
}
-PythonDictionary::PythonDictionary (const lldb::ScriptInterpreterObjectSP &script_object_sp) :
- PythonObject ()
-{
- if (script_object_sp)
- Reset((PyObject *)script_object_sp->GetObject()); // Use "Reset()" to ensure that py_obj is a dictionary
-}
-
PythonDictionary::~PythonDictionary ()
{
}
@@ -347,7 +391,7 @@ PythonDictionary::Reset (PyObject *py_obj)
}
uint32_t
-PythonDictionary::GetSize()
+PythonDictionary::GetSize() const
{
if (m_py_obj)
return PyDict_Size(m_py_obj);
@@ -460,4 +504,21 @@ PythonDictionary::SetItemForKey (const PythonString &key, const PythonObject &va
PyDict_SetItem(m_py_obj, key.get(), value.get());
}
+StructuredData::DictionarySP
+PythonDictionary::CreateStructuredDictionary() const
+{
+ StructuredData::DictionarySP result(new StructuredData::Dictionary);
+ PythonList keys(GetKeys());
+ uint32_t num_keys = keys.GetSize();
+ for (uint32_t i = 0; i < num_keys; ++i)
+ {
+ PythonObject key = keys.GetItemAtIndex(i);
+ PythonString key_str = key.Str();
+ PythonObject value = GetItemForKey(key);
+ StructuredData::ObjectSP structured_value = value.CreateStructuredObject();
+ result->AddItem(key_str.GetString(), structured_value);
+ }
+ return result;
+}
+
#endif
diff --git a/source/Interpreter/ScriptInterpreter.cpp b/source/Interpreter/ScriptInterpreter.cpp
index 45e3b44cc0ac..f1ec50e663fd 100644
--- a/source/Interpreter/ScriptInterpreter.cpp
+++ b/source/Interpreter/ScriptInterpreter.cpp
@@ -7,8 +7,6 @@
//
//===----------------------------------------------------------------------===//
-#include "lldb/lldb-python.h"
-
#include "lldb/Interpreter/ScriptInterpreter.h"
#include <string>
@@ -19,7 +17,6 @@
#include "lldb/Core/Stream.h"
#include "lldb/Core/StringList.h"
#include "lldb/Interpreter/CommandReturnObject.h"
-#include "lldb/Interpreter/ScriptInterpreterPython.h"
#include "lldb/Utility/PseudoTerminal.h"
using namespace lldb;
@@ -110,57 +107,3 @@ ScriptInterpreter::AcquireInterpreterLock ()
{
return std::unique_ptr<ScriptInterpreterLocker>(new ScriptInterpreterLocker());
}
-
-void
-ScriptInterpreter::InitializeInterpreter (SWIGInitCallback python_swig_init_callback,
- SWIGBreakpointCallbackFunction swig_breakpoint_callback,
- SWIGWatchpointCallbackFunction swig_watchpoint_callback,
- SWIGPythonTypeScriptCallbackFunction swig_typescript_callback,
- SWIGPythonCreateSyntheticProvider swig_synthetic_script,
- SWIGPythonCalculateNumChildren swig_calc_children,
- SWIGPythonGetChildAtIndex swig_get_child_index,
- SWIGPythonGetIndexOfChildWithName swig_get_index_child,
- SWIGPythonCastPyObjectToSBValue swig_cast_to_sbvalue ,
- SWIGPythonGetValueObjectSPFromSBValue swig_get_valobj_sp_from_sbvalue,
- SWIGPythonUpdateSynthProviderInstance swig_update_provider,
- SWIGPythonMightHaveChildrenSynthProviderInstance swig_mighthavechildren_provider,
- SWIGPythonGetValueSynthProviderInstance swig_getvalue_provider,
- SWIGPythonCallCommand swig_call_command,
- SWIGPythonCallModuleInit swig_call_module_init,
- SWIGPythonCreateOSPlugin swig_create_os_plugin,
- SWIGPythonScriptKeyword_Process swig_run_script_keyword_process,
- SWIGPythonScriptKeyword_Thread swig_run_script_keyword_thread,
- SWIGPythonScriptKeyword_Target swig_run_script_keyword_target,
- SWIGPythonScriptKeyword_Frame swig_run_script_keyword_frame,
- SWIGPythonScriptKeyword_Value swig_run_script_keyword_value,
- SWIGPython_GetDynamicSetting swig_plugin_get,
- SWIGPythonCreateScriptedThreadPlan swig_thread_plan_script,
- SWIGPythonCallThreadPlan swig_call_thread_plan)
-{
-#ifndef LLDB_DISABLE_PYTHON
- ScriptInterpreterPython::InitializeInterpreter (python_swig_init_callback,
- swig_breakpoint_callback,
- swig_watchpoint_callback,
- swig_typescript_callback,
- swig_synthetic_script,
- swig_calc_children,
- swig_get_child_index,
- swig_get_index_child,
- swig_cast_to_sbvalue ,
- swig_get_valobj_sp_from_sbvalue,
- swig_update_provider,
- swig_mighthavechildren_provider,
- swig_getvalue_provider,
- swig_call_command,
- swig_call_module_init,
- swig_create_os_plugin,
- swig_run_script_keyword_process,
- swig_run_script_keyword_thread,
- swig_run_script_keyword_target,
- swig_run_script_keyword_frame,
- swig_run_script_keyword_value,
- swig_plugin_get,
- swig_thread_plan_script,
- swig_call_thread_plan);
-#endif // #ifndef LLDB_DISABLE_PYTHON
-}
diff --git a/source/Interpreter/ScriptInterpreterNone.cpp b/source/Interpreter/ScriptInterpreterNone.cpp
index e33480d1a6d5..909a1161c9c1 100644
--- a/source/Interpreter/ScriptInterpreterNone.cpp
+++ b/source/Interpreter/ScriptInterpreterNone.cpp
@@ -7,8 +7,6 @@
//
//===----------------------------------------------------------------------===//
-#include "lldb/lldb-python.h"
-
#include "lldb/Interpreter/ScriptInterpreterNone.h"
#include "lldb/Core/Stream.h"
#include "lldb/Core/StreamFile.h"
diff --git a/source/Interpreter/ScriptInterpreterPython.cpp b/source/Interpreter/ScriptInterpreterPython.cpp
index 8155cbb189fe..8f60793550c3 100644
--- a/source/Interpreter/ScriptInterpreterPython.cpp
+++ b/source/Interpreter/ScriptInterpreterPython.cpp
@@ -30,6 +30,8 @@
#include "lldb/Core/Communication.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Timer.h"
+#include "lldb/Core/ValueObject.h"
+#include "lldb/DataFormatters/TypeSummary.h"
#include "lldb/Host/ConnectionFileDescriptor.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Host/Pipe.h"
@@ -43,34 +45,39 @@
#include "lldb/Host/windows/ConnectionGenericFileWindows.h"
#endif
+#include "llvm/ADT/StringRef.h"
+
using namespace lldb;
using namespace lldb_private;
-
-static ScriptInterpreter::SWIGInitCallback g_swig_init_callback = nullptr;
-static ScriptInterpreter::SWIGBreakpointCallbackFunction g_swig_breakpoint_callback = nullptr;
-static ScriptInterpreter::SWIGWatchpointCallbackFunction g_swig_watchpoint_callback = nullptr;
-static ScriptInterpreter::SWIGPythonTypeScriptCallbackFunction g_swig_typescript_callback = nullptr;
-static ScriptInterpreter::SWIGPythonCreateSyntheticProvider g_swig_synthetic_script = nullptr;
-static ScriptInterpreter::SWIGPythonCalculateNumChildren g_swig_calc_children = nullptr;
-static ScriptInterpreter::SWIGPythonGetChildAtIndex g_swig_get_child_index = nullptr;
-static ScriptInterpreter::SWIGPythonGetIndexOfChildWithName g_swig_get_index_child = nullptr;
-static ScriptInterpreter::SWIGPythonCastPyObjectToSBValue g_swig_cast_to_sbvalue = nullptr;
-static ScriptInterpreter::SWIGPythonGetValueObjectSPFromSBValue g_swig_get_valobj_sp_from_sbvalue = nullptr;
-static ScriptInterpreter::SWIGPythonUpdateSynthProviderInstance g_swig_update_provider = nullptr;
-static ScriptInterpreter::SWIGPythonMightHaveChildrenSynthProviderInstance g_swig_mighthavechildren_provider = nullptr;
-static ScriptInterpreter::SWIGPythonGetValueSynthProviderInstance g_swig_getvalue_provider = nullptr;
-static ScriptInterpreter::SWIGPythonCallCommand g_swig_call_command = nullptr;
-static ScriptInterpreter::SWIGPythonCallModuleInit g_swig_call_module_init = nullptr;
-static ScriptInterpreter::SWIGPythonCreateOSPlugin g_swig_create_os_plugin = nullptr;
-static ScriptInterpreter::SWIGPythonScriptKeyword_Process g_swig_run_script_keyword_process = nullptr;
-static ScriptInterpreter::SWIGPythonScriptKeyword_Thread g_swig_run_script_keyword_thread = nullptr;
-static ScriptInterpreter::SWIGPythonScriptKeyword_Target g_swig_run_script_keyword_target = nullptr;
-static ScriptInterpreter::SWIGPythonScriptKeyword_Frame g_swig_run_script_keyword_frame = nullptr;
-static ScriptInterpreter::SWIGPythonScriptKeyword_Value g_swig_run_script_keyword_value = nullptr;
-static ScriptInterpreter::SWIGPython_GetDynamicSetting g_swig_plugin_get = nullptr;
-static ScriptInterpreter::SWIGPythonCreateScriptedThreadPlan g_swig_thread_plan_script = nullptr;
-static ScriptInterpreter::SWIGPythonCallThreadPlan g_swig_call_thread_plan = nullptr;
+static ScriptInterpreterPython::SWIGInitCallback g_swig_init_callback = nullptr;
+static ScriptInterpreterPython::SWIGBreakpointCallbackFunction g_swig_breakpoint_callback = nullptr;
+static ScriptInterpreterPython::SWIGWatchpointCallbackFunction g_swig_watchpoint_callback = nullptr;
+static ScriptInterpreterPython::SWIGPythonTypeScriptCallbackFunction g_swig_typescript_callback = nullptr;
+static ScriptInterpreterPython::SWIGPythonCreateSyntheticProvider g_swig_synthetic_script = nullptr;
+static ScriptInterpreterPython::SWIGPythonCreateCommandObject g_swig_create_cmd = nullptr;
+static ScriptInterpreterPython::SWIGPythonCalculateNumChildren g_swig_calc_children = nullptr;
+static ScriptInterpreterPython::SWIGPythonGetChildAtIndex g_swig_get_child_index = nullptr;
+static ScriptInterpreterPython::SWIGPythonGetIndexOfChildWithName g_swig_get_index_child = nullptr;
+static ScriptInterpreterPython::SWIGPythonCastPyObjectToSBValue g_swig_cast_to_sbvalue = nullptr;
+static ScriptInterpreterPython::SWIGPythonGetValueObjectSPFromSBValue g_swig_get_valobj_sp_from_sbvalue = nullptr;
+static ScriptInterpreterPython::SWIGPythonUpdateSynthProviderInstance g_swig_update_provider = nullptr;
+static ScriptInterpreterPython::SWIGPythonMightHaveChildrenSynthProviderInstance g_swig_mighthavechildren_provider = nullptr;
+static ScriptInterpreterPython::SWIGPythonGetValueSynthProviderInstance g_swig_getvalue_provider = nullptr;
+static ScriptInterpreterPython::SWIGPythonCallCommand g_swig_call_command = nullptr;
+static ScriptInterpreterPython::SWIGPythonCallCommandObject g_swig_call_command_object = nullptr;
+static ScriptInterpreterPython::SWIGPythonCallModuleInit g_swig_call_module_init = nullptr;
+static ScriptInterpreterPython::SWIGPythonCreateOSPlugin g_swig_create_os_plugin = nullptr;
+static ScriptInterpreterPython::SWIGPythonScriptKeyword_Process g_swig_run_script_keyword_process = nullptr;
+static ScriptInterpreterPython::SWIGPythonScriptKeyword_Thread g_swig_run_script_keyword_thread = nullptr;
+static ScriptInterpreterPython::SWIGPythonScriptKeyword_Target g_swig_run_script_keyword_target = nullptr;
+static ScriptInterpreterPython::SWIGPythonScriptKeyword_Frame g_swig_run_script_keyword_frame = nullptr;
+static ScriptInterpreterPython::SWIGPythonScriptKeyword_Value g_swig_run_script_keyword_value = nullptr;
+static ScriptInterpreterPython::SWIGPython_GetDynamicSetting g_swig_plugin_get = nullptr;
+static ScriptInterpreterPython::SWIGPythonCreateScriptedThreadPlan g_swig_thread_plan_script = nullptr;
+static ScriptInterpreterPython::SWIGPythonCallThreadPlan g_swig_call_thread_plan = nullptr;
+
+static bool g_initialized = false;
static std::string
ReadPythonBacktrace (PyObject* py_backtrace);
@@ -171,8 +178,7 @@ ScriptInterpreterPython::ScriptInterpreterPython (CommandInterpreter &interprete
m_lock_count (0),
m_command_thread_state (nullptr)
{
-
- ScriptInterpreterPython::InitializePrivate ();
+ assert(g_initialized && "ScriptInterpreterPython created but initialize has not been called!");
m_dictionary_name.append("_dict");
StreamString run_string;
@@ -185,17 +191,7 @@ ScriptInterpreterPython::ScriptInterpreterPython (CommandInterpreter &interprete
run_string.Clear();
- // Importing 'lldb' module calls SBDebugger::Initialize, which calls Debugger::Initialize, which increments a
- // global debugger ref-count; therefore we need to check the ref-count before and after importing lldb, and if the
- // ref-count increased we need to call Debugger::Terminate here to decrement the ref-count so that when the final
- // call to Debugger::Terminate is made, the ref-count has the correct value.
- //
- // Bonus question: Why doesn't the ref-count always increase? Because sometimes lldb has already been imported, in
- // which case the code inside it, including the call to SBDebugger::Initialize(), does not get executed.
-
- int old_count = Debugger::TestDebuggerRefCount();
-
- run_string.Printf ("run_one_line (%s, 'import copy, os, re, sys, uuid, lldb')", m_dictionary_name.c_str());
+ run_string.Printf ("run_one_line (%s, 'import copy, keyword, os, re, sys, uuid, lldb')", m_dictionary_name.c_str());
PyRun_SimpleString (run_string.GetData());
// WARNING: temporary code that loads Cocoa formatters - this should be done on a per-platform basis rather than loading the whole set
@@ -205,11 +201,6 @@ ScriptInterpreterPython::ScriptInterpreterPython (CommandInterpreter &interprete
PyRun_SimpleString (run_string.GetData());
run_string.Clear();
- int new_count = Debugger::TestDebuggerRefCount();
-
- if (new_count > old_count)
- Debugger::Terminate();
-
run_string.Printf ("run_one_line (%s, 'import lldb.embedded_interpreter; from lldb.embedded_interpreter import run_python_interpreter; from lldb.embedded_interpreter import run_one_line')", m_dictionary_name.c_str());
PyRun_SimpleString (run_string.GetData());
run_string.Clear();
@@ -393,6 +384,13 @@ ScriptInterpreterPython::LeaveSession ()
m_session_is_active = false;
}
+static PyObject *
+PyFile_FromFile_Const(FILE *fp, const char *name, const char *mode, int (*close)(FILE *))
+{
+ // Read through the Python source, doesn't seem to modify these strings
+ return PyFile_FromFile(fp, const_cast<char*>(name), const_cast<char*>(mode), close);
+}
+
bool
ScriptInterpreterPython::EnterSession (uint16_t on_entry_flags,
FILE *in,
@@ -458,7 +456,7 @@ ScriptInterpreterPython::EnterSession (uint16_t on_entry_flags,
{
m_saved_stdin.Reset(sys_module_dict.GetItemForKey("stdin"));
// This call can deadlock your process if the file is locked
- PyObject *new_file = PyFile_FromFile (in, (char *) "", (char *) "r", nullptr);
+ PyObject *new_file = PyFile_FromFile_Const (in, "", "r", nullptr);
sys_module_dict.SetItemForKey ("stdin", new_file);
Py_DECREF (new_file);
}
@@ -470,7 +468,7 @@ ScriptInterpreterPython::EnterSession (uint16_t on_entry_flags,
{
m_saved_stdout.Reset(sys_module_dict.GetItemForKey("stdout"));
- PyObject *new_file = PyFile_FromFile (out, (char *) "", (char *) "w", nullptr);
+ PyObject *new_file = PyFile_FromFile_Const (out, "", "w", nullptr);
sys_module_dict.SetItemForKey ("stdout", new_file);
Py_DECREF (new_file);
}
@@ -483,7 +481,7 @@ ScriptInterpreterPython::EnterSession (uint16_t on_entry_flags,
{
m_saved_stderr.Reset(sys_module_dict.GetItemForKey("stderr"));
- PyObject *new_file = PyFile_FromFile (err, (char *) "", (char *) "w", nullptr);
+ PyObject *new_file = PyFile_FromFile_Const (err, "", "w", nullptr);
sys_module_dict.SetItemForKey ("stderr", new_file);
Py_DECREF (new_file);
}
@@ -738,22 +736,21 @@ public:
}
- virtual
- ~IOHandlerPythonInterpreter()
+ ~IOHandlerPythonInterpreter() override
{
}
- virtual ConstString
- GetControlSequence (char ch)
+ ConstString
+ GetControlSequence (char ch) override
{
if (ch == 'd')
return ConstString("quit()\n");
return ConstString();
}
- virtual void
- Run ()
+ void
+ Run () override
{
if (m_python)
{
@@ -799,32 +796,20 @@ public:
SetIsDone(true);
}
- virtual void
- Hide ()
- {
-
- }
-
- virtual void
- Refresh ()
- {
-
- }
-
- virtual void
- Cancel ()
+ void
+ Cancel () override
{
}
- virtual bool
- Interrupt ()
+ bool
+ Interrupt () override
{
return m_python->Interrupt();
}
- virtual void
- GotEOF()
+ void
+ GotEOF() override
{
}
@@ -1348,15 +1333,15 @@ ScriptInterpreterPython::GenerateTypeSynthClass (StringList &user_input, std::st
return true;
}
-lldb::ScriptInterpreterObjectSP
-ScriptInterpreterPython::OSPlugin_CreatePluginObject (const char *class_name, lldb::ProcessSP process_sp)
+StructuredData::GenericSP
+ScriptInterpreterPython::OSPlugin_CreatePluginObject(const char *class_name, lldb::ProcessSP process_sp)
{
if (class_name == nullptr || class_name[0] == '\0')
- return lldb::ScriptInterpreterObjectSP();
-
+ return StructuredData::GenericSP();
+
if (!process_sp)
- return lldb::ScriptInterpreterObjectSP();
-
+ return StructuredData::GenericSP();
+
void* ret_val;
{
@@ -1367,12 +1352,12 @@ ScriptInterpreterPython::OSPlugin_CreatePluginObject (const char *class_name, ll
m_dictionary_name.c_str(),
process_sp);
}
-
- return MakeScriptObject(ret_val);
+
+ return StructuredData::GenericSP(new StructuredPythonObject(ret_val));
}
-lldb::ScriptInterpreterObjectSP
-ScriptInterpreterPython::OSPlugin_RegisterInfo (lldb::ScriptInterpreterObjectSP os_plugin_object_sp)
+StructuredData::DictionarySP
+ScriptInterpreterPython::OSPlugin_RegisterInfo(StructuredData::ObjectSP os_plugin_object_sp)
{
Locker py_lock(this,
Locker::AcquireLock | Locker::NoSTDIN,
@@ -1381,13 +1366,17 @@ ScriptInterpreterPython::OSPlugin_RegisterInfo (lldb::ScriptInterpreterObjectSP
static char callee_name[] = "get_register_info";
if (!os_plugin_object_sp)
- return lldb::ScriptInterpreterObjectSP();
-
- PyObject* implementor = (PyObject*)os_plugin_object_sp->GetObject();
-
+ return StructuredData::DictionarySP();
+
+ StructuredData::Generic *generic = os_plugin_object_sp->GetAsGeneric();
+ if (!generic)
+ return nullptr;
+
+ PyObject *implementor = (PyObject *)generic->GetValue();
+
if (implementor == nullptr || implementor == Py_None)
- return lldb::ScriptInterpreterObjectSP();
-
+ return StructuredData::DictionarySP();
+
PyObject* pmeth = PyObject_GetAttrString(implementor, callee_name);
if (PyErr_Occurred())
@@ -1398,7 +1387,7 @@ ScriptInterpreterPython::OSPlugin_RegisterInfo (lldb::ScriptInterpreterObjectSP
if (pmeth == nullptr || pmeth == Py_None)
{
Py_XDECREF(pmeth);
- return lldb::ScriptInterpreterObjectSP();
+ return StructuredData::DictionarySP();
}
if (PyCallable_Check(pmeth) == 0)
@@ -1409,7 +1398,7 @@ ScriptInterpreterPython::OSPlugin_RegisterInfo (lldb::ScriptInterpreterObjectSP
}
Py_XDECREF(pmeth);
- return lldb::ScriptInterpreterObjectSP();
+ return StructuredData::DictionarySP();
}
if (PyErr_Occurred())
@@ -1428,27 +1417,31 @@ ScriptInterpreterPython::OSPlugin_RegisterInfo (lldb::ScriptInterpreterObjectSP
PyErr_Print();
PyErr_Clear();
}
-
- return MakeScriptObject(py_return);
+
+ PythonDictionary result_dict(py_return);
+ return result_dict.CreateStructuredDictionary();
}
-lldb::ScriptInterpreterObjectSP
-ScriptInterpreterPython::OSPlugin_ThreadsInfo (lldb::ScriptInterpreterObjectSP os_plugin_object_sp)
+StructuredData::ArraySP
+ScriptInterpreterPython::OSPlugin_ThreadsInfo(StructuredData::ObjectSP os_plugin_object_sp)
{
Locker py_lock (this,
Locker::AcquireLock | Locker::NoSTDIN,
Locker::FreeLock);
static char callee_name[] = "get_thread_info";
-
+
if (!os_plugin_object_sp)
- return lldb::ScriptInterpreterObjectSP();
-
- PyObject* implementor = (PyObject*)os_plugin_object_sp->GetObject();
-
+ return StructuredData::ArraySP();
+
+ StructuredData::Generic *generic = os_plugin_object_sp->GetAsGeneric();
+ if (!generic)
+ return nullptr;
+ PyObject *implementor = (PyObject *)generic->GetValue();
+
if (implementor == nullptr || implementor == Py_None)
- return lldb::ScriptInterpreterObjectSP();
-
+ return StructuredData::ArraySP();
+
PyObject* pmeth = PyObject_GetAttrString(implementor, callee_name);
if (PyErr_Occurred())
@@ -1459,7 +1452,7 @@ ScriptInterpreterPython::OSPlugin_ThreadsInfo (lldb::ScriptInterpreterObjectSP o
if (pmeth == nullptr || pmeth == Py_None)
{
Py_XDECREF(pmeth);
- return lldb::ScriptInterpreterObjectSP();
+ return StructuredData::ArraySP();
}
if (PyCallable_Check(pmeth) == 0)
@@ -1470,7 +1463,7 @@ ScriptInterpreterPython::OSPlugin_ThreadsInfo (lldb::ScriptInterpreterObjectSP o
}
Py_XDECREF(pmeth);
- return lldb::ScriptInterpreterObjectSP();
+ return StructuredData::ArraySP();
}
if (PyErr_Occurred())
@@ -1489,8 +1482,9 @@ ScriptInterpreterPython::OSPlugin_ThreadsInfo (lldb::ScriptInterpreterObjectSP o
PyErr_Print();
PyErr_Clear();
}
-
- return MakeScriptObject(py_return);
+
+ PythonList ResultList(py_return);
+ return ResultList.CreateStructuredArray();
}
// GetPythonValueFormatString provides a system independent type safe way to
@@ -1519,9 +1513,8 @@ template <> const char *GetPythonValueFormatString (unsigned long long) { return
template <> const char *GetPythonValueFormatString (float t) { return "f"; }
template <> const char *GetPythonValueFormatString (double t) { return "d"; }
-lldb::ScriptInterpreterObjectSP
-ScriptInterpreterPython::OSPlugin_RegisterContextData (lldb::ScriptInterpreterObjectSP os_plugin_object_sp,
- lldb::tid_t tid)
+StructuredData::StringSP
+ScriptInterpreterPython::OSPlugin_RegisterContextData(StructuredData::ObjectSP os_plugin_object_sp, lldb::tid_t tid)
{
Locker py_lock (this,
Locker::AcquireLock | Locker::NoSTDIN,
@@ -1531,12 +1524,15 @@ ScriptInterpreterPython::OSPlugin_RegisterContextData (lldb::ScriptInterpreterOb
static char *param_format = const_cast<char *>(GetPythonValueFormatString(tid));
if (!os_plugin_object_sp)
- return lldb::ScriptInterpreterObjectSP();
-
- PyObject* implementor = (PyObject*)os_plugin_object_sp->GetObject();
-
+ return StructuredData::StringSP();
+
+ StructuredData::Generic *generic = os_plugin_object_sp->GetAsGeneric();
+ if (!generic)
+ return nullptr;
+ PyObject *implementor = (PyObject *)generic->GetValue();
+
if (implementor == nullptr || implementor == Py_None)
- return lldb::ScriptInterpreterObjectSP();
+ return StructuredData::StringSP();
PyObject* pmeth = PyObject_GetAttrString(implementor, callee_name);
@@ -1548,7 +1544,7 @@ ScriptInterpreterPython::OSPlugin_RegisterContextData (lldb::ScriptInterpreterOb
if (pmeth == nullptr || pmeth == Py_None)
{
Py_XDECREF(pmeth);
- return lldb::ScriptInterpreterObjectSP();
+ return StructuredData::StringSP();
}
if (PyCallable_Check(pmeth) == 0)
@@ -1559,7 +1555,7 @@ ScriptInterpreterPython::OSPlugin_RegisterContextData (lldb::ScriptInterpreterOb
}
Py_XDECREF(pmeth);
- return lldb::ScriptInterpreterObjectSP();
+ return StructuredData::StringSP();
}
if (PyErr_Occurred())
@@ -1578,14 +1574,12 @@ ScriptInterpreterPython::OSPlugin_RegisterContextData (lldb::ScriptInterpreterOb
PyErr_Print();
PyErr_Clear();
}
-
- return MakeScriptObject(py_return);
+ PythonString result_string(py_return);
+ return result_string.CreateStructuredString();
}
-lldb::ScriptInterpreterObjectSP
-ScriptInterpreterPython::OSPlugin_CreateThread (lldb::ScriptInterpreterObjectSP os_plugin_object_sp,
- lldb::tid_t tid,
- lldb::addr_t context)
+StructuredData::DictionarySP
+ScriptInterpreterPython::OSPlugin_CreateThread(StructuredData::ObjectSP os_plugin_object_sp, lldb::tid_t tid, lldb::addr_t context)
{
Locker py_lock(this,
Locker::AcquireLock | Locker::NoSTDIN,
@@ -1597,13 +1591,16 @@ ScriptInterpreterPython::OSPlugin_CreateThread (lldb::ScriptInterpreterObjectSP
param_format += GetPythonValueFormatString(context);
if (!os_plugin_object_sp)
- return lldb::ScriptInterpreterObjectSP();
-
- PyObject* implementor = (PyObject*)os_plugin_object_sp->GetObject();
-
+ return StructuredData::DictionarySP();
+
+ StructuredData::Generic *generic = os_plugin_object_sp->GetAsGeneric();
+ if (!generic)
+ return nullptr;
+ PyObject *implementor = (PyObject *)generic->GetValue();
+
if (implementor == nullptr || implementor == Py_None)
- return lldb::ScriptInterpreterObjectSP();
-
+ return StructuredData::DictionarySP();
+
PyObject* pmeth = PyObject_GetAttrString(implementor, callee_name);
if (PyErr_Occurred())
@@ -1614,7 +1611,7 @@ ScriptInterpreterPython::OSPlugin_CreateThread (lldb::ScriptInterpreterObjectSP
if (pmeth == nullptr || pmeth == Py_None)
{
Py_XDECREF(pmeth);
- return lldb::ScriptInterpreterObjectSP();
+ return StructuredData::DictionarySP();
}
if (PyCallable_Check(pmeth) == 0)
@@ -1625,7 +1622,7 @@ ScriptInterpreterPython::OSPlugin_CreateThread (lldb::ScriptInterpreterObjectSP
}
Py_XDECREF(pmeth);
- return lldb::ScriptInterpreterObjectSP();
+ return StructuredData::DictionarySP();
}
if (PyErr_Occurred())
@@ -1644,27 +1641,27 @@ ScriptInterpreterPython::OSPlugin_CreateThread (lldb::ScriptInterpreterObjectSP
PyErr_Print();
PyErr_Clear();
}
-
- return MakeScriptObject(py_return);
+
+ PythonDictionary result_dict(py_return);
+ return result_dict.CreateStructuredDictionary();
}
-lldb::ScriptInterpreterObjectSP
-ScriptInterpreterPython::CreateScriptedThreadPlan (const char *class_name,
- lldb::ThreadPlanSP thread_plan_sp)
+StructuredData::ObjectSP
+ScriptInterpreterPython::CreateScriptedThreadPlan(const char *class_name, lldb::ThreadPlanSP thread_plan_sp)
{
if (class_name == nullptr || class_name[0] == '\0')
- return lldb::ScriptInterpreterObjectSP();
-
+ return StructuredData::ObjectSP();
+
if (!thread_plan_sp.get())
- return lldb::ScriptInterpreterObjectSP();
+ return StructuredData::ObjectSP();
Debugger &debugger = thread_plan_sp->GetTarget().GetDebugger();
ScriptInterpreter *script_interpreter = debugger.GetCommandInterpreter().GetScriptInterpreter();
ScriptInterpreterPython *python_interpreter = static_cast<ScriptInterpreterPython *>(script_interpreter);
if (!script_interpreter)
- return lldb::ScriptInterpreterObjectSP();
-
+ return StructuredData::ObjectSP();
+
void* ret_val;
{
@@ -1674,20 +1671,21 @@ ScriptInterpreterPython::CreateScriptedThreadPlan (const char *class_name,
python_interpreter->m_dictionary_name.c_str(),
thread_plan_sp);
}
-
- return MakeScriptObject(ret_val);
+
+ return StructuredData::ObjectSP(new StructuredPythonObject(ret_val));
}
bool
-ScriptInterpreterPython::ScriptedThreadPlanExplainsStop (lldb::ScriptInterpreterObjectSP implementor_sp,
- Event *event,
- bool &script_error)
+ScriptInterpreterPython::ScriptedThreadPlanExplainsStop(StructuredData::ObjectSP implementor_sp, Event *event, bool &script_error)
{
bool explains_stop = true;
+ StructuredData::Generic *generic = nullptr;
if (implementor_sp)
+ generic = implementor_sp->GetAsGeneric();
+ if (generic)
{
Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
- explains_stop = g_swig_call_thread_plan (implementor_sp->GetObject(), "explains_stop", event, script_error);
+ explains_stop = g_swig_call_thread_plan(generic->GetValue(), "explains_stop", event, script_error);
if (script_error)
return true;
}
@@ -1695,15 +1693,16 @@ ScriptInterpreterPython::ScriptedThreadPlanExplainsStop (lldb::ScriptInterpreter
}
bool
-ScriptInterpreterPython::ScriptedThreadPlanShouldStop (lldb::ScriptInterpreterObjectSP implementor_sp,
- Event *event,
- bool &script_error)
+ScriptInterpreterPython::ScriptedThreadPlanShouldStop(StructuredData::ObjectSP implementor_sp, Event *event, bool &script_error)
{
bool should_stop = true;
+ StructuredData::Generic *generic = nullptr;
if (implementor_sp)
+ generic = implementor_sp->GetAsGeneric();
+ if (generic)
{
Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
- should_stop = g_swig_call_thread_plan (implementor_sp->GetObject(), "should_stop", event, script_error);
+ should_stop = g_swig_call_thread_plan(generic->GetValue(), "should_stop", event, script_error);
if (script_error)
return true;
}
@@ -1711,14 +1710,16 @@ ScriptInterpreterPython::ScriptedThreadPlanShouldStop (lldb::ScriptInterpreterOb
}
lldb::StateType
-ScriptInterpreterPython::ScriptedThreadPlanGetRunState (lldb::ScriptInterpreterObjectSP implementor_sp,
- bool &script_error)
+ScriptInterpreterPython::ScriptedThreadPlanGetRunState(StructuredData::ObjectSP implementor_sp, bool &script_error)
{
bool should_step = false;
+ StructuredData::Generic *generic = nullptr;
if (implementor_sp)
+ generic = implementor_sp->GetAsGeneric();
+ if (generic)
{
Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
- should_step = g_swig_call_thread_plan (implementor_sp->GetObject(), "should_step", NULL, script_error);
+ should_step = g_swig_call_thread_plan(generic->GetValue(), "should_step", NULL, script_error);
if (script_error)
should_step = true;
}
@@ -1728,72 +1729,69 @@ ScriptInterpreterPython::ScriptedThreadPlanGetRunState (lldb::ScriptInterpreterO
return lldb::eStateRunning;
}
-
-lldb::ScriptInterpreterObjectSP
-ScriptInterpreterPython::LoadPluginModule (const FileSpec& file_spec,
- lldb_private::Error& error)
+StructuredData::ObjectSP
+ScriptInterpreterPython::LoadPluginModule(const FileSpec &file_spec, lldb_private::Error &error)
{
if (!file_spec.Exists())
{
error.SetErrorString("no such file");
- return lldb::ScriptInterpreterObjectSP();
+ return StructuredData::ObjectSP();
}
- ScriptInterpreterObjectSP module_sp;
-
+ StructuredData::ObjectSP module_sp;
+
if (LoadScriptingModule(file_spec.GetPath().c_str(),true,true,error,&module_sp))
return module_sp;
-
- return lldb::ScriptInterpreterObjectSP();
+
+ return StructuredData::ObjectSP();
}
-lldb::ScriptInterpreterObjectSP
-ScriptInterpreterPython::GetDynamicSettings (lldb::ScriptInterpreterObjectSP plugin_module_sp,
- Target* target,
- const char* setting_name,
- lldb_private::Error& error)
+StructuredData::DictionarySP
+ScriptInterpreterPython::GetDynamicSettings(StructuredData::ObjectSP plugin_module_sp, Target *target, const char *setting_name,
+ lldb_private::Error &error)
{
- if (!plugin_module_sp || !target || !setting_name || !setting_name[0])
- return lldb::ScriptInterpreterObjectSP();
-
- if (!g_swig_plugin_get)
- return lldb::ScriptInterpreterObjectSP();
-
+ if (!plugin_module_sp || !target || !setting_name || !setting_name[0] || !g_swig_plugin_get)
+ return StructuredData::DictionarySP();
+ StructuredData::Generic *generic = plugin_module_sp->GetAsGeneric();
+ if (!generic)
+ return StructuredData::DictionarySP();
+
PyObject *reply_pyobj = nullptr;
{
Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
TargetSP target_sp(target->shared_from_this());
- reply_pyobj = (PyObject*)g_swig_plugin_get(plugin_module_sp->GetObject(),setting_name,target_sp);
+ reply_pyobj = (PyObject *)g_swig_plugin_get(generic->GetValue(), setting_name, target_sp);
}
-
- return MakeScriptObject(reply_pyobj);
+
+ PythonDictionary py_dict(reply_pyobj);
+
+ return py_dict.CreateStructuredDictionary();
}
-lldb::ScriptInterpreterObjectSP
-ScriptInterpreterPython::CreateSyntheticScriptedProvider (const char *class_name,
- lldb::ValueObjectSP valobj)
+StructuredData::ObjectSP
+ScriptInterpreterPython::CreateSyntheticScriptedProvider(const char *class_name, lldb::ValueObjectSP valobj)
{
if (class_name == nullptr || class_name[0] == '\0')
- return lldb::ScriptInterpreterObjectSP();
-
+ return StructuredData::ObjectSP();
+
if (!valobj.get())
- return lldb::ScriptInterpreterObjectSP();
-
+ return StructuredData::ObjectSP();
+
ExecutionContext exe_ctx (valobj->GetExecutionContextRef());
Target *target = exe_ctx.GetTargetPtr();
if (!target)
- return lldb::ScriptInterpreterObjectSP();
-
+ return StructuredData::ObjectSP();
+
Debugger &debugger = target->GetDebugger();
ScriptInterpreter *script_interpreter = debugger.GetCommandInterpreter().GetScriptInterpreter();
ScriptInterpreterPython *python_interpreter = (ScriptInterpreterPython *) script_interpreter;
if (!script_interpreter)
- return lldb::ScriptInterpreterObjectSP();
-
- void* ret_val;
+ return StructuredData::ObjectSP();
+
+ void *ret_val = nullptr;
{
Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
@@ -1801,8 +1799,31 @@ ScriptInterpreterPython::CreateSyntheticScriptedProvider (const char *class_name
python_interpreter->m_dictionary_name.c_str(),
valobj);
}
+
+ return StructuredData::ObjectSP(new StructuredPythonObject(ret_val));
+}
+
+StructuredData::GenericSP
+ScriptInterpreterPython::CreateScriptCommandObject (const char *class_name)
+{
+ DebuggerSP debugger_sp(GetCommandInterpreter().GetDebugger().shared_from_this());
+
+ if (class_name == nullptr || class_name[0] == '\0')
+ return StructuredData::GenericSP();
+
+ if (!debugger_sp.get())
+ return StructuredData::GenericSP();
+
+ void* ret_val;
+
+ {
+ Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
+ ret_val = g_swig_create_cmd (class_name,
+ m_dictionary_name.c_str(),
+ debugger_sp);
+ }
- return MakeScriptObject(ret_val);
+ return StructuredData::GenericSP(new StructuredPythonObject(ret_val));
}
bool
@@ -1869,11 +1890,9 @@ ScriptInterpreterPython::GenerateWatchpointCommandCallbackData (StringList &user
}
bool
-ScriptInterpreterPython::GetScriptedSummary (const char *python_function_name,
- lldb::ValueObjectSP valobj,
- lldb::ScriptInterpreterObjectSP& callee_wrapper_sp,
- const TypeSummaryOptions& options,
- std::string& retval)
+ScriptInterpreterPython::GetScriptedSummary(const char *python_function_name, lldb::ValueObjectSP valobj,
+ StructuredData::ObjectSP &callee_wrapper_sp, const TypeSummaryOptions &options,
+ std::string &retval)
{
Timer scoped_timer (__PRETTY_FUNCTION__, __PRETTY_FUNCTION__);
@@ -1883,13 +1902,19 @@ ScriptInterpreterPython::GetScriptedSummary (const char *python_function_name,
retval.assign("<no object>");
return false;
}
-
- void* old_callee = (callee_wrapper_sp ? callee_wrapper_sp->GetObject() : nullptr);
+
+ void *old_callee = nullptr;
+ StructuredData::Generic *generic = nullptr;
+ if (callee_wrapper_sp)
+ {
+ generic = callee_wrapper_sp->GetAsGeneric();
+ if (generic)
+ old_callee = generic->GetValue();
+ }
void* new_callee = old_callee;
bool ret_val;
- if (python_function_name
- && *python_function_name)
+ if (python_function_name && *python_function_name)
{
{
Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
@@ -1913,10 +1938,9 @@ ScriptInterpreterPython::GetScriptedSummary (const char *python_function_name,
}
if (new_callee && old_callee != new_callee)
- callee_wrapper_sp = MakeScriptObject(new_callee);
-
+ callee_wrapper_sp.reset(new StructuredPythonObject(new_callee));
+
return ret_val;
-
}
void
@@ -2042,20 +2066,21 @@ ScriptInterpreterPython::WatchpointCallbackFunction
}
size_t
-ScriptInterpreterPython::CalculateNumChildren (const lldb::ScriptInterpreterObjectSP& implementor_sp)
+ScriptInterpreterPython::CalculateNumChildren(const StructuredData::ObjectSP &implementor_sp)
{
if (!implementor_sp)
return 0;
-
- void* implementor = implementor_sp->GetObject();
-
+ StructuredData::Generic *generic = implementor_sp->GetAsGeneric();
+ if (!generic)
+ return 0;
+ void *implementor = generic->GetValue();
if (!implementor)
return 0;
if (!g_swig_calc_children)
return 0;
- uint32_t ret_val = 0;
+ size_t ret_val = 0;
{
Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
@@ -2066,13 +2091,15 @@ ScriptInterpreterPython::CalculateNumChildren (const lldb::ScriptInterpreterObje
}
lldb::ValueObjectSP
-ScriptInterpreterPython::GetChildAtIndex (const lldb::ScriptInterpreterObjectSP& implementor_sp, uint32_t idx)
+ScriptInterpreterPython::GetChildAtIndex(const StructuredData::ObjectSP &implementor_sp, uint32_t idx)
{
if (!implementor_sp)
return lldb::ValueObjectSP();
-
- void* implementor = implementor_sp->GetObject();
-
+
+ StructuredData::Generic *generic = implementor_sp->GetAsGeneric();
+ if (!generic)
+ return lldb::ValueObjectSP();
+ void *implementor = generic->GetValue();
if (!implementor)
return lldb::ValueObjectSP();
@@ -2102,13 +2129,15 @@ ScriptInterpreterPython::GetChildAtIndex (const lldb::ScriptInterpreterObjectSP&
}
int
-ScriptInterpreterPython::GetIndexOfChildWithName (const lldb::ScriptInterpreterObjectSP& implementor_sp, const char* child_name)
+ScriptInterpreterPython::GetIndexOfChildWithName(const StructuredData::ObjectSP &implementor_sp, const char *child_name)
{
if (!implementor_sp)
return UINT32_MAX;
-
- void* implementor = implementor_sp->GetObject();
-
+
+ StructuredData::Generic *generic = implementor_sp->GetAsGeneric();
+ if (!generic)
+ return UINT32_MAX;
+ void *implementor = generic->GetValue();
if (!implementor)
return UINT32_MAX;
@@ -2126,15 +2155,17 @@ ScriptInterpreterPython::GetIndexOfChildWithName (const lldb::ScriptInterpreterO
}
bool
-ScriptInterpreterPython::UpdateSynthProviderInstance (const lldb::ScriptInterpreterObjectSP& implementor_sp)
+ScriptInterpreterPython::UpdateSynthProviderInstance(const StructuredData::ObjectSP &implementor_sp)
{
bool ret_val = false;
if (!implementor_sp)
return ret_val;
-
- void* implementor = implementor_sp->GetObject();
-
+
+ StructuredData::Generic *generic = implementor_sp->GetAsGeneric();
+ if (!generic)
+ return ret_val;
+ void *implementor = generic->GetValue();
if (!implementor)
return ret_val;
@@ -2150,15 +2181,17 @@ ScriptInterpreterPython::UpdateSynthProviderInstance (const lldb::ScriptInterpre
}
bool
-ScriptInterpreterPython::MightHaveChildrenSynthProviderInstance (const lldb::ScriptInterpreterObjectSP& implementor_sp)
+ScriptInterpreterPython::MightHaveChildrenSynthProviderInstance(const StructuredData::ObjectSP &implementor_sp)
{
bool ret_val = false;
if (!implementor_sp)
return ret_val;
-
- void* implementor = implementor_sp->GetObject();
-
+
+ StructuredData::Generic *generic = implementor_sp->GetAsGeneric();
+ if (!generic)
+ return ret_val;
+ void *implementor = generic->GetValue();
if (!implementor)
return ret_val;
@@ -2174,15 +2207,17 @@ ScriptInterpreterPython::MightHaveChildrenSynthProviderInstance (const lldb::Scr
}
lldb::ValueObjectSP
-ScriptInterpreterPython::GetSyntheticValue (const lldb::ScriptInterpreterObjectSP& implementor_sp)
+ScriptInterpreterPython::GetSyntheticValue(const StructuredData::ObjectSP &implementor_sp)
{
lldb::ValueObjectSP ret_val(nullptr);
if (!implementor_sp)
return ret_val;
-
- void* implementor = implementor_sp->GetObject();
-
+
+ StructuredData::Generic *generic = implementor_sp->GetAsGeneric();
+ if (!generic)
+ return ret_val;
+ void *implementor = generic->GetValue();
if (!implementor)
return ret_val;
@@ -2440,11 +2475,8 @@ uint64_t replace_all(std::string& str, const std::string& oldStr, const std::str
}
bool
-ScriptInterpreterPython::LoadScriptingModule (const char* pathname,
- bool can_reload,
- bool init_session,
- lldb_private::Error& error,
- lldb::ScriptInterpreterObjectSP* module_sp)
+ScriptInterpreterPython::LoadScriptingModule(const char *pathname, bool can_reload, bool init_session, lldb_private::Error &error,
+ StructuredData::ObjectSP *module_sp)
{
if (!pathname || !pathname[0])
{
@@ -2575,17 +2607,36 @@ ScriptInterpreterPython::LoadScriptingModule (const char* pathname,
command_stream.Printf("%s",basename.c_str());
void* module_pyobj = nullptr;
if (ExecuteOneLineWithReturn(command_stream.GetData(),ScriptInterpreter::eScriptReturnTypeOpaqueObject,&module_pyobj) && module_pyobj)
- *module_sp = MakeScriptObject(module_pyobj);
+ module_sp->reset(new StructuredPythonObject(module_pyobj));
}
return true;
}
}
-lldb::ScriptInterpreterObjectSP
-ScriptInterpreterPython::MakeScriptObject (void* object)
+bool
+ScriptInterpreterPython::IsReservedWord (const char* word)
{
- return lldb::ScriptInterpreterObjectSP(new ScriptInterpreterPythonObject(object));
+ if (!word || !word[0])
+ return false;
+
+ llvm::StringRef word_sr(word);
+
+ // filter out a few characters that would just confuse us
+ // and that are clearly not keyword material anyway
+ if (word_sr.find_first_of("'\"") != llvm::StringRef::npos)
+ return false;
+
+ StreamString command_stream;
+ command_stream.Printf("keyword.iskeyword('%s')", word);
+ bool result;
+ ExecuteScriptOptions options;
+ options.SetEnableIO(false);
+ options.SetMaskoutErrors(true);
+ options.SetSetLLDBGlobals(false);
+ if (ExecuteOneLineWithReturn(command_stream.GetData(), ScriptInterpreter::eScriptReturnTypeBool, &result, options))
+ return result;
+ return false;
}
ScriptInterpreterPython::SynchronicityHandler::SynchronicityHandler (lldb::DebuggerSP debugger_sp,
@@ -2663,6 +2714,62 @@ ScriptInterpreterPython::RunScriptBasedCommand(const char* impl_function,
return ret_val;
}
+bool
+ScriptInterpreterPython::RunScriptBasedCommand (StructuredData::GenericSP impl_obj_sp,
+ const char* args,
+ ScriptedCommandSynchronicity synchronicity,
+ lldb_private::CommandReturnObject& cmd_retobj,
+ Error& error,
+ const lldb_private::ExecutionContext& exe_ctx)
+{
+ if (!impl_obj_sp || !impl_obj_sp->IsValid())
+ {
+ error.SetErrorString("no function to execute");
+ return false;
+ }
+
+ if (!g_swig_call_command_object)
+ {
+ error.SetErrorString("no helper function to run scripted commands");
+ return false;
+ }
+
+ lldb::DebuggerSP debugger_sp = m_interpreter.GetDebugger().shared_from_this();
+ lldb::ExecutionContextRefSP exe_ctx_ref_sp(new ExecutionContextRef(exe_ctx));
+
+ if (!debugger_sp.get())
+ {
+ error.SetErrorString("invalid Debugger pointer");
+ return false;
+ }
+
+ bool ret_val = false;
+
+ std::string err_msg;
+
+ {
+ Locker py_lock(this,
+ Locker::AcquireLock | Locker::InitSession | (cmd_retobj.GetInteractive() ? 0 : Locker::NoSTDIN),
+ Locker::FreeLock | Locker::TearDownSession);
+
+ SynchronicityHandler synch_handler(debugger_sp,
+ synchronicity);
+
+ ret_val = g_swig_call_command_object (impl_obj_sp->GetValue(),
+ debugger_sp,
+ args,
+ cmd_retobj,
+ exe_ctx_ref_sp);
+ }
+
+ if (!ret_val)
+ error.SetErrorString("unable to execute script function");
+ else
+ error.Clear();
+
+ return ret_val;
+}
+
// in Python, a special attribute __doc__ contains the docstring
// for an object (function, method, class, ...) if any is defined
// Otherwise, the attribute's value is None
@@ -2695,6 +2802,228 @@ ScriptInterpreterPython::GetDocumentationForItem(const char* item, std::string&
}
}
+bool
+ScriptInterpreterPython::GetShortHelpForCommandObject (StructuredData::GenericSP cmd_obj_sp,
+ std::string& dest)
+{
+ bool got_string = false;
+ dest.clear();
+
+ Locker py_lock (this,
+ Locker::AcquireLock | Locker::NoSTDIN,
+ Locker::FreeLock);
+
+ static char callee_name[] = "get_short_help";
+
+ if (!cmd_obj_sp)
+ return false;
+
+ PyObject* implementor = (PyObject*)cmd_obj_sp->GetValue();
+
+ if (implementor == nullptr || implementor == Py_None)
+ return false;
+
+ PyObject* pmeth = PyObject_GetAttrString(implementor, callee_name);
+
+ if (PyErr_Occurred())
+ {
+ PyErr_Clear();
+ }
+
+ if (pmeth == nullptr || pmeth == Py_None)
+ {
+ Py_XDECREF(pmeth);
+ return false;
+ }
+
+ if (PyCallable_Check(pmeth) == 0)
+ {
+ if (PyErr_Occurred())
+ {
+ PyErr_Clear();
+ }
+
+ Py_XDECREF(pmeth);
+ return false;
+ }
+
+ if (PyErr_Occurred())
+ {
+ PyErr_Clear();
+ }
+
+ Py_XDECREF(pmeth);
+
+ // right now we know this function exists and is callable..
+ PyObject* py_return = PyObject_CallMethod(implementor, callee_name, nullptr);
+
+ // if it fails, print the error but otherwise go on
+ if (PyErr_Occurred())
+ {
+ PyErr_Print();
+ PyErr_Clear();
+ }
+
+ if (py_return != nullptr && py_return != Py_None)
+ {
+ if (PyString_Check(py_return))
+ {
+ dest.assign(PyString_AsString(py_return));
+ got_string = true;
+ }
+ }
+ Py_XDECREF(py_return);
+
+ return got_string;
+}
+
+uint32_t
+ScriptInterpreterPython::GetFlagsForCommandObject (StructuredData::GenericSP cmd_obj_sp)
+{
+ uint32_t result = 0;
+
+ Locker py_lock (this,
+ Locker::AcquireLock | Locker::NoSTDIN,
+ Locker::FreeLock);
+
+ static char callee_name[] = "get_flags";
+
+ if (!cmd_obj_sp)
+ return result;
+
+ PyObject* implementor = (PyObject*)cmd_obj_sp->GetValue();
+
+ if (implementor == nullptr || implementor == Py_None)
+ return result;
+
+ PyObject* pmeth = PyObject_GetAttrString(implementor, callee_name);
+
+ if (PyErr_Occurred())
+ {
+ PyErr_Clear();
+ }
+
+ if (pmeth == nullptr || pmeth == Py_None)
+ {
+ Py_XDECREF(pmeth);
+ return result;
+ }
+
+ if (PyCallable_Check(pmeth) == 0)
+ {
+ if (PyErr_Occurred())
+ {
+ PyErr_Clear();
+ }
+
+ Py_XDECREF(pmeth);
+ return result;
+ }
+
+ if (PyErr_Occurred())
+ {
+ PyErr_Clear();
+ }
+
+ Py_XDECREF(pmeth);
+
+ // right now we know this function exists and is callable..
+ PyObject* py_return = PyObject_CallMethod(implementor, callee_name, nullptr);
+
+ // if it fails, print the error but otherwise go on
+ if (PyErr_Occurred())
+ {
+ PyErr_Print();
+ PyErr_Clear();
+ }
+
+ if (py_return != nullptr && py_return != Py_None)
+ {
+ if (PyInt_Check(py_return))
+ result = (uint32_t)PyInt_AsLong(py_return);
+ else if (PyLong_Check(py_return))
+ result = (uint32_t)PyLong_AsLong(py_return);
+ }
+ Py_XDECREF(py_return);
+
+ return result;
+}
+
+bool
+ScriptInterpreterPython::GetLongHelpForCommandObject (StructuredData::GenericSP cmd_obj_sp,
+ std::string& dest)
+{
+ bool got_string = false;
+ dest.clear();
+
+ Locker py_lock (this,
+ Locker::AcquireLock | Locker::NoSTDIN,
+ Locker::FreeLock);
+
+ static char callee_name[] = "get_long_help";
+
+ if (!cmd_obj_sp)
+ return false;
+
+ PyObject* implementor = (PyObject*)cmd_obj_sp->GetValue();
+
+ if (implementor == nullptr || implementor == Py_None)
+ return false;
+
+ PyObject* pmeth = PyObject_GetAttrString(implementor, callee_name);
+
+ if (PyErr_Occurred())
+ {
+ PyErr_Clear();
+ }
+
+ if (pmeth == nullptr || pmeth == Py_None)
+ {
+ Py_XDECREF(pmeth);
+ return false;
+ }
+
+ if (PyCallable_Check(pmeth) == 0)
+ {
+ if (PyErr_Occurred())
+ {
+ PyErr_Clear();
+ }
+
+ Py_XDECREF(pmeth);
+ return false;
+ }
+
+ if (PyErr_Occurred())
+ {
+ PyErr_Clear();
+ }
+
+ Py_XDECREF(pmeth);
+
+ // right now we know this function exists and is callable..
+ PyObject* py_return = PyObject_CallMethod(implementor, callee_name, nullptr);
+
+ // if it fails, print the error but otherwise go on
+ if (PyErr_Occurred())
+ {
+ PyErr_Print();
+ PyErr_Clear();
+ }
+
+ if (py_return != nullptr && py_return != Py_None)
+ {
+ if (PyString_Check(py_return))
+ {
+ dest.assign(PyString_AsString(py_return));
+ got_string = true;
+ }
+ }
+ Py_XDECREF(py_return);
+
+ return got_string;
+}
+
std::unique_ptr<ScriptInterpreterLocker>
ScriptInterpreterPython::AcquireInterpreterLock ()
{
@@ -2710,6 +3039,7 @@ ScriptInterpreterPython::InitializeInterpreter (SWIGInitCallback swig_init_callb
SWIGWatchpointCallbackFunction swig_watchpoint_callback,
SWIGPythonTypeScriptCallbackFunction swig_typescript_callback,
SWIGPythonCreateSyntheticProvider swig_synthetic_script,
+ SWIGPythonCreateCommandObject swig_create_cmd,
SWIGPythonCalculateNumChildren swig_calc_children,
SWIGPythonGetChildAtIndex swig_get_child_index,
SWIGPythonGetIndexOfChildWithName swig_get_index_child,
@@ -2719,6 +3049,7 @@ ScriptInterpreterPython::InitializeInterpreter (SWIGInitCallback swig_init_callb
SWIGPythonMightHaveChildrenSynthProviderInstance swig_mighthavechildren_provider,
SWIGPythonGetValueSynthProviderInstance swig_getvalue_provider,
SWIGPythonCallCommand swig_call_command,
+ SWIGPythonCallCommandObject swig_call_command_object,
SWIGPythonCallModuleInit swig_call_module_init,
SWIGPythonCreateOSPlugin swig_create_os_plugin,
SWIGPythonScriptKeyword_Process swig_run_script_keyword_process,
@@ -2735,6 +3066,7 @@ ScriptInterpreterPython::InitializeInterpreter (SWIGInitCallback swig_init_callb
g_swig_watchpoint_callback = swig_watchpoint_callback;
g_swig_typescript_callback = swig_typescript_callback;
g_swig_synthetic_script = swig_synthetic_script;
+ g_swig_create_cmd = swig_create_cmd;
g_swig_calc_children = swig_calc_children;
g_swig_get_child_index = swig_get_child_index;
g_swig_get_index_child = swig_get_index_child;
@@ -2744,6 +3076,7 @@ ScriptInterpreterPython::InitializeInterpreter (SWIGInitCallback swig_init_callb
g_swig_mighthavechildren_provider = swig_mighthavechildren_provider;
g_swig_getvalue_provider = swig_getvalue_provider;
g_swig_call_command = swig_call_command;
+ g_swig_call_command_object = swig_call_command_object;
g_swig_call_module_init = swig_call_module_init;
g_swig_create_os_plugin = swig_create_os_plugin;
g_swig_run_script_keyword_process = swig_run_script_keyword_process;
@@ -2759,11 +3092,7 @@ ScriptInterpreterPython::InitializeInterpreter (SWIGInitCallback swig_init_callb
void
ScriptInterpreterPython::InitializePrivate ()
{
- static int g_initialized = false;
-
- if (g_initialized)
- return;
-
+ assert(!g_initialized && "ScriptInterpreterPython::InitializePrivate() called more than once!");
g_initialized = true;
Timer scoped_timer (__PRETTY_FUNCTION__, __PRETTY_FUNCTION__);
@@ -2773,6 +3102,9 @@ ScriptInterpreterPython::InitializePrivate ()
TerminalState stdin_tty_state;
stdin_tty_state.Save(STDIN_FILENO, false);
+#if defined(LLDB_PYTHON_HOME)
+ Py_SetPythonHome(LLDB_PYTHON_HOME);
+#endif
PyGILState_STATE gstate;
Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SCRIPT | LIBLLDB_LOG_VERBOSE));
bool threads_already_initialized = false;
@@ -2787,43 +3119,23 @@ ScriptInterpreterPython::InitializePrivate ()
}
Py_InitializeEx (0);
- // Initialize SWIG after setting up python
if (g_swig_init_callback)
g_swig_init_callback ();
// Update the path python uses to search for modules to include the current directory.
PyRun_SimpleString ("import sys");
- PyRun_SimpleString ("sys.path.append ('.')");
-
- // Find the module that owns this code and use that path we get to
- // set the sys.path appropriately.
+ AddToSysPath(AddLocation::End, ".");
FileSpec file_spec;
- char python_dir_path[PATH_MAX];
+ // Don't denormalize paths when calling file_spec.GetPath(). On platforms that use
+ // a backslash as the path separator, this will result in executing python code containing
+ // paths with unescaped backslashes. But Python also accepts forward slashes, so to make
+ // life easier we just use that.
if (HostInfo::GetLLDBPath(ePathTypePythonDir, file_spec))
- {
- std::string python_path("sys.path.insert(0,\"");
- size_t orig_len = python_path.length();
- if (file_spec.GetPath(python_dir_path, sizeof (python_dir_path)))
- {
- python_path.append (python_dir_path);
- python_path.append ("\")");
- PyRun_SimpleString (python_path.c_str());
- python_path.resize (orig_len);
- }
-
- if (HostInfo::GetLLDBPath(ePathTypeLLDBShlibDir, file_spec))
- {
- if (file_spec.GetPath(python_dir_path, sizeof (python_dir_path)))
- {
- python_path.append (python_dir_path);
- python_path.append ("\")");
- PyRun_SimpleString (python_path.c_str());
- python_path.resize (orig_len);
- }
- }
- }
+ AddToSysPath(AddLocation::Beginning, file_spec.GetPath(false));
+ if (HostInfo::GetLLDBPath(ePathTypeLLDBShlibDir, file_spec))
+ AddToSysPath(AddLocation::Beginning, file_spec.GetPath(false));
PyRun_SimpleString ("sys.dont_write_bytecode = 1; import lldb.embedded_interpreter; from lldb.embedded_interpreter import run_python_interpreter; from lldb.embedded_interpreter import run_one_line");
@@ -2839,6 +3151,28 @@ ScriptInterpreterPython::InitializePrivate ()
stdin_tty_state.Restore();
}
+void
+ScriptInterpreterPython::AddToSysPath(AddLocation location, std::string path)
+{
+ std::string path_copy;
+
+ std::string statement;
+ if (location == AddLocation::Beginning)
+ {
+ statement.assign("sys.path.insert(0,\"");
+ statement.append (path);
+ statement.append ("\")");
+ }
+ else
+ {
+ statement.assign("sys.path.append(\"");
+ statement.append(path);
+ statement.append("\")");
+ }
+ PyRun_SimpleString (statement.c_str());
+}
+
+
//void
//ScriptInterpreterPython::Terminate ()
//{