diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2017-09-13 21:38:55 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2017-09-13 21:38:55 +0200 |
commit | 136946c3ea6a14d391b5045b5eb71fa8ec207077 (patch) | |
tree | 948d12db4fa4865f5870fb8782af98a06147d359 /miscutils/hexedit.c | |
parent | 73af705628ddaedc4c6f7f78b9658d6c01310309 (diff) | |
download | busybox-w32-136946c3ea6a14d391b5045b5eb71fa8ec207077.tar.gz busybox-w32-136946c3ea6a14d391b5045b5eb71fa8ec207077.tar.bz2 busybox-w32-136946c3ea6a14d391b5045b5eb71fa8ec207077.zip |
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 <vda.linux@googlemail.com>
Diffstat (limited to '')
-rw-r--r-- | miscutils/hexedit.c | 67 |
1 files changed, 41 insertions, 26 deletions
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 { | |||
38 | /* Hopefully there aren't arches with PAGE_SIZE > 64k */ | 38 | /* Hopefully there aren't arches with PAGE_SIZE > 64k */ |
39 | #define G_mapsize (64*1024) | 39 | #define G_mapsize (64*1024) |
40 | 40 | ||
41 | static void format_line(char *hex, uint8_t *data, off_t offset) | 41 | /* "12ef5670 (nn )*16 abcdef_1_3_5_7_9\n" */ |
42 | #define LINEBUF_SIZE (8 + 1 + 3*16 + 16 + 1 /*paranoia:*/ + 14) | ||
43 | |||
44 | static int format_line(char *hex, uint8_t *data, off_t offset) | ||
42 | { | 45 | { |
43 | char *text = hex + 16*3; | 46 | int ofs_pos; |
47 | char *text; | ||
44 | uint8_t *end, *end1; | 48 | uint8_t *end, *end1; |
45 | 49 | ||
50 | #if 1 | ||
51 | /* Can be more than 4Gb, thus >8 chars, thus use a variable - don't assume 8! */ | ||
52 | ofs_pos = sprintf(hex, "%08"OFF_FMT"x ", offset); | ||
53 | #else | ||
54 | if (offset <= 0xffff) | ||
55 | ofs_pos = sprintf(hex, "%04"OFF_FMT"x ", offset); | ||
56 | else | ||
57 | ofs_pos = sprintf(hex, "%08"OFF_FMT"x ", offset); | ||
58 | #endif | ||
59 | hex += ofs_pos; | ||
60 | |||
61 | text = hex + 16*3; | ||
46 | end1 = data + 15; | 62 | end1 = data + 15; |
47 | if ((G.size - offset) > 0) { | 63 | if ((G.size - offset) > 0) { |
48 | end = end1; | 64 | end = end1; |
@@ -66,6 +82,8 @@ static void format_line(char *hex, uint8_t *data, off_t offset) | |||
66 | data++; | 82 | data++; |
67 | } | 83 | } |
68 | *text = '\0'; | 84 | *text = '\0'; |
85 | |||
86 | return ofs_pos; | ||
69 | } | 87 | } |
70 | 88 | ||
71 | static void redraw(void) | 89 | static void redraw(void) |
@@ -78,11 +96,11 @@ static void redraw(void) | |||
78 | offset = 0; | 96 | offset = 0; |
79 | i = 0; | 97 | i = 0; |
80 | while (i < G.height) { | 98 | while (i < G.height) { |
81 | char buf[16*4 + 8]; | 99 | char buf[LINEBUF_SIZE]; |
82 | format_line(buf, data, offset); | 100 | format_line(buf, data, offset); |
83 | printf( | 101 | printf( |
84 | "\r\n%08"OFF_FMT"x %s" + (!i)*2, /* print \r\n only on 2nd line and later */ | 102 | "\r\n%s" + (!i)*2, /* print \r\n only on 2nd line and later */ |
85 | offset, buf | 103 | buf |
86 | ); | 104 | ); |
87 | data += 16; | 105 | data += 16; |
88 | offset += 16; | 106 | offset += 16; |
@@ -92,22 +110,22 @@ static void redraw(void) | |||
92 | 110 | ||
93 | static void redraw_cur_line(void) | 111 | static void redraw_cur_line(void) |
94 | { | 112 | { |
95 | off_t offset; | 113 | char buf[LINEBUF_SIZE]; |
96 | int len; | ||
97 | char buf[16*4 + 8]; | ||
98 | uint8_t *data; | 114 | uint8_t *data; |
115 | off_t offset; | ||
116 | int column; | ||
99 | 117 | ||
100 | len = (0xf & (uintptr_t)G.current_byte); | 118 | column = (0xf & (uintptr_t)G.current_byte); |
101 | data = G.current_byte - len; | 119 | data = G.current_byte - column; |
102 | offset = G.offset + (data - G.addr); | 120 | offset = G.offset + (data - G.addr); |
103 | format_line(buf, data, offset); | 121 | |
104 | printf( | 122 | column = column*3 + G.half; |
105 | "\r%08"OFF_FMT"x %s", | 123 | column += format_line(buf, data, offset); |
106 | offset, buf | 124 | printf("%s" |
107 | ); | 125 | "\r" |
108 | printf( | 126 | "%.*s", |
109 | "\r%08"OFF_FMT"x %.*s", | 127 | buf + column, |
110 | offset, (len*3 + G.half), buf | 128 | column, buf |
111 | ); | 129 | ); |
112 | } | 130 | } |
113 | 131 | ||
@@ -216,7 +234,7 @@ int hexedit_main(int argc UNUSED_PARAM, char **argv) | |||
216 | 234 | ||
217 | printf(CLEAR); | 235 | printf(CLEAR); |
218 | redraw(); | 236 | redraw(); |
219 | printf(HOME "%08x ", 0); | 237 | printf(ESC"[1;10H"); /* position on 1st hex byte in first line */ |
220 | 238 | ||
221 | //TODO: //PgUp/PgDown; Home/End: start/end of line; '<'/'>': start/end of file | 239 | //TODO: //PgUp/PgDown; Home/End: start/end of line; '<'/'>': start/end of file |
222 | //Backspace: undo | 240 | //Backspace: undo |
@@ -229,10 +247,6 @@ int hexedit_main(int argc UNUSED_PARAM, char **argv) | |||
229 | //TODO: detect window resize | 247 | //TODO: detect window resize |
230 | //TODO: read-only mode if open(O_RDWR) fails? hide cursor in this case? | 248 | //TODO: read-only mode if open(O_RDWR) fails? hide cursor in this case? |
231 | 249 | ||
232 | //TODO: smarter redraw: if down-arrow is pressed on last visible line, | ||
233 | //emit LF, then print the tail of next line, then CR, then beginning - | ||
234 | //which makes cursor end up exactly where it should be! Same for up-arrow. | ||
235 | |||
236 | for (;;) { | 250 | for (;;) { |
237 | char read_key_buffer[KEYCODE_BUFFER_SIZE]; | 251 | char read_key_buffer[KEYCODE_BUFFER_SIZE]; |
238 | int32_t key; | 252 | int32_t key; |
@@ -320,10 +334,11 @@ int hexedit_main(int argc UNUSED_PARAM, char **argv) | |||
320 | } | 334 | } |
321 | if ((0xf & (uintptr_t)G.current_byte) == 0) { | 335 | if ((0xf & (uintptr_t)G.current_byte) == 0) { |
322 | /* leftmost pos, wrap to prev line */ | 336 | /* leftmost pos, wrap to prev line */ |
323 | if (G.current_byte == G.addr) | 337 | if (G.current_byte == G.addr) { |
324 | move_mapping_lower(); | 338 | move_mapping_lower(); |
325 | if ((G.current_byte - G.addr) < 16) | 339 | if (G.current_byte == G.addr) |
326 | break; /* first line, don't do anything */ | 340 | break; /* first line, don't do anything */ |
341 | } | ||
327 | G.half = 1; | 342 | G.half = 1; |
328 | G.current_byte--; | 343 | G.current_byte--; |
329 | printf(ESC"[46C"); /* cursor right 3*15 + 1 chars */ | 344 | printf(ESC"[46C"); /* cursor right 3*15 + 1 chars */ |