summaryrefslogtreecommitdiffstats
path: root/patches/procps-3.2.8/0067-watch_ansi_colour.patch
blob: 3d0b01fb96f8c8fa51644fcc4699d1dafe28731e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
From cda40ddb76fa6619d86bf675ae0cc816f16f26c9 Mon Sep 17 00:00:00 2001
From: http://ftp.de.debian.org/debian/pool/main/p/procps/procps_3.2.8-8.debian.tar.gz <info@debian.org>
Date: Fri, 19 Mar 2010 21:58:47 +0100
Subject: [PATCH 67/70] watch_ansi_colour

---
 watch.1 |    7 ++++-
 watch.c |   93 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 96 insertions(+), 4 deletions(-)

diff --git a/watch.1 b/watch.1
index c5f17c4..aecbfeb 100644
--- a/watch.1
+++ b/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 ]
@@ -75,6 +76,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
diff --git a/watch.c b/watch.c
index 7ab57ab..af7229e 100644
--- a/watch.c
+++ b/watch.c
@@ -37,6 +37,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'},
@@ -50,7 +51,7 @@ static struct option longopts[] = {
 };
 
 static char usage[] =
-    "Usage: %s [-bdhnptvx] [--beep] [--differences[=cumulative]] [--exec] [--help] [--interval=<n>] [--no-title] [--version] <command>\n";
+    "Usage: %s [-bcdhnptvx] [--beep] [--color] [--differences[=cumulative]] [--exec] [--help] [--interval=<n>] [--no-title] [--version] <command>\n";
 
 static char *progname;
 
@@ -62,6 +63,74 @@ static int show_title = 2;  // number of lines used, 2 or 0
 static int precise_timekeeping = 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)
@@ -187,6 +256,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;
@@ -205,12 +275,15 @@ main(int argc, char *argv[])
 	setlocale(LC_ALL, "");
 	progname = argv[0];
 
-	while ((optc = getopt_long(argc, argv, "+bed::hn:pvtx", longopts, (int *) 0))
+	while ((optc = getopt_long(argc, argv, "+bced::hn:pvtx", 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)
@@ -319,6 +392,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();
@@ -460,7 +541,13 @@ main(int argc, char *argv[])
 						}while (c != WEOF && !isprint(c) && c<128
 						       && wcwidth(c) == 0
 						       && c != L'\n'
-						       && c != L'\t');
+						       && c != L'\t'
+                   && (c != L'\033' || option_color != 1));
+          if (c == L'\033' && option_color == 1) {
+            x--;
+            process_ansi(p);
+            continue;
+          }
 					if (c == L'\n')
 						if (!oldeolseen && x == 0) {
 							x = -1;
-- 
1.7.0