aboutsummaryrefslogtreecommitdiff
path: root/toys/other/hexedit.c
diff options
context:
space:
mode:
Diffstat (limited to 'toys/other/hexedit.c')
-rw-r--r--toys/other/hexedit.c250
1 files changed, 0 insertions, 250 deletions
diff --git a/toys/other/hexedit.c b/toys/other/hexedit.c
deleted file mode 100644
index 668e51c4..00000000
--- a/toys/other/hexedit.c
+++ /dev/null
@@ -1,250 +0,0 @@
-/* hexedit.c - Hexadecimal file editor
- *
- * Copyright 2015 Rob Landley <rob@landley.net>
- *
- * No standard
-
-USE_HEXEDIT(NEWTOY(hexedit, "<1>1r", TOYFLAG_USR|TOYFLAG_BIN))
-
-config HEXEDIT
- bool "hexedit"
- default n
- 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 (yy<TT.len) {
- printf("\r%0*llX ", TT.numlen, yy);
- for (x=0; x<16; x++) {
- if (yy+x<TT.len) printf(" %02X", TT.data[yy+x]);
- else printf(" ");
- }
- printf(" ");
- for (x=0; x<16; x++) draw_char(TT.data[yy+x]);
- }
- esc("K");
-}
-
-static void draw_page(void)
-{
- int y;
-
- jump(0, 0);
- for (y = 0; y<TT.height; y++) {
- if (y) printf("\r\n");
- draw_line(y);
- }
-}
-
-// side: 0 = editing left, 1 = editing right, 2 = clear, 3 = read only
-static void highlight(int xx, int yy, int side)
-{
- char cc = TT.data[16*(TT.base+yy)+xx];
- int i;
-
- // Display cursor
- jump(2+TT.numlen+3*xx, yy);
- esc("0m");
- if (side!=2) esc("7m");
- if (side>1) 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 (++pos<TT.len && ++x==16) {
- x = 0;
- if (++y == TT.height) {
- --y;
- goto down;
- }
- }
- }
- }
- if (key>255) 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.len) {
-down:
- TT.base++;
- esc("1S");
- jump(0, TT.height-1);
- draw_line(TT.height-1);
- }
- if (pos+16<TT.len && ++y>=TT.height) y--;
- } else if (key==KEY_RIGHT) {
- if (x<15 && pos+1<TT.len) x++;
- } else if (key==KEY_LEFT) {
- if (x) x--;
- } else if (key==KEY_PGUP) {
- TT.base -= TT.height;
- if (TT.base<0) TT.base = 0;
- draw_page();
- } else if (key==KEY_PGDN) {
- TT.base += TT.height;
- if ((TT.base*16)>=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();
-}