[git commit] hexedit: smarter redraw

Denys Vlasenko vda.linux at googlemail.com
Wed Sep 13 19:38:55 UTC 2017


commit: https://git.busybox.net/busybox/commit/?id=136946c3ea6a14d391b5045b5eb71fa8ec207077
branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master

function                                             old     new   delta
format_line                                          197     209     +12
hexedit_main                                         930     924      -6
redraw_cur_line                                      104      94     -10
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/2 up/down: 12/-16)             Total: -4 bytes

Signed-off-by: Denys Vlasenko <vda.linux at googlemail.com>
---
 miscutils/hexedit.c | 67 ++++++++++++++++++++++++++++++++---------------------
 1 file changed, 41 insertions(+), 26 deletions(-)

diff --git a/miscutils/hexedit.c b/miscutils/hexedit.c
index cd4b3b1..ac38978 100644
--- a/miscutils/hexedit.c
+++ b/miscutils/hexedit.c
@@ -38,11 +38,27 @@ struct globals {
 /* Hopefully there aren't arches with PAGE_SIZE > 64k */
 #define G_mapsize (64*1024)
 
-static void format_line(char *hex, uint8_t *data, off_t offset)
+/* "12ef5670 (nn )*16 abcdef_1_3_5_7_9\n" */
+#define LINEBUF_SIZE (8 + 1 + 3*16 + 16 + 1 /*paranoia:*/ + 14)
+
+static int format_line(char *hex, uint8_t *data, off_t offset)
 {
-	char *text = hex + 16*3;
+	int ofs_pos;
+	char *text;
 	uint8_t *end, *end1;
 
+#if 1
+	/* Can be more than 4Gb, thus >8 chars, thus use a variable - don't assume 8! */
+	ofs_pos = sprintf(hex, "%08"OFF_FMT"x ", offset);
+#else
+	if (offset <= 0xffff)
+		ofs_pos = sprintf(hex, "%04"OFF_FMT"x ", offset);
+	else
+		ofs_pos = sprintf(hex, "%08"OFF_FMT"x ", offset);
+#endif
+	hex += ofs_pos;
+
+	text = hex + 16*3;
 	end1 = data + 15;
 	if ((G.size - offset) > 0) {
 		end = end1;
@@ -66,6 +82,8 @@ static void format_line(char *hex, uint8_t *data, off_t offset)
 		data++;
 	}
 	*text = '\0';
+
+	return ofs_pos;
 }
 
 static void redraw(void)
@@ -78,11 +96,11 @@ static void redraw(void)
 	offset = 0;
 	i = 0;
 	while (i < G.height) {
-		char buf[16*4 + 8];
+		char buf[LINEBUF_SIZE];
 		format_line(buf, data, offset);
 		printf(
-			"\r\n%08"OFF_FMT"x %s" + (!i)*2, /* print \r\n only on 2nd line and later */
-			offset, buf
+			"\r\n%s" + (!i)*2, /* print \r\n only on 2nd line and later */
+			buf
 		);
 		data += 16;
 		offset += 16;
@@ -92,22 +110,22 @@ static void redraw(void)
 
 static void redraw_cur_line(void)
 {
-	off_t offset;
-	int len;
-	char buf[16*4 + 8];
+	char buf[LINEBUF_SIZE];
 	uint8_t *data;
+	off_t offset;
+	int column;
 
-	len = (0xf & (uintptr_t)G.current_byte);
-	data = G.current_byte - len;
+	column = (0xf & (uintptr_t)G.current_byte);
+	data = G.current_byte - column;
 	offset = G.offset + (data - G.addr);
-	format_line(buf, data, offset);
-	printf(
-		"\r%08"OFF_FMT"x %s",
-		offset, buf
-	);
-	printf(
-		"\r%08"OFF_FMT"x %.*s",
-		offset, (len*3 + G.half), buf
+
+	column = column*3 + G.half;
+	column += format_line(buf, data, offset);
+	printf("%s"
+		"\r"
+		"%.*s",
+		buf + column,
+		column, buf
 	);
 }
 
@@ -216,7 +234,7 @@ int hexedit_main(int argc UNUSED_PARAM, char **argv)
 
 	printf(CLEAR);
 	redraw();
-	printf(HOME "%08x ", 0);
+	printf(ESC"[1;10H"); /* position on 1st hex byte in first line */
 
 //TODO: //PgUp/PgDown; Home/End: start/end of line; '<'/'>': start/end of file
 	//Backspace: undo
@@ -229,10 +247,6 @@ int hexedit_main(int argc UNUSED_PARAM, char **argv)
 //TODO: detect window resize
 //TODO: read-only mode if open(O_RDWR) fails? hide cursor in this case?
 
-//TODO: smarter redraw: if down-arrow is pressed on last visible line,
-//emit LF, then print the tail of next line, then CR, then beginning -
-//which makes cursor end up exactly where it should be! Same for up-arrow.
-
 	for (;;) {
 		char read_key_buffer[KEYCODE_BUFFER_SIZE];
 		int32_t key;
@@ -320,10 +334,11 @@ int hexedit_main(int argc UNUSED_PARAM, char **argv)
 			}
 			if ((0xf & (uintptr_t)G.current_byte) == 0) {
 				/* leftmost pos, wrap to prev line */
-				if (G.current_byte == G.addr)
+				if (G.current_byte == G.addr) {
 					move_mapping_lower();
-				if ((G.current_byte - G.addr) < 16)
-					break; /* first line, don't do anything */
+					if (G.current_byte == G.addr)
+						break; /* first line, don't do anything */
+				}
 				G.half = 1;
 				G.current_byte--;
 				printf(ESC"[46C"); /* cursor right 3*15 + 1 chars */


More information about the busybox-cvs mailing list