"Ted Unangst" writes: > it only gets deeper and thicker... Indeed.
Here's a shorter implementation. Like colorls(1), it uses wide characters (only within the putname() function) but is slightly cleaned up and simplified. Index: ls.c =================================================================== RCS file: /cvs/src/bin/ls/ls.c,v retrieving revision 1.43 diff -u -p -r1.43 ls.c --- ls.c 9 Oct 2015 01:37:06 -0000 1.43 +++ ls.c 26 Oct 2015 21:53:40 -0000 @@ -48,6 +48,7 @@ #include <string.h> #include <unistd.h> #include <limits.h> +#include <locale.h> #include <util.h> #include "ls.h" @@ -102,6 +103,8 @@ ls_main(int argc, char *argv[]) int ch, fts_options, notused; int kflag = 0, width = 0; char *p; + + setlocale(LC_CTYPE, ""); /* Terminal defaults to -Cq, non-terminal defaults to -1. */ if (isatty(STDOUT_FILENO)) { Index: util.c =================================================================== RCS file: /cvs/src/bin/ls/util.c,v retrieving revision 1.16 diff -u -p -r1.16 util.c --- util.c 21 Nov 2013 15:54:45 -0000 1.16 +++ util.c 26 Oct 2015 21:53:40 -0000 @@ -41,10 +41,13 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <wchar.h> +#include <wctype.h> #include "ls.h" #include "extern.h" +#ifdef SMALL int putname(char *name) { @@ -54,6 +57,33 @@ putname(char *name) putchar((!isprint((unsigned char)*name) && f_nonprint) ? '?' : *name); return len; } +#else +int +putname(char *name) +{ + int width, n; + wchar_t wc; + + width = 0; + while ((n = mbtowc(&wc, name, MB_CUR_MAX)) != 0) { + if (n == -1) { + width++; + name++; + putchar('?'); + } else if (iswprint(wc)) { + width += wcwidth(wc); + name += n; + printf("%lc", wc); + } else { + width++; + name += n; + putchar('?'); + } + } + + return width; +} +#endif void usage(void)