Convert various CommandInterpreter functions to StringRef.

llvm-svn: 283370
This commit is contained in:
Zachary Turner
2016-10-05 20:03:37 +00:00
parent 0a6916f303
commit 11eb9c64a2
11 changed files with 286 additions and 297 deletions

View File

@@ -18,6 +18,7 @@
#include <vector>
// Other libraries and framework includes
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringRef.h"
// Project includes
#include "lldb/Core/Error.h"
@@ -136,6 +137,7 @@ public:
/// The number or arguments in this object.
//------------------------------------------------------------------
size_t GetArgumentCount() const;
bool empty() const { return GetArgumentCount() == 0; }
//------------------------------------------------------------------
/// Gets the NULL terminated C string argument pointer for the
@@ -147,6 +149,8 @@ public:
//------------------------------------------------------------------
const char *GetArgumentAtIndex(size_t idx) const;
llvm::ArrayRef<ArgEntry> entries() const { return m_entries; }
char GetArgumentQuoteCharAtIndex(size_t idx) const;
//------------------------------------------------------------------
@@ -315,9 +319,6 @@ public:
Error ParseOptions(Options &options, ExecutionContext *execution_context,
lldb::PlatformSP platform_sp, bool require_validation);
size_t FindArgumentIndexForOption(Option *long_options,
int long_options_index);
bool IsPositionalArgument(const char *arg);
// The following works almost identically to ParseOptions, except that no
@@ -459,6 +460,9 @@ public:
size_t *argument_index = nullptr) const;
private:
size_t FindArgumentIndexForOption(Option *long_options,
int long_options_index) const;
std::vector<ArgEntry> m_entries;
std::vector<char *> m_argv;

View File

@@ -108,6 +108,7 @@ public:
typedef std::map<std::string, lldb::CommandObjectSP> CommandMap;
// TODO: Change arguments and all derived classes to use StringRef.
CommandObject(CommandInterpreter &interpreter, const char *name,
const char *help = nullptr, const char *syntax = nullptr,
uint32_t flags = 0);

View File

