xref: /csrg-svn/old/od/od.c (revision 4530)
1*4530Sdlw static char *sccsid = "@(#)od.c	5.4 (Berkeley) 10/16/81";
24492Sdlw /*
34492Sdlw  * od -- octal, hex, decimal, character dump of data in a file.
44492Sdlw  *
5*4530Sdlw  * usage:  od [-abcdDefFhHiIlLopPvxX] [file] [[+]offset[.][b] [label]]
64492Sdlw  *
74492Sdlw  * where the option flags have the following meaning:
84492Sdlw  *   character	object	radix	signed?
94492Sdlw  *	a	byte	(10)	(n.a.)	ASCII named byte stream
104492Sdlw  *	b	byte	  8	 no	byte octal
114492Sdlw  *	c	byte	 (8)	(no)	character with octal non-graphic bytes
124492Sdlw  *	d	short	 10	 no
134492Sdlw  *	D	long	 10	 no
144492Sdlw  *	e,F	double	(10)		double precision floating pt.
154492Sdlw  *	f	float	(10)		single precision floating pt.
164492Sdlw  *	h,x	short	 16	 no
174492Sdlw  *	H,X	long	 16	 no
184492Sdlw  *	i	short	 10	yes
194492Sdlw  *	I,l,L	long	 10	yes
204492Sdlw  *	o	short	  8	 no	(default conversion)
214492Sdlw  *	O	long	  8	 no
224492Sdlw  *
234492Sdlw  *	p				indicate EVEN parity on 'a' conversion
244492Sdlw  *	P				indicate ODD parity on 'a' conversion
254492Sdlw  *	v				show all data - don't skip like lines.
264492Sdlw  *
274492Sdlw  * More than one format character may be given.
284492Sdlw  * If {file} is not specified, standard input is read.
294492Sdlw  * If {file} is not specified, then {offset} must start with '+'.
304492Sdlw  * {Offset} may be HEX (0xnnn), OCTAL (0nn), or decimal (nnn.); the default
314492Sdlw  * is the same as the address radix, which will be the same as the first
324492Sdlw  * object radix.
334492Sdlw  */
344492Sdlw 
354492Sdlw #include <stdio.h>
364492Sdlw 
374492Sdlw #define NO	0
384492Sdlw #define YES	1
394492Sdlw #define EVEN	-1
404492Sdlw #define ODD	1
414492Sdlw #define UNSIGNED 0
424492Sdlw #define SIGNED	1
434492Sdlw 
444492Sdlw int	a_put();
454492Sdlw int	b_put();
464492Sdlw int	c_put();
474492Sdlw int	s_put();
484492Sdlw int	us_put();
494492Sdlw int	l_put();
504492Sdlw int	f_put();
514492Sdlw int	d_put();
524492Sdlw 
534492Sdlw struct dfmt {
544492Sdlw 	int	df_field;	/* external field required for object */
554492Sdlw 	int	df_size;	/* size (bytes) of object */
564492Sdlw 	int	df_radix;	/* conversion radix */
574492Sdlw 	int	df_signed;	/* signed? flag */
584492Sdlw 	int	(*df_put)();	/* function to output object */
594492Sdlw 	char	*df_fmt;
604492Sdlw } *conv_vec[32];		/* vector of conversions to be done */
614492Sdlw 
624492Sdlw struct dfmt	ascii	= { 3, sizeof (char),   10,        0,  a_put, 0};
634492Sdlw struct dfmt	byte	= { 3, sizeof (char),    8, UNSIGNED,  b_put, 0};
644492Sdlw struct dfmt	cchar	= { 3, sizeof (char),    8, UNSIGNED,  c_put, 0};
654492Sdlw struct dfmt	u_s_oct	= { 6, sizeof (short),   8, UNSIGNED, us_put, 0};
664492Sdlw struct dfmt	u_s_dec	= { 5, sizeof (short),  10, UNSIGNED, us_put, 0};
674492Sdlw struct dfmt	u_s_hex	= { 4, sizeof (short),  16, UNSIGNED, us_put, 0};
684492Sdlw struct dfmt	u_l_oct	= {11, sizeof (long),    8, UNSIGNED,  l_put, 0};
694492Sdlw struct dfmt	u_l_dec	= {10, sizeof (long),   10, UNSIGNED,  l_put, 0};
704492Sdlw struct dfmt	u_l_hex	= { 8, sizeof (long),   16, UNSIGNED,  l_put, 0};
714492Sdlw struct dfmt	s_s_dec	= { 6, sizeof (short),  10,   SIGNED,  s_put, 0};
724492Sdlw struct dfmt	s_l_dec	= {11, sizeof (long),   10,   SIGNED,  l_put, 0};
734492Sdlw struct dfmt	flt	= {14, sizeof (float),  10,   SIGNED,  f_put, 0};
744492Sdlw struct dfmt	dble	= {21, sizeof (double), 10,   SIGNED,  d_put, 0};
754492Sdlw 
76*4530Sdlw 
77*4530Sdlw char	usage[]	= "od [-abcdfhilopvx] [file] [[+]offset[.][b] [label]]";
784492Sdlw char	dbuf[16];
794492Sdlw char	lastdbuf[16];
804492Sdlw int	addr_base;
814492Sdlw long	addr;
82*4530Sdlw long	label = -1L;
834492Sdlw int	_parity = NO;
844492Sdlw char	fmt[]	= "            %s";	/* 12 blanks */
854492Sdlw char	*icvt();
864492Sdlw char	*underline();
87*4530Sdlw long	get_addr();
884492Sdlw 
89*4530Sdlw 
904492Sdlw main(argc, argv)
914492Sdlw char **argv;
924492Sdlw {
934492Sdlw 	register char *p;
944492Sdlw 	register char *l;
954492Sdlw 	register n, same;
964492Sdlw 	struct dfmt	*d;
974492Sdlw 	struct dfmt	**cv = conv_vec;
984492Sdlw 	int	showall = NO;
994492Sdlw 	int	field, llen, nelm;
1004492Sdlw 	int	max_llen = 0;
1014492Sdlw 
1024492Sdlw 	argv++;
103*4530Sdlw 	argc--;
1044492Sdlw 	max_llen = max_nelm = 0;
1054492Sdlw 
106*4530Sdlw 	if(argc > 0) {
1074492Sdlw 		p = *argv;
1084492Sdlw 		if(*p == '-') {
1094492Sdlw 			while(*++p != '\0') {
1104492Sdlw 				switch(*p) {
1114492Sdlw 				case 'a':
1124492Sdlw 					d = &ascii;
1134492Sdlw 					break;
1144492Sdlw 				case 'b':
1154492Sdlw 					d = &byte;
1164492Sdlw 					break;
1174492Sdlw 				case 'c':
1184492Sdlw 					d = &cchar;
1194492Sdlw 					break;
1204492Sdlw 				case 'd':
1214492Sdlw 					d = &u_s_dec;
1224492Sdlw 					break;
1234492Sdlw 				case 'D':
1244492Sdlw 					d = &u_l_dec;
1254492Sdlw 					break;
1264492Sdlw 				case 'e':
1274492Sdlw 				case 'F':
1284492Sdlw 					d = &dble;
1294492Sdlw 					break;
1304492Sdlw 				case 'f':
1314492Sdlw 					d = &flt;
1324492Sdlw 					break;
1334492Sdlw 				case 'h':
1344492Sdlw 				case 'x':
1354492Sdlw 					d = &u_s_hex;
1364492Sdlw 					break;
1374492Sdlw 				case 'H':
1384492Sdlw 				case 'X':
1394492Sdlw 					d = &u_l_hex;
1404492Sdlw 					break;
1414492Sdlw 				case 'i':
1424492Sdlw 					d = &s_s_dec;
1434492Sdlw 					break;
1444492Sdlw 				case 'I':
1454492Sdlw 				case 'l':
1464492Sdlw 				case 'L':
1474492Sdlw 					d = &s_l_dec;
1484492Sdlw 					break;
1494492Sdlw 				case 'o':
1504492Sdlw 					d = &u_s_oct;
1514492Sdlw 					break;
1524492Sdlw 				case 'O':
1534492Sdlw 					d = &u_l_oct;
1544492Sdlw 					break;
1554492Sdlw 				case 'p':
1564492Sdlw 					_parity = EVEN;
1574492Sdlw 					continue;
1584492Sdlw 				case 'P':
1594492Sdlw 					_parity = ODD;
1604492Sdlw 					continue;
1614492Sdlw 				case 'v':
1624492Sdlw 					showall = YES;
1634492Sdlw 					continue;
164*4530Sdlw 				default:
165*4530Sdlw 					printf("od: bad flag -%c\n", *p);
166*4530Sdlw 					puts(usage);
167*4530Sdlw 					exit(1);
1684492Sdlw 				}
1694492Sdlw 				nelm = 16 / d->df_size;
1704492Sdlw 				llen = (d->df_field + 1) * nelm;
1714492Sdlw 				if (llen > max_llen)
1724492Sdlw 					max_llen = llen;
1734492Sdlw 				if (nelm > max_nelm)
1744492Sdlw 					max_nelm = nelm;
1754492Sdlw 				/*
1764492Sdlw 				 * nelm will always be a power of 2.
1774492Sdlw 				 * line length must always be multiple
1784492Sdlw 				 * of max_nelm.
1794492Sdlw 				 */
1804492Sdlw 				nelm = max_nelm - 1;
1814492Sdlw 				max_llen = (max_llen + nelm) & (~nelm);
1824492Sdlw 				if (addr_base == 0)
1834492Sdlw 					addr_base = d->df_radix;
1844492Sdlw 				*(cv++) = d;
1854492Sdlw 			}
1864492Sdlw 			argc--;
1874492Sdlw 			argv++;
1884492Sdlw 		}
1894492Sdlw 	}
1904492Sdlw 
1914492Sdlw 	if(cv == conv_vec) {
1924492Sdlw 		addr_base = 8;
1934492Sdlw 		*(cv++) = &u_s_oct;
194*4530Sdlw 		max_nelm = 16 / u_s_oct.df_size;
195*4530Sdlw 		max_llen = max_nelm * (u_s_oct.df_field + 1);
1964492Sdlw 	}
1974492Sdlw 	*cv = (struct dfmt *)0;
1984492Sdlw 
1994492Sdlw 	cv = conv_vec;
2004492Sdlw 	while (d = *cv++) {
2014492Sdlw 		nelm = 16 / d->df_size;
2024492Sdlw 		field = max_llen / nelm;
2034492Sdlw 		d->df_fmt = fmt + 12 - (field - d->df_field);
2044492Sdlw 	}
2054492Sdlw 
206*4530Sdlw 	if(argc > 0 && **argv != '+') {
2074492Sdlw 		if (freopen(*argv, "r", stdin) == NULL) {
2084492Sdlw 			printf("od: cannot open %s\n", *argv);
2094492Sdlw 			exit(1);
2104492Sdlw 		}
2114492Sdlw 		argv++;
2124492Sdlw 		argc--;
2134492Sdlw 	}
2144492Sdlw 
215*4530Sdlw 	if (argc > 0)
216*4530Sdlw 	{
217*4530Sdlw 		addr = get_addr(*argv);
218*4530Sdlw 		offset(addr);
219*4530Sdlw 		argv++;
220*4530Sdlw 		argc--;
2214492Sdlw 
222*4530Sdlw 		if (argc > 0)
223*4530Sdlw 			label = get_addr(*argv);
224*4530Sdlw 	}
225*4530Sdlw 
2264492Sdlw 	same = -1;
2274492Sdlw 	while ((n = fread(dbuf, 1, sizeof(dbuf), stdin)) > 0) {
2284492Sdlw 		if (same>=0 && strncmp(dbuf, lastdbuf, 16) == 0 && !showall) {
2294492Sdlw 			if (same==0) {
2304492Sdlw 				printf("*\n");
2314492Sdlw 				same = 1;
2324492Sdlw 			}
2334492Sdlw 		}
2344492Sdlw 		else {
2354492Sdlw 			line(n);
2364492Sdlw 			same = 0;
2374492Sdlw 			p = dbuf;
2384492Sdlw 			l = lastdbuf;
2394492Sdlw 			for (nelm=0; nelm<16; nelm++) {
2404492Sdlw 				*l++ = *p;
2414492Sdlw 				*p++ = '\0';
2424492Sdlw 			}
2434492Sdlw 		}
2444492Sdlw 		addr += n;
245*4530Sdlw 		if (label >= 0)
246*4530Sdlw 			label += n;
2474492Sdlw 	}
248*4530Sdlw 	put_addr('\n');
2494492Sdlw }
2504492Sdlw 
251*4530Sdlw put_addr(c)
252*4530Sdlw char	c;
253*4530Sdlw {
254*4530Sdlw 	fputs(icvt(addr, addr_base, UNSIGNED, 7), stdout);
255*4530Sdlw 	if (label >= 0)
256*4530Sdlw 		printf(" (%s)", icvt(label, addr_base, UNSIGNED, 7));
257*4530Sdlw 	putchar(c);
258*4530Sdlw }
259*4530Sdlw 
2604492Sdlw line(n)
2614492Sdlw int	n;
2624492Sdlw {
2634492Sdlw 	register i, first;
2644492Sdlw 	register struct dfmt *c;
2654492Sdlw 	register struct dfmt **cv = conv_vec;
2664492Sdlw 
2674492Sdlw 	first = YES;
2684492Sdlw 	while (c = *cv++) {
2694492Sdlw 		if (first) {
270*4530Sdlw 			put_addr(' ');
2714492Sdlw 			first = NO;
272*4530Sdlw 		} else {
2734492Sdlw 			putchar('\t');
274*4530Sdlw 			if (label >= 0)
275*4530Sdlw 				fputs("\t  ", stdout);
276*4530Sdlw 		}
2774492Sdlw 		i = 0;
2784492Sdlw 		while (i < n)
2794492Sdlw 			i += (*(c->df_put))(dbuf+i, c);
2804492Sdlw 		putchar('\n');
2814492Sdlw 	}
2824492Sdlw }
2834492Sdlw 
2844492Sdlw s_put(n, d)
2854492Sdlw short	*n;
2864492Sdlw struct dfmt	*d;
2874492Sdlw {
2884492Sdlw 	printf(d->df_fmt, icvt((long)*n, d->df_radix, d->df_signed, d->df_field));
2894492Sdlw 	return(d->df_size);
2904492Sdlw }
2914492Sdlw 
2924492Sdlw us_put(n, d)
2934492Sdlw unsigned short	*n;
2944492Sdlw struct dfmt	*d;
2954492Sdlw {
2964492Sdlw 	printf(d->df_fmt, icvt((long)*n, d->df_radix, d->df_signed, d->df_field));
2974492Sdlw 	return(d->df_size);
2984492Sdlw }
2994492Sdlw 
3004492Sdlw l_put(n, d)
3014492Sdlw long	*n;
3024492Sdlw struct dfmt	*d;
3034492Sdlw {
3044492Sdlw 	printf(d->df_fmt, icvt(*n, d->df_radix, d->df_signed, d->df_field));
3054492Sdlw 	return(d->df_size);
3064492Sdlw }
3074492Sdlw 
3084492Sdlw d_put(f, d)
3094492Sdlw double	*f;
3104492Sdlw struct dfmt *d;
3114492Sdlw {
3124492Sdlw 	char fbuf[24];
3134500Sdlw 	struct l { long n[2]; };
3144500Sdlw 
3154500Sdlw #if	vax
3164500Sdlw 	if ((((struct l *)f)->n[0] & 0xff00) == 0x8000)	/* Vax illegal f.p. */
3174500Sdlw 		sprintf(fbuf, "    %08x %08x",
3184500Sdlw 			((struct l *)f)->n[0], ((struct l *)f)->n[1]);
3194500Sdlw 	else
3204500Sdlw #endif
3214500Sdlw 
3224500Sdlw 		sprintf(fbuf, "%21.14e", *f);
3234492Sdlw 	printf(d->df_fmt, fbuf);
3244492Sdlw 	return(d->df_size);
3254492Sdlw }
3264492Sdlw 
3274492Sdlw f_put(f, d)
3284492Sdlw float	*f;
3294492Sdlw struct dfmt *d;
3304492Sdlw {
3314492Sdlw 	char fbuf[16];
3324500Sdlw 
3334500Sdlw #if	vax
3344500Sdlw 	if ((*(long *)f & 0xff00) == 0x8000)	/* Vax illegal f.p. form */
3354500Sdlw 		sprintf(fbuf, "      %08x", *(long *)f);
3364500Sdlw 	else
3374500Sdlw #endif
3384500Sdlw 		sprintf(fbuf, "%14.7e", *f);
3394492Sdlw 	printf(d->df_fmt, fbuf);
3404492Sdlw 	return(d->df_size);
3414492Sdlw }
3424492Sdlw 
3434492Sdlw 
3444492Sdlw char	asc_name[34][4] = {
3454492Sdlw 	"nul",
3464492Sdlw 	"soh",
3474492Sdlw 	"stx",
3484492Sdlw 	"etx",
3494492Sdlw 	"eot",
3504492Sdlw 	"enq",
3514492Sdlw 	"ack",
3524492Sdlw 	"bel",
3534492Sdlw 	" bs",
3544492Sdlw 	" ht",
3554492Sdlw 	" nl",
3564492Sdlw 	" vt",
3574492Sdlw 	" ff",
3584492Sdlw 	" cr",
3594492Sdlw 	" so",
3604492Sdlw 	" si",
3614492Sdlw 	"dle",
3624492Sdlw 	"dc1",
3634492Sdlw 	"dc2",
3644492Sdlw 	"dc3",
3654492Sdlw 	"dc4",
3664492Sdlw 	"nak",
3674492Sdlw 	"syn",
3684492Sdlw 	"etb",
3694492Sdlw 	"can",
3704492Sdlw 	" em",
3714492Sdlw 	"sub",
3724492Sdlw 	"esc",
3734492Sdlw 	" fs",
3744492Sdlw 	" gs",
3754492Sdlw 	" rs",
3764492Sdlw 	" us",
3774492Sdlw 	" sp",
3784492Sdlw 	"del"
3794492Sdlw };
3804492Sdlw 
3814492Sdlw a_put(cc, d)
3824492Sdlw char	*cc;
3834492Sdlw struct dfmt *d;
3844492Sdlw {
3854492Sdlw 	int c = *cc;
3864492Sdlw 	register char *s = "   ";
3874492Sdlw 	register pbit = parity((int)c & 0377);
3884492Sdlw 
3894492Sdlw 	c &= 0177;
3904492Sdlw 	if (c > ' ' && c < 0177)
3914492Sdlw 	{
3924492Sdlw 		s[2] = *cc;
3934492Sdlw 		if (pbit == _parity)
3944503Sdlw 			printf(d->df_fmt, underline(s));
3954492Sdlw 		else
3964492Sdlw 			printf(d->df_fmt, s);
3974492Sdlw 	}
3984492Sdlw 	else
3994492Sdlw 	{
4004492Sdlw 		if (c == 0177)
4014492Sdlw 			c = ' ' + 1;
4024492Sdlw 		if (pbit == _parity)
4034503Sdlw 			printf(d->df_fmt, underline(asc_name[c]));
4044492Sdlw 		else
4054492Sdlw 			printf(d->df_fmt, asc_name[c]);
4064492Sdlw 	}
4074492Sdlw 	return(1);
4084492Sdlw }
4094492Sdlw 
4104492Sdlw parity(word)
4114492Sdlw int	word;
4124492Sdlw {
4134492Sdlw 	register int p = 0;
4144492Sdlw 	register int w = word;
4154492Sdlw 
4164492Sdlw 	if (w)
4174492Sdlw 		do {
4184492Sdlw 			p ^= 1;
4194492Sdlw 		} while(w &= (~(-w)));
4204492Sdlw 	return (p? ODD:EVEN);
4214492Sdlw }
4224492Sdlw 
4234492Sdlw char *
4244503Sdlw underline(s)
4254492Sdlw char	*s;
4264492Sdlw {
4274492Sdlw 	static char ulbuf[16];
4284492Sdlw 	register char *u = ulbuf;
4294492Sdlw 
4304503Sdlw 	while (*s) {
4314503Sdlw 		if (*s != ' ') {
4324492Sdlw 			*u++ = '_';
4334492Sdlw 			*u++ = '\b';
4344492Sdlw 		}
4354492Sdlw 		*u++ = *s++;
4364492Sdlw 	}
4374492Sdlw 	*u = '\0';
4384492Sdlw 	return(ulbuf);
4394492Sdlw }
4404492Sdlw 
4414492Sdlw b_put(b, d)
4424492Sdlw char	*b;
4434492Sdlw struct dfmt *d;
4444492Sdlw {
4454492Sdlw 	printf(d->df_fmt, icvt((long)*b & 0377, d->df_radix, d->df_signed, d->df_field));
4464492Sdlw 	return(1);
4474492Sdlw }
4484492Sdlw 
4494492Sdlw c_put(cc, d)
4504492Sdlw char	*cc;
4514492Sdlw struct dfmt *d;
4524492Sdlw {
4534492Sdlw 	int c = *cc & 0377;
4544492Sdlw 	register char *s = "   ";
4554492Sdlw 
4564492Sdlw 	if(c>037 && c<0177) {
4574492Sdlw 		s[2] = *cc;
4584492Sdlw 		printf(d->df_fmt, s);
4594492Sdlw 		return(1);
4604492Sdlw 	}
4614492Sdlw 
4624492Sdlw 	switch(c) {
4634492Sdlw 	case '\0':
4644492Sdlw 		s = " \\0";
4654492Sdlw 		break;
4664492Sdlw 	case '\b':
4674492Sdlw 		s = " \\b";
4684492Sdlw 		break;
4694492Sdlw 	case '\f':
4704492Sdlw 		s = " \\f";
4714492Sdlw 		break;
4724492Sdlw 	case '\n':
4734492Sdlw 		s = " \\n";
4744492Sdlw 		break;
4754492Sdlw 	case '\r':
4764492Sdlw 		s = " \\r";
4774492Sdlw 		break;
4784492Sdlw 	case '\t':
4794492Sdlw 		s = " \\t";
4804492Sdlw 		break;
4814492Sdlw 	default:
4824492Sdlw 		s = icvt((long)c, d->df_radix, d->df_signed, d->df_field);
4834492Sdlw 	}
4844492Sdlw 	printf(d->df_fmt, s);
4854492Sdlw 	return(1);
4864492Sdlw }
4874492Sdlw 
4884492Sdlw /*
4894492Sdlw  * integer to ascii conversion
4904492Sdlw  *
4914492Sdlw  * This code has been rearranged to produce optimized runtime code.
4924492Sdlw  */
4934492Sdlw 
4944492Sdlw #define MAXINTLENGTH	32
4954492Sdlw static char	_digit[] = "0123456789abcdef";
4964492Sdlw static char	_icv_buf[MAXINTLENGTH+1];
4974492Sdlw static long	_mask = 0x7fffffff;
4984492Sdlw 
4994492Sdlw char *
5004492Sdlw icvt (value, radix, signed, ndigits)
5014492Sdlw long	value;
5024492Sdlw int	radix;
5034492Sdlw int	signed;
5044492Sdlw int	ndigits;
5054492Sdlw {
5064492Sdlw 	register long	val = value;
5074492Sdlw 	register long	rad = radix;
5084492Sdlw 	register char	*b = &_icv_buf[MAXINTLENGTH];
5094492Sdlw 	register char	*d = _digit;
5104492Sdlw 	register long	tmp1;
5114492Sdlw 	register long	tmp2;
5124492Sdlw 	long	rem;
5134492Sdlw 	long	kludge;
5144492Sdlw 	int	sign;
5154492Sdlw 
5164492Sdlw 	if (val == 0)
5174492Sdlw 	{
5184492Sdlw 		*--b = '0';
5194492Sdlw 		sign = 0;
5204492Sdlw 		goto done; /*return(b);*/
5214492Sdlw 	}
5224492Sdlw 
5234492Sdlw 	if (signed && (sign = (val < 0)))	/* signed conversion */
5244492Sdlw 	{
5254492Sdlw 		/*
5264492Sdlw 		 * It is necessary to do the first divide
5274492Sdlw 		 * before the absolute value, for the case -2^31
5284492Sdlw 		 *
5294492Sdlw 		 * This is actually what is being done...
5304492Sdlw 		 * tmp1 = (int)(val % rad);
5314492Sdlw 		 * val /= rad;
5324492Sdlw 		 * val = -val
5334492Sdlw 		 * *--b = d[-tmp1];
5344492Sdlw 		 */
5354492Sdlw 		tmp1 = val / rad;
5364492Sdlw 		*--b = d[(tmp1 * rad) - val];
5374492Sdlw 		val = -tmp1;
5384492Sdlw 	}
5394492Sdlw 	else				/* unsigned conversion */
5404492Sdlw 	{
5414492Sdlw 		sign = 0;
5424492Sdlw 		if (val < 0)
5434492Sdlw 		{	/* ALL THIS IS TO SIMULATE UNSIGNED LONG MOD & DIV */
5444492Sdlw 			kludge = _mask - (rad - 1);
5454492Sdlw 			val &= _mask;
5464492Sdlw 			/*
5474492Sdlw 			 * This is really what's being done...
5484492Sdlw 			 * rem = (kludge % rad) + (val % rad);
5494492Sdlw 			 * val = (kludge / rad) + (val / rad) + (rem / rad) + 1;
5504492Sdlw 			 * *--b = d[rem % rad];
5514492Sdlw 			 */
5524492Sdlw 			tmp1 = kludge / rad;
5534492Sdlw 			tmp2 = val / rad;
5544492Sdlw 			rem = (kludge - (tmp1 * rad)) + (val - (tmp2 * rad));
5554492Sdlw 			val = ++tmp1 + tmp2;
5564492Sdlw 			tmp1 = rem / rad;
5574492Sdlw 			val += tmp1;
5584492Sdlw 			*--b = d[rem - (tmp1 * rad)];
5594492Sdlw 		}
5604492Sdlw 	}
5614492Sdlw 
5624492Sdlw 	while (val)
5634492Sdlw 	{
5644492Sdlw 		/*
5654492Sdlw 		 * This is really what's being done ...
5664492Sdlw 		 * *--b = d[val % rad];
5674492Sdlw 		 * val /= rad;
5684492Sdlw 		 */
5694492Sdlw 		tmp1 = val / rad;
5704492Sdlw 		*--b = d[val - (tmp1 * rad)];
5714492Sdlw 		val = tmp1;
5724492Sdlw 	}
5734492Sdlw 
5744492Sdlw done:
5754492Sdlw 	if (sign)
5764492Sdlw 		*--b = '-';
5774492Sdlw 
5784492Sdlw 	tmp1 = ndigits - (&_icv_buf[MAXINTLENGTH] - b);
5794492Sdlw 	tmp2 = signed? ' ':'0';
5804492Sdlw 	while (tmp1 > 0)
5814492Sdlw 	{
5824492Sdlw 		*--b = tmp2;
5834492Sdlw 		tmp1--;
5844492Sdlw 	}
5854492Sdlw 
5864492Sdlw 	return(b);
5874492Sdlw }
5884492Sdlw 
589*4530Sdlw long
590*4530Sdlw get_addr(s)
5914492Sdlw register char *s;
5924492Sdlw {
5934492Sdlw 	register char *p;
594*4530Sdlw 	register long a;
5954492Sdlw 	register int d;
5964492Sdlw 
5974492Sdlw 	if (*s=='+')
5984492Sdlw 		s++;
5994492Sdlw 	if (*s=='x') {
6004492Sdlw 		s++;
6014492Sdlw 		addr_base = 16;
6024492Sdlw 	} else if (*s=='0' && s[1]=='x') {
6034492Sdlw 		s += 2;
6044492Sdlw 		addr_base = 16;
6054492Sdlw 	} else if (*s == '0')
6064492Sdlw 		addr_base = 8;
6074492Sdlw 	p = s;
6084492Sdlw 	while(*p) {
6094492Sdlw 		if (*p++=='.')
6104492Sdlw 			addr_base = 10;
6114492Sdlw 	}
6124492Sdlw 	for (a=0; *s; s++) {
6134492Sdlw 		d = *s;
6144492Sdlw 		if(d>='0' && d<='9')
6154492Sdlw 			a = a*addr_base + d - '0';
6164492Sdlw 		else if (d>='a' && d<='f' && addr_base==16)
6174492Sdlw 			a = a*addr_base + d + 10 - 'a';
6184492Sdlw 		else
6194492Sdlw 			break;
6204492Sdlw 	}
621*4530Sdlw 
6224492Sdlw 	if (*s == '.')
6234492Sdlw 		s++;
624*4530Sdlw 	if(*s=='b')
6254492Sdlw 		a *= 512;
626*4530Sdlw 	if(*s=='B')
627*4530Sdlw 		a *= 1024;
628*4530Sdlw 
629*4530Sdlw 	return(a);
630*4530Sdlw }
631*4530Sdlw 
632*4530Sdlw offset(a)
633*4530Sdlw long	a;
634*4530Sdlw {
6354492Sdlw 	if (canseek(stdin))
6364492Sdlw 		fseek(stdin, a, 0);
6374492Sdlw 	else
6384492Sdlw 		dumbseek(stdin, a);
6394492Sdlw }
6404492Sdlw 
6414492Sdlw dumbseek(s, offset)
6424492Sdlw FILE	*s;
6434492Sdlw long	offset;
6444492Sdlw {
6454492Sdlw 	char	buf[BUFSIZ];
6464492Sdlw 	int	n;
6474492Sdlw 	int	nr;
6484492Sdlw 
6494492Sdlw 	while (offset > 0)
6504492Sdlw 	{
6514492Sdlw 		nr = (offset > BUFSIZ) ? BUFSIZ : (int)offset;
6524492Sdlw 		if ((n = fread(buf, 1, nr, s)) != nr)
6534492Sdlw 		{
6544492Sdlw 			fprintf(stderr, "EOF\n");
6554492Sdlw 			exit(1);
6564492Sdlw 		}
6574492Sdlw 		offset -= n;
6584492Sdlw 	}
6594492Sdlw }
6604492Sdlw 
6614492Sdlw #include <sys/types.h>
6624492Sdlw #include <sys/stat.h>
6634492Sdlw 
6644492Sdlw canseek(f)
6654492Sdlw FILE	*f;
6664492Sdlw {
6674492Sdlw 	struct stat statb;
6684492Sdlw 
6694492Sdlw 	return( (fstat(fileno(f),&statb)==0) &&
6704492Sdlw 		(statb.st_nlink > 0) &&		/*!pipe*/
6714492Sdlw 		(!isatty(fileno(f))) );
6724492Sdlw }
673