]> granicus.if.org Git - procps-ng/commitdiff
top: extend utf-8 multi-byte support to users & groups
authorJim Warner <james.warner@comcast.net>
Sat, 30 Sep 2017 05:22:22 +0000 (00:22 -0500)
committerCraig Small <csmall@enc.com.au>
Sun, 1 Oct 2017 11:35:12 +0000 (22:35 +1100)
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 <james.warner@comcast.net>
top/top.c
top/top.h

index 9cf11e9307eb73cc65c1a2665dae2b3ad64f307d..14794e5e552aebf0491872f1f74e36ed62b02dd4 100644 (file)
--- 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
 
 
index 1dd7d0a3eac80890dba8b26c8e94bb76b00c1e3b..fb8fb350cbda5ee37de0bcda144f5213a7a20924 100644 (file)
--- 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);