Remove some more uses of Args::GetArgumentAtIndex.

llvm-svn: 289188
This commit is contained in:
Zachary Turner 2016-12-09 05:46:41 +00:00
parent 8db7e5e4ee
commit 2c84f908af
6 changed files with 142 additions and 157 deletions

View File

@ -98,58 +98,61 @@ bool CommandObjectMultiword::Execute(const char *args_string,
const size_t argc = args.GetArgumentCount(); const size_t argc = args.GetArgumentCount();
if (argc == 0) { if (argc == 0) {
this->CommandObject::GenerateHelpText(result); this->CommandObject::GenerateHelpText(result);
} else { return result.Succeeded();
const char *sub_command = args.GetArgumentAtIndex(0);
if (sub_command) {
if (::strcasecmp(sub_command, "help") == 0) {
this->CommandObject::GenerateHelpText(result);
} else if (!m_subcommand_dict.empty()) {
StringList matches;
CommandObject *sub_cmd_obj = GetSubcommandObject(sub_command, &matches);
if (sub_cmd_obj != nullptr) {
// Now call CommandObject::Execute to process and options in
// 'rest_of_line'. From there
// the command-specific version of Execute will be called, with the
// processed arguments.
args.Shift();
sub_cmd_obj->Execute(args_string, result);
} else {
std::string error_msg;
const size_t num_subcmd_matches = matches.GetSize();
if (num_subcmd_matches > 0)
error_msg.assign("ambiguous command ");
else
error_msg.assign("invalid command ");
error_msg.append("'");
error_msg.append(GetCommandName());
error_msg.append(" ");
error_msg.append(sub_command);
error_msg.append("'.");
if (num_subcmd_matches > 0) {
error_msg.append(" Possible completions:");
for (size_t i = 0; i < num_subcmd_matches; i++) {
error_msg.append("\n\t");
error_msg.append(matches.GetStringAtIndex(i));
}
}
error_msg.append("\n");
result.AppendRawError(error_msg.c_str());
result.SetStatus(eReturnStatusFailed);
}
} else {
result.AppendErrorWithFormat("'%s' does not have any subcommands.\n",
GetCommandName().str().c_str());
result.SetStatus(eReturnStatusFailed);
}
}
} }
return result.Succeeded(); auto sub_command = args[0].ref;
if (sub_command.empty())
return result.Succeeded();
if (sub_command.equals_lower("help")) {
this->CommandObject::GenerateHelpText(result);
return result.Succeeded();
}
if (m_subcommand_dict.empty()) {
result.AppendErrorWithFormat("'%s' does not have any subcommands.\n",
GetCommandName().str().c_str());
result.SetStatus(eReturnStatusFailed);
return false;
}
StringList matches;
CommandObject *sub_cmd_obj = GetSubcommandObject(sub_command, &matches);
if (sub_cmd_obj != nullptr) {
// Now call CommandObject::Execute to process options in `rest_of_line`.
// From there the command-specific version of Execute will be called,
// with the processed arguments.
args.Shift();
sub_cmd_obj->Execute(args_string, result);
return result.Succeeded();
}
std::string error_msg;
const size_t num_subcmd_matches = matches.GetSize();
if (num_subcmd_matches > 0)
error_msg.assign("ambiguous command ");
else
error_msg.assign("invalid command ");
error_msg.append("'");
error_msg.append(GetCommandName());
error_msg.append(" ");
error_msg.append(sub_command);
error_msg.append("'.");
if (num_subcmd_matches > 0) {
error_msg.append(" Possible completions:");
for (size_t i = 0; i < num_subcmd_matches; i++) {
error_msg.append("\n\t");
error_msg.append(matches.GetStringAtIndex(i));
}
}
error_msg.append("\n");
result.AppendRawError(error_msg.c_str());
result.SetStatus(eReturnStatusFailed);
return false;
} }
void CommandObjectMultiword::GenerateHelpText(Stream &output_stream) { void CommandObjectMultiword::GenerateHelpText(Stream &output_stream) {
@ -191,16 +194,15 @@ int CommandObjectMultiword::HandleCompletion(Args &input, int &cursor_index,
bool &word_complete, bool &word_complete,
StringList &matches) { StringList &matches) {
// Any of the command matches will provide a complete word, otherwise the // Any of the command matches will provide a complete word, otherwise the
// individual // individual completers will override this.
// completers will override this.
word_complete = true; word_complete = true;
const char *arg0 = input.GetArgumentAtIndex(0); auto arg0 = input[0].ref;
if (cursor_index == 0) { if (cursor_index == 0) {
AddNamesMatchingPartialString(m_subcommand_dict, arg0, matches); AddNamesMatchingPartialString(m_subcommand_dict, arg0, matches);
if (matches.GetSize() == 1 && matches.GetStringAtIndex(0) != nullptr && if (matches.GetSize() == 1 && matches.GetStringAtIndex(0) != nullptr &&
strcmp(arg0, matches.GetStringAtIndex(0)) == 0) { (arg0 == matches.GetStringAtIndex(0))) {
StringList temp_matches; StringList temp_matches;
CommandObject *cmd_obj = GetSubcommandObject(arg0, &temp_matches); CommandObject *cmd_obj = GetSubcommandObject(arg0, &temp_matches);
if (cmd_obj != nullptr) { if (cmd_obj != nullptr) {
@ -240,7 +242,7 @@ const char *CommandObjectMultiword::GetRepeatCommand(Args &current_command_args,
if (current_command_args.GetArgumentCount() <= index) if (current_command_args.GetArgumentCount() <= index)
return nullptr; return nullptr;
CommandObject *sub_command_object = CommandObject *sub_command_object =
GetSubcommandObject(current_command_args.GetArgumentAtIndex(index)); GetSubcommandObject(current_command_args[index].ref);
if (sub_command_object == nullptr) if (sub_command_object == nullptr)
return nullptr; return nullptr;
return sub_command_object->GetRepeatCommand(current_command_args, index); return sub_command_object->GetRepeatCommand(current_command_args, index);

View File

@ -48,12 +48,12 @@ public:
int match_start_point, int max_return_elements, int match_start_point, int max_return_elements,
bool &word_complete, bool &word_complete,
StringList &matches) override { StringList &matches) override {
std::string completion_str(input.GetArgumentAtIndex(cursor_index)); auto completion_str = input[cursor_index].ref;
completion_str.erase(cursor_char_position); completion_str = completion_str.take_front(cursor_char_position);
CommandCompletions::InvokeCommonCompletionCallbacks( CommandCompletions::InvokeCommonCompletionCallbacks(
GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion, GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
completion_str.c_str(), match_start_point, max_return_elements, nullptr, completion_str, match_start_point, max_return_elements, nullptr,
word_complete, matches); word_complete, matches);
return matches.GetSize(); return matches.GetSize();
} }
@ -68,11 +68,9 @@ protected:
return false; return false;
} }
const char *path = command.GetArgumentAtIndex(0);
Error error; Error error;
FileSpec dylib_fspec(path, true); FileSpec dylib_fspec(command[0].ref, true);
if (m_interpreter.GetDebugger().LoadPlugin(dylib_fspec, error)) if (m_interpreter.GetDebugger().LoadPlugin(dylib_fspec, error))
result.SetStatus(eReturnStatusSuccessFinishResult); result.SetStatus(eReturnStatusSuccessFinishResult);

View File

@ -212,27 +212,23 @@ protected:
"registers names are supplied as arguments\n"); "registers names are supplied as arguments\n");
result.SetStatus(eReturnStatusFailed); result.SetStatus(eReturnStatusFailed);
} else { } else {
const char *arg_cstr; for (auto &entry : command) {
for (int arg_idx = 0;
(arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
++arg_idx) {
// in most LLDB commands we accept $rbx as the name for register RBX - // in most LLDB commands we accept $rbx as the name for register RBX -
// and here we would // and here we would reject it and non-existant. we should be more
// reject it and non-existant. we should be more consistent towards // consistent towards the user and allow them to say reg read $rbx -
// the user and allow them // internally, however, we should be strict and not allow ourselves
// to say reg read $rbx - internally, however, we should be strict and
// not allow ourselves
// to call our registers $rbx in our own API // to call our registers $rbx in our own API
if (*arg_cstr == '$') auto arg_str = entry.ref;
arg_cstr = arg_cstr + 1; arg_str.consume_front("$");
reg_info = reg_ctx->GetRegisterInfoByName(arg_cstr);
reg_info = reg_ctx->GetRegisterInfoByName(arg_str);
if (reg_info) { if (reg_info) {
if (!DumpRegister(m_exe_ctx, strm, reg_ctx, reg_info)) if (!DumpRegister(m_exe_ctx, strm, reg_ctx, reg_info))
strm.Printf("%-12s = error: unavailable\n", reg_info->name); strm.Printf("%-12s = error: unavailable\n", reg_info->name);
} else { } else {
result.AppendErrorWithFormat("Invalid register name '%s'.\n", result.AppendErrorWithFormat("Invalid register name '%s'.\n",
arg_cstr); arg_str.str().c_str());
} }
} }
} }
@ -355,18 +351,15 @@ protected:
"register write takes exactly 2 arguments: <reg-name> <value>"); "register write takes exactly 2 arguments: <reg-name> <value>");
result.SetStatus(eReturnStatusFailed); result.SetStatus(eReturnStatusFailed);
} else { } else {
const char *reg_name = command.GetArgumentAtIndex(0); auto reg_name = command[0].ref;
llvm::StringRef value_str = command.GetArgumentAtIndex(1); auto value_str = command[1].ref;
// in most LLDB commands we accept $rbx as the name for register RBX - and // in most LLDB commands we accept $rbx as the name for register RBX - and
// here we would // here we would reject it and non-existant. we should be more consistent
// reject it and non-existant. we should be more consistent towards the // towards the user and allow them to say reg write $rbx - internally,
// user and allow them // however, we should be strict and not allow ourselves to call our
// to say reg write $rbx - internally, however, we should be strict and // registers $rbx in our own API
// not allow ourselves reg_name.consume_front("$");
// to call our registers $rbx in our own API
if (reg_name && *reg_name == '$')
reg_name = reg_name + 1;
const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(reg_name); const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(reg_name);
@ -385,17 +378,18 @@ protected:
} }
if (error.AsCString()) { if (error.AsCString()) {
result.AppendErrorWithFormat( result.AppendErrorWithFormat(
"Failed to write register '%s' with value '%s': %s\n", reg_name, "Failed to write register '%s' with value '%s': %s\n",
value_str.str().c_str(), error.AsCString()); reg_name.str().c_str(), value_str.str().c_str(),
error.AsCString());
} else { } else {
result.AppendErrorWithFormat( result.AppendErrorWithFormat(
"Failed to write register '%s' with value '%s'", reg_name, "Failed to write register '%s' with value '%s'",
value_str.str().c_str()); reg_name.str().c_str(), value_str.str().c_str());
} }
result.SetStatus(eReturnStatusFailed); result.SetStatus(eReturnStatusFailed);
} else { } else {
result.AppendErrorWithFormat("Register not found for '%s'.\n", result.AppendErrorWithFormat("Register not found for '%s'.\n",
reg_name); reg_name.str().c_str());
result.SetStatus(eReturnStatusFailed); result.SetStatus(eReturnStatusFailed);
} }
} }

