Make it so that drivenengine never changes (only appends) output bytes.

This commit is contained in:
2022-01-06 17:24:32 -05:00
parent 3306281dcc
commit dc2237e5c1
4 changed files with 59 additions and 42 deletions

View File

@@ -3,32 +3,33 @@
Channel::Channel(DrivenEngine *de, int chid, int port, const std::string &target, bool stop) {
chid_ = chid;
sb_in_.reset(new StreamBuffer);
sb_out_.reset(new StreamBuffer);
port_ = port;
closed_ = false;
target_ = target;
readline_enabled_ = (chid == 0);
readline_enabled_ = false;
readline_lastc_ = 0;
desired_prompt_ = "";
stop_driver_ = stop;
sb_in_ = std::make_shared<StreamBuffer>();
sb_out_ = std::make_shared<StreamBuffer>();
sb_drvout_ = sb_out_;
}
void Channel::show_or_hide_command(bool ignore_sb_out) {
bool sb_out_empty = (sb_out_->fill() == 0) || ignore_sb_out;
if (!sb_out_empty || (!readline_enabled_) || (stop_driver_)) {
int ccsize = current_prompt_.size() + current_command_.size();
readline_echo_ += util::repeat_string("\b \b", ccsize);
void Channel::erase_command() {
int ccsize = current_prompt_.size() + current_command_.size();
if (ccsize > 0) {
sb_drvout_->write_bytes(util::repeat_string("\b \b", ccsize));
current_prompt_ = "";
current_command_ = "";
return;
}
}
void Channel::echo_command() {
// If the prompt has changed, erase everything and start over.
if (desired_prompt_ != current_prompt_) {
int ccsize = current_prompt_.size() + current_command_.size();
readline_echo_ += util::repeat_string("\b \b", ccsize);
readline_echo_ += desired_prompt_;
sb_drvout_->write_bytes(util::repeat_string("\b \b", ccsize));
sb_drvout_->write_bytes(desired_prompt_);
current_command_ = "";
current_prompt_ = desired_prompt_;
}
@@ -39,21 +40,20 @@ void Channel::show_or_hide_command(bool ignore_sb_out) {
// Echo backspaces to remove the non-matching part.
int remove = current_command_.size() - match;
if (remove > 0) {
readline_echo_ += util::repeat_string("\b \b", remove);
sb_drvout_->write_bytes(util::repeat_string("\b \b", remove));
current_command_ = current_command_.substr(0, match);
}
// Echo the new part.
std::string newpart = desired_command_.substr(current_command_.size());
if (newpart != "") {
readline_echo_ += newpart;
sb_drvout_->write_bytes(newpart);
current_command_ = desired_command_;
}
}
void Channel::set_prompt(const std::string &p) {
desired_prompt_ = p;
show_or_hide_command(false);
}
void Channel::feed_readline(int nbytes, const char *bytes) {
@@ -63,8 +63,8 @@ void Channel::feed_readline(int nbytes, const char *bytes) {
// Ignore newline immediately after carriage return.
// Otherwise, crlf produces two newlines.
} else if ((c == '\r') || (c == '\n')) {
show_or_hide_command(true);
readline_echo_ = readline_echo_ + " \n";
echo_command();
sb_drvout_->write_bytes(std::string(" \n"));
sb_in_->write_bytes(desired_command_);
sb_in_->write_uint8('\n');
desired_command_ = "";
@@ -86,35 +86,33 @@ void Channel::feed_readline(int nbytes, const char *bytes) {
}
void Channel::peek_outgoing(int *nbytes, const char **bytes) {
show_or_hide_command(false);
if (readline_echo_.size() > 0) {
*nbytes = readline_echo_.size();
*bytes = readline_echo_.c_str();
} else {
*nbytes = sb_out_->fill();
*bytes = sb_out_->data();
if (readline_enabled_) {
if (!sb_out_->empty()) {
erase_command();
sb_out_->transfer_into(sb_drvout_.get());
}
echo_command();
}
*nbytes = sb_drvout_->fill();
*bytes = sb_drvout_->data();
}
void Channel::sent_outgoing(int nbytes) {
if (nbytes > 0) {
if (readline_echo_.size() > 0) {
if (nbytes < int(readline_echo_.size())) {
readline_echo_ = readline_echo_.substr(nbytes);
return;
}
nbytes -= readline_echo_.size();
readline_echo_ = "";
}
sb_out_->read_bytes(nbytes);
}
sb_drvout_->read_bytes(nbytes);
}
void Channel::set_readline(bool e) {
if (e != readline_enabled_) {
readline_enabled_ = e;
if (readline_enabled_) {
sb_drvout_ = std::make_shared<StreamBuffer>();
} else {
sb_out_->transfer_into(sb_drvout_.get());
sb_out_->clear();
sb_drvout_->transfer_into(sb_out_.get());
sb_drvout_ = sb_out_;
}
desired_command_ = "";
show_or_hide_command(false);
}
}
@@ -196,7 +194,9 @@ const std::string &DrivenEngine::drv_get_target(int chid) {
}
bool DrivenEngine::drv_outgoing_empty(int chid) {
return get_chid(chid)->sb_out_->empty();
int nbytes; const char *bytes;
drv_peek_outgoing(chid, &nbytes, &bytes);
return (nbytes > 0);
}
bool DrivenEngine::drv_get_channel_released(int chid) {
@@ -264,6 +264,7 @@ bool DrivenEngine::drv_get_stop_driver() {
DrivenEngine::DrivenEngine() {
next_unused_chid_ = 1;
stdio_channel_ = std::make_shared<Channel>(this, 0, 0, "", false);
stdio_channel_->set_readline(true);
channels_[0] = stdio_channel_;
rescan_lua_source_ = true;
clock_ = 0.0;