[prev in list] [next in list] [prev in thread] [next in thread] 

List:       busybox
Subject:    [PATCH v4r 1/2] less: fully implement -R and print color escapes
From:       FriendlyNeighborhoodShane <shane.880088.supw () gmail ! com>
Date:       2022-05-10 15:20:09
Message-ID: 20220510150810.10594-2-shane.880088.supw () gmail ! com
[Download RAW message or body]

The earlier implementation used to just strip color escapes. This makes them
output 'raw', coloring the screen. Like less, it assumes that the codes don't
move the cursor. Emits NORMAL at newlines, like less, to deal with malformed
input.

count_colctrl() counts the number of chars in the next ANSI-SGR [1] escape,
essentially matching for "\033\[[0-9;]*m".

Doesn't work in regex find mode, but neither does the normal escape
highlighting.

[1] https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_(Select_Graphic_Rendition)_parameters

Signed-off-by: FriendlyNeighborhoodShane <shane.880088.supw@gmail.com>
---
 miscutils/less.c | 54 +++++++++++++++++++++++++++---------------------
 1 file changed, 30 insertions(+), 24 deletions(-)

diff --git a/miscutils/less.c b/miscutils/less.c
index 8a0525cb7..1e2c4c5cf 100644
--- a/miscutils/less.c
+++ b/miscutils/less.c
@@ -139,7 +139,7 @@
 //usage:     "\n	-S	Truncate long lines"
 //usage:	)
 //usage:	IF_FEATURE_LESS_RAW(
-//usage:     "\n	-R	Remove color escape codes in input"
+//usage:     "\n	-R	Output 'raw' color escape codes"
 //usage:	)
 //usage:     "\n	-~	Suppress ~s displayed past EOF"
 
@@ -229,9 +229,6 @@ struct globals {
 	regex_t pattern;
 	smallint pattern_valid;
 #endif
-#if ENABLE_FEATURE_LESS_RAW
-	smallint in_escape;
-#endif
 #if ENABLE_FEATURE_LESS_ASK_TERMINAL
 	smallint winsize_err;
 #endif
@@ -541,26 +538,6 @@ static void read_lines(void)
 				*--p = '\0';
 				continue;
 			}
-#if ENABLE_FEATURE_LESS_RAW
-			if (option_mask32 & FLAG_R) {
-				if (c == '\033')
-					goto discard;
-				if (G.in_escape) {
-					if (isdigit(c)
-					 || c == '['
-					 || c == ';'
-					 || c == 'm'
-					) {
- discard:
-						G.in_escape = (c != 'm');
-						readpos++;
-						continue;
-					}
-					/* Hmm, unexpected end of "ESC [ N ; N m" sequence */
-					G.in_escape = 0;
-				}
-			}
-#endif
 			{
 				size_t new_last_line_pos = last_line_pos + 1;
 				if (c == '\t') {
@@ -864,13 +841,34 @@ static void print_found(const char *line)
 void print_found(const char *line);
 #endif
 
+static size_t count_colctrl(const char *str)
+{
+    size_t n;
+    if (str[1] == '['
+     && (n = strspn(str+2, "0123456789;")) >= 0 // always true
+     && str[n+2] == 'm')
+        return n+3;
+    return 0;
+}
+
 static void print_ascii(const char *str)
 {
 	char buf[width+1];
 	char *p;
 	size_t n;
+#if ENABLE_FEATURE_LESS_RAW
+	size_t esc = 0;
+#endif
 
 	while (*str) {
+#if ENABLE_FEATURE_LESS_RAW
+		if (esc) {
+			printf("%.*s", (int) esc, str);
+			str += esc;
+			esc = 0;
+			continue;
+		}
+#endif
 		n = strcspn(str, controls);
 		if (n) {
 			if (!str[n]) break;
@@ -886,6 +884,13 @@ 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++ = '{';
+#if ENABLE_FEATURE_LESS_RAW
+			else if ((option_mask32 & FLAG_R)
+					 && *str == '\033'
+					 && (esc = count_colctrl(str))) {
+				break; // flush collected control chars
+			}
+#endif
 			else
 				*p++ = ctrlconv[(unsigned char)*str];
 			str++;
@@ -894,6 +899,7 @@ static void print_ascii(const char *str)
 		print_hilite(buf);
 	}
 	puts(str);
+	printf(NORMAL);
 }
 
 /* Print the buffer */
-- 
2.36.1

_______________________________________________
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic