diff options
author | Rob Landley <rob@landley.net> | 2016-03-15 02:23:50 -0500 |
---|---|---|
committer | Rob Landley <rob@landley.net> | 2016-03-15 02:23:50 -0500 |
commit | 2b999e614c48f084f6a14d589d434904aec6d491 (patch) | |
tree | c4c4fb5e6c4be3eca4fc47d7c61950a50f82d7eb /lib | |
parent | eb24df9749994d175a2de3b7fc0535abe46a7576 (diff) | |
download | toybox-2b999e614c48f084f6a14d589d434904aec6d491.tar.gz |
Add ls -b and make ls -q work with utf8.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/lib.h | 8 | ||||
-rw-r--r-- | lib/linestack.c | 92 |
2 files changed, 65 insertions, 35 deletions
@@ -223,11 +223,15 @@ void linestack_addstack(struct linestack **lls, struct linestack *throw, 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, int cols, char **buf)); +int crunch_escape(FILE *out, int cols, int wc); +int crunch_rev_escape(FILE *out, int cols, int wc); +int crunch_str(char **str, int width, FILE *out, char *escmore, + int (*escout)(FILE *out, int cols, wchar_t wc)); int draw_str(char *start, int width); int utf8len(char *str); int utf8skip(char *str, int width); +int draw_trim_esc(char *str, int padto, int width, char *escmore, + int (*escout)(FILE *out, int cols,int wc)); int draw_trim(char *str, int padto, int width); // interestingtimes.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, <XX> 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) break; - if (out) fwrite(end, bytes, 1, out); - } else if (!escout || 0>(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-columns<col) buf[col = width-columns] = 0; - if (out) fputs(buf, out); - tty_esc("27m"); - } else continue; - columns += col; - end += bytes; + if (!escmore || wc>255 || !strchr(escmore, wc)) { + if (width-columns<col) break; + if (out) fwrite(end, bytes, 1, out); + + continue; + } + } + + if (bytes<1) { + bytes = 1; + wc = *end; + } + col = width-columns; + if (col<1) break; + col = escout(out, col, wc); } *str = end; return columns; } +int crunch_escape(FILE *out, int cols, int wc) +{ + char buf[8]; + int rc; + + if (wc<' ') rc = sprintf(buf, "^%c", '@'+wc); + else if (wc<256) rc = sprintf(buf, "<%02X>", 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); +} |