top(1) - support UTF-8 display

Reviewed by:	eadler
Approved by:	gnn (mentor)
Differential Revision:	https://reviews.freebsd.org/D16006
This commit is contained in:
Daichi GOTO 2018-07-01 05:32:03 +00:00
parent 24e8c13220
commit 4417ed2dbf
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=335836
6 changed files with 113 additions and 14 deletions

View File

@ -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

View File

@ -988,9 +988,13 @@ format_next_process(struct handle * xhandle, char *(*get_userid)(int), int flags
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)

View File

@ -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;
@ -606,6 +607,14 @@ main(int argc, char *argv[])
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:
/*

View File

@ -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;

View File

@ -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
@ -328,3 +329,61 @@ find_pid(pid_t pid)
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;
}

View File

@ -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);