mirror of
https://github.com/9fans/plan9port.git
synced 2025-01-12 11:10:07 +00:00
xd: add -R for runewise dump
Ported from Plan 9 2013-05-21.
b377a116d1
Closes #16.
This commit is contained in:
parent
67d25b6fb0
commit
c665ab76a8
2 changed files with 119 additions and 41 deletions
|
@ -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
|
||||
|
|
153
src/cmd/xd.c
153
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;
|
||||
|
@ -352,6 +381,31 @@ 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)
|
||||
{
|
||||
|
@ -359,33 +413,50 @@ fmtc(char *f)
|
|||
|
||||
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
|
||||
xprint(char *fmt, ulong d)
|
||||
fmtr(char *f)
|
||||
{
|
||||
if(Bprint(&bout, fmt, d)<0){
|
||||
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, ...)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue