xref: /csrg-svn/old/od/od.c (revision 4492)
1*4492Sdlw static char *sccsid = "@(#)od.c	5.1 (Berkeley) 10/13/81";
2*4492Sdlw /*
3*4492Sdlw  * od -- octal, hex, decimal, character dump of data in a file.
4*4492Sdlw  *
5*4492Sdlw  * usage:	od [-abcdDefFhHiIlLopPvxX] [file] [[+]offset[.][b]]
6*4492Sdlw  *
7*4492Sdlw  * where the option flags have the following meaning:
8*4492Sdlw  *   character	object	radix	signed?
9*4492Sdlw  *	a	byte	(10)	(n.a.)	ASCII named byte stream
10*4492Sdlw  *	b	byte	  8	 no	byte octal
11*4492Sdlw  *	c	byte	 (8)	(no)	character with octal non-graphic bytes
12*4492Sdlw  *	d	short	 10	 no
13*4492Sdlw  *	D	long	 10	 no
14*4492Sdlw  *	e,F	double	(10)		double precision floating pt.
15*4492Sdlw  *	f	float	(10)		single precision floating pt.
16*4492Sdlw  *	h,x	short	 16	 no
17*4492Sdlw  *	H,X	long	 16	 no
18*4492Sdlw  *	i	short	 10	yes
19*4492Sdlw  *	I,l,L	long	 10	yes
20*4492Sdlw  *	o	short	  8	 no	(default conversion)
21*4492Sdlw  *	O	long	  8	 no
22*4492Sdlw  *
23*4492Sdlw  *	p				indicate EVEN parity on 'a' conversion
24*4492Sdlw  *	P				indicate ODD parity on 'a' conversion
25*4492Sdlw  *	v				show all data - don't skip like lines.
26*4492Sdlw  *
27*4492Sdlw  * More than one format character may be given.
28*4492Sdlw  * If {file} is not specified, standard input is read.
29*4492Sdlw  * If {file} is not specified, then {offset} must start with '+'.
30*4492Sdlw  * {Offset} may be HEX (0xnnn), OCTAL (0nn), or decimal (nnn.); the default
31*4492Sdlw  * is the same as the address radix, which will be the same as the first
32*4492Sdlw  * object radix.
33*4492Sdlw  */
34*4492Sdlw 
35*4492Sdlw #include <stdio.h>
36*4492Sdlw 
37*4492Sdlw #define NO	0
38*4492Sdlw #define YES	1
39*4492Sdlw #define EVEN	-1
40*4492Sdlw #define ODD	1
41*4492Sdlw #define UNSIGNED 0
42*4492Sdlw #define SIGNED	1
43*4492Sdlw 
44*4492Sdlw int	a_put();
45*4492Sdlw int	b_put();
46*4492Sdlw int	c_put();
47*4492Sdlw int	s_put();
48*4492Sdlw int	us_put();
49*4492Sdlw int	l_put();
50*4492Sdlw int	f_put();
51*4492Sdlw int	d_put();
52*4492Sdlw 
53*4492Sdlw struct dfmt {
54*4492Sdlw 	int	df_field;	/* external field required for object */
55*4492Sdlw 	int	df_size;	/* size (bytes) of object */
56*4492Sdlw 	int	df_radix;	/* conversion radix */
57*4492Sdlw 	int	df_signed;	/* signed? flag */
58*4492Sdlw 	int	(*df_put)();	/* function to output object */
59*4492Sdlw 	char	*df_fmt;
60*4492Sdlw } *conv_vec[32];		/* vector of conversions to be done */
61*4492Sdlw 
62*4492Sdlw struct dfmt	ascii	= { 3, sizeof (char),   10,        0,  a_put, 0};
63*4492Sdlw struct dfmt	byte	= { 3, sizeof (char),    8, UNSIGNED,  b_put, 0};
64*4492Sdlw struct dfmt	cchar	= { 3, sizeof (char),    8, UNSIGNED,  c_put, 0};
65*4492Sdlw struct dfmt	u_s_oct	= { 6, sizeof (short),   8, UNSIGNED, us_put, 0};
66*4492Sdlw struct dfmt	u_s_dec	= { 5, sizeof (short),  10, UNSIGNED, us_put, 0};
67*4492Sdlw struct dfmt	u_s_hex	= { 4, sizeof (short),  16, UNSIGNED, us_put, 0};
68*4492Sdlw struct dfmt	u_l_oct	= {11, sizeof (long),    8, UNSIGNED,  l_put, 0};
69*4492Sdlw struct dfmt	u_l_dec	= {10, sizeof (long),   10, UNSIGNED,  l_put, 0};
70*4492Sdlw struct dfmt	u_l_hex	= { 8, sizeof (long),   16, UNSIGNED,  l_put, 0};
71*4492Sdlw struct dfmt	s_s_dec	= { 6, sizeof (short),  10,   SIGNED,  s_put, 0};
72*4492Sdlw struct dfmt	s_l_dec	= {11, sizeof (long),   10,   SIGNED,  l_put, 0};
73*4492Sdlw struct dfmt	flt	= {14, sizeof (float),  10,   SIGNED,  f_put, 0};
74*4492Sdlw struct dfmt	dble	= {21, sizeof (double), 10,   SIGNED,  d_put, 0};
75*4492Sdlw 
76*4492Sdlw char	dbuf[16];
77*4492Sdlw char	lastdbuf[16];
78*4492Sdlw int	addr_base;
79*4492Sdlw long	addr;
80*4492Sdlw int	_parity = NO;
81*4492Sdlw char	fmt[]	= "            %s";	/* 12 blanks */
82*4492Sdlw char	*icvt();
83*4492Sdlw char	*underline();
84*4492Sdlw 
85*4492Sdlw main(argc, argv)
86*4492Sdlw char **argv;
87*4492Sdlw {
88*4492Sdlw 	register char *p;
89*4492Sdlw 	register char *l;
90*4492Sdlw 	register n, same;
91*4492Sdlw 	struct dfmt	*d;
92*4492Sdlw 	struct dfmt	**cv = conv_vec;
93*4492Sdlw 	int	showall = NO;
94*4492Sdlw 	int	field, llen, nelm;
95*4492Sdlw 	int	max_llen = 0;
96*4492Sdlw 
97*4492Sdlw 	argv++;
98*4492Sdlw 	max_llen = max_nelm = 0;
99*4492Sdlw 
100*4492Sdlw 	if(argc > 1) {
101*4492Sdlw 		p = *argv;
102*4492Sdlw 		if(*p == '-') {
103*4492Sdlw 			while(*++p != '\0') {
104*4492Sdlw 				switch(*p) {
105*4492Sdlw 				case 'a':
106*4492Sdlw 					d = &ascii;
107*4492Sdlw 					break;
108*4492Sdlw 				case 'b':
109*4492Sdlw 					d = &byte;
110*4492Sdlw 					break;
111*4492Sdlw 				case 'c':
112*4492Sdlw 					d = &cchar;
113*4492Sdlw 					break;
114*4492Sdlw 				case 'd':
115*4492Sdlw 					d = &u_s_dec;
116*4492Sdlw 					break;
117*4492Sdlw 				case 'D':
118*4492Sdlw 					d = &u_l_dec;
119*4492Sdlw 					break;
120*4492Sdlw 				case 'e':
121*4492Sdlw 				case 'F':
122*4492Sdlw 					d = &dble;
123*4492Sdlw 					break;
124*4492Sdlw 				case 'f':
125*4492Sdlw 					d = &flt;
126*4492Sdlw 					break;
127*4492Sdlw 				case 'h':
128*4492Sdlw 				case 'x':
129*4492Sdlw 					d = &u_s_hex;
130*4492Sdlw 					break;
131*4492Sdlw 				case 'H':
132*4492Sdlw 				case 'X':
133*4492Sdlw 					d = &u_l_hex;
134*4492Sdlw 					break;
135*4492Sdlw 				case 'i':
136*4492Sdlw 					d = &s_s_dec;
137*4492Sdlw 					break;
138*4492Sdlw 				case 'I':
139*4492Sdlw 				case 'l':
140*4492Sdlw 				case 'L':
141*4492Sdlw 					d = &s_l_dec;
142*4492Sdlw 					break;
143*4492Sdlw 				case 'o':
144*4492Sdlw 					d = &u_s_oct;
145*4492Sdlw 					break;
146*4492Sdlw 				case 'O':
147*4492Sdlw 					d = &u_l_oct;
148*4492Sdlw 					break;
149*4492Sdlw 				case 'p':
150*4492Sdlw 					_parity = EVEN;
151*4492Sdlw 					continue;
152*4492Sdlw 				case 'P':
153*4492Sdlw 					_parity = ODD;
154*4492Sdlw 					continue;
155*4492Sdlw 				case 'v':
156*4492Sdlw 					showall = YES;
157*4492Sdlw 					continue;
158*4492Sdlw 				}
159*4492Sdlw 				nelm = 16 / d->df_size;
160*4492Sdlw 				llen = (d->df_field + 1) * nelm;
161*4492Sdlw 				if (llen > max_llen)
162*4492Sdlw 					max_llen = llen;
163*4492Sdlw 				if (nelm > max_nelm)
164*4492Sdlw 					max_nelm = nelm;
165*4492Sdlw 				/*
166*4492Sdlw 				 * nelm will always be a power of 2.
167*4492Sdlw 				 * line length must always be multiple
168*4492Sdlw 				 * of max_nelm.
169*4492Sdlw 				 */
170*4492Sdlw 				nelm = max_nelm - 1;
171*4492Sdlw 				max_llen = (max_llen + nelm) & (~nelm);
172*4492Sdlw 				if (addr_base == 0)
173*4492Sdlw 					addr_base = d->df_radix;
174*4492Sdlw 				*(cv++) = d;
175*4492Sdlw 			}
176*4492Sdlw 			argc--;
177*4492Sdlw 			argv++;
178*4492Sdlw 		}
179*4492Sdlw 	}
180*4492Sdlw 
181*4492Sdlw 	if(cv == conv_vec) {
182*4492Sdlw 		addr_base = 8;
183*4492Sdlw 		*(cv++) = &u_s_oct;
184*4492Sdlw 		max_llen = (16 / u_s_oct.df_size) * (u_s_oct.df_field + 1);
185*4492Sdlw 	}
186*4492Sdlw 	*cv = (struct dfmt *)0;
187*4492Sdlw 
188*4492Sdlw 	cv = conv_vec;
189*4492Sdlw 	while (d = *cv++) {
190*4492Sdlw 		nelm = 16 / d->df_size;
191*4492Sdlw 		field = max_llen / nelm;
192*4492Sdlw 		d->df_fmt = fmt + 12 - (field - d->df_field);
193*4492Sdlw 	}
194*4492Sdlw 
195*4492Sdlw 	if(argc > 1 && **argv != '+') {
196*4492Sdlw 		if (freopen(*argv, "r", stdin) == NULL) {
197*4492Sdlw 			printf("od: cannot open %s\n", *argv);
198*4492Sdlw 			exit(1);
199*4492Sdlw 		}
200*4492Sdlw 		argv++;
201*4492Sdlw 		argc--;
202*4492Sdlw 	}
203*4492Sdlw 
204*4492Sdlw 	if (argc > 1)
205*4492Sdlw 		offset(*argv);
206*4492Sdlw 
207*4492Sdlw 	same = -1;
208*4492Sdlw 	while ((n = fread(dbuf, 1, sizeof(dbuf), stdin)) > 0) {
209*4492Sdlw 		if (same>=0 && strncmp(dbuf, lastdbuf, 16) == 0 && !showall) {
210*4492Sdlw 			if (same==0) {
211*4492Sdlw 				printf("*\n");
212*4492Sdlw 				same = 1;
213*4492Sdlw 			}
214*4492Sdlw 		}
215*4492Sdlw 		else {
216*4492Sdlw 			line(n);
217*4492Sdlw 			same = 0;
218*4492Sdlw 			p = dbuf;
219*4492Sdlw 			l = lastdbuf;
220*4492Sdlw 			for (nelm=0; nelm<16; nelm++) {
221*4492Sdlw 				*l++ = *p;
222*4492Sdlw 				*p++ = '\0';
223*4492Sdlw 			}
224*4492Sdlw 		}
225*4492Sdlw 		addr += n;
226*4492Sdlw 	}
227*4492Sdlw 	puts(icvt(addr, addr_base, UNSIGNED, 7));
228*4492Sdlw }
229*4492Sdlw 
230*4492Sdlw line(n)
231*4492Sdlw int	n;
232*4492Sdlw {
233*4492Sdlw 	register i, first;
234*4492Sdlw 	register struct dfmt *c;
235*4492Sdlw 	register struct dfmt **cv = conv_vec;
236*4492Sdlw 
237*4492Sdlw 	first = YES;
238*4492Sdlw 	while (c = *cv++) {
239*4492Sdlw 		if (first) {
240*4492Sdlw 			printf("%s ", icvt(addr, addr_base, UNSIGNED, 7));
241*4492Sdlw 			first = NO;
242*4492Sdlw 		} else
243*4492Sdlw 			putchar('\t');
244*4492Sdlw 		i = 0;
245*4492Sdlw 		while (i < n)
246*4492Sdlw 			i += (*(c->df_put))(dbuf+i, c);
247*4492Sdlw 		putchar('\n');
248*4492Sdlw 	}
249*4492Sdlw }
250*4492Sdlw 
251*4492Sdlw s_put(n, d)
252*4492Sdlw short	*n;
253*4492Sdlw struct dfmt	*d;
254*4492Sdlw {
255*4492Sdlw 	printf(d->df_fmt, icvt((long)*n, d->df_radix, d->df_signed, d->df_field));
256*4492Sdlw 	return(d->df_size);
257*4492Sdlw }
258*4492Sdlw 
259*4492Sdlw us_put(n, d)
260*4492Sdlw unsigned short	*n;
261*4492Sdlw struct dfmt	*d;
262*4492Sdlw {
263*4492Sdlw 	printf(d->df_fmt, icvt((long)*n, d->df_radix, d->df_signed, d->df_field));
264*4492Sdlw 	return(d->df_size);
265*4492Sdlw }
266*4492Sdlw 
267*4492Sdlw l_put(n, d)
268*4492Sdlw long	*n;
269*4492Sdlw struct dfmt	*d;
270*4492Sdlw {
271*4492Sdlw 	printf(d->df_fmt, icvt(*n, d->df_radix, d->df_signed, d->df_field));
272*4492Sdlw 	return(d->df_size);
273*4492Sdlw }
274*4492Sdlw 
275*4492Sdlw d_put(f, d)
276*4492Sdlw double	*f;
277*4492Sdlw struct dfmt *d;
278*4492Sdlw {
279*4492Sdlw 	char fbuf[24];
280*4492Sdlw 	sprintf(fbuf, "%21.14e", *f);
281*4492Sdlw 	printf(d->df_fmt, fbuf);
282*4492Sdlw 	return(d->df_size);
283*4492Sdlw }
284*4492Sdlw 
285*4492Sdlw f_put(f, d)
286*4492Sdlw float	*f;
287*4492Sdlw struct dfmt *d;
288*4492Sdlw {
289*4492Sdlw 	char fbuf[16];
290*4492Sdlw 	sprintf(fbuf, "%14.7e", *f);
291*4492Sdlw 	printf(d->df_fmt, fbuf);
292*4492Sdlw 	return(d->df_size);
293*4492Sdlw }
294*4492Sdlw 
295*4492Sdlw 
296*4492Sdlw char	asc_name[34][4] = {
297*4492Sdlw 	"nul",
298*4492Sdlw 	"soh",
299*4492Sdlw 	"stx",
300*4492Sdlw 	"etx",
301*4492Sdlw 	"eot",
302*4492Sdlw 	"enq",
303*4492Sdlw 	"ack",
304*4492Sdlw 	"bel",
305*4492Sdlw 	" bs",
306*4492Sdlw 	" ht",
307*4492Sdlw 	" nl",
308*4492Sdlw 	" vt",
309*4492Sdlw 	" ff",
310*4492Sdlw 	" cr",
311*4492Sdlw 	" so",
312*4492Sdlw 	" si",
313*4492Sdlw 	"dle",
314*4492Sdlw 	"dc1",
315*4492Sdlw 	"dc2",
316*4492Sdlw 	"dc3",
317*4492Sdlw 	"dc4",
318*4492Sdlw 	"nak",
319*4492Sdlw 	"syn",
320*4492Sdlw 	"etb",
321*4492Sdlw 	"can",
322*4492Sdlw 	" em",
323*4492Sdlw 	"sub",
324*4492Sdlw 	"esc",
325*4492Sdlw 	" fs",
326*4492Sdlw 	" gs",
327*4492Sdlw 	" rs",
328*4492Sdlw 	" us",
329*4492Sdlw 	" sp",
330*4492Sdlw 	"del"
331*4492Sdlw };
332*4492Sdlw 
333*4492Sdlw a_put(cc, d)
334*4492Sdlw char	*cc;
335*4492Sdlw struct dfmt *d;
336*4492Sdlw {
337*4492Sdlw 	int c = *cc;
338*4492Sdlw 	register char *s = "   ";
339*4492Sdlw 	register pbit = parity((int)c & 0377);
340*4492Sdlw 
341*4492Sdlw 	c &= 0177;
342*4492Sdlw 	if (c > ' ' && c < 0177)
343*4492Sdlw 	{
344*4492Sdlw 		s[2] = *cc;
345*4492Sdlw 		if (pbit == _parity)
346*4492Sdlw 			printf(d->df_fmt, underline(s, 1));
347*4492Sdlw 		else
348*4492Sdlw 			printf(d->df_fmt, s);
349*4492Sdlw 	}
350*4492Sdlw 	else
351*4492Sdlw 	{
352*4492Sdlw 		if (c == 0177)
353*4492Sdlw 			c = ' ' + 1;
354*4492Sdlw 		if (pbit == _parity)
355*4492Sdlw 			printf(d->df_fmt, underline(asc_name[c], 3));
356*4492Sdlw 		else
357*4492Sdlw 			printf(d->df_fmt, asc_name[c]);
358*4492Sdlw 	}
359*4492Sdlw 	return(1);
360*4492Sdlw }
361*4492Sdlw 
362*4492Sdlw parity(word)
363*4492Sdlw int	word;
364*4492Sdlw {
365*4492Sdlw 	register int p = 0;
366*4492Sdlw 	register int w = word;
367*4492Sdlw 
368*4492Sdlw 	if (w)
369*4492Sdlw 		do {
370*4492Sdlw 			p ^= 1;
371*4492Sdlw 		} while(w &= (~(-w)));
372*4492Sdlw 	return (p? ODD:EVEN);
373*4492Sdlw }
374*4492Sdlw 
375*4492Sdlw char *
376*4492Sdlw underline(s, n)
377*4492Sdlw char	*s;
378*4492Sdlw int	n;
379*4492Sdlw {
380*4492Sdlw 	static char ulbuf[16];
381*4492Sdlw 	register char *u = ulbuf;
382*4492Sdlw 
383*4492Sdlw 	while (n--) {
384*4492Sdlw 		if (*s && *s != ' ') {
385*4492Sdlw 			*u++ = '_';
386*4492Sdlw 			*u++ = '\b';
387*4492Sdlw 		}
388*4492Sdlw 		*u++ = *s++;
389*4492Sdlw 	}
390*4492Sdlw 	*u = '\0';
391*4492Sdlw 	return(ulbuf);
392*4492Sdlw }
393*4492Sdlw 
394*4492Sdlw b_put(b, d)
395*4492Sdlw char	*b;
396*4492Sdlw struct dfmt *d;
397*4492Sdlw {
398*4492Sdlw 	printf(d->df_fmt, icvt((long)*b & 0377, d->df_radix, d->df_signed, d->df_field));
399*4492Sdlw 	return(1);
400*4492Sdlw }
401*4492Sdlw 
402*4492Sdlw c_put(cc, d)
403*4492Sdlw char	*cc;
404*4492Sdlw struct dfmt *d;
405*4492Sdlw {
406*4492Sdlw 	int c = *cc & 0377;
407*4492Sdlw 	register char *s = "   ";
408*4492Sdlw 
409*4492Sdlw 	if(c>037 && c<0177) {
410*4492Sdlw 		s[2] = *cc;
411*4492Sdlw 		printf(d->df_fmt, s);
412*4492Sdlw 		return(1);
413*4492Sdlw 	}
414*4492Sdlw 
415*4492Sdlw 	switch(c) {
416*4492Sdlw 	case '\0':
417*4492Sdlw 		s = " \\0";
418*4492Sdlw 		break;
419*4492Sdlw 	case '\b':
420*4492Sdlw 		s = " \\b";
421*4492Sdlw 		break;
422*4492Sdlw 	case '\f':
423*4492Sdlw 		s = " \\f";
424*4492Sdlw 		break;
425*4492Sdlw 	case '\n':
426*4492Sdlw 		s = " \\n";
427*4492Sdlw 		break;
428*4492Sdlw 	case '\r':
429*4492Sdlw 		s = " \\r";
430*4492Sdlw 		break;
431*4492Sdlw 	case '\t':
432*4492Sdlw 		s = " \\t";
433*4492Sdlw 		break;
434*4492Sdlw 	default:
435*4492Sdlw 		s = icvt((long)c, d->df_radix, d->df_signed, d->df_field);
436*4492Sdlw 	}
437*4492Sdlw 	printf(d->df_fmt, s);
438*4492Sdlw 	return(1);
439*4492Sdlw }
440*4492Sdlw 
441*4492Sdlw /*
442*4492Sdlw  * integer to ascii conversion
443*4492Sdlw  *
444*4492Sdlw  * This code has been rearranged to produce optimized runtime code.
445*4492Sdlw  */
446*4492Sdlw 
447*4492Sdlw #define MAXINTLENGTH	32
448*4492Sdlw static char	_digit[] = "0123456789abcdef";
449*4492Sdlw static char	_icv_buf[MAXINTLENGTH+1];
450*4492Sdlw static long	_mask = 0x7fffffff;
451*4492Sdlw 
452*4492Sdlw char *
453*4492Sdlw icvt (value, radix, signed, ndigits)
454*4492Sdlw long	value;
455*4492Sdlw int	radix;
456*4492Sdlw int	signed;
457*4492Sdlw int	ndigits;
458*4492Sdlw {
459*4492Sdlw 	register long	val = value;
460*4492Sdlw 	register long	rad = radix;
461*4492Sdlw 	register char	*b = &_icv_buf[MAXINTLENGTH];
462*4492Sdlw 	register char	*d = _digit;
463*4492Sdlw 	register long	tmp1;
464*4492Sdlw 	register long	tmp2;
465*4492Sdlw 	long	rem;
466*4492Sdlw 	long	kludge;
467*4492Sdlw 	int	sign;
468*4492Sdlw 
469*4492Sdlw 	if (val == 0)
470*4492Sdlw 	{
471*4492Sdlw 		*--b = '0';
472*4492Sdlw 		sign = 0;
473*4492Sdlw 		goto done; /*return(b);*/
474*4492Sdlw 	}
475*4492Sdlw 
476*4492Sdlw 	if (signed && (sign = (val < 0)))	/* signed conversion */
477*4492Sdlw 	{
478*4492Sdlw 		/*
479*4492Sdlw 		 * It is necessary to do the first divide
480*4492Sdlw 		 * before the absolute value, for the case -2^31
481*4492Sdlw 		 *
482*4492Sdlw 		 * This is actually what is being done...
483*4492Sdlw 		 * tmp1 = (int)(val % rad);
484*4492Sdlw 		 * val /= rad;
485*4492Sdlw 		 * val = -val
486*4492Sdlw 		 * *--b = d[-tmp1];
487*4492Sdlw 		 */
488*4492Sdlw 		tmp1 = val / rad;
489*4492Sdlw 		*--b = d[(tmp1 * rad) - val];
490*4492Sdlw 		val = -tmp1;
491*4492Sdlw 	}
492*4492Sdlw 	else				/* unsigned conversion */
493*4492Sdlw 	{
494*4492Sdlw 		sign = 0;
495*4492Sdlw 		if (val < 0)
496*4492Sdlw 		{	/* ALL THIS IS TO SIMULATE UNSIGNED LONG MOD & DIV */
497*4492Sdlw 			kludge = _mask - (rad - 1);
498*4492Sdlw 			val &= _mask;
499*4492Sdlw 			/*
500*4492Sdlw 			 * This is really what's being done...
501*4492Sdlw 			 * rem = (kludge % rad) + (val % rad);
502*4492Sdlw 			 * val = (kludge / rad) + (val / rad) + (rem / rad) + 1;
503*4492Sdlw 			 * *--b = d[rem % rad];
504*4492Sdlw 			 */
505*4492Sdlw 			tmp1 = kludge / rad;
506*4492Sdlw 			tmp2 = val / rad;
507*4492Sdlw 			rem = (kludge - (tmp1 * rad)) + (val - (tmp2 * rad));
508*4492Sdlw 			val = ++tmp1 + tmp2;
509*4492Sdlw 			tmp1 = rem / rad;
510*4492Sdlw 			val += tmp1;
511*4492Sdlw 			*--b = d[rem - (tmp1 * rad)];
512*4492Sdlw 		}
513*4492Sdlw 	}
514*4492Sdlw 
515*4492Sdlw 	while (val)
516*4492Sdlw 	{
517*4492Sdlw 		/*
518*4492Sdlw 		 * This is really what's being done ...
519*4492Sdlw 		 * *--b = d[val % rad];
520*4492Sdlw 		 * val /= rad;
521*4492Sdlw 		 */
522*4492Sdlw 		tmp1 = val / rad;
523*4492Sdlw 		*--b = d[val - (tmp1 * rad)];
524*4492Sdlw 		val = tmp1;
525*4492Sdlw 	}
526*4492Sdlw 
527*4492Sdlw done:
528*4492Sdlw 	if (sign)
529*4492Sdlw 		*--b = '-';
530*4492Sdlw 
531*4492Sdlw 	tmp1 = ndigits - (&_icv_buf[MAXINTLENGTH] - b);
532*4492Sdlw 	tmp2 = signed? ' ':'0';
533*4492Sdlw 	while (tmp1 > 0)
534*4492Sdlw 	{
535*4492Sdlw 		*--b = tmp2;
536*4492Sdlw 		tmp1--;
537*4492Sdlw 	}
538*4492Sdlw 
539*4492Sdlw 	return(b);
540*4492Sdlw }
541*4492Sdlw 
542*4492Sdlw offset(s)
543*4492Sdlw register char *s;
544*4492Sdlw {
545*4492Sdlw 	register char *p;
546*4492Sdlw 	long a;
547*4492Sdlw 	register int d;
548*4492Sdlw 
549*4492Sdlw 	if (*s=='+')
550*4492Sdlw 		s++;
551*4492Sdlw 	if (*s=='x') {
552*4492Sdlw 		s++;
553*4492Sdlw 		addr_base = 16;
554*4492Sdlw 	} else if (*s=='0' && s[1]=='x') {
555*4492Sdlw 		s += 2;
556*4492Sdlw 		addr_base = 16;
557*4492Sdlw 	} else if (*s == '0')
558*4492Sdlw 		addr_base = 8;
559*4492Sdlw 	p = s;
560*4492Sdlw 	while(*p) {
561*4492Sdlw 		if (*p++=='.')
562*4492Sdlw 			addr_base = 10;
563*4492Sdlw 	}
564*4492Sdlw 	for (a=0; *s; s++) {
565*4492Sdlw 		d = *s;
566*4492Sdlw 		if(d>='0' && d<='9')
567*4492Sdlw 			a = a*addr_base + d - '0';
568*4492Sdlw 		else if (d>='a' && d<='f' && addr_base==16)
569*4492Sdlw 			a = a*addr_base + d + 10 - 'a';
570*4492Sdlw 		else
571*4492Sdlw 			break;
572*4492Sdlw 	}
573*4492Sdlw 	if (*s == '.')
574*4492Sdlw 		s++;
575*4492Sdlw 	if(*s=='b' || *s=='B')
576*4492Sdlw 		a *= 512;
577*4492Sdlw 	if (canseek(stdin))
578*4492Sdlw 		fseek(stdin, a, 0);
579*4492Sdlw 	else
580*4492Sdlw 		dumbseek(stdin, a);
581*4492Sdlw 	addr = a;
582*4492Sdlw }
583*4492Sdlw 
584*4492Sdlw dumbseek(s, offset)
585*4492Sdlw FILE	*s;
586*4492Sdlw long	offset;
587*4492Sdlw {
588*4492Sdlw 	char	buf[BUFSIZ];
589*4492Sdlw 	int	n;
590*4492Sdlw 	int	nr;
591*4492Sdlw 
592*4492Sdlw 	while (offset > 0)
593*4492Sdlw 	{
594*4492Sdlw 		nr = (offset > BUFSIZ) ? BUFSIZ : (int)offset;
595*4492Sdlw 		if ((n = fread(buf, 1, nr, s)) != nr)
596*4492Sdlw 		{
597*4492Sdlw 			fprintf(stderr, "EOF\n");
598*4492Sdlw 			exit(1);
599*4492Sdlw 		}
600*4492Sdlw 		offset -= n;
601*4492Sdlw 	}
602*4492Sdlw }
603*4492Sdlw 
604*4492Sdlw #include <sys/types.h>
605*4492Sdlw #include <sys/stat.h>
606*4492Sdlw 
607*4492Sdlw canseek(f)
608*4492Sdlw FILE	*f;
609*4492Sdlw {
610*4492Sdlw 	struct stat statb;
611*4492Sdlw 
612*4492Sdlw 	return( (fstat(fileno(f),&statb)==0) &&
613*4492Sdlw 		(statb.st_nlink > 0) &&		/*!pipe*/
614*4492Sdlw 		(!isatty(fileno(f))) );
615*4492Sdlw }
616