diff options
Diffstat (limited to 'source/Interpreter')
-rw-r--r-- | source/Interpreter/Args.cpp | 5 | ||||
-rw-r--r-- | source/Interpreter/CommandInterpreter.cpp | 100 | ||||
-rw-r--r-- | source/Interpreter/CommandObject.cpp | 7 | ||||
-rw-r--r-- | source/Interpreter/OptionGroupArchitecture.cpp | 11 | ||||
-rw-r--r-- | source/Interpreter/OptionGroupFormat.cpp | 5 | ||||
-rw-r--r-- | source/Interpreter/OptionValueDictionary.cpp | 3 | ||||
-rw-r--r-- | source/Interpreter/ScriptInterpreter.cpp | 5 |
7 files changed, 99 insertions, 37 deletions
diff --git a/source/Interpreter/Args.cpp b/source/Interpreter/Args.cpp index a23ba3094b22..07e5191f898a 100644 --- a/source/Interpreter/Args.cpp +++ b/source/Interpreter/Args.cpp @@ -185,6 +185,11 @@ Args::Args(llvm::StringRef command) { SetCommandString(command); } Args::Args(const Args &rhs) { *this = rhs; } +Args::Args(const StringList &list) : Args() { + for(size_t i = 0; i < list.GetSize(); ++i) + AppendArgument(list[i]); +} + Args &Args::operator=(const Args &rhs) { Clear(); diff --git a/source/Interpreter/CommandInterpreter.cpp b/source/Interpreter/CommandInterpreter.cpp index 986be7ffbf89..8dc5637b6e4e 100644 --- a/source/Interpreter/CommandInterpreter.cpp +++ b/source/Interpreter/CommandInterpreter.cpp @@ -546,7 +546,7 @@ void CommandInterpreter::LoadCommandDictionary() { char buffer[1024]; int num_printed = snprintf(buffer, 1024, "%s %s", break_regexes[i][1], "-o"); - assert(num_printed < 1024); + lldbassert(num_printed < 1024); UNUSED_IF_ASSERT_DISABLED(num_printed); success = tbreak_regex_cmd_ap->AddRegexCommand(break_regexes[i][0], buffer); @@ -891,8 +891,8 @@ bool CommandInterpreter::AddCommand(llvm::StringRef name, const lldb::CommandObjectSP &cmd_sp, bool can_replace) { if (cmd_sp.get()) - assert((this == &cmd_sp->GetCommandInterpreter()) && - "tried to add a CommandObject from a different interpreter"); + lldbassert((this == &cmd_sp->GetCommandInterpreter()) && + "tried to add a CommandObject from a different interpreter"); if (name.empty()) return false; @@ -913,8 +913,8 @@ bool CommandInterpreter::AddUserCommand(llvm::StringRef name, const lldb::CommandObjectSP &cmd_sp, bool can_replace) { if (cmd_sp.get()) - assert((this == &cmd_sp->GetCommandInterpreter()) && - "tried to add a CommandObject from a different interpreter"); + lldbassert((this == &cmd_sp->GetCommandInterpreter()) && + "tried to add a CommandObject from a different interpreter"); if (!name.empty()) { // do not allow replacement of internal commands @@ -1062,8 +1062,8 @@ CommandInterpreter::AddAlias(llvm::StringRef alias_name, lldb::CommandObjectSP &command_obj_sp, llvm::StringRef args_string) { if (command_obj_sp.get()) - assert((this == &command_obj_sp->GetCommandInterpreter()) && - "tried to add a CommandObject from a different interpreter"); + lldbassert((this == &command_obj_sp->GetCommandInterpreter()) && + "tried to add a CommandObject from a different interpreter"); std::unique_ptr<CommandAlias> command_alias_up( new CommandAlias(*this, command_obj_sp, args_string, alias_name)); @@ -1541,6 +1541,12 @@ bool CommandInterpreter::HandleCommand(const char *command_line, if (!no_context_switching) UpdateExecutionContext(override_context); + if (WasInterrupted()) { + result.AppendError("interrupted"); + result.SetStatus(eReturnStatusFailed); + return false; + } + bool add_to_history; if (lazy_add_to_history == eLazyBoolCalculate) add_to_history = (m_command_source_depth == 0); @@ -1839,7 +1845,7 @@ int CommandInterpreter::HandleCompletion( matches.Clear(); // Only max_return_elements == -1 is supported at present: - assert(max_return_elements == -1); + lldbassert(max_return_elements == -1); bool word_complete; num_command_matches = HandleCompletionMatches( parsed_line, cursor_index, cursor_char_position, match_start_point, @@ -2210,7 +2216,7 @@ void CommandInterpreter::HandleCommands(const StringList &commands, m_debugger.SetAsyncExecution(false); } - for (size_t idx = 0; idx < num_lines; idx++) { + for (size_t idx = 0; idx < num_lines && !WasInterrupted(); idx++) { const char *cmd = commands.GetStringAtIndex(idx); if (cmd[0] == '\0') continue; @@ -2569,7 +2575,7 @@ void CommandInterpreter::OutputHelpText(Stream &strm, llvm::StringRef word_text, while (!text.empty()) { if (text.front() == '\n' || - (text.front() == ' ' && nextWordLength(text.ltrim(' ')) < chars_left)) { + (text.front() == ' ' && nextWordLength(text.ltrim(' ')) > chars_left)) { strm.EOL(); strm.Indent(); chars_left = max_columns - indent_size; @@ -2677,8 +2683,67 @@ size_t CommandInterpreter::GetProcessOutput() { return total_bytes; } +void CommandInterpreter::StartHandlingCommand() { + auto idle_state = CommandHandlingState::eIdle; + if (m_command_state.compare_exchange_strong( + idle_state, CommandHandlingState::eInProgress)) + lldbassert(m_iohandler_nesting_level == 0); + else + lldbassert(m_iohandler_nesting_level > 0); + ++m_iohandler_nesting_level; +} + +void CommandInterpreter::FinishHandlingCommand() { + lldbassert(m_iohandler_nesting_level > 0); + if (--m_iohandler_nesting_level == 0) { + auto prev_state = m_command_state.exchange(CommandHandlingState::eIdle); + lldbassert(prev_state != CommandHandlingState::eIdle); + } +} + +bool CommandInterpreter::InterruptCommand() { + auto in_progress = CommandHandlingState::eInProgress; + return m_command_state.compare_exchange_strong( + in_progress, CommandHandlingState::eInterrupted); +} + +bool CommandInterpreter::WasInterrupted() const { + bool was_interrupted = + (m_command_state == CommandHandlingState::eInterrupted); + lldbassert(!was_interrupted || m_iohandler_nesting_level > 0); + return was_interrupted; +} + +void CommandInterpreter::PrintCommandOutput(Stream &stream, + llvm::StringRef str) { + // Split the output into lines and poll for interrupt requests + const char *data = str.data(); + size_t size = str.size(); + while (size > 0 && !WasInterrupted()) { + size_t chunk_size = 0; + for (; chunk_size < size; ++chunk_size) { + lldbassert(data[chunk_size] != '\0'); + if (data[chunk_size] == '\n') { + ++chunk_size; + break; + } + } + chunk_size = stream.Write(data, chunk_size); + lldbassert(size >= chunk_size); + data += chunk_size; + size -= chunk_size; + } + if (size > 0) { + stream.Printf("\n... Interrupted.\n"); + } +} + void CommandInterpreter::IOHandlerInputComplete(IOHandler &io_handler, std::string &line) { + // If we were interrupted, bail out... + if (WasInterrupted()) + return; + const bool is_interactive = io_handler.GetIsInteractive(); if (is_interactive == false) { // When we are not interactive, don't execute blank lines. This will happen @@ -2700,6 +2765,8 @@ void CommandInterpreter::IOHandlerInputComplete(IOHandler &io_handler, line.c_str()); } + StartHandlingCommand(); + lldb_private::CommandReturnObject result; HandleCommand(line.c_str(), eLazyBoolCalculate, result); @@ -2710,18 +2777,18 @@ void CommandInterpreter::IOHandlerInputComplete(IOHandler &io_handler, if (!result.GetImmediateOutputStream()) { llvm::StringRef output = result.GetOutputData(); - if (!output.empty()) - io_handler.GetOutputStreamFile()->PutCString(output); + PrintCommandOutput(*io_handler.GetOutputStreamFile(), output); } // Now emit the command error text from the command we just executed if (!result.GetImmediateErrorStream()) { llvm::StringRef error = result.GetErrorData(); - if (!error.empty()) - io_handler.GetErrorStreamFile()->PutCString(error); + PrintCommandOutput(*io_handler.GetErrorStreamFile(), error); } } + FinishHandlingCommand(); + switch (result.GetStatus()) { case eReturnStatusInvalid: case eReturnStatusSuccessFinishNoResult: @@ -2777,6 +2844,9 @@ bool CommandInterpreter::IOHandlerInterrupt(IOHandler &io_handler) { ExecutionContext exe_ctx(GetExecutionContext()); Process *process = exe_ctx.GetProcessPtr(); + if (InterruptCommand()) + return true; + if (process) { StateType state = process->GetState(); if (StateIsRunningState(state)) { @@ -2998,7 +3068,7 @@ CommandInterpreter::ResolveCommandImpl(std::string &command_line, result.AppendRawError(error_msg.GetString()); } else { // We didn't have only one match, otherwise we wouldn't get here. - assert(num_matches == 0); + lldbassert(num_matches == 0); result.AppendErrorWithFormat("'%s' is not a valid command.\n", next_word.c_str()); } diff --git a/source/Interpreter/CommandObject.cpp b/source/Interpreter/CommandObject.cpp index f9a5b10bb4b8..98a6a941864e 100644 --- a/source/Interpreter/CommandObject.cpp +++ b/source/Interpreter/CommandObject.cpp @@ -17,8 +17,8 @@ #include <stdlib.h> #include "lldb/Core/Address.h" -#include "lldb/Core/ArchSpec.h" #include "lldb/Interpreter/Options.h" +#include "lldb/Utility/ArchSpec.h" // These are for the Sourcename completers. // FIXME: Make a separate file for the completers. @@ -57,7 +57,7 @@ llvm::StringRef CommandObject::GetHelp() { return m_cmd_help_short; } llvm::StringRef CommandObject::GetHelpLong() { return m_cmd_help_long; } llvm::StringRef CommandObject::GetSyntax() { - if (m_cmd_syntax.empty()) + if (!m_cmd_syntax.empty()) return m_cmd_syntax; StreamString syntax_str; @@ -1113,7 +1113,8 @@ CommandObject::ArgumentTableEntry CommandObject::g_arguments_data[] = { { eArgTypeWatchpointID, "watchpt-id", CommandCompletions::eNoCompletion, { nullptr, false }, "Watchpoint IDs are positive integers." }, { eArgTypeWatchpointIDRange, "watchpt-id-list", CommandCompletions::eNoCompletion, { nullptr, false }, "For example, '1-3' or '1 to 3'." }, { eArgTypeWatchType, "watch-type", CommandCompletions::eNoCompletion, { nullptr, false }, "Specify the type for a watchpoint." }, - { eArgRawInput, "raw-input", CommandCompletions::eNoCompletion, { nullptr, false }, "Free-form text passed to a command without prior interpretation, allowing spaces without requiring quotes. To pass arguments and free form text put two dashes ' -- ' between the last argument and any raw input." } + { eArgRawInput, "raw-input", CommandCompletions::eNoCompletion, { nullptr, false }, "Free-form text passed to a command without prior interpretation, allowing spaces without requiring quotes. To pass arguments and free form text put two dashes ' -- ' between the last argument and any raw input." }, + { eArgTypeCommand, "command", CommandCompletions::eNoCompletion, { nullptr, false }, "An LLDB Command line command." } // clang-format on }; diff --git a/source/Interpreter/OptionGroupArchitecture.cpp b/source/Interpreter/OptionGroupArchitecture.cpp index d5354fe0739c..bbd69b8f13fc 100644 --- a/source/Interpreter/OptionGroupArchitecture.cpp +++ b/source/Interpreter/OptionGroupArchitecture.cpp @@ -8,12 +8,8 @@ //===----------------------------------------------------------------------===// #include "lldb/Interpreter/OptionGroupArchitecture.h" - -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Host/OptionParser.h" +#include "lldb/Target/Platform.h" using namespace lldb; using namespace lldb_private; @@ -34,10 +30,7 @@ llvm::ArrayRef<OptionDefinition> OptionGroupArchitecture::GetDefinitions() { bool OptionGroupArchitecture::GetArchitecture(Platform *platform, ArchSpec &arch) { - if (m_arch_str.empty()) - arch.Clear(); - else - arch.SetTriple(m_arch_str.c_str(), platform); + arch = Platform::GetAugmentedArchSpec(platform, m_arch_str); return arch.IsValid(); } diff --git a/source/Interpreter/OptionGroupFormat.cpp b/source/Interpreter/OptionGroupFormat.cpp index 7c4239f92642..75d8df950f18 100644 --- a/source/Interpreter/OptionGroupFormat.cpp +++ b/source/Interpreter/OptionGroupFormat.cpp @@ -9,11 +9,6 @@ #include "lldb/Interpreter/OptionGroupFormat.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes -#include "lldb/Core/ArchSpec.h" #include "lldb/Host/OptionParser.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Target/ExecutionContext.h" diff --git a/source/Interpreter/OptionValueDictionary.cpp b/source/Interpreter/OptionValueDictionary.cpp index b245a09c1951..a57ede486319 100644 --- a/source/Interpreter/OptionValueDictionary.cpp +++ b/source/Interpreter/OptionValueDictionary.cpp @@ -227,8 +227,7 @@ OptionValueDictionary::GetSubValue(const ExecutionContext *exe_ctx, } assert(!temp.empty()); - llvm::StringRef key, value; - llvm::StringRef quote_char; + llvm::StringRef key, quote_char; if (temp[0] == '\"' || temp[0] == '\'') { quote_char = temp.take_front(); diff --git a/source/Interpreter/ScriptInterpreter.cpp b/source/Interpreter/ScriptInterpreter.cpp index 57f7eea6e4c1..497ad283f1a4 100644 --- a/source/Interpreter/ScriptInterpreter.cpp +++ b/source/Interpreter/ScriptInterpreter.cpp @@ -69,10 +69,9 @@ lldb::ScriptLanguage ScriptInterpreter::StringToLanguage(const llvm::StringRef &language) { if (language.equals_lower(LanguageToString(eScriptLanguageNone))) return eScriptLanguageNone; - else if (language.equals_lower(LanguageToString(eScriptLanguagePython))) + if (language.equals_lower(LanguageToString(eScriptLanguagePython))) return eScriptLanguagePython; - else - return eScriptLanguageUnknown; + return eScriptLanguageUnknown; } Status ScriptInterpreter::SetBreakpointCommandCallback( |