xref: /csrg-svn/old/od/od.c (revision 4503)
1*4503Sdlw static char *sccsid = "@(#)od.c	5.3 (Berkeley) 10/14/81";
24492Sdlw /*
34492Sdlw  * od -- octal, hex, decimal, character dump of data in a file.
44492Sdlw  *
54492Sdlw  * usage:	od [-abcdDefFhHiIlLopPvxX] [file] [[+]offset[.][b]]
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 
764492Sdlw char	dbuf[16];
774492Sdlw char	lastdbuf[16];
784492Sdlw int	addr_base;
794492Sdlw long	addr;
804492Sdlw int	_parity = NO;
814492Sdlw char	fmt[]	= "            %s";	/* 12 blanks */
824492Sdlw char	*icvt();
834492Sdlw char	*underline();
844492Sdlw 
854492Sdlw main(argc, argv)
864492Sdlw char **argv;
874492Sdlw {
884492Sdlw 	register char *p;
894492Sdlw 	register char *l;
904492Sdlw 	register n, same;
914492Sdlw 	struct dfmt	*d;
924492Sdlw 	struct dfmt	**cv = conv_vec;
934492Sdlw 	int	showall = NO;
944492Sdlw 	int	field, llen, nelm;
954492Sdlw 	int	max_llen = 0;
964492Sdlw 
974492Sdlw 	argv++;
984492Sdlw 	max_llen = max_nelm = 0;
994492Sdlw 
1004492Sdlw 	if(argc > 1) {
1014492Sdlw 		p = *argv;
1024492Sdlw 		if(*p == '-') {
1034492Sdlw 			while(*++p != '\0') {
1044492Sdlw 				switch(*p) {
1054492Sdlw 				case 'a':
1064492Sdlw 					d = &ascii;
1074492Sdlw 					break;
1084492Sdlw 				case 'b':
1094492Sdlw 					d = &byte;
1104492Sdlw 					break;
1114492Sdlw 				case 'c':
1124492Sdlw 					d = &cchar;
1134492Sdlw 					break;
1144492Sdlw 				case 'd':
1154492Sdlw 					d = &u_s_dec;
1164492Sdlw 					break;
1174492Sdlw 				case 'D':
1184492Sdlw 					d = &u_l_dec;
1194492Sdlw 					break;
1204492Sdlw 				case 'e':
1214492Sdlw 				case 'F':
1224492Sdlw 					d = &dble;
1234492Sdlw 					break;
1244492Sdlw 				case 'f':
1254492Sdlw 					d = &flt;
1264492Sdlw 					break;
1274492Sdlw 				case 'h':
1284492Sdlw 				case 'x':
1294492Sdlw 					d = &u_s_hex;
1304492Sdlw 					break;
1314492Sdlw 				case 'H':
1324492Sdlw 				case 'X':
1334492Sdlw 					d = &u_l_hex;
1344492Sdlw 					break;
1354492Sdlw 				case 'i':
1364492Sdlw 					d = &s_s_dec;
1374492Sdlw 					break;
1384492Sdlw 				case 'I':
1394492Sdlw 				case 'l':
1404492Sdlw 				case 'L':
1414492Sdlw 					d = &s_l_dec;
1424492Sdlw 					break;
1434492Sdlw 				case 'o':
1444492Sdlw 					d = &u_s_oct;
1454492Sdlw 					break;
1464492Sdlw 				case 'O':
1474492Sdlw 					d = &u_l_oct;
1484492Sdlw 					break;
1494492Sdlw 				case 'p':
1504492Sdlw 					_parity = EVEN;
1514492Sdlw 					continue;
1524492Sdlw 				case 'P':
1534492Sdlw 					_parity = ODD;
1544492Sdlw 					continue;
1554492Sdlw 				case 'v':
1564492Sdlw 					showall = YES;
1574492Sdlw 					continue;
1584492Sdlw 				}
1594492Sdlw 				nelm = 16 / d->df_size;
1604492Sdlw 				llen = (d->df_field + 1) * nelm;
1614492Sdlw 				if (llen > max_llen)
1624492Sdlw 					max_llen = llen;
1634492Sdlw 				if (nelm > max_nelm)
1644492Sdlw 					max_nelm = nelm;
1654492Sdlw 				/*
1664492Sdlw 				 * nelm will always be a power of 2.
1674492Sdlw 				 * line length must always be multiple
1684492Sdlw 				 * of max_nelm.
1694492Sdlw 				 */
1704492Sdlw 				nelm = max_nelm - 1;
1714492Sdlw 				max_llen = (max_llen + nelm) & (~nelm);
1724492Sdlw 				if (addr_base == 0)
1734492Sdlw 					addr_base = d->df_radix;
1744492Sdlw 				*(cv++) = d;
1754492Sdlw 			}
1764492Sdlw 			argc--;
1774492Sdlw 			argv++;
1784492Sdlw 		}
1794492Sdlw 	}
1804492Sdlw 
1814492Sdlw 	if(cv == conv_vec) {
1824492Sdlw 		addr_base = 8;
1834492Sdlw 		*(cv++) = &u_s_oct;
1844492Sdlw 		max_llen = (16 / u_s_oct.df_size) * (u_s_oct.df_field + 1);
1854492Sdlw 	}
1864492Sdlw 	*cv = (struct dfmt *)0;
1874492Sdlw 
1884492Sdlw 	cv = conv_vec;
1894492Sdlw 	while (d = *cv++) {
1904492Sdlw 		nelm = 16 / d->df_size;
1914492Sdlw 		field = max_llen / nelm;
1924492Sdlw 		d->df_fmt = fmt + 12 - (field - d->df_field);
1934492Sdlw 	}
1944492Sdlw 
1954492Sdlw 	if(argc > 1 && **argv != '+') {
1964492Sdlw 		if (freopen(*argv, "r", stdin) == NULL) {
1974492Sdlw 			printf("od: cannot open %s\n", *argv);
1984492Sdlw 			exit(1);
1994492Sdlw 		}
2004492Sdlw 		argv++;
2014492Sdlw 		argc--;
2024492Sdlw 	}
2034492Sdlw 
2044492Sdlw 	if (argc > 1)
2054492Sdlw 		offset(*argv);
2064492Sdlw 
2074492Sdlw 	same = -1;
2084492Sdlw 	while ((n = fread(dbuf, 1, sizeof(dbuf), stdin)) > 0) {
2094492Sdlw 		if (same>=0 && strncmp(dbuf, lastdbuf, 16) == 0 && !showall) {
2104492Sdlw 			if (same==0) {
2114492Sdlw 				printf("*\n");
2124492Sdlw 				same = 1;
2134492Sdlw 			}
2144492Sdlw 		}
2154492Sdlw 		else {
2164492Sdlw 			line(n);
2174492Sdlw 			same = 0;
2184492Sdlw 			p = dbuf;
2194492Sdlw 			l = lastdbuf;
2204492Sdlw 			for (nelm=0; nelm<16; nelm++) {
2214492Sdlw 				*l++ = *p;
2224492Sdlw 				*p++ = '\0';
2234492Sdlw 			}
2244492Sdlw 		}
2254492Sdlw 		addr += n;
2264492Sdlw 	}
2274492Sdlw 	puts(icvt(addr, addr_base, UNSIGNED, 7));
2284492Sdlw }
2294492Sdlw 
2304492Sdlw line(n)
2314492Sdlw int	n;
2324492Sdlw {
2334492Sdlw 	register i, first;
2344492Sdlw 	register struct dfmt *c;
2354492Sdlw 	register struct dfmt **cv = conv_vec;
2364492Sdlw 
2374492Sdlw 	first = YES;
2384492Sdlw 	while (c = *cv++) {
2394492Sdlw 		if (first) {
2404492Sdlw 			printf("%s ", icvt(addr, addr_base, UNSIGNED, 7));
2414492Sdlw 			first = NO;
2424492Sdlw 		} else
2434492Sdlw 			putchar('\t');
2444492Sdlw 		i = 0;
2454492Sdlw 		while (i < n)
2464492Sdlw 			i += (*(c->df_put))(dbuf+i, c);
2474492Sdlw 		putchar('\n');
2484492Sdlw 	}
2494492Sdlw }
2504492Sdlw 
2514492Sdlw s_put(n, d)
2524492Sdlw short	*n;
2534492Sdlw struct dfmt	*d;
2544492Sdlw {
2554492Sdlw 	printf(d->df_fmt, icvt((long)*n, d->df_radix, d->df_signed, d->df_field));
2564492Sdlw 	return(d->df_size);
2574492Sdlw }
2584492Sdlw 
2594492Sdlw us_put(n, d)
2604492Sdlw unsigned short	*n;
2614492Sdlw struct dfmt	*d;
2624492Sdlw {
2634492Sdlw 	printf(d->df_fmt, icvt((long)*n, d->df_radix, d->df_signed, d->df_field));
2644492Sdlw 	return(d->df_size);
2654492Sdlw }
2664492Sdlw 
2674492Sdlw l_put(n, d)
2684492Sdlw long	*n;
2694492Sdlw struct dfmt	*d;
2704492Sdlw {
2714492Sdlw 	printf(d->df_fmt, icvt(*n, d->df_radix, d->df_signed, d->df_field));
2724492Sdlw 	return(d->df_size);
2734492Sdlw }
2744492Sdlw 
2754492Sdlw d_put(f, d)
2764492Sdlw double	*f;
2774492Sdlw struct dfmt *d;
2784492Sdlw {
2794492Sdlw 	char fbuf[24];
2804500Sdlw 	struct l { long n[2]; };
2814500Sdlw 
2824500Sdlw #if	vax
2834500Sdlw 	if ((((struct l *)f)->n[0] & 0xff00) == 0x8000)	/* Vax illegal f.p. */
2844500Sdlw 		sprintf(fbuf, "    %08x %08x",
2854500Sdlw 			((struct l *)f)->n[0], ((struct l *)f)->n[1]);
2864500Sdlw 	else
2874500Sdlw #endif
2884500Sdlw 
2894500Sdlw 		sprintf(fbuf, "%21.14e", *f);
2904492Sdlw 	printf(d->df_fmt, fbuf);
2914492Sdlw 	return(d->df_size);
2924492Sdlw }
2934492Sdlw 
2944492Sdlw f_put(f, d)
2954492Sdlw float	*f;
2964492Sdlw struct dfmt *d;
2974492Sdlw {
2984492Sdlw 	char fbuf[16];
2994500Sdlw 
3004500Sdlw #if	vax
3014500Sdlw 	if ((*(long *)f & 0xff00) == 0x8000)	/* Vax illegal f.p. form */
3024500Sdlw 		sprintf(fbuf, "      %08x", *(long *)f);
3034500Sdlw 	else
3044500Sdlw #endif
3054500Sdlw 		sprintf(fbuf, "%14.7e", *f);
3064492Sdlw 	printf(d->df_fmt, fbuf);
3074492Sdlw 	return(d->df_size);
3084492Sdlw }
3094492Sdlw 
3104492Sdlw 
3114492Sdlw char	asc_name[34][4] = {
3124492Sdlw 	"nul",
3134492Sdlw 	"soh",
3144492Sdlw 	"stx",
3154492Sdlw 	"etx",
3164492Sdlw 	"eot",
3174492Sdlw 	"enq",
3184492Sdlw 	"ack",
3194492Sdlw 	"bel",
3204492Sdlw 	" bs",
3214492Sdlw 	" ht",
3224492Sdlw 	" nl",
3234492Sdlw 	" vt",
3244492Sdlw 	" ff",
3254492Sdlw 	" cr",
3264492Sdlw 	" so",
3274492Sdlw 	" si",
3284492Sdlw 	"dle",
3294492Sdlw 	"dc1",
3304492Sdlw 	"dc2",
3314492Sdlw 	"dc3",
3324492Sdlw 	"dc4",
3334492Sdlw 	"nak",
3344492Sdlw 	"syn",
3354492Sdlw 	"etb",
3364492Sdlw 	"can",
3374492Sdlw 	" em",
3384492Sdlw 	"sub",
3394492Sdlw 	"esc",
3404492Sdlw 	" fs",
3414492Sdlw 	" gs",
3424492Sdlw 	" rs",
3434492Sdlw 	" us",
3444492Sdlw 	" sp",
3454492Sdlw 	"del"
3464492Sdlw };
3474492Sdlw 
3484492Sdlw a_put(cc, d)
3494492Sdlw char	*cc;
3504492Sdlw struct dfmt *d;
3514492Sdlw {
3524492Sdlw 	int c = *cc;
3534492Sdlw 	register char *s = "   ";
3544492Sdlw 	register pbit = parity((int)c & 0377);
3554492Sdlw 
3564492Sdlw 	c &= 0177;
3574492Sdlw 	if (c > ' ' && c < 0177)
3584492Sdlw 	{
3594492Sdlw 		s[2] = *cc;
3604492Sdlw 		if (pbit == _parity)
361*4503Sdlw 			printf(d->df_fmt, underline(s));
3624492Sdlw 		else
3634492Sdlw 			printf(d->df_fmt, s);
3644492Sdlw 	}
3654492Sdlw 	else
3664492Sdlw 	{
3674492Sdlw 		if (c == 0177)
3684492Sdlw 			c = ' ' + 1;
3694492Sdlw 		if (pbit == _parity)
370*4503Sdlw 			printf(d->df_fmt, underline(asc_name[c]));
3714492Sdlw 		else
3724492Sdlw 			printf(d->df_fmt, asc_name[c]);
3734492Sdlw 	}
3744492Sdlw 	return(1);
3754492Sdlw }
3764492Sdlw 
3774492Sdlw parity(word)
3784492Sdlw int	word;
3794492Sdlw {
3804492Sdlw 	register int p = 0;
3814492Sdlw 	register int w = word;
3824492Sdlw 
3834492Sdlw 	if (w)
3844492Sdlw 		do {
3854492Sdlw 			p ^= 1;
3864492Sdlw 		} while(w &= (~(-w)));
3874492Sdlw 	return (p? ODD:EVEN);
3884492Sdlw }
3894492Sdlw 
3904492Sdlw char *
391*4503Sdlw underline(s)
3924492Sdlw char	*s;
3934492Sdlw {
3944492Sdlw 	static char ulbuf[16];
3954492Sdlw 	register char *u = ulbuf;
3964492Sdlw 
397*4503Sdlw 	while (*s) {
398*4503Sdlw 		if (*s != ' ') {
3994492Sdlw 			*u++ = '_';
4004492Sdlw 			*u++ = '\b';
4014492Sdlw 		}
4024492Sdlw 		*u++ = *s++;
4034492Sdlw 	}
4044492Sdlw 	*u = '\0';
4054492Sdlw 	return(ulbuf);
4064492Sdlw }
4074492Sdlw 
4084492Sdlw b_put(b, d)
4094492Sdlw char	*b;
4104492Sdlw struct dfmt *d;
4114492Sdlw {
4124492Sdlw 	printf(d->df_fmt, icvt((long)*b & 0377, d->df_radix, d->df_signed, d->df_field));
4134492Sdlw 	return(1);
4144492Sdlw }
4154492Sdlw 
4164492Sdlw c_put(cc, d)
4174492Sdlw char	*cc;
4184492Sdlw struct dfmt *d;
4194492Sdlw {
4204492Sdlw 	int c = *cc & 0377;
4214492Sdlw 	register char *s = "   ";
4224492Sdlw 
4234492Sdlw 	if(c>037 && c<0177) {
4244492Sdlw 		s[2] = *cc;
4254492Sdlw 		printf(d->df_fmt, s);
4264492Sdlw 		return(1);
4274492Sdlw 	}
4284492Sdlw 
4294492Sdlw 	switch(c) {
4304492Sdlw 	case '\0':
4314492Sdlw 		s = " \\0";
4324492Sdlw 		break;
4334492Sdlw 	case '\b':
4344492Sdlw 		s = " \\b";
4354492Sdlw 		break;
4364492Sdlw 	case '\f':
4374492Sdlw 		s = " \\f";
4384492Sdlw 		break;
4394492Sdlw 	case '\n':
4404492Sdlw 		s = " \\n";
4414492Sdlw 		break;
4424492Sdlw 	case '\r':
4434492Sdlw 		s = " \\r";
4444492Sdlw 		break;
4454492Sdlw 	case '\t':
4464492Sdlw 		s = " \\t";
4474492Sdlw 		break;
4484492Sdlw 	default:
4494492Sdlw 		s = icvt((long)c, d->df_radix, d->df_signed, d->df_field);
4504492Sdlw 	}
4514492Sdlw 	printf(d->df_fmt, s);
4524492Sdlw 	return(1);
4534492Sdlw }
4544492Sdlw 
4554492Sdlw /*
4564492Sdlw  * integer to ascii conversion
4574492Sdlw  *
4584492Sdlw  * This code has been rearranged to produce optimized runtime code.
4594492Sdlw  */
4604492Sdlw 
4614492Sdlw #define MAXINTLENGTH	32
4624492Sdlw static char	_digit[] = "0123456789abcdef";
4634492Sdlw static char	_icv_buf[MAXINTLENGTH+1];
4644492Sdlw static long	_mask = 0x7fffffff;
4654492Sdlw 
4664492Sdlw char *
4674492Sdlw icvt (value, radix, signed, ndigits)
4684492Sdlw long	value;
4694492Sdlw int	radix;
4704492Sdlw int	signed;
4714492Sdlw int	ndigits;
4724492Sdlw {
4734492Sdlw 	register long	val = value;
4744492Sdlw 	register long	rad = radix;
4754492Sdlw 	register char	*b = &_icv_buf[MAXINTLENGTH];
4764492Sdlw 	register char	*d = _digit;
4774492Sdlw 	register long	tmp1;
4784492Sdlw 	register long	tmp2;
4794492Sdlw 	long	rem;
4804492Sdlw 	long	kludge;
4814492Sdlw 	int	sign;
4824492Sdlw 
4834492Sdlw 	if (val == 0)
4844492Sdlw 	{
4854492Sdlw 		*--b = '0';
4864492Sdlw 		sign = 0;
4874492Sdlw 		goto done; /*return(b);*/
4884492Sdlw 	}
4894492Sdlw 
4904492Sdlw 	if (signed && (sign = (val < 0)))	/* signed conversion */
4914492Sdlw 	{
4924492Sdlw 		/*
4934492Sdlw 		 * It is necessary to do the first divide
4944492Sdlw 		 * before the absolute value, for the case -2^31
4954492Sdlw 		 *
4964492Sdlw 		 * This is actually what is being done...
4974492Sdlw 		 * tmp1 = (int)(val % rad);
4984492Sdlw 		 * val /= rad;
4994492Sdlw 		 * val = -val
5004492Sdlw 		 * *--b = d[-tmp1];
5014492Sdlw 		 */
5024492Sdlw 		tmp1 = val / rad;
5034492Sdlw 		*--b = d[(tmp1 * rad) - val];
5044492Sdlw 		val = -tmp1;
5054492Sdlw 	}
5064492Sdlw 	else				/* unsigned conversion */
5074492Sdlw 	{
5084492Sdlw 		sign = 0;
5094492Sdlw 		if (val < 0)
5104492Sdlw 		{	/* ALL THIS IS TO SIMULATE UNSIGNED LONG MOD & DIV */
5114492Sdlw 			kludge = _mask - (rad - 1);
5124492Sdlw 			val &= _mask;
5134492Sdlw 			/*
5144492Sdlw 			 * This is really what's being done...
5154492Sdlw 			 * rem = (kludge % rad) + (val % rad);
5164492Sdlw 			 * val = (kludge / rad) + (val / rad) + (rem / rad) + 1;
5174492Sdlw 			 * *--b = d[rem % rad];
5184492Sdlw 			 */
5194492Sdlw 			tmp1 = kludge / rad;
5204492Sdlw 			tmp2 = val / rad;
5214492Sdlw 			rem = (kludge - (tmp1 * rad)) + (val - (tmp2 * rad));
5224492Sdlw 			val = ++tmp1 + tmp2;
5234492Sdlw 			tmp1 = rem / rad;
5244492Sdlw 			val += tmp1;
5254492Sdlw 			*--b = d[rem - (tmp1 * rad)];
5264492Sdlw 		}
5274492Sdlw 	}
5284492Sdlw 
5294492Sdlw 	while (val)
5304492Sdlw 	{
5314492Sdlw 		/*
5324492Sdlw 		 * This is really what's being done ...
5334492Sdlw 		 * *--b = d[val % rad];
5344492Sdlw 		 * val /= rad;
5354492Sdlw 		 */
5364492Sdlw 		tmp1 = val / rad;
5374492Sdlw 		*--b = d[val - (tmp1 * rad)];
5384492Sdlw 		val = tmp1;
5394492Sdlw 	}
5404492Sdlw 
5414492Sdlw done:
5424492Sdlw 	if (sign)
5434492Sdlw 		*--b = '-';
5444492Sdlw 
5454492Sdlw 	tmp1 = ndigits - (&_icv_buf[MAXINTLENGTH] - b);
5464492Sdlw 	tmp2 = signed? ' ':'0';
5474492Sdlw 	while (tmp1 > 0)
5484492Sdlw 	{
5494492Sdlw 		*--b = tmp2;
5504492Sdlw 		tmp1--;
5514492Sdlw 	}
5524492Sdlw 
5534492Sdlw 	return(b);
5544492Sdlw }
5554492Sdlw 
5564492Sdlw offset(s)
5574492Sdlw register char *s;
5584492Sdlw {
5594492Sdlw 	register char *p;
5604492Sdlw 	long a;
5614492Sdlw 	register int d;
5624492Sdlw 
5634492Sdlw 	if (*s=='+')
5644492Sdlw 		s++;
5654492Sdlw 	if (*s=='x') {
5664492Sdlw 		s++;
5674492Sdlw 		addr_base = 16;
5684492Sdlw 	} else if (*s=='0' && s[1]=='x') {
5694492Sdlw 		s += 2;
5704492Sdlw 		addr_base = 16;
5714492Sdlw 	} else if (*s == '0')
5724492Sdlw 		addr_base = 8;
5734492Sdlw 	p = s;
5744492Sdlw 	while(*p) {
5754492Sdlw 		if (*p++=='.')
5764492Sdlw 			addr_base = 10;
5774492Sdlw 	}
5784492Sdlw 	for (a=0; *s; s++) {
5794492Sdlw 		d = *s;
5804492Sdlw 		if(d>='0' && d<='9')
5814492Sdlw 			a = a*addr_base + d - '0';
5824492Sdlw 		else if (d>='a' && d<='f' && addr_base==16)
5834492Sdlw 			a = a*addr_base + d + 10 - 'a';
5844492Sdlw 		else
5854492Sdlw 			break;
5864492Sdlw 	}
5874492Sdlw 	if (*s == '.')
5884492Sdlw 		s++;
5894492Sdlw 	if(*s=='b' || *s=='B')
5904492Sdlw 		a *= 512;
5914492Sdlw 	if (canseek(stdin))
5924492Sdlw 		fseek(stdin, a, 0);
5934492Sdlw 	else
5944492Sdlw 		dumbseek(stdin, a);
5954492Sdlw 	addr = a;
5964492Sdlw }
5974492Sdlw 
5984492Sdlw dumbseek(s, offset)
5994492Sdlw FILE	*s;
6004492Sdlw long	offset;
6014492Sdlw {
6024492Sdlw 	char	buf[BUFSIZ];
6034492Sdlw 	int	n;
6044492Sdlw 	int	nr;
6054492Sdlw 
6064492Sdlw 	while (offset > 0)
6074492Sdlw 	{
6084492Sdlw 		nr = (offset > BUFSIZ) ? BUFSIZ : (int)offset;
6094492Sdlw 		if ((n = fread(buf, 1, nr, s)) != nr)
6104492Sdlw 		{
6114492Sdlw 			fprintf(stderr, "EOF\n");
6124492Sdlw 			exit(1);
6134492Sdlw 		}
6144492Sdlw 		offset -= n;
6154492Sdlw 	}
6164492Sdlw }
6174492Sdlw 
6184492Sdlw #include <sys/types.h>
6194492Sdlw #include <sys/stat.h>
6204492Sdlw 
6214492Sdlw canseek(f)
6224492Sdlw FILE	*f;
6234492Sdlw {
6244492Sdlw 	struct stat statb;
6254492Sdlw 
6264492Sdlw 	return( (fstat(fileno(f),&statb)==0) &&
6274492Sdlw 		(statb.st_nlink > 0) &&		/*!pipe*/
6284492Sdlw 		(!isatty(fileno(f))) );
6294492Sdlw }
630