Author: daichi
Date: Sun Jul  1 05:32:03 2018
New Revision: 335836
URL: https://svnweb.freebsd.org/changeset/base/335836

Log:
  top(1) - support UTF-8 display
  
  Reviewed by:  eadler
  Approved by:  gnn (mentor)
  Differential Revision:        https://reviews.freebsd.org/D16006

Modified:
  head/usr.bin/top/display.c
  head/usr.bin/top/machine.c
  head/usr.bin/top/top.c
  head/usr.bin/top/top.h
  head/usr.bin/top/utils.c
  head/usr.bin/top/utils.h

Modified: head/usr.bin/top/display.c
==============================================================================
--- head/usr.bin/top/display.c  Sun Jul  1 01:56:40 2018        (r335835)
+++ head/usr.bin/top/display.c  Sun Jul  1 05:32:03 2018        (r335836)
@@ -1258,19 +1258,43 @@ line_update(char *old, char *new, int start, int line)
 char *
 printable(char str[])
 {
-    char *ptr;
-    char ch;
+       char *ptr;
+       char ch;
 
-    ptr = str;
-    while ((ch = *ptr) != '\0')
-    {
-       if (!isprint(ch))
-       {
-           *ptr = '?';
+       ptr = str;
+       if (utf8flag) {
+               while ((ch = *ptr) != '\0') {
+                       if (0x00 == (0x80 & ch)) {
+                               if (!isprint(ch)) {
+                                       *ptr = '?';
+                               }
+                               ++ptr;
+                       } else if (0xC0 == (0xE0 & ch)) {
+                               ++ptr;
+                               if ('\0' != *ptr) ++ptr;
+                       } else if (0xE0 == (0xF0 & ch)) {
+                               ++ptr;
+                               if ('\0' != *ptr) ++ptr;
+                               if ('\0' != *ptr) ++ptr;
+                       } else if (0xF0 == (0xF8 & ch)) {
+                               ++ptr;
+                               if ('\0' != *ptr) ++ptr;
+                               if ('\0' != *ptr) ++ptr;
+                               if ('\0' != *ptr) ++ptr;
+                       } else {
+                               *ptr = '?';
+                               ++ptr;
+                       }
+               }
+       } else {
+               while ((ch = *ptr) != '\0') {
+                       if (!isprint(ch)) {
+                               *ptr = '?';
+                       }
+                       ptr++;
+               }
        }
-       ptr++;
-    }
-    return(str);
+       return(str);
 }
 
 void

Modified: head/usr.bin/top/machine.c
==============================================================================
--- head/usr.bin/top/machine.c  Sun Jul  1 01:56:40 2018        (r335835)
+++ head/usr.bin/top/machine.c  Sun Jul  1 05:32:03 2018        (r335836)
@@ -988,9 +988,13 @@ format_next_process(struct handle * xhandle, char *(*g
                                if (*src == '\0')
                                        continue;
                                len = (argbuflen - (dst - argbuf) - 1) / 4;
-                               strvisx(dst, src,
-                                   MIN(strlen(src), len),
-                                   VIS_NL | VIS_CSTYLE);
+                               if (utf8flag) {
+                                       utf8strvisx(dst, src, MIN(strlen(src), 
len));
+                               } else {
+                                       strvisx(dst, src,
+                                           MIN(strlen(src), len),
+                                           VIS_NL | VIS_CSTYLE);
+                               }
                                while (*dst != '\0')
                                        dst++;
                                if ((argbuflen - (dst - argbuf) - 1) / 4 > 0)

Modified: head/usr.bin/top/top.c
==============================================================================
--- head/usr.bin/top/top.c      Sun Jul  1 01:56:40 2018        (r335835)
+++ head/usr.bin/top/top.c      Sun Jul  1 05:32:03 2018        (r335836)
@@ -69,6 +69,7 @@ static int max_topn;          /* maximum displayable processes
 struct process_select ps;
 const char * myname = "top";
 pid_t mypid;
+bool utf8flag = false;
 
 /* pointers to display routines */
 static void (*d_loadave)(int mpid, double *avenrun) = i_loadave;
@@ -605,6 +606,14 @@ main(int argc, char *argv[])
        sleep(3 * warnings);
        fputc('\n', stderr);
     }
+
+       /* check if you are using UTF-8 */
+       char *env_lang;
+       if (NULL != (env_lang = getenv("LANG")) && 
+               0 != strcmp(env_lang, "") &&
+               NULL != strstr(env_lang, "UTF-8")) {
+               utf8flag = true;
+       }
 
 restart:
 

Modified: head/usr.bin/top/top.h
==============================================================================
--- head/usr.bin/top/top.h      Sun Jul  1 01:56:40 2018        (r335835)
+++ head/usr.bin/top/top.h      Sun Jul  1 05:32:03 2018        (r335836)
@@ -8,6 +8,7 @@
 #define TOP_H
 
 #include <unistd.h>
+#include <stdbool.h>
 
 /* Number of lines of header information on the standard screen */
 extern int Header_lines;
@@ -37,6 +38,7 @@ extern enum displaymodes displaymode;
 extern int pcpu_stats;
 extern int overstrike;
 extern pid_t mypid;
+extern bool utf8flag;
 
 extern const char * myname;
 

Modified: head/usr.bin/top/utils.c
==============================================================================
--- head/usr.bin/top/utils.c    Sun Jul  1 01:56:40 2018        (r335835)
+++ head/usr.bin/top/utils.c    Sun Jul  1 05:32:03 2018        (r335836)
@@ -2,6 +2,7 @@
  *  This program may be freely redistributed,
  *  but this entire comment MUST remain intact.
  *
+ *  Copyright (c) 2018, Daichi Goto
  *  Copyright (c) 2018, Eitan Adler
  *  Copyright (c) 1984, 1989, William LeFebvre, Rice University
  *  Copyright (c) 1989, 1990, 1992, William LeFebvre, Northwestern University
@@ -327,4 +328,62 @@ find_pid(pid_t pid)
 done:
        kvm_close(kd);
        return ret;
+}
+
+/*
+ * utf8strvisx(dst,src,src_len) 
+ *     strvisx(dst,src,src_len,VIS_NL|VIS_CSTYLE) coresponding to UTF-8.
+ */
+static const char *vis_encodes[] = {
+       "\\0", "\\^A", "\\^B", "\\^C", "\\^D", "\\^E", "\\^F", "\\a",
+       "\\b", "\t", "\\n", "\\v", "\\f", "\\r", "\\^N", "\\^O", "\\^P",
+       "\\^Q", "\\^R", "\\^S", "\\^T", "\\^U", "\\^V", "\\^W", "\\^X",
+       "\\^Y", "\\^Z", "\\^[", "\\^\\", "\\^]", "\\^^", "\\^_"
+};
+
+int
+utf8strvisx(char *dst, const char *src, size_t src_len)
+{
+       const char *src_p;
+       char *dst_p;
+       int i, j, olen, len;
+
+       src_p = src;
+       dst_p = dst;
+       i = olen = 0;
+       len = (int)src_len;
+       while (i < len) {
+               if (0x00 == (0x80 & *src_p)) {
+                       if (0 <= *src_p && *src_p <= 31) {
+                               j = strlen(vis_encodes[(int)*src_p]);
+                               strcpy(dst_p, vis_encodes[(int)*src_p]);
+                               dst_p += j;
+                               olen += j;
+                       } else if (127 == *src_p) {
+                               strcpy(dst_p, "\\^?");
+                               olen += 3;
+                       } else {
+                               *dst_p++ = *src_p;
+                               ++olen;
+                       }
+                       ++i;
+                       ++src_p;
+               } else if (0xC0 == (0xE0 & *src_p)) {
+                       *dst_p++ = *src_p++; ++i; ++olen;
+                       if (i < len) { *dst_p++ = *src_p++; ++i; ++olen; }
+               } else if (0xE0 == (0xF0 & *src_p)) {
+                       *dst_p++ = *src_p++; ++i; ++olen;
+                       if (i < len) { *dst_p++ = *src_p++; ++i; ++olen; }
+                       if (i < len) { *dst_p++ = *src_p++; ++i; ++olen; }
+               } else if (0xF0 == (0xF8 & *src_p)) {
+                       *dst_p++ = *src_p++; ++i; ++olen;
+                       if (i < len) { *dst_p++ = *src_p++; ++i; ++olen; }
+                       if (i < len) { *dst_p++ = *src_p++; ++i; ++olen; }
+                       if (i < len) { *dst_p++ = *src_p++; ++i; ++olen; }
+               } else {
+                       *dst_p++ = '?'; ++i; ++olen;
+               }
+       }
+
+       return olen;
 }

Modified: head/usr.bin/top/utils.h
==============================================================================
--- head/usr.bin/top/utils.h    Sun Jul  1 01:56:40 2018        (r335835)
+++ head/usr.bin/top/utils.h    Sun Jul  1 05:32:03 2018        (r335836)
@@ -22,4 +22,5 @@ const char *format_time(long);
 char *format_k(int64_t);
 int string_index(const char *string, const char * const *array);
 int find_pid(pid_t pid);
+int utf8strvisx(char *, const char *, size_t);
 
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to