aboutsummaryrefslogtreecommitdiff
path: root/miscutils/hexedit.c
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2017-09-15 14:00:41 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2017-09-15 14:00:41 +0200
commitf3fa86525850620d31e48a742a25fd4965b1dba2 (patch)
tree0febe63460aef1e01456e2e4d56b33bdcccfdab0 /miscutils/hexedit.c
parent9a4100cf53f75356854ce752374babf8135c3f42 (diff)
downloadbusybox-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.c60
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
117static void redraw(void) 127static 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
141static void redraw_cur_line(void) 159static 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;
243int hexedit_main(int argc UNUSED_PARAM, char **argv) 261int 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 */