aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/xd.c
diff options
context:
space:
mode:
authorLeah Neukirchen <leah@vuxu.org>2017-09-26 15:48:18 +0200
committerDavid du Colombier <0intro@gmail.com>2017-10-01 11:46:06 +0200
commitc665ab76a83dbe4a56410d3f65e02716cd773a6d (patch)
treeeb2d0b7134b25c01247eaf1ddd763fa676753b0a /src/cmd/xd.c
parent67d25b6fb0ec561de501f2df969c9cad999672d0 (diff)
downloadplan9port-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.c151
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);
}