watch: interpret ANSI color code sequences
A patch from Debian. Bug-Debian: http://bugs.debian.org/129334 Backported-by: Sami Kerola <kerolasa@iki.fi>
This commit is contained in:
parent
db552d38bc
commit
39a2f5d717
7
watch.1
7
watch.1
@ -1,4 +1,4 @@
|
|||||||
.TH WATCH 1 "2009 May 11" " " "Linux User's Manual"
|
.TH WATCH 1 "2010 Mar 01" " " "Linux User's Manual"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
watch \- execute a program periodically, showing output fullscreen
|
watch \- execute a program periodically, showing output fullscreen
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
@ -8,6 +8,7 @@ watch \- execute a program periodically, showing output fullscreen
|
|||||||
.RB [ \-n
|
.RB [ \-n
|
||||||
.IR seconds ]
|
.IR seconds ]
|
||||||
.RB [ \-\-beep ]
|
.RB [ \-\-beep ]
|
||||||
|
.RB [ \-\-color ]
|
||||||
.RB [ \-\-differences[=\fIcumulative\fP]]
|
.RB [ \-\-differences[=\fIcumulative\fP]]
|
||||||
.RB [ \-\-errexit ]
|
.RB [ \-\-errexit ]
|
||||||
.RB [ \-\-exec ]
|
.RB [ \-\-exec ]
|
||||||
@ -57,6 +58,10 @@ or
|
|||||||
options, which will cause
|
options, which will cause
|
||||||
.B watch
|
.B watch
|
||||||
to exit if the return value from the program is non-zero.
|
to exit if the return value from the program is non-zero.
|
||||||
|
.PP
|
||||||
|
By default \fBwatch\fR will normally not pass escape characters, however
|
||||||
|
if you use the \fI\-\-c\fR or \fI\-\-color\fR option, then
|
||||||
|
\fBwatch\fR will interpret ANSI color sequences for the foreground.
|
||||||
|
|
||||||
.SH NOTE
|
.SH NOTE
|
||||||
Note that
|
Note that
|
||||||
|
93
watch.c
93
watch.c
@ -32,6 +32,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
static struct option longopts[] = {
|
static struct option longopts[] = {
|
||||||
|
{"color", no_argument, 0, 'c' },
|
||||||
{"differences", optional_argument, 0, 'd'},
|
{"differences", optional_argument, 0, 'd'},
|
||||||
{"help", no_argument, 0, 'h'},
|
{"help", no_argument, 0, 'h'},
|
||||||
{"interval", required_argument, 0, 'n'},
|
{"interval", required_argument, 0, 'n'},
|
||||||
@ -44,7 +45,7 @@ static struct option longopts[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static char usage[] =
|
static char usage[] =
|
||||||
"Usage: %s [-bdhntvx] [--beep] [--differences[=cumulative]] [--exec] [--help] [--interval=<n>] [--no-title] [--version] <command>\n";
|
"Usage: %s [-bdhntvx] [--beep] [--color] [--differences[=cumulative]] [--exec] [--help] [--interval=<n>] [--no-title] [--version] <command>\n";
|
||||||
|
|
||||||
static char *progname;
|
static char *progname;
|
||||||
|
|
||||||
@ -55,6 +56,74 @@ static int first_screen = 1;
|
|||||||
static int show_title = 2; // number of lines used, 2 or 0
|
static int show_title = 2; // number of lines used, 2 or 0
|
||||||
|
|
||||||
#define min(x,y) ((x) > (y) ? (y) : (x))
|
#define min(x,y) ((x) > (y) ? (y) : (x))
|
||||||
|
#define MAX_ANSIBUF 10
|
||||||
|
|
||||||
|
static void init_ansi_colors(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
short ncurses_colors[] = {
|
||||||
|
COLOR_BLACK, COLOR_RED, COLOR_GREEN, COLOR_YELLOW, COLOR_BLUE,
|
||||||
|
COLOR_MAGENTA, COLOR_CYAN, COLOR_WHITE };
|
||||||
|
|
||||||
|
for (i=0; i< 8; i++)
|
||||||
|
init_pair(i+1, ncurses_colors[i], -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void set_ansi_attribute(const int attrib)
|
||||||
|
{
|
||||||
|
switch (attrib)
|
||||||
|
{
|
||||||
|
case -1:
|
||||||
|
return;
|
||||||
|
case 0:
|
||||||
|
standend();
|
||||||
|
return;
|
||||||
|
case 1:
|
||||||
|
attrset(A_BOLD);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (attrib >= 30 && attrib <= 37) {
|
||||||
|
color_set(attrib-29,NULL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void process_ansi(FILE *fp)
|
||||||
|
{
|
||||||
|
int i,c, num1, num2;
|
||||||
|
char buf[MAX_ANSIBUF];
|
||||||
|
char *nextnum;
|
||||||
|
|
||||||
|
|
||||||
|
c= getc(fp);
|
||||||
|
if (c != '[') {
|
||||||
|
ungetc(c, fp);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for(i=0; i<MAX_ANSIBUF; i++)
|
||||||
|
{
|
||||||
|
c = getc(fp);
|
||||||
|
if (c == 'm') //COLOUR SEQUENCE ENDS in 'm'
|
||||||
|
{
|
||||||
|
buf[i] = '\0';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (c < '0' && c > '9' && c != ';')
|
||||||
|
{
|
||||||
|
while(--i >= 0)
|
||||||
|
ungetc(buf[i],fp);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
buf[i] = (char)c;
|
||||||
|
}
|
||||||
|
num1 = strtol(buf, &nextnum, 10);
|
||||||
|
if (nextnum != buf && nextnum[0] != '\0')
|
||||||
|
num2 = strtol(nextnum+1, NULL, 10);
|
||||||
|
else
|
||||||
|
num2 = -1;
|
||||||
|
set_ansi_attribute(num1);
|
||||||
|
set_ansi_attribute(num2);
|
||||||
|
}
|
||||||
|
|
||||||
static void do_usage(void) NORETURN;
|
static void do_usage(void) NORETURN;
|
||||||
static void do_usage(void)
|
static void do_usage(void)
|
||||||
@ -145,6 +214,7 @@ main(int argc, char *argv[])
|
|||||||
option_differences_cumulative = 0,
|
option_differences_cumulative = 0,
|
||||||
option_exec = 0,
|
option_exec = 0,
|
||||||
option_beep = 0,
|
option_beep = 0,
|
||||||
|
option_color = 0,
|
||||||
option_errexit = 0,
|
option_errexit = 0,
|
||||||
option_help = 0, option_version = 0;
|
option_help = 0, option_version = 0;
|
||||||
double interval = 2;
|
double interval = 2;
|
||||||
@ -158,12 +228,15 @@ main(int argc, char *argv[])
|
|||||||
setlocale(LC_ALL, "");
|
setlocale(LC_ALL, "");
|
||||||
progname = argv[0];
|
progname = argv[0];
|
||||||
|
|
||||||
while ((optc = getopt_long(argc, argv, "+bed::hn:vtx", longopts, (int *) 0))
|
while ((optc = getopt_long(argc, argv, "+bced::hn:vtx", longopts, (int *) 0))
|
||||||
!= EOF) {
|
!= EOF) {
|
||||||
switch (optc) {
|
switch (optc) {
|
||||||
case 'b':
|
case 'b':
|
||||||
option_beep = 1;
|
option_beep = 1;
|
||||||
break;
|
break;
|
||||||
|
case 'c':
|
||||||
|
option_color = 1;
|
||||||
|
break;
|
||||||
case 'd':
|
case 'd':
|
||||||
option_differences = 1;
|
option_differences = 1;
|
||||||
if (optarg)
|
if (optarg)
|
||||||
@ -251,6 +324,14 @@ main(int argc, char *argv[])
|
|||||||
/* Set up tty for curses use. */
|
/* Set up tty for curses use. */
|
||||||
curses_started = 1;
|
curses_started = 1;
|
||||||
initscr();
|
initscr();
|
||||||
|
if (option_color) {
|
||||||
|
if (has_colors()) {
|
||||||
|
start_color();
|
||||||
|
use_default_colors();
|
||||||
|
init_ansi_colors();
|
||||||
|
} else
|
||||||
|
option_color = 0;
|
||||||
|
}
|
||||||
nonl();
|
nonl();
|
||||||
noecho();
|
noecho();
|
||||||
cbreak();
|
cbreak();
|
||||||
@ -350,7 +431,13 @@ main(int argc, char *argv[])
|
|||||||
c = getc(p);
|
c = getc(p);
|
||||||
while (c != EOF && !isprint(c)
|
while (c != EOF && !isprint(c)
|
||||||
&& c != '\n'
|
&& c != '\n'
|
||||||
&& c != '\t');
|
&& c != '\t'
|
||||||
|
&& (c != L'\033' || option_color != 1));
|
||||||
|
if (c == L'\033' && option_color == 1) {
|
||||||
|
x--;
|
||||||
|
process_ansi(p);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (c == '\n')
|
if (c == '\n')
|
||||||
if (!oldeolseen && x == 0) {
|
if (!oldeolseen && x == 0) {
|
||||||
x = -1;
|
x = -1;
|
||||||
|
Loading…
Reference in New Issue
Block a user