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