diff options
author | rsc <devnull@localhost> | 2003-11-23 18:04:47 +0000 |
---|---|---|
committer | rsc <devnull@localhost> | 2003-11-23 18:04:47 +0000 |
commit | bc7cb1a15a67c859c8c71c4b52bb35fe9425a63d (patch) | |
tree | 8ca0fe4e2418e6aa18dc74a236c577a719f6c6ed /src/cmd/xd.c | |
parent | f08fdedcee12c06e3ce9ac9bec363915978e8289 (diff) | |
download | plan9port-bc7cb1a15a67c859c8c71c4b52bb35fe9425a63d.tar.gz plan9port-bc7cb1a15a67c859c8c71c4b52bb35fe9425a63d.tar.bz2 plan9port-bc7cb1a15a67c859c8c71c4b52bb35fe9425a63d.zip |
new utilities.
the .C files compile but are renamed to avoid building automatically.
Diffstat (limited to 'src/cmd/xd.c')
-rw-r--r-- | src/cmd/xd.c | 355 |
1 files changed, 355 insertions, 0 deletions
diff --git a/src/cmd/xd.c b/src/cmd/xd.c new file mode 100644 index 00000000..0d6e1bc3 --- /dev/null +++ b/src/cmd/xd.c @@ -0,0 +1,355 @@ +#include <u.h> +#include <libc.h> +#include <bio.h> + +unsigned char odata[16]; +unsigned char data[16]; +int ndata; +unsigned long addr; +int repeats; +int swizzle; +int flush; +int abase=2; +int xd(char *, int); +void xprint(char *, long); +void initarg(void), swizz(void); +enum{ + Narg=10 +}; +typedef struct Arg Arg; +typedef void fmtfn(char *); +struct Arg +{ + int ascii; /* 0==none, 1==ascii */ + int loglen; /* 0==1, 1==2, 2==4, 3==8 */ + int base; /* 0==8, 1==10, 2==16 */ + fmtfn *fn; /* function to call with data */ + char *afmt; /* format to use to print address */ + char *fmt; /* format to use to print data */ +}arg[Narg]; +int narg; + +fmtfn fmt0, fmt1, fmt2, fmt3, fmtc; +fmtfn *fmt[4] = { + fmt0, + fmt1, + fmt2, + fmt3 +}; + +char *dfmt[4][3] = { + " %.3uo", " %.3ud", " %.2ux", + " %.6uo", " %.5ud", " %.4ux", + " %.11luo", " %.10lud", " %.8lux", + " %.22lluo", " %.20llud", " %.16llux", +}; + +char *cfmt[3][3] = { + " %c", " %c", " %c", + " %.3s", " %.3s", " %.2s", + " %.3uo", " %.3ud", " %.2ux", +}; + +char *afmt[2][3] = { + "%.7luo ", "%.7lud ", "%.7lux ", + "%7luo ", "%7lud ", "%7lux ", +}; + +Biobuf bin; +Biobuf bout; + +void +main(int argc, char *argv[]) +{ + int i, err; + Arg *ap; + + Binit(&bout, 1, OWRITE); + err = 0; + ap = 0; + while(argc>1 && argv[1][0]=='-' && argv[1][1]){ + --argc; + argv++; + argv[0]++; + if(argv[0][0] == 'r'){ + repeats = 1; + if(argv[0][1]) + goto Usage; + continue; + } + if(argv[0][0] == 's'){ + swizzle = 1; + if(argv[0][1]) + goto Usage; + continue; + } + if(argv[0][0] == 'u'){ + flush = 1; + if(argv[0][1]) + goto Usage; + continue; + } + if(argv[0][0] == 'a'){ + argv[0]++; + switch(argv[0][0]){ + case 'o': + abase = 0; + break; + case 'd': + abase = 1; + break; + case 'x': + abase = 2; + break; + default: + goto Usage; + } + if(argv[0][1]) + goto Usage; + continue; + } + ap = &arg[narg]; + initarg(); + while(argv[0][0]){ + switch(argv[0][0]){ + case 'c': + ap->ascii = 1; + ap->loglen = 0; + if(argv[0][1] || argv[0][-1]!='-') + goto Usage; + break; + case 'o': + ap->base = 0; + break; + case 'd': + ap->base = 1; + break; + case 'x': + ap->base = 2; + break; + case 'b': + case '1': + ap->loglen = 0; + break; + case 'w': + case '2': + ap->loglen = 1; + break; + case 'l': + case '4': + ap->loglen = 2; + break; + case 'v': + case '8': + ap->loglen = 3; + break; + default: + Usage: + fprint(2, "usage: xd [-u] [-r] [-s] [-a{odx}] [-c|{b1w2l4v8}{odx}] ... file ...\n"); + exits("usage"); + } + argv[0]++; + } + if(ap->ascii) + ap->fn = fmtc; + else + ap->fn = fmt[ap->loglen]; + ap->fmt = dfmt[ap->loglen][ap->base]; + ap->afmt = afmt[ap>arg][abase]; + } + if(narg == 0) + initarg(); + if(argc == 1) + err = xd(0, 0); + else if(argc == 2) + err = xd(argv[1], 0); + else for(i=1; i<argc; i++) + err |= xd(argv[i], 1); + exits(err? "error" : 0); +} + +void +initarg(void) +{ + Arg *ap; + + ap = &arg[narg++]; + if(narg >= Narg){ + fprint(2, "xd: too many formats (max %d)\n", Narg); + exits("usage"); + } + ap->ascii = 0; + ap->loglen = 2; + ap->base = 2; + ap->fn = fmt2; + ap->fmt = dfmt[ap->loglen][ap->base]; + ap->afmt = afmt[narg>1][abase]; +} + +int +xd(char *name, int title) +{ + int fd; + int i, star; + Arg *ap; + Biobuf *bp; + + fd = 0; + if(name){ + bp = Bopen(name, OREAD); + if(bp == 0){ + fprint(2, "xd: can't open %s\n", name); + return 1; + } + }else{ + bp = &bin; + Binit(bp, fd, OREAD); + } + if(title) + xprint("%s\n", (long)name); + addr = 0; + star = 0; + while((ndata=Bread(bp, data, 16)) >= 0){ + if(ndata < 16) + for(i=ndata; i<16; i++) + data[i] = 0; + if(swizzle) + swizz(); + if(ndata==16 && repeats){ + if(addr>0 && data[0]==odata[0]){ + for(i=1; i<16; i++) + if(data[i] != odata[i]) + break; + if(i == 16){ + addr += 16; + if(star == 0){ + star++; + xprint("*\n", 0); + } + continue; + } + } + for(i=0; i<16; i++) + odata[i] = data[i]; + star = 0; + } + for(ap=arg; ap<&arg[narg]; ap++){ + xprint(ap->afmt, addr); + (*ap->fn)(ap->fmt); + xprint("\n", 0); + if(flush) + Bflush(&bout); + } + addr += ndata; + if(ndata<16){ + xprint(afmt[0][abase], addr); + xprint("\n", 0); + if(flush) + Bflush(&bout); + break; + } + } + Bterm(bp); + return 0; +} + +void +swizz(void) +{ + uchar *p, *q; + int i; + uchar swdata[16]; + + p = data; + q = swdata; + for(i=0; i<16; i++) + *q++ = *p++; + p = data; + q = swdata; + for(i=0; i<4; i++){ + p[0] = q[3]; + p[1] = q[2]; + p[2] = q[1]; + p[3] = q[0]; + p += 4; + q += 4; + } +} + +void +fmt0(char *f) +{ + int i; + for(i=0; i<ndata; i++) + xprint(f, data[i]); +} + +void +fmt1(char *f) +{ + int i; + for(i=0; i<ndata; i+=sizeof(unsigned short)) + xprint(f, (data[i]<<8)|data[i+1]); +} + +void +fmt2(char *f) +{ + int i; + for(i=0; i<ndata; i+=sizeof(unsigned long)) + xprint(f, (data[i]<<24)|(data[i+1]<<16)|(data[i+2]<<8)|data[i+3]); +} + +void +fmt3(char *f) +{ + int i; + unsigned long long v; + for(i=0; i<ndata; i+=sizeof(unsigned long long)){ + v = (data[i]<<24)|(data[i+1]<<16)|(data[i+2]<<8)|data[i+3]; + v <<= 32; + v |= (data[i+4]<<24)|(data[i+1+4]<<16)|(data[i+2+4]<<8)|data[i+3+4]; + if(Bprint(&bout, f, v)<0){ + fprint(2, "xd: i/o error\n"); + exits("i/o error"); + } + } +} + +void +fmtc(char *f) +{ + int i; + + USED(f); + for(i=0; i<ndata; i++) + switch(data[i]){ + case '\t': + xprint(cfmt[1][2], (long)"\\t"); + break; + case '\r': + xprint(cfmt[1][2], (long)"\\r"); + break; + case '\n': + xprint(cfmt[1][2], (long)"\\n"); + break; + case '\b': + xprint(cfmt[1][2], (long)"\\b"); + break; + default: + if(data[i]>=0x7F || ' '>data[i]) + xprint(cfmt[2][2], data[i]); + else + xprint(cfmt[0][2], data[i]); + break; + } +} + +void +xprint(char *fmt, long d) +{ + if(Bprint(&bout, fmt, d)<0){ + fprint(2, "xd: i/o error\n"); + exits("i/o error"); + } +} |