[PATCH v2] less: Add -R

Bernhard Reutner-Fischer rep.dot.nop at gmail.com
Wed Jan 22 09:52:39 UTC 2014


Let ANSI escape sequences for color go through verbatim.
git diff HEAD^ --color=always | ./busybox_unstripped less -R

v2: Also handle NNN;NNN;

Signed-off-by: Bernhard Reutner-Fischer <rep.dot.nop at gmail.com>
---
 miscutils/less.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 47 insertions(+), 9 deletions(-)

diff --git a/miscutils/less.c b/miscutils/less.c
index 506231d..5a06478 100644
--- a/miscutils/less.c
+++ b/miscutils/less.c
@@ -98,7 +98,7 @@
 //config:	  Enables "-N" command.
 
 //usage:#define less_trivial_usage
-//usage:       "[-E" IF_FEATURE_LESS_FLAGS("Mm") "Nh~I?] [FILE]..."
+//usage:       "[-E" IF_FEATURE_LESS_FLAGS("Mm") "Nh~IR?] [FILE]..."
 //usage:#define less_full_usage "\n\n"
 //usage:       "View FILE (or stdin) one screenful at a time\n"
 //usage:     "\n	-E	Quit once the end of a file is reached"
@@ -108,6 +108,7 @@
 //usage:	)
 //usage:     "\n	-N	Prefix line number to each line"
 //usage:     "\n	-I	Ignore case in all searches"
+//usage:     "\n	-R	display color escape sequences"
 //usage:     "\n	-~	Suppress ~s displayed past EOF"
 
 #include <sched.h>  /* sched_yield() */
@@ -142,7 +143,8 @@ enum {
 	FLAG_N = 1 << 3,
 	FLAG_TILDE = 1 << 4,
 	FLAG_I = 1 << 5,
-	FLAG_S = (1 << 6) * ENABLE_FEATURE_LESS_DASHCMD,
+	FLAG_R = 1 << 6,
+	FLAG_S = (1 << 7) * ENABLE_FEATURE_LESS_DASHCMD,
 /* hijack command line options variable for internal state vars */
 	LESS_STATE_MATCH_BACKWARDS = 1 << 15,
 };
@@ -677,6 +679,27 @@ static void lineno_str(char *nbuf9, const char *line)
 	}
 }
 
+/* Determine if STR points to an ANSI color escape sequence of the form:
+ * \033[NNNm
+ * where NNN is
+ *  - optional
+ *  - can consist of one or more 3-digits, optionally separated by ';'
+ */
+static int is_ansi_color(const char *str)
+{
+	if (*str && *str++ == '\033' && *str == '[') {
+		unsigned nums = 4;
+		while (nums-- && *(++str)) {
+			if (*str == 'm')
+				return 1;
+			else if (*str == ';')
+				nums = 4;
+			else if (!isdigit(*str))
+				return 0;
+		}
+	}
+	return 0;
+}
 
 #if ENABLE_FEATURE_LESS_REGEXP
 static void print_found(const char *line)
@@ -700,10 +723,18 @@ static void print_found(const char *line)
 			p += n;
 			str += n;
 		}
-		n = strspn(str, controls);
-		memset(p, '.', n);
-		p += n;
-		str += n;
+		if (option_mask32 & FLAG_R && is_ansi_color(str)) {
+			/* Let color sequences go through: \033[NNNm N is optional */
+			while (*str != 'm') {
+				*p++ = *str++;
+			}
+			*p++ = *str++;
+		} else {
+			n = strspn(str, controls);
+			memset(p, '.', n);
+			p += n;
+			str += n;
+		}
 	}
 	strcpy(p, str);
 
@@ -775,12 +806,19 @@ static void print_ascii(const char *str)
 			/* VT100's CSI, aka Meta-ESC. Who's inventor? */
 			/* I want to know who committed this sin */
 				*p++ = '{';
-			else
+			else if (option_mask32 & FLAG_R && is_ansi_color(str)) {
+				/* Let color sequences go through: \033[NNNm N is optional */
+				while (*str != 'm') {
+					*p++ = *str++;
+				}
+				*p++ = *str++;
+				break;
+			} else
 				*p++ = ctrlconv[(unsigned char)*str];
 			str++;
 		} while (--n);
 		*p = '\0';
-		print_hilite(buf);
+		printf(buf);
 	}
 	puts(str);
 }
@@ -1617,7 +1655,7 @@ int less_main(int argc, char **argv)
 	/* TODO: -x: do not interpret backspace, -xx: tab also */
 	/* -xxx: newline also */
 	/* -w N: assume width N (-xxx -w 32: hex viewer of sorts) */
-	getopt32(argv, "EMmN~I" IF_FEATURE_LESS_DASHCMD("S"));
+	getopt32(argv, "EMmN~IR" IF_FEATURE_LESS_DASHCMD("S"));
 	argc -= optind;
 	argv += optind;
 	num_files = argc;
-- 
1.8.5.2



More information about the busybox mailing list