aboutsummaryrefslogtreecommitdiffstats
path: root/source/Interpreter
diff options
context:
space:
mode:
Diffstat (limited to 'source/Interpreter')
-rw-r--r--source/Interpreter/CommandAlias.cpp16
-rw-r--r--source/Interpreter/CommandInterpreter.cpp375
-rw-r--r--source/Interpreter/CommandObject.cpp29
-rw-r--r--source/Interpreter/CommandObjectRegexCommand.cpp20
-rw-r--r--source/Interpreter/CommandReturnObject.cpp3
-rw-r--r--source/Interpreter/InterpreterProperties.td28
-rw-r--r--source/Interpreter/OptionArgParser.cpp36
-rw-r--r--source/Interpreter/OptionGroupArchitecture.cpp3
-rw-r--r--source/Interpreter/OptionGroupFormat.cpp3
-rw-r--r--source/Interpreter/OptionGroupOutputFile.cpp3
-rw-r--r--source/Interpreter/OptionGroupPlatform.cpp3
-rw-r--r--source/Interpreter/OptionGroupPythonClassWithDict.cpp123
-rw-r--r--source/Interpreter/OptionGroupUUID.cpp3
-rw-r--r--source/Interpreter/OptionGroupValueObjectDisplay.cpp3
-rw-r--r--source/Interpreter/OptionGroupVariable.cpp4
-rw-r--r--source/Interpreter/OptionGroupWatchpoint.cpp49
-rw-r--r--source/Interpreter/OptionValue.cpp7
-rw-r--r--source/Interpreter/OptionValueArch.cpp6
-rw-r--r--source/Interpreter/OptionValueBoolean.cpp18
-rw-r--r--source/Interpreter/OptionValueDictionary.cpp6
-rw-r--r--source/Interpreter/OptionValueEnumeration.cpp15
-rw-r--r--source/Interpreter/OptionValueFileSpec.cpp6
-rw-r--r--source/Interpreter/OptionValueFileSpecList.cpp (renamed from source/Interpreter/OptionValueFileSpecLIst.cpp)2
-rw-r--r--source/Interpreter/OptionValueFormatEntity.cpp6
-rw-r--r--source/Interpreter/OptionValueLanguage.cpp16
-rw-r--r--source/Interpreter/OptionValueRegex.cpp12
-rw-r--r--source/Interpreter/OptionValueUUID.cpp40
-rw-r--r--source/Interpreter/Options.cpp95
28 files changed, 471 insertions, 459 deletions
diff --git a/source/Interpreter/CommandAlias.cpp b/source/Interpreter/CommandAlias.cpp
index 8c40574ee50e..5139c53a47b3 100644
--- a/source/Interpreter/CommandAlias.cpp
+++ b/source/Interpreter/CommandAlias.cpp
@@ -64,8 +64,8 @@ static bool ProcessAliasOptionsArgs(lldb::CommandObjectSP &cmd_obj_sp,
option_arg_vector->emplace_back("<argument>", -1, options_string);
else {
for (auto &entry : args.entries()) {
- if (!entry.ref.empty())
- option_arg_vector->emplace_back("<argument>", -1, entry.ref);
+ if (!entry.ref().empty())
+ option_arg_vector->emplace_back("<argument>", -1, entry.ref());
}
}
}
@@ -115,18 +115,16 @@ bool CommandAlias::WantsCompletion() {
return false;
}
-int CommandAlias::HandleCompletion(CompletionRequest &request) {
+void CommandAlias::HandleCompletion(CompletionRequest &request) {
if (IsValid())
- return m_underlying_command_sp->HandleCompletion(request);
- return -1;
+ m_underlying_command_sp->HandleCompletion(request);
}
-int CommandAlias::HandleArgumentCompletion(
+void CommandAlias::HandleArgumentCompletion(
CompletionRequest &request, OptionElementVector &opt_element_vector) {
if (IsValid())
- return m_underlying_command_sp->HandleArgumentCompletion(
- request, opt_element_vector);
- return -1;
+ m_underlying_command_sp->HandleArgumentCompletion(request,
+ opt_element_vector);
}
Options *CommandAlias::GetOptions() {
diff --git a/source/Interpreter/CommandInterpreter.cpp b/source/Interpreter/CommandInterpreter.cpp
index 8948037a6307..0c059096c6cd 100644
--- a/source/Interpreter/CommandInterpreter.cpp
+++ b/source/Interpreter/CommandInterpreter.cpp
@@ -16,7 +16,6 @@
#include "Commands/CommandObjectApropos.h"
#include "Commands/CommandObjectBreakpoint.h"
-#include "Commands/CommandObjectBugreport.h"
#include "Commands/CommandObjectCommands.h"
#include "Commands/CommandObjectDisassemble.h"
#include "Commands/CommandObjectExpression.h"
@@ -64,11 +63,14 @@
#include "lldb/Utility/Args.h"
#include "lldb/Target/Process.h"
+#include "lldb/Target/StopInfo.h"
#include "lldb/Target/TargetList.h"
#include "lldb/Target/Thread.h"
+#include "lldb/Target/UnixSignals.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
+#include "llvm/Support/FormatAdapters.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/PrettyStackTrace.h"
@@ -77,10 +79,6 @@ using namespace lldb_private;
static const char *k_white_space = " \t\v";
-static constexpr bool NoGlobalSetting = true;
-static constexpr uintptr_t DefaultValueTrue = true;
-static constexpr uintptr_t DefaultValueFalse = false;
-static constexpr const char *NoCStrDefault = nullptr;
static constexpr const char *InitFileWarning =
"There is a .lldbinit file in the current directory which is not being "
"read.\n"
@@ -93,38 +91,12 @@ static constexpr const char *InitFileWarning =
"and\n"
"accept the security risk.";
-static constexpr PropertyDefinition g_properties[] = {
- {"expand-regex-aliases", OptionValue::eTypeBoolean, NoGlobalSetting,
- DefaultValueFalse, NoCStrDefault, {},
- "If true, regular expression alias commands will show the "
- "expanded command that will be executed. This can be used to "
- "debug new regular expression alias commands."},
- {"prompt-on-quit", OptionValue::eTypeBoolean, NoGlobalSetting,
- DefaultValueTrue, NoCStrDefault, {},
- "If true, LLDB will prompt you before quitting if there are any live "
- "processes being debugged. If false, LLDB will quit without asking in any "
- "case."},
- {"stop-command-source-on-error", OptionValue::eTypeBoolean, NoGlobalSetting,
- DefaultValueTrue, NoCStrDefault, {},
- "If true, LLDB will stop running a 'command source' "
- "script upon encountering an error."},
- {"space-repl-prompts", OptionValue::eTypeBoolean, NoGlobalSetting,
- DefaultValueFalse, NoCStrDefault, {},
- "If true, blank lines will be printed between between REPL submissions."},
- {"echo-commands", OptionValue::eTypeBoolean, NoGlobalSetting,
- DefaultValueTrue, NoCStrDefault, {},
- "If true, commands will be echoed before they are evaluated."},
- {"echo-comment-commands", OptionValue::eTypeBoolean, NoGlobalSetting,
- DefaultValueTrue, NoCStrDefault, {},
- "If true, commands will be echoed even if they are pure comment lines."}};
+#define LLDB_PROPERTIES_interpreter
+#include "InterpreterProperties.inc"
enum {
- ePropertyExpandRegexAliases = 0,
- ePropertyPromptOnQuit = 1,
- ePropertyStopCmdSourceOnError = 2,
- eSpaceReplPrompts = 3,
- eEchoCommands = 4,
- eEchoCommentCommands = 5
+#define LLDB_PROPERTIES_interpreter
+#include "InterpreterPropertiesEnum.inc"
};
ConstString &CommandInterpreter::GetStaticBroadcasterClass() {
@@ -139,7 +111,7 @@ CommandInterpreter::CommandInterpreter(Debugger &debugger,
Properties(OptionValuePropertiesSP(
new OptionValueProperties(ConstString("interpreter")))),
IOHandlerDelegate(IOHandlerDelegate::Completion::LLDBCommand),
- m_debugger(debugger), m_synchronous_execution(synchronous_execution),
+ m_debugger(debugger), m_synchronous_execution(true),
m_skip_lldbinit_files(false), m_skip_app_init_files(false),
m_command_io_handler_sp(), m_comment_char('#'),
m_batch_command_mode(false), m_truncation_warning(eNoTruncation),
@@ -148,20 +120,21 @@ CommandInterpreter::CommandInterpreter(Debugger &debugger,
SetEventName(eBroadcastBitThreadShouldExit, "thread-should-exit");
SetEventName(eBroadcastBitResetPrompt, "reset-prompt");
SetEventName(eBroadcastBitQuitCommandReceived, "quit");
+ SetSynchronous(synchronous_execution);
CheckInWithManager();
- m_collection_sp->Initialize(g_properties);
+ m_collection_sp->Initialize(g_interpreter_properties);
}
bool CommandInterpreter::GetExpandRegexAliases() const {
const uint32_t idx = ePropertyExpandRegexAliases;
return m_collection_sp->GetPropertyAtIndexAsBoolean(
- nullptr, idx, g_properties[idx].default_uint_value != 0);
+ nullptr, idx, g_interpreter_properties[idx].default_uint_value != 0);
}
bool CommandInterpreter::GetPromptOnQuit() const {
const uint32_t idx = ePropertyPromptOnQuit;
return m_collection_sp->GetPropertyAtIndexAsBoolean(
- nullptr, idx, g_properties[idx].default_uint_value != 0);
+ nullptr, idx, g_interpreter_properties[idx].default_uint_value != 0);
}
void CommandInterpreter::SetPromptOnQuit(bool b) {
@@ -170,24 +143,24 @@ void CommandInterpreter::SetPromptOnQuit(bool b) {
}
bool CommandInterpreter::GetEchoCommands() const {
- const uint32_t idx = eEchoCommands;
+ const uint32_t idx = ePropertyEchoCommands;
return m_collection_sp->GetPropertyAtIndexAsBoolean(
- nullptr, idx, g_properties[idx].default_uint_value != 0);
+ nullptr, idx, g_interpreter_properties[idx].default_uint_value != 0);
}
void CommandInterpreter::SetEchoCommands(bool b) {
- const uint32_t idx = eEchoCommands;
+ const uint32_t idx = ePropertyEchoCommands;
m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b);
}
bool CommandInterpreter::GetEchoCommentCommands() const {
- const uint32_t idx = eEchoCommentCommands;
+ const uint32_t idx = ePropertyEchoCommentCommands;
return m_collection_sp->GetPropertyAtIndexAsBoolean(
- nullptr, idx, g_properties[idx].default_uint_value != 0);
+ nullptr, idx, g_interpreter_properties[idx].default_uint_value != 0);
}
void CommandInterpreter::SetEchoCommentCommands(bool b) {
- const uint32_t idx = eEchoCommentCommands;
+ const uint32_t idx = ePropertyEchoCommentCommands;
m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b);
}
@@ -223,13 +196,13 @@ void CommandInterpreter::ResolveCommand(const char *command_line,
bool CommandInterpreter::GetStopCmdSourceOnError() const {
const uint32_t idx = ePropertyStopCmdSourceOnError;
return m_collection_sp->GetPropertyAtIndexAsBoolean(
- nullptr, idx, g_properties[idx].default_uint_value != 0);
+ nullptr, idx, g_interpreter_properties[idx].default_uint_value != 0);
}
bool CommandInterpreter::GetSpaceReplPrompts() const {
- const uint32_t idx = eSpaceReplPrompts;
+ const uint32_t idx = ePropertySpaceReplPrompts;
return m_collection_sp->GetPropertyAtIndexAsBoolean(
- nullptr, idx, g_properties[idx].default_uint_value != 0);
+ nullptr, idx, g_interpreter_properties[idx].default_uint_value != 0);
}
void CommandInterpreter::Initialize() {
@@ -473,8 +446,6 @@ void 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"] =
@@ -1628,8 +1599,7 @@ bool CommandInterpreter::HandleCommand(const char *command_line,
llvm::PrettyStackTraceFormat stack_trace("HandleCommand(command = \"%s\")",
command_line);
- if (log)
- log->Printf("Processing command: %s", command_line);
+ LLDB_LOGF(log, "Processing command: %s", command_line);
static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
Timer scoped_timer(func_cat, "Handling command: %s.", command_line);
@@ -1735,13 +1705,13 @@ bool CommandInterpreter::HandleCommand(const char *command_line,
// "br s -n main", command_string is now "breakpoint set -n main".
if (log) {
llvm::StringRef command_name = cmd_obj ? cmd_obj->GetCommandName() : "<not found>";
- log->Printf("HandleCommand, cmd_obj : '%s'", command_name.str().c_str());
- log->Printf("HandleCommand, (revised) command_string: '%s'",
- command_string.c_str());
+ LLDB_LOGF(log, "HandleCommand, cmd_obj : '%s'", command_name.str().c_str());
+ LLDB_LOGF(log, "HandleCommand, (revised) command_string: '%s'",
+ command_string.c_str());
const bool wants_raw_input =
(cmd_obj != nullptr) ? cmd_obj->WantsRawCommandString() : false;
- log->Printf("HandleCommand, wants_raw_input:'%s'",
- wants_raw_input ? "True" : "False");
+ LLDB_LOGF(log, "HandleCommand, wants_raw_input:'%s'",
+ wants_raw_input ? "True" : "False");
}
// Phase 2.
@@ -1771,34 +1741,30 @@ bool CommandInterpreter::HandleCommand(const char *command_line,
if (pos != 0 && pos != std::string::npos)
remainder.erase(0, pos);
- if (log)
- log->Printf(
- "HandleCommand, command line after removing command name(s): '%s'",
- remainder.c_str());
+ LLDB_LOGF(
+ log, "HandleCommand, command line after removing command name(s): '%s'",
+ remainder.c_str());
cmd_obj->Execute(remainder.c_str(), result);
}
- if (log)
- log->Printf("HandleCommand, command %s",
- (result.Succeeded() ? "succeeded" : "did not succeed"));
+ LLDB_LOGF(log, "HandleCommand, command %s",
+ (result.Succeeded() ? "succeeded" : "did not succeed"));
return result.Succeeded();
}
-int CommandInterpreter::HandleCompletionMatches(CompletionRequest &request) {
- int num_command_matches = 0;
+void CommandInterpreter::HandleCompletionMatches(CompletionRequest &request) {
bool look_for_subcommand = false;
// For any of the command completions a unique match will be a complete word.
- request.SetWordComplete(true);
- if (request.GetCursorIndex() == -1) {
+ if (request.GetParsedLine().GetArgumentCount() == 0) {
// We got nothing on the command line, so return the list of commands
bool include_aliases = true;
StringList new_matches, descriptions;
- num_command_matches = GetCommandNamesMatchingPartialString(
- "", include_aliases, new_matches, descriptions);
+ GetCommandNamesMatchingPartialString("", include_aliases, new_matches,
+ descriptions);
request.AddCompletions(new_matches, descriptions);
} else if (request.GetCursorIndex() == 0) {
// The cursor is in the first argument, so just do a lookup in the
@@ -1808,24 +1774,18 @@ int CommandInterpreter::HandleCompletionMatches(CompletionRequest &request) {
GetCommandObject(request.GetParsedLine().GetArgumentAtIndex(0),
&new_matches, &new_descriptions);
- if (num_command_matches == 1 && cmd_obj && cmd_obj->IsMultiwordObject() &&
+ if (new_matches.GetSize() && cmd_obj && cmd_obj->IsMultiwordObject() &&
new_matches.GetStringAtIndex(0) != nullptr &&
strcmp(request.GetParsedLine().GetArgumentAtIndex(0),
new_matches.GetStringAtIndex(0)) == 0) {
- if (request.GetParsedLine().GetArgumentCount() == 1) {
- request.SetWordComplete(true);
- } else {
+ if (request.GetParsedLine().GetArgumentCount() != 1) {
look_for_subcommand = true;
- num_command_matches = 0;
new_matches.DeleteStringAtIndex(0);
new_descriptions.DeleteStringAtIndex(0);
- request.GetParsedLine().AppendArgument(llvm::StringRef());
- request.SetCursorIndex(request.GetCursorIndex() + 1);
- request.SetCursorCharPosition(0);
+ request.AppendEmptyArgument();
}
}
request.AddCompletions(new_matches, new_descriptions);
- num_command_matches = request.GetNumberOfMatches();
}
if (request.GetCursorIndex() > 0 || look_for_subcommand) {
@@ -1834,81 +1794,31 @@ int CommandInterpreter::HandleCompletionMatches(CompletionRequest &request) {
// matching initial command:
CommandObject *command_object =
GetCommandObject(request.GetParsedLine().GetArgumentAtIndex(0));
- if (command_object == nullptr) {
- return 0;
- } else {
- request.GetParsedLine().Shift();
- request.SetCursorIndex(request.GetCursorIndex() - 1);
- num_command_matches = command_object->HandleCompletion(request);
+ if (command_object) {
+ request.ShiftArguments();
+ command_object->HandleCompletion(request);
}
}
-
- return num_command_matches;
}
-int CommandInterpreter::HandleCompletion(
- const char *current_line, const char *cursor, const char *last_char,
- int match_start_point, int max_return_elements, StringList &matches,
- StringList &descriptions) {
+void CommandInterpreter::HandleCompletion(CompletionRequest &request) {
- llvm::StringRef command_line(current_line, last_char - current_line);
- CompletionResult result;
- CompletionRequest request(command_line, cursor - current_line,
- match_start_point, max_return_elements, result);
// Don't complete comments, and if the line we are completing is just the
// history repeat character, substitute the appropriate history line.
- const char *first_arg = request.GetParsedLine().GetArgumentAtIndex(0);
- if (first_arg) {
- if (first_arg[0] == m_comment_char)
- return 0;
- else if (first_arg[0] == CommandHistory::g_repeat_char) {
- if (auto hist_str = m_command_history.FindString(first_arg)) {
- matches.InsertStringAtIndex(0, *hist_str);
- descriptions.InsertStringAtIndex(0, "Previous command history event");
- return -2;
- } else
- return 0;
- }
- }
-
- // Only max_return_elements == -1 is supported at present:
- lldbassert(max_return_elements == -1);
-
- int num_command_matches = HandleCompletionMatches(request);
- result.GetMatches(matches);
- result.GetDescriptions(descriptions);
+ llvm::StringRef first_arg = request.GetParsedLine().GetArgumentAtIndex(0);
- if (num_command_matches <= 0)
- return num_command_matches;
-
- if (request.GetParsedLine().GetArgumentCount() == 0) {
- // If we got an empty string, insert nothing.
- matches.InsertStringAtIndex(0, "");
- descriptions.InsertStringAtIndex(0, "");
- } else {
- // Now figure out if there is a common substring, and if so put that in
- // element 0, otherwise put an empty string in element 0.
- std::string command_partial_str = request.GetCursorArgumentPrefix().str();
-
- std::string common_prefix;
- matches.LongestCommonPrefix(common_prefix);
- const size_t partial_name_len = command_partial_str.size();
- common_prefix.erase(0, partial_name_len);
-
- // If we matched a unique single command, add a space... Only do this if
- // the completer told us this was a complete word, however...
- if (num_command_matches == 1 && request.GetWordComplete()) {
- char quote_char = request.GetParsedLine()[request.GetCursorIndex()].quote;
- common_prefix =
- Args::EscapeLLDBCommandArgument(common_prefix, quote_char);
- if (quote_char != '\0')
- common_prefix.push_back(quote_char);
- common_prefix.push_back(' ');
+ if (!first_arg.empty()) {
+ if (first_arg.front() == m_comment_char)
+ return;
+ if (first_arg.front() == CommandHistory::g_repeat_char) {
+ if (auto hist_str = m_command_history.FindString(first_arg))
+ request.AddCompletion(*hist_str, "Previous command history event",
+ CompletionMode::RewriteLine);
+ return;
}
- matches.InsertStringAtIndex(0, common_prefix.c_str());
- descriptions.InsertStringAtIndex(0, "");
}
- return num_command_matches;
+
+ HandleCompletionMatches(request);
}
CommandInterpreter::~CommandInterpreter() {}
@@ -2051,7 +1961,7 @@ void CommandInterpreter::BuildAliasCommandArgs(CommandObject *alias_cmd_obj,
for (auto entry : llvm::enumerate(cmd_args.entries())) {
if (!used[entry.index()] && !wants_raw_input)
- new_args.AppendArgument(entry.value().ref);
+ new_args.AppendArgument(entry.value().ref());
}
cmd_args.Clear();
@@ -2231,6 +2141,45 @@ PlatformSP CommandInterpreter::GetPlatform(bool prefer_target_platform) {
return platform_sp;
}
+bool CommandInterpreter::DidProcessStopAbnormally() const {
+ TargetSP target_sp = m_debugger.GetTargetList().GetSelectedTarget();
+ if (!target_sp)
+ return false;
+
+ ProcessSP process_sp(target_sp->GetProcessSP());
+ if (!process_sp)
+ return false;
+
+ if (eStateStopped != process_sp->GetState())
+ return false;
+
+ for (const auto &thread_sp : process_sp->GetThreadList().Threads()) {
+ StopInfoSP stop_info = thread_sp->GetStopInfo();
+ if (!stop_info)
+ return false;
+
+ const StopReason reason = stop_info->GetStopReason();
+ if (reason == eStopReasonException || reason == eStopReasonInstrumentation)
+ return true;
+
+ if (reason == eStopReasonSignal) {
+ const auto stop_signal = static_cast<int32_t>(stop_info->GetValue());
+ UnixSignalsSP signals_sp = process_sp->GetUnixSignals();
+ if (!signals_sp || !signals_sp->SignalIsValid(stop_signal))
+ // The signal is unknown, treat it as abnormal.
+ return true;
+
+ const auto sigint_num = signals_sp->GetSignalNumberFromName("SIGINT");
+ const auto sigstop_num = signals_sp->GetSignalNumberFromName("SIGSTOP");
+ if ((stop_signal != sigint_num) && (stop_signal != sigstop_num))
+ // The signal very likely implies a crash.
+ return true;
+ }
+ }
+
+ return false;
+}
+
void CommandInterpreter::HandleCommands(const StringList &commands,
ExecutionContext *override_context,
CommandInterpreterRunOptions &options,
@@ -2341,38 +2290,22 @@ void CommandInterpreter::HandleCommands(const StringList &commands,
}
// Also check for "stop on crash here:
- bool should_stop = false;
- if (tmp_result.GetDidChangeProcessState() && options.GetStopOnCrash()) {
- TargetSP target_sp(m_debugger.GetTargetList().GetSelectedTarget());
- if (target_sp) {
- ProcessSP process_sp(target_sp->GetProcessSP());
- if (process_sp) {
- for (ThreadSP thread_sp : process_sp->GetThreadList().Threads()) {
- StopReason reason = thread_sp->GetStopReason();
- if (reason == eStopReasonSignal || reason == eStopReasonException ||
- reason == eStopReasonInstrumentation) {
- should_stop = true;
- break;
- }
- }
- }
- }
- if (should_stop) {
- if (idx != num_lines - 1)
- result.AppendErrorWithFormat(
- "Aborting reading of commands after command #%" PRIu64
- ": '%s' stopped with a signal or exception.\n",
- (uint64_t)idx + 1, cmd);
- else
- result.AppendMessageWithFormat(
- "Command #%" PRIu64 " '%s' stopped with a signal or exception.\n",
- (uint64_t)idx + 1, cmd);
+ if (tmp_result.GetDidChangeProcessState() && options.GetStopOnCrash() &&
+ DidProcessStopAbnormally()) {
+ if (idx != num_lines - 1)
+ result.AppendErrorWithFormat(
+ "Aborting reading of commands after command #%" PRIu64
+ ": '%s' stopped with a signal or exception.\n",
+ (uint64_t)idx + 1, cmd);
+ else
+ result.AppendMessageWithFormat(
+ "Command #%" PRIu64 " '%s' stopped with a signal or exception.\n",
+ (uint64_t)idx + 1, cmd);
- result.SetStatus(tmp_result.GetStatus());
- m_debugger.SetAsyncExecution(old_async_execution);
+ result.SetStatus(tmp_result.GetStatus());
+ m_debugger.SetAsyncExecution(old_async_execution);
- return;
- }
+ return;
}
}
@@ -2405,18 +2338,18 @@ void CommandInterpreter::HandleCommandsFromFile(
return;
}
- StreamFileSP input_file_sp(new StreamFile());
std::string cmd_file_path = cmd_file.GetPath();
- Status error = FileSystem::Instance().Open(input_file_sp->GetFile(), cmd_file,
- File::eOpenOptionRead);
-
- if (error.Fail()) {
- result.AppendErrorWithFormat(
- "error: an error occurred read file '%s': %s\n", cmd_file_path.c_str(),
- error.AsCString());
+ auto input_file_up =
+ FileSystem::Instance().Open(cmd_file, File::eOpenOptionRead);
+ if (!input_file_up) {
+ std::string error = llvm::toString(input_file_up.takeError());
+ result.AppendErrorWithFormatv(
+ "error: an error occurred read file '{0}': {1}\n", cmd_file_path,
+ llvm::fmt_consume(input_file_up.takeError()));
result.SetStatus(eReturnStatusFailed);
return;
}
+ FileSP input_file_sp = FileSP(std::move(input_file_up.get()));
Debugger &debugger = GetDebugger();
@@ -2502,8 +2435,8 @@ void CommandInterpreter::HandleCommandsFromFile(
}
if (flags & eHandleCommandFlagPrintResult) {
- debugger.GetOutputFile()->Printf("Executing commands in '%s'.\n",
- cmd_file_path.c_str());
+ debugger.GetOutputFile().Printf("Executing commands in '%s'.\n",
+ cmd_file_path.c_str());
}
// Used for inheriting the right settings when "command source" might
@@ -2541,6 +2474,9 @@ void CommandInterpreter::HandleCommandsFromFile(
bool CommandInterpreter::GetSynchronous() { return m_synchronous_execution; }
void CommandInterpreter::SetSynchronous(bool value) {
+ // Asynchronous mode is not supported during reproducer replay.
+ if (repro::Reproducer::Instance().GetLoader())
+ return;
m_synchronous_execution = value;
}
@@ -2701,32 +2637,14 @@ void CommandInterpreter::UpdateExecutionContext(
}
}
-size_t CommandInterpreter::GetProcessOutput() {
- // The process has stuff waiting for stderr; get it and write it out to the
- // appropriate place.
- char stdio_buffer[1024];
- size_t len;
- size_t total_bytes = 0;
- Status error;
+void CommandInterpreter::GetProcessOutput() {
TargetSP target_sp(m_debugger.GetTargetList().GetSelectedTarget());
- if (target_sp) {
- ProcessSP process_sp(target_sp->GetProcessSP());
- if (process_sp) {
- while ((len = process_sp->GetSTDOUT(stdio_buffer, sizeof(stdio_buffer),
- error)) > 0) {
- size_t bytes_written = len;
- m_debugger.GetOutputFile()->Write(stdio_buffer, bytes_written);
- total_bytes += len;
- }
- while ((len = process_sp->GetSTDERR(stdio_buffer, sizeof(stdio_buffer),
- error)) > 0) {
- size_t bytes_written = len;
- m_debugger.GetErrorFile()->Write(stdio_buffer, bytes_written);
- total_bytes += len;
- }
- }
- }
- return total_bytes;
+ if (!target_sp)
+ return;
+
+ if (ProcessSP process_sp = target_sp->GetProcessSP())
+ m_debugger.FlushProcessOutput(*process_sp, /*flush_stdout*/ true,
+ /*flush_stderr*/ true);
}
void CommandInterpreter::StartHandlingCommand() {
@@ -2818,8 +2736,8 @@ void CommandInterpreter::IOHandlerInputComplete(IOHandler &io_handler,
// from a file) we need to echo the command out so we don't just see the
// command output and no command...
if (EchoCommandNonInteractive(line, io_handler.GetFlags()))
- io_handler.GetOutputStreamFile()->Printf("%s%s\n", io_handler.GetPrompt(),
- line.c_str());
+ io_handler.GetOutputStreamFileSP()->Printf(
+ "%s%s\n", io_handler.GetPrompt(), line.c_str());
}
StartHandlingCommand();
@@ -2836,13 +2754,13 @@ void CommandInterpreter::IOHandlerInputComplete(IOHandler &io_handler,
if (!result.GetImmediateOutputStream()) {
llvm::StringRef output = result.GetOutputData();
- PrintCommandOutput(*io_handler.GetOutputStreamFile(), output);
+ PrintCommandOutput(*io_handler.GetOutputStreamFileSP(), output);
}
// Now emit the command error text from the command we just executed
if (!result.GetImmediateErrorStream()) {
llvm::StringRef error = result.GetErrorData();
- PrintCommandOutput(*io_handler.GetErrorStreamFile(), error);
+ PrintCommandOutput(*io_handler.GetErrorStreamFileSP(), error);
}
}
@@ -2875,27 +2793,10 @@ void CommandInterpreter::IOHandlerInputComplete(IOHandler &io_handler,
// Finally, if we're going to stop on crash, check that here:
if (!m_quit_requested && result.GetDidChangeProcessState() &&
- io_handler.GetFlags().Test(eHandleCommandFlagStopOnCrash)) {
- bool should_stop = false;
- TargetSP target_sp(m_debugger.GetTargetList().GetSelectedTarget());
- if (target_sp) {
- ProcessSP process_sp(target_sp->GetProcessSP());
- if (process_sp) {
- for (ThreadSP thread_sp : process_sp->GetThreadList().Threads()) {
- StopReason reason = thread_sp->GetStopReason();
- if ((reason == eStopReasonSignal || reason == eStopReasonException ||
- reason == eStopReasonInstrumentation) &&
- !result.GetAbnormalStopWasExpected()) {
- should_stop = true;
- break;
- }
- }
- }
- }
- if (should_stop) {
- io_handler.SetIsDone(true);
- m_stopped_for_crash = true;
- }
+ io_handler.GetFlags().Test(eHandleCommandFlagStopOnCrash) &&
+ DidProcessStopAbnormally()) {
+ io_handler.SetIsDone(true);
+ m_stopped_for_crash = true;
}
}
@@ -3009,8 +2910,8 @@ CommandInterpreter::GetIOHandler(bool force_create,
m_command_io_handler_sp = std::make_shared<IOHandlerEditline>(
m_debugger, IOHandler::Type::CommandInterpreter,
- m_debugger.GetInputFile(), m_debugger.GetOutputFile(),
- m_debugger.GetErrorFile(), flags, "lldb", m_debugger.GetPrompt(),
+ m_debugger.GetInputFileSP(), m_debugger.GetOutputStreamSP(),
+ m_debugger.GetErrorStreamSP(), flags, "lldb", m_debugger.GetPrompt(),
llvm::StringRef(), // Continuation prompt
false, // Don't enable multiple line input, just single line commands
m_debugger.GetUseColor(),
diff --git a/source/Interpreter/CommandObject.cpp b/source/Interpreter/CommandObject.cpp
index 8e493c7a326f..d666852ee68c 100644
--- a/source/Interpreter/CommandObject.cpp
+++ b/source/Interpreter/CommandObject.cpp
@@ -257,14 +257,14 @@ void CommandObject::Cleanup() {
m_api_locker.unlock();
}
-int CommandObject::HandleCompletion(CompletionRequest &request) {
+void CommandObject::HandleCompletion(CompletionRequest &request) {
// Default implementation of WantsCompletion() is !WantsRawCommandString().
// Subclasses who want raw command string but desire, for example, argument
// completion should override WantsCompletion() to return true, instead.
if (WantsRawCommandString() && !WantsCompletion()) {
// FIXME: Abstract telling the completion to insert the completion
// character.
- return -1;
+ return;
} else {
// Can we do anything generic with the options?
Options *cur_options = GetOptions();
@@ -278,11 +278,11 @@ int CommandObject::HandleCompletion(CompletionRequest &request) {
bool handled_by_options = cur_options->HandleOptionCompletion(
request, opt_element_vector, GetCommandInterpreter());
if (handled_by_options)
- return request.GetNumberOfMatches();
+ return;
}
// If we got here, the last word is not an option or an option argument.
- return HandleArgumentCompletion(request, opt_element_vector);
+ HandleArgumentCompletion(request, opt_element_vector);
}
}
@@ -917,12 +917,21 @@ const char *CommandObject::GetArgumentDescriptionAsCString(
return g_arguments_data[arg_type].help_text;
}
-Target *CommandObject::GetDummyTarget() {
- return m_interpreter.GetDebugger().GetDummyTarget();
+Target &CommandObject::GetDummyTarget() {
+ return *m_interpreter.GetDebugger().GetDummyTarget();
+}
+
+Target &CommandObject::GetSelectedOrDummyTarget(bool prefer_dummy) {
+ return *m_interpreter.GetDebugger().GetSelectedOrDummyTarget(prefer_dummy);
}
-Target *CommandObject::GetSelectedOrDummyTarget(bool prefer_dummy) {
- return m_interpreter.GetDebugger().GetSelectedOrDummyTarget(prefer_dummy);
+Target &CommandObject::GetSelectedTarget() {
+ assert(m_flags.AnySet(eCommandRequiresTarget | eCommandProcessMustBePaused |
+ eCommandProcessMustBeLaunched | eCommandRequiresFrame |
+ eCommandRequiresThread | eCommandRequiresProcess |
+ eCommandRequiresRegContext) &&
+ "GetSelectedTarget called from object that may have no target");
+ return *m_interpreter.GetDebugger().GetSelectedTarget();
}
Thread *CommandObject::GetDefaultThread() {
@@ -958,7 +967,7 @@ bool CommandObjectParsed::Execute(const char *args_string,
}
if (!handled) {
for (auto entry : llvm::enumerate(cmd_args.entries())) {
- if (!entry.value().ref.empty() && entry.value().ref.front() == '`') {
+ if (!entry.value().ref().empty() && entry.value().ref().front() == '`') {
cmd_args.ReplaceArgumentAtIndex(
entry.index(),
m_interpreter.ProcessEmbeddedScriptCommands(entry.value().c_str()));
@@ -1064,7 +1073,7 @@ CommandObject::ArgumentTableEntry CommandObject::g_arguments_data[] = {
{ eArgTypePythonScript, "python-script", CommandCompletions::eNoCompletion, { nullptr, false }, "Source code written in Python." },
{ eArgTypeQueueName, "queue-name", CommandCompletions::eNoCompletion, { nullptr, false }, "The name of the thread queue." },
{ eArgTypeRegisterName, "register-name", CommandCompletions::eNoCompletion, { RegisterNameHelpTextCallback, true }, nullptr },
- { eArgTypeRegularExpression, "regular-expression", CommandCompletions::eNoCompletion, { nullptr, false }, "A regular expression." },
+ { eArgTypeRegularExpression, "regular-expression", CommandCompletions::eNoCompletion, { nullptr, false }, "A POSIX-compliant extended regular expression." },
{ eArgTypeRunArgs, "run-args", CommandCompletions::eNoCompletion, { nullptr, false }, "Arguments to be passed to the target program when it starts executing." },
{ eArgTypeRunMode, "run-mode", CommandCompletions::eNoCompletion, { nullptr, false }, "Help text goes here." },
{ eArgTypeScriptedCommandSynchronicity, "script-cmd-synchronicity", CommandCompletions::eNoCompletion, { nullptr, false }, "The synchronicity to use to run scripted commands with regard to LLDB event system." },
diff --git a/source/Interpreter/CommandObjectRegexCommand.cpp b/source/Interpreter/CommandObjectRegexCommand.cpp
index 19335b95ca3a..693d18ce7bdf 100644
--- a/source/Interpreter/CommandObjectRegexCommand.cpp
+++ b/source/Interpreter/CommandObjectRegexCommand.cpp
@@ -30,15 +30,14 @@ bool CommandObjectRegexCommand::DoExecute(llvm::StringRef command,
CommandReturnObject &result) {
EntryCollection::const_iterator pos, end = m_entries.end();
for (pos = m_entries.begin(); pos != end; ++pos) {
- RegularExpression::Match regex_match(m_max_matches);
-
- if (pos->regex.Execute(command, &regex_match)) {
+ llvm::SmallVector<llvm::StringRef, 4> matches;
+ if (pos->regex.Execute(command, &matches)) {
std::string new_command(pos->command);
- std::string match_str;
char percent_var[8];
size_t idx, percent_var_idx;
for (uint32_t match_idx = 1; match_idx <= m_max_matches; ++match_idx) {
- if (regex_match.GetMatchAtIndex(command, match_idx, match_str)) {
+ if (match_idx < matches.size()) {
+ const std::string match_str = matches[match_idx].str();
const int percent_var_len =
::snprintf(percent_var, sizeof(percent_var), "%%%u", match_idx);
for (idx = 0; (percent_var_idx = new_command.find(
@@ -74,8 +73,9 @@ bool CommandObjectRegexCommand::AddRegexCommand(const char *re_cstr,
const char *command_cstr) {
m_entries.resize(m_entries.size() + 1);
// Only add the regular expression if it compiles
- if (m_entries.back().regex.Compile(
- llvm::StringRef::withNullAsEmpty(re_cstr))) {
+ m_entries.back().regex =
+ RegularExpression(llvm::StringRef::withNullAsEmpty(re_cstr));
+ if (m_entries.back().regex.IsValid()) {
m_entries.back().command.assign(command_cstr);
return true;
}
@@ -84,13 +84,9 @@ bool CommandObjectRegexCommand::AddRegexCommand(const char *re_cstr,
return false;
}
-int CommandObjectRegexCommand::HandleCompletion(CompletionRequest &request) {
+void CommandObjectRegexCommand::HandleCompletion(CompletionRequest &request) {
if (m_completion_type_mask) {
CommandCompletions::InvokeCommonCompletionCallbacks(
GetCommandInterpreter(), m_completion_type_mask, request, nullptr);
- return request.GetNumberOfMatches();
- } else {
- request.SetWordComplete(false);
}
- return 0;
}
diff --git a/source/Interpreter/CommandReturnObject.cpp b/source/Interpreter/CommandReturnObject.cpp
index 3a7a8755d975..c17390be7311 100644
--- a/source/Interpreter/CommandReturnObject.cpp
+++ b/source/Interpreter/CommandReturnObject.cpp
@@ -33,8 +33,7 @@ static void DumpStringToStreamWithNewline(Stream &strm, const std::string &s,
CommandReturnObject::CommandReturnObject()
: m_out_stream(), m_err_stream(), m_status(eReturnStatusStarted),
- m_did_change_process_state(false), m_interactive(true),
- m_abnormal_stop_was_expected(false) {}
+ m_did_change_process_state(false), m_interactive(true) {}
CommandReturnObject::~CommandReturnObject() {}
diff --git a/source/Interpreter/InterpreterProperties.td b/source/Interpreter/InterpreterProperties.td
new file mode 100644
index 000000000000..600c1e3edb9b
--- /dev/null
+++ b/source/Interpreter/InterpreterProperties.td
@@ -0,0 +1,28 @@
+include "../../include/lldb/Core/PropertiesBase.td"
+
+let Definition = "interpreter" in {
+ def ExpandRegexAliases: Property<"expand-regex-aliases", "Boolean">,
+ Global,
+ DefaultFalse,
+ Desc<"If true, regular expression alias commands will show the expanded command that will be executed. This can be used to debug new regular expression alias commands.">;
+ def PromptOnQuit: Property<"prompt-on-quit", "Boolean">,
+ Global,
+ DefaultTrue,
+ Desc<"If true, LLDB will prompt you before quitting if there are any live processes being debugged. If false, LLDB will quit without asking in any case.">;
+ def StopCmdSourceOnError: Property<"stop-command-source-on-error", "Boolean">,
+ Global,
+ DefaultTrue,
+ Desc<"If true, LLDB will stop running a 'command source' script upon encountering an error.">;
+ def SpaceReplPrompts: Property<"space-repl-prompts", "Boolean">,
+ Global,
+ DefaultFalse,
+ Desc<"If true, blank lines will be printed between between REPL submissions.">;
+ def EchoCommands: Property<"echo-commands", "Boolean">,
+ Global,
+ DefaultTrue,
+ Desc<"If true, commands will be echoed before they are evaluated.">;
+ def EchoCommentCommands: Property<"echo-comment-commands", "Boolean">,
+ Global,
+ DefaultTrue,
+ Desc<"If true, commands will be echoed even if they are pure comment lines.">;
+}
diff --git a/source/Interpreter/OptionArgParser.cpp b/source/Interpreter/OptionArgParser.cpp
index efaac0720fd0..14b81cd7b3d2 100644
--- a/source/Interpreter/OptionArgParser.cpp
+++ b/source/Interpreter/OptionArgParser.cpp
@@ -211,29 +211,21 @@ lldb::addr_t OptionArgParser::ToAddress(const ExecutionContext *exe_ctx,
// pointer types.
static RegularExpression g_symbol_plus_offset_regex(
"^(.*)([-\\+])[[:space:]]*(0x[0-9A-Fa-f]+|[0-9]+)[[:space:]]*$");
- RegularExpression::Match regex_match(3);
- if (g_symbol_plus_offset_regex.Execute(sref, &regex_match)) {
+
+ llvm::SmallVector<llvm::StringRef, 4> matches;
+ if (g_symbol_plus_offset_regex.Execute(sref, &matches)) {
uint64_t offset = 0;
- bool add = true;
- std::string name;
- std::string str;
- if (regex_match.GetMatchAtIndex(s, 1, name)) {
- if (regex_match.GetMatchAtIndex(s, 2, str)) {
- add = str[0] == '+';
-
- if (regex_match.GetMatchAtIndex(s, 3, str)) {
- if (!llvm::StringRef(str).getAsInteger(0, offset)) {
- Status error;
- addr = ToAddress(exe_ctx, name.c_str(), LLDB_INVALID_ADDRESS,
- &error);
- if (addr != LLDB_INVALID_ADDRESS) {
- if (add)
- return addr + offset;
- else
- return addr - offset;
- }
- }
- }
+ std::string name = matches[1].str();
+ std::string sign = matches[2].str();
+ std::string str_offset = matches[3].str();
+ if (!llvm::StringRef(str_offset).getAsInteger(0, offset)) {
+ Status error;
+ addr = ToAddress(exe_ctx, name.c_str(), LLDB_INVALID_ADDRESS, &error);
+ if (addr != LLDB_INVALID_ADDRESS) {
+ if (sign[0] == '+')
+ return addr + offset;
+ else
+ return addr - offset;
}
}
}
diff --git a/source/Interpreter/OptionGroupArchitecture.cpp b/source/Interpreter/OptionGroupArchitecture.cpp
index 2ee1a9c7cf84..11f786c52c09 100644
--- a/source/Interpreter/OptionGroupArchitecture.cpp
+++ b/source/Interpreter/OptionGroupArchitecture.cpp
@@ -46,8 +46,7 @@ OptionGroupArchitecture::SetOptionValue(uint32_t option_idx,
break;
default:
- error.SetErrorStringWithFormat("unrecognized option '%c'", short_option);
- break;
+ llvm_unreachable("Unimplemented option");
}
return error;
diff --git a/source/Interpreter/OptionGroupFormat.cpp b/source/Interpreter/OptionGroupFormat.cpp
index d9acfd663dd1..c25e35f84517 100644
--- a/source/Interpreter/OptionGroupFormat.cpp
+++ b/source/Interpreter/OptionGroupFormat.cpp
@@ -160,8 +160,7 @@ Status OptionGroupFormat::SetOptionValue(uint32_t option_idx,
} break;
default:
- error.SetErrorStringWithFormat("unrecognized option '%c'", short_option);
- break;
+ llvm_unreachable("Unimplemented option");
}
return error;
diff --git a/source/Interpreter/OptionGroupOutputFile.cpp b/source/Interpreter/OptionGroupOutputFile.cpp
index ccb99a8fce4a..3df75cf86b85 100644
--- a/source/Interpreter/OptionGroupOutputFile.cpp
+++ b/source/Interpreter/OptionGroupOutputFile.cpp
@@ -50,8 +50,7 @@ OptionGroupOutputFile::SetOptionValue(uint32_t option_idx,
break;
default:
- error.SetErrorStringWithFormat("unrecognized option '%c'", short_option);
- break;
+ llvm_unreachable("Unimplemented option");
}
return error;
diff --git a/source/Interpreter/OptionGroupPlatform.cpp b/source/Interpreter/OptionGroupPlatform.cpp
index 6dc2996bb78a..6ddbbf0e3abb 100644
--- a/source/Interpreter/OptionGroupPlatform.cpp
+++ b/source/Interpreter/OptionGroupPlatform.cpp
@@ -113,8 +113,7 @@ OptionGroupPlatform::SetOptionValue(uint32_t option_idx,
break;
default:
- error.SetErrorStringWithFormat("unrecognized option '%c'", short_option);
- break;
+ llvm_unreachable("Unimplemented option");
}
return error;
}
diff --git a/source/Interpreter/OptionGroupPythonClassWithDict.cpp b/source/Interpreter/OptionGroupPythonClassWithDict.cpp
new file mode 100644
index 000000000000..9a893ec53625
--- /dev/null
+++ b/source/Interpreter/OptionGroupPythonClassWithDict.cpp
@@ -0,0 +1,123 @@
+//===-- OptionGroupPythonClassWithDict.cpp ----------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Interpreter/OptionGroupPythonClassWithDict.h"
+
+#include "lldb/Host/OptionParser.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+OptionGroupPythonClassWithDict::OptionGroupPythonClassWithDict
+ (const char *class_use,
+ int class_option,
+ int key_option,
+ int value_option,
+ const char *class_long_option,
+ const char *key_long_option,
+ const char *value_long_option,
+ bool required) {
+ m_key_usage_text.assign("The key for a key/value pair passed to the class"
+ " that implements a ");
+ m_key_usage_text.append(class_use);
+ m_key_usage_text.append(". Pairs can be specified more than once.");
+
+ m_value_usage_text.assign("The value for a previous key in the pair passed to"
+ " the class that implements a ");
+ m_value_usage_text.append(class_use);
+ m_value_usage_text.append(". Pairs can be specified more than once.");
+
+ m_class_usage_text.assign("The name of the class that will manage a ");
+ m_class_usage_text.append(class_use);
+ m_class_usage_text.append(".");
+
+ m_option_definition[0].usage_mask = LLDB_OPT_SET_1;
+ m_option_definition[0].required = required;
+ m_option_definition[0].long_option = class_long_option;
+ m_option_definition[0].short_option = class_option;
+ m_option_definition[0].validator = nullptr;
+ m_option_definition[0].option_has_arg = OptionParser::eRequiredArgument;
+ m_option_definition[0].enum_values = {};
+ m_option_definition[0].completion_type = 0;
+ m_option_definition[0].argument_type = eArgTypePythonClass;
+ m_option_definition[0].usage_text = m_class_usage_text.data();
+
+ m_option_definition[1].usage_mask = LLDB_OPT_SET_1;
+ m_option_definition[1].required = required;
+ m_option_definition[1].long_option = key_long_option;
+ m_option_definition[1].short_option = key_option;
+ m_option_definition[1].validator = nullptr;
+ m_option_definition[1].option_has_arg = OptionParser::eRequiredArgument;
+ m_option_definition[1].enum_values = {};
+ m_option_definition[1].completion_type = 0;
+ m_option_definition[1].argument_type = eArgTypeNone;
+ m_option_definition[1].usage_text = m_key_usage_text.data();
+
+ m_option_definition[2].usage_mask = LLDB_OPT_SET_1;
+ m_option_definition[2].required = required;
+ m_option_definition[2].long_option = value_long_option;
+ m_option_definition[2].short_option = value_option;
+ m_option_definition[2].validator = nullptr;
+ m_option_definition[2].option_has_arg = OptionParser::eRequiredArgument;
+ m_option_definition[2].enum_values = {};
+ m_option_definition[2].completion_type = 0;
+ m_option_definition[2].argument_type = eArgTypeNone;
+ m_option_definition[2].usage_text = m_value_usage_text.data();
+}
+
+OptionGroupPythonClassWithDict::~OptionGroupPythonClassWithDict() {}
+
+Status OptionGroupPythonClassWithDict::SetOptionValue(
+ uint32_t option_idx,
+ llvm::StringRef option_arg,
+ ExecutionContext *execution_context) {
+ Status error;
+ switch (option_idx) {
+ case 0: {
+ m_class_name.assign(option_arg);
+ } break;
+ case 1: {
+ if (m_current_key.empty())
+ m_current_key.assign(option_arg);
+ else
+ error.SetErrorStringWithFormat("Key: \"%s\" missing value.",
+ m_current_key.c_str());
+
+ } break;
+ case 2: {
+ if (!m_current_key.empty()) {
+ m_dict_sp->AddStringItem(m_current_key, option_arg);
+ m_current_key.clear();
+ }
+ else
+ error.SetErrorStringWithFormat("Value: \"%s\" missing matching key.",
+ option_arg.str().c_str());
+ } break;
+ default:
+ llvm_unreachable("Unimplemented option");
+ }
+ return error;
+}
+
+void OptionGroupPythonClassWithDict::OptionParsingStarting(
+ ExecutionContext *execution_context) {
+ m_current_key.erase();
+ m_dict_sp = std::make_shared<StructuredData::Dictionary>();
+}
+
+Status OptionGroupPythonClassWithDict::OptionParsingFinished(
+ ExecutionContext *execution_context) {
+ Status error;
+ // If we get here and there's contents in the m_current_key, somebody must
+ // have provided a key but no value.
+ if (!m_current_key.empty())
+ error.SetErrorStringWithFormat("Key: \"%s\" missing value.",
+ m_current_key.c_str());
+ return error;
+}
+
diff --git a/source/Interpreter/OptionGroupUUID.cpp b/source/Interpreter/OptionGroupUUID.cpp
index e32673bc52af..8fc330a89391 100644
--- a/source/Interpreter/OptionGroupUUID.cpp
+++ b/source/Interpreter/OptionGroupUUID.cpp
@@ -40,8 +40,7 @@ Status OptionGroupUUID::SetOptionValue(uint32_t option_idx,
break;
default:
- error.SetErrorStringWithFormat("unrecognized option '%c'", short_option);
- break;
+ llvm_unreachable("Unimplemented option");
}
return error;
diff --git a/source/Interpreter/OptionGroupValueObjectDisplay.cpp b/source/Interpreter/OptionGroupValueObjectDisplay.cpp
index 4e5463a4de00..81c10a6c762e 100644
--- a/source/Interpreter/OptionGroupValueObjectDisplay.cpp
+++ b/source/Interpreter/OptionGroupValueObjectDisplay.cpp
@@ -152,8 +152,7 @@ Status OptionGroupValueObjectDisplay::SetOptionValue(
break;
default:
- error.SetErrorStringWithFormat("unrecognized option '%c'", short_option);
- break;
+ llvm_unreachable("Unimplemented option");
}
return error;
diff --git a/source/Interpreter/OptionGroupVariable.cpp b/source/Interpreter/OptionGroupVariable.cpp
index d703c3dedcd9..a9004bf03cd2 100644
--- a/source/Interpreter/OptionGroupVariable.cpp
+++ b/source/Interpreter/OptionGroupVariable.cpp
@@ -109,9 +109,7 @@ OptionGroupVariable::SetOptionValue(uint32_t option_idx,
error = summary_string.SetCurrentValue(option_arg);
break;
default:
- error.SetErrorStringWithFormat("unrecognized short option '%c'",
- short_option);
- break;
+ llvm_unreachable("Unimplemented option");
}
return error;
diff --git a/source/Interpreter/OptionGroupWatchpoint.cpp b/source/Interpreter/OptionGroupWatchpoint.cpp
index 28e6b817fcc5..682f99b8c5cc 100644
--- a/source/Interpreter/OptionGroupWatchpoint.cpp
+++ b/source/Interpreter/OptionGroupWatchpoint.cpp
@@ -16,16 +16,45 @@ using namespace lldb;
using namespace lldb_private;
static constexpr OptionEnumValueElement g_watch_type[] = {
- {OptionGroupWatchpoint::eWatchRead, "read", "Watch for read"},
- {OptionGroupWatchpoint::eWatchWrite, "write", "Watch for write"},
- {OptionGroupWatchpoint::eWatchReadWrite, "read_write",
- "Watch for read/write"} };
+ {
+ OptionGroupWatchpoint::eWatchRead,
+ "read",
+ "Watch for read",
+ },
+ {
+ OptionGroupWatchpoint::eWatchWrite,
+ "write",
+ "Watch for write",
+ },
+ {
+ OptionGroupWatchpoint::eWatchReadWrite,
+ "read_write",
+ "Watch for read/write",
+ },
+};
static constexpr OptionEnumValueElement g_watch_size[] = {
- {1, "1", "Watch for byte size of 1"},
- {2, "2", "Watch for byte size of 2"},
- {4, "4", "Watch for byte size of 4"},
- {8, "8", "Watch for byte size of 8"} };
+ {
+ 1,
+ "1",
+ "Watch for byte size of 1",
+ },
+ {
+ 2,
+ "2",
+ "Watch for byte size of 2",
+ },
+ {
+ 4,
+ "4",
+ "Watch for byte size of 4",
+ },
+ {
+ 8,
+ "8",
+ "Watch for byte size of 8",
+ },
+};
static constexpr OptionDefinition g_option_table[] = {
{LLDB_OPT_SET_1, false, "watch", 'w', OptionParser::eRequiredArgument,
@@ -72,9 +101,7 @@ OptionGroupWatchpoint::SetOptionValue(uint32_t option_idx,
break;
default:
- error.SetErrorStringWithFormat("unrecognized short option '%c'",
- short_option);
- break;
+ llvm_unreachable("Unimplemented option");
}
return error;
diff --git a/source/Interpreter/OptionValue.cpp b/source/Interpreter/OptionValue.cpp
index 00c8642595b7..bc929aa9dabf 100644
--- a/source/Interpreter/OptionValue.cpp
+++ b/source/Interpreter/OptionValue.cpp
@@ -565,11 +565,8 @@ bool OptionValue::DumpQualifiedName(Stream &strm) const {
return dumped_something;
}
-size_t OptionValue::AutoComplete(CommandInterpreter &interpreter,
- CompletionRequest &request) {
- request.SetWordComplete(false);
- return request.GetNumberOfMatches();
-}
+void OptionValue::AutoComplete(CommandInterpreter &interpreter,
+ CompletionRequest &request) {}
Status OptionValue::SetValueFromString(llvm::StringRef value,
VarSetOperationType op) {
diff --git a/source/Interpreter/OptionValueArch.cpp b/source/Interpreter/OptionValueArch.cpp
index 92dc45d092be..7271c1471f90 100644
--- a/source/Interpreter/OptionValueArch.cpp
+++ b/source/Interpreter/OptionValueArch.cpp
@@ -68,11 +68,9 @@ lldb::OptionValueSP OptionValueArch::DeepCopy() const {
return OptionValueSP(new OptionValueArch(*this));
}
-size_t OptionValueArch::AutoComplete(CommandInterpreter &interpreter,
- CompletionRequest &request) {
- request.SetWordComplete(false);
+void OptionValueArch::AutoComplete(CommandInterpreter &interpreter,
+ CompletionRequest &request) {
CommandCompletions::InvokeCommonCompletionCallbacks(
interpreter, CommandCompletions::eArchitectureCompletion, request,
nullptr);
- return request.GetNumberOfMatches();
}
diff --git a/source/Interpreter/OptionValueBoolean.cpp b/source/Interpreter/OptionValueBoolean.cpp
index 8be8220fb306..6f893a94e863 100644
--- a/source/Interpreter/OptionValueBoolean.cpp
+++ b/source/Interpreter/OptionValueBoolean.cpp
@@ -71,21 +71,17 @@ lldb::OptionValueSP OptionValueBoolean::DeepCopy() const {
return OptionValueSP(new OptionValueBoolean(*this));
}
-size_t OptionValueBoolean::AutoComplete(CommandInterpreter &interpreter,
- CompletionRequest &request) {
- request.SetWordComplete(false);
- static const llvm::StringRef g_autocomplete_entries[] = {
- "true", "false", "on", "off", "yes", "no", "1", "0"};
+void OptionValueBoolean::AutoComplete(CommandInterpreter &interpreter,
+ CompletionRequest &request) {
+ llvm::StringRef autocomplete_entries[] = {"true", "false", "on", "off",
+ "yes", "no", "1", "0"};
- auto entries = llvm::makeArrayRef(g_autocomplete_entries);
+ auto entries = llvm::makeArrayRef(autocomplete_entries);
// only suggest "true" or "false" by default
if (request.GetCursorArgumentPrefix().empty())
entries = entries.take_front(2);
- for (auto entry : entries) {
- if (entry.startswith_lower(request.GetCursorArgumentPrefix()))
- request.AddCompletion(entry);
- }
- return request.GetNumberOfMatches();
+ for (auto entry : entries)
+ request.TryCompleteCurrentArg(entry);
}
diff --git a/source/Interpreter/OptionValueDictionary.cpp b/source/Interpreter/OptionValueDictionary.cpp
index eb66c485bfd1..a4022288fccb 100644
--- a/source/Interpreter/OptionValueDictionary.cpp
+++ b/source/Interpreter/OptionValueDictionary.cpp
@@ -111,18 +111,18 @@ Status OptionValueDictionary::SetArgs(const Args &args,
return error;
}
for (const auto &entry : args) {
- if (entry.ref.empty()) {
+ if (entry.ref().empty()) {
error.SetErrorString("empty argument");
return error;
}
- if (!entry.ref.contains('=')) {
+ if (!entry.ref().contains('=')) {
error.SetErrorString(
"assign operation takes one or more key=value arguments");
return error;
}
llvm::StringRef key, value;
- std::tie(key, value) = entry.ref.split('=');
+ std::tie(key, value) = entry.ref().split('=');
bool key_valid = false;
if (key.empty()) {
error.SetErrorString("empty dictionary key");
diff --git a/source/Interpreter/OptionValueEnumeration.cpp b/source/Interpreter/OptionValueEnumeration.cpp
index 0b76bd0601aa..26933aa78240 100644
--- a/source/Interpreter/OptionValueEnumeration.cpp
+++ b/source/Interpreter/OptionValueEnumeration.cpp
@@ -102,21 +102,16 @@ lldb::OptionValueSP OptionValueEnumeration::DeepCopy() const {
return OptionValueSP(new OptionValueEnumeration(*this));
}
-size_t OptionValueEnumeration::AutoComplete(CommandInterpreter &interpreter,
- CompletionRequest &request) {
- request.SetWordComplete(false);
-
+void OptionValueEnumeration::AutoComplete(CommandInterpreter &interpreter,
+ CompletionRequest &request) {
const uint32_t num_enumerators = m_enumerations.GetSize();
if (!request.GetCursorArgumentPrefix().empty()) {
for (size_t i = 0; i < num_enumerators; ++i) {
llvm::StringRef name = m_enumerations.GetCStringAtIndex(i).GetStringRef();
- if (name.startswith(request.GetCursorArgumentPrefix()))
- request.AddCompletion(name);
+ request.TryCompleteCurrentArg(name);
}
- } else {
- // only suggest "true" or "false" by default
+ return;
+ }
for (size_t i = 0; i < num_enumerators; ++i)
request.AddCompletion(m_enumerations.GetCStringAtIndex(i).GetStringRef());
- }
- return request.GetNumberOfMatches();
}
diff --git a/source/Interpreter/OptionValueFileSpec.cpp b/source/Interpreter/OptionValueFileSpec.cpp
index 062d7ccdf2aa..20d3d4e68e33 100644
--- a/source/Interpreter/OptionValueFileSpec.cpp
+++ b/source/Interpreter/OptionValueFileSpec.cpp
@@ -99,12 +99,10 @@ lldb::OptionValueSP OptionValueFileSpec::DeepCopy() const {
return OptionValueSP(new OptionValueFileSpec(*this));
}
-size_t OptionValueFileSpec::AutoComplete(CommandInterpreter &interpreter,
- CompletionRequest &request) {
- request.SetWordComplete(false);
+void OptionValueFileSpec::AutoComplete(CommandInterpreter &interpreter,
+ CompletionRequest &request) {
CommandCompletions::InvokeCommonCompletionCallbacks(
interpreter, m_completion_mask, request, nullptr);
- return request.GetNumberOfMatches();
}
const lldb::DataBufferSP &OptionValueFileSpec::GetFileContents() {
diff --git a/source/Interpreter/OptionValueFileSpecLIst.cpp b/source/Interpreter/OptionValueFileSpecList.cpp
index a95188870f0b..1a9d3c9ecb87 100644
--- a/source/Interpreter/OptionValueFileSpecLIst.cpp
+++ b/source/Interpreter/OptionValueFileSpecList.cpp
@@ -1,4 +1,4 @@
-//===-- OptionValueFileSpecLIst.cpp -----------------------------*- C++ -*-===//
+//===-- OptionValueFileSpecList.cpp ---------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/source/Interpreter/OptionValueFormatEntity.cpp b/source/Interpreter/OptionValueFormatEntity.cpp
index 1bb8c9f6955a..8dc52650a331 100644
--- a/source/Interpreter/OptionValueFormatEntity.cpp
+++ b/source/Interpreter/OptionValueFormatEntity.cpp
@@ -116,7 +116,7 @@ lldb::OptionValueSP OptionValueFormatEntity::DeepCopy() const {
return OptionValueSP(new OptionValueFormatEntity(*this));
}
-size_t OptionValueFormatEntity::AutoComplete(CommandInterpreter &interpreter,
- CompletionRequest &request) {
- return FormatEntity::AutoComplete(request);
+void OptionValueFormatEntity::AutoComplete(CommandInterpreter &interpreter,
+ CompletionRequest &request) {
+ FormatEntity::AutoComplete(request);
}
diff --git a/source/Interpreter/OptionValueLanguage.cpp b/source/Interpreter/OptionValueLanguage.cpp
index d935d5e23496..1d7e18868b6f 100644
--- a/source/Interpreter/OptionValueLanguage.cpp
+++ b/source/Interpreter/OptionValueLanguage.cpp
@@ -10,6 +10,7 @@
#include "lldb/DataFormatters/FormatManager.h"
#include "lldb/Target/Language.h"
+#include "lldb/Symbol/TypeSystem.h"
#include "lldb/Utility/Args.h"
#include "lldb/Utility/Stream.h"
@@ -39,23 +40,20 @@ Status OptionValueLanguage::SetValueFromString(llvm::StringRef value,
case eVarSetOperationReplace:
case eVarSetOperationAssign: {
ConstString lang_name(value.trim());
- std::set<lldb::LanguageType> languages_for_types;
- std::set<lldb::LanguageType> languages_for_expressions;
- Language::GetLanguagesSupportingTypeSystems(languages_for_types,
- languages_for_expressions);
-
+ LanguageSet languages_for_types = Language::GetLanguagesSupportingTypeSystems();
LanguageType new_type =
Language::GetLanguageTypeFromString(lang_name.GetStringRef());
- if (new_type && languages_for_types.count(new_type)) {
+ if (new_type && languages_for_types[new_type]) {
m_value_was_set = true;
m_current_value = new_type;
} else {
StreamString error_strm;
error_strm.Printf("invalid language type '%s', ", value.str().c_str());
error_strm.Printf("valid values are:\n");
- for (lldb::LanguageType language : languages_for_types) {
- error_strm.Printf("%s%s%s", " ",
- Language::GetNameForLanguageType(language), "\n");
+ for (int bit : languages_for_types.bitvector.set_bits()) {
+ auto language = (LanguageType)bit;
+ error_strm.Printf(" %s\n",
+ Language::GetNameForLanguageType(language));
}
error.SetErrorString(error_strm.GetString());
}
diff --git a/source/Interpreter/OptionValueRegex.cpp b/source/Interpreter/OptionValueRegex.cpp
index bbe3fa715019..cf806fb550f9 100644
--- a/source/Interpreter/OptionValueRegex.cpp
+++ b/source/Interpreter/OptionValueRegex.cpp
@@ -46,16 +46,14 @@ Status OptionValueRegex::SetValueFromString(llvm::StringRef value,
case eVarSetOperationReplace:
case eVarSetOperationAssign:
- if (m_regex.Compile(value)) {
+ m_regex = RegularExpression(value);
+ if (m_regex.IsValid()) {
m_value_was_set = true;
NotifyValueChanged();
+ } else if (llvm::Error err = m_regex.GetError()) {
+ error.SetErrorString(llvm::toString(std::move(err)));
} else {
- char regex_error[1024];
- if (m_regex.GetErrorAsCString(regex_error, sizeof(regex_error)))
- error.SetErrorString(regex_error);
- else
- error.SetErrorStringWithFormat("regex error %u",
- m_regex.GetErrorCode());
+ error.SetErrorString("regex error");
}
break;
}
diff --git a/source/Interpreter/OptionValueUUID.cpp b/source/Interpreter/OptionValueUUID.cpp
index f39b66b77bb0..7a6bc65b25a4 100644
--- a/source/Interpreter/OptionValueUUID.cpp
+++ b/source/Interpreter/OptionValueUUID.cpp
@@ -62,30 +62,24 @@ lldb::OptionValueSP OptionValueUUID::DeepCopy() const {
return OptionValueSP(new OptionValueUUID(*this));
}
-size_t OptionValueUUID::AutoComplete(CommandInterpreter &interpreter,
- CompletionRequest &request) {
- request.SetWordComplete(false);
+void OptionValueUUID::AutoComplete(CommandInterpreter &interpreter,
+ CompletionRequest &request) {
ExecutionContext exe_ctx(interpreter.GetExecutionContext());
Target *target = exe_ctx.GetTargetPtr();
- if (target) {
- auto prefix = request.GetCursorArgumentPrefix();
- llvm::SmallVector<uint8_t, 20> uuid_bytes;
- if (UUID::DecodeUUIDBytesFromString(prefix, uuid_bytes).empty()) {
- const size_t num_modules = target->GetImages().GetSize();
- for (size_t i = 0; i < num_modules; ++i) {
- ModuleSP module_sp(target->GetImages().GetModuleAtIndex(i));
- if (module_sp) {
- const UUID &module_uuid = module_sp->GetUUID();
- if (module_uuid.IsValid()) {
- llvm::ArrayRef<uint8_t> module_bytes = module_uuid.GetBytes();
- if (module_bytes.size() >= uuid_bytes.size() &&
- module_bytes.take_front(uuid_bytes.size()).equals(uuid_bytes)) {
- request.AddCompletion(module_uuid.GetAsString());
- }
- }
- }
- }
- }
+ if (!target)
+ return;
+ auto prefix = request.GetCursorArgumentPrefix();
+ llvm::SmallVector<uint8_t, 20> uuid_bytes;
+ if (!UUID::DecodeUUIDBytesFromString(prefix, uuid_bytes).empty())
+ return;
+ const size_t num_modules = target->GetImages().GetSize();
+ for (size_t i = 0; i < num_modules; ++i) {
+ ModuleSP module_sp(target->GetImages().GetModuleAtIndex(i));
+ if (!module_sp)
+ continue;
+ const UUID &module_uuid = module_sp->GetUUID();
+ if (!module_uuid.IsValid())
+ continue;
+ request.TryCompleteCurrentArg(module_uuid.GetAsString());
}
- return request.GetNumberOfMatches();
}
diff --git a/source/Interpreter/Options.cpp b/source/Interpreter/Options.cpp
index ba15c020f2da..0bceea14269d 100644
--- a/source/Interpreter/Options.cpp
+++ b/source/Interpreter/Options.cpp
@@ -645,8 +645,6 @@ bool Options::VerifyPartialOptions(CommandReturnObject &result) {
bool Options::HandleOptionCompletion(CompletionRequest &request,
OptionElementVector &opt_element_vector,
CommandInterpreter &interpreter) {
- request.SetWordComplete(true);
-
// For now we just scan the completions to see if the cursor position is in
// an option or its argument. Otherwise we'll call HandleArgumentCompletion.
// In the future we can use completion to validate options as well if we
@@ -654,12 +652,11 @@ bool Options::HandleOptionCompletion(CompletionRequest &request,
auto opt_defs = GetDefinitions();
- std::string cur_opt_std_str = request.GetCursorArgumentPrefix().str();
- const char *cur_opt_str = cur_opt_std_str.c_str();
+ llvm::StringRef cur_opt_str = request.GetCursorArgumentPrefix();
for (size_t i = 0; i < opt_element_vector.size(); i++) {
- int opt_pos = opt_element_vector[i].opt_pos;
- int opt_arg_pos = opt_element_vector[i].opt_arg_pos;
+ size_t opt_pos = static_cast<size_t>(opt_element_vector[i].opt_pos);
+ size_t opt_arg_pos = static_cast<size_t>(opt_element_vector[i].opt_arg_pos);
int opt_defs_index = opt_element_vector[i].opt_defs_index;
if (opt_pos == request.GetCursorIndex()) {
// We're completing the option itself.
@@ -669,13 +666,13 @@ bool Options::HandleOptionCompletion(CompletionRequest &request,
// FIXME: We should scan the other options provided and only complete
// options
// within the option group they belong to.
- char opt_str[3] = {'-', 'a', '\0'};
+ std::string opt_str = "-a";
for (auto &def : opt_defs) {
if (!def.short_option)
continue;
opt_str[1] = def.short_option;
- request.AddCompletion(opt_str);
+ request.AddCompletion(opt_str, def.usage_text);
}
return true;
@@ -687,7 +684,7 @@ bool Options::HandleOptionCompletion(CompletionRequest &request,
full_name.erase(full_name.begin() + 2, full_name.end());
full_name.append(def.long_option);
- request.AddCompletion(full_name.c_str());
+ request.AddCompletion(full_name, def.usage_text);
}
return true;
} else if (opt_defs_index != OptionArgElement::eUnrecognizedArg) {
@@ -695,17 +692,14 @@ bool Options::HandleOptionCompletion(CompletionRequest &request,
// anyway (getopt_long_only is happy with shortest unique string, but
// it's still a nice thing to do.) Otherwise return The string so the
// upper level code will know this is a full match and add the " ".
- if (cur_opt_str && strlen(cur_opt_str) > 2 && cur_opt_str[0] == '-' &&
- cur_opt_str[1] == '-' &&
- strcmp(opt_defs[opt_defs_index].long_option, cur_opt_str) != 0) {
- std::string full_name("--");
- full_name.append(opt_defs[opt_defs_index].long_option);
- request.AddCompletion(full_name.c_str());
- return true;
- } else {
- request.AddCompletion(request.GetCursorArgument());
+ const OptionDefinition &opt = opt_defs[opt_defs_index];
+ llvm::StringRef long_option = opt.long_option;
+ if (cur_opt_str.startswith("--") && cur_opt_str != long_option) {
+ request.AddCompletion("--" + long_option.str(), opt.usage_text);
return true;
- }
+ } else
+ request.AddCompletion(request.GetCursorArgumentPrefix());
+ return true;
} else {
// FIXME - not handling wrong options yet:
// Check to see if they are writing a long option & complete it.
@@ -713,18 +707,11 @@ bool Options::HandleOptionCompletion(CompletionRequest &request,
// elements
// that are not unique up to this point. getopt_long_only does
// shortest unique match for long options already.
-
- if (cur_opt_str && strlen(cur_opt_str) > 2 && cur_opt_str[0] == '-' &&
- cur_opt_str[1] == '-') {
+ if (cur_opt_str.consume_front("--")) {
for (auto &def : opt_defs) {
- if (!def.long_option)
- continue;
-
- if (strstr(def.long_option, cur_opt_str + 2) == def.long_option) {
- std::string full_name("--");
- full_name.append(def.long_option);
- request.AddCompletion(full_name.c_str());
- }
+ llvm::StringRef long_option(def.long_option);
+ if (long_option.startswith(cur_opt_str))
+ request.AddCompletion("--" + long_option.str(), def.usage_text);
}
}
return true;
@@ -733,13 +720,9 @@ bool Options::HandleOptionCompletion(CompletionRequest &request,
} else if (opt_arg_pos == request.GetCursorIndex()) {
// Okay the cursor is on the completion of an argument. See if it has a
// completion, otherwise return no matches.
-
- CompletionRequest subrequest = request;
- subrequest.SetCursorCharPosition(subrequest.GetCursorArgument().size());
if (opt_defs_index != -1) {
- HandleOptionArgumentCompletion(subrequest, opt_element_vector, i,
+ HandleOptionArgumentCompletion(request, opt_element_vector, i,
interpreter);
- request.SetWordComplete(subrequest.GetWordComplete());
return true;
} else {
// No completion callback means no completions...
@@ -754,34 +737,20 @@ bool Options::HandleOptionCompletion(CompletionRequest &request,
return false;
}
-bool Options::HandleOptionArgumentCompletion(
+void Options::HandleOptionArgumentCompletion(
CompletionRequest &request, OptionElementVector &opt_element_vector,
int opt_element_index, CommandInterpreter &interpreter) {
auto opt_defs = GetDefinitions();
std::unique_ptr<SearchFilter> filter_up;
- int opt_arg_pos = opt_element_vector[opt_element_index].opt_arg_pos;
int opt_defs_index = opt_element_vector[opt_element_index].opt_defs_index;
// See if this is an enumeration type option, and if so complete it here:
const auto &enum_values = opt_defs[opt_defs_index].enum_values;
- if (!enum_values.empty()) {
- bool return_value = false;
- std::string match_string(
- request.GetParsedLine().GetArgumentAtIndex(opt_arg_pos),
- request.GetParsedLine().GetArgumentAtIndex(opt_arg_pos) +
- request.GetCursorCharPosition());
-
- for (const auto &enum_value : enum_values) {
- if (strstr(enum_value.string_value, match_string.c_str()) ==
- enum_value.string_value) {
- request.AddCompletion(enum_value.string_value);
- return_value = true;
- }
- }
- return return_value;
- }
+ if (!enum_values.empty())
+ for (const auto &enum_value : enum_values)
+ request.TryCompleteCurrentArg(enum_value.string_value);
// If this is a source file or symbol type completion, and there is a -shlib
// option somewhere in the supplied arguments, then make a search filter for
@@ -836,7 +805,7 @@ bool Options::HandleOptionArgumentCompletion(
}
}
- return CommandCompletions::InvokeCommonCompletionCallbacks(
+ CommandCompletions::InvokeCommonCompletionCallbacks(
interpreter, completion_mask, request, filter_up.get());
}
@@ -954,7 +923,7 @@ static Args ReconstituteArgsAfterParsing(llvm::ArrayRef<char *> parsed,
for (const char *arg : parsed) {
auto pos = FindOriginalIter(arg, original);
assert(pos != original.end());
- result.AppendArgument(pos->ref, pos->quote);
+ result.AppendArgument(pos->ref(), pos->GetQuoteChar());
}
return result;
}
@@ -965,8 +934,8 @@ static size_t FindArgumentIndexForOption(const Args &args,
std::string long_opt =
llvm::formatv("--{0}", long_option.definition->long_option);
for (const auto &entry : llvm::enumerate(args)) {
- if (entry.value().ref.startswith(short_opt) ||
- entry.value().ref.startswith(long_opt))
+ if (entry.value().ref().startswith(short_opt) ||
+ entry.value().ref().startswith(long_opt))
return entry.index();
}
@@ -1105,7 +1074,7 @@ llvm::Expected<Args> Options::ParseAlias(const Args &args,
continue;
if (!input_line.empty()) {
- auto tmp_arg = args_copy[idx].ref;
+ auto tmp_arg = args_copy[idx].ref();
size_t pos = input_line.find(tmp_arg);
if (pos != std::string::npos)
input_line.erase(pos, tmp_arg.size());
@@ -1115,9 +1084,9 @@ llvm::Expected<Args> Options::ParseAlias(const Args &args,
OptionParser::eNoArgument) &&
(OptionParser::GetOptionArgument() != nullptr) &&
(idx < args_copy.GetArgumentCount()) &&
- (args_copy[idx].ref == OptionParser::GetOptionArgument())) {
+ (args_copy[idx].ref() == OptionParser::GetOptionArgument())) {
if (input_line.size() > 0) {
- auto tmp_arg = args_copy[idx].ref;
+ auto tmp_arg = args_copy[idx].ref();
size_t pos = input_line.find(tmp_arg);
if (pos != std::string::npos)
input_line.erase(pos, tmp_arg.size());
@@ -1308,7 +1277,7 @@ OptionElementVector Options::ParseForCompletion(const Args &args,
const Args::ArgEntry &cursor = args[cursor_index];
if ((static_cast<int32_t>(dash_dash_pos) == -1 ||
cursor_index < dash_dash_pos) &&
- !cursor.IsQuoted() && cursor.ref == "-") {
+ !cursor.IsQuoted() && cursor.ref() == "-") {
option_element_vector.push_back(
OptionArgElement(OptionArgElement::eBareDash, cursor_index,
OptionArgElement::eBareDash));
@@ -1411,6 +1380,10 @@ llvm::Expected<Args> Options::Parse(const Args &args,
? nullptr
: OptionParser::GetOptionArgument(),
execution_context);
+ // If the Option setting returned an error, we should stop parsing
+ // and return the error.
+ if (error.Fail())
+ break;
} else {
error.SetErrorStringWithFormat("invalid option with value '%i'", val);
}