From 136946c3ea6a14d391b5045b5eb71fa8ec207077 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Wed, 13 Sep 2017 21:38:55 +0200 Subject: hexedit: smarter redraw 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 --- miscutils/hexedit.c | 67 ++++++++++++++++++++++++++++++++--------------------- 1 file changed, 41 insertions(+), 26 deletions(-) (limited to 'miscutils/hexedit.c') diff --git a/miscutils/hexedit.c b/miscutils/hexedit.c index cd4b3b1ad..ac38978fd 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 */ -- cgit v1.2.3