|
|
1.1 ! root 1: static char *sccsid = "@(#)od.c 5.12 (Berkeley) 5/14/84"; ! 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: } ! 364: ! 365: put_addr(a, l, c) ! 366: long a; ! 367: long l; ! 368: char c; ! 369: { ! 370: fputs(icvt(a, addr_base, UNSIGNED, 7), stdout); ! 371: if (l >= 0) ! 372: printf(" (%s)", icvt(l, addr_base, UNSIGNED, 7)); ! 373: putchar(c); ! 374: } ! 375: ! 376: line(n) ! 377: int n; ! 378: { ! 379: register i, first; ! 380: register struct dfmt *c; ! 381: register struct dfmt **cv = conv_vec; ! 382: ! 383: first = YES; ! 384: while (c = *cv++) ! 385: { ! 386: if (c->df_paddr) ! 387: { ! 388: if (first) ! 389: { ! 390: put_addr(addr, label, ' '); ! 391: first = NO; ! 392: } ! 393: else ! 394: { ! 395: putchar('\t'); ! 396: if (label >= 0) ! 397: fputs("\t ", stdout); ! 398: } ! 399: } ! 400: i = 0; ! 401: while (i < n) ! 402: i += (*(c->df_put))(dbuf+i, c); ! 403: if (c->df_paddr) ! 404: putchar('\n'); ! 405: } ! 406: } ! 407: ! 408: s_put(n, d) ! 409: short *n; ! 410: struct dfmt *d; ! 411: { ! 412: printf(d->df_fmt, icvt((long)*n, d->df_radix, d->df_signed, d->df_field)); ! 413: return(d->df_size); ! 414: } ! 415: ! 416: us_put(n, d) ! 417: unsigned short *n; ! 418: struct dfmt *d; ! 419: { ! 420: printf(d->df_fmt, icvt((long)*n, d->df_radix, d->df_signed, d->df_field)); ! 421: return(d->df_size); ! 422: } ! 423: ! 424: l_put(n, d) ! 425: long *n; ! 426: struct dfmt *d; ! 427: { ! 428: printf(d->df_fmt, icvt(*n, d->df_radix, d->df_signed, d->df_field)); ! 429: return(d->df_size); ! 430: } ! 431: ! 432: d_put(f, d) ! 433: double *f; ! 434: struct dfmt *d; ! 435: { ! 436: char fbuf[24]; ! 437: struct l { long n[2]; }; ! 438: ! 439: #if vax ! 440: if ((((struct l *)f)->n[0] & 0xff00) == 0x8000) /* Vax illegal f.p. */ ! 441: sprintf(fbuf, " %08x %08x", ! 442: ((struct l *)f)->n[0], ((struct l *)f)->n[1]); ! 443: else ! 444: #endif ! 445: ! 446: sprintf(fbuf, "%21.14e", *f); ! 447: printf(d->df_fmt, fbuf); ! 448: return(d->df_size); ! 449: } ! 450: ! 451: f_put(f, d) ! 452: float *f; ! 453: struct dfmt *d; ! 454: { ! 455: char fbuf[16]; ! 456: ! 457: #if vax ! 458: if ((*(long *)f & 0xff00) == 0x8000) /* Vax illegal f.p. form */ ! 459: sprintf(fbuf, " %08x", *(long *)f); ! 460: else ! 461: #endif ! 462: sprintf(fbuf, "%14.7e", *f); ! 463: printf(d->df_fmt, fbuf); ! 464: return(d->df_size); ! 465: } ! 466: ! 467: ! 468: char asc_name[34][4] = { ! 469: /* 000 */ "nul", "soh", "stx", "etx", "eot", "enq", "ack", "bel", ! 470: /* 010 */ " bs", " ht", " nl", " vt", " ff", " cr", " so", " si", ! 471: /* 020 */ "dle", "dc1", "dc2", "dc3", "dc4", "nak", "syn", "etb", ! 472: /* 030 */ "can", " em", "sub", "esc", " fs", " gs", " rs", " us", ! 473: /* 040 */ " sp", "del" ! 474: }; ! 475: ! 476: a_put(cc, d) ! 477: char *cc; ! 478: struct dfmt *d; ! 479: { ! 480: int c = *cc; ! 481: register char *s = " "; ! 482: register pbit = parity((int)c & 0377); ! 483: ! 484: c &= 0177; ! 485: if (isgraphic(c)) ! 486: { ! 487: s[2] = c; ! 488: if (pbit == _parity) ! 489: printf(d->df_fmt, underline(s)); ! 490: else ! 491: printf(d->df_fmt, s); ! 492: } ! 493: else ! 494: { ! 495: if (c == 0177) ! 496: c = ' ' + 1; ! 497: if (pbit == _parity) ! 498: printf(d->df_fmt, underline(asc_name[c])); ! 499: else ! 500: printf(d->df_fmt, asc_name[c]); ! 501: } ! 502: return(1); ! 503: } ! 504: ! 505: parity(word) ! 506: int word; ! 507: { ! 508: register int p = 0; ! 509: register int w = word; ! 510: ! 511: if (w) ! 512: do ! 513: { ! 514: p ^= 1; ! 515: } while(w &= (~(-w))); ! 516: return (p? ODD:EVEN); ! 517: } ! 518: ! 519: char * ! 520: underline(s) ! 521: char *s; ! 522: { ! 523: static char ulbuf[16]; ! 524: register char *u = ulbuf; ! 525: ! 526: while (*s) ! 527: { ! 528: if (*s != ' ') ! 529: { ! 530: *u++ = '_'; ! 531: *u++ = '\b'; ! 532: } ! 533: *u++ = *s++; ! 534: } ! 535: *u = '\0'; ! 536: return(ulbuf); ! 537: } ! 538: ! 539: b_put(b, d) ! 540: char *b; ! 541: struct dfmt *d; ! 542: { ! 543: printf(d->df_fmt, icvt((long)*b & 0377, d->df_radix, d->df_signed, d->df_field)); ! 544: return(1); ! 545: } ! 546: ! 547: c_put(cc, d) ! 548: char *cc; ! 549: struct dfmt *d; ! 550: { ! 551: register char *s; ! 552: register int n; ! 553: register int c = *cc & 0377; ! 554: ! 555: s = scvt(c, d); ! 556: for (n = d->df_field - strlen(s); n > 0; n--) ! 557: putchar(' '); ! 558: printf(d->df_fmt, s); ! 559: return(1); ! 560: } ! 561: ! 562: char *scvt(c, d) ! 563: int c; ! 564: struct dfmt *d; ! 565: { ! 566: static char s[2]; ! 567: ! 568: switch(c) ! 569: { ! 570: case '\0': ! 571: return("\\0"); ! 572: ! 573: case '\b': ! 574: return("\\b"); ! 575: ! 576: case '\f': ! 577: return("\\f"); ! 578: ! 579: case '\n': ! 580: return("\\n"); ! 581: ! 582: case '\r': ! 583: return("\\r"); ! 584: ! 585: case '\t': ! 586: return("\\t"); ! 587: ! 588: default: ! 589: if (isprint(c)) ! 590: { ! 591: s[0] = c; ! 592: return(s); ! 593: } ! 594: return(icvt((long)c, d->df_radix, d->df_signed, d->df_field)); ! 595: } ! 596: } ! 597: ! 598: /* ! 599: * Look for strings. ! 600: * A string contains bytes > 037 && < 177, and ends with a null. ! 601: * The minimum length is given in the dfmt structure. ! 602: */ ! 603: ! 604: #define CNULL '\0' ! 605: #define S_EMPTY 0 ! 606: #define S_FILL 1 ! 607: #define S_CONT 2 ! 608: #define SBUFSIZE 1024 ! 609: ! 610: static char str_buf[SBUFSIZE]; ! 611: static int str_mode = S_EMPTY; ! 612: static char *str_ptr; ! 613: static long str_addr; ! 614: static long str_label; ! 615: ! 616: st_put(cc, d) ! 617: char *cc; ! 618: struct dfmt *d; ! 619: { ! 620: register int c; ! 621: ! 622: if (cc == 0) ! 623: { ! 624: pr_sbuf(d, YES); ! 625: return(1); ! 626: } ! 627: ! 628: c = (*cc & 0377); ! 629: ! 630: if (str_mode & S_FILL) ! 631: { ! 632: if (isascii(c)) ! 633: put_sbuf(c, d); ! 634: else ! 635: { ! 636: *str_ptr = CNULL; ! 637: if (c == NULL) ! 638: pr_sbuf(d, YES); ! 639: str_mode = S_EMPTY; ! 640: } ! 641: } ! 642: else if (isascii(c)) ! 643: { ! 644: str_mode = S_FILL; ! 645: str_addr = addr + (cc - dbuf); /* ugly */ ! 646: if ((str_label = label) >= 0) ! 647: str_label += (cc - dbuf); /* '' */ ! 648: str_ptr = str_buf; ! 649: put_sbuf(c, d); ! 650: } ! 651: ! 652: return(1); ! 653: } ! 654: ! 655: put_sbuf(c, d) ! 656: int c; ! 657: struct dfmt *d; ! 658: { ! 659: *str_ptr++ = c; ! 660: if (str_ptr >= (str_buf + SBUFSIZE)) ! 661: { ! 662: pr_sbuf(d, NO); ! 663: str_ptr = str_buf; ! 664: str_mode |= S_CONT; ! 665: } ! 666: } ! 667: ! 668: pr_sbuf(d, end) ! 669: struct dfmt *d; ! 670: int end; ! 671: { ! 672: register char *p = str_buf; ! 673: ! 674: if (str_mode == S_EMPTY ! 675: || (!(str_mode & S_CONT) && (str_ptr - str_buf) < d->df_size)) ! 676: return; ! 677: ! 678: if (!(str_mode & S_CONT)) ! 679: put_addr(str_addr, str_label, ' '); ! 680: ! 681: while (p < str_ptr) ! 682: fputs(scvt(*p++, d), stdout); ! 683: ! 684: if (end) ! 685: putchar('\n'); ! 686: } ! 687: ! 688: /* ! 689: * integer to ascii conversion ! 690: * ! 691: * This code has been rearranged to produce optimized runtime code. ! 692: */ ! 693: ! 694: #define MAXINTLENGTH 32 ! 695: static char _digit[] = "0123456789abcdef"; ! 696: static char _icv_buf[MAXINTLENGTH+1]; ! 697: static long _mask = 0x7fffffff; ! 698: ! 699: char * ! 700: icvt (value, radix, signed, ndigits) ! 701: long value; ! 702: int radix; ! 703: int signed; ! 704: int ndigits; ! 705: { ! 706: register long val = value; ! 707: register long rad = radix; ! 708: register char *b = &_icv_buf[MAXINTLENGTH]; ! 709: register char *d = _digit; ! 710: register long tmp1; ! 711: register long tmp2; ! 712: long rem; ! 713: long kludge; ! 714: int sign; ! 715: ! 716: if (val == 0) ! 717: { ! 718: *--b = '0'; ! 719: sign = 0; ! 720: goto done; /*return(b);*/ ! 721: } ! 722: ! 723: if (signed && (sign = (val < 0))) /* signed conversion */ ! 724: { ! 725: /* ! 726: * It is necessary to do the first divide ! 727: * before the absolute value, for the case -2^31 ! 728: * ! 729: * This is actually what is being done... ! 730: * tmp1 = (int)(val % rad); ! 731: * val /= rad; ! 732: * val = -val ! 733: * *--b = d[-tmp1]; ! 734: */ ! 735: tmp1 = val / rad; ! 736: *--b = d[(tmp1 * rad) - val]; ! 737: val = -tmp1; ! 738: } ! 739: else /* unsigned conversion */ ! 740: { ! 741: sign = 0; ! 742: if (val < 0) ! 743: { /* ALL THIS IS TO SIMULATE UNSIGNED LONG MOD & DIV */ ! 744: kludge = _mask - (rad - 1); ! 745: val &= _mask; ! 746: /* ! 747: * This is really what's being done... ! 748: * rem = (kludge % rad) + (val % rad); ! 749: * val = (kludge / rad) + (val / rad) + (rem / rad) + 1; ! 750: * *--b = d[rem % rad]; ! 751: */ ! 752: tmp1 = kludge / rad; ! 753: tmp2 = val / rad; ! 754: rem = (kludge - (tmp1 * rad)) + (val - (tmp2 * rad)); ! 755: val = ++tmp1 + tmp2; ! 756: tmp1 = rem / rad; ! 757: val += tmp1; ! 758: *--b = d[rem - (tmp1 * rad)]; ! 759: } ! 760: } ! 761: ! 762: while (val) ! 763: { ! 764: /* ! 765: * This is really what's being done ... ! 766: * *--b = d[val % rad]; ! 767: * val /= rad; ! 768: */ ! 769: tmp1 = val / rad; ! 770: *--b = d[val - (tmp1 * rad)]; ! 771: val = tmp1; ! 772: } ! 773: ! 774: done: ! 775: if (sign) ! 776: *--b = '-'; ! 777: ! 778: tmp1 = ndigits - (&_icv_buf[MAXINTLENGTH] - b); ! 779: tmp2 = signed? ' ':'0'; ! 780: while (tmp1 > 0) ! 781: { ! 782: *--b = tmp2; ! 783: tmp1--; ! 784: } ! 785: ! 786: return(b); ! 787: } ! 788: ! 789: long get_addr(s) ! 790: register char *s; ! 791: { ! 792: register char *p; ! 793: register long a; ! 794: register int d; ! 795: ! 796: if (*s=='+') ! 797: s++; ! 798: if (*s=='x') ! 799: { ! 800: s++; ! 801: addr_base = 16; ! 802: } ! 803: else if (*s=='0' && s[1]=='x') ! 804: { ! 805: s += 2; ! 806: addr_base = 16; ! 807: } ! 808: else if (*s == '0') ! 809: addr_base = 8; ! 810: p = s; ! 811: while(*p) ! 812: { ! 813: if (*p++=='.') ! 814: addr_base = 10; ! 815: } ! 816: for (a=0; *s; s++) ! 817: { ! 818: d = *s; ! 819: if(isdigit(d)) ! 820: a = a*addr_base + d - '0'; ! 821: else if (ishex(d) && addr_base==16) ! 822: a = a*addr_base + d + 10 - 'a'; ! 823: else ! 824: break; ! 825: } ! 826: ! 827: if (*s == '.') ! 828: s++; ! 829: if(*s=='b') ! 830: a *= 512; ! 831: if(*s=='B') ! 832: a *= 1024; ! 833: ! 834: return(a); ! 835: } ! 836: ! 837: offset(a) ! 838: long a; ! 839: { ! 840: if (canseek(stdin)) ! 841: { ! 842: /* ! 843: * in case we're accessing a raw disk, ! 844: * we have to seek in multiples of a physical block. ! 845: */ ! 846: fseek(stdin, a & 0xfffffe00L, 0); ! 847: a &= 0x1ffL; ! 848: } ! 849: dumbseek(stdin, a); ! 850: } ! 851: ! 852: dumbseek(s, offset) ! 853: FILE *s; ! 854: long offset; ! 855: { ! 856: char buf[BUFSIZ]; ! 857: int n; ! 858: int nr; ! 859: ! 860: while (offset > 0) ! 861: { ! 862: nr = (offset > BUFSIZ) ? BUFSIZ : (int)offset; ! 863: if ((n = fread(buf, 1, nr, s)) != nr) ! 864: { ! 865: fprintf(stderr, "EOF\n"); ! 866: exit(1); ! 867: } ! 868: offset -= n; ! 869: } ! 870: } ! 871: ! 872: #include <sys/types.h> ! 873: #include <sys/stat.h> ! 874: ! 875: canseek(f) ! 876: FILE *f; ! 877: { ! 878: struct stat statb; ! 879: ! 880: return( (fstat(fileno(f),&statb)==0) && ! 881: (statb.st_nlink > 0) && /*!pipe*/ ! 882: (!isatty(fileno(f))) ); ! 883: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.