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: }

Defined functions

a_put defined in line 476; used 2 times
b_put defined in line 539; used 2 times
c_put defined in line 547; used 2 times
canseek defined in line 875; used 1 times
d_put defined in line 432; used 2 times
dumbseek defined in line 852; used 1 times
f_put defined in line 451; used 2 times
get_addr defined in line 789; used 3 times
icvt defined in line 699; used 8 times
l_put defined in line 424; used 5 times
line defined in line 376; used 1 times
main defined in line 151; never used
offset defined in line 837; used 7 times
parity defined in line 505; used 1 times
pr_sbuf defined in line 668; used 3 times
put_addr defined in line 365; used 3 times
put_sbuf defined in line 655; used 2 times
s_put defined in line 408; used 2 times
scvt defined in line 562; used 3 times
st_put defined in line 616; used 2 times
underline defined in line 519; used 3 times
us_put defined in line 416; used 4 times

Defined variables

_ctype defined in line 115; used 5 times
_digit defined in line 695; used 1 times
_icv_buf defined in line 696; used 2 times
_mask defined in line 697; used 2 times
_parity defined in line 92; used 4 times
addr defined in line 89; used 6 times
addr_base defined in line 88; used 9 times
asc_name defined in line 468; used 2 times
ascii defined in line 69; used 1 times
byte defined in line 70; used 1 times
cchar defined in line 71; used 1 times
conv_vec defined in line 67; used 6 times
dble defined in line 81; used 1 times
dbuf defined in line 86; used 6 times
dbuf_size defined in line 91; used 10 times
flt defined in line 80; used 1 times
fmt defined in line 93; used 1 times
label defined in line 90; used 7 times
lastdbuf defined in line 87; used 2 times
s_l_dec defined in line 79; used 1 times
s_s_dec defined in line 78; used 1 times
sccsid defined in line 1; never used
str_addr defined in line 613; used 2 times
str_buf defined in line 610; used 5 times
str_label defined in line 614; used 3 times
str_mode defined in line 611; used 7 times
str_ptr defined in line 612; used 7 times
string defined in line 82; used 1 times
u_l_dec defined in line 76; used 1 times
u_l_hex defined in line 77; used 1 times
u_l_oct defined in line 75; used 1 times
u_s_dec defined in line 73; used 1 times
u_s_hex defined in line 74; used 1 times
u_s_oct defined in line 72; used 2 times
usage defined in line 85; used 1 times

Defined struct's

dfmt defined in line 59; used 62 times
l defined in line 437; used 6 times

Defined macros

A defined in line 104; used 101 times
BIG_DBUF defined in line 39; used 1 times
CNULL defined in line 604; used 1 times
D defined in line 106; used 12 times
DBUF_SIZE defined in line 38; used 2 times
EVEN defined in line 42; used 2 times
G defined in line 105; used 95 times
MAXINTLENGTH defined in line 694; used 3 times
MIN_SLEN defined in line 47; used 1 times
NO defined in line 40; used 5 times
ODD defined in line 43; used 2 times
P defined in line 107; used 96 times
PADDR defined in line 46; used 13 times
SBUFSIZE defined in line 608; used 2 times
SIGNED defined in line 45; used 4 times
S_CONT defined in line 607; used 3 times
S_EMPTY defined in line 605; used 3 times
S_FILL defined in line 606; used 2 times
UNSIGNED defined in line 44; used 10 times
X defined in line 108; used 7 times
YES defined in line 41; used 5 times
isascii defined in line 110; used 2 times
isdigit defined in line 109; used 3 times
isgraphic defined in line 111; used 1 times
ishex defined in line 113; used 1 times
isprint defined in line 112; used 1 times
Last modified: 1987-02-08
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 5483
Valid CSS Valid XHTML 1.0 Strict