View File

@ -774,24 +774,20 @@ public:
const char *GetRepeatCommand(Args &current_command_args, const char *GetRepeatCommand(Args &current_command_args,
uint32_t index) override { uint32_t index) override {
// This is kind of gross, but the command hasn't been parsed yet so we can't // This is kind of gross, but the command hasn't been parsed yet so we can't
// look at the option // look at the option values for this invocation... I have to scan the
// values for this invocation... I have to scan the arguments directly. // arguments directly.
size_t num_args = current_command_args.GetArgumentCount(); auto iter =
bool is_reverse = false; llvm::find_if(current_command_args, [](const Args::ArgEntry &e) {
for (size_t i = 0; i < num_args; i++) { return e.ref == "-r" || e.ref == "--reverse";
const char *arg = current_command_args.GetArgumentAtIndex(i); });
if (arg && (strcmp(arg, "-r") == 0 || strcmp(arg, "--reverse") == 0)) { if (iter == current_command_args.end())
is_reverse = true;
}
}
if (is_reverse) {
if (m_reverse_name.empty()) {
m_reverse_name = m_cmd_name;
m_reverse_name.append(" -r");
}
return m_reverse_name.c_str();
} else
return m_cmd_name.c_str(); return m_cmd_name.c_str();
if (m_reverse_name.empty()) {
m_reverse_name = m_cmd_name;
m_reverse_name.append(" -r");
}
return m_reverse_name.c_str();
} }
protected: protected:

View File

@ -54,53 +54,49 @@ bool CommandObjectSyntax::DoExecute(Args &command,
CommandObject *cmd_obj; CommandObject *cmd_obj;
const size_t argc = command.GetArgumentCount(); const size_t argc = command.GetArgumentCount();
if (argc > 0) { if (argc == 0) {
cmd_obj = m_interpreter.GetCommandObject(command.GetArgumentAtIndex(0));
bool all_okay = true;
// TODO: Convert to entry-based iteration. Requires converting
// GetSubcommandObject.
for (size_t i = 1; i < argc; ++i) {
std::string sub_command = command.GetArgumentAtIndex(i);
if (!cmd_obj->IsMultiwordObject()) {
all_okay = false;
break;
} else {
cmd_obj = cmd_obj->GetSubcommandObject(sub_command.c_str());
if (!cmd_obj) {
all_okay = false;
break;
}
}
}
if (all_okay && (cmd_obj != nullptr)) {
Stream &output_strm = result.GetOutputStream();
if (cmd_obj->GetOptions() != nullptr) {
output_strm.Printf("\nSyntax: %s\n", cmd_obj->GetSyntax().str().c_str());
output_strm.Printf(
"(Try 'help %s' for more information on command options syntax.)\n",
cmd_obj->GetCommandName().str().c_str());
result.SetStatus(eReturnStatusSuccessFinishNoResult);
} else {
output_strm.Printf("\nSyntax: %s\n", cmd_obj->GetSyntax().str().c_str());
result.SetStatus(eReturnStatusSuccessFinishNoResult);
}
} else {
std::string cmd_string;
command.GetCommandString(cmd_string);
StreamString error_msg_stream;
const bool generate_apropos = true;
const bool generate_type_lookup = false;
CommandObjectHelp::GenerateAdditionalHelpAvenuesMessage(
&error_msg_stream, cmd_string, "", "",
generate_apropos, generate_type_lookup);
result.AppendErrorWithFormat("%s", error_msg_stream.GetData());
result.SetStatus(eReturnStatusFailed);
}
} else {
result.AppendError("Must call 'syntax' with a valid command."); result.AppendError("Must call 'syntax' with a valid command.");
result.SetStatus(eReturnStatusFailed); result.SetStatus(eReturnStatusFailed);
return false;
}
cmd_obj = m_interpreter.GetCommandObject(command[0].ref);
bool all_okay = llvm::all_of(
command.entries().drop_front(), [&cmd_obj](const Args::ArgEntry &e) {
if (!cmd_obj || !cmd_obj->IsMultiwordObject())
return false;
if (!(cmd_obj = cmd_obj->GetSubcommandObject(e.ref)))
return false;
return true;
});
if (!all_okay) {
std::string cmd_string;
command.GetCommandString(cmd_string);
StreamString error_msg_stream;
const bool generate_apropos = true;
const bool generate_type_lookup = false;
CommandObjectHelp::GenerateAdditionalHelpAvenuesMessage(
&error_msg_stream, cmd_string, "", "", generate_apropos,
generate_type_lookup);
result.AppendErrorWithFormat("%s", error_msg_stream.GetData());
result.SetStatus(eReturnStatusFailed);
return false;
}
Stream &output_strm = result.GetOutputStream();
if (cmd_obj->GetOptions() != nullptr) {
output_strm.Printf("\nSyntax: %s\n", cmd_obj->GetSyntax().str().c_str());
output_strm.Printf(
"(Try 'help %s' for more information on command options syntax.)\n",
cmd_obj->GetCommandName().str().c_str());
result.SetStatus(eReturnStatusSuccessFinishNoResult);
} else {
output_strm.Printf("\nSyntax: %s\n", cmd_obj->GetSyntax().str().c_str());
result.SetStatus(eReturnStatusSuccessFinishNoResult);
} }
return result.Succeeded(); return result.Succeeded();

View File

@ -1100,23 +1100,22 @@ std::string Args::ParseAliasOptions(Options &options,
continue; continue;
if (!result_string.empty()) { if (!result_string.empty()) {
const char *tmp_arg = GetArgumentAtIndex(idx); auto tmp_arg = m_entries[idx].ref;
size_t pos = result_string.find(tmp_arg); size_t pos = result_string.find(tmp_arg);
if (pos != std::string::npos) if (pos != std::string::npos)
result_string.erase(pos, strlen(tmp_arg)); result_string.erase(pos, tmp_arg.size());
} }
ReplaceArgumentAtIndex(idx, llvm::StringRef()); ReplaceArgumentAtIndex(idx, llvm::StringRef());
if ((long_options[long_options_index].definition->option_has_arg != if ((long_options[long_options_index].definition->option_has_arg !=
OptionParser::eNoArgument) && OptionParser::eNoArgument) &&
(OptionParser::GetOptionArgument() != nullptr) && (OptionParser::GetOptionArgument() != nullptr) &&
(idx + 1 < GetArgumentCount()) && (idx + 1 < GetArgumentCount()) &&
(strcmp(OptionParser::GetOptionArgument(), (m_entries[idx + 1].ref == OptionParser::GetOptionArgument())) {
GetArgumentAtIndex(idx + 1)) == 0)) {
if (result_string.size() > 0) { if (result_string.size() > 0) {
const char *tmp_arg = GetArgumentAtIndex(idx + 1); auto tmp_arg = m_entries[idx + 1].ref;
size_t pos = result_string.find(tmp_arg); size_t pos = result_string.find(tmp_arg);
if (pos != std::string::npos) if (pos != std::string::npos)
result_string.erase(pos, strlen(tmp_arg)); result_string.erase(pos, tmp_arg.size());
} }
ReplaceArgumentAtIndex(idx + 1, llvm::StringRef()); ReplaceArgumentAtIndex(idx + 1, llvm::StringRef());
} }