diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2017-09-15 14:00:41 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2017-09-15 14:00:41 +0200 |
commit | f3fa86525850620d31e48a742a25fd4965b1dba2 (patch) | |
tree | 0febe63460aef1e01456e2e4d56b33bdcccfdab0 /miscutils/hexedit.c | |
parent | 9a4100cf53f75356854ce752374babf8135c3f42 (diff) | |
download | busybox-w32-f3fa86525850620d31e48a742a25fd4965b1dba2.tar.gz busybox-w32-f3fa86525850620d31e48a742a25fd4965b1dba2.tar.bz2 busybox-w32-f3fa86525850620d31e48a742a25fd4965b1dba2.zip |
hexedit: fixes to "goto address" code
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'miscutils/hexedit.c')
-rw-r--r-- | miscutils/hexedit.c | 60 |
1 files changed, 40 insertions, 20 deletions
diff --git a/miscutils/hexedit.c b/miscutils/hexedit.c index 7e74e1f24..8334181c7 100644 --- a/miscutils/hexedit.c +++ b/miscutils/hexedit.c | |||
@@ -31,6 +31,7 @@ struct globals { | |||
31 | int fd; | 31 | int fd; |
32 | unsigned height; | 32 | unsigned height; |
33 | unsigned row; | 33 | unsigned row; |
34 | unsigned pagesize; | ||
34 | uint8_t *baseaddr; | 35 | uint8_t *baseaddr; |
35 | uint8_t *current_byte; | 36 | uint8_t *current_byte; |
36 | uint8_t *eof_byte; | 37 | uint8_t *eof_byte; |
@@ -45,8 +46,17 @@ struct globals { | |||
45 | SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \ | 46 | SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \ |
46 | } while (0) | 47 | } while (0) |
47 | 48 | ||
48 | /* Hopefully there aren't arches with PAGE_SIZE > 64k */ | 49 | //TODO: move to libbb |
49 | #define G_mapsize (64*1024) | 50 | #if defined(__x86_64__) || defined(i386) |
51 | # define G_pagesize 4096 | ||
52 | # define INIT_PAGESIZE() ((void)0) | ||
53 | #else | ||
54 | # define G_pagesize (G.pagesize) | ||
55 | # define INIT_PAGESIZE() ((void)(G.pagesize = getpagesize())) | ||
56 | #endif | ||
57 | |||
58 | /* hopefully there aren't arches with PAGE_SIZE > 64k */ | ||
59 | #define G_mapsize (64*1024) | ||
50 | 60 | ||
51 | /* "12ef5670 (xx )*16 _1_3_5_7_9abcdef\n"NUL */ | 61 | /* "12ef5670 (xx )*16 _1_3_5_7_9abcdef\n"NUL */ |
52 | #define LINEBUF_SIZE (8 + 1 + 3*16 + 16 + 1 + 1 /*paranoia:*/ + 13) | 62 | #define LINEBUF_SIZE (8 + 1 + 3*16 + 16 + 1 + 1 /*paranoia:*/ + 13) |
@@ -86,7 +96,7 @@ static int format_line(char *hex, uint8_t *data, off_t offset) | |||
86 | #endif | 96 | #endif |
87 | hex += ofs_pos; | 97 | hex += ofs_pos; |
88 | 98 | ||
89 | text = hex + 16*3; | 99 | text = hex + 16 * 3; |
90 | end1 = data + 15; | 100 | end1 = data + 15; |
91 | if ((G.size - offset) > 0) { | 101 | if ((G.size - offset) > 0) { |
92 | end = end1; | 102 | end = end1; |
@@ -114,28 +124,36 @@ static int format_line(char *hex, uint8_t *data, off_t offset) | |||
114 | return ofs_pos; | 124 | return ofs_pos; |
115 | } | 125 | } |
116 | 126 | ||
117 | static void redraw(void) | 127 | static void redraw(unsigned cursor) |
118 | { | 128 | { |
119 | uint8_t *data; | 129 | uint8_t *data; |
120 | off_t offset; | 130 | off_t offset; |
121 | unsigned i, pos; | 131 | unsigned i, pos; |
122 | 132 | ||
123 | printf(HOME CLEAR); | 133 | printf(HOME CLEAR); |
124 | data = G.baseaddr; | 134 | |
125 | offset = G.offset; | 135 | /* if cursor is past end of screen, how many lines to move down? */ |
136 | i = (cursor / 16) - G.height + 1; | ||
137 | if ((int)i < 0) | ||
138 | i = 0; | ||
139 | |||
140 | data = G.baseaddr + i * 16; | ||
141 | offset = G.offset + i * 16; | ||
142 | cursor -= i * 16; | ||
126 | pos = i = 0; | 143 | pos = i = 0; |
127 | while (i < G.height) { | 144 | while (i < G.height) { |
128 | char buf[LINEBUF_SIZE]; | 145 | char buf[LINEBUF_SIZE]; |
129 | pos = format_line(buf, data, offset); | 146 | pos = format_line(buf, data, offset); |
130 | printf( | 147 | printf( |
131 | "\r\n%s" + (!i)*2, /* print \r\n only on 2nd line and later */ | 148 | "\r\n%s" + (!i) * 2, /* print \r\n only on 2nd line and later */ |
132 | buf | 149 | buf |
133 | ); | 150 | ); |
134 | data += 16; | 151 | data += 16; |
135 | offset += 16; | 152 | offset += 16; |
136 | i++; | 153 | i++; |
137 | } | 154 | } |
138 | printf(ESC"[1;%uH", pos + 1); /* position on 1st hex byte in first line */ | 155 | |
156 | printf(ESC"[%u;%uH", 1 + cursor / 16, 1 + pos + (cursor & 0xf) * 3); | ||
139 | } | 157 | } |
140 | 158 | ||
141 | static void redraw_cur_line(void) | 159 | static void redraw_cur_line(void) |
@@ -195,7 +213,7 @@ static int move_mapping_further(void) | |||
195 | if ((G.size - G.offset) < G_mapsize) | 213 | if ((G.size - G.offset) < G_mapsize) |
196 | return 0; /* can't move mapping even further, it's at the end already */ | 214 | return 0; /* can't move mapping even further, it's at the end already */ |
197 | 215 | ||
198 | pagesize = getpagesize(); /* constant on most arches */ | 216 | pagesize = G_pagesize; /* constant on most arches */ |
199 | pos = G.current_byte - G.baseaddr; | 217 | pos = G.current_byte - G.baseaddr; |
200 | if (pos >= pagesize) { | 218 | if (pos >= pagesize) { |
201 | /* move offset up until current position is in 1st page */ | 219 | /* move offset up until current position is in 1st page */ |
@@ -219,7 +237,7 @@ static int move_mapping_lower(void) | |||
219 | if (G.offset == 0) | 237 | if (G.offset == 0) |
220 | return 0; /* we are at 0 already */ | 238 | return 0; /* we are at 0 already */ |
221 | 239 | ||
222 | pagesize = getpagesize(); /* constant on most arches */ | 240 | pagesize = G_pagesize; /* constant on most arches */ |
223 | pos = G.current_byte - G.baseaddr; | 241 | pos = G.current_byte - G.baseaddr; |
224 | 242 | ||
225 | /* move offset down until current position is in last page */ | 243 | /* move offset down until current position is in last page */ |
@@ -243,6 +261,7 @@ int hexedit_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | |||
243 | int hexedit_main(int argc UNUSED_PARAM, char **argv) | 261 | int hexedit_main(int argc UNUSED_PARAM, char **argv) |
244 | { | 262 | { |
245 | INIT_G(); | 263 | INIT_G(); |
264 | INIT_PAGESIZE(); | ||
246 | 265 | ||
247 | get_terminal_width_height(-1, NULL, &G.height); | 266 | get_terminal_width_height(-1, NULL, &G.height); |
248 | if (1) { | 267 | if (1) { |
@@ -263,7 +282,7 @@ int hexedit_main(int argc UNUSED_PARAM, char **argv) | |||
263 | bb_signals(BB_FATAL_SIGS, sig_catcher); | 282 | bb_signals(BB_FATAL_SIGS, sig_catcher); |
264 | 283 | ||
265 | remap(0); | 284 | remap(0); |
266 | redraw(); | 285 | redraw(0); |
267 | 286 | ||
268 | //TODO: //Home/End: start/end of line; '<'/'>': start/end of file | 287 | //TODO: //Home/End: start/end of line; '<'/'>': start/end of file |
269 | //Backspace: undo | 288 | //Backspace: undo |
@@ -411,26 +430,27 @@ int hexedit_main(int argc UNUSED_PARAM, char **argv) | |||
411 | { | 430 | { |
412 | char buf[sizeof(G.offset)*3 + 4]; | 431 | char buf[sizeof(G.offset)*3 + 4]; |
413 | printf(ESC"[999;1H" CLEAR_TILL_EOL); /* go to last line */ | 432 | printf(ESC"[999;1H" CLEAR_TILL_EOL); /* go to last line */ |
414 | if (read_line_input(NULL, "Go to (dec,0Xhex,0oct): ", buf, sizeof(buf)) >= 0) { | 433 | if (read_line_input(NULL, "Go to (dec,0Xhex,0oct): ", buf, sizeof(buf)) > 0) { |
415 | off_t t; | 434 | off_t t; |
416 | unsigned pgmask; | 435 | unsigned pgmask; |
417 | 436 | ||
418 | t = bb_strtoull(buf, NULL, 0); | 437 | t = bb_strtoull(buf, NULL, 0); |
419 | if (t >= G.size) | 438 | if (t >= G.size) |
420 | t = G.size - 1; | 439 | t = G.size - 1; |
421 | pgmask = getpagesize() - 1; | 440 | pgmask = G_pagesize - 1; |
422 | cnt = t & pgmask; | 441 | cnt = t & pgmask; |
423 | t = t & ~(off_t)pgmask; | 442 | t = t & ~(off_t)pgmask; |
424 | if (t < 0) | 443 | if (t < 0) |
425 | cnt = t = 0; | 444 | cnt = t = 0; |
445 | if (t != 0 && cnt < 0x1ff) { | ||
446 | /* very close to end of page, possibly to EOF */ | ||
447 | /* move one page lower */ | ||
448 | t -= G_pagesize; | ||
449 | cnt += G_pagesize; | ||
450 | } | ||
426 | G.offset = t; | 451 | G.offset = t; |
427 | remap(cnt & 0xf); | 452 | remap(cnt); |
428 | redraw(); | 453 | redraw(cnt); |
429 | if (cnt & 0xf) | ||
430 | printf(ESC"[%uC", (cnt & 0xf) * 3); /* cursor right 3*i */ | ||
431 | cnt >>= 4; | ||
432 | if (cnt) | ||
433 | goto k_down; | ||
434 | break; | 454 | break; |
435 | } | 455 | } |
436 | /* EOF/error on input: fall through to exiting */ | 456 | /* EOF/error on input: fall through to exiting */ |