1*32739Sbostic static char *sccsid = "@(#)od.c 5.14 (Berkeley) 12/02/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 } 363*32739Sbostic exit(0); 3644492Sdlw } 3654492Sdlw 3664687Sdlw put_addr(a, l, c) 3674687Sdlw long a; 3684687Sdlw long l; 3694530Sdlw char c; 3704530Sdlw { 3714687Sdlw fputs(icvt(a, addr_base, UNSIGNED, 7), stdout); 3724687Sdlw if (l >= 0) 3734687Sdlw printf(" (%s)", icvt(l, addr_base, UNSIGNED, 7)); 3744530Sdlw putchar(c); 3754530Sdlw } 3764530Sdlw 3774492Sdlw line(n) 3784492Sdlw int n; 3794492Sdlw { 3804492Sdlw register i, first; 3814492Sdlw register struct dfmt *c; 3824492Sdlw register struct dfmt **cv = conv_vec; 3834492Sdlw 3844492Sdlw first = YES; 3854687Sdlw while (c = *cv++) 3864687Sdlw { 3874687Sdlw if (c->df_paddr) 3884687Sdlw { 3894687Sdlw if (first) 3904687Sdlw { 3914687Sdlw put_addr(addr, label, ' '); 3924687Sdlw first = NO; 3934687Sdlw } 3944687Sdlw else 3954687Sdlw { 3964687Sdlw putchar('\t'); 3974687Sdlw if (label >= 0) 3984687Sdlw fputs("\t ", stdout); 3994687Sdlw } 4004530Sdlw } 4014492Sdlw i = 0; 4024492Sdlw while (i < n) 4034492Sdlw i += (*(c->df_put))(dbuf+i, c); 4044687Sdlw if (c->df_paddr) 4054687Sdlw putchar('\n'); 4064492Sdlw } 4074492Sdlw } 4084492Sdlw 4094492Sdlw s_put(n, d) 4104492Sdlw short *n; 4114492Sdlw struct dfmt *d; 4124492Sdlw { 4134492Sdlw printf(d->df_fmt, icvt((long)*n, d->df_radix, d->df_signed, d->df_field)); 4144492Sdlw return(d->df_size); 4154492Sdlw } 4164492Sdlw 4174492Sdlw us_put(n, d) 4184492Sdlw unsigned short *n; 4194492Sdlw struct dfmt *d; 4204492Sdlw { 4214492Sdlw printf(d->df_fmt, icvt((long)*n, d->df_radix, d->df_signed, d->df_field)); 4224492Sdlw return(d->df_size); 4234492Sdlw } 4244492Sdlw 4254492Sdlw l_put(n, d) 4264492Sdlw long *n; 4274492Sdlw struct dfmt *d; 4284492Sdlw { 4294492Sdlw printf(d->df_fmt, icvt(*n, d->df_radix, d->df_signed, d->df_field)); 4304492Sdlw return(d->df_size); 4314492Sdlw } 4324492Sdlw 4334492Sdlw d_put(f, d) 4344492Sdlw double *f; 4354492Sdlw struct dfmt *d; 4364492Sdlw { 4374492Sdlw char fbuf[24]; 4384500Sdlw struct l { long n[2]; }; 4394500Sdlw 4404500Sdlw #if vax 4414500Sdlw if ((((struct l *)f)->n[0] & 0xff00) == 0x8000) /* Vax illegal f.p. */ 44232416Sbostic (void)sprintf(fbuf, " %08x %08x", 4434500Sdlw ((struct l *)f)->n[0], ((struct l *)f)->n[1]); 4444500Sdlw else 4454500Sdlw #endif 4464500Sdlw 44732416Sbostic (void)sprintf(fbuf, "%21.14e", *f); 4484492Sdlw printf(d->df_fmt, fbuf); 4494492Sdlw return(d->df_size); 4504492Sdlw } 4514492Sdlw 4524492Sdlw f_put(f, d) 4534492Sdlw float *f; 4544492Sdlw struct dfmt *d; 4554492Sdlw { 4564492Sdlw char fbuf[16]; 4574500Sdlw 4584500Sdlw #if vax 4594500Sdlw if ((*(long *)f & 0xff00) == 0x8000) /* Vax illegal f.p. form */ 46032416Sbostic (void)sprintf(fbuf, " %08x", *(long *)f); 4614500Sdlw else 4624500Sdlw #endif 46332416Sbostic (void)sprintf(fbuf, "%14.7e", *f); 4644492Sdlw printf(d->df_fmt, fbuf); 4654492Sdlw return(d->df_size); 4664492Sdlw } 4674492Sdlw 4684492Sdlw 4694492Sdlw char asc_name[34][4] = { 4704687Sdlw /* 000 */ "nul", "soh", "stx", "etx", "eot", "enq", "ack", "bel", 4714687Sdlw /* 010 */ " bs", " ht", " nl", " vt", " ff", " cr", " so", " si", 4724687Sdlw /* 020 */ "dle", "dc1", "dc2", "dc3", "dc4", "nak", "syn", "etb", 4734687Sdlw /* 030 */ "can", " em", "sub", "esc", " fs", " gs", " rs", " us", 4744687Sdlw /* 040 */ " sp", "del" 4754492Sdlw }; 4764492Sdlw 4774492Sdlw a_put(cc, d) 4784492Sdlw char *cc; 4794492Sdlw struct dfmt *d; 4804492Sdlw { 4814492Sdlw int c = *cc; 4824492Sdlw register char *s = " "; 4834492Sdlw register pbit = parity((int)c & 0377); 4844492Sdlw 4854492Sdlw c &= 0177; 4864687Sdlw if (isgraphic(c)) 4874492Sdlw { 4884687Sdlw s[2] = c; 4894492Sdlw if (pbit == _parity) 4904503Sdlw printf(d->df_fmt, underline(s)); 4914492Sdlw else 4924492Sdlw printf(d->df_fmt, s); 4934492Sdlw } 4944492Sdlw else 4954492Sdlw { 4964492Sdlw if (c == 0177) 4974492Sdlw c = ' ' + 1; 4984492Sdlw if (pbit == _parity) 4994503Sdlw printf(d->df_fmt, underline(asc_name[c])); 5004492Sdlw else 5014492Sdlw printf(d->df_fmt, asc_name[c]); 5024492Sdlw } 5034492Sdlw return(1); 5044492Sdlw } 5054492Sdlw 5064492Sdlw parity(word) 5074492Sdlw int word; 5084492Sdlw { 5094492Sdlw register int p = 0; 5104492Sdlw register int w = word; 5114492Sdlw 5124492Sdlw if (w) 5134687Sdlw do 5144687Sdlw { 5154492Sdlw p ^= 1; 5164492Sdlw } while(w &= (~(-w))); 5174492Sdlw return (p? ODD:EVEN); 5184492Sdlw } 5194492Sdlw 5204492Sdlw char * 5214503Sdlw underline(s) 5224492Sdlw char *s; 5234492Sdlw { 5244492Sdlw static char ulbuf[16]; 5254492Sdlw register char *u = ulbuf; 5264492Sdlw 5274687Sdlw while (*s) 5284687Sdlw { 5294687Sdlw if (*s != ' ') 5304687Sdlw { 5314492Sdlw *u++ = '_'; 5324492Sdlw *u++ = '\b'; 5334492Sdlw } 5344492Sdlw *u++ = *s++; 5354492Sdlw } 5364492Sdlw *u = '\0'; 5374492Sdlw return(ulbuf); 5384492Sdlw } 5394492Sdlw 5404492Sdlw b_put(b, d) 5414492Sdlw char *b; 5424492Sdlw struct dfmt *d; 5434492Sdlw { 5444492Sdlw printf(d->df_fmt, icvt((long)*b & 0377, d->df_radix, d->df_signed, d->df_field)); 5454492Sdlw return(1); 5464492Sdlw } 5474492Sdlw 5484492Sdlw c_put(cc, d) 5494492Sdlw char *cc; 5504492Sdlw struct dfmt *d; 5514492Sdlw { 5524687Sdlw register char *s; 5534687Sdlw register int n; 5544687Sdlw register int c = *cc & 0377; 5554492Sdlw 5564687Sdlw s = scvt(c, d); 5574687Sdlw for (n = d->df_field - strlen(s); n > 0; n--) 5584687Sdlw putchar(' '); 5594687Sdlw printf(d->df_fmt, s); 5604687Sdlw return(1); 5614687Sdlw } 5624687Sdlw 5634687Sdlw char *scvt(c, d) 5644687Sdlw int c; 5654687Sdlw struct dfmt *d; 5664687Sdlw { 5674687Sdlw static char s[2]; 5684687Sdlw 5694687Sdlw switch(c) 5704687Sdlw { 5714687Sdlw case '\0': 5724687Sdlw return("\\0"); 5734687Sdlw 5744687Sdlw case '\b': 5754687Sdlw return("\\b"); 5764687Sdlw 5774687Sdlw case '\f': 5784687Sdlw return("\\f"); 5794687Sdlw 5804687Sdlw case '\n': 5814687Sdlw return("\\n"); 5824687Sdlw 5834687Sdlw case '\r': 5844687Sdlw return("\\r"); 5854687Sdlw 5864687Sdlw case '\t': 5874687Sdlw return("\\t"); 5884687Sdlw 5894687Sdlw default: 5904687Sdlw if (isprint(c)) 5914687Sdlw { 5924687Sdlw s[0] = c; 5934687Sdlw return(s); 5944687Sdlw } 5954687Sdlw return(icvt((long)c, d->df_radix, d->df_signed, d->df_field)); 5964492Sdlw } 5974687Sdlw } 5984492Sdlw 5994687Sdlw /* 6004687Sdlw * Look for strings. 6014687Sdlw * A string contains bytes > 037 && < 177, and ends with a null. 6024687Sdlw * The minimum length is given in the dfmt structure. 6034687Sdlw */ 6044687Sdlw 6054687Sdlw #define CNULL '\0' 6064687Sdlw #define S_EMPTY 0 6074687Sdlw #define S_FILL 1 6084687Sdlw #define S_CONT 2 6094687Sdlw #define SBUFSIZE 1024 6104687Sdlw 6114687Sdlw static char str_buf[SBUFSIZE]; 6124687Sdlw static int str_mode = S_EMPTY; 6134687Sdlw static char *str_ptr; 6144687Sdlw static long str_addr; 6154687Sdlw static long str_label; 6164687Sdlw 6174716Sdlw st_put(cc, d) 6184716Sdlw char *cc; 6194687Sdlw struct dfmt *d; 6204687Sdlw { 6214716Sdlw register int c; 6224716Sdlw 6234716Sdlw if (cc == 0) 6244687Sdlw { 6254687Sdlw pr_sbuf(d, YES); 6264716Sdlw return(1); 6274492Sdlw } 6284716Sdlw 6294716Sdlw c = (*cc & 0377); 6304716Sdlw 6314716Sdlw if (str_mode & S_FILL) 6324687Sdlw { 6334716Sdlw if (isascii(c)) 6344716Sdlw put_sbuf(c, d); 6354687Sdlw else 6364687Sdlw { 6374687Sdlw *str_ptr = CNULL; 6384716Sdlw if (c == NULL) 6394687Sdlw pr_sbuf(d, YES); 6404687Sdlw str_mode = S_EMPTY; 6414687Sdlw } 6424687Sdlw } 6434716Sdlw else if (isascii(c)) 6444687Sdlw { 6454687Sdlw str_mode = S_FILL; 6464716Sdlw str_addr = addr + (cc - dbuf); /* ugly */ 6474687Sdlw if ((str_label = label) >= 0) 6484716Sdlw str_label += (cc - dbuf); /* '' */ 6494687Sdlw str_ptr = str_buf; 6504716Sdlw put_sbuf(c, d); 6514687Sdlw } 6524687Sdlw 6534492Sdlw return(1); 6544492Sdlw } 6554492Sdlw 6564687Sdlw put_sbuf(c, d) 6574716Sdlw int c; 6584687Sdlw struct dfmt *d; 6594687Sdlw { 6604687Sdlw *str_ptr++ = c; 6614687Sdlw if (str_ptr >= (str_buf + SBUFSIZE)) 6624687Sdlw { 6634687Sdlw pr_sbuf(d, NO); 6644687Sdlw str_ptr = str_buf; 6654687Sdlw str_mode |= S_CONT; 6664687Sdlw } 6674687Sdlw } 6684687Sdlw 6694687Sdlw pr_sbuf(d, end) 6704687Sdlw struct dfmt *d; 6714687Sdlw int end; 6724687Sdlw { 6734687Sdlw register char *p = str_buf; 6744687Sdlw 6754687Sdlw if (str_mode == S_EMPTY 6764687Sdlw || (!(str_mode & S_CONT) && (str_ptr - str_buf) < d->df_size)) 6774687Sdlw return; 6784687Sdlw 6794687Sdlw if (!(str_mode & S_CONT)) 6804687Sdlw put_addr(str_addr, str_label, ' '); 6814687Sdlw 6824687Sdlw while (p < str_ptr) 6834687Sdlw fputs(scvt(*p++, d), stdout); 6844687Sdlw 6854687Sdlw if (end) 6864687Sdlw putchar('\n'); 6874687Sdlw } 6884687Sdlw 6894492Sdlw /* 6904492Sdlw * integer to ascii conversion 6914492Sdlw * 6924492Sdlw * This code has been rearranged to produce optimized runtime code. 6934492Sdlw */ 6944492Sdlw 6954492Sdlw #define MAXINTLENGTH 32 6964492Sdlw static char _digit[] = "0123456789abcdef"; 6974492Sdlw static char _icv_buf[MAXINTLENGTH+1]; 6984492Sdlw static long _mask = 0x7fffffff; 6994492Sdlw 7004492Sdlw char * 7014492Sdlw icvt (value, radix, signed, ndigits) 7024492Sdlw long value; 7034492Sdlw int radix; 7044492Sdlw int signed; 7054492Sdlw int ndigits; 7064492Sdlw { 7074492Sdlw register long val = value; 7084492Sdlw register long rad = radix; 7094492Sdlw register char *b = &_icv_buf[MAXINTLENGTH]; 7104492Sdlw register char *d = _digit; 7114492Sdlw register long tmp1; 7124492Sdlw register long tmp2; 7134492Sdlw long rem; 7144492Sdlw long kludge; 7154492Sdlw int sign; 7164492Sdlw 7174492Sdlw if (val == 0) 7184492Sdlw { 7194492Sdlw *--b = '0'; 7204492Sdlw sign = 0; 7214492Sdlw goto done; /*return(b);*/ 7224492Sdlw } 7234492Sdlw 7244492Sdlw if (signed && (sign = (val < 0))) /* signed conversion */ 7254492Sdlw { 7264492Sdlw /* 7274492Sdlw * It is necessary to do the first divide 7284492Sdlw * before the absolute value, for the case -2^31 7294492Sdlw * 7304492Sdlw * This is actually what is being done... 7314492Sdlw * tmp1 = (int)(val % rad); 7324492Sdlw * val /= rad; 7334492Sdlw * val = -val 7344492Sdlw * *--b = d[-tmp1]; 7354492Sdlw */ 7364492Sdlw tmp1 = val / rad; 7374492Sdlw *--b = d[(tmp1 * rad) - val]; 7384492Sdlw val = -tmp1; 7394492Sdlw } 7404492Sdlw else /* unsigned conversion */ 7414492Sdlw { 7424492Sdlw sign = 0; 7434492Sdlw if (val < 0) 7444492Sdlw { /* ALL THIS IS TO SIMULATE UNSIGNED LONG MOD & DIV */ 7454492Sdlw kludge = _mask - (rad - 1); 7464492Sdlw val &= _mask; 7474492Sdlw /* 7484492Sdlw * This is really what's being done... 7494492Sdlw * rem = (kludge % rad) + (val % rad); 7504492Sdlw * val = (kludge / rad) + (val / rad) + (rem / rad) + 1; 7514492Sdlw * *--b = d[rem % rad]; 7524492Sdlw */ 7534492Sdlw tmp1 = kludge / rad; 7544492Sdlw tmp2 = val / rad; 7554492Sdlw rem = (kludge - (tmp1 * rad)) + (val - (tmp2 * rad)); 7564492Sdlw val = ++tmp1 + tmp2; 7574492Sdlw tmp1 = rem / rad; 7584492Sdlw val += tmp1; 7594492Sdlw *--b = d[rem - (tmp1 * rad)]; 7604492Sdlw } 7614492Sdlw } 7624492Sdlw 7634492Sdlw while (val) 7644492Sdlw { 7654492Sdlw /* 7664492Sdlw * This is really what's being done ... 7674492Sdlw * *--b = d[val % rad]; 7684492Sdlw * val /= rad; 7694492Sdlw */ 7704492Sdlw tmp1 = val / rad; 7714492Sdlw *--b = d[val - (tmp1 * rad)]; 7724492Sdlw val = tmp1; 7734492Sdlw } 7744492Sdlw 7754492Sdlw done: 7764492Sdlw if (sign) 7774492Sdlw *--b = '-'; 7784492Sdlw 7794492Sdlw tmp1 = ndigits - (&_icv_buf[MAXINTLENGTH] - b); 7804492Sdlw tmp2 = signed? ' ':'0'; 7814492Sdlw while (tmp1 > 0) 7824492Sdlw { 7834492Sdlw *--b = tmp2; 7844492Sdlw tmp1--; 7854492Sdlw } 7864492Sdlw 7874492Sdlw return(b); 7884492Sdlw } 7894492Sdlw 7904687Sdlw long get_addr(s) 7914492Sdlw register char *s; 7924492Sdlw { 7934492Sdlw register char *p; 7944530Sdlw register long a; 7954492Sdlw register int d; 7964492Sdlw 7974492Sdlw if (*s=='+') 7984492Sdlw s++; 7994687Sdlw if (*s=='x') 8004687Sdlw { 8014492Sdlw s++; 8024492Sdlw addr_base = 16; 8034687Sdlw } 8044687Sdlw else if (*s=='0' && s[1]=='x') 8054687Sdlw { 8064492Sdlw s += 2; 8074492Sdlw addr_base = 16; 8084687Sdlw } 8094687Sdlw else if (*s == '0') 8104492Sdlw addr_base = 8; 8114492Sdlw p = s; 8124687Sdlw while(*p) 8134687Sdlw { 8144492Sdlw if (*p++=='.') 8154492Sdlw addr_base = 10; 8164492Sdlw } 8174687Sdlw for (a=0; *s; s++) 8184687Sdlw { 8194492Sdlw d = *s; 8204687Sdlw if(isdigit(d)) 8214492Sdlw a = a*addr_base + d - '0'; 8224687Sdlw else if (ishex(d) && addr_base==16) 8234492Sdlw a = a*addr_base + d + 10 - 'a'; 8244492Sdlw else 8254492Sdlw break; 8264492Sdlw } 8274530Sdlw 8284492Sdlw if (*s == '.') 8294492Sdlw s++; 8304530Sdlw if(*s=='b') 8314492Sdlw a *= 512; 8324530Sdlw if(*s=='B') 8334530Sdlw a *= 1024; 8344530Sdlw 8354530Sdlw return(a); 8364530Sdlw } 8374530Sdlw 8384530Sdlw offset(a) 8394530Sdlw long a; 8404530Sdlw { 8414492Sdlw if (canseek(stdin)) 84211071Sdlw { 84311071Sdlw /* 84411071Sdlw * in case we're accessing a raw disk, 84511071Sdlw * we have to seek in multiples of a physical block. 84611071Sdlw */ 84711071Sdlw fseek(stdin, a & 0xfffffe00L, 0); 84811071Sdlw a &= 0x1ffL; 84911071Sdlw } 85011071Sdlw dumbseek(stdin, a); 8514492Sdlw } 8524492Sdlw 8534492Sdlw dumbseek(s, offset) 8544492Sdlw FILE *s; 8554492Sdlw long offset; 8564492Sdlw { 8574492Sdlw char buf[BUFSIZ]; 8584492Sdlw int n; 8594492Sdlw int nr; 8604492Sdlw 8614492Sdlw while (offset > 0) 8624492Sdlw { 8634492Sdlw nr = (offset > BUFSIZ) ? BUFSIZ : (int)offset; 8644492Sdlw if ((n = fread(buf, 1, nr, s)) != nr) 8654492Sdlw { 8664492Sdlw fprintf(stderr, "EOF\n"); 8674492Sdlw exit(1); 8684492Sdlw } 8694492Sdlw offset -= n; 8704492Sdlw } 8714492Sdlw } 8724492Sdlw 8734492Sdlw #include <sys/types.h> 8744492Sdlw #include <sys/stat.h> 8754492Sdlw 8764492Sdlw canseek(f) 8774492Sdlw FILE *f; 8784492Sdlw { 8794492Sdlw struct stat statb; 8804492Sdlw 8814492Sdlw return( (fstat(fileno(f),&statb)==0) && 8824492Sdlw (statb.st_nlink > 0) && /*!pipe*/ 8834492Sdlw (!isatty(fileno(f))) ); 8844492Sdlw } 885