From 2b999e614c48f084f6a14d589d434904aec6d491 Mon Sep 17 00:00:00 2001 From: Rob Landley Date: Tue, 15 Mar 2016 02:23:50 -0500 Subject: Add ls -b and make ls -q work with utf8. --- lib/linestack.c | 92 ++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 59 insertions(+), 33 deletions(-) (limited to 'lib/linestack.c') diff --git a/lib/linestack.c b/lib/linestack.c index f8ca32a4..eef790b5 100644 --- a/lib/linestack.c +++ b/lib/linestack.c @@ -81,56 +81,75 @@ struct linestack *linestack_load(char *name) // 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, int cols, char **buf)) +int crunch_str(char **str, int width, FILE *out, char *escmore, + int (*escout)(FILE *out, int cols, int wc)) { int columns = 0, col, bytes; char *start, *end; - for (end = start = *str; *end;) { - wchar_t wc = *end; + for (end = start = *str; *end; columns += col, end += bytes) { + wchar_t wc; - bytes = 0; - if (*end >= ' ' && (bytes = mbrtowc(&wc, end, 99,0))>0 - && (col = wcwidth(wc))>=0) + if ((bytes = mbrtowc(&wc, end, MB_CUR_MAX, 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", (unsigned)wc); - col = strlen(buf); - if (width-columns255 || !strchr(escmore, wc)) { + if (width-columns", wc); + else rc = sprintf(buf, "U+%04X", wc); + + if (rc > cols) buf[rc = cols] = 0; + if (out) fputs(buf, out); + + return rc; +} + +int crunch_rev_escape(FILE *out, int cols, int wc) +{ + int rc; + + tty_esc("7m"); + rc = crunch_escape(out, cols, wc); + tty_esc("27m"); + + return rc; +} + // Write width chars at start of string to strdout with standard escapes // Returns length in columns so caller can pad it out with spaces. int draw_str(char *start, int width) { - return crunch_str(&start, width, stdout, 0); + return crunch_str(&start, width, stdout, 0, crunch_rev_escape); } // Return utf8 columns int utf8len(char *str) { - return crunch_str(&str, INT_MAX, 0, 0); + return crunch_str(&str, INT_MAX, 0, 0, crunch_rev_escape); } // Return bytes used by (up to) this many columns @@ -138,14 +157,15 @@ int utf8skip(char *str, int width) { char *s = str; - crunch_str(&s, width, 0, 0); + crunch_str(&s, width, 0, 0, crunch_rev_escape); return s-str; } -// Print utf8 to stdout with standard escapes,trimmed to width and padded +// Print utf8 to stdout with standard escapes, trimmed to width and padded // out to padto. If padto<0 left justify. Returns columns printed -int draw_trim(char *str, int padto, int width) +int draw_trim_esc(char *str, int padto, int width, char *escmore, + int (*escout)(FILE *out, int cols, int wc)) { int apad = abs(padto), len = utf8len(str); @@ -154,8 +174,14 @@ int draw_trim(char *str, int padto, int width) // Left pad if right justified if (padto>0 && apad>len) printf("%*s", apad-len, ""); - crunch_str(&str, len, stdout, 0); + crunch_str(&str, len, stdout, 0, crunch_rev_escape); if (padto<0 && apad>len) printf("%*s", apad-len, ""); return (apad > len) ? apad : len; } + +// draw_trim_esc() with default escape +int draw_trim(char *str, int padto, int width) +{ + return draw_trim_esc(str, padto, width, 0, 0); +} -- cgit v1.2.3