1*32416Sbostic static char *sccsid = "@(#)od.c 5.13 (Berkeley) 10/22/87"; 24492Sdlw /* 34492Sdlw * od -- octal, hex, decimal, character dump of data in a file. 44492Sdlw * 511074Sdlw * usage: od [-abBcdDefFhHiIlLopPs[n]vw[n]xX] [file] [[+]offset[.][b] [label]] 64492Sdlw * 74492Sdlw * where the option flags have the following meaning: 84492Sdlw * character object radix signed? 94492Sdlw * a byte (10) (n.a.) ASCII named byte stream 104492Sdlw * b byte 8 no byte octal 114492Sdlw * c byte (8) (no) character with octal non-graphic bytes 124492Sdlw * d short 10 no 134492Sdlw * D long 10 no 144492Sdlw * e,F double (10) double precision floating pt. 154492Sdlw * f float (10) single precision floating pt. 164492Sdlw * h,x short 16 no 174492Sdlw * H,X long 16 no 184492Sdlw * i short 10 yes 194492Sdlw * I,l,L long 10 yes 204687Sdlw * o,B short 8 no (default conversion) 214492Sdlw * O long 8 no 2211074Sdlw * s[n] string (8) ASCII graphic strings 234492Sdlw * 244492Sdlw * p indicate EVEN parity on 'a' conversion 254492Sdlw * P indicate ODD parity on 'a' conversion 264492Sdlw * v show all data - don't skip like lines. 2711074Sdlw * w[n] bytes per display line 284492Sdlw * 294492Sdlw * More than one format character may be given. 304492Sdlw * If {file} is not specified, standard input is read. 314492Sdlw * If {file} is not specified, then {offset} must start with '+'. 3211074Sdlw * {Offset} may be HEX (0xnnn), OCTAL (0nn), or decimal (nnn.). 3311074Sdlw * The default is octal. The same radix will be used to display the address. 344492Sdlw */ 354492Sdlw 364492Sdlw #include <stdio.h> 374492Sdlw 3811074Sdlw #define DBUF_SIZE BUFSIZ 3911074Sdlw #define BIG_DBUF 32 404687Sdlw #define NO 0 414687Sdlw #define YES 1 424687Sdlw #define EVEN -1 434687Sdlw #define ODD 1 444687Sdlw #define UNSIGNED 0 454687Sdlw #define SIGNED 1 464687Sdlw #define PADDR 1 474687Sdlw #define MIN_SLEN 3 484492Sdlw 494492Sdlw int a_put(); 504492Sdlw int b_put(); 514492Sdlw int c_put(); 524492Sdlw int s_put(); 534492Sdlw int us_put(); 544492Sdlw int l_put(); 554492Sdlw int f_put(); 564492Sdlw int d_put(); 574687Sdlw int st_put(); 584492Sdlw 594492Sdlw struct dfmt { 604492Sdlw int df_field; /* external field required for object */ 614492Sdlw int df_size; /* size (bytes) of object */ 624492Sdlw int df_radix; /* conversion radix */ 634492Sdlw int df_signed; /* signed? flag */ 644687Sdlw int df_paddr; /* "put address on each line?" flag */ 654492Sdlw int (*df_put)(); /* function to output object */ 664687Sdlw char *df_fmt; /* output string format */ 674492Sdlw } *conv_vec[32]; /* vector of conversions to be done */ 684492Sdlw 694687Sdlw struct dfmt ascii = { 3, sizeof (char), 10, 0, PADDR, a_put, 0}; 704687Sdlw struct dfmt byte = { 3, sizeof (char), 8, UNSIGNED, PADDR, b_put, 0}; 714687Sdlw struct dfmt cchar = { 3, sizeof (char), 8, UNSIGNED, PADDR, c_put, 0}; 724687Sdlw struct dfmt u_s_oct = { 6, sizeof (short), 8, UNSIGNED, PADDR, us_put, 0}; 734687Sdlw struct dfmt u_s_dec = { 5, sizeof (short), 10, UNSIGNED, PADDR, us_put, 0}; 744687Sdlw struct dfmt u_s_hex = { 4, sizeof (short), 16, UNSIGNED, PADDR, us_put, 0}; 754687Sdlw struct dfmt u_l_oct = {11, sizeof (long), 8, UNSIGNED, PADDR, l_put, 0}; 764687Sdlw struct dfmt u_l_dec = {10, sizeof (long), 10, UNSIGNED, PADDR, l_put, 0}; 774687Sdlw struct dfmt u_l_hex = { 8, sizeof (long), 16, UNSIGNED, PADDR, l_put, 0}; 784687Sdlw struct dfmt s_s_dec = { 6, sizeof (short), 10, SIGNED, PADDR, s_put, 0}; 794687Sdlw struct dfmt s_l_dec = {11, sizeof (long), 10, SIGNED, PADDR, l_put, 0}; 804687Sdlw struct dfmt flt = {14, sizeof (float), 10, SIGNED, PADDR, f_put, 0}; 814687Sdlw struct dfmt dble = {21, sizeof (double), 10, SIGNED, PADDR, d_put, 0}; 824687Sdlw struct dfmt string = { 0, 0, 8, 0, NO, st_put, 0}; 834492Sdlw 844530Sdlw 8511074Sdlw char usage[] ="usage: od [-abcdfhilopswvx] [file] [[+]offset[.][b] [label]]"; 864687Sdlw char dbuf[DBUF_SIZE]; 874687Sdlw char lastdbuf[DBUF_SIZE]; 8811074Sdlw int addr_base = 8; /* default address base is OCTAL */ 8911074Sdlw long addr = 0L; /* current file offset */ 9011074Sdlw long label = -1L; /* current label; -1 is "off" */ 9111074Sdlw int dbuf_size = 16; /* file bytes / display line */ 9211074Sdlw int _parity = NO; /* show parity on ascii bytes */ 934492Sdlw char fmt[] = " %s"; /* 12 blanks */ 944492Sdlw char *icvt(); 954687Sdlw char *scvt(); 964492Sdlw char *underline(); 974530Sdlw long get_addr(); 984492Sdlw 994530Sdlw 1004687Sdlw /* 1014687Sdlw * special form of _ctype 1024687Sdlw */ 1034687Sdlw 1044687Sdlw #define A 01 1054687Sdlw #define G 02 1064687Sdlw #define D 04 1074687Sdlw #define P 010 1084687Sdlw #define X 020 1094687Sdlw #define isdigit(c) (_ctype[c] & D) 1104687Sdlw #define isascii(c) (_ctype[c] & A) 1114687Sdlw #define isgraphic(c) (_ctype[c] & G) 1124687Sdlw #define isprint(c) (_ctype[c] & P) 1134687Sdlw #define ishex(c) (_ctype[c] & (X|D)) 1144687Sdlw 1154687Sdlw char _ctype[256] = { 1164687Sdlw /* 000 */ 0, 0, 0, 0, 0, 0, 0, 0, 1174687Sdlw /* 010 */ A, A, A, 0, A, A, 0, 0, 1184687Sdlw /* 020 */ 0, 0, 0, 0, 0, 0, 0, 0, 1194687Sdlw /* 030 */ 0, 0, 0, 0, 0, 0, 0, 0, 1204687Sdlw /* 040 */ P|A, P|G|A, P|G|A, P|G|A, P|G|A, P|G|A, P|G|A, P|G|A, 1214687Sdlw /* 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, 1224687Sdlw /* 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, 1234687Sdlw /* 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, 1244687Sdlw /* 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, 1254687Sdlw /* 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, 1264687Sdlw /* 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, 1274687Sdlw /* 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, 1284687Sdlw /* 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, 1294687Sdlw /* 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, 1304687Sdlw /* 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, 1314687Sdlw /* 170 */ P|G|A, P|G|A, P|G|A, P|G|A, P|G|A, P|G|A, P|G|A, 0, 1324687Sdlw /* 200 */ 0, 0, 0, 0, 0, 0, 0, 0, 1334687Sdlw /* 210 */ 0, 0, 0, 0, 0, 0, 0, 0, 1344687Sdlw /* 220 */ 0, 0, 0, 0, 0, 0, 0, 0, 1354687Sdlw /* 230 */ 0, 0, 0, 0, 0, 0, 0, 0, 1364687Sdlw /* 240 */ 0, 0, 0, 0, 0, 0, 0, 0, 1374687Sdlw /* 250 */ 0, 0, 0, 0, 0, 0, 0, 0, 1384687Sdlw /* 260 */ 0, 0, 0, 0, 0, 0, 0, 0, 1394687Sdlw /* 270 */ 0, 0, 0, 0, 0, 0, 0, 0, 1404687Sdlw /* 300 */ 0, 0, 0, 0, 0, 0, 0, 0, 1414687Sdlw /* 310 */ 0, 0, 0, 0, 0, 0, 0, 0, 1424687Sdlw /* 320 */ 0, 0, 0, 0, 0, 0, 0, 0, 1434687Sdlw /* 330 */ 0, 0, 0, 0, 0, 0, 0, 0, 1444687Sdlw /* 340 */ 0, 0, 0, 0, 0, 0, 0, 0, 1454687Sdlw /* 350 */ 0, 0, 0, 0, 0, 0, 0, 0, 1464687Sdlw /* 360 */ 0, 0, 0, 0, 0, 0, 0, 0, 1474687Sdlw /* 370 */ 0, 0, 0, 0, 0, 0, 0, 0, 1484687Sdlw }; 1494687Sdlw 1504687Sdlw 1514492Sdlw main(argc, argv) 1524687Sdlw int argc; 1534687Sdlw char **argv; 1544492Sdlw { 1554492Sdlw register char *p; 1564492Sdlw register char *l; 1574492Sdlw register n, same; 1584492Sdlw struct dfmt *d; 1594492Sdlw struct dfmt **cv = conv_vec; 1604492Sdlw int showall = NO; 1614492Sdlw int field, llen, nelm; 1624492Sdlw int max_llen = 0; 1634492Sdlw 1644492Sdlw argv++; 1654530Sdlw argc--; 1664492Sdlw 1674687Sdlw if(argc > 0) 1684687Sdlw { 1694492Sdlw p = *argv; 1704687Sdlw if(*p == '-') 1714687Sdlw { 1724687Sdlw while(*++p != '\0') 1734687Sdlw { 1744687Sdlw switch(*p) 1754687Sdlw { 1764492Sdlw case 'a': 1774492Sdlw d = &ascii; 1784492Sdlw break; 1794492Sdlw case 'b': 1804492Sdlw d = &byte; 1814492Sdlw break; 1824492Sdlw case 'c': 1834492Sdlw d = &cchar; 1844492Sdlw break; 1854492Sdlw case 'd': 1864492Sdlw d = &u_s_dec; 1874492Sdlw break; 1884492Sdlw case 'D': 1894492Sdlw d = &u_l_dec; 1904492Sdlw break; 1914492Sdlw case 'e': 1924492Sdlw case 'F': 1934492Sdlw d = &dble; 1944492Sdlw break; 1954492Sdlw case 'f': 1964492Sdlw d = &flt; 1974492Sdlw break; 1984492Sdlw case 'h': 1994492Sdlw case 'x': 2004492Sdlw d = &u_s_hex; 2014492Sdlw break; 2024492Sdlw case 'H': 2034492Sdlw case 'X': 2044492Sdlw d = &u_l_hex; 2054492Sdlw break; 2064492Sdlw case 'i': 2074492Sdlw d = &s_s_dec; 2084492Sdlw break; 2094492Sdlw case 'I': 2104492Sdlw case 'l': 2114492Sdlw case 'L': 2124492Sdlw d = &s_l_dec; 2134492Sdlw break; 2144492Sdlw case 'o': 2154687Sdlw case 'B': 2164492Sdlw d = &u_s_oct; 2174492Sdlw break; 2184492Sdlw case 'O': 2194492Sdlw d = &u_l_oct; 2204492Sdlw break; 2214492Sdlw case 'p': 2224492Sdlw _parity = EVEN; 2234492Sdlw continue; 2244492Sdlw case 'P': 2254492Sdlw _parity = ODD; 2264492Sdlw continue; 2274687Sdlw case 's': 2284687Sdlw d = &string; 2294687Sdlw *(cv++) = d; 2304687Sdlw while (isdigit(p[1])) 2314687Sdlw d->df_size = (10 * d->df_size) + (*++p - '0'); 2324687Sdlw if (d->df_size <= 0) 2334687Sdlw d->df_size = MIN_SLEN; 2344687Sdlw showall = YES; 2354687Sdlw continue; 23611074Sdlw case 'w': 23711074Sdlw dbuf_size = 0; 23811074Sdlw while (isdigit(p[1])) 23911074Sdlw dbuf_size = (10 * dbuf_size) + (*++p - '0'); 24011074Sdlw if (dbuf_size == 0) 24111074Sdlw dbuf_size = BIG_DBUF; 24211074Sdlw continue; 2434492Sdlw case 'v': 2444492Sdlw showall = YES; 2454492Sdlw continue; 2464530Sdlw default: 2474530Sdlw printf("od: bad flag -%c\n", *p); 2484530Sdlw puts(usage); 2494530Sdlw exit(1); 2504492Sdlw } 2514492Sdlw *(cv++) = d; 2524492Sdlw } 2534492Sdlw argc--; 2544492Sdlw argv++; 2554492Sdlw } 2564492Sdlw } 2574492Sdlw 2584687Sdlw /* 2594687Sdlw * if nothing spec'd, setup default conversion. 2604687Sdlw */ 2614687Sdlw if(cv == conv_vec) 2624492Sdlw *(cv++) = &u_s_oct; 26311074Sdlw 2644492Sdlw *cv = (struct dfmt *)0; 2654492Sdlw 2664687Sdlw /* 26711074Sdlw * calculate display parameters 26811074Sdlw */ 26911074Sdlw for (cv = conv_vec; d = *cv; cv++) 27011074Sdlw { 27111074Sdlw nelm = (dbuf_size + d->df_size - 1) / d->df_size; 27211074Sdlw llen = nelm * (d->df_field + 1); 27311074Sdlw if (llen > max_llen) 27411074Sdlw max_llen = llen; 27511074Sdlw } 27611074Sdlw 27711074Sdlw /* 2784687Sdlw * setup df_fmt to point to uniform output fields. 2794687Sdlw */ 28011074Sdlw for (cv = conv_vec; d = *cv; cv++) 2814687Sdlw { 2824687Sdlw if (d->df_field) /* only if external field is known */ 2834687Sdlw { 28411074Sdlw nelm = (dbuf_size + d->df_size - 1) / d->df_size; 2854687Sdlw field = max_llen / nelm; 2864687Sdlw d->df_fmt = fmt + 12 - (field - d->df_field); 2874687Sdlw } 2884492Sdlw } 2894492Sdlw 2904687Sdlw /* 2914687Sdlw * input file specified ? 2924687Sdlw */ 2934687Sdlw if(argc > 0 && **argv != '+') 2944687Sdlw { 2954687Sdlw if (freopen(*argv, "r", stdin) == NULL) 2964687Sdlw { 29712093Smckusick perror(*argv); 2984492Sdlw exit(1); 2994492Sdlw } 3004492Sdlw argv++; 3014492Sdlw argc--; 3024492Sdlw } 3034492Sdlw 3044687Sdlw /* 3054687Sdlw * check for possible offset [label] 3064687Sdlw */ 3074530Sdlw if (argc > 0) 3084530Sdlw { 3094530Sdlw addr = get_addr(*argv); 3104530Sdlw offset(addr); 3114530Sdlw argv++; 3124530Sdlw argc--; 3134492Sdlw 3144530Sdlw if (argc > 0) 3154530Sdlw label = get_addr(*argv); 3164530Sdlw } 3174530Sdlw 3184687Sdlw /* 3194687Sdlw * main dump loop 3204687Sdlw */ 3214492Sdlw same = -1; 32211074Sdlw while ((n = fread(dbuf, 1, dbuf_size, stdin)) > 0) 3234687Sdlw { 32416484Sralph if (same>=0 && bcmp(dbuf, lastdbuf, dbuf_size) == 0 && !showall) 3254687Sdlw { 3264687Sdlw if (same==0) 3274687Sdlw { 3284492Sdlw printf("*\n"); 3294492Sdlw same = 1; 3304492Sdlw } 3314492Sdlw } 3324687Sdlw else 3334687Sdlw { 3344492Sdlw line(n); 3354492Sdlw same = 0; 3364492Sdlw p = dbuf; 3374492Sdlw l = lastdbuf; 33811074Sdlw for (nelm = 0; nelm < dbuf_size; nelm++) 3394687Sdlw { 3404492Sdlw *l++ = *p; 3414492Sdlw *p++ = '\0'; 3424492Sdlw } 3434492Sdlw } 3444492Sdlw addr += n; 3454530Sdlw if (label >= 0) 3464530Sdlw label += n; 3474492Sdlw } 3484687Sdlw 3494687Sdlw /* 3504687Sdlw * Some conversions require "flushing". 3514687Sdlw */ 3524687Sdlw n = 0; 3534687Sdlw for (cv = conv_vec; *cv; cv++) 3544687Sdlw { 3554687Sdlw if ((*cv)->df_paddr) 3564687Sdlw { 3574687Sdlw if (n++ == 0) 3584687Sdlw put_addr(addr, label, '\n'); 3594687Sdlw } 3604687Sdlw else 3614687Sdlw (*((*cv)->df_put))(0, *cv); 3624687Sdlw } 3634492Sdlw } 3644492Sdlw 3654687Sdlw put_addr(a, l, c) 3664687Sdlw long a; 3674687Sdlw long l; 3684530Sdlw char c; 3694530Sdlw { 3704687Sdlw fputs(icvt(a, addr_base, UNSIGNED, 7), stdout); 3714687Sdlw if (l >= 0) 3724687Sdlw printf(" (%s)", icvt(l, addr_base, UNSIGNED, 7)); 3734530Sdlw putchar(c); 3744530Sdlw } 3754530Sdlw 3764492Sdlw line(n) 3774492Sdlw int n; 3784492Sdlw { 3794492Sdlw register i, first; 3804492Sdlw register struct dfmt *c; 3814492Sdlw register struct dfmt **cv = conv_vec; 3824492Sdlw 3834492Sdlw first = YES; 3844687Sdlw while (c = *cv++) 3854687Sdlw { 3864687Sdlw if (c->df_paddr) 3874687Sdlw { 3884687Sdlw if (first) 3894687Sdlw { 3904687Sdlw put_addr(addr, label, ' '); 3914687Sdlw first = NO; 3924687Sdlw } 3934687Sdlw else 3944687Sdlw { 3954687Sdlw putchar('\t'); 3964687Sdlw if (label >= 0) 3974687Sdlw fputs("\t ", stdout); 3984687Sdlw } 3994530Sdlw } 4004492Sdlw i = 0; 4014492Sdlw while (i < n) 4024492Sdlw i += (*(c->df_put))(dbuf+i, c); 4034687Sdlw if (c->df_paddr) 4044687Sdlw putchar('\n'); 4054492Sdlw } 4064492Sdlw } 4074492Sdlw 4084492Sdlw s_put(n, d) 4094492Sdlw short *n; 4104492Sdlw struct dfmt *d; 4114492Sdlw { 4124492Sdlw printf(d->df_fmt, icvt((long)*n, d->df_radix, d->df_signed, d->df_field)); 4134492Sdlw return(d->df_size); 4144492Sdlw } 4154492Sdlw 4164492Sdlw us_put(n, d) 4174492Sdlw unsigned short *n; 4184492Sdlw struct dfmt *d; 4194492Sdlw { 4204492Sdlw printf(d->df_fmt, icvt((long)*n, d->df_radix, d->df_signed, d->df_field)); 4214492Sdlw return(d->df_size); 4224492Sdlw } 4234492Sdlw 4244492Sdlw l_put(n, d) 4254492Sdlw long *n; 4264492Sdlw struct dfmt *d; 4274492Sdlw { 4284492Sdlw printf(d->df_fmt, icvt(*n, d->df_radix, d->df_signed, d->df_field)); 4294492Sdlw return(d->df_size); 4304492Sdlw } 4314492Sdlw 4324492Sdlw d_put(f, d) 4334492Sdlw double *f; 4344492Sdlw struct dfmt *d; 4354492Sdlw { 4364492Sdlw char fbuf[24]; 4374500Sdlw struct l { long n[2]; }; 4384500Sdlw 4394500Sdlw #if vax 4404500Sdlw if ((((struct l *)f)->n[0] & 0xff00) == 0x8000) /* Vax illegal f.p. */ 441*32416Sbostic (void)sprintf(fbuf, " %08x %08x", 4424500Sdlw ((struct l *)f)->n[0], ((struct l *)f)->n[1]); 4434500Sdlw else 4444500Sdlw #endif 4454500Sdlw 446*32416Sbostic (void)sprintf(fbuf, "%21.14e", *f); 4474492Sdlw printf(d->df_fmt, fbuf); 4484492Sdlw return(d->df_size); 4494492Sdlw } 4504492Sdlw 4514492Sdlw f_put(f, d) 4524492Sdlw float *f; 4534492Sdlw struct dfmt *d; 4544492Sdlw { 4554492Sdlw char fbuf[16]; 4564500Sdlw 4574500Sdlw #if vax 4584500Sdlw if ((*(long *)f & 0xff00) == 0x8000) /* Vax illegal f.p. form */ 459*32416Sbostic (void)sprintf(fbuf, " %08x", *(long *)f); 4604500Sdlw else 4614500Sdlw #endif 462*32416Sbostic (void)sprintf(fbuf, "%14.7e", *f); 4634492Sdlw printf(d->df_fmt, fbuf); 4644492Sdlw return(d->df_size); 4654492Sdlw } 4664492Sdlw 4674492Sdlw 4684492Sdlw char asc_name[34][4] = { 4694687Sdlw /* 000 */ "nul", "soh", "stx", "etx", "eot", "enq", "ack", "bel", 4704687Sdlw /* 010 */ " bs", " ht", " nl", " vt", " ff", " cr", " so", " si", 4714687Sdlw /* 020 */ "dle", "dc1", "dc2", "dc3", "dc4", "nak", "syn", "etb", 4724687Sdlw /* 030 */ "can", " em", "sub", "esc", " fs", " gs", " rs", " us", 4734687Sdlw /* 040 */ " sp", "del" 4744492Sdlw }; 4754492Sdlw 4764492Sdlw a_put(cc, d) 4774492Sdlw char *cc; 4784492Sdlw struct dfmt *d; 4794492Sdlw { 4804492Sdlw int c = *cc; 4814492Sdlw register char *s = " "; 4824492Sdlw register pbit = parity((int)c & 0377); 4834492Sdlw 4844492Sdlw c &= 0177; 4854687Sdlw if (isgraphic(c)) 4864492Sdlw { 4874687Sdlw s[2] = c; 4884492Sdlw if (pbit == _parity) 4894503Sdlw printf(d->df_fmt, underline(s)); 4904492Sdlw else 4914492Sdlw printf(d->df_fmt, s); 4924492Sdlw } 4934492Sdlw else 4944492Sdlw { 4954492Sdlw if (c == 0177) 4964492Sdlw c = ' ' + 1; 4974492Sdlw if (pbit == _parity) 4984503Sdlw printf(d->df_fmt, underline(asc_name[c])); 4994492Sdlw else 5004492Sdlw printf(d->df_fmt, asc_name[c]); 5014492Sdlw } 5024492Sdlw return(1); 5034492Sdlw } 5044492Sdlw 5054492Sdlw parity(word) 5064492Sdlw int word; 5074492Sdlw { 5084492Sdlw register int p = 0; 5094492Sdlw register int w = word; 5104492Sdlw 5114492Sdlw if (w) 5124687Sdlw do 5134687Sdlw { 5144492Sdlw p ^= 1; 5154492Sdlw } while(w &= (~(-w))); 5164492Sdlw return (p? ODD:EVEN); 5174492Sdlw } 5184492Sdlw 5194492Sdlw char * 5204503Sdlw underline(s) 5214492Sdlw char *s; 5224492Sdlw { 5234492Sdlw static char ulbuf[16]; 5244492Sdlw register char *u = ulbuf; 5254492Sdlw 5264687Sdlw while (*s) 5274687Sdlw { 5284687Sdlw if (*s != ' ') 5294687Sdlw { 5304492Sdlw *u++ = '_'; 5314492Sdlw *u++ = '\b'; 5324492Sdlw } 5334492Sdlw *u++ = *s++; 5344492Sdlw } 5354492Sdlw *u = '\0'; 5364492Sdlw return(ulbuf); 5374492Sdlw } 5384492Sdlw 5394492Sdlw b_put(b, d) 5404492Sdlw char *b; 5414492Sdlw struct dfmt *d; 5424492Sdlw { 5434492Sdlw printf(d->df_fmt, icvt((long)*b & 0377, d->df_radix, d->df_signed, d->df_field)); 5444492Sdlw return(1); 5454492Sdlw } 5464492Sdlw 5474492Sdlw c_put(cc, d) 5484492Sdlw char *cc; 5494492Sdlw struct dfmt *d; 5504492Sdlw { 5514687Sdlw register char *s; 5524687Sdlw register int n; 5534687Sdlw register int c = *cc & 0377; 5544492Sdlw 5554687Sdlw s = scvt(c, d); 5564687Sdlw for (n = d->df_field - strlen(s); n > 0; n--) 5574687Sdlw putchar(' '); 5584687Sdlw printf(d->df_fmt, s); 5594687Sdlw return(1); 5604687Sdlw } 5614687Sdlw 5624687Sdlw char *scvt(c, d) 5634687Sdlw int c; 5644687Sdlw struct dfmt *d; 5654687Sdlw { 5664687Sdlw static char s[2]; 5674687Sdlw 5684687Sdlw switch(c) 5694687Sdlw { 5704687Sdlw case '\0': 5714687Sdlw return("\\0"); 5724687Sdlw 5734687Sdlw case '\b': 5744687Sdlw return("\\b"); 5754687Sdlw 5764687Sdlw case '\f': 5774687Sdlw return("\\f"); 5784687Sdlw 5794687Sdlw case '\n': 5804687Sdlw return("\\n"); 5814687Sdlw 5824687Sdlw case '\r': 5834687Sdlw return("\\r"); 5844687Sdlw 5854687Sdlw case '\t': 5864687Sdlw return("\\t"); 5874687Sdlw 5884687Sdlw default: 5894687Sdlw if (isprint(c)) 5904687Sdlw { 5914687Sdlw s[0] = c; 5924687Sdlw return(s); 5934687Sdlw } 5944687Sdlw return(icvt((long)c, d->df_radix, d->df_signed, d->df_field)); 5954492Sdlw } 5964687Sdlw } 5974492Sdlw 5984687Sdlw /* 5994687Sdlw * Look for strings. 6004687Sdlw * A string contains bytes > 037 && < 177, and ends with a null. 6014687Sdlw * The minimum length is given in the dfmt structure. 6024687Sdlw */ 6034687Sdlw 6044687Sdlw #define CNULL '\0' 6054687Sdlw #define S_EMPTY 0 6064687Sdlw #define S_FILL 1 6074687Sdlw #define S_CONT 2 6084687Sdlw #define SBUFSIZE 1024 6094687Sdlw 6104687Sdlw static char str_buf[SBUFSIZE]; 6114687Sdlw static int str_mode = S_EMPTY; 6124687Sdlw static char *str_ptr; 6134687Sdlw static long str_addr; 6144687Sdlw static long str_label; 6154687Sdlw 6164716Sdlw st_put(cc, d) 6174716Sdlw char *cc; 6184687Sdlw struct dfmt *d; 6194687Sdlw { 6204716Sdlw register int c; 6214716Sdlw 6224716Sdlw if (cc == 0) 6234687Sdlw { 6244687Sdlw pr_sbuf(d, YES); 6254716Sdlw return(1); 6264492Sdlw } 6274716Sdlw 6284716Sdlw c = (*cc & 0377); 6294716Sdlw 6304716Sdlw if (str_mode & S_FILL) 6314687Sdlw { 6324716Sdlw if (isascii(c)) 6334716Sdlw put_sbuf(c, d); 6344687Sdlw else 6354687Sdlw { 6364687Sdlw *str_ptr = CNULL; 6374716Sdlw if (c == NULL) 6384687Sdlw pr_sbuf(d, YES); 6394687Sdlw str_mode = S_EMPTY; 6404687Sdlw } 6414687Sdlw } 6424716Sdlw else if (isascii(c)) 6434687Sdlw { 6444687Sdlw str_mode = S_FILL; 6454716Sdlw str_addr = addr + (cc - dbuf); /* ugly */ 6464687Sdlw if ((str_label = label) >= 0) 6474716Sdlw str_label += (cc - dbuf); /* '' */ 6484687Sdlw str_ptr = str_buf; 6494716Sdlw put_sbuf(c, d); 6504687Sdlw } 6514687Sdlw 6524492Sdlw return(1); 6534492Sdlw } 6544492Sdlw 6554687Sdlw put_sbuf(c, d) 6564716Sdlw int c; 6574687Sdlw struct dfmt *d; 6584687Sdlw { 6594687Sdlw *str_ptr++ = c; 6604687Sdlw if (str_ptr >= (str_buf + SBUFSIZE)) 6614687Sdlw { 6624687Sdlw pr_sbuf(d, NO); 6634687Sdlw str_ptr = str_buf; 6644687Sdlw str_mode |= S_CONT; 6654687Sdlw } 6664687Sdlw } 6674687Sdlw 6684687Sdlw pr_sbuf(d, end) 6694687Sdlw struct dfmt *d; 6704687Sdlw int end; 6714687Sdlw { 6724687Sdlw register char *p = str_buf; 6734687Sdlw 6744687Sdlw if (str_mode == S_EMPTY 6754687Sdlw || (!(str_mode & S_CONT) && (str_ptr - str_buf) < d->df_size)) 6764687Sdlw return; 6774687Sdlw 6784687Sdlw if (!(str_mode & S_CONT)) 6794687Sdlw put_addr(str_addr, str_label, ' '); 6804687Sdlw 6814687Sdlw while (p < str_ptr) 6824687Sdlw fputs(scvt(*p++, d), stdout); 6834687Sdlw 6844687Sdlw if (end) 6854687Sdlw putchar('\n'); 6864687Sdlw } 6874687Sdlw 6884492Sdlw /* 6894492Sdlw * integer to ascii conversion 6904492Sdlw * 6914492Sdlw * This code has been rearranged to produce optimized runtime code. 6924492Sdlw */ 6934492Sdlw 6944492Sdlw #define MAXINTLENGTH 32 6954492Sdlw static char _digit[] = "0123456789abcdef"; 6964492Sdlw static char _icv_buf[MAXINTLENGTH+1]; 6974492Sdlw static long _mask = 0x7fffffff; 6984492Sdlw 6994492Sdlw char * 7004492Sdlw icvt (value, radix, signed, ndigits) 7014492Sdlw long value; 7024492Sdlw int radix; 7034492Sdlw int signed; 7044492Sdlw int ndigits; 7054492Sdlw { 7064492Sdlw register long val = value; 7074492Sdlw register long rad = radix; 7084492Sdlw register char *b = &_icv_buf[MAXINTLENGTH]; 7094492Sdlw register char *d = _digit; 7104492Sdlw register long tmp1; 7114492Sdlw register long tmp2; 7124492Sdlw long rem; 7134492Sdlw long kludge; 7144492Sdlw int sign; 7154492Sdlw 7164492Sdlw if (val == 0) 7174492Sdlw { 7184492Sdlw *--b = '0'; 7194492Sdlw sign = 0; 7204492Sdlw goto done; /*return(b);*/ 7214492Sdlw } 7224492Sdlw 7234492Sdlw if (signed && (sign = (val < 0))) /* signed conversion */ 7244492Sdlw { 7254492Sdlw /* 7264492Sdlw * It is necessary to do the first divide 7274492Sdlw * before the absolute value, for the case -2^31 7284492Sdlw * 7294492Sdlw * This is actually what is being done... 7304492Sdlw * tmp1 = (int)(val % rad); 7314492Sdlw * val /= rad; 7324492Sdlw * val = -val 7334492Sdlw * *--b = d[-tmp1]; 7344492Sdlw */ 7354492Sdlw tmp1 = val / rad; 7364492Sdlw *--b = d[(tmp1 * rad) - val]; 7374492Sdlw val = -tmp1; 7384492Sdlw } 7394492Sdlw else /* unsigned conversion */ 7404492Sdlw { 7414492Sdlw sign = 0; 7424492Sdlw if (val < 0) 7434492Sdlw { /* ALL THIS IS TO SIMULATE UNSIGNED LONG MOD & DIV */ 7444492Sdlw kludge = _mask - (rad - 1); 7454492Sdlw val &= _mask; 7464492Sdlw /* 7474492Sdlw * This is really what's being done... 7484492Sdlw * rem = (kludge % rad) + (val % rad); 7494492Sdlw * val = (kludge / rad) + (val / rad) + (rem / rad) + 1; 7504492Sdlw * *--b = d[rem % rad]; 7514492Sdlw */ 7524492Sdlw tmp1 = kludge / rad; 7534492Sdlw tmp2 = val / rad; 7544492Sdlw rem = (kludge - (tmp1 * rad)) + (val - (tmp2 * rad)); 7554492Sdlw val = ++tmp1 + tmp2; 7564492Sdlw tmp1 = rem / rad; 7574492Sdlw val += tmp1; 7584492Sdlw *--b = d[rem - (tmp1 * rad)]; 7594492Sdlw } 7604492Sdlw } 7614492Sdlw 7624492Sdlw while (val) 7634492Sdlw { 7644492Sdlw /* 7654492Sdlw * This is really what's being done ... 7664492Sdlw * *--b = d[val % rad]; 7674492Sdlw * val /= rad; 7684492Sdlw */ 7694492Sdlw tmp1 = val / rad; 7704492Sdlw *--b = d[val - (tmp1 * rad)]; 7714492Sdlw val = tmp1; 7724492Sdlw } 7734492Sdlw 7744492Sdlw done: 7754492Sdlw if (sign) 7764492Sdlw *--b = '-'; 7774492Sdlw 7784492Sdlw tmp1 = ndigits - (&_icv_buf[MAXINTLENGTH] - b); 7794492Sdlw tmp2 = signed? ' ':'0'; 7804492Sdlw while (tmp1 > 0) 7814492Sdlw { 7824492Sdlw *--b = tmp2; 7834492Sdlw tmp1--; 7844492Sdlw } 7854492Sdlw 7864492Sdlw return(b); 7874492Sdlw } 7884492Sdlw 7894687Sdlw long get_addr(s) 7904492Sdlw register char *s; 7914492Sdlw { 7924492Sdlw register char *p; 7934530Sdlw register long a; 7944492Sdlw register int d; 7954492Sdlw 7964492Sdlw if (*s=='+') 7974492Sdlw s++; 7984687Sdlw if (*s=='x') 7994687Sdlw { 8004492Sdlw s++; 8014492Sdlw addr_base = 16; 8024687Sdlw } 8034687Sdlw else if (*s=='0' && s[1]=='x') 8044687Sdlw { 8054492Sdlw s += 2; 8064492Sdlw addr_base = 16; 8074687Sdlw } 8084687Sdlw else if (*s == '0') 8094492Sdlw addr_base = 8; 8104492Sdlw p = s; 8114687Sdlw while(*p) 8124687Sdlw { 8134492Sdlw if (*p++=='.') 8144492Sdlw addr_base = 10; 8154492Sdlw } 8164687Sdlw for (a=0; *s; s++) 8174687Sdlw { 8184492Sdlw d = *s; 8194687Sdlw if(isdigit(d)) 8204492Sdlw a = a*addr_base + d - '0'; 8214687Sdlw else if (ishex(d) && addr_base==16) 8224492Sdlw a = a*addr_base + d + 10 - 'a'; 8234492Sdlw else 8244492Sdlw break; 8254492Sdlw } 8264530Sdlw 8274492Sdlw if (*s == '.') 8284492Sdlw s++; 8294530Sdlw if(*s=='b') 8304492Sdlw a *= 512; 8314530Sdlw if(*s=='B') 8324530Sdlw a *= 1024; 8334530Sdlw 8344530Sdlw return(a); 8354530Sdlw } 8364530Sdlw 8374530Sdlw offset(a) 8384530Sdlw long a; 8394530Sdlw { 8404492Sdlw if (canseek(stdin)) 84111071Sdlw { 84211071Sdlw /* 84311071Sdlw * in case we're accessing a raw disk, 84411071Sdlw * we have to seek in multiples of a physical block. 84511071Sdlw */ 84611071Sdlw fseek(stdin, a & 0xfffffe00L, 0); 84711071Sdlw a &= 0x1ffL; 84811071Sdlw } 84911071Sdlw dumbseek(stdin, a); 8504492Sdlw } 8514492Sdlw 8524492Sdlw dumbseek(s, offset) 8534492Sdlw FILE *s; 8544492Sdlw long offset; 8554492Sdlw { 8564492Sdlw char buf[BUFSIZ]; 8574492Sdlw int n; 8584492Sdlw int nr; 8594492Sdlw 8604492Sdlw while (offset > 0) 8614492Sdlw { 8624492Sdlw nr = (offset > BUFSIZ) ? BUFSIZ : (int)offset; 8634492Sdlw if ((n = fread(buf, 1, nr, s)) != nr) 8644492Sdlw { 8654492Sdlw fprintf(stderr, "EOF\n"); 8664492Sdlw exit(1); 8674492Sdlw } 8684492Sdlw offset -= n; 8694492Sdlw } 8704492Sdlw } 8714492Sdlw 8724492Sdlw #include <sys/types.h> 8734492Sdlw #include <sys/stat.h> 8744492Sdlw 8754492Sdlw canseek(f) 8764492Sdlw FILE *f; 8774492Sdlw { 8784492Sdlw struct stat statb; 8794492Sdlw 8804492Sdlw return( (fstat(fileno(f),&statb)==0) && 8814492Sdlw (statb.st_nlink > 0) && /*!pipe*/ 8824492Sdlw (!isatty(fileno(f))) ); 8834492Sdlw } 884