From 6253e48aadc09bd1af93caa45fe305466977fd0f Mon Sep 17 00:00:00 2001 From: Rob Landley Date: Sun, 10 May 2015 18:56:49 -0500 Subject: Git hates me. --- toys/other/hexedit.c | 250 +++++++++++++++++++++++++++++++++++++++++++++++++ toys/pending/hexedit.c | 250 ------------------------------------------------- 2 files changed, 250 insertions(+), 250 deletions(-) create mode 100644 toys/other/hexedit.c delete mode 100644 toys/pending/hexedit.c diff --git a/toys/other/hexedit.c b/toys/other/hexedit.c new file mode 100644 index 00000000..518755bb --- /dev/null +++ b/toys/other/hexedit.c @@ -0,0 +1,250 @@ +/* hexedit.c - Hexadecimal file editor + * + * Copyright 2015 Rob Landley + * + * No standard + +USE_HEXEDIT(NEWTOY(hexedit, "<1>1r", TOYFLAG_USR|TOYFLAG_BIN)) + +config HEXEDIT + bool "hexedit" + default y + help + usage: hexedit FILENAME + + Hexadecimal file editor. + + -r Read only (display but don't edit) +*/ + +#define FOR_hexedit +#include "toys.h" + +GLOBALS( + char *data; + long long len, base; + int numlen; + unsigned height; +) + +static void esc(char *s) +{ + printf("\033[%s", s); +} + +static void jump(int x, int y) +{ + char s[32]; + + sprintf(s, "%d;%dH", y+1, x+1); + esc(s); +} + +static void fix_terminal(void) +{ + set_terminal(1, 0, 0); + esc("?25h"); + esc("0m"); + jump(0, 999); +} + +static void sigttyreset(int i) +{ + fix_terminal(); + // how do I re-raise the signal so it dies with right signal info for wait()? + _exit(127); +} + +// Render all characters printable, using color to distinguish. +static void draw_char(char broiled) +{ + if (broiled<32 || broiled>=127) { + if (broiled>127) { + esc("2m"); + broiled &= 127; + } + if (broiled<32 || broiled==127) { + esc("7m"); + if (broiled==127) broiled = 32; + else broiled += 64; + } + printf("%c", broiled); + esc("0m"); + } else printf("%c", broiled); +} + +static void draw_line(long long yy) +{ + int x; + + yy = (TT.base+yy)*16; + + if (yy1) printf("%02X", cc); + else for (i=0; i<2;) { + if (side==i) esc("32m"); + printf("%X", (cc>>(4*(1&++i)))&15); + } + esc("0m"); + jump(TT.numlen+17*3+xx, yy); + draw_char(cc); +} + +#define KEY_UP 256 +#define KEY_DOWN 257 +#define KEY_RIGHT 258 +#define KEY_LEFT 259 +#define KEY_PGUP 260 +#define KEY_PGDN 261 +#define KEY_HOME 262 +#define KEY_END 263 +#define KEY_INSERT 264 + +void hexedit_main(void) +{ + // up down right left pgup pgdn home end ins + char *keys[] = {"\033[A", "\033[B", "\033[C", "\033[D", "\033[5~", "\033[6~", + "\033OH", "\033OF", "\033[2~", 0}; + long long pos; + int x, y, i, side = 0, key, ro = toys.optflags&FLAG_r, + fd = xopen(*toys.optargs, ro ? O_RDONLY : O_RDWR); + + TT.height = 25; + terminal_size(0, &TT.height); + if (TT.height) TT.height--; + sigatexit(sigttyreset); + esc("0m"); + esc("?25l"); + fflush(0); + set_terminal(1, 1, 0); + + if ((TT.len = fdlength(fd))<0) error_exit("bad length"); + if (sizeof(long)==32 && TT.len>SIZE_MAX) TT.len = SIZE_MAX; + // count file length hex digits, rounded up to multiple of 4 + for (pos = TT.len, TT.numlen = 0; pos; pos >>= 4, TT.numlen++); + TT.numlen += (4-TT.numlen)&3; + + TT.data = mmap(0, TT.len, PROT_READ|(PROT_WRITE*!ro), MAP_SHARED, fd, 0); + + draw_page(); + + y = x = 0; + for (;;) { + // Get position within file, trimming if we overshot end. + pos = 16*(TT.base+y)+x; + if (pos>=TT.len) { + pos = TT.len-1; + x = (TT.len-1)%15; + } + + // Display cursor + highlight(x, y, ro ? 3 : side); + fflush(0); + + // Wait for next key + key = scan_key(toybuf, keys, 1); + // Exit for q, ctrl-c, ctrl-d, escape, or EOF + if (key==-1 || key==3 || key==4 || key==27 || key=='q') break; + highlight(x, y, 2); + + if (key>='a' && key<='f') key-=32; + if (!ro && ((key>='0' && key<='9') || (key>='A' && key<='F'))) { + i = key - '0'; + if (i>9) i -= 7; + TT.data[pos] &= 15<<(4*side); + TT.data[pos] |= i<<(4*!side); + + highlight(x, y, ++side); + if (side==2) { + side = 0; + if (++pos255) side = 0; + if (key==KEY_UP) { + if (--y<0) { + if (TT.base) { + TT.base--; + esc("1T"); + jump(0, TT.height); + esc("K"); + jump(0, 0); + draw_line(0); + } + y = 0; + } + } else if (key==KEY_DOWN) { + if (y == TT.height-1 && pos+32=TT.height) y--; + } else if (key==KEY_RIGHT) { + if (x<15 && pos+1=TT.len) TT.base=(TT.len-1)/16; + while ((TT.base+y)*16>=TT.len) y--; + if (16*(TT.base+y)+x>=TT.len) x = (TT.len-1)&15; + draw_page(); + } else if (key==KEY_HOME) { + TT.base = 0; + x = 0; + draw_page(); + } else if (key==KEY_END) { + TT.base=(TT.len-1)/16; + x = (TT.len-1)&15; + draw_page(); + } + } + munmap(TT.data, TT.len); + close(fd); + fix_terminal(); +} diff --git a/toys/pending/hexedit.c b/toys/pending/hexedit.c deleted file mode 100644 index 518755bb..00000000 --- a/toys/pending/hexedit.c +++ /dev/null @@ -1,250 +0,0 @@ -/* hexedit.c - Hexadecimal file editor - * - * Copyright 2015 Rob Landley - * - * No standard - -USE_HEXEDIT(NEWTOY(hexedit, "<1>1r", TOYFLAG_USR|TOYFLAG_BIN)) - -config HEXEDIT - bool "hexedit" - default y - help - usage: hexedit FILENAME - - Hexadecimal file editor. - - -r Read only (display but don't edit) -*/ - -#define FOR_hexedit -#include "toys.h" - -GLOBALS( - char *data; - long long len, base; - int numlen; - unsigned height; -) - -static void esc(char *s) -{ - printf("\033[%s", s); -} - -static void jump(int x, int y) -{ - char s[32]; - - sprintf(s, "%d;%dH", y+1, x+1); - esc(s); -} - -static void fix_terminal(void) -{ - set_terminal(1, 0, 0); - esc("?25h"); - esc("0m"); - jump(0, 999); -} - -static void sigttyreset(int i) -{ - fix_terminal(); - // how do I re-raise the signal so it dies with right signal info for wait()? - _exit(127); -} - -// Render all characters printable, using color to distinguish. -static void draw_char(char broiled) -{ - if (broiled<32 || broiled>=127) { - if (broiled>127) { - esc("2m"); - broiled &= 127; - } - if (broiled<32 || broiled==127) { - esc("7m"); - if (broiled==127) broiled = 32; - else broiled += 64; - } - printf("%c", broiled); - esc("0m"); - } else printf("%c", broiled); -} - -static void draw_line(long long yy) -{ - int x; - - yy = (TT.base+yy)*16; - - if (yy1) printf("%02X", cc); - else for (i=0; i<2;) { - if (side==i) esc("32m"); - printf("%X", (cc>>(4*(1&++i)))&15); - } - esc("0m"); - jump(TT.numlen+17*3+xx, yy); - draw_char(cc); -} - -#define KEY_UP 256 -#define KEY_DOWN 257 -#define KEY_RIGHT 258 -#define KEY_LEFT 259 -#define KEY_PGUP 260 -#define KEY_PGDN 261 -#define KEY_HOME 262 -#define KEY_END 263 -#define KEY_INSERT 264 - -void hexedit_main(void) -{ - // up down right left pgup pgdn home end ins - char *keys[] = {"\033[A", "\033[B", "\033[C", "\033[D", "\033[5~", "\033[6~", - "\033OH", "\033OF", "\033[2~", 0}; - long long pos; - int x, y, i, side = 0, key, ro = toys.optflags&FLAG_r, - fd = xopen(*toys.optargs, ro ? O_RDONLY : O_RDWR); - - TT.height = 25; - terminal_size(0, &TT.height); - if (TT.height) TT.height--; - sigatexit(sigttyreset); - esc("0m"); - esc("?25l"); - fflush(0); - set_terminal(1, 1, 0); - - if ((TT.len = fdlength(fd))<0) error_exit("bad length"); - if (sizeof(long)==32 && TT.len>SIZE_MAX) TT.len = SIZE_MAX; - // count file length hex digits, rounded up to multiple of 4 - for (pos = TT.len, TT.numlen = 0; pos; pos >>= 4, TT.numlen++); - TT.numlen += (4-TT.numlen)&3; - - TT.data = mmap(0, TT.len, PROT_READ|(PROT_WRITE*!ro), MAP_SHARED, fd, 0); - - draw_page(); - - y = x = 0; - for (;;) { - // Get position within file, trimming if we overshot end. - pos = 16*(TT.base+y)+x; - if (pos>=TT.len) { - pos = TT.len-1; - x = (TT.len-1)%15; - } - - // Display cursor - highlight(x, y, ro ? 3 : side); - fflush(0); - - // Wait for next key - key = scan_key(toybuf, keys, 1); - // Exit for q, ctrl-c, ctrl-d, escape, or EOF - if (key==-1 || key==3 || key==4 || key==27 || key=='q') break; - highlight(x, y, 2); - - if (key>='a' && key<='f') key-=32; - if (!ro && ((key>='0' && key<='9') || (key>='A' && key<='F'))) { - i = key - '0'; - if (i>9) i -= 7; - TT.data[pos] &= 15<<(4*side); - TT.data[pos] |= i<<(4*!side); - - highlight(x, y, ++side); - if (side==2) { - side = 0; - if (++pos255) side = 0; - if (key==KEY_UP) { - if (--y<0) { - if (TT.base) { - TT.base--; - esc("1T"); - jump(0, TT.height); - esc("K"); - jump(0, 0); - draw_line(0); - } - y = 0; - } - } else if (key==KEY_DOWN) { - if (y == TT.height-1 && pos+32=TT.height) y--; - } else if (key==KEY_RIGHT) { - if (x<15 && pos+1=TT.len) TT.base=(TT.len-1)/16; - while ((TT.base+y)*16>=TT.len) y--; - if (16*(TT.base+y)+x>=TT.len) x = (TT.len-1)&15; - draw_page(); - } else if (key==KEY_HOME) { - TT.base = 0; - x = 0; - draw_page(); - } else if (key==KEY_END) { - TT.base=(TT.len-1)/16; - x = (TT.len-1)&15; - draw_page(); - } - } - munmap(TT.data, TT.len); - close(fd); - fix_terminal(); -} -- cgit v1.2.3