hexedit: fixes to "goto address" code
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
9a4100cf53
commit
f3fa865258
@ -31,6 +31,7 @@ struct globals {
|
|||||||
int fd;
|
int fd;
|
||||||
unsigned height;
|
unsigned height;
|
||||||
unsigned row;
|
unsigned row;
|
||||||
|
unsigned pagesize;
|
||||||
uint8_t *baseaddr;
|
uint8_t *baseaddr;
|
||||||
uint8_t *current_byte;
|
uint8_t *current_byte;
|
||||||
uint8_t *eof_byte;
|
uint8_t *eof_byte;
|
||||||
@ -45,7 +46,16 @@ struct globals {
|
|||||||
SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \
|
SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
/* Hopefully there aren't arches with PAGE_SIZE > 64k */
|
//TODO: move to libbb
|
||||||
|
#if defined(__x86_64__) || defined(i386)
|
||||||
|
# define G_pagesize 4096
|
||||||
|
# define INIT_PAGESIZE() ((void)0)
|
||||||
|
#else
|
||||||
|
# define G_pagesize (G.pagesize)
|
||||||
|
# define INIT_PAGESIZE() ((void)(G.pagesize = getpagesize()))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* hopefully there aren't arches with PAGE_SIZE > 64k */
|
||||||
#define G_mapsize (64*1024)
|
#define G_mapsize (64*1024)
|
||||||
|
|
||||||
/* "12ef5670 (xx )*16 _1_3_5_7_9abcdef\n"NUL */
|
/* "12ef5670 (xx )*16 _1_3_5_7_9abcdef\n"NUL */
|
||||||
@ -86,7 +96,7 @@ static int format_line(char *hex, uint8_t *data, off_t offset)
|
|||||||
#endif
|
#endif
|
||||||
hex += ofs_pos;
|
hex += ofs_pos;
|
||||||
|
|
||||||
text = hex + 16*3;
|
text = hex + 16 * 3;
|
||||||
end1 = data + 15;
|
end1 = data + 15;
|
||||||
if ((G.size - offset) > 0) {
|
if ((G.size - offset) > 0) {
|
||||||
end = end1;
|
end = end1;
|
||||||
@ -114,28 +124,36 @@ static int format_line(char *hex, uint8_t *data, off_t offset)
|
|||||||
return ofs_pos;
|
return ofs_pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void redraw(void)
|
static void redraw(unsigned cursor)
|
||||||
{
|
{
|
||||||
uint8_t *data;
|
uint8_t *data;
|
||||||
off_t offset;
|
off_t offset;
|
||||||
unsigned i, pos;
|
unsigned i, pos;
|
||||||
|
|
||||||
printf(HOME CLEAR);
|
printf(HOME CLEAR);
|
||||||
data = G.baseaddr;
|
|
||||||
offset = G.offset;
|
/* if cursor is past end of screen, how many lines to move down? */
|
||||||
|
i = (cursor / 16) - G.height + 1;
|
||||||
|
if ((int)i < 0)
|
||||||
|
i = 0;
|
||||||
|
|
||||||
|
data = G.baseaddr + i * 16;
|
||||||
|
offset = G.offset + i * 16;
|
||||||
|
cursor -= i * 16;
|
||||||
pos = i = 0;
|
pos = i = 0;
|
||||||
while (i < G.height) {
|
while (i < G.height) {
|
||||||
char buf[LINEBUF_SIZE];
|
char buf[LINEBUF_SIZE];
|
||||||
pos = format_line(buf, data, offset);
|
pos = format_line(buf, data, offset);
|
||||||
printf(
|
printf(
|
||||||
"\r\n%s" + (!i)*2, /* print \r\n only on 2nd line and later */
|
"\r\n%s" + (!i) * 2, /* print \r\n only on 2nd line and later */
|
||||||
buf
|
buf
|
||||||
);
|
);
|
||||||
data += 16;
|
data += 16;
|
||||||
offset += 16;
|
offset += 16;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
printf(ESC"[1;%uH", pos + 1); /* position on 1st hex byte in first line */
|
|
||||||
|
printf(ESC"[%u;%uH", 1 + cursor / 16, 1 + pos + (cursor & 0xf) * 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void redraw_cur_line(void)
|
static void redraw_cur_line(void)
|
||||||
@ -195,7 +213,7 @@ static int move_mapping_further(void)
|
|||||||
if ((G.size - G.offset) < G_mapsize)
|
if ((G.size - G.offset) < G_mapsize)
|
||||||
return 0; /* can't move mapping even further, it's at the end already */
|
return 0; /* can't move mapping even further, it's at the end already */
|
||||||
|
|
||||||
pagesize = getpagesize(); /* constant on most arches */
|
pagesize = G_pagesize; /* constant on most arches */
|
||||||
pos = G.current_byte - G.baseaddr;
|
pos = G.current_byte - G.baseaddr;
|
||||||
if (pos >= pagesize) {
|
if (pos >= pagesize) {
|
||||||
/* move offset up until current position is in 1st page */
|
/* move offset up until current position is in 1st page */
|
||||||
@ -219,7 +237,7 @@ static int move_mapping_lower(void)
|
|||||||
if (G.offset == 0)
|
if (G.offset == 0)
|
||||||
return 0; /* we are at 0 already */
|
return 0; /* we are at 0 already */
|
||||||
|
|
||||||
pagesize = getpagesize(); /* constant on most arches */
|
pagesize = G_pagesize; /* constant on most arches */
|
||||||
pos = G.current_byte - G.baseaddr;
|
pos = G.current_byte - G.baseaddr;
|
||||||
|
|
||||||
/* move offset down until current position is in last page */
|
/* move offset down until current position is in last page */
|
||||||
@ -243,6 +261,7 @@ int hexedit_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
|
|||||||
int hexedit_main(int argc UNUSED_PARAM, char **argv)
|
int hexedit_main(int argc UNUSED_PARAM, char **argv)
|
||||||
{
|
{
|
||||||
INIT_G();
|
INIT_G();
|
||||||
|
INIT_PAGESIZE();
|
||||||
|
|
||||||
get_terminal_width_height(-1, NULL, &G.height);
|
get_terminal_width_height(-1, NULL, &G.height);
|
||||||
if (1) {
|
if (1) {
|
||||||
@ -263,7 +282,7 @@ int hexedit_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
bb_signals(BB_FATAL_SIGS, sig_catcher);
|
bb_signals(BB_FATAL_SIGS, sig_catcher);
|
||||||
|
|
||||||
remap(0);
|
remap(0);
|
||||||
redraw();
|
redraw(0);
|
||||||
|
|
||||||
//TODO: //Home/End: start/end of line; '<'/'>': start/end of file
|
//TODO: //Home/End: start/end of line; '<'/'>': start/end of file
|
||||||
//Backspace: undo
|
//Backspace: undo
|
||||||
@ -411,26 +430,27 @@ int hexedit_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
{
|
{
|
||||||
char buf[sizeof(G.offset)*3 + 4];
|
char buf[sizeof(G.offset)*3 + 4];
|
||||||
printf(ESC"[999;1H" CLEAR_TILL_EOL); /* go to last line */
|
printf(ESC"[999;1H" CLEAR_TILL_EOL); /* go to last line */
|
||||||
if (read_line_input(NULL, "Go to (dec,0Xhex,0oct): ", buf, sizeof(buf)) >= 0) {
|
if (read_line_input(NULL, "Go to (dec,0Xhex,0oct): ", buf, sizeof(buf)) > 0) {
|
||||||
off_t t;
|
off_t t;
|
||||||
unsigned pgmask;
|
unsigned pgmask;
|
||||||
|
|
||||||
t = bb_strtoull(buf, NULL, 0);
|
t = bb_strtoull(buf, NULL, 0);
|
||||||
if (t >= G.size)
|
if (t >= G.size)
|
||||||
t = G.size - 1;
|
t = G.size - 1;
|
||||||
pgmask = getpagesize() - 1;
|
pgmask = G_pagesize - 1;
|
||||||
cnt = t & pgmask;
|
cnt = t & pgmask;
|
||||||
t = t & ~(off_t)pgmask;
|
t = t & ~(off_t)pgmask;
|
||||||
if (t < 0)
|
if (t < 0)
|
||||||
cnt = t = 0;
|
cnt = t = 0;
|
||||||
|
if (t != 0 && cnt < 0x1ff) {
|
||||||
|
/* very close to end of page, possibly to EOF */
|
||||||
|
/* move one page lower */
|
||||||
|
t -= G_pagesize;
|
||||||
|
cnt += G_pagesize;
|
||||||
|
}
|
||||||
G.offset = t;
|
G.offset = t;
|
||||||
remap(cnt & 0xf);
|
remap(cnt);
|
||||||
redraw();
|
redraw(cnt);
|
||||||
if (cnt & 0xf)
|
|
||||||
printf(ESC"[%uC", (cnt & 0xf) * 3); /* cursor right 3*i */
|
|
||||||
cnt >>= 4;
|
|
||||||
if (cnt)
|
|
||||||
goto k_down;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* EOF/error on input: fall through to exiting */
|
/* EOF/error on input: fall through to exiting */
|
||||||
|
Loading…
Reference in New Issue
Block a user