aboutsummaryrefslogtreecommitdiff
path: root/st.c
diff options
context:
space:
mode:
authorRoberto E. Vargas Caballero <k0ga@shike2.com>2014-04-28 18:32:09 +0200
committerRoberto E. Vargas Caballero <k0ga@shike2.com>2014-04-28 18:32:09 +0200
commit3764f38fc805a8846bd18f1d555a10227fd14e29 (patch)
tree2cdc4ea292102e561d4c2a5ae645cecef3489302 /st.c
parent53105cf74fde46229912275c073f8c0f219b05bb (diff)
downloadst-3764f38fc805a8846bd18f1d555a10227fd14e29.tar.gz
st-3764f38fc805a8846bd18f1d555a10227fd14e29.zip
Fix tputc control code handling
The patch 53105cf modified how control codes were detected, because it tried to handle also C1 control codes (0x80-0x9f), that have upper bit to 1, so they are multi byte character in utf8. Code was checking the value of width in order to known that after decoding the unicode point had a width of 1 byte, but it as incorrect because this width is the columnb width.
Diffstat (limited to 'st.c')
-rw-r--r--st.c20
1 files changed, 8 insertions, 12 deletions
diff --git a/st.c b/st.c
index 0425c72..9a979ea 100644
--- a/st.c
+++ b/st.c
@@ -70,8 +70,9 @@ char *argv0;
70#define LEN(a) (sizeof(a) / sizeof(a)[0]) 70#define LEN(a) (sizeof(a) / sizeof(a)[0])
71#define DEFAULT(a, b) (a) = (a) ? (a) : (b) 71#define DEFAULT(a, b) (a) = (a) ? (a) : (b)
72#define BETWEEN(x, a, b) ((a) <= (x) && (x) <= (b)) 72#define BETWEEN(x, a, b) ((a) <= (x) && (x) <= (b))
73#define ISCONTROLC0(c) (BETWEEN((uchar) (c), 0, 0x1f)) 73#define ISCONTROLC0(c) (BETWEEN(c, 0, 0x1f))
74#define ISCONTROLC1(c) (BETWEEN((uchar) (c), 0x80, 0x9f)) 74#define ISCONTROLC1(c) (BETWEEN(c, 0x80, 0x9f))
75#define ISCONTROL(c) (ISCONTROLC0(c) || ISCONTROLC1(c))
75#define LIMIT(x, a, b) (x) = (x) < (a) ? (a) : (x) > (b) ? (b) : (x) 76#define LIMIT(x, a, b) (x) = (x) < (a) ? (a) : (x) > (b) ? (b) : (x)
76#define ATTRCMP(a, b) ((a).mode != (b).mode || (a).fg != (b).fg || (a).bg != (b).bg) 77#define ATTRCMP(a, b) ((a).mode != (b).mode || (a).fg != (b).fg || (a).bg != (b).bg)
77#define IS_SET(flag) ((term.mode & (flag)) != 0) 78#define IS_SET(flag) ((term.mode & (flag)) != 0)
@@ -402,7 +403,6 @@ static void ttyread(void);
402static void ttyresize(void); 403static void ttyresize(void);
403static void ttysend(char *, size_t); 404static void ttysend(char *, size_t);
404static void ttywrite(const char *, size_t); 405static void ttywrite(const char *, size_t);
405static inline bool iscontrol(char);
406 406
407static void xdraws(char *, Glyph, int, int, int, int); 407static void xdraws(char *, Glyph, int, int, int, int);
408static void xhints(void); 408static void xhints(void);
@@ -2300,17 +2300,12 @@ tputtab(int n) {
2300 tmoveto(x, term.c.y); 2300 tmoveto(x, term.c.y);
2301} 2301}
2302 2302
2303static inline bool
2304iscontrol(char c) {
2305 return ISCONTROLC0(c) || ISCONTROLC1(c);
2306}
2307
2308void 2303void
2309techo(char *buf, int len) { 2304techo(char *buf, int len) {
2310 for(; len > 0; buf++, len--) { 2305 for(; len > 0; buf++, len--) {
2311 char c = *buf; 2306 char c = *buf;
2312 2307
2313 if(iscontrol(c)) { /* control code */ 2308 if(ISCONTROL(c)) { /* control code */
2314 if(c & 0x80) { 2309 if(c & 0x80) {
2315 c &= 0x7f; 2310 c &= 0x7f;
2316 tputc("^", 1); 2311 tputc("^", 1);
@@ -2439,16 +2434,17 @@ tputc(char *c, int len) {
2439 2434
2440 if(len == 1) { 2435 if(len == 1) {
2441 width = 1; 2436 width = 1;
2442 ascii = *c; 2437 unicodep = ascii = *c;
2443 } else { 2438 } else {
2444 utf8decode(c, &unicodep, UTF_SIZ); 2439 utf8decode(c, &unicodep, UTF_SIZ);
2445 width = wcwidth(unicodep); 2440 width = wcwidth(unicodep);
2441 control = ISCONTROLC1(unicodep);
2446 ascii = unicodep; 2442 ascii = unicodep;
2447 } 2443 }
2448 2444
2449 control = iscontrol(ascii) && width == 1;
2450 if(IS_SET(MODE_PRINT)) 2445 if(IS_SET(MODE_PRINT))
2451 tprinter(c, len); 2446 tprinter(c, len);
2447 control = ISCONTROL(unicodep);
2452 2448
2453 /* 2449 /*
2454 * STR sequence must be checked before anything else 2450 * STR sequence must be checked before anything else
@@ -2460,7 +2456,7 @@ tputc(char *c, int len) {
2460 if(width == 1 && 2456 if(width == 1 &&
2461 (ascii == '\a' || ascii == 030 || 2457 (ascii == '\a' || ascii == 030 ||
2462 ascii == 032 || ascii == 033 || 2458 ascii == 032 || ascii == 033 ||
2463 ISCONTROLC1(ascii))) { 2459 ISCONTROLC1(unicodep))) {
2464 term.esc &= ~ESC_STR; 2460 term.esc &= ~ESC_STR;
2465 term.esc |= ESC_STR_END; 2461 term.esc |= ESC_STR_END;
2466 } else if(strescseq.len + len < sizeof(strescseq.buf) - 1) { 2462 } else if(strescseq.len + len < sizeof(strescseq.buf) - 1) {