diff options
Diffstat (limited to 'src/escape.c')
| -rw-r--r-- | src/escape.c | 179 |
1 files changed, 103 insertions, 76 deletions
diff --git a/src/escape.c b/src/escape.c index 119010c..9576e8e 100644 --- a/src/escape.c +++ b/src/escape.c @@ -53,94 +53,123 @@ static int sgr_serialize(const struct term *t, char *buf, size_t sz) return n; } +static const signed char hex_val[256] = { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, + -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +}; + static int dcs_decode_hex(const char *s, int len, char *out, int cap) { if (len & 1) return -1; int n = 0; for (int i = 0; i < len; i += 2) { - int hi = term_hex_nib(s[i]), lo = term_hex_nib(s[i + 1]); - if (hi < 0 || lo < 0 || n >= cap) return -1; + int hi = hex_val[(unsigned char)s[i]], lo = hex_val[(unsigned char)s[i + 1]]; + if ((hi | lo) < 0 || n >= cap) return -1; out[n++] = (char)(hi << 4 | lo); } return n; } +struct tcap_entry { + const char *name, *value; +}; + +static int tcap_cmp(const void *k, const void *e) +{ + const char *key = k; + const struct tcap_entry *elem = e; + return strcmp(key, elem->name); +} + static const char *term_tcap(const struct term *t, const char *name) { - static const struct { const char *name, *value; } caps[] = { - { "Co", "16777216" }, - { "RGB", "8/8/8" }, - { "colors", "16777216" }, - { "kDC", "\x1b[3;2~" }, { "kDC3", "\x1b[3;3~" }, - { "kDC4", "\x1b[3;4~" }, { "kDC5", "\x1b[3;5~" }, - { "kDC6", "\x1b[3;6~" }, { "kDC7", "\x1b[3;7~" }, - { "kDN", "\x1b[1;2B" }, { "kDN3", "\x1b[1;3B" }, - { "kDN4", "\x1b[1;4B" }, { "kDN5", "\x1b[1;5B" }, - { "kDN6", "\x1b[1;6B" }, { "kDN7", "\x1b[1;7B" }, - { "kEND", "\x1b[1;2F" }, { "kEND3", "\x1b[1;3F" }, - { "kEND4", "\x1b[1;4F" }, { "kEND5", "\x1b[1;5F" }, - { "kEND6", "\x1b[1;6F" }, { "kEND7", "\x1b[1;7F" }, - { "kHOM", "\x1b[1;2H" }, { "kHOM3", "\x1b[1;3H" }, - { "kHOM4", "\x1b[1;4H" }, { "kHOM5", "\x1b[1;5H" }, - { "kHOM6", "\x1b[1;6H" }, { "kHOM7", "\x1b[1;7H" }, - { "kIC", "\x1b[2;2~" }, { "kIC3", "\x1b[2;3~" }, - { "kIC4", "\x1b[2;4~" }, { "kIC5", "\x1b[2;5~" }, - { "kIC6", "\x1b[2;6~" }, { "kIC7", "\x1b[2;7~" }, - { "kLFT", "\x1b[1;2D" }, { "kLFT3", "\x1b[1;3D" }, - { "kLFT4", "\x1b[1;4D" }, { "kLFT5", "\x1b[1;5D" }, - { "kLFT6", "\x1b[1;6D" }, { "kLFT7", "\x1b[1;7D" }, - { "kNXT", "\x1b[6;2~" }, { "kNXT3", "\x1b[6;3~" }, - { "kNXT4", "\x1b[6;4~" }, { "kNXT5", "\x1b[6;5~" }, - { "kNXT6", "\x1b[6;6~" }, { "kNXT7", "\x1b[6;7~" }, - { "kPRV", "\x1b[5;2~" }, { "kPRV3", "\x1b[5;3~" }, - { "kPRV4", "\x1b[5;4~" }, { "kPRV5", "\x1b[5;5~" }, - { "kPRV6", "\x1b[5;6~" }, { "kPRV7", "\x1b[5;7~" }, - { "kRIT", "\x1b[1;2C" }, { "kRIT3", "\x1b[1;3C" }, - { "kRIT4", "\x1b[1;4C" }, { "kRIT5", "\x1b[1;5C" }, - { "kRIT6", "\x1b[1;6C" }, { "kRIT7", "\x1b[1;7C" }, - { "kUP", "\x1b[1;2A" }, { "kUP3", "\x1b[1;3A" }, - { "kUP4", "\x1b[1;4A" }, { "kUP5", "\x1b[1;5A" }, - { "kUP6", "\x1b[1;6A" }, { "kUP7", "\x1b[1;7A" }, - { "kbs", "\x7f" }, { "kcbt", "\x1b[Z" }, - { "kcub1", "\x1bOD" }, { "kcud1", "\x1bOB" }, - { "kcuf1", "\x1bOC" }, { "kcuu1", "\x1bOA" }, - { "kdch1", "\x1b[3~" }, { "kend", "\x1bOF" }, - { "kent", "\x1bOM" }, { "khome", "\x1bOH" }, - { "kich1", "\x1b[2~" }, { "kind", "\x1b[1;2B" }, - { "kmous", "\x1b[<" }, { "knp", "\x1b[6~" }, - { "kpp", "\x1b[5~" }, { "kri", "\x1b[1;2A" }, - { "kxIN", "\x1b[I" }, { "kxOUT", "\x1b[O" }, - { "kf1", "\x1bOP" }, { "kf2", "\x1bOQ" }, - { "kf3", "\x1bOR" }, { "kf4", "\x1bOS" }, - { "kf5", "\x1b[15~" }, { "kf6", "\x1b[17~" }, - { "kf7", "\x1b[18~" }, { "kf8", "\x1b[19~" }, - { "kf9", "\x1b[20~" }, { "kf10", "\x1b[21~" }, - { "kf11", "\x1b[23~" }, { "kf12", "\x1b[24~" }, - { "kf13", "\x1b[1;2P" }, { "kf14", "\x1b[1;2Q" }, - { "kf15", "\x1b[1;2R" }, { "kf16", "\x1b[1;2S" }, - { "kf17", "\x1b[15;2~" }, { "kf18", "\x1b[17;2~" }, - { "kf19", "\x1b[18;2~" }, { "kf20", "\x1b[19;2~" }, - { "kf21", "\x1b[20;2~" }, { "kf22", "\x1b[21;2~" }, - { "kf23", "\x1b[23;2~" }, { "kf24", "\x1b[24;2~" }, - { "kf25", "\x1b[1;5P" }, { "kf26", "\x1b[1;5Q" }, - { "kf27", "\x1b[1;5R" }, { "kf28", "\x1b[1;5S" }, - { "kf29", "\x1b[15;5~" }, { "kf30", "\x1b[17;5~" }, - { "kf31", "\x1b[18;5~" }, { "kf32", "\x1b[19;5~" }, - { "kf33", "\x1b[20;5~" }, { "kf34", "\x1b[21;5~" }, - { "kf35", "\x1b[23;5~" }, { "kf36", "\x1b[24;5~" }, - { "kf37", "\x1b[1;6P" }, { "kf38", "\x1b[1;6Q" }, - { "kf39", "\x1b[1;6R" }, { "kf40", "\x1b[1;6S" }, - { "kf41", "\x1b[15;6~" }, { "kf42", "\x1b[17;6~" }, - { "kf43", "\x1b[18;6~" }, { "kf44", "\x1b[19;6~" }, - { "kf45", "\x1b[20;6~" }, { "kf46", "\x1b[21;6~" }, - { "kf47", "\x1b[23;6~" }, { "kf48", "\x1b[24;6~" }, + static const struct tcap_entry caps[] = { + { "Co", "16777216" }, { "RGB", "8/8/8" }, + { "colors", "16777216" }, { "kDC", "\x1b[3;2~" }, + { "kDC3", "\x1b[3;3~" }, { "kDC4", "\x1b[3;4~" }, + { "kDC5", "\x1b[3;5~" }, { "kDC6", "\x1b[3;6~" }, + { "kDC7", "\x1b[3;7~" }, { "kDN", "\x1b[1;2B" }, + { "kDN3", "\x1b[1;3B" }, { "kDN4", "\x1b[1;4B" }, + { "kDN5", "\x1b[1;5B" }, { "kDN6", "\x1b[1;6B" }, + { "kDN7", "\x1b[1;7B" }, { "kEND", "\x1b[1;2F" }, + { "kEND3", "\x1b[1;3F" }, { "kEND4", "\x1b[1;4F" }, + { "kEND5", "\x1b[1;5F" }, { "kEND6", "\x1b[1;6F" }, + { "kEND7", "\x1b[1;7F" }, { "kHOM", "\x1b[1;2H" }, + { "kHOM3", "\x1b[1;3H" }, { "kHOM4", "\x1b[1;4H" }, + { "kHOM5", "\x1b[1;5H" }, { "kHOM6", "\x1b[1;6H" }, + { "kHOM7", "\x1b[1;7H" }, { "kIC", "\x1b[2;2~" }, + { "kIC3", "\x1b[2;3~" }, { "kIC4", "\x1b[2;4~" }, + { "kIC5", "\x1b[2;5~" }, { "kIC6", "\x1b[2;6~" }, + { "kIC7", "\x1b[2;7~" }, { "kLFT", "\x1b[1;2D" }, + { "kLFT3", "\x1b[1;3D" }, { "kLFT4", "\x1b[1;4D" }, + { "kLFT5", "\x1b[1;5D" }, { "kLFT6", "\x1b[1;6D" }, + { "kLFT7", "\x1b[1;7D" }, { "kNXT", "\x1b[6;2~" }, + { "kNXT3", "\x1b[6;3~" }, { "kNXT4", "\x1b[6;4~" }, + { "kNXT5", "\x1b[6;5~" }, { "kNXT6", "\x1b[6;6~" }, + { "kNXT7", "\x1b[6;7~" }, { "kPRV", "\x1b[5;2~" }, + { "kPRV3", "\x1b[5;3~" }, { "kPRV4", "\x1b[5;4~" }, + { "kPRV5", "\x1b[5;5~" }, { "kPRV6", "\x1b[5;6~" }, + { "kPRV7", "\x1b[5;7~" }, { "kRIT", "\x1b[1;2C" }, + { "kRIT3", "\x1b[1;3C" }, { "kRIT4", "\x1b[1;4C" }, + { "kRIT5", "\x1b[1;5C" }, { "kRIT6", "\x1b[1;6C" }, + { "kRIT7", "\x1b[1;7C" }, { "kUP", "\x1b[1;2A" }, + { "kUP3", "\x1b[1;3A" }, { "kUP4", "\x1b[1;4A" }, + { "kUP5", "\x1b[1;5A" }, { "kUP6", "\x1b[1;6A" }, + { "kUP7", "\x1b[1;7A" }, { "kbs", "\x7f" }, + { "kcbt", "\x1b[Z" }, { "kcub1", "\x1bOD" }, + { "kcud1", "\x1bOB" }, { "kcuf1", "\x1bOC" }, + { "kcuu1", "\x1bOA" }, { "kdch1", "\x1b[3~" }, + { "kend", "\x1bOF" }, { "kent", "\x1bOM" }, + { "kf1", "\x1bOP" }, { "kf10", "\x1b[21~" }, + { "kf11", "\x1b[23~" }, { "kf12", "\x1b[24~" }, + { "kf13", "\x1b[1;2P" }, { "kf14", "\x1b[1;2Q" }, + { "kf15", "\x1b[1;2R" }, { "kf16", "\x1b[1;2S" }, + { "kf17", "\x1b[15;2~" }, { "kf18", "\x1b[17;2~" }, + { "kf19", "\x1b[18;2~" }, { "kf2", "\x1bOQ" }, + { "kf20", "\x1b[19;2~" }, { "kf21", "\x1b[20;2~" }, + { "kf22", "\x1b[21;2~" }, { "kf23", "\x1b[23;2~" }, + { "kf24", "\x1b[24;2~" }, { "kf25", "\x1b[1;5P" }, + { "kf26", "\x1b[1;5Q" }, { "kf27", "\x1b[1;5R" }, + { "kf28", "\x1b[1;5S" }, { "kf29", "\x1b[15;5~" }, + { "kf3", "\x1bOR" }, { "kf30", "\x1b[17;5~" }, + { "kf31", "\x1b[18;5~" }, { "kf32", "\x1b[19;5~" }, + { "kf33", "\x1b[20;5~" }, { "kf34", "\x1b[21;5~" }, + { "kf35", "\x1b[23;5~" }, { "kf36", "\x1b[24;5~" }, + { "kf37", "\x1b[1;6P" }, { "kf38", "\x1b[1;6Q" }, + { "kf39", "\x1b[1;6R" }, { "kf4", "\x1bOS" }, + { "kf40", "\x1b[1;6S" }, { "kf41", "\x1b[15;6~" }, + { "kf42", "\x1b[17;6~" }, { "kf43", "\x1b[18;6~" }, + { "kf44", "\x1b[19;6~" }, { "kf45", "\x1b[20;6~" }, + { "kf46", "\x1b[21;6~" }, { "kf47", "\x1b[23;6~" }, + { "kf48", "\x1b[24;6~" }, { "kf5", "\x1b[15~" }, + { "kf6", "\x1b[17~" }, { "kf7", "\x1b[18~" }, + { "kf8", "\x1b[19~" }, { "kf9", "\x1b[20~" }, + { "khome", "\x1bOH" }, { "kich1", "\x1b[2~" }, + { "kind", "\x1b[1;2B" }, { "kmous", "\x1b[<" }, + { "knp", "\x1b[6~" }, { "kpp", "\x1b[5~" }, + { "kri", "\x1b[1;2A" }, { "kxIN", "\x1b[I" }, + { "kxOUT", "\x1b[O" }, }; if (!strcmp(name, "TN") || !strcmp(name, "name")) return t->tcap_name; - for (size_t i = 0; i < sizeof(caps) / sizeof(caps[0]); i++) - if (!strcmp(name, caps[i].name)) - return caps[i].value; - return NULL; + const struct tcap_entry *found = bsearch(name, caps, + sizeof(caps) / sizeof(caps[0]), + sizeof(caps[0]), tcap_cmp); + return found ? found->value : NULL; } struct resp_buf { @@ -154,9 +183,7 @@ static void resp_put(struct resp_buf *r, const char *s, size_t n) if (r->failed) return; if (r->len + n + 1 > r->cap) { - size_t cap = r->cap ? r->cap : 256; - while (cap < r->len + n + 1) - cap *= 2; + size_t cap = term_grow_cap(r->cap ? r->cap : 256, r->len + n + 1); char *p = realloc(r->s, cap); if (!p) { r->failed = true; |
