From: Jim Warner Date: Sat, 30 Sep 2017 05:22:22 +0000 (-0500) Subject: top: extend utf-8 multi-byte support to users & groups X-Git-Tag: v4.0.0~694 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d2aa8009b58a2ff374df68be3f588d29ae5f3596;p=procps-ng top: extend utf-8 multi-byte support to users & groups Since all the necessary utf-8 plumbing is now in place this commit will extend multi-byte support to user and group names. Now top will be on a par with the ps guy. [ plus, it's also my way of showing appreciation for ] [ all those investments silently made by translators ] Reference(s): https://gitlab.com/procps-ng/procps/issues/68 Signed-off-by: Jim Warner --- diff --git a/top/top.c b/top/top.c index 9cf11e93..14794e5e 100644 --- a/top/top.c +++ b/top/top.c @@ -1442,6 +1442,25 @@ static inline const char *make_str (const char *str, int width, int justr, int c } // end: make_str + /* + * Make and then justify a potentially multi-byte character string, + * and include a visual clue should tuncation be necessary. */ +static inline const char *make_str_utf8 (const char *str, int width, int justr, int col) { + static char buf[SCREENMAX]; + int delta = utf8_delta(str); + + if (width >= (int)strlen(str) - delta) + snprintf(buf, sizeof(buf), "%s", str); + else { + snprintf(buf, sizeof(buf), "%.*s", utf8_embody(str, width - 1), str); + delta = utf8_delta(buf); + buf[width + delta - 1] = COLPLUSCH; + AUTOX_COL(col); + } + return justify_pad(buf, width + delta, justr); +} // end: make_str_utf8 + + /* * Do some scaling then justify stuff. * We'll interpret 'num' as a kibibytes quantity and try to @@ -5053,8 +5072,13 @@ static const char *task_show (const WIN_t *q, struct pids_stack *p) { #ifndef SCROLLVAR_NO #define makeVAR(S) { if (!q->varcolbeg) cp = make_str(S, q->varcolsz, Js, AUTOX_NO); \ else cp = make_str(q->varcolbeg < (int)strlen(S) ? S + q->varcolbeg : "", q->varcolsz, Js, AUTOX_NO); } + #define varUTF8(S) { const char *pv = S; \ + if (!q->varcolbeg) cp = make_str_utf8(pv, q->varcolsz, Js, AUTOX_NO); \ + else cp = make_str_utf8((q->varcolbeg < ((int)strlen(pv) - utf8_delta(pv))) \ + ? pv + utf8_embody(pv, q->varcolbeg) : "", q->varcolsz, Js, AUTOX_NO); } #else #define makeVAR(S) cp = make_str(S, q->varcolsz, Js, AUTOX_NO) + #define varUTF8(S) cp = make_str_utf8(S, q->varcolsz, Js, AUTOX_NO) #endif static char rbuf[ROWMINSIZ]; char *rp; @@ -5192,23 +5216,29 @@ static const char *task_show (const WIN_t *q, struct pids_stack *p) { } break; /* str, make_str (all AUTOX yes) */ - case EU_GRP: case EU_LXC: case EU_TTY: + case EU_WCH: + cp = make_str(rSv(i, str), W, Js, i); + break; + /* str, make_str_utf8 (all AUTOX yes) */ + case EU_GRP: case EU_UEN: case EU_URN: case EU_USN: - case EU_WCH: - cp = make_str(rSv(i, str), W, Js, i); + cp = make_str_utf8(rSv(i, str), W, Js, i); break; /* str, make_str with varialbe width */ case EU_CGN: case EU_CGR: case EU_ENV: case EU_SGD: - case EU_SGN: makeVAR(rSv(i, str)); break; + /* str, make_str_utf8 with varialbe width */ + case EU_SGN: + varUTF8(rSv(i, str)); + break; /* str, make_str with varialbe width + additional decoration */ case EU_CMD: makeVAR(forest_colour(q, p)); @@ -5254,6 +5284,7 @@ static const char *task_show (const WIN_t *q, struct pids_stack *p) { return rbuf; #undef rSv #undef makeVAR + #undef varUTF8 } // end: task_show diff --git a/top/top.h b/top/top.h index 1dd7d0a3..fb8fb350 100644 --- a/top/top.h +++ b/top/top.h @@ -581,6 +581,7 @@ typedef struct WIN_t { //atic inline const char *make_chr (const char ch, int width, int justr); //atic inline const char *make_num (long num, int width, int justr, int col, int noz); //atic inline const char *make_str (const char *str, int width, int justr, int col); +//atic inline const char *make_str_utf8 (const char *str, int width, int justr, int col); //atic const char *scale_mem (int target, long num, int width, int justr); //atic const char *scale_num (unsigned long num, int width, int justr); //atic const char *scale_pcnt (float num, int width, int justr);