⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xd.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
#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 *, ...);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;voidmain(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);}voidinitarg(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];}intxd(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", 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;}voidswizz(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;	}}voidfmt0(char *f){	int i;	for(i=0; i<ndata; i++)		xprint(f, data[i]);}voidfmt1(char *f){	int i;	for(i=0; i<ndata; i+=sizeof(unsigned short))		xprint(f, (data[i]<<8)|data[i+1]);}voidfmt2(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]);}voidfmt3(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");		}	}}voidfmtc(char *f){	int i;	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;		}}voidxprint(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);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -