mirror of
https://github.com/intel/llvm.git
synced 2026-01-22 23:49:22 +08:00
Convert various CommandInterpreter functions to StringRef.
llvm-svn: 283370
This commit is contained in:
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 =
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user