From 28b79a2c8868430cf536a5a7d356ae33d9afb761 Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Sat, 16 Mar 2019 15:49:35 -0700 Subject: [PATCH] Some further steps towards removing R_NULL Introduce char_event_type_t::check_exit to represent "check for exit" instead of R_NULL. --- src/input.cpp | 14 +++++++------- src/input.h | 4 ++-- src/input_common.cpp | 14 ++++++++------ src/input_common.h | 10 +++++++--- src/reader.cpp | 2 +- 5 files changed, 25 insertions(+), 19 deletions(-) diff --git a/src/input.cpp b/src/input.cpp index 4687ef283..f344694f3 100644 --- a/src/input.cpp +++ b/src/input.cpp @@ -348,12 +348,12 @@ static void input_mapping_execute(const input_mapping_t &m, bool allow_commands) } if (has_commands && !allow_commands) { - // We don't want to run commands yet. Put the characters back and return R_NULL. + // We don't want to run commands yet. Put the characters back and return check_exit. for (wcstring::const_reverse_iterator it = m.seq.rbegin(), end = m.seq.rend(); it != end; ++it) { input_common_next_ch(*it); } - input_common_next_ch(R_NULL); + input_common_next_ch(char_event_type_t::check_exit); return; // skip the input_set_bind_mode } else if (has_functions && !has_commands) { // Functions are added at the head of the input queue. @@ -374,11 +374,11 @@ static void input_mapping_execute(const input_mapping_t &m, bool allow_commands) parser_t::principal_parser().eval(cmd, io_chain_t(), TOP); } proc_set_last_statuses(std::move(last_statuses)); - input_common_next_ch(R_NULL); + input_common_next_ch(char_event_type_t::check_exit); } else { // Invalid binding, mixed commands and functions. We would need to execute these one by // one. - input_common_next_ch(R_NULL); + input_common_next_ch(char_event_type_t::check_exit); } // Empty bind mode indicates to not reset the mode (#2871) @@ -504,9 +504,9 @@ char_event_t input_readch(bool allow_commands) { } else { input_common_next_ch(evt); input_mapping_execute_matching_or_generic(allow_commands); - // Regarding allow_commands, we're in a loop, but if a fish command - // is executed, R_NULL is unread, so the next pass through the loop - // we'll break out and return it. + // Regarding allow_commands, we're in a loop, but if a fish command is executed, + // check_exit is unread, so the next pass through the loop we'll break out and return + // it. } } } diff --git a/src/input.h b/src/input.h index fc20d24db..a5d582306 100644 --- a/src/input.h +++ b/src/input.h @@ -31,8 +31,8 @@ void init_input(); /// key press, and is returned as such. /// /// The argument determines whether fish commands are allowed to be run as bindings. If false, when -/// a character is encountered that would invoke a fish command, it is unread and R_NULL is -/// returned. +/// a character is encountered that would invoke a fish command, it is unread and +/// char_event_type_t::check_exit is returned. char_event_t input_readch(bool allow_commands = true); /// Enqueue a character or a readline function to the queue of unread characters that input_readch diff --git a/src/input_common.cpp b/src/input_common.cpp index f344232a1..d71bbb91f 100644 --- a/src/input_common.cpp +++ b/src/input_common.cpp @@ -50,10 +50,12 @@ static char_event_t lookahead_pop() { } /// \return the next lookahead char, or none if none. Discards timeouts. -static maybe_t lookahead_pop_char() { +static maybe_t lookahead_pop_evt() { while (has_lookahead()) { auto evt = lookahead_pop(); - if (evt.is_char()) return evt.get_char(); + if (! evt.is_timeout()) { + return evt; + } } return none(); } @@ -116,7 +118,7 @@ static char_event_t readb() { if (interrupt_handler) { if (auto interrupt_evt = interrupt_handler()) { return *interrupt_evt; - } else if (auto mc = lookahead_pop_char()) { + } else if (auto mc = lookahead_pop_evt()) { return *mc; } } @@ -142,7 +144,7 @@ static char_event_t readb() { if (ioport > 0 && FD_ISSET(ioport, &fdset)) { iothread_service_completion(); - if (auto mc = lookahead_pop_char()) { + if (auto mc = lookahead_pop_evt()) { return *mc; } } @@ -183,7 +185,7 @@ void update_wait_on_escape_ms(const environment_t &vars) { } char_event_t input_common_readch() { - if (auto mc = lookahead_pop_char()) { + if (auto mc = lookahead_pop_evt()) { return *mc; } wchar_t res; @@ -208,7 +210,7 @@ char_event_t input_common_readch() { case (size_t)(-1): { std::memset(&state, '\0', sizeof(state)); debug(2, L"Illegal input"); - return R_NULL; + return char_event_type_t::check_exit; } case (size_t)(-2): { break; diff --git a/src/input_common.h b/src/input_common.h index 2dc302383..51aa41f60 100644 --- a/src/input_common.h +++ b/src/input_common.h @@ -11,8 +11,6 @@ enum { R_MIN = INPUT_COMMON_BASE, - // R_NULL is sometimes returned by the input when a character was requested but none could be - // delivered, or when an exception happened. R_NULL = R_MIN, R_BEGINNING_OF_LINE, @@ -89,7 +87,11 @@ enum class char_event_type_t { timeout, /// end-of-file was reached. - eof + eof, + + /// An event was handled internally, or an interrupt was received. Check to see if the reader + /// loop should exit. + check_exit, }; class char_event_t { @@ -105,6 +107,8 @@ class char_event_t { bool is_eof() const { return type == char_event_type_t::eof; } + bool is_check_exit() const { return type == char_event_type_t::check_exit; } + bool is_readline() const { return is_char() && c_ >= R_BEGIN_INPUT_FUNCTIONS && c_ < R_END_INPUT_FUNCTIONS; } diff --git a/src/reader.cpp b/src/reader.cpp index bf2a871fb..19c455b44 100644 --- a/src/reader.cpp +++ b/src/reader.cpp @@ -2501,7 +2501,7 @@ maybe_t reader_data_t::readline(int nchars) { } } - if (!event_needing_handling) { + if (!event_needing_handling || event_needing_handling->is_check_exit()) { event_needing_handling = R_NULL; } else if (event_needing_handling->is_eof()) { reader_force_exit();