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 | |
| 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')
| -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 */ |
