From 544c1ec1614cd9a8dcedac3478701e4b97b0f8a0 Mon Sep 17 00:00:00 2001 From: Rob Landley Date: Sun, 17 Jan 2016 14:08:10 -0600 Subject: Update draw_str() and friends to do standard escaping for ^X U+ABCD. --- lib/lib.h | 6 +++--- lib/linestack.c | 61 +++++++++++++++++++++++++++++++++++----------------- toys/other/hexedit.c | 8 +++---- 3 files changed, 48 insertions(+), 27 deletions(-) diff --git a/lib/lib.h b/lib/lib.h index 0c6d3796..2338037c 100644 --- a/lib/lib.h +++ b/lib/lib.h @@ -214,9 +214,9 @@ void linestack_insert(struct linestack **lls, long pos, char *line, long len); void linestack_append(struct linestack **lls, char *line); struct linestack *linestack_load(char *name); int crunch_str(char **str, int width, FILE *out, - int (*escout)(FILE *out, wchar_t wc)); -int draw_str(char *start, int width, int (*escout)(FILE *out, wchar_t wc)); -int draw_rstr(char *start, int width, int (*escout)(FILE *out, wchar_t wc)); + int (*escout)(FILE *out, int cols, char **buf)); +int draw_str(char *start, int width); +int draw_rstr(char *start, int width); // interestingtimes.c int xgettty(void); diff --git a/lib/linestack.c b/lib/linestack.c index cc6b6724..83b0e276 100644 --- a/lib/linestack.c +++ b/lib/linestack.c @@ -76,25 +76,43 @@ struct linestack *linestack_load(char *name) return ls; } -// Show width many columns, negative means from right edge. Write unprintable -// chars through escout() instead of write(). If out=0 just measure. -// Returns width in columns. +// Show width many columns, negative means from right edge. +// If out=0 just measure +// if escout, send it unprintable chars, returns columns output or -1 for +// standard escape: ^X if <32, if invliad UTF8, U+XXXX if UTF8 !iswprint() +// Returns width in columns, moves *str to end of data consumed. int crunch_str(char **str, int width, FILE *out, - int (*escout)(FILE *out, wchar_t wc)) + int (*escout)(FILE *out, int cols, char **buf)) { - int columns = 0, col, bytes, lowlen = escout(0, 0); + int columns = 0, col, bytes; char *start, *end; for (end = start = *str; *end;) { - wchar_t wc; - - if (columns+lowlen>width) break; - - bytes = mbrtowc(&wc, end, 99, 0); - if (bytes<0 || wc<32 || (col = wcwidth(wc))<0) { - bytes = 1; - col = escout(out, *end); - } else if (out) fwrite(end, bytes, 1, out); + wchar_t wc = *end; + + bytes = 0; + if (*end >= ' ' && (bytes = mbrtowc(&wc, end, 99,0))>0 + && (col = wcwidth(wc))>=0) + { + if (width-columns(col = escout(out, width-columns, &end))) { + char buf[32]; + + tty_esc("7m"); + if (*end < ' ') { + bytes = 1; + sprintf(buf, "^%c", '@'+*end); + } else if (bytes<1) { + bytes = 1; + sprintf(buf, "<%02X>", *end); + } else sprintf(buf, "U+%04X", wc); + col = strlen(buf); + if (width-columns width) crunch_str(&s, len-width, 0, escout); - return crunch_str(&s, width, stdout, escout); + if (len > width) crunch_str(&s, len-width, 0, 0); + return crunch_str(&s, width, stdout, 0); } diff --git a/toys/other/hexedit.c b/toys/other/hexedit.c index c86d75e8..b2e32c0e 100644 --- a/toys/other/hexedit.c +++ b/toys/other/hexedit.c @@ -56,7 +56,7 @@ static void draw_tail(void) tty_jump(0, TT.height); tty_esc("K"); - draw_rstr(*toys.optargs, 71, draw_char); + draw_rstr(*toys.optargs, 71); } static void draw_line(long long yy) @@ -127,7 +127,7 @@ void hexedit_main(void) fflush(0); xset_terminal(1, 1, 0); - if ((TT.len = fdlength(fd))<0) error_exit("bad length"); + if ((TT.len = fdlength(fd))<1) error_exit("bad length"); if (sizeof(long)==32 && TT.len>SIZE_MAX) TT.len = SIZE_MAX; // count file length hex in digits, rounded up to multiple of 4 for (pos = TT.len, TT.numlen = 0; pos; pos >>= 4, TT.numlen++); @@ -139,7 +139,7 @@ void hexedit_main(void) for (;;) { // Scroll display if necessary if (pos<0) pos = 0; - if (pos>TT.len) pos = TT.len-1; + if (pos>=TT.len) pos = TT.len-1; x = pos&15; y = pos/16; @@ -214,7 +214,7 @@ void hexedit_main(void) TT.data[pos] = toybuf[sizeof(long long)*UNDO_LEN+TT.undo]; } } - if (key>256) { + if (key>=256) { key -= 256; if (key==KEY_UP) pos -= 16; -- cgit v1.2.3