summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko2017-09-13 21:38:55 +0200
committerDenys Vlasenko2017-09-13 21:38:55 +0200
commit136946c3ea6a14d391b5045b5eb71fa8ec207077 (patch)
tree948d12db4fa4865f5870fb8782af98a06147d359
parent73af705628ddaedc4c6f7f78b9658d6c01310309 (diff)
downloadbusybox-136946c3ea6a14d391b5045b5eb71fa8ec207077.zip
busybox-136946c3ea6a14d391b5045b5eb71fa8ec207077.tar.gz
hexedit: smarter redraw
function old new delta format_line 197 209 +12 hexedit_main 930 924 -6 redraw_cur_line 104 94 -10 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 1/2 up/down: 12/-16) Total: -4 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--miscutils/hexedit.c67
1 files changed, 41 insertions, 26 deletions
diff --git a/miscutils/hexedit.c b/miscutils/hexedit.c
index cd4b3b1..ac38978 100644
--- a/miscutils/hexedit.c
+++ b/miscutils/hexedit.c
@@ -38,11 +38,27 @@ struct globals {
/* Hopefully there aren't arches with PAGE_SIZE > 64k */
#define G_mapsize (64*1024)
-static void format_line(char *hex, uint8_t *data, off_t offset)
+/* "12ef5670 (nn )*16 abcdef_1_3_5_7_9\n" */
+#define LINEBUF_SIZE (8 + 1 + 3*16 + 16 + 1 /*paranoia:*/ + 14)
+
+static int format_line(char *hex, uint8_t *data, off_t offset)
{
- char *text = hex + 16*3;
+ int ofs_pos;
+ char *text;
uint8_t *end, *end1;
+#if 1
+ /* Can be more than 4Gb, thus >8 chars, thus use a variable - don't assume 8! */
+ ofs_pos = sprintf(hex, "%08"OFF_FMT"x ", offset);
+#else
+ if (offset <= 0xffff)
+ ofs_pos = sprintf(hex, "%04"OFF_FMT"x ", offset);
+ else
+ ofs_pos = sprintf(hex, "%08"OFF_FMT"x ", offset);
+#endif
+ hex += ofs_pos;
+
+ text = hex + 16*3;
end1 = data + 15;
if ((G.size - offset) > 0) {
end = end1;
@@ -66,6 +82,8 @@ static void format_line(char *hex, uint8_t *data, off_t offset)
data++;
}
*text = '\0';
+
+ return ofs_pos;
}
static void redraw(void)
@@ -78,11 +96,11 @@ static void redraw(void)
offset = 0;
i = 0;
while (i < G.height) {
- char buf[16*4 + 8];
+ char buf[LINEBUF_SIZE];
format_line(buf, data, offset);
printf(
- "\r\n%08"OFF_FMT"x %s" + (!i)*2, /* print \r\n only on 2nd line and later */
- offset, buf
+ "\r\n%s" + (!i)*2, /* print \r\n only on 2nd line and later */
+ buf
);
data += 16;
offset += 16;
@@ -92,22 +110,22 @@ static void redraw(void)
static void redraw_cur_line(void)
{
- off_t offset;
- int len;
- char buf[16*4 + 8];
+ char buf[LINEBUF_SIZE];
uint8_t *data;
+ off_t offset;
+ int column;
- len = (0xf & (uintptr_t)G.current_byte);
- data = G.current_byte - len;
+ column = (0xf & (uintptr_t)G.current_byte);
+ data = G.current_byte - column;
offset = G.offset + (data - G.addr);
- format_line(buf, data, offset);
- printf(
- "\r%08"OFF_FMT"x %s",
- offset, buf
- );
- printf(
- "\r%08"OFF_FMT"x %.*s",
- offset, (len*3 + G.half), buf
+
+ column = column*3 + G.half;
+ column += format_line(buf, data, offset);
+ printf("%s"
+ "\r"
+ "%.*s",
+ buf + column,
+ column, buf
);
}
@@ -216,7 +234,7 @@ int hexedit_main(int argc UNUSED_PARAM, char **argv)
printf(CLEAR);
redraw();
- printf(HOME "%08x ", 0);
+ printf(ESC"[1;10H"); /* position on 1st hex byte in first line */
//TODO: //PgUp/PgDown; Home/End: start/end of line; '<'/'>': start/end of file
//Backspace: undo
@@ -229,10 +247,6 @@ int hexedit_main(int argc UNUSED_PARAM, char **argv)
//TODO: detect window resize
//TODO: read-only mode if open(O_RDWR) fails? hide cursor in this case?
-//TODO: smarter redraw: if down-arrow is pressed on last visible line,
-//emit LF, then print the tail of next line, then CR, then beginning -
-//which makes cursor end up exactly where it should be! Same for up-arrow.
-
for (;;) {
char read_key_buffer[KEYCODE_BUFFER_SIZE];
int32_t key;
@@ -320,10 +334,11 @@ int hexedit_main(int argc UNUSED_PARAM, char **argv)
}
if ((0xf & (uintptr_t)G.current_byte) == 0) {
/* leftmost pos, wrap to prev line */
- if (G.current_byte == G.addr)
+ if (G.current_byte == G.addr) {
move_mapping_lower();
- if ((G.current_byte - G.addr) < 16)
- break; /* first line, don't do anything */
+ if (G.current_byte == G.addr)
+ break; /* first line, don't do anything */
+ }
G.half = 1;
G.current_byte--;
printf(ESC"[46C"); /* cursor right 3*15 + 1 chars */