diff options
author | Leah Neukirchen <leah@vuxu.org> | 2017-09-26 15:48:18 +0200 |
---|---|---|
committer | David du Colombier <0intro@gmail.com> | 2017-10-01 11:46:06 +0200 |
commit | c665ab76a83dbe4a56410d3f65e02716cd773a6d (patch) | |
tree | eb2d0b7134b25c01247eaf1ddd763fa676753b0a /src/cmd/xd.c | |
parent | 67d25b6fb0ec561de501f2df969c9cad999672d0 (diff) | |
download | plan9port-c665ab76a83dbe4a56410d3f65e02716cd773a6d.tar.gz plan9port-c665ab76a83dbe4a56410d3f65e02716cd773a6d.tar.bz2 plan9port-c665ab76a83dbe4a56410d3f65e02716cd773a6d.zip |
xd: add -R for runewise dump
Ported from Plan 9 2013-05-21.
https://github.com/0intro/plan9/commit/b377a116d132865c011a3fb3ea76528ffd32963f
Closes #16.
Diffstat (limited to 'src/cmd/xd.c')
-rw-r--r-- | src/cmd/xd.c | 151 |
1 files changed, 111 insertions, 40 deletions
diff --git a/src/cmd/xd.c b/src/cmd/xd.c index e5389fea..9f83e1cf 100644 --- a/src/cmd/xd.c +++ b/src/cmd/xd.c @@ -3,8 +3,9 @@ #include <bio.h> unsigned char odata[16]; -unsigned char data[16]; +unsigned char data[32]; int ndata; +int nread; unsigned long addr; int repeats; int swizzle; @@ -12,16 +13,20 @@ int swizzle8; int flush; int abase=2; int xd(char *, int); -void xprint(char *, ulong); +void xprint(char *, ...); void initarg(void), swizz(void), swizz8(void); enum{ - Narg=10 + Narg=10, + + TNone=0, + TAscii, + TRune, }; typedef struct Arg Arg; typedef void fmtfn(char *); struct Arg { - int ascii; /* 0==none, 1==ascii */ + int chartype; /* TNone, TAscii, TRunes */ 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 */ @@ -30,7 +35,7 @@ struct Arg }arg[Narg]; int narg; -fmtfn fmt0, fmt1, fmt2, fmt3, fmtc; +fmtfn fmt0, fmt1, fmt2, fmt3, fmtc, fmtr; fmtfn *fmt[4] = { fmt0, fmt1, @@ -46,11 +51,15 @@ char *dfmt[4][3] = { }; char *cfmt[3][3] = { - " %c", " %c", " %c", + " %c", " %c", " %c", " %.3s", " %.3s", " %.2s", " %.3uo", " %.3ud", " %.2ux", }; +char *rfmt[1][1] = { + " %2.2C", +}; + char *afmt[2][3] = { "%.7luo ", "%.7lud ", "%.7lux ", "%7luo ", "%7lud ", "%7lux ", @@ -120,7 +129,13 @@ main(int argc, char *argv[]) while(argv[0][0]){ switch(argv[0][0]){ case 'c': - ap->ascii = 1; + ap->chartype = TAscii; + ap->loglen = 0; + if(argv[0][1] || argv[0][-1]!='-') + goto Usage; + break; + case 'R': + ap->chartype = TRune; ap->loglen = 0; if(argv[0][1] || argv[0][-1]!='-') goto Usage; @@ -157,7 +172,9 @@ main(int argc, char *argv[]) } argv[0]++; } - if(ap->ascii) + if(ap->chartype == TRune) + ap->fn = fmtr; + else if(ap->chartype == TAscii) ap->fn = fmtc; else ap->fn = fmt[ap->loglen]; @@ -185,7 +202,7 @@ initarg(void) fprint(2, "xd: too many formats (max %d)\n", Narg); exits("usage"); } - ap->ascii = 0; + ap->chartype = TNone; ap->loglen = 2; ap->base = 2; ap->fn = fmt2; @@ -197,7 +214,7 @@ int xd(char *name, int title) { int fd; - int i, star; + int i, star, nsee, nleft; Arg *ap; Biobuf *bp; @@ -216,21 +233,29 @@ xd(char *name, int 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++) + nsee = 16; + nleft = 0; + /* read 32 but see only 16 so that runes are happy */ + while((ndata=Bread(bp, data + nleft, 32 - nleft)) >= 0){ + ndata += nleft; + nleft = 0; + nread = ndata; + if(ndata>nsee) + ndata = nsee; + else if(ndata<nsee) + for(i=ndata; i<nsee; i++) data[i] = 0; if(swizzle) swizz(); if(swizzle8) swizz8(); - if(ndata==16 && repeats){ + if(ndata==nsee && repeats){ if(addr>0 && data[0]==odata[0]){ - for(i=1; i<16; i++) + for(i=1; i<nsee; i++) if(data[i] != odata[i]) break; - if(i == 16){ - addr += 16; + if(i == nsee){ + addr += nsee; if(star == 0){ star++; xprint("*\n", 0); @@ -238,7 +263,7 @@ xd(char *name, int title) continue; } } - for(i=0; i<16; i++) + for(i=0; i<nsee; i++) odata[i] = data[i]; star = 0; } @@ -250,13 +275,17 @@ xd(char *name, int title) Bflush(&bout); } addr += ndata; - if(ndata<16){ + if(ndata<nsee){ xprint(afmt[0][abase], addr); xprint("\n", 0); if(flush) Bflush(&bout); break; } + if(nread>nsee){ + nleft = nread - nsee; + memmove(data, data + nsee, nleft); + } } Bterm(bp); return 0; @@ -353,39 +382,81 @@ fmt3(char *f) } void +onefmtc(uchar c) +{ + switch(c){ + 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(c>=0x7F || ' '>c) + xprint(cfmt[2][2], c); + else + xprint(cfmt[0][2], c); + break; + } +} + +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; + onefmtc(data[i]); +} + +void +fmtr(char *f) +{ + int i, w, cw; + Rune r; + static int nstart; + + USED(f); + if(nstart) + xprint("%*c", 3*nstart, ' '); + for(i=nstart; i<ndata; ) + if(data[i] < Runeself) + onefmtc(data[i++]); + else{ + w = chartorune(&r, (char *)data+i); + if(w == 1 || i + w>nread) + onefmtc(data[i++]); + else{ + cw = w; + if(i + w>ndata) + cw = ndata - i; + xprint(rfmt[0][0], r); + xprint("%*c", 3*cw-3, ' '); + i += w; + } } + if(i > ndata) + nstart = i - ndata; + else + nstart = 0; } void -xprint(char *fmt, ulong d) +xprint(char *fmt, ...) { - if(Bprint(&bout, fmt, d)<0){ + va_list arglist; + + va_start(arglist, fmt); + if(Bvprint(&bout, fmt, arglist)<0){ fprint(2, "xd: i/o error\n"); exits("i/o error"); } + va_end(arglist); } |