123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436 |
- /*
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
- #include <u.h>
- #include <libc.h>
- #include <bio.h>
- uint8_t odata[16];
- uint8_t data[32];
- int ndata;
- int nread;
- uint32_t addr;
- int repeats;
- int swizzle;
- int flush;
- int abase=2;
- int xd(char *, int);
- void xprint(char *, ...);
- void initarg(void), swizz(void);
- enum{
- Narg=10,
- TNone=0,
- TAscii,
- TRune,
- };
- typedef struct Arg Arg;
- typedef void fmtfn(char *);
- struct Arg
- {
- 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 */
- 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, fmtr;
- 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 *rfmt[1][1] = {
- " %2.2C",
- };
- 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->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;
- 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->chartype == TRune)
- ap->fn = fmtr;
- else if(ap->chartype == TAscii)
- 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->chartype = TNone;
- 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, nsee, nleft;
- 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", name);
- addr = 0;
- star = 0;
- 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==nsee && repeats){
- if(addr>0 && data[0]==odata[0]){
- for(i=1; i<nsee; i++)
- if(data[i] != odata[i])
- break;
- if(i == nsee){
- addr += nsee;
- if(star == 0){
- star++;
- xprint("*\n", 0);
- }
- continue;
- }
- }
- for(i=0; i<nsee; 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<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;
- }
- void
- swizz(void)
- {
- uint8_t *p, *q;
- int i;
- uint8_t 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(uint16_t))
- xprint(f, (data[i]<<8)|data[i+1]);
- }
- void
- fmt2(char *f)
- {
- int i;
- for(i=0; i<ndata; i+=sizeof(uint32_t))
- xprint(f, (data[i]<<24)|(data[i+1]<<16)|(data[i+2]<<8)|data[i+3]);
- }
- void
- fmt3(char *f)
- {
- int i;
- uint64_t v;
- for(i=0; i<ndata; i+=sizeof(uint64_t)){
- 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
- onefmtc(uint8_t 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)
- {
- int i;
- USED(f);
- for(i=0; i<ndata; i++)
- 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, ...)
- {
- 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);
- }
|