From a47c6f78eb070474986a01d859f59c13deafee7c Mon Sep 17 00:00:00 2001 From: CismonX Date: Thu, 3 Dec 2020 14:15:04 +0800 Subject: [PATCH] Fix bugs. --- src/ctlseqs.c | 52 +++++++++++++++++++++++++++++---------------------- 1 file changed, 30 insertions(+), 22 deletions(-) diff --git a/src/ctlseqs.c b/src/ctlseqs.c index 7512946..427fee3 100644 --- a/src/ctlseqs.c +++ b/src/ctlseqs.c @@ -178,7 +178,7 @@ ctlseqs_do_read(struct ctlseqs_reader *reader) } CTLSEQS_HOT static enum ctlseqs_state -ctlseqs_state_transit(enum ctlseqs_state state, char ch) +ctlseqs_state_transition(enum ctlseqs_state state, char ch) { switch (state) { case ctlseqs_state_none: @@ -203,8 +203,10 @@ ctlseqs_state_transit(enum ctlseqs_state state, char ch) case ctlseqs_state_csi: if (ch >= '0' && ch <= '?') { return state; + } else if (ch >= ' ' && ch <= '/') { + return ctlseqs_state_csi_intmd; } - return (ch >= ' ' && ch <= '/') ? ctlseqs_state_csi_intmd : ctlseqs_state_err; + return (ch >= '@' && ch <= '~') ? ctlseqs_state_done : ctlseqs_state_err; case ctlseqs_state_csi_intmd: if (ch >= ' ' && ch <= '/') { return state; @@ -215,9 +217,8 @@ ctlseqs_state_transit(enum ctlseqs_state state, char ch) return ctlseqs_state_str_end; } else if (ch < 0x08 || ch > '~' || (ch > 0x0d && ch < ' ')) { return ctlseqs_state_err; - } else { - return state; } + return state; case ctlseqs_state_ss: return (ch >= ' ' && ch <= '~') ? ctlseqs_state_done : ctlseqs_state_err; case ctlseqs_state_ctlstr: @@ -321,15 +322,20 @@ ctlseqs_match_pattern(struct ctlseqs_reader *reader, struct ctlseqs_matcher cons } CTLSEQS_HOT static ssize_t -ctlseqs_match(struct ctlseqs_reader *reader, struct ctlseqs_matcher const *matcher) +ctlseqs_match(struct ctlseqs_reader *reader, struct ctlseqs_matcher const *matcher, bool retain_partial) { ssize_t retval = CTLSEQS_PARTIAL; char const *buf = reader->rbuf + reader->buf_start; size_t idx, len = reader->buf_end - reader->buf_start; enum ctlseqs_state state = reader->state; for (idx = 0; idx < len; ++idx) { - state = ctlseqs_state_transit(state, buf[idx]); + state = ctlseqs_state_transition(state, buf[idx]); if (state == ctlseqs_state_err) { + for (; idx < len; ++idx) { + if (buf[idx] == 0x1b) { + break; + } + } retval = CTLSEQS_NOSEQ; break; } @@ -339,16 +345,11 @@ ctlseqs_match(struct ctlseqs_reader *reader, struct ctlseqs_matcher const *match } } if (retval == CTLSEQS_PARTIAL || retval == CTLSEQS_NOSEQ) { - for (; idx < len; ++idx) { - if (buf[idx] == 0x1b) { - break; - } - } reader->buffer[0].num = idx; reader->buffer[1].str = buf; } reader->state = state; - if (!reader->retain_partial || retval != CTLSEQS_PARTIAL) { + if (!retain_partial || retval != CTLSEQS_PARTIAL) { reader->buf_start += idx; } if (reader->buf_start == reader->buf_end) { @@ -477,23 +478,30 @@ ctlseqs_reader_setopt(struct ctlseqs_reader *reader, struct ctlseqs_reader_opts CTLSEQS_HOT ssize_t ctlseqs_read(struct ctlseqs_reader *reader, struct ctlseqs_matcher const *matcher, int timeout) { + ssize_t match_result; if (reader->buf_start != 0) { - ssize_t match_result = ctlseqs_match(reader, matcher); - if (match_result >= 0) { - return match_result; + match_result = ctlseqs_match(reader, matcher, true); + if (match_result != CTLSEQS_PARTIAL) { + goto terminate; } } if (!reader->no_poll) { - int poll_result = ctlseqs_poll(&reader->pollfd, timeout); - if (poll_result < 0) { - return poll_result; + match_result = ctlseqs_poll(&reader->pollfd, timeout); + if (match_result < 0) { + goto terminate; } } - int read_result = ctlseqs_do_read(reader); - if (CTLSEQS_UNLIKELY(read_result < 0)) { - return read_result; + match_result = ctlseqs_do_read(reader); + if (CTLSEQS_UNLIKELY(match_result < 0)) { + if (match_result == CTLSEQS_TIMEOUT && reader->state != ctlseqs_state_none) { + match_result = CTLSEQS_PARTIAL; + } + goto terminate; } - return ctlseqs_match(reader, matcher); + match_result = ctlseqs_match(reader, matcher, reader->retain_partial); + terminate: + reader->state = ctlseqs_state_none; + return match_result; } CTLSEQS_COLD void