| // Copyright 2019 The Fuchsia Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| #include "src/developer/debug/zxdb/console/mock_console.h" | |
| #include <lib/syslog/cpp/macros.h> | |
| #include "src/developer/debug/shared/message_loop.h" | |
| #include "src/developer/debug/zxdb/console/command.h" | |
| #include "src/developer/debug/zxdb/console/command_parser.h" | |
| namespace zxdb { | |
| void MockConsole::Output(const OutputBuffer& output) { | |
| output_queue_.push_back({MockConsole::OutputEvent::Type::kOutput, output}); | |
| output_buffer_.Append(output); | |
| if (waiting_for_output_) { | |
| waiting_for_output_ = false; | |
| debug_ipc::MessageLoop::Current()->QuitNow(); | |
| } | |
| } | |
| void MockConsole::Clear() { | |
| output_queue_.push_back({MockConsole::OutputEvent::Type::kClear, OutputBuffer()}); | |
| output_buffer_.Clear(); | |
| if (waiting_for_output_) { | |
| waiting_for_output_ = false; | |
| debug_ipc::MessageLoop::Current()->QuitNow(); | |
| } | |
| } | |
| MockConsole::OutputEvent MockConsole::GetOutputEvent() { | |
| FX_DCHECK(!waiting_for_output_); | |
| if (output_queue_.empty() && debug_ipc::MessageLoop::Current()) { | |
| waiting_for_output_ = true; | |
| debug_ipc::MessageLoop::Current()->Run(); | |
| } | |
| waiting_for_output_ = false; | |
| if (output_queue_.empty()) { | |
| return {MockConsole::OutputEvent::Type::kQuitEarly, OutputBuffer()}; | |
| } | |
| auto ret = std::move(output_queue_.front()); | |
| output_queue_.erase(output_queue_.begin()); | |
| return ret; | |
| } | |
| void MockConsole::FlushOutputEvents() { output_queue_.clear(); } | |
| bool MockConsole::SendModalReply(const std::string& line) { | |
| if (!last_modal_cb_) | |
| return false; | |
| // Clear callback before issuing the callback so it can issue more if necessary. | |
| auto cb = std::move(last_modal_cb_); | |
| cb(line); | |
| return true; | |
| } | |
| void MockConsole::ModalGetOption(const line_input::ModalPromptOptions& options, | |
| OutputBuffer message, const std::string& prompt, | |
| line_input::ModalLineInput::ModalCompletionCallback cb) { | |
| // Only one modal prompt is supported at a time by this mock. Otherwise things will get confused | |
| // when sending the mock reply. | |
| FX_DCHECK(!last_modal_cb_); | |
| last_modal_cb_ = std::move(cb); | |
| // Add the message to the output queue so tests can see what as printed for this prompt. | |
| Output(message); | |
| } | |
| void MockConsole::ProcessInputLine(const std::string& line, CommandCallback callback) { | |
| FX_DCHECK(!line.empty()); | |
| Command cmd; | |
| auto err = ParseCommand(line, &cmd); | |
| if (err.has_error()) { | |
| Console::Output(err); | |
| return; | |
| } | |
| err = context_.FillOutCommand(&cmd); | |
| if (err.has_error()) { | |
| Console::Output(err); | |
| return; | |
| } | |
| err = DispatchCommand(&context_, cmd, std::move(callback)); | |
| if (cmd.thread() && cmd.verb() != Verb::kNone) { | |
| // Show the right source/disassembly for the next listing. | |
| context_.SetSourceAffinityForThread(cmd.thread(), GetVerbRecord(cmd.verb())->source_affinity); | |
| } | |
| if (err.has_error()) { | |
| Console::Output(err); | |
| } | |
| } | |
| } // namespace zxdb |