commit c665ab76a83dbe4a56410d3f65e02716cd773a6d from: Leah Neukirchen via: David du Colombier <0intro@gmail.com> date: Sun Oct 01 09:46:06 2017 UTC xd: add -R for runewise dump Ported from Plan 9 2013-05-21. https://github.com/0intro/plan9/commit/b377a116d132865c011a3fb3ea76528ffd32963f Closes #16. commit - 67d25b6fb0ec561de501f2df969c9cad999672d0 commit + c665ab76a83dbe4a56410d3f65e02716cd773a6d blob - 9d43a750822b54900fac724b8eebb4cbc41fd8b0 blob + 5ec167bdc6a0d2c6639b8b620022f745f397cf91 --- man/man1/xd.1 +++ man/man1/xd.1 @@ -66,6 +66,13 @@ but print .SM ASCII representations or C escape sequences where possible. .TP +.B -R +Format as +.B 1x +but print +.B Rune +representations or C escape sequences where possible. +.TP .BI -a style Print file addresses in the given style (and size 4). .TP blob - e5389fea2ef69932a15fe89f6938b5627d153e6e blob + 9f83e1cf900374ec7e4b9fa8265c67cc85dcb390 --- src/cmd/xd.c +++ src/cmd/xd.c @@ -3,8 +3,9 @@ #include 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,11 +129,17 @@ 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; + break; case 'o': ap->base = 0; break; @@ -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(ndata0 && data[0]==odata[0]){ - for(i=1; i<16; i++) + for(i=1; insee){ + 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=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; inread) + 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); }