Ted Unangst wrote: > Christian Weisgerber wrote: > > On 2015-10-23, "Ted Unangst" <t...@tedunangst.com> wrote: > > > > >> To what degree should tools like ls protect terminals from escape codes? > > > > > > I think this is beyond the scope of what ls should care about. du doesn't > > > have > > > such a check. Does the shell perform a check before tab completing? > > > > Our ksh, bash, and tcsh all escape unprintable characters. > > well, if this is a blocking issue, the putchar line is now changed to print ? > instead of any control characters. > > putchar(c >= ' ' ? c : '?');
The very latest and greatest. Not much changed. We could use a u8width() function analog of wcswidth, but len seems to do alright for the simple cases. 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 23 Oct 2015 12:39:52 -0000 @@ -410,6 +410,8 @@ traverse(int argc, char *argv[], int opt fts_close(ftsp); } +extern size_t u8len(char *); + /* * Display() takes a linked list of FTSENT structures and passes the list * along with any other necessary information to the print function. P @@ -474,8 +476,8 @@ display(FTSENT *p, FTSENT *list) continue; } } - if (cur->fts_namelen > maxlen) - maxlen = cur->fts_namelen; + if (u8len(cur->fts_name) > maxlen) + maxlen = u8len(cur->fts_name); if (needstats) { sp = cur->fts_statp; if (sp->st_blocks > maxblock) 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 24 Oct 2015 11:49:56 -0000 @@ -46,12 +46,34 @@ #include "extern.h" int +isu8cont(unsigned char c) +{ + return ((c & (0x80 | 0x40)) == 0x80); +} +size_t +u8len(const char *s) +{ + size_t len = 0; + + for (; *s; s++) + if (!isu8cont(*s)) + len++; + return len; +} + +int putname(char *name) { int len; - for (len = 0; *name; len++, name++) - putchar((!isprint((unsigned char)*name) && f_nonprint) ? '?' : *name); + for (len = 0; *name; name++) { + unsigned char c = *name; + if (!isu8cont(c)) + len++; + if (isascii(c) && !isprint(c)) + c = '?'; + putchar(c); + } return len; }