aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/xd.c
diff options
context:
space:
mode:
authorrsc <devnull@localhost>2003-11-23 18:04:47 +0000
committerrsc <devnull@localhost>2003-11-23 18:04:47 +0000
commitbc7cb1a15a67c859c8c71c4b52bb35fe9425a63d (patch)
tree8ca0fe4e2418e6aa18dc74a236c577a719f6c6ed /src/cmd/xd.c
parentf08fdedcee12c06e3ce9ac9bec363915978e8289 (diff)
downloadplan9port-bc7cb1a15a67c859c8c71c4b52bb35fe9425a63d.tar.gz
plan9port-bc7cb1a15a67c859c8c71c4b52bb35fe9425a63d.tar.bz2
plan9port-bc7cb1a15a67c859c8c71c4b52bb35fe9425a63d.zip
new utilities.
the .C files compile but are renamed to avoid building automatically.
Diffstat (limited to 'src/cmd/xd.c')
-rw-r--r--src/cmd/xd.c355
1 files changed, 355 insertions, 0 deletions
diff --git a/src/cmd/xd.c b/src/cmd/xd.c
new file mode 100644
index 00000000..0d6e1bc3
--- /dev/null
+++ b/src/cmd/xd.c
@@ -0,0 +1,355 @@
+#include <u.h>
+#include <libc.h>
+#include <bio.h>
+
+unsigned char odata[16];
+unsigned char data[16];
+int ndata;
+unsigned long addr;
+int repeats;
+int swizzle;
+int flush;
+int abase=2;
+int xd(char *, int);
+void xprint(char *, long);
+void initarg(void), swizz(void);
+enum{
+ Narg=10
+};
+typedef struct Arg Arg;
+typedef void fmtfn(char *);
+struct Arg
+{
+ int ascii; /* 0==none, 1==ascii */
+ 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 */
+ char *afmt; /* format to use to print address */
+ char *fmt; /* format to use to print data */
+}arg[Narg];
+int narg;
+
+fmtfn fmt0, fmt1, fmt2, fmt3, fmtc;
+fmtfn *fmt[4] = {
+ fmt0,
+ fmt1,
+ fmt2,
+ fmt3
+};
+
+char *dfmt[4][3] = {
+ " %.3uo", " %.3ud", " %.2ux",
+ " %.6uo", " %.5ud", " %.4ux",
+ " %.11luo", " %.10lud", " %.8lux",
+ " %.22lluo", " %.20llud", " %.16llux",
+};
+
+char *cfmt[3][3] = {
+ " %c", " %c", " %c",
+ " %.3s", " %.3s", " %.2s",
+ " %.3uo", " %.3ud", " %.2ux",
+};
+
+char *afmt[2][3] = {
+ "%.7luo ", "%.7lud ", "%.7lux ",
+ "%7luo ", "%7lud ", "%7lux ",
+};
+
+Biobuf bin;
+Biobuf bout;
+
+void
+main(int argc, char *argv[])
+{
+ int i, err;
+ Arg *ap;
+
+ Binit(&bout, 1, OWRITE);
+ err = 0;
+ ap = 0;
+ while(argc>1 && argv[1][0]=='-' && argv[1][1]){
+ --argc;
+ argv++;
+ argv[0]++;
+ if(argv[0][0] == 'r'){
+ repeats = 1;
+ if(argv[0][1])
+ goto Usage;
+ continue;
+ }
+ if(argv[0][0] == 's'){
+ swizzle = 1;
+ if(argv[0][1])
+ goto Usage;
+ continue;
+ }
+ if(argv[0][0] == 'u'){
+ flush = 1;
+ if(argv[0][1])
+ goto Usage;
+ continue;
+ }
+ if(argv[0][0] == 'a'){
+ argv[0]++;
+ switch(argv[0][0]){
+ case 'o':
+ abase = 0;
+ break;
+ case 'd':
+ abase = 1;
+ break;
+ case 'x':
+ abase = 2;
+ break;
+ default:
+ goto Usage;
+ }
+ if(argv[0][1])
+ goto Usage;
+ continue;
+ }
+ ap = &arg[narg];
+ initarg();
+ while(argv[0][0]){
+ switch(argv[0][0]){
+ case 'c':
+ ap->ascii = 1;
+ ap->loglen = 0;
+ if(argv[0][1] || argv[0][-1]!='-')
+ goto Usage;
+ break;
+ case 'o':
+ ap->base = 0;
+ break;
+ case 'd':
+ ap->base = 1;
+ break;
+ case 'x':
+ ap->base = 2;
+ break;
+ case 'b':
+ case '1':
+ ap->loglen = 0;
+ break;
+ case 'w':
+ case '2':
+ ap->loglen = 1;
+ break;
+ case 'l':
+ case '4':
+ ap->loglen = 2;
+ break;
+ case 'v':
+ case '8':
+ ap->loglen = 3;
+ break;
+ default:
+ Usage:
+ fprint(2, "usage: xd [-u] [-r] [-s] [-a{odx}] [-c|{b1w2l4v8}{odx}] ... file ...\n");
+ exits("usage");
+ }
+ argv[0]++;
+ }
+ if(ap->ascii)
+ ap->fn = fmtc;
+ else
+ ap->fn = fmt[ap->loglen];
+ ap->fmt = dfmt[ap->loglen][ap->base];
+ ap->afmt = afmt[ap>arg][abase];
+ }
+ if(narg == 0)
+ initarg();
+ if(argc == 1)
+ err = xd(0, 0);
+ else if(argc == 2)
+ err = xd(argv[1], 0);
+ else for(i=1; i<argc; i++)
+ err |= xd(argv[i], 1);
+ exits(err? "error" : 0);
+}
+
+void
+initarg(void)
+{
+ Arg *ap;
+
+ ap = &arg[narg++];
+ if(narg >= Narg){
+ fprint(2, "xd: too many formats (max %d)\n", Narg);
+ exits("usage");
+ }
+ ap->ascii = 0;
+ ap->loglen = 2;
+ ap->base = 2;
+ ap->fn = fmt2;
+ ap->fmt = dfmt[ap->loglen][ap->base];
+ ap->afmt = afmt[narg>1][abase];
+}
+
+int
+xd(char *name, int title)
+{
+ int fd;
+ int i, star;
+ Arg *ap;
+ Biobuf *bp;
+
+ fd = 0;
+ if(name){
+ bp = Bopen(name, OREAD);
+ if(bp == 0){
+ fprint(2, "xd: can't open %s\n", name);
+ return 1;
+ }
+ }else{
+ bp = &bin;
+ Binit(bp, fd, OREAD);
+ }
+ if(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++)
+ data[i] = 0;
+ if(swizzle)
+ swizz();
+ if(ndata==16 && repeats){
+ if(addr>0 && data[0]==odata[0]){
+ for(i=1; i<16; i++)
+ if(data[i] != odata[i])
+ break;
+ if(i == 16){
+ addr += 16;
+ if(star == 0){
+ star++;
+ xprint("*\n", 0);
+ }
+ continue;
+ }
+ }
+ for(i=0; i<16; i++)
+ odata[i] = data[i];
+ star = 0;
+ }
+ for(ap=arg; ap<&arg[narg]; ap++){
+ xprint(ap->afmt, addr);
+ (*ap->fn)(ap->fmt);
+ xprint("\n", 0);
+ if(flush)
+ Bflush(&bout);
+ }
+ addr += ndata;
+ if(ndata<16){
+ xprint(afmt[0][abase], addr);
+ xprint("\n", 0);
+ if(flush)
+ Bflush(&bout);
+ break;
+ }
+ }
+ Bterm(bp);
+ return 0;
+}
+
+void
+swizz(void)
+{
+ uchar *p, *q;
+ int i;
+ uchar swdata[16];
+
+ p = data;
+ q = swdata;
+ for(i=0; i<16; i++)
+ *q++ = *p++;
+ p = data;
+ q = swdata;
+ for(i=0; i<4; i++){
+ p[0] = q[3];
+ p[1] = q[2];
+ p[2] = q[1];
+ p[3] = q[0];
+ p += 4;
+ q += 4;
+ }
+}
+
+void
+fmt0(char *f)
+{
+ int i;
+ for(i=0; i<ndata; i++)
+ xprint(f, data[i]);
+}
+
+void
+fmt1(char *f)
+{
+ int i;
+ for(i=0; i<ndata; i+=sizeof(unsigned short))
+ xprint(f, (data[i]<<8)|data[i+1]);
+}
+
+void
+fmt2(char *f)
+{
+ int i;
+ for(i=0; i<ndata; i+=sizeof(unsigned long))
+ xprint(f, (data[i]<<24)|(data[i+1]<<16)|(data[i+2]<<8)|data[i+3]);
+}
+
+void
+fmt3(char *f)
+{
+ int i;
+ unsigned long long v;
+ for(i=0; i<ndata; i+=sizeof(unsigned long long)){
+ 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];
+ if(Bprint(&bout, f, v)<0){
+ fprint(2, "xd: i/o error\n");
+ exits("i/o error");
+ }
+ }
+}
+
+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;
+ }
+}
+
+void
+xprint(char *fmt, long d)
+{
+ if(Bprint(&bout, fmt, d)<0){
+ fprint(2, "xd: i/o error\n");
+ exits("i/o error");
+ }
+}