From adeaf195b669ab14e4a563dbea77cdb7a2dfd76b Mon Sep 17 00:00:00 2001 From: CismonX Date: Thu, 17 Dec 2020 15:53:20 +0800 Subject: [PATCH] Fix bugs in matcher. Improve code. --- src/ctlseqs.c | 73 ++++++++++++++++++++++++++------------------------- src/ctlseqs.h | 2 +- 2 files changed, 38 insertions(+), 37 deletions(-) diff --git a/src/ctlseqs.c b/src/ctlseqs.c index 3840903..ce36758 100644 --- a/src/ctlseqs.c +++ b/src/ctlseqs.c @@ -63,26 +63,26 @@ # define CTLSEQS_TRIE_INIT_SIZE 16 #endif // !CTLSEQS_TRIE_INIT_SIZE -#define CTLSEQS_VALUE_STR(stop_cond) \ - for (cnt = 0; ; ++cnt) { \ - num = seq_val[cnt]; \ - if (stop_cond) { \ - break; \ - } \ - } \ - buf[0].num = cnt; \ - buf[1].str = seq_val; \ - *seq = seq_val + cnt; \ - *buf_offset += 2; \ +#define CTLSEQS_VALUE_STR(stop_cond) \ + for (cnt = 0; ; ++cnt) { \ + num = seq_val[cnt]; \ + if (stop_cond) { \ + break; \ + } \ + } \ + buf_val[0].num = cnt; \ + buf_val[1].str = seq_val; \ + *seq = seq_val + cnt; \ + *buf += 2; \ return true -#define CTLSEQS_VALUE_NUM(base) \ - errno = 0; \ - num = strtoul(seq_val, seq, base); \ - if (errno != 0 || seq_val == *seq) { \ - return false; \ - } \ - buf[0].num = num; \ - *buf_offset += 1; \ +#define CTLSEQS_VALUE_NUM(base) \ + errno = 0; \ + num = strtoul(seq_val, seq, base); \ + if (errno || seq_val == *seq) { \ + return false; \ + } \ + buf_val[0].num = num; \ + ++*buf; \ return true enum ctlseqs_placeholder { @@ -120,9 +120,9 @@ struct ctlseqs_trie_node { struct ctlseqs_match_ctx { ssize_t value; - size_t result_idx; struct ctlseqs_trie_node const *node; char *rbuf; + union ctlseqs_value *result; }; struct ctlseqs_matcher { @@ -233,29 +233,29 @@ ctlseqs_state_transition(enum ctlseqs_state state, char ch) } CTLSEQS_HOT static bool -ctlseqs_fetch(char **seq, int type, union ctlseqs_value *buf, size_t *buf_offset) +ctlseqs_fetch(char **seq, int type, union ctlseqs_value **buf) { unsigned long cnt, num; char *seq_val = *seq; - buf += *buf_offset; + union ctlseqs_value *buf_val = *buf; switch (type) { case ctlseqs_ph_num: CTLSEQS_VALUE_NUM(10); case ctlseqs_ph_nums: for (cnt = 1; ; ++cnt) { + errno = 0; num = strtoul(seq_val, seq, 10); - if (errno != 0 || seq_val == *seq) { + if (errno || seq_val == *seq) { return false; } - buf[cnt].num = num; - if (seq_val[0] == ';') { - ++seq_val; - } else { + buf_val[cnt].num = num; + if ((*seq)[0] != ';') { break; } + seq_val = *seq + 1; } - buf[0].num = cnt; - *buf_offset += 1; + buf_val[0].num = cnt; + *buf += cnt + 1; return true; case ctlseqs_ph_str: CTLSEQS_VALUE_STR(num < ' ' || num > '~'); @@ -280,8 +280,9 @@ ctlseqs_match_pattern(struct ctlseqs_reader *reader, struct ctlseqs_matcher cons { struct ctlseqs_trie_node const *old_node, empty_node = { 0 }; struct ctlseqs_match_ctx match_ctx = { - .node = matcher == NULL ? &empty_node : &matcher->root, - .rbuf = reader->rbuf + reader->buf_start + 1, + .node = matcher == NULL ? &empty_node : &matcher->root, + .rbuf = reader->rbuf + reader->buf_start + 1, + .result = reader->buffer, }; ssize_t match_stack_top = -1; while (true) { @@ -298,12 +299,12 @@ ctlseqs_match_pattern(struct ctlseqs_reader *reader, struct ctlseqs_matcher cons match_ctx.node = match_ctx.node->children[-match_ctx.value]; struct ctlseqs_trie_node *next_node = match_ctx.node->next; matcher->match_stack[++match_stack_top] = (struct ctlseqs_match_ctx) { - .value = next_node == NULL ? 0 : -next_node->placeholder, - .node = old_node, - .rbuf = match_ctx.rbuf, - .result_idx = match_ctx.result_idx, + .value = next_node == NULL ? 0 : -next_node->placeholder, + .node = old_node, + .rbuf = match_ctx.rbuf, + .result = match_ctx.result, }; - if (!ctlseqs_fetch(&match_ctx.rbuf, -match_ctx.value, reader->buffer, &match_ctx.result_idx)) { + if (!ctlseqs_fetch(&match_ctx.rbuf, -match_ctx.value, &match_ctx.result)) { break; } } else { diff --git a/src/ctlseqs.h b/src/ctlseqs.h index 0a17ec5..b04a712 100644 --- a/src/ctlseqs.h +++ b/src/ctlseqs.h @@ -287,7 +287,7 @@ // XTGETTCAP response message #define CTLSEQS_RESP_XTGETTCAP(n, s) CTLSEQS_DCS n "+r" s CTLSEQS_ST // Primary DA response message -#define CTLSEQS_RESP_PRIMARY_DA(ns) CTLSEQS_CSI ns "c" +#define CTLSEQS_RESP_PRIMARY_DA(ns) CTLSEQS_CSI "?" ns "c" // Secondary DA response message #define CTLSEQS_RESP_SECONDARY_DA(n1, n2, n3) CTLSEQS_CSI ">" n1 ";" n2 ";" n3 "c" // DECLRP response message