|
@@ -2,10 +2,11 @@
|
|
|
#include <libc.h>
|
|
|
#include <bio.h>
|
|
|
|
|
|
-unsigned char odata[16];
|
|
|
-unsigned char data[16];
|
|
|
+uchar odata[16];
|
|
|
+uchar data[32];
|
|
|
int ndata;
|
|
|
-unsigned long addr;
|
|
|
+int nread;
|
|
|
+ulong addr;
|
|
|
int repeats;
|
|
|
int swizzle;
|
|
|
int flush;
|
|
@@ -14,13 +15,17 @@ int xd(char *, int);
|
|
|
void xprint(char *, ...);
|
|
|
void initarg(void), swizz(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 */
|
|
@@ -29,7 +34,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,
|
|
@@ -50,6 +55,10 @@ char *cfmt[3][3] = {
|
|
|
" %.3uo", " %.3ud", " %.2ux",
|
|
|
};
|
|
|
|
|
|
+char *rfmt[1][1] = {
|
|
|
+ " %2.2C",
|
|
|
+};
|
|
|
+
|
|
|
char *afmt[2][3] = {
|
|
|
"%.7luo ", "%.7lud ", "%.7lux ",
|
|
|
"%7luo ", "%7lud ", "%7lux ",
|
|
@@ -113,7 +122,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;
|
|
@@ -150,7 +165,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];
|
|
@@ -178,7 +195,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;
|
|
@@ -190,7 +207,7 @@ int
|
|
|
xd(char *name, int title)
|
|
|
{
|
|
|
int fd;
|
|
|
- int i, star;
|
|
|
+ int i, star, nsee, nleft;
|
|
|
Arg *ap;
|
|
|
Biobuf *bp;
|
|
|
|
|
@@ -209,19 +226,27 @@ xd(char *name, int title)
|
|
|
xprint("%s\n", 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(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);
|
|
@@ -229,7 +254,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;
|
|
|
}
|
|
@@ -241,13 +266,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;
|
|
@@ -288,7 +317,7 @@ void
|
|
|
fmt1(char *f)
|
|
|
{
|
|
|
int i;
|
|
|
- for(i=0; i<ndata; i+=sizeof(unsigned short))
|
|
|
+ for(i=0; i<ndata; i+=sizeof(ushort))
|
|
|
xprint(f, (data[i]<<8)|data[i+1]);
|
|
|
}
|
|
|
|
|
@@ -296,7 +325,7 @@ void
|
|
|
fmt2(char *f)
|
|
|
{
|
|
|
int i;
|
|
|
- for(i=0; i<ndata; i+=sizeof(unsigned long))
|
|
|
+ for(i=0; i<ndata; i+=sizeof(ulong))
|
|
|
xprint(f, (data[i]<<24)|(data[i+1]<<16)|(data[i+2]<<8)|data[i+3]);
|
|
|
}
|
|
|
|
|
@@ -304,8 +333,9 @@ void
|
|
|
fmt3(char *f)
|
|
|
{
|
|
|
int i;
|
|
|
- unsigned long long v;
|
|
|
- for(i=0; i<ndata; i+=sizeof(unsigned long long)){
|
|
|
+ uvlong v;
|
|
|
+
|
|
|
+ for(i=0; i<ndata; i+=sizeof(uvlong)){
|
|
|
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];
|
|
@@ -316,6 +346,31 @@ fmt3(char *f)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+void
|
|
|
+onefmtc(uchar c)
|
|
|
+{
|
|
|
+ switch(c){
|
|
|
+ case '\t':
|
|
|
+ xprint(cfmt[1][2], "\\t");
|
|
|
+ break;
|
|
|
+ case '\r':
|
|
|
+ xprint(cfmt[1][2], "\\r");
|
|
|
+ break;
|
|
|
+ case '\n':
|
|
|
+ xprint(cfmt[1][2], "\\n");
|
|
|
+ break;
|
|
|
+ case '\b':
|
|
|
+ xprint(cfmt[1][2], "\\b");
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ if(c>=0x7F || ' '>c)
|
|
|
+ xprint(cfmt[2][2], c);
|
|
|
+ else
|
|
|
+ xprint(cfmt[0][2], c);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
void
|
|
|
fmtc(char *f)
|
|
|
{
|
|
@@ -323,26 +378,39 @@ fmtc(char *f)
|
|
|
|
|
|
USED(f);
|
|
|
for(i=0; i<ndata; i++)
|
|
|
- switch(data[i]){
|
|
|
- case '\t':
|
|
|
- xprint(cfmt[1][2], "\\t");
|
|
|
- break;
|
|
|
- case '\r':
|
|
|
- xprint(cfmt[1][2], "\\r");
|
|
|
- break;
|
|
|
- case '\n':
|
|
|
- xprint(cfmt[1][2], "\\n");
|
|
|
- break;
|
|
|
- case '\b':
|
|
|
- xprint(cfmt[1][2], "\\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
|