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
|
||||
watch \- execute a program periodically, showing output fullscreen
|
||||
.SH SYNOPSIS
|
||||
@ -8,6 +8,7 @@ watch \- execute a program periodically, showing output fullscreen
|
||||
.RB [ \-n
|
||||
.IR seconds ]
|
||||
.RB [ \-\-beep ]
|
||||
.RB [ \-\-color ]
|
||||
.RB [ \-\-differences[=\fIcumulative\fP]]
|
||||
.RB [ \-\-errexit ]
|
||||
.RB [ \-\-exec ]
|
||||
@ -57,6 +58,10 @@ or
|
||||
options, which will cause
|
||||
.B watch
|
||||
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
|
||||
Note that
|
||||
|
93
watch.c
93
watch.c
@ -32,6 +32,7 @@
|
||||
#endif
|
||||
|
||||
static struct option longopts[] = {
|
||||
{"color", no_argument, 0, 'c' },
|
||||
{"differences", optional_argument, 0, 'd'},
|
||||
{"help", no_argument, 0, 'h'},
|
||||
{"interval", required_argument, 0, 'n'},
|
||||
@ -44,7 +45,7 @@ static struct option longopts[] = {
|
||||
};
|
||||
|
||||
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;
|
||||
|
||||
@ -55,6 +56,74 @@ static int first_screen = 1;
|
||||
static int show_title = 2; // number of lines used, 2 or 0
|
||||
|
||||
#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)
|
||||
@ -145,6 +214,7 @@ main(int argc, char *argv[])
|
||||
option_differences_cumulative = 0,
|
||||
option_exec = 0,
|
||||
option_beep = 0,
|
||||
option_color = 0,
|
||||
option_errexit = 0,
|
||||
option_help = 0, option_version = 0;
|
||||
double interval = 2;
|
||||
@ -158,12 +228,15 @@ main(int argc, char *argv[])
|
||||
setlocale(LC_ALL, "");
|
||||
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) {
|
||||
switch (optc) {
|
||||
case 'b':
|
||||
option_beep = 1;
|
||||
break;
|
||||
case 'c':
|
||||
option_color = 1;
|
||||
break;
|
||||
case 'd':
|
||||
option_differences = 1;
|
||||
if (optarg)
|
||||
@ -251,6 +324,14 @@ main(int argc, char *argv[])
|
||||
/* Set up tty for curses use. */
|
||||
curses_started = 1;
|
||||
initscr();
|
||||
if (option_color) {
|
||||
if (has_colors()) {
|
||||
start_color();
|
||||
use_default_colors();
|
||||
init_ansi_colors();
|
||||
} else
|
||||
option_color = 0;
|
||||
}
|
||||
nonl();
|
||||
noecho();
|
||||
cbreak();
|
||||
@ -350,7 +431,13 @@ main(int argc, char *argv[])
|
||||
c = getc(p);
|
||||
while (c != EOF && !isprint(c)
|
||||
&& 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 (!oldeolseen && x == 0) {
|
||||
x = -1;
|
||||
|
Loading…
Reference in New Issue
Block a user