mirror of
https://github.com/radareorg/r0.git
synced 2026-11-07 14:38:26 -10:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bb011f88af | ||
|
|
c5498bd961 | ||
|
|
a173daa812 | ||
|
|
9096ed5126 | ||
|
|
b074f2280d | ||
|
|
ec8e0225c3 |
No files matched your search
@@ -1,8 +1,8 @@
|
||||
CC?=gcc
|
||||
VERSION=0.5
|
||||
VERSION=0.6git
|
||||
CCw32?=i486-mingw32-gcc
|
||||
CFLAGS+=-O2 -Wall
|
||||
CFLAGS+=-DVERSION=\"${VERSION}\"
|
||||
#CFLAGS+=-DVERSION=\"${VERSION}\"
|
||||
PREFIX?=/usr/local
|
||||
DESTDIR?=
|
||||
|
||||
@@ -11,7 +11,13 @@ all: ired bdiff
|
||||
bdiff: bdiff.o
|
||||
${CC} ${CFLAGS} bdiff.o -o bdiff
|
||||
|
||||
ired.o: cmd.c io.c util.c hexparse.c
|
||||
ired.o: calc.c cmd.c io.c util.c hexparse.c
|
||||
|
||||
ired.js:
|
||||
emcc -o ired.js ired.c
|
||||
|
||||
ired.bc:
|
||||
clang -emit-llvm -o ired.bc -c ired.c
|
||||
|
||||
ired: ired.o
|
||||
${CC} ${CFLAGS} ired.o -o ired
|
||||
|
||||
@@ -0,0 +1,346 @@
|
||||
/* ported to C by pancake for r2 in 2012-2013 */
|
||||
// TODO: integrate floating point support
|
||||
// TODO: do not use global variables
|
||||
/*
|
||||
Reference Chapter 6:
|
||||
"The C++ Programming Language", Special Edition.
|
||||
Bjarne Stroustrup,Addison-Wesley Pub Co; 3 edition (February 15, 2000)
|
||||
ISBN: 0201700735
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define R_API
|
||||
#define R_NUMCALC_STRSZ 4096
|
||||
|
||||
typedef struct {
|
||||
double d;
|
||||
ut64 n;
|
||||
} RNumCalcValue;
|
||||
typedef enum {
|
||||
RNCNAME, RNCNUMBER, RNCEND, RNCINC, RNCDEC,
|
||||
RNCPLUS='+', RNCMINUS='-', RNCMUL='*', RNCDIV='/',
|
||||
//RNCXOR='^', RNCOR='|', RNCAND='&',
|
||||
RNCPRINT=';', RNCASSIGN='=', RNCLEFTP='(', RNCRIGHTP=')'
|
||||
} RNumCalcToken;
|
||||
|
||||
typedef struct r_num_calc_t {
|
||||
RNumCalcToken curr_tok;
|
||||
RNumCalcValue number_value;
|
||||
char string_value[R_NUMCALC_STRSZ];
|
||||
int errors;
|
||||
char oc;
|
||||
const char *calc_err;
|
||||
int calc_i;
|
||||
const char *calc_buf;
|
||||
int calc_len;
|
||||
} RNumCalc;
|
||||
|
||||
|
||||
typedef struct r_num_t {
|
||||
ut64 (*callback)(struct r_num_t *userptr, const char *str, int *ok);
|
||||
// RNumCallback callback;
|
||||
ut64 value;
|
||||
double fvalue;
|
||||
void *userptr;
|
||||
RNumCalc nc;
|
||||
} RNum;
|
||||
/* accessors */
|
||||
static inline RNumCalcValue Nset(ut64 v) { RNumCalcValue n; n.d = (double)v; n.n = v; return n; }
|
||||
static inline RNumCalcValue Nsetf(double v) { RNumCalcValue n; n.d = v; n.n = (ut64)v; return n; }
|
||||
static inline RNumCalcValue Naddf(RNumCalcValue n, double v) { n.d += v; n.n += (ut64)v; return n; }
|
||||
static inline RNumCalcValue Naddi(RNumCalcValue n, ut64 v) { n.d += (double)v; n.n += v; return n; }
|
||||
static inline RNumCalcValue Nsubi(RNumCalcValue n, ut64 v) { n.d -= (double)v; n.n -= v; return n; }
|
||||
static inline RNumCalcValue Nadd(RNumCalcValue n, RNumCalcValue v) { n.d += v.d; n.n += v.n; return n; }
|
||||
static inline RNumCalcValue Nsub(RNumCalcValue n, RNumCalcValue v) { n.d -= v.d; n.n -= v.n; return n; }
|
||||
static inline RNumCalcValue Nmul(RNumCalcValue n, RNumCalcValue v) { n.d *= v.d; n.n *= v.n; return n; }
|
||||
static inline RNumCalcValue Ndiv(RNumCalcValue n, RNumCalcValue v) {
|
||||
if (v.d) n.d /= v.d; else n.d = 0;
|
||||
if (v.n) n.n /= v.n; else n.n = 0;
|
||||
return n;
|
||||
}
|
||||
|
||||
static RNumCalcValue expr(RNum*, RNumCalc*, int);
|
||||
static RNumCalcValue term(RNum*, RNumCalc*, int);
|
||||
static void error(RNum*, RNumCalc*, const char *);
|
||||
static RNumCalcValue prim(RNum*, RNumCalc*, int);
|
||||
static RNumCalcToken get_token(RNum*, RNumCalc*);
|
||||
|
||||
static void error(RNum *num, RNumCalc *nc, const char *s) {
|
||||
nc->errors++;
|
||||
nc->calc_err = s;
|
||||
//fprintf (stderr, "error: %s\n", s);
|
||||
}
|
||||
|
||||
static RNumCalcValue expr(RNum *num, RNumCalc *nc, int get) {
|
||||
RNumCalcValue left = term (num, nc, get);
|
||||
for (;;) {
|
||||
if (nc->curr_tok == RNCPLUS)
|
||||
left = Nadd (left, term (num, nc, 1));
|
||||
else if (nc->curr_tok == RNCMINUS)
|
||||
left = Nsub (left, term (num, nc, 1));
|
||||
else break;
|
||||
}
|
||||
return left;
|
||||
}
|
||||
|
||||
static RNumCalcValue term(RNum *num, RNumCalc *nc, int get) {
|
||||
RNumCalcValue left = prim (num, nc, get);
|
||||
for (;;) {
|
||||
if (nc->curr_tok == RNCMUL) {
|
||||
left = Nmul (left, prim (num, nc, 1));
|
||||
} else
|
||||
if (nc->curr_tok == RNCDIV) {
|
||||
RNumCalcValue d = prim (num, nc, 1);
|
||||
if (!d.d) {
|
||||
error (num, nc, "divide by 0");
|
||||
return d;
|
||||
}
|
||||
left = Ndiv (left, d);
|
||||
} else return left;
|
||||
}
|
||||
}
|
||||
|
||||
static RNumCalcValue prim(RNum *num, RNumCalc *nc, int get) {
|
||||
char *p;
|
||||
RNumCalcValue v = {0};
|
||||
if (get) get_token (num, nc);
|
||||
switch (nc->curr_tok) {
|
||||
case RNCNUMBER:
|
||||
v = nc->number_value;
|
||||
get_token (num, nc);
|
||||
return v;
|
||||
case RNCNAME:
|
||||
for(p=nc->string_value;*p&&*p==' ';p++) {};
|
||||
v = Nset (str2ut64 (nc->string_value));
|
||||
get_token (num, nc);
|
||||
if (nc->curr_tok == RNCASSIGN)
|
||||
v = expr (num, nc, 1);
|
||||
if (nc->curr_tok == RNCINC) Naddi (v, 1);
|
||||
if (nc->curr_tok == RNCDEC) Nsubi (v, 1);
|
||||
return v;
|
||||
case RNCINC: return Naddi (prim (num, nc, 1), 1);
|
||||
case RNCDEC: return Naddi (prim (num, nc, 1), -1);
|
||||
case RNCMINUS: return Nsub (v, prim (num, nc, 1));
|
||||
case RNCLEFTP:
|
||||
v = expr (num, nc, 1);
|
||||
if (nc->curr_tok == RNCRIGHTP)
|
||||
get_token (num, nc);
|
||||
else error (num, nc, " ')' expected");
|
||||
case RNCEND:
|
||||
case RNCPLUS:
|
||||
case RNCMUL:
|
||||
case RNCDIV:
|
||||
case RNCPRINT:
|
||||
case RNCASSIGN:
|
||||
case RNCRIGHTP:
|
||||
return v;
|
||||
//default: error (num, nc, "primary expected");
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
static void cin_putback (RNum *num, RNumCalc *nc, char c) {
|
||||
nc->oc = c;
|
||||
}
|
||||
|
||||
R_API const char *r_num_calc_index (RNum *num, const char *p) {
|
||||
if (num == NULL)
|
||||
return NULL;
|
||||
if (p) {
|
||||
num->nc.calc_buf = p;
|
||||
num->nc.calc_len = strlen (p);
|
||||
num->nc.calc_i = 0;
|
||||
}
|
||||
//if (num->nc.calc_i>num->nc.calc_len) return NULL;
|
||||
return num->nc.calc_buf + num->nc.calc_i;
|
||||
}
|
||||
|
||||
static int cin_get(RNumCalc *nc, char *c) {
|
||||
if (nc->oc) {
|
||||
*c = nc->oc;
|
||||
nc->oc = 0;
|
||||
} else {
|
||||
if (!nc->calc_buf)
|
||||
return 0;
|
||||
//if (nc->calc_i>nc->calc_len) return 0;
|
||||
*c = nc->calc_buf[nc->calc_i];
|
||||
if (*c) nc->calc_i++;
|
||||
else return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int cin_get_num(RNum *num, RNumCalc *nc, RNumCalcValue *n) {
|
||||
char c, str[R_NUMCALC_STRSZ];
|
||||
double d;
|
||||
int i = 0;
|
||||
str[0] = 0;
|
||||
while (cin_get (nc, &c)) {
|
||||
if (c!=':' && c!='.' && !isalnum (c)) {
|
||||
cin_putback (num, nc, c);
|
||||
break;
|
||||
}
|
||||
if (i<R_NUMCALC_STRSZ)
|
||||
str[i++] = c;
|
||||
}
|
||||
str[i] = 0;
|
||||
*n = Nset (str2ut64 (str));
|
||||
if (*str>='0' && *str<='9' && strchr (str, '.')) {
|
||||
if (sscanf (str, "%lf", &d)<1)
|
||||
return 0;
|
||||
*n = Nsetf (d);
|
||||
}
|
||||
#if 0
|
||||
// XXX: use r_num_get here
|
||||
if (str[0]=='0' && str[1]=='x') {
|
||||
ut64 x = 0;
|
||||
if (sscanf (str+2, "%llx", &x)<1)
|
||||
return 0;
|
||||
*n = Nset (x);
|
||||
} else
|
||||
if (strchr (str, '.')) {
|
||||
if (sscanf (str, "%lf", &d)<1)
|
||||
return 0;
|
||||
*n = Nsetf (d);
|
||||
} else {
|
||||
ut64 u;
|
||||
if (sscanf (str, "%"PFMT64d, &u)<1)
|
||||
return 0;
|
||||
*n = Nset (u);
|
||||
}
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
static RNumCalcToken get_token(RNum *num, RNumCalc *nc) {
|
||||
char ch = 0, c = 0;
|
||||
|
||||
do { if (!cin_get (nc, &ch)) return nc->curr_tok = RNCEND;
|
||||
} while (ch!='\n' && isspace (ch));
|
||||
|
||||
switch (ch) {
|
||||
case 0:
|
||||
case ';':
|
||||
case '\n':
|
||||
return nc->curr_tok = RNCEND;
|
||||
case '+': // added for ++name and name++
|
||||
if (cin_get (nc, &c) && c == '+')
|
||||
return nc->curr_tok = RNCINC;
|
||||
cin_putback (num, nc, c);
|
||||
return nc->curr_tok = (RNumCalcToken) ch;
|
||||
case '-':
|
||||
if (cin_get (nc, &c) && c == '-')
|
||||
return nc->curr_tok = RNCDEC;
|
||||
cin_putback (num, nc, c);
|
||||
return nc->curr_tok = (RNumCalcToken) ch;
|
||||
case '*':
|
||||
case '/':
|
||||
case '(':
|
||||
case ')':
|
||||
case '=':
|
||||
return nc->curr_tok = (RNumCalcToken) ch;
|
||||
case '0':case '1': case '2': case '3': case '4':
|
||||
case '5': case '6': case '7': case '8': case '9':
|
||||
case '.':
|
||||
cin_putback (num, nc, ch);
|
||||
if (!cin_get_num (num, nc, &nc->number_value)) {
|
||||
error (num, nc, "invalid number conversion");
|
||||
return 1;
|
||||
}
|
||||
return nc->curr_tok = RNCNUMBER;
|
||||
default:
|
||||
#define isvalidchar(x) \
|
||||
(isalnum(x) || x==':' || x=='$' || x=='.' || x=='_' || x=='?' || x=='\\' \
|
||||
|| x==' ' || x=='[' || x==']' || x=='}' || x=='{' || x=='/' || (x>='0'&&x<='9'))
|
||||
{
|
||||
int i = 0;
|
||||
nc->string_value[i++] = ch;
|
||||
if (ch == '[') {
|
||||
while (cin_get (nc, &ch) && ch!=']') {
|
||||
if (i>=R_NUMCALC_STRSZ) {
|
||||
error (num, nc, "string too long");
|
||||
return 0;
|
||||
}
|
||||
nc->string_value[i++] = ch;
|
||||
}
|
||||
nc->string_value[i++] = ch;
|
||||
} else {
|
||||
while (cin_get (nc, &ch) && isvalidchar (ch)) {
|
||||
if (i>=R_NUMCALC_STRSZ) {
|
||||
error (num, nc, "string too long");
|
||||
return 0;
|
||||
}
|
||||
nc->string_value[i++] = ch;
|
||||
}
|
||||
}
|
||||
nc->string_value[i] = 0;
|
||||
cin_putback (num, nc, ch);
|
||||
|
||||
return nc->curr_tok = RNCNAME;
|
||||
}
|
||||
//}
|
||||
error (num, nc, "bad token");
|
||||
return nc->curr_tok = RNCPRINT;
|
||||
}
|
||||
}
|
||||
|
||||
static void load_token(RNum *num, RNumCalc *nc, const char *s) {
|
||||
nc->calc_i = 0;
|
||||
nc->calc_len = 0;
|
||||
nc->calc_buf = s;
|
||||
nc->calc_err = NULL;
|
||||
}
|
||||
|
||||
R_API ut64 r_num_calc (RNum *num, const char *str, const char **err) {
|
||||
RNumCalcValue n;
|
||||
RNumCalc *nc, nc_local;
|
||||
if (!str || !*str)
|
||||
return 0LL;
|
||||
|
||||
if (num == NULL)
|
||||
nc = &nc_local;
|
||||
else nc = &num->nc;
|
||||
|
||||
/* init */
|
||||
nc->curr_tok = RNCPRINT;
|
||||
nc->number_value.d = 0.0;
|
||||
nc->number_value.n = 0LL;
|
||||
nc->errors = 0;
|
||||
nc->oc = 0;
|
||||
nc->calc_err = NULL;
|
||||
nc->calc_i = 0;
|
||||
nc->calc_len = 0;
|
||||
nc->calc_buf = NULL;
|
||||
|
||||
load_token (num, nc, str);
|
||||
get_token (num, nc);
|
||||
n = expr (num, nc, 0);
|
||||
if (err) *err = nc->calc_err;
|
||||
//if (nc->curr_tok == RNCEND) return 0LL; // XXX: Error
|
||||
//if (nc->curr_tok == RNCPRINT) //return 0LL; // XXX: the fuck
|
||||
// n = expr (num, nc, 0);
|
||||
if (n.d != ((double)(ut64)n.d)) {
|
||||
if (num) num->fvalue = n.d;
|
||||
} else if (num) num->fvalue = (double)n.n;
|
||||
return n.n;
|
||||
}
|
||||
|
||||
#if 0
|
||||
int main(int argc, char* argv[]) {
|
||||
RNumCalcValue n;
|
||||
RNumCalc nc;
|
||||
while (!feof (stdin)) {
|
||||
get_token (nc);
|
||||
if (nc.curr_tok == RNCEND) break;
|
||||
if (nc.curr_tok == RNCPRINT) continue;
|
||||
n = expr (num, nc, 0);
|
||||
if (n.d == ((double)(int)n.d))
|
||||
printf ("%llx\n", n.n);
|
||||
else printf ("%lf\n", n.d);
|
||||
}
|
||||
return nc->errors;
|
||||
}
|
||||
#endif
|
||||
@@ -154,7 +154,7 @@ static int cmd_write(const char *arg) {
|
||||
|
||||
static int cmd_help(char *arg) {
|
||||
if(*arg) {
|
||||
ut64 ret = str2ut64(arg);
|
||||
ut64 ret = r_num_calc (NULL, arg, NULL);
|
||||
printf("0x%"LLF"x %"LLF"d 0%"LLF"o\n", ret, ret, ret);
|
||||
} else printf(
|
||||
"s[+-addr] seek to relative or absolute address\n"
|
||||
@@ -164,6 +164,7 @@ static int cmd_help(char *arg) {
|
||||
"x[size] hexdump\n"
|
||||
"X[size] hexpair dump\n"
|
||||
"p[fmt] print formatted current block ('p' for help)\n"
|
||||
"d[size] disasemble\n"
|
||||
"r[+-[num]] truncate or -remove N bytes\n"
|
||||
".[file] interpret file\n"
|
||||
"<[file] load file in current seek\n"
|
||||
@@ -227,13 +228,16 @@ static int cmd_system(char *arg) {
|
||||
if(fd) {
|
||||
if((buf = getcurblk("", &len))) {
|
||||
setenv("BLOCK", ".curblk", 1);
|
||||
if(fwrite(buf, len, 1, fd)<len)
|
||||
perror("fwrite");
|
||||
fwrite(buf, len, 1, fd);
|
||||
free(buf);
|
||||
}
|
||||
fclose(fd);
|
||||
}
|
||||
}
|
||||
if(strstr(arg, "BSIZE")) {
|
||||
sprintf(str, "%d", len);
|
||||
setenv("BSIZE", str, 1);
|
||||
}
|
||||
if(strstr(arg, "OFFSET")) {
|
||||
sprintf(str, "%"LLF"d", curseek);
|
||||
setenv("OFFSET", str, 1);
|
||||
|
||||
@@ -3,8 +3,12 @@
|
||||
#define ut64 unsigned long long
|
||||
#define ut8 unsigned char
|
||||
|
||||
static int earlyquit = 0;
|
||||
static int verbose = 1;
|
||||
static char *script = 0;
|
||||
static int scriptn = 0;
|
||||
static const char **scripts = 0;
|
||||
static int cmdn = 0;
|
||||
static char **cmds = 0;
|
||||
static ut64 oldseek, curseek = 0LL;
|
||||
static int obsize, bsize = 256;
|
||||
static int red_cmd(char *cmd); // XXX : recursive depenency
|
||||
@@ -12,6 +16,7 @@ static int red_cmd(char *cmd); // XXX : recursive depenency
|
||||
|
||||
#include "ired.h"
|
||||
#include "util.c"
|
||||
#include "calc.c"
|
||||
#include "cmd.c"
|
||||
|
||||
static void red_slurpin() {
|
||||
@@ -24,7 +29,7 @@ static void red_slurpin() {
|
||||
}
|
||||
}
|
||||
|
||||
static int red_interpret(char *file) {
|
||||
static int red_interpret(const char *file) {
|
||||
char buf[BUFSZ];
|
||||
FILE *fd = fopen(file, "r");
|
||||
if(fd != NULL) {
|
||||
@@ -51,12 +56,14 @@ static int red_cmd(char *cmd) {
|
||||
case 's': return cmd_seek(arg); break;
|
||||
case 'b': return cmd_bsize(arg); break;
|
||||
case '/': return cmd_search(arg); break;
|
||||
case 'd': return cmd_system ("echo X | ired -n $BLOCK | rasm2 -o $OFFSET -D - |head -n $(($LINES-1))");
|
||||
case 'p': return cmd_print(arg); break;
|
||||
case 'r': return cmd_resize(arg); break;
|
||||
case 'x': return cmd_hexdump(arg); break;
|
||||
case 'X': return cmd_bytedump(arg); break;
|
||||
case 'w': return cmd_write(arg); break;
|
||||
case '!': return cmd_system(arg); break;
|
||||
case 'V': return cmd_system("vired $FILE"); break;
|
||||
case '?': return cmd_help(arg); break;
|
||||
default: fprintf(stderr, "? %s\n", cmd);
|
||||
}
|
||||
@@ -96,8 +103,14 @@ static int red_open(char *file) {
|
||||
if(ret != -1) {
|
||||
oldseek = 0;
|
||||
setenv("FILE", file, 1);
|
||||
if(script)
|
||||
red_interpret(script);
|
||||
if(scripts)
|
||||
for (ret=0;ret<scriptn;ret++)
|
||||
red_interpret(scripts[ret]);
|
||||
if(cmds)
|
||||
for (ret=0;ret<cmdn;ret++)
|
||||
red_cmd(cmds[ret]);
|
||||
if(earlyquit)
|
||||
return 0;
|
||||
while((ret=red_prompt())>0) {
|
||||
curseek = oldseek;
|
||||
bsize = obsize;
|
||||
@@ -109,20 +122,26 @@ static int red_open(char *file) {
|
||||
}
|
||||
|
||||
static int red_help() {
|
||||
puts("ired [-hnv] [-i script] [file] [..]");
|
||||
puts("ired [-qhnv] [-c cmd] [-i script] [-|file ..]");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
int i, ret = 1;
|
||||
argc++;
|
||||
cmdn = 0;
|
||||
scriptn = 0;
|
||||
scripts = malloc(sizeof(const char*)*argc);
|
||||
cmds = malloc(sizeof(const char*)*argc);
|
||||
if(argc>1 && argv[1])
|
||||
for(i=1; i<argc; i++) {
|
||||
if(argv[i] && argv[i][0]=='-')
|
||||
switch(argv[i][1]) {
|
||||
case 'i': script = argv[++i]; break;
|
||||
case 'q': earlyquit = 1; break;
|
||||
case 'i': scripts[scriptn++] = argv[++i]; break;
|
||||
case 'c': cmds[cmdn++] = argv[++i]; break;
|
||||
case 'n': verbose = 0; break;
|
||||
case 'v': puts("ired "VERSION); ret = 0; break;
|
||||
case 'v': puts(VERSION); ret = 0; break;
|
||||
case 'h': ret = red_help(); break;
|
||||
case 0x0: red_slurpin(); ret = 0; break;
|
||||
} else {
|
||||
@@ -130,5 +149,6 @@ int main(int argc, char **argv) {
|
||||
ret = red_open(argv[i]);
|
||||
}
|
||||
} else ret = red_help();
|
||||
free(scripts);
|
||||
return ret;
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
#define VERSION "0.5"
|
||||
#define VERSION "0.6"
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
@@ -7,11 +7,8 @@ static inline void hexdump(const ut8 *buf, unsigned int len, int w) {
|
||||
for(i=0;i<len;i+=w) {
|
||||
printf("0x%08"LLF"x: ", curseek+i);
|
||||
for(j=i;j<i+w;j++) {
|
||||
if(j>=len) {
|
||||
printf(j%2?" ":" ");
|
||||
continue;
|
||||
}
|
||||
printf(j%2?"%02x ":"%02x", buf[j]);
|
||||
if(j<len) printf(j%2?"%02x ":"%02x", buf[j]);
|
||||
else printf(j%2?" ":" ");
|
||||
}
|
||||
printf(" ");
|
||||
for(j=i;j<i+w;j++)
|
||||
|
||||
@@ -4,48 +4,72 @@
|
||||
|
||||
PATH=.:$PATH
|
||||
|
||||
if [ -n "$1" ]; then
|
||||
$0 | ired -n $@
|
||||
ttyset=`stty -g`
|
||||
bye() {
|
||||
[ -n "$ttyset" ] && stty $ttyset
|
||||
exit 0
|
||||
fi
|
||||
}
|
||||
case "$1" in
|
||||
-) : ; ;;
|
||||
'') echo "vired [-hv] [file]" ; exit 1 ; ;;
|
||||
*) $0 - | ired -n $@ ; bye ; ;;
|
||||
esac
|
||||
|
||||
ttyset=`stty -g`
|
||||
stty -echo -icanon min 1
|
||||
trap bye 2
|
||||
|
||||
getkey() {
|
||||
echo "` stty -echo -icanon min 1 ; dd if=/dev/tty count=1 bs=1 2>/dev/null`"
|
||||
}
|
||||
|
||||
getstr() {
|
||||
stty icanon echo
|
||||
read A
|
||||
echo $A
|
||||
echo "$A"
|
||||
stty -icanon -echo
|
||||
}
|
||||
|
||||
OLINES=0
|
||||
autobs() {
|
||||
LINES=`tput lines`
|
||||
if [ "${OLINES}" != "${LINES}" ]; then
|
||||
[ -n "${LINES}" ] && \
|
||||
echo "b"$((($LINES-1)*16))
|
||||
OLINES=${LINES}
|
||||
fi
|
||||
}
|
||||
|
||||
trap autobs 28
|
||||
|
||||
P=''
|
||||
echo "b 256"
|
||||
while : ; do
|
||||
autobs
|
||||
echo "!clear"
|
||||
case $P in
|
||||
'd') echo '!echo X | ired -n $BLOCK | rasm2 -o $OFFSET -d -' ;;
|
||||
#'d') echo '!echo X | ired -n $| rasm2 -o $OFFSET -vd -|head -n '$LINES ; ;;
|
||||
d) echo d ;;
|
||||
*) echo x ;;
|
||||
esac
|
||||
A=`dd if=/dev/tty count=1 bs=1 2>/dev/null`
|
||||
case $A in
|
||||
case "`getkey`" in
|
||||
'j') echo "s+16" ;;
|
||||
'k') echo "s-16" ;;
|
||||
'J') echo "s+b" ;;
|
||||
'K') echo "s-b" ;;
|
||||
'h') echo "s-1" ;;
|
||||
'l') echo "s+1" ;;
|
||||
'q') stty $ttyset; exit ;;
|
||||
'b') printf 'b '>/dev/tty; echo b `getstr` ;;
|
||||
'w') printf 'w '>/dev/tty; echo w `getstr` ;;
|
||||
's') printf 's '>/dev/tty; echo s `getstr` ;;
|
||||
'r') printf 'r '>/dev/tty; echo r `getstr` ;;
|
||||
':') printf ': '>/dev/tty; echo `getstr`; read A ;;
|
||||
'?') echo '?'; read A ;;
|
||||
'q') bye ; ;;
|
||||
'b') printf 'b'>/dev/tty; echo b`getstr` ;;
|
||||
'w') printf 'w'>/dev/tty; echo w`getstr` ;;
|
||||
's') printf 's'>/dev/tty; echo s`getstr` ;;
|
||||
'r') printf 'r '>/dev/tty; echo r`getstr` ;;
|
||||
':') printf ': '>/dev/tty; getstr; getkey >/dev/null ; ;;
|
||||
'?') echo '?'; getkey >/dev/null; ;;
|
||||
'+') echo "b+1" ;;
|
||||
'-') echo "b-1" ;;
|
||||
'*') echo "b+16" ;;
|
||||
'/') echo "b-16" ;;
|
||||
'p') if [ -n "$P" ]; then P=''; else P=d; fi ;;
|
||||
p|P) if [ -n "$P" ]; then P=''; else P=d; fi ;;
|
||||
esac
|
||||
done
|
||||
Reference in new issue
Block a user