aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2017-09-14 10:51:12 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2017-09-14 10:51:12 +0200
commitd54f58d487bfa5d6646d9a728d503351691081bf (patch)
tree7e8b76263c6a70e3b26defc49677bce5227e3784
parent363fb5ec4091120003b3f204996e7ff0aa354e58 (diff)
downloadbusybox-w32-d54f58d487bfa5d6646d9a728d503351691081bf.tar.gz
busybox-w32-d54f58d487bfa5d6646d9a728d503351691081bf.tar.bz2
busybox-w32-d54f58d487bfa5d6646d9a728d503351691081bf.zip
hexedit: implement "[enter] goto offset" key
This is a must if you need to edit sector 123456789999 on your /dev/disk. text data bss dec hex filename 922745 481 6832 930058 e310a busybox_old 923023 481 6832 930336 e3220 busybox_unstripped Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--miscutils/hexedit.c79
-rw-r--r--miscutils/less.c4
2 files changed, 56 insertions, 27 deletions
diff --git a/miscutils/hexedit.c b/miscutils/hexedit.c
index b8627e826..eaf4ba57b 100644
--- a/miscutils/hexedit.c
+++ b/miscutils/hexedit.c
@@ -17,7 +17,8 @@
17 17
18#define ESC "\033" 18#define ESC "\033"
19#define HOME ESC"[H" 19#define HOME ESC"[H"
20#define CLEAR ESC"[H"ESC"[J" 20#define CLEAR ESC"[J"
21#define CLEAR_TILL_EOL ESC"[K"
21#define SET_ALT_SCR ESC"[?1049h" 22#define SET_ALT_SCR ESC"[?1049h"
22#define POP_ALT_SCR ESC"[?1049l" 23#define POP_ALT_SCR ESC"[?1049l"
23 24
@@ -30,7 +31,7 @@ struct globals {
30 int fd; 31 int fd;
31 unsigned height; 32 unsigned height;
32 unsigned row; 33 unsigned row;
33 uint8_t *addr; 34 uint8_t *baseaddr;
34 uint8_t *current_byte; 35 uint8_t *current_byte;
35 uint8_t *eof_byte; 36 uint8_t *eof_byte;
36 off_t size; 37 off_t size;
@@ -117,14 +118,15 @@ static void redraw(void)
117{ 118{
118 uint8_t *data; 119 uint8_t *data;
119 off_t offset; 120 off_t offset;
120 unsigned i; 121 unsigned i, pos;
121 122
122 data = G.addr; 123 printf(HOME CLEAR);
123 offset = 0; 124 data = G.baseaddr;
124 i = 0; 125 offset = G.offset;
126 pos = i = 0;
125 while (i < G.height) { 127 while (i < G.height) {
126 char buf[LINEBUF_SIZE]; 128 char buf[LINEBUF_SIZE];
127 format_line(buf, data, offset); 129 pos = format_line(buf, data, offset);
128 printf( 130 printf(
129 "\r\n%s" + (!i)*2, /* print \r\n only on 2nd line and later */ 131 "\r\n%s" + (!i)*2, /* print \r\n only on 2nd line and later */
130 buf 132 buf
@@ -133,6 +135,7 @@ static void redraw(void)
133 offset += 16; 135 offset += 16;
134 i++; 136 i++;
135 } 137 }
138 printf(ESC"[1;%uH", pos + 1); /* position on 1st hex byte in first line */
136} 139}
137 140
138static void redraw_cur_line(void) 141static void redraw_cur_line(void)
@@ -144,7 +147,7 @@ static void redraw_cur_line(void)
144 147
145 column = (0xf & (uintptr_t)G.current_byte); 148 column = (0xf & (uintptr_t)G.current_byte);
146 data = G.current_byte - column; 149 data = G.current_byte - column;
147 offset = G.offset + (data - G.addr); 150 offset = G.offset + (data - G.baseaddr);
148 151
149 column = column*3 + G.half; 152 column = column*3 + G.half;
150 column += format_line(buf, data, offset); 153 column += format_line(buf, data, offset);
@@ -158,28 +161,28 @@ static void redraw_cur_line(void)
158 161
159static void remap(unsigned cur_pos) 162static void remap(unsigned cur_pos)
160{ 163{
161 if (G.addr) 164 if (G.baseaddr)
162 munmap(G.addr, G_mapsize); 165 munmap(G.baseaddr, G_mapsize);
163 166
164 G.addr = mmap(NULL, 167 G.baseaddr = mmap(NULL,
165 G_mapsize, 168 G_mapsize,
166 PROT_READ | PROT_WRITE, 169 PROT_READ | PROT_WRITE,
167 MAP_SHARED, 170 MAP_SHARED,
168 G.fd, 171 G.fd,
169 G.offset 172 G.offset
170 ); 173 );
171 if (G.addr == MAP_FAILED) { 174 if (G.baseaddr == MAP_FAILED) {
172 restore_term(); 175 restore_term();
173 bb_perror_msg_and_die("mmap"); 176 bb_perror_msg_and_die("mmap");
174 } 177 }
175 178
176 G.current_byte = G.addr + cur_pos; 179 G.current_byte = G.baseaddr + cur_pos;
177 180
178 G.eof_byte = G.addr + G_mapsize; 181 G.eof_byte = G.baseaddr + G_mapsize;
179 if ((G.size - G.offset) < G_mapsize) { 182 if ((G.size - G.offset) < G_mapsize) {
180 /* mapping covers tail of the file */ 183 /* mapping covers tail of the file */
181 /* we do have a mapped byte which is past eof */ 184 /* we do have a mapped byte which is past eof */
182 G.eof_byte = G.addr + (G.size - G.offset); 185 G.eof_byte = G.baseaddr + (G.size - G.offset);
183 } 186 }
184} 187}
185static void move_mapping_further(void) 188static void move_mapping_further(void)
@@ -191,7 +194,7 @@ static void move_mapping_further(void)
191 return; /* can't move mapping even further, it's at the end already */ 194 return; /* can't move mapping even further, it's at the end already */
192 195
193 pagesize = getpagesize(); /* constant on most arches */ 196 pagesize = getpagesize(); /* constant on most arches */
194 pos = G.current_byte - G.addr; 197 pos = G.current_byte - G.baseaddr;
195 if (pos >= pagesize) { 198 if (pos >= pagesize) {
196 /* move offset up until current position is in 1st page */ 199 /* move offset up until current position is in 1st page */
197 do { 200 do {
@@ -214,7 +217,7 @@ static void move_mapping_lower(void)
214 return; /* we are at 0 already */ 217 return; /* we are at 0 already */
215 218
216 pagesize = getpagesize(); /* constant on most arches */ 219 pagesize = getpagesize(); /* constant on most arches */
217 pos = G.current_byte - G.addr; 220 pos = G.current_byte - G.baseaddr;
218 221
219 /* move offset down until current position is in last page */ 222 /* move offset down until current position is in last page */
220 pos += pagesize; 223 pos += pagesize;
@@ -252,18 +255,15 @@ int hexedit_main(int argc UNUSED_PARAM, char **argv)
252 G.size = xlseek(G.fd, 0, SEEK_END); 255 G.size = xlseek(G.fd, 0, SEEK_END);
253 256
254 /* TERMIOS_RAW_CRNL suppresses \n -> \r\n translation, helps with down-arrow */ 257 /* TERMIOS_RAW_CRNL suppresses \n -> \r\n translation, helps with down-arrow */
258 printf(SET_ALT_SCR);
255 set_termios_to_raw(STDIN_FILENO, &G.orig_termios, TERMIOS_RAW_CRNL); 259 set_termios_to_raw(STDIN_FILENO, &G.orig_termios, TERMIOS_RAW_CRNL);
256 bb_signals(BB_FATAL_SIGS, sig_catcher); 260 bb_signals(BB_FATAL_SIGS, sig_catcher);
257 261
258 remap(0); 262 remap(0);
259
260 printf(SET_ALT_SCR);
261 redraw(); 263 redraw();
262 printf(ESC"[1;10H"); /* position on 1st hex byte in first line */
263 264
264//TODO: //Home/End: start/end of line; '<'/'>': start/end of file 265//TODO: //Home/End: start/end of line; '<'/'>': start/end of file
265 //Backspace: undo 266 //Backspace: undo
266 //Enter: goto specified position
267 //Ctrl-L: redraw 267 //Ctrl-L: redraw
268 //Ctrl-Z: suspend 268 //Ctrl-Z: suspend
269 //'/', Ctrl-S: search 269 //'/', Ctrl-S: search
@@ -367,9 +367,9 @@ int hexedit_main(int argc UNUSED_PARAM, char **argv)
367 } 367 }
368 if ((0xf & (uintptr_t)G.current_byte) == 0) { 368 if ((0xf & (uintptr_t)G.current_byte) == 0) {
369 /* leftmost pos, wrap to prev line */ 369 /* leftmost pos, wrap to prev line */
370 if (G.current_byte == G.addr) { 370 if (G.current_byte == G.baseaddr) {
371 move_mapping_lower(); 371 move_mapping_lower();
372 if (G.current_byte == G.addr) 372 if (G.current_byte == G.baseaddr)
373 break; /* first line, don't do anything */ 373 break; /* first line, don't do anything */
374 } 374 }
375 G.half = 1; 375 G.half = 1;
@@ -385,9 +385,9 @@ int hexedit_main(int argc UNUSED_PARAM, char **argv)
385 cnt = G.height; 385 cnt = G.height;
386 case KEYCODE_UP: 386 case KEYCODE_UP:
387 k_up: 387 k_up:
388 if ((G.current_byte - G.addr) < 16) { 388 if ((G.current_byte - G.baseaddr) < 16) {
389 move_mapping_lower(); 389 move_mapping_lower();
390 if ((G.current_byte - G.addr) < 16) 390 if ((G.current_byte - G.baseaddr) < 16)
391 break; 391 break;
392 } 392 }
393 G.current_byte -= 16; 393 G.current_byte -= 16;
@@ -403,6 +403,35 @@ int hexedit_main(int argc UNUSED_PARAM, char **argv)
403 if (--cnt) 403 if (--cnt)
404 goto k_up; 404 goto k_up;
405 break; 405 break;
406
407 case '\n':
408 case '\r':
409 /* [Enter]: goto specified position */
410 {
411 char buf[sizeof(G.offset)*3 + 4];
412 printf(ESC"[999;1H" CLEAR_TILL_EOL); /* go to last line */
413 if (read_line_input(NULL, "Go to (dec,0Xhex,0oct): ", buf, sizeof(buf)) >= 0) {
414 off_t t;
415 unsigned pgmask;
416
417 t = bb_strtoull(buf, NULL, 0);
418 if (t >= G.size)
419 t = G.size - 1;
420 pgmask = getpagesize() - 1;
421 cnt = t & pgmask;
422 t = t & ~(off_t)pgmask;
423 if (t < 0)
424 cnt = t = 0;
425 G.offset = t;
426 remap(0);
427 redraw();
428 cnt /= 16;
429 if (cnt)
430 goto k_down;
431 break;
432 }
433 /* EOF/error on input: fall through to exiting */
434 }
406 case CTRL('X'): 435 case CTRL('X'):
407 restore_term(); 436 restore_term();
408 return EXIT_SUCCESS; 437 return EXIT_SUCCESS;
diff --git a/miscutils/less.c b/miscutils/less.c
index f869a9e82..d524b6c87 100644
--- a/miscutils/less.c
+++ b/miscutils/less.c
@@ -281,9 +281,9 @@ static void set_tty_cooked(void)
281 281
282/* Move the cursor to a position (x,y), where (0,0) is the 282/* Move the cursor to a position (x,y), where (0,0) is the
283 top-left corner of the console */ 283 top-left corner of the console */
284static void move_cursor(int line, int row) 284static void move_cursor(int line, int col)
285{ 285{
286 printf(ESC"[%u;%uH", line, row); 286 printf(ESC"[%u;%uH", line, col);
287} 287}
288 288
289static void clear_line(void) 289static void clear_line(void)