@@ -27,6 +27,7 @@ namespace lldb_private {
class CommandObjectRegexCommand : public CommandObjectRaw {
public:
// TODO: Convert this class to use StringRefs.
CommandObjectRegexCommand(CommandInterpreter &interpreter, const char *name,
const char *help, const char *syntax,
uint32_t max_matches, uint32_t completion_type_mask,

View File

@@ -29,6 +29,8 @@
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "llvm/ADT/StringSwitch.h"
using namespace lldb;
using namespace lldb_private;
@@ -101,10 +103,7 @@ bool CommandObjectArgs::DoExecute(Args &args, CommandReturnObject &result) {
return false;
}
const size_t num_args = args.GetArgumentCount();
size_t arg_index;
if (!num_args) {
if (args.empty()) {
result.AppendError("args requires at least one argument");
result.SetStatus(eReturnStatusFailed);
return false;
@@ -143,73 +142,71 @@ bool CommandObjectArgs::DoExecute(Args &args, CommandReturnObject &result) {
ValueList value_list;
for (arg_index = 0; arg_index < num_args; ++arg_index) {
const char *arg_type_cstr = args.GetArgumentAtIndex(arg_index);
for (auto &arg_entry : args.entries()) {
llvm::StringRef arg_type = arg_entry.ref;
Value value;
value.SetValueType(Value::eValueTypeScalar);
CompilerType compiler_type;
char *int_pos;
if ((int_pos = strstr(const_cast<char *>(arg_type_cstr), "int"))) {
llvm::StringRef int_type = arg_type;
std::size_t int_pos = arg_type.find("int");
if (int_pos != llvm::StringRef::npos) {
Encoding encoding = eEncodingSint;
int width = 0;
if (int_pos > arg_type_cstr + 1) {
result.AppendErrorWithFormat("Invalid format: %s.\n", arg_type_cstr);
if (int_pos > 1) {
result.AppendErrorWithFormat("Invalid format: %s.\n",
arg_entry.c_str());
result.SetStatus(eReturnStatusFailed);
return false;
}
if (int_pos == arg_type_cstr + 1 && arg_type_cstr[0] != 'u') {
result.AppendErrorWithFormat("Invalid format: %s.\n", arg_type_cstr);
if (int_pos == 1 && arg_type[0] != 'u') {
result.AppendErrorWithFormat("Invalid format: %s.\n",
arg_entry.c_str());
result.SetStatus(eReturnStatusFailed);
return false;
}
if (arg_type_cstr[0] == 'u') {
if (arg_type[0] == 'u') {
encoding = eEncodingUint;
}
char *width_pos = int_pos + 3;
llvm::StringRef width_spec = arg_type.drop_front(int_pos + 3);
if (!strcmp(width_pos, "8_t"))
width = 8;
else if (!strcmp(width_pos, "16_t"))
width = 16;
else if (!strcmp(width_pos, "32_t"))
width = 32;
else if (!strcmp(width_pos, "64_t"))
width = 64;
else {
result.AppendErrorWithFormat("Invalid format: %s.\n", arg_type_cstr);
auto exp_result = llvm::StringSwitch<llvm::Optional<int>>(width_spec)
.Case("8_t", 8)
.Case("16_t", 16)
.Case("32_t", 32)
.Case("64_t", 64)
.Default(llvm::None);
if (!exp_result.hasValue()) {
result.AppendErrorWithFormat("Invalid format: %s.\n",
arg_entry.c_str());
result.SetStatus(eReturnStatusFailed);
return false;
}
width = *exp_result;
compiler_type =
type_system->GetBuiltinTypeForEncodingAndBitSize(encoding, width);
if (!compiler_type.IsValid()) {
result.AppendErrorWithFormat(
"Couldn't get Clang type for format %s (%s integer, width %d).\n",
arg_type_cstr, (encoding == eEncodingSint ? "signed" : "unsigned"),
width);
arg_entry.c_str(),
(encoding == eEncodingSint ? "signed" : "unsigned"), width);
result.SetStatus(eReturnStatusFailed);
return false;
}
} else if (strchr(arg_type_cstr, '*')) {
if (!strcmp(arg_type_cstr, "void*"))
compiler_type =
type_system->GetBasicTypeFromAST(eBasicTypeVoid).GetPointerType();
else if (!strcmp(arg_type_cstr, "char*"))
compiler_type =
type_system->GetBasicTypeFromAST(eBasicTypeChar).GetPointerType();
else {
result.AppendErrorWithFormat("Invalid format: %s.\n", arg_type_cstr);
result.SetStatus(eReturnStatusFailed);
return false;
}
} else if (arg_type == "void*") {
compiler_type =
type_system->GetBasicTypeFromAST(eBasicTypeVoid).GetPointerType();
} else if (arg_type == "char*") {
compiler_type =
type_system->GetBasicTypeFromAST(eBasicTypeChar).GetPointerType();
} else {
result.AppendErrorWithFormat("Invalid format: %s.\n", arg_type_cstr);
result.AppendErrorWithFormat("Invalid format: %s.\n", arg_entry.c_str());
result.SetStatus(eReturnStatusFailed);
return false;
}
@@ -226,10 +223,10 @@ bool CommandObjectArgs::DoExecute(Args &args, CommandReturnObject &result) {
result.GetOutputStream().Printf("Arguments : \n");
for (arg_index = 0; arg_index < num_args; ++arg_index) {
result.GetOutputStream().Printf("%" PRIu64 " (%s): ", (uint64_t)arg_index,
args.GetArgumentAtIndex(arg_index));
value_list.GetValueAtIndex(arg_index)->Dump(&result.GetOutputStream());
for (auto entry : llvm::enumerate(args.entries())) {
result.GetOutputStream().Printf("%" PRIu64 " (%s): ", (uint64_t)entry.Index,
entry.Value.c_str());
value_list.GetValueAtIndex(entry.Index)->Dump(&result.GetOutputStream());
result.GetOutputStream().Printf("\n");
}

View File

@@ -1113,7 +1113,7 @@ protected:
return false;
}
if (command.GetArgumentCount() == 0) {
if (command.empty()) {
// No breakpoint selected; enable all currently set breakpoints.
target->EnableAllBreakpoints();
result.AppendMessageWithFormat("All breakpoints enabled. (%" PRIu64
@@ -1226,7 +1226,7 @@ protected:
return false;
}
if (command.GetArgumentCount() == 0) {
if (command.empty()) {
// No breakpoint selected; disable all currently set breakpoints.
target->DisableAllBreakpoints();
result.AppendMessageWithFormat("All breakpoints disabled. (%" PRIu64
@@ -1400,7 +1400,7 @@ protected:
Stream &output_stream = result.GetOutputStream();
if (command.GetArgumentCount() == 0) {
if (command.empty()) {
// No breakpoint selected; show info about all currently set breakpoints.
result.AppendMessage("Current breakpoints:");
for (size_t i = 0; i < num_breakpoints; ++i) {
@@ -1693,7 +1693,7 @@ protected:
return false;
}
if (command.GetArgumentCount() == 0) {
if (command.empty()) {
if (!m_options.m_force &&
!m_interpreter.Confirm(
"About to delete all breakpoints, do you want to do that?",
@@ -2295,7 +2295,7 @@ protected:
target->GetBreakpointList().GetListMutex(lock);
BreakpointIDList valid_bp_ids;
if (command.GetArgumentCount() > 0) {
if (!command.empty()) {
CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs(
command, target, result, &valid_bp_ids);
@@ -2397,7 +2397,7 @@ void CommandObjectMultiwordBreakpoint::VerifyIDs(Args &args, Target *target,
Args temp_args;
if (args.GetArgumentCount() == 0) {
if (args.empty()) {
if (target->GetLastCreatedBreakpoint()) {
valid_ids->AddBreakpointID(BreakpointID(
target->GetLastCreatedBreakpoint()->GetID(), LLDB_INVALID_BREAK_ID));

View File

@@ -562,7 +562,7 @@ protected:
return false;
}
if (command.GetArgumentCount() == 0) {
if (command.empty()) {
result.AppendError(
"No breakpoint specified from which to delete the commands");
result.SetStatus(eReturnStatusFailed);
@@ -653,7 +653,7 @@ protected:
return false;
}
if (command.GetArgumentCount() == 0) {
if (command.empty()) {
result.AppendError(
"No breakpoint specified for which to list the commands");
result.SetStatus(eReturnStatusFailed);

View File

@@ -306,9 +306,8 @@ protected:
};
bool DoExecute(Args &command, CommandReturnObject &result) override {
const size_t argc = command.GetArgumentCount();
if (argc == 1) {
const char *filename = command.GetArgumentAtIndex(0);
if (command.GetArgumentCount() == 1) {
llvm::StringRef filename = command.GetArgumentAtIndex(0);
FileSpec cmd_file(filename, true);
ExecutionContext *exe_ctx = nullptr; // Just use the default context.
@@ -600,9 +599,7 @@ protected:
std::string raw_command_string(remainder);
Args args(raw_command_string.c_str());
size_t argc = args.GetArgumentCount();
if (argc < 2) {
if (args.GetArgumentCount() < 2) {
result.AppendError("'command alias' requires at least two arguments");
result.SetStatus(eReturnStatusFailed);
return false;
@@ -610,6 +607,8 @@ protected:
// Get the alias command.
// TODO: Convert this function to use StringRef. Requires converting
// GetCommandObjectForCommand.
const std::string alias_command = args.GetArgumentAtIndex(0);
if (alias_command.size() > 1 && alias_command[0] == '-') {
result.AppendError("aliases starting with a dash are not supported");
@@ -719,6 +718,9 @@ protected:
return false;
}
// TODO: Convert these to StringRefs. Should convert other dependent
// functions (CommandExists, UserCommandExists, AliasExists, AddAlias,
// etc at the same time.
const std::string alias_command = args.GetArgumentAtIndex(0);
const std::string actual_command = args.GetArgumentAtIndex(1);
@@ -744,11 +746,11 @@ protected:
OptionArgVectorSP option_arg_vector_sp =
OptionArgVectorSP(new OptionArgVector);
while (cmd_obj->IsMultiwordObject() && args.GetArgumentCount() > 0) {
while (cmd_obj->IsMultiwordObject() && !args.empty()) {
if (argc >= 3) {
const std::string sub_command = args.GetArgumentAtIndex(0);
assert(sub_command.length() != 0);
subcommand_obj_sp = cmd_obj->GetSubcommandSP(sub_command.c_str());
llvm::StringRef sub_command = args.GetArgumentAtIndex(0);
assert(!sub_command.empty());
subcommand_obj_sp = cmd_obj->GetSubcommandSP(sub_command.data());
if (subcommand_obj_sp) {
sub_cmd_obj = subcommand_obj_sp.get();
use_subcommand = true;
@@ -759,7 +761,7 @@ protected:
result.AppendErrorWithFormat(
"'%s' is not a valid sub-command of '%s'. "
"Unable to create alias.\n",
sub_command.c_str(), actual_command.c_str());
sub_command.data(), actual_command.c_str());
result.SetStatus(eReturnStatusFailed);
return false;
}
@@ -770,7 +772,7 @@ protected:
std::string args_string;
if (args.GetArgumentCount() > 0) {
if (!args.empty()) {
CommandObjectSP tmp_sp =
m_interpreter.GetCommandSPExact(cmd_obj->GetCommandName(), false);
if (use_subcommand)
@@ -847,44 +849,48 @@ protected:
CommandObject::CommandMap::iterator pos;
CommandObject *cmd_obj;
if (args.GetArgumentCount() != 0) {
const char *command_name = args.GetArgumentAtIndex(0);
cmd_obj = m_interpreter.GetCommandObject(command_name);
if (cmd_obj) {
if (m_interpreter.CommandExists(command_name)) {
if (cmd_obj->IsRemovable()) {
result.AppendErrorWithFormat(
"'%s' is not an alias, it is a debugger command which can be "
"removed using the 'command delete' command.\n",
command_name);
} else {
result.AppendErrorWithFormat(
"'%s' is a permanent debugger command and cannot be removed.\n",
command_name);
}
result.SetStatus(eReturnStatusFailed);
if (args.empty()) {
result.AppendError("must call 'unalias' with a valid alias");
result.SetStatus(eReturnStatusFailed);
return false;
}
// TODO: Convert this function to return a StringRef. Should also convert
// dependent functions GetCommandObject, CommandExists, RemoveAlias,
// AliasExists, etc.
const char *command_name = args.GetArgumentAtIndex(0);
cmd_obj = m_interpreter.GetCommandObject(command_name);
if (cmd_obj) {
if (m_interpreter.CommandExists(command_name)) {
if (cmd_obj->IsRemovable()) {
result.AppendErrorWithFormat(
"'%s' is not an alias, it is a debugger command which can be "
"removed using the 'command delete' command.\n",
command_name);
} else {
if (!m_interpreter.RemoveAlias(command_name)) {
if (m_interpreter.AliasExists(command_name))
result.AppendErrorWithFormat(
"Error occurred while attempting to unalias '%s'.\n",
command_name);
else
result.AppendErrorWithFormat("'%s' is not an existing alias.\n",
command_name);
result.SetStatus(eReturnStatusFailed);
} else
result.SetStatus(eReturnStatusSuccessFinishNoResult);
result.AppendErrorWithFormat(
"'%s' is a permanent debugger command and cannot be removed.\n",
command_name);
}
} else {
result.AppendErrorWithFormat(
"'%s' is not a known command.\nTry 'help' to see a "
"current list of commands.\n",
command_name);
result.SetStatus(eReturnStatusFailed);
} else {
if (!m_interpreter.RemoveAlias(command_name)) {
if (m_interpreter.AliasExists(command_name))
result.AppendErrorWithFormat(
"Error occurred while attempting to unalias '%s'.\n",
command_name);
else
result.AppendErrorWithFormat("'%s' is not an existing alias.\n",
command_name);
result.SetStatus(eReturnStatusFailed);
} else
result.SetStatus(eReturnStatusSuccessFinishNoResult);
}
} else {
result.AppendError("must call 'unalias' with a valid alias");
result.AppendErrorWithFormat(
"'%s' is not a known command.\nTry 'help' to see a "
"current list of commands.\n",
command_name);
result.SetStatus(eReturnStatusFailed);
}
@@ -925,34 +931,35 @@ protected:
bool DoExecute(Args &args, CommandReturnObject &result) override {
CommandObject::CommandMap::iterator pos;
if (args.GetArgumentCount() != 0) {
const char *command_name = args.GetArgumentAtIndex(0);
if (m_interpreter.CommandExists(command_name)) {
if (m_interpreter.RemoveCommand(command_name)) {
result.SetStatus(eReturnStatusSuccessFinishNoResult);
} else {
result.AppendErrorWithFormat(
"'%s' is a permanent debugger command and cannot be removed.\n",
command_name);
result.SetStatus(eReturnStatusFailed);
}
} else {
StreamString error_msg_stream;
const bool generate_apropos = true;
const bool generate_type_lookup = false;
CommandObjectHelp::GenerateAdditionalHelpAvenuesMessage(
&error_msg_stream, command_name, nullptr, nullptr, generate_apropos,
generate_type_lookup);
result.AppendErrorWithFormat("%s", error_msg_stream.GetData());
result.SetStatus(eReturnStatusFailed);
}
} else {
if (args.empty()) {
result.AppendErrorWithFormat("must call '%s' with one or more valid user "
"defined regular expression command names",
GetCommandName());
result.SetStatus(eReturnStatusFailed);
}
// TODO: Convert this to accept a stringRef.
const char *command_name = args.GetArgumentAtIndex(0);
if (m_interpreter.CommandExists(command_name)) {
if (m_interpreter.RemoveCommand(command_name)) {
result.SetStatus(eReturnStatusSuccessFinishNoResult);
} else {
result.AppendErrorWithFormat(
"'%s' is a permanent debugger command and cannot be removed.\n",
command_name);
result.SetStatus(eReturnStatusFailed);
}
} else {
StreamString error_msg_stream;
const bool generate_apropos = true;
const bool generate_type_lookup = false;
CommandObjectHelp::GenerateAdditionalHelpAvenuesMessage(
&error_msg_stream, command_name, nullptr, nullptr, generate_apropos,
generate_type_lookup);
result.AppendErrorWithFormat("%s", error_msg_stream.GetData());
result.SetStatus(eReturnStatusFailed);
}
return result.Succeeded();
}
};
@@ -1064,48 +1071,49 @@ protected:
result.AppendError("usage: 'command regex <command-name> "
"[s/<regex1>/<subst1>/ s/<regex2>/<subst2>/ ...]'\n");
result.SetStatus(eReturnStatusFailed);
return false;
}
Error error;
const char *name = command.GetArgumentAtIndex(0);
m_regex_cmd_ap.reset(
new CommandObjectRegexCommand(m_interpreter, name, m_options.GetHelp(),
m_options.GetSyntax(), 10, 0, true));
if (argc == 1) {
Debugger &debugger = m_interpreter.GetDebugger();
bool color_prompt = debugger.GetUseColor();
const bool multiple_lines = true; // Get multiple lines
IOHandlerSP io_handler_sp(new IOHandlerEditline(
debugger, IOHandler::Type::Other,
"lldb-regex", // Name of input reader for history
llvm::StringRef("> "), // Prompt
llvm::StringRef(), // Continuation prompt
multiple_lines, color_prompt,
0, // Don't show line numbers
*this));
if (io_handler_sp) {
debugger.PushIOHandler(io_handler_sp);
result.SetStatus(eReturnStatusSuccessFinishNoResult);
}
} else {
Error error;
const char *name = command.GetArgumentAtIndex(0);
m_regex_cmd_ap.reset(new CommandObjectRegexCommand(
m_interpreter, name, m_options.GetHelp(), m_options.GetSyntax(), 10,
0, true));
if (argc == 1) {
Debugger &debugger = m_interpreter.GetDebugger();
bool color_prompt = debugger.GetUseColor();
const bool multiple_lines = true; // Get multiple lines
IOHandlerSP io_handler_sp(new IOHandlerEditline(
debugger, IOHandler::Type::Other,
"lldb-regex", // Name of input reader for history
llvm::StringRef("> "), // Prompt
llvm::StringRef(), // Continuation prompt
multiple_lines, color_prompt,
0, // Don't show line numbers
*this));
if (io_handler_sp) {
debugger.PushIOHandler(io_handler_sp);
result.SetStatus(eReturnStatusSuccessFinishNoResult);
}
} else {
for (size_t arg_idx = 1; arg_idx < argc; ++arg_idx) {
llvm::StringRef arg_strref(command.GetArgumentAtIndex(arg_idx));
bool check_only = false;
error = AppendRegexSubstitution(arg_strref, check_only);
if (error.Fail())
break;
}
if (error.Success()) {
AddRegexCommandToInterpreter();
}
for (size_t arg_idx = 1; arg_idx < argc; ++arg_idx) {
llvm::StringRef arg_strref(command.GetArgumentAtIndex(arg_idx));
bool check_only = false;
error = AppendRegexSubstitution(arg_strref, check_only);
if (error.Fail())
break;
}
if (error.Fail()) {
result.AppendError(error.AsCString());
result.SetStatus(eReturnStatusFailed);
if (error.Success()) {
AddRegexCommandToInterpreter();
}
}
if (error.Fail()) {
result.AppendError(error.AsCString());
result.SetStatus(eReturnStatusFailed);
}
return result.Succeeded();
}
@@ -1254,6 +1262,7 @@ private:
return llvm::makeArrayRef(g_regex_options);
}
// TODO: Convert these functions to return StringRefs.
const char *GetHelp() {
return (m_help.empty() ? nullptr : m_help.c_str());
}
@@ -1532,33 +1541,26 @@ protected:
return false;
}
size_t argc = command.GetArgumentCount();
if (0 == argc) {
if (command.empty()) {
result.AppendError("command script import needs one or more arguments");
result.SetStatus(eReturnStatusFailed);
return false;
}
for (size_t i = 0; i < argc; i++) {
std::string path = command.GetArgumentAtIndex(i);
for (auto &entry : command.entries()) {
Error error;
const bool init_session = true;
// FIXME: this is necessary because CommandObject::CheckRequirements()
// assumes that
// commands won't ever be recursively invoked, but it's actually possible
// to craft
// a Python script that does other "command script imports" in
// __lldb_init_module
// the real fix is to have recursive commands possible with a
// CommandInvocation object
// separate from the CommandObject itself, so that recursive command
// invocations
// won't stomp on each other (wrt to execution contents, options, and
// more)
// assumes that commands won't ever be recursively invoked, but it's
// actually possible to craft a Python script that does other "command
// script imports" in __lldb_init_module the real fix is to have recursive
// commands possible with a CommandInvocation object separate from the
// CommandObject itself, so that recursive command invocations won't stomp
// on each other (wrt to execution contents, options, and more)
m_exe_ctx.Clear();
if (m_interpreter.GetScriptInterpreter()->LoadScriptingModule(
path.c_str(), m_options.m_allow_reload, init_session, error)) {
entry.c_str(), m_options.m_allow_reload, init_session, error)) {
result.SetStatus(eReturnStatusSuccessFinishNoResult);
} else {
result.AppendErrorWithFormat("module importing failed: %s",
@@ -1752,9 +1754,7 @@ protected:
return false;
}
size_t argc = command.GetArgumentCount();
if (argc != 1) {
if (command.GetArgumentCount() != 1) {
result.AppendError("'command script add' requires one argument");
result.SetStatus(eReturnStatusFailed);
return false;
@@ -1892,9 +1892,7 @@ public:
protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
size_t argc = command.GetArgumentCount();
if (argc != 1) {
if (command.GetArgumentCount() != 1) {
result.AppendError("'command script delete' requires one argument");
result.SetStatus(eReturnStatusFailed);
return false;

View File

@@ -300,7 +300,7 @@ bool CommandObjectDisassemble::DoExecute(Args &command,
result.SetStatus(eReturnStatusSuccessFinishResult);
if (command.GetArgumentCount() != 0) {
if (!command.empty()) {
result.AppendErrorWithFormat(
"\"disassemble\" arguments are specified as options.\n");
const int terminal_width =

View File

@@ -533,7 +533,7 @@ protected:
const Format format = m_option_format.GetFormat();
options.SetFormat(format);
if (command.GetArgumentCount() > 0) {
if (!command.empty()) {
VariableList regex_var_list;
// If we have any args to the variable command, we will make

View File

@@ -182,22 +182,24 @@ protected:
result.AppendErrorWithFormat(
"%s takes a log channel and one or more log types.\n",
m_cmd_name.c_str());
} else {
std::string channel(args.GetArgumentAtIndex(0));
args.Shift(); // Shift off the channel
char log_file[PATH_MAX];
if (m_options.log_file)
m_options.log_file.GetPath(log_file, sizeof(log_file));
else
log_file[0] = '\0';
bool success = m_interpreter.GetDebugger().EnableLog(
channel.c_str(), args.GetConstArgumentVector(), log_file,
m_options.log_options, result.GetErrorStream());
if (success)
result.SetStatus(eReturnStatusSuccessFinishNoResult);
else
result.SetStatus(eReturnStatusFailed);
return false;
}
// Store into a std::string since we're about to shift the channel off.
std::string channel = args.GetArgumentAtIndex(0);
args.Shift(); // Shift off the channel
char log_file[PATH_MAX];
if (m_options.log_file)
m_options.log_file.GetPath(log_file, sizeof(log_file));
else
log_file[0] = '\0';
bool success = m_interpreter.GetDebugger().EnableLog(
channel.c_str(), args.GetConstArgumentVector(), log_file,
m_options.log_options, result.GetErrorStream());
if (success)
result.SetStatus(eReturnStatusSuccessFinishNoResult);
else
result.SetStatus(eReturnStatusFailed);
return result.Succeeded();
}
@@ -240,33 +242,32 @@ public:
protected:
bool DoExecute(Args &args, CommandReturnObject &result) override {
const size_t argc = args.GetArgumentCount();
if (argc == 0) {
if (args.empty()) {
result.AppendErrorWithFormat(
"%s takes a log channel and one or more log types.\n",
m_cmd_name.c_str());
} else {
Log::Callbacks log_callbacks;
return false;
}
std::string channel(args.GetArgumentAtIndex(0));
args.Shift(); // Shift off the channel
if (Log::GetLogChannelCallbacks(ConstString(channel.c_str()),
log_callbacks)) {
log_callbacks.disable(args.GetConstArgumentVector(),
&result.GetErrorStream());
Log::Callbacks log_callbacks;
const std::string channel = args.GetArgumentAtIndex(0);
args.Shift(); // Shift off the channel
if (Log::GetLogChannelCallbacks(ConstString(channel), log_callbacks)) {
log_callbacks.disable(args.GetConstArgumentVector(),
&result.GetErrorStream());
result.SetStatus(eReturnStatusSuccessFinishNoResult);
} else if (channel == "all") {
Log::DisableAllLogChannels(&result.GetErrorStream());
} else {
LogChannelSP log_channel_sp(LogChannel::FindPlugin(channel.data()));
if (log_channel_sp) {
log_channel_sp->Disable(args.GetConstArgumentVector(),
&result.GetErrorStream());
result.SetStatus(eReturnStatusSuccessFinishNoResult);
} else if (channel == "all") {
Log::DisableAllLogChannels(&result.GetErrorStream());
} else {
LogChannelSP log_channel_sp(LogChannel::FindPlugin(channel.c_str()));
if (log_channel_sp) {
log_channel_sp->Disable(args.GetConstArgumentVector(),
&result.GetErrorStream());
result.SetStatus(eReturnStatusSuccessFinishNoResult);
} else
result.AppendErrorWithFormat("Invalid log channel '%s'.\n",
args.GetArgumentAtIndex(0));
}
} else
result.AppendErrorWithFormat("Invalid log channel '%s'.\n",
channel.data());
}
return result.Succeeded();
}
@@ -301,30 +302,28 @@ public:
protected:
bool DoExecute(Args &args, CommandReturnObject &result) override {
const size_t argc = args.GetArgumentCount();
if (argc == 0) {
if (args.empty()) {
Log::ListAllLogChannels(&result.GetOutputStream());
result.SetStatus(eReturnStatusSuccessFinishResult);
} else {
for (size_t i = 0; i < argc; ++i) {
for (auto &entry : args.entries()) {
Log::Callbacks log_callbacks;
std::string channel(args.GetArgumentAtIndex(i));
if (Log::GetLogChannelCallbacks(ConstString(channel.c_str()),
if (Log::GetLogChannelCallbacks(ConstString(entry.ref),
log_callbacks)) {
log_callbacks.list_categories(&result.GetOutputStream());
result.SetStatus(eReturnStatusSuccessFinishResult);
} else if (channel == "all") {
} else if (entry.ref == "all") {
Log::ListAllLogChannels(&result.GetOutputStream());
result.SetStatus(eReturnStatusSuccessFinishResult);
} else {
LogChannelSP log_channel_sp(LogChannel::FindPlugin(channel.c_str()));
LogChannelSP log_channel_sp(LogChannel::FindPlugin(entry.c_str()));
if (log_channel_sp) {
log_channel_sp->ListCategories(&result.GetOutputStream());
result.SetStatus(eReturnStatusSuccessFinishNoResult);
} else
result.AppendErrorWithFormat("Invalid log channel '%s'.\n",
args.GetArgumentAtIndex(0));
entry.c_str());
}
}
}
@@ -348,45 +347,41 @@ public:
protected:
bool DoExecute(Args &args, CommandReturnObject &result) override {
const size_t argc = args.GetArgumentCount();
result.SetStatus(eReturnStatusFailed);
if (argc == 1) {
const char *sub_command = args.GetArgumentAtIndex(0);
if (args.GetArgumentCount() == 1) {
llvm::StringRef sub_command = args.GetArgumentAtIndex(0);
if (strcasecmp(sub_command, "enable") == 0) {
if (sub_command.equals_lower("enable")) {
Timer::SetDisplayDepth(UINT32_MAX);
result.SetStatus(eReturnStatusSuccessFinishNoResult);
} else if (strcasecmp(sub_command, "disable") == 0) {
} else if (sub_command.equals_lower("disable")) {
Timer::DumpCategoryTimes(&result.GetOutputStream());
Timer::SetDisplayDepth(0);
result.SetStatus(eReturnStatusSuccessFinishResult);
} else if (strcasecmp(sub_command, "dump") == 0) {
} else if (sub_command.equals_lower("dump")) {
Timer::DumpCategoryTimes(&result.GetOutputStream());
result.SetStatus(eReturnStatusSuccessFinishResult);
} else if (strcasecmp(sub_command, "reset") == 0) {
} else if (sub_command.equals_lower("reset")) {
Timer::ResetCategoryTimes();
result.SetStatus(eReturnStatusSuccessFinishResult);
}
} else if (argc == 2) {
const char *sub_command = args.GetArgumentAtIndex(0);
} else if (args.GetArgumentCount() == 2) {
llvm::StringRef sub_command = args.GetArgumentAtIndex(0);
llvm::StringRef param = args.GetArgumentAtIndex(1);
if (strcasecmp(sub_command, "enable") == 0) {
bool success;
uint32_t depth =
StringConvert::ToUInt32(args.GetArgumentAtIndex(1), 0, 0, &success);
if (success) {
Timer::SetDisplayDepth(depth);
result.SetStatus(eReturnStatusSuccessFinishNoResult);
} else
if (sub_command.equals_lower("enable")) {
uint32_t depth;
if (param.consumeInteger(0, depth)) {
result.AppendError(
"Could not convert enable depth to an unsigned integer.");
}
if (strcasecmp(sub_command, "increment") == 0) {
} else {
Timer::SetDisplayDepth(depth);
result.SetStatus(eReturnStatusSuccessFinishNoResult);
}
} else if (sub_command.equals_lower("increment")) {
bool success;
bool increment = Args::StringToBoolean(
llvm::StringRef::withNullAsEmpty(args.GetArgumentAtIndex(1)), false,
&success);
bool increment = Args::StringToBoolean(param, false, &success);
if (success) {
Timer::SetQuiet(!increment);
result.SetStatus(eReturnStatusSuccessFinishNoResult);

View File

@@ -25,6 +25,7 @@
#include "lldb/Target/StackFrame.h"
#include "lldb/Target/Target.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringSwitch.h"
@@ -925,16 +926,15 @@ bool Args::ContainsEnvironmentVariable(llvm::StringRef env_var_name,
return false;
// Check each arg to see if it matches the env var name.
for (size_t i = 0; i < GetArgumentCount(); ++i) {
auto arg_value = llvm::StringRef::withNullAsEmpty(GetArgumentAtIndex(i));
for (auto arg : llvm::enumerate(m_entries)) {
llvm::StringRef name, value;
std::tie(name, value) = arg_value.split('=');
if (name == env_var_name) {
if (argument_index)
*argument_index = i;
return true;
}
std::tie(name, value) = arg.Value.ref.split('=');
if (name != env_var_name)
continue;
if (argument_index)
*argument_index = arg.Index;
return true;
}
// We didn't find a match.
@@ -942,26 +942,21 @@ bool Args::ContainsEnvironmentVariable(llvm::StringRef env_var_name,
}
size_t Args::FindArgumentIndexForOption(Option *long_options,
int long_options_index) {
int long_options_index) const {
char short_buffer[3];
char long_buffer[255];
::snprintf(short_buffer, sizeof(short_buffer), "-%c",
long_options[long_options_index].val);
::snprintf(long_buffer, sizeof(long_buffer), "--%s",
long_options[long_options_index].definition->long_option);
size_t end = GetArgumentCount();
size_t idx = 0;
while (idx < end) {
if ((::strncmp(GetArgumentAtIndex(idx), short_buffer,
strlen(short_buffer)) == 0) ||
(::strncmp(GetArgumentAtIndex(idx), long_buffer, strlen(long_buffer)) ==
0)) {
return idx;
}
++idx;
for (auto entry : llvm::enumerate(m_entries)) {
if (entry.Value.ref.startswith(short_buffer) ||
entry.Value.ref.startswith(long_buffer))
return entry.Index;
}
return end;
return size_t(-1);
}
bool Args::IsPositionalArgument(const char *arg) {
@@ -1094,28 +1089,29 @@ void Args::ParseAliasOptions(Options &options, CommandReturnObject &result,
// given) from the argument list. Also remove them from the
// raw_input_string, if one was passed in.
size_t idx = FindArgumentIndexForOption(long_options, long_options_index);
if (idx < GetArgumentCount()) {
if (idx == size_t(-1))
continue;
if (raw_input_string.size() > 0) {
const char *tmp_arg = GetArgumentAtIndex(idx);
size_t pos = raw_input_string.find(tmp_arg);
if (pos != std::string::npos)
raw_input_string.erase(pos, strlen(tmp_arg));
}
ReplaceArgumentAtIndex(idx, llvm::StringRef());
if ((long_options[long_options_index].definition->option_has_arg !=
OptionParser::eNoArgument) &&
(OptionParser::GetOptionArgument() != nullptr) &&
(idx + 1 < GetArgumentCount()) &&
(strcmp(OptionParser::GetOptionArgument(),
GetArgumentAtIndex(idx + 1)) == 0)) {
if (raw_input_string.size() > 0) {
const char *tmp_arg = GetArgumentAtIndex(idx);
const char *tmp_arg = GetArgumentAtIndex(idx + 1);
size_t pos = raw_input_string.find(tmp_arg);
if (pos != std::string::npos)
raw_input_string.erase(pos, strlen(tmp_arg));
}
ReplaceArgumentAtIndex(idx, llvm::StringRef());
if ((long_options[long_options_index].definition->option_has_arg !=
OptionParser::eNoArgument) &&
(OptionParser::GetOptionArgument() != nullptr) &&
(idx + 1 < GetArgumentCount()) &&
(strcmp(OptionParser::GetOptionArgument(),
GetArgumentAtIndex(idx + 1)) == 0)) {
if (raw_input_string.size() > 0) {
const char *tmp_arg = GetArgumentAtIndex(idx + 1);
size_t pos = raw_input_string.find(tmp_arg);
if (pos != std::string::npos)
raw_input_string.erase(pos, strlen(tmp_arg));
}
ReplaceArgumentAtIndex(idx + 1, llvm::StringRef());
}
ReplaceArgumentAtIndex(idx + 1, llvm::StringRef());
}
}
}
@@ -1160,13 +1156,10 @@ void Args::ParseArgsForCompletion(Options &options,
auto opt_defs = options.GetDefinitions();
// Fooey... OptionParser::Parse permutes the GetArgumentVector to move the
// options to the front.
// So we have to build another Arg and pass that to OptionParser::Parse so it
// doesn't
// change the one we have.
// options to the front. So we have to build another Arg and pass that to
// OptionParser::Parse so it doesn't change the one we have.
std::vector<const char *> dummy_vec(
GetArgumentVector(), GetArgumentVector() + GetArgumentCount() + 1);
std::vector<char *> dummy_vec = m_argv;
bool failed_once = false;
uint32_t dash_dash_pos = -1;
@@ -1175,9 +1168,9 @@ void Args::ParseArgsForCompletion(Options &options,
bool missing_argument = false;
int long_options_index = -1;
val = OptionParser::Parse(
dummy_vec.size() - 1, const_cast<char *const *>(&dummy_vec.front()),
sstr.GetData(), long_options, &long_options_index);
val =
OptionParser::Parse(dummy_vec.size() - 1, &dummy_vec[0], sstr.GetData(),
long_options, &long_options_index);
if (val == -1) {
// When we're completing a "--" which is the last option on line,