Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 1 Jul 2018 05:32:04 +0000 (UTC)
From:      Daichi GOTO <daichi@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r335836 - head/usr.bin/top
Message-ID:  <201807010532.w615W44e042172@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
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);
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201807010532.w615W44e042172>