made handling of "mailname" global variable simpler -- now it
[unix-history] / usr / src / old / od / od.c
CommitLineData
3dbf8875 1static char *sccsid = "@(#)od.c 5.8 (Berkeley) %G%";
3718e103
DW
2/*
3 * od -- octal, hex, decimal, character dump of data in a file.
4 *
0e88daf2 5 * usage: od [-abBcdDefFhHiIlLopPsvxX] [file] [[+]offset[.][b] [label]]
3718e103
DW
6 *
7 * where the option flags have the following meaning:
8 * character object radix signed?
9 * a byte (10) (n.a.) ASCII named byte stream
10 * b byte 8 no byte octal
11 * c byte (8) (no) character with octal non-graphic bytes
12 * d short 10 no
13 * D long 10 no
14 * e,F double (10) double precision floating pt.
15 * f float (10) single precision floating pt.
16 * h,x short 16 no
17 * H,X long 16 no
18 * i short 10 yes
19 * I,l,L long 10 yes
0e88daf2 20 * o,B short 8 no (default conversion)
3718e103 21 * O long 8 no
0e88daf2 22 * s string (8) ASCII graphic strings
3718e103
DW
23 *
24 * p indicate EVEN parity on 'a' conversion
25 * P indicate ODD parity on 'a' conversion
26 * v show all data - don't skip like lines.
27 *
28 * More than one format character may be given.
29 * If {file} is not specified, standard input is read.
30 * If {file} is not specified, then {offset} must start with '+'.
31 * {Offset} may be HEX (0xnnn), OCTAL (0nn), or decimal (nnn.); the default
32 * is the same as the address radix, which will be the same as the first
33 * object radix.
34 */
35
36#include <stdio.h>
37
0e88daf2
DW
38#define DBUF_SIZE 16
39#define NO 0
40#define YES 1
41#define EVEN -1
42#define ODD 1
43#define UNSIGNED 0
44#define SIGNED 1
45#define PADDR 1
46#define MIN_SLEN 3
3718e103
DW
47
48int a_put();
49int b_put();
50int c_put();
51int s_put();
52int us_put();
53int l_put();
54int f_put();
55int d_put();
0e88daf2 56int st_put();
3718e103
DW
57
58struct dfmt {
59 int df_field; /* external field required for object */
60 int df_size; /* size (bytes) of object */
61 int df_radix; /* conversion radix */
62 int df_signed; /* signed? flag */
0e88daf2 63 int df_paddr; /* "put address on each line?" flag */
3718e103 64 int (*df_put)(); /* function to output object */
0e88daf2 65 char *df_fmt; /* output string format */
3718e103
DW
66} *conv_vec[32]; /* vector of conversions to be done */
67
0e88daf2
DW
68struct dfmt ascii = { 3, sizeof (char), 10, 0, PADDR, a_put, 0};
69struct dfmt byte = { 3, sizeof (char), 8, UNSIGNED, PADDR, b_put, 0};
70struct dfmt cchar = { 3, sizeof (char), 8, UNSIGNED, PADDR, c_put, 0};
71struct dfmt u_s_oct = { 6, sizeof (short), 8, UNSIGNED, PADDR, us_put, 0};
72struct dfmt u_s_dec = { 5, sizeof (short), 10, UNSIGNED, PADDR, us_put, 0};
73struct dfmt u_s_hex = { 4, sizeof (short), 16, UNSIGNED, PADDR, us_put, 0};
74struct dfmt u_l_oct = {11, sizeof (long), 8, UNSIGNED, PADDR, l_put, 0};
75struct dfmt u_l_dec = {10, sizeof (long), 10, UNSIGNED, PADDR, l_put, 0};
76struct dfmt u_l_hex = { 8, sizeof (long), 16, UNSIGNED, PADDR, l_put, 0};
77struct dfmt s_s_dec = { 6, sizeof (short), 10, SIGNED, PADDR, s_put, 0};
78struct dfmt s_l_dec = {11, sizeof (long), 10, SIGNED, PADDR, l_put, 0};
79struct dfmt flt = {14, sizeof (float), 10, SIGNED, PADDR, f_put, 0};
80struct dfmt dble = {21, sizeof (double), 10, SIGNED, PADDR, d_put, 0};
81struct dfmt string = { 0, 0, 8, 0, NO, st_put, 0};
82
83
84char usage[] = "usage: od [-abcdfhilopsvx] [file] [[+]offset[.][b] [label]]";
85char dbuf[DBUF_SIZE];
86char lastdbuf[DBUF_SIZE];
7f1bc61f 87int addr_base = 8; /* default address base is OCTAL */
3718e103 88long addr;
1fd5a2d4 89long label = -1L;
3718e103
DW
90int _parity = NO;
91char fmt[] = " %s"; /* 12 blanks */
92char *icvt();
0e88daf2 93char *scvt();
3718e103 94char *underline();
1fd5a2d4
DW
95long get_addr();
96
3718e103 97
0e88daf2
DW
98/*
99 * special form of _ctype
100 */
101
102#define A 01
103#define G 02
104#define D 04
105#define P 010
106#define X 020
107#define isdigit(c) (_ctype[c] & D)
108#define isascii(c) (_ctype[c] & A)
109#define isgraphic(c) (_ctype[c] & G)
110#define isprint(c) (_ctype[c] & P)
111#define ishex(c) (_ctype[c] & (X|D))
112
113char _ctype[256] = {
114/* 000 */ 0, 0, 0, 0, 0, 0, 0, 0,
115/* 010 */ A, A, A, 0, A, A, 0, 0,
116/* 020 */ 0, 0, 0, 0, 0, 0, 0, 0,
117/* 030 */ 0, 0, 0, 0, 0, 0, 0, 0,
118/* 040 */ P|A, P|G|A, P|G|A, P|G|A, P|G|A, P|G|A, P|G|A, P|G|A,
119/* 050 */ P|G|A, P|G|A, P|G|A, P|G|A, P|G|A, P|G|A, P|G|A, P|G|A,
120/* 060 */ P|G|D|A,P|G|D|A,P|G|D|A,P|G|D|A,P|G|D|A,P|G|D|A,P|G|D|A,P|G|D|A,
121/* 070 */ P|G|D|A,P|G|D|A, P|G|A, P|G|A, P|G|A, P|G|A, P|G|A, P|G|A,
122/* 100 */ P|G|A, P|G|A, P|G|A, P|G|A, P|G|A, P|G|A, P|G|A, P|G|A,
123/* 110 */ P|G|A, P|G|A, P|G|A, P|G|A, P|G|A, P|G|A, P|G|A, P|G|A,
124/* 120 */ P|G|A, P|G|A, P|G|A, P|G|A, P|G|A, P|G|A, P|G|A, P|G|A,
125/* 130 */ P|G|A, P|G|A, P|G|A, P|G|A, P|G|A, P|G|A, P|G|A, P|G|A,
126/* 140 */ P|G|A,X|P|G|A,X|P|G|A,X|P|G|A,X|P|G|A,X|P|G|A,X|P|G|A, P|G|A,
127/* 150 */ P|G|A, P|G|A, P|G|A, P|G|A, P|G|A, P|G|A, P|G|A, P|G|A,
128/* 160 */ P|G|A, P|G|A, P|G|A, P|G|A, P|G|A, P|G|A, P|G|A, P|G|A,
129/* 170 */ P|G|A, P|G|A, P|G|A, P|G|A, P|G|A, P|G|A, P|G|A, 0,
130/* 200 */ 0, 0, 0, 0, 0, 0, 0, 0,
131/* 210 */ 0, 0, 0, 0, 0, 0, 0, 0,
132/* 220 */ 0, 0, 0, 0, 0, 0, 0, 0,
133/* 230 */ 0, 0, 0, 0, 0, 0, 0, 0,
134/* 240 */ 0, 0, 0, 0, 0, 0, 0, 0,
135/* 250 */ 0, 0, 0, 0, 0, 0, 0, 0,
136/* 260 */ 0, 0, 0, 0, 0, 0, 0, 0,
137/* 270 */ 0, 0, 0, 0, 0, 0, 0, 0,
138/* 300 */ 0, 0, 0, 0, 0, 0, 0, 0,
139/* 310 */ 0, 0, 0, 0, 0, 0, 0, 0,
140/* 320 */ 0, 0, 0, 0, 0, 0, 0, 0,
141/* 330 */ 0, 0, 0, 0, 0, 0, 0, 0,
142/* 340 */ 0, 0, 0, 0, 0, 0, 0, 0,
143/* 350 */ 0, 0, 0, 0, 0, 0, 0, 0,
144/* 360 */ 0, 0, 0, 0, 0, 0, 0, 0,
145/* 370 */ 0, 0, 0, 0, 0, 0, 0, 0,
146};
147
148
3718e103 149main(argc, argv)
0e88daf2
DW
150int argc;
151char **argv;
3718e103
DW
152{
153 register char *p;
154 register char *l;
155 register n, same;
156 struct dfmt *d;
157 struct dfmt **cv = conv_vec;
158 int showall = NO;
159 int field, llen, nelm;
160 int max_llen = 0;
161
162 argv++;
1fd5a2d4 163 argc--;
3718e103
DW
164 max_llen = max_nelm = 0;
165
0e88daf2
DW
166 if(argc > 0)
167 {
3718e103 168 p = *argv;
0e88daf2
DW
169 if(*p == '-')
170 {
171 while(*++p != '\0')
172 {
173 switch(*p)
174 {
3718e103
DW
175 case 'a':
176 d = &ascii;
177 break;
178 case 'b':
179 d = &byte;
180 break;
181 case 'c':
182 d = &cchar;
183 break;
184 case 'd':
185 d = &u_s_dec;
186 break;
187 case 'D':
188 d = &u_l_dec;
189 break;
190 case 'e':
191 case 'F':
192 d = &dble;
193 break;
194 case 'f':
195 d = &flt;
196 break;
197 case 'h':
198 case 'x':
199 d = &u_s_hex;
200 break;
201 case 'H':
202 case 'X':
203 d = &u_l_hex;
204 break;
205 case 'i':
206 d = &s_s_dec;
207 break;
208 case 'I':
209 case 'l':
210 case 'L':
211 d = &s_l_dec;
212 break;
213 case 'o':
0e88daf2 214 case 'B':
3718e103
DW
215 d = &u_s_oct;
216 break;
217 case 'O':
218 d = &u_l_oct;
219 break;
220 case 'p':
221 _parity = EVEN;
222 continue;
223 case 'P':
224 _parity = ODD;
225 continue;
0e88daf2
DW
226 case 's':
227 d = &string;
228 *(cv++) = d;
0e88daf2
DW
229 while (isdigit(p[1]))
230 d->df_size = (10 * d->df_size) + (*++p - '0');
231 if (d->df_size <= 0)
232 d->df_size = MIN_SLEN;
233 showall = YES;
234 continue;
3718e103
DW
235 case 'v':
236 showall = YES;
237 continue;
1fd5a2d4
DW
238 default:
239 printf("od: bad flag -%c\n", *p);
240 puts(usage);
241 exit(1);
3718e103 242 }
0e88daf2 243 nelm = DBUF_SIZE / d->df_size;
3718e103
DW
244 llen = (d->df_field + 1) * nelm;
245 if (llen > max_llen)
246 max_llen = llen;
247 if (nelm > max_nelm)
248 max_nelm = nelm;
249 /*
250 * nelm will always be a power of 2.
251 * line length must always be multiple
252 * of max_nelm.
253 */
254 nelm = max_nelm - 1;
255 max_llen = (max_llen + nelm) & (~nelm);
3718e103
DW
256 *(cv++) = d;
257 }
258 argc--;
259 argv++;
260 }
261 }
262
0e88daf2
DW
263 /*
264 * if nothing spec'd, setup default conversion.
265 */
266 if(cv == conv_vec)
267 {
3718e103 268 *(cv++) = &u_s_oct;
0e88daf2 269 max_nelm = DBUF_SIZE / u_s_oct.df_size;
1fd5a2d4 270 max_llen = max_nelm * (u_s_oct.df_field + 1);
3718e103
DW
271 }
272 *cv = (struct dfmt *)0;
273
0e88daf2
DW
274 /*
275 * setup df_fmt to point to uniform output fields.
276 */
3718e103 277 cv = conv_vec;
0e88daf2
DW
278 while (d = *cv++)
279 {
280 if (d->df_field) /* only if external field is known */
281 {
282 nelm = DBUF_SIZE / d->df_size;
283 field = max_llen / nelm;
284 d->df_fmt = fmt + 12 - (field - d->df_field);
285 }
3718e103
DW
286 }
287
0e88daf2
DW
288 /*
289 * input file specified ?
290 */
291 if(argc > 0 && **argv != '+')
292 {
293 if (freopen(*argv, "r", stdin) == NULL)
294 {
3718e103
DW
295 printf("od: cannot open %s\n", *argv);
296 exit(1);
297 }
298 argv++;
299 argc--;
300 }
301
0e88daf2
DW
302 /*
303 * check for possible offset [label]
304 */
1fd5a2d4
DW
305 if (argc > 0)
306 {
307 addr = get_addr(*argv);
308 offset(addr);
309 argv++;
310 argc--;
311
312 if (argc > 0)
313 label = get_addr(*argv);
314 }
3718e103 315
0e88daf2
DW
316 /*
317 * main dump loop
318 */
3718e103 319 same = -1;
0e88daf2
DW
320 while ((n = fread(dbuf, 1, DBUF_SIZE, stdin)) > 0)
321 {
7f1bc61f 322 if (same>=0 && bufncmp(dbuf, lastdbuf, DBUF_SIZE) == 0 && !showall)
0e88daf2
DW
323 {
324 if (same==0)
325 {
3718e103
DW
326 printf("*\n");
327 same = 1;
328 }
329 }
0e88daf2
DW
330 else
331 {
3718e103
DW
332 line(n);
333 same = 0;
334 p = dbuf;
335 l = lastdbuf;
0e88daf2
DW
336 for (nelm = 0; nelm < DBUF_SIZE; nelm++)
337 {
3718e103
DW
338 *l++ = *p;
339 *p++ = '\0';
340 }
341 }
342 addr += n;
1fd5a2d4
DW
343 if (label >= 0)
344 label += n;
3718e103 345 }
0e88daf2
DW
346
347 /*
348 * Some conversions require "flushing".
349 */
350 n = 0;
351 for (cv = conv_vec; *cv; cv++)
352 {
353 if ((*cv)->df_paddr)
354 {
355 if (n++ == 0)
356 put_addr(addr, label, '\n');
357 }
358 else
359 (*((*cv)->df_put))(0, *cv);
360 }
1fd5a2d4
DW
361}
362
0e88daf2
DW
363put_addr(a, l, c)
364long a;
365long l;
1fd5a2d4
DW
366char c;
367{
0e88daf2
DW
368 fputs(icvt(a, addr_base, UNSIGNED, 7), stdout);
369 if (l >= 0)
370 printf(" (%s)", icvt(l, addr_base, UNSIGNED, 7));
1fd5a2d4 371 putchar(c);
3718e103
DW
372}
373
374line(n)
375int n;
376{
377 register i, first;
378 register struct dfmt *c;
379 register struct dfmt **cv = conv_vec;
380
381 first = YES;
0e88daf2
DW
382 while (c = *cv++)
383 {
384 if (c->df_paddr)
385 {
386 if (first)
387 {
388 put_addr(addr, label, ' ');
389 first = NO;
390 }
391 else
392 {
393 putchar('\t');
394 if (label >= 0)
395 fputs("\t ", stdout);
396 }
1fd5a2d4 397 }
3718e103
DW
398 i = 0;
399 while (i < n)
400 i += (*(c->df_put))(dbuf+i, c);
0e88daf2
DW
401 if (c->df_paddr)
402 putchar('\n');
3718e103
DW
403 }
404}
405
406s_put(n, d)
407short *n;
408struct dfmt *d;
409{
410 printf(d->df_fmt, icvt((long)*n, d->df_radix, d->df_signed, d->df_field));
411 return(d->df_size);
412}
413
414us_put(n, d)
415unsigned short *n;
416struct dfmt *d;
417{
418 printf(d->df_fmt, icvt((long)*n, d->df_radix, d->df_signed, d->df_field));
419 return(d->df_size);
420}
421
422l_put(n, d)
423long *n;
424struct dfmt *d;
425{
426 printf(d->df_fmt, icvt(*n, d->df_radix, d->df_signed, d->df_field));
427 return(d->df_size);
428}
429
430d_put(f, d)
431double *f;
432struct dfmt *d;
433{
434 char fbuf[24];
d13b8628
DW
435 struct l { long n[2]; };
436
437#if vax
438 if ((((struct l *)f)->n[0] & 0xff00) == 0x8000) /* Vax illegal f.p. */
439 sprintf(fbuf, " %08x %08x",
440 ((struct l *)f)->n[0], ((struct l *)f)->n[1]);
441 else
442#endif
443
444 sprintf(fbuf, "%21.14e", *f);
3718e103
DW
445 printf(d->df_fmt, fbuf);
446 return(d->df_size);
447}
448
449f_put(f, d)
450float *f;
451struct dfmt *d;
452{
453 char fbuf[16];
d13b8628
DW
454
455#if vax
456 if ((*(long *)f & 0xff00) == 0x8000) /* Vax illegal f.p. form */
457 sprintf(fbuf, " %08x", *(long *)f);
458 else
459#endif
460 sprintf(fbuf, "%14.7e", *f);
3718e103
DW
461 printf(d->df_fmt, fbuf);
462 return(d->df_size);
463}
464
465
466char asc_name[34][4] = {
0e88daf2
DW
467/* 000 */ "nul", "soh", "stx", "etx", "eot", "enq", "ack", "bel",
468/* 010 */ " bs", " ht", " nl", " vt", " ff", " cr", " so", " si",
469/* 020 */ "dle", "dc1", "dc2", "dc3", "dc4", "nak", "syn", "etb",
470/* 030 */ "can", " em", "sub", "esc", " fs", " gs", " rs", " us",
471/* 040 */ " sp", "del"
3718e103
DW
472};
473
474a_put(cc, d)
475char *cc;
476struct dfmt *d;
477{
478 int c = *cc;
479 register char *s = " ";
480 register pbit = parity((int)c & 0377);
481
482 c &= 0177;
0e88daf2 483 if (isgraphic(c))
3718e103 484 {
0e88daf2 485 s[2] = c;
3718e103 486 if (pbit == _parity)
d2b19b28 487 printf(d->df_fmt, underline(s));
3718e103
DW
488 else
489 printf(d->df_fmt, s);
490 }
491 else
492 {
493 if (c == 0177)
494 c = ' ' + 1;
495 if (pbit == _parity)
d2b19b28 496 printf(d->df_fmt, underline(asc_name[c]));
3718e103
DW
497 else
498 printf(d->df_fmt, asc_name[c]);
499 }
500 return(1);
501}
502
503parity(word)
504int word;
505{
506 register int p = 0;
507 register int w = word;
508
509 if (w)
0e88daf2
DW
510 do
511 {
3718e103
DW
512 p ^= 1;
513 } while(w &= (~(-w)));
514 return (p? ODD:EVEN);
515}
516
517char *
d2b19b28 518underline(s)
3718e103 519char *s;
3718e103
DW
520{
521 static char ulbuf[16];
522 register char *u = ulbuf;
523
0e88daf2
DW
524 while (*s)
525 {
526 if (*s != ' ')
527 {
3718e103
DW
528 *u++ = '_';
529 *u++ = '\b';
530 }
531 *u++ = *s++;
532 }
533 *u = '\0';
534 return(ulbuf);
535}
536
537b_put(b, d)
538char *b;
539struct dfmt *d;
540{
541 printf(d->df_fmt, icvt((long)*b & 0377, d->df_radix, d->df_signed, d->df_field));
542 return(1);
543}
544
545c_put(cc, d)
546char *cc;
547struct dfmt *d;
548{
0e88daf2
DW
549 register char *s;
550 register int n;
551 register int c = *cc & 0377;
552
553 s = scvt(c, d);
554 for (n = d->df_field - strlen(s); n > 0; n--)
555 putchar(' ');
556 printf(d->df_fmt, s);
557 return(1);
558}
559
560char *scvt(c, d)
561int c;
562struct dfmt *d;
563{
564 static char s[2];
565
566 switch(c)
567 {
568 case '\0':
569 return("\\0");
570
571 case '\b':
572 return("\\b");
3718e103 573
0e88daf2
DW
574 case '\f':
575 return("\\f");
576
577 case '\n':
578 return("\\n");
579
580 case '\r':
581 return("\\r");
582
583 case '\t':
584 return("\\t");
585
586 default:
587 if (isprint(c))
588 {
589 s[0] = c;
590 return(s);
591 }
592 return(icvt((long)c, d->df_radix, d->df_signed, d->df_field));
3718e103 593 }
0e88daf2 594}
3718e103 595
0e88daf2
DW
596/*
597 * Look for strings.
598 * A string contains bytes > 037 && < 177, and ends with a null.
599 * The minimum length is given in the dfmt structure.
600 */
601
602#define CNULL '\0'
603#define S_EMPTY 0
604#define S_FILL 1
605#define S_CONT 2
606#define SBUFSIZE 1024
607
608static char str_buf[SBUFSIZE];
609static int str_mode = S_EMPTY;
610static char *str_ptr;
611static long str_addr;
612static long str_label;
613
67e162d0
DW
614st_put(cc, d)
615char *cc;
0e88daf2
DW
616struct dfmt *d;
617{
67e162d0
DW
618 register int c;
619
620 if (cc == 0)
0e88daf2
DW
621 {
622 pr_sbuf(d, YES);
67e162d0 623 return(1);
3718e103 624 }
67e162d0
DW
625
626 c = (*cc & 0377);
627
628 if (str_mode & S_FILL)
0e88daf2 629 {
67e162d0
DW
630 if (isascii(c))
631 put_sbuf(c, d);
0e88daf2
DW
632 else
633 {
634 *str_ptr = CNULL;
67e162d0 635 if (c == NULL)
0e88daf2
DW
636 pr_sbuf(d, YES);
637 str_mode = S_EMPTY;
638 }
639 }
67e162d0 640 else if (isascii(c))
0e88daf2
DW
641 {
642 str_mode = S_FILL;
67e162d0 643 str_addr = addr + (cc - dbuf); /* ugly */
0e88daf2 644 if ((str_label = label) >= 0)
67e162d0 645 str_label += (cc - dbuf); /* '' */
0e88daf2 646 str_ptr = str_buf;
67e162d0 647 put_sbuf(c, d);
0e88daf2
DW
648 }
649
3718e103
DW
650 return(1);
651}
652
0e88daf2 653put_sbuf(c, d)
67e162d0 654int c;
0e88daf2
DW
655struct dfmt *d;
656{
657 *str_ptr++ = c;
658 if (str_ptr >= (str_buf + SBUFSIZE))
659 {
660 pr_sbuf(d, NO);
661 str_ptr = str_buf;
662 str_mode |= S_CONT;
663 }
664}
665
666pr_sbuf(d, end)
667struct dfmt *d;
668int end;
669{
670 register char *p = str_buf;
671
672 if (str_mode == S_EMPTY
673 || (!(str_mode & S_CONT) && (str_ptr - str_buf) < d->df_size))
674 return;
675
676 if (!(str_mode & S_CONT))
677 put_addr(str_addr, str_label, ' ');
678
679 while (p < str_ptr)
680 fputs(scvt(*p++, d), stdout);
681
682 if (end)
683 putchar('\n');
684}
685
3718e103
DW
686/*
687 * integer to ascii conversion
688 *
689 * This code has been rearranged to produce optimized runtime code.
690 */
691
692#define MAXINTLENGTH 32
693static char _digit[] = "0123456789abcdef";
694static char _icv_buf[MAXINTLENGTH+1];
695static long _mask = 0x7fffffff;
696
697char *
698icvt (value, radix, signed, ndigits)
699long value;
700int radix;
701int signed;
702int ndigits;
703{
704 register long val = value;
705 register long rad = radix;
706 register char *b = &_icv_buf[MAXINTLENGTH];
707 register char *d = _digit;
708 register long tmp1;
709 register long tmp2;
710 long rem;
711 long kludge;
712 int sign;
713
714 if (val == 0)
715 {
716 *--b = '0';
717 sign = 0;
718 goto done; /*return(b);*/
719 }
720
721 if (signed && (sign = (val < 0))) /* signed conversion */
722 {
723 /*
724 * It is necessary to do the first divide
725 * before the absolute value, for the case -2^31
726 *
727 * This is actually what is being done...
728 * tmp1 = (int)(val % rad);
729 * val /= rad;
730 * val = -val
731 * *--b = d[-tmp1];
732 */
733 tmp1 = val / rad;
734 *--b = d[(tmp1 * rad) - val];
735 val = -tmp1;
736 }
737 else /* unsigned conversion */
738 {
739 sign = 0;
740 if (val < 0)
741 { /* ALL THIS IS TO SIMULATE UNSIGNED LONG MOD & DIV */
742 kludge = _mask - (rad - 1);
743 val &= _mask;
744 /*
745 * This is really what's being done...
746 * rem = (kludge % rad) + (val % rad);
747 * val = (kludge / rad) + (val / rad) + (rem / rad) + 1;
748 * *--b = d[rem % rad];
749 */
750 tmp1 = kludge / rad;
751 tmp2 = val / rad;
752 rem = (kludge - (tmp1 * rad)) + (val - (tmp2 * rad));
753 val = ++tmp1 + tmp2;
754 tmp1 = rem / rad;
755 val += tmp1;
756 *--b = d[rem - (tmp1 * rad)];
757 }
758 }
759
760 while (val)
761 {
762 /*
763 * This is really what's being done ...
764 * *--b = d[val % rad];
765 * val /= rad;
766 */
767 tmp1 = val / rad;
768 *--b = d[val - (tmp1 * rad)];
769 val = tmp1;
770 }
771
772done:
773 if (sign)
774 *--b = '-';
775
776 tmp1 = ndigits - (&_icv_buf[MAXINTLENGTH] - b);
777 tmp2 = signed? ' ':'0';
778 while (tmp1 > 0)
779 {
780 *--b = tmp2;
781 tmp1--;
782 }
783
784 return(b);
785}
786
0e88daf2 787long get_addr(s)
3718e103
DW
788register char *s;
789{
790 register char *p;
1fd5a2d4 791 register long a;
3718e103
DW
792 register int d;
793
794 if (*s=='+')
795 s++;
0e88daf2
DW
796 if (*s=='x')
797 {
3718e103
DW
798 s++;
799 addr_base = 16;
0e88daf2
DW
800 }
801 else if (*s=='0' && s[1]=='x')
802 {
3718e103
DW
803 s += 2;
804 addr_base = 16;
0e88daf2
DW
805 }
806 else if (*s == '0')
3718e103
DW
807 addr_base = 8;
808 p = s;
0e88daf2
DW
809 while(*p)
810 {
3718e103
DW
811 if (*p++=='.')
812 addr_base = 10;
813 }
0e88daf2
DW
814 for (a=0; *s; s++)
815 {
3718e103 816 d = *s;
0e88daf2 817 if(isdigit(d))
3718e103 818 a = a*addr_base + d - '0';
0e88daf2 819 else if (ishex(d) && addr_base==16)
3718e103
DW
820 a = a*addr_base + d + 10 - 'a';
821 else
822 break;
823 }
1fd5a2d4 824
3718e103
DW
825 if (*s == '.')
826 s++;
1fd5a2d4 827 if(*s=='b')
3718e103 828 a *= 512;
1fd5a2d4
DW
829 if(*s=='B')
830 a *= 1024;
831
832 return(a);
833}
834
7f1bc61f
DW
835bufncmp(a, b, n)
836char *a;
837char *b;
838int n;
839{
840 while (n--)
841 if (*a++ != *b++)
842 return(1);
843}
844
1fd5a2d4
DW
845offset(a)
846long a;
847{
3718e103
DW
848 if (canseek(stdin))
849 fseek(stdin, a, 0);
850 else
851 dumbseek(stdin, a);
3718e103
DW
852}
853
854dumbseek(s, offset)
855FILE *s;
856long offset;
857{
858 char buf[BUFSIZ];
859 int n;
860 int nr;
861
862 while (offset > 0)
863 {
864 nr = (offset > BUFSIZ) ? BUFSIZ : (int)offset;
865 if ((n = fread(buf, 1, nr, s)) != nr)
866 {
867 fprintf(stderr, "EOF\n");
868 exit(1);
869 }
870 offset -= n;
871 }
872}
873
874#include <sys/types.h>
875#include <sys/stat.h>
876
877canseek(f)
878FILE *f;
879{
880 struct stat statb;
881
882 return( (fstat(fileno(f),&statb)==0) &&
883 (statb.st_nlink > 0) && /*!pipe*/
884 (!isatty(fileno(f))) );
885}