1*4875Sdlw static char *sccsid = "@(#)od.c 5.7 (Berkeley) 11/12/81"; 24492Sdlw /* 34492Sdlw * od -- octal, hex, decimal, character dump of data in a file. 44492Sdlw * 54687Sdlw * usage: od [-abBcdDefFhHiIlLopPsvxX] [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 224687Sdlw * s 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. 274492Sdlw * 284492Sdlw * More than one format character may be given. 294492Sdlw * If {file} is not specified, standard input is read. 304492Sdlw * If {file} is not specified, then {offset} must start with '+'. 314492Sdlw * {Offset} may be HEX (0xnnn), OCTAL (0nn), or decimal (nnn.); the default 324492Sdlw * is the same as the address radix, which will be the same as the first 334492Sdlw * object radix. 344492Sdlw */ 354492Sdlw 364492Sdlw #include <stdio.h> 374492Sdlw 384687Sdlw #define DBUF_SIZE 16 394687Sdlw #define NO 0 404687Sdlw #define YES 1 414687Sdlw #define EVEN -1 424687Sdlw #define ODD 1 434687Sdlw #define UNSIGNED 0 444687Sdlw #define SIGNED 1 454687Sdlw #define PADDR 1 464687Sdlw #define MIN_SLEN 3 474492Sdlw 484492Sdlw int a_put(); 494492Sdlw int b_put(); 504492Sdlw int c_put(); 514492Sdlw int s_put(); 524492Sdlw int us_put(); 534492Sdlw int l_put(); 544492Sdlw int f_put(); 554492Sdlw int d_put(); 564687Sdlw int st_put(); 574492Sdlw 584492Sdlw struct dfmt { 594492Sdlw int df_field; /* external field required for object */ 604492Sdlw int df_size; /* size (bytes) of object */ 614492Sdlw int df_radix; /* conversion radix */ 624492Sdlw int df_signed; /* signed? flag */ 634687Sdlw int df_paddr; /* "put address on each line?" flag */ 644492Sdlw int (*df_put)(); /* function to output object */ 654687Sdlw char *df_fmt; /* output string format */ 664492Sdlw } *conv_vec[32]; /* vector of conversions to be done */ 674492Sdlw 684687Sdlw struct dfmt ascii = { 3, sizeof (char), 10, 0, PADDR, a_put, 0}; 694687Sdlw struct dfmt byte = { 3, sizeof (char), 8, UNSIGNED, PADDR, b_put, 0}; 704687Sdlw struct dfmt cchar = { 3, sizeof (char), 8, UNSIGNED, PADDR, c_put, 0}; 714687Sdlw struct dfmt u_s_oct = { 6, sizeof (short), 8, UNSIGNED, PADDR, us_put, 0}; 724687Sdlw struct dfmt u_s_dec = { 5, sizeof (short), 10, UNSIGNED, PADDR, us_put, 0}; 734687Sdlw struct dfmt u_s_hex = { 4, sizeof (short), 16, UNSIGNED, PADDR, us_put, 0}; 744687Sdlw struct dfmt u_l_oct = {11, sizeof (long), 8, UNSIGNED, PADDR, l_put, 0}; 754687Sdlw struct dfmt u_l_dec = {10, sizeof (long), 10, UNSIGNED, PADDR, l_put, 0}; 764687Sdlw struct dfmt u_l_hex = { 8, sizeof (long), 16, UNSIGNED, PADDR, l_put, 0}; 774687Sdlw struct dfmt s_s_dec = { 6, sizeof (short), 10, SIGNED, PADDR, s_put, 0}; 784687Sdlw struct dfmt s_l_dec = {11, sizeof (long), 10, SIGNED, PADDR, l_put, 0}; 794687Sdlw struct dfmt flt = {14, sizeof (float), 10, SIGNED, PADDR, f_put, 0}; 804687Sdlw struct dfmt dble = {21, sizeof (double), 10, SIGNED, PADDR, d_put, 0}; 814687Sdlw struct dfmt string = { 0, 0, 8, 0, NO, st_put, 0}; 824492Sdlw 834530Sdlw 844687Sdlw char usage[] = "usage: od [-abcdfhilopsvx] [file] [[+]offset[.][b] [label]]"; 854687Sdlw char dbuf[DBUF_SIZE]; 864687Sdlw char lastdbuf[DBUF_SIZE]; 87*4875Sdlw int addr_base = 8; /* default address base is OCTAL */ 884492Sdlw long addr; 894530Sdlw long label = -1L; 904492Sdlw int _parity = NO; 914492Sdlw char fmt[] = " %s"; /* 12 blanks */ 924492Sdlw char *icvt(); 934687Sdlw char *scvt(); 944492Sdlw char *underline(); 954530Sdlw long get_addr(); 964492Sdlw 974530Sdlw 984687Sdlw /* 994687Sdlw * special form of _ctype 1004687Sdlw */ 1014687Sdlw 1024687Sdlw #define A 01 1034687Sdlw #define G 02 1044687Sdlw #define D 04 1054687Sdlw #define P 010 1064687Sdlw #define X 020 1074687Sdlw #define isdigit(c) (_ctype[c] & D) 1084687Sdlw #define isascii(c) (_ctype[c] & A) 1094687Sdlw #define isgraphic(c) (_ctype[c] & G) 1104687Sdlw #define isprint(c) (_ctype[c] & P) 1114687Sdlw #define ishex(c) (_ctype[c] & (X|D)) 1124687Sdlw 1134687Sdlw char _ctype[256] = { 1144687Sdlw /* 000 */ 0, 0, 0, 0, 0, 0, 0, 0, 1154687Sdlw /* 010 */ A, A, A, 0, A, A, 0, 0, 1164687Sdlw /* 020 */ 0, 0, 0, 0, 0, 0, 0, 0, 1174687Sdlw /* 030 */ 0, 0, 0, 0, 0, 0, 0, 0, 1184687Sdlw /* 040 */ P|A, P|G|A, P|G|A, P|G|A, P|G|A, P|G|A, P|G|A, P|G|A, 1194687Sdlw /* 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, 1204687Sdlw /* 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, 1214687Sdlw /* 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, 1224687Sdlw /* 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, 1234687Sdlw /* 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, 1244687Sdlw /* 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, 1254687Sdlw /* 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, 1264687Sdlw /* 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, 1274687Sdlw /* 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, 1284687Sdlw /* 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, 1294687Sdlw /* 170 */ P|G|A, P|G|A, P|G|A, P|G|A, P|G|A, P|G|A, P|G|A, 0, 1304687Sdlw /* 200 */ 0, 0, 0, 0, 0, 0, 0, 0, 1314687Sdlw /* 210 */ 0, 0, 0, 0, 0, 0, 0, 0, 1324687Sdlw /* 220 */ 0, 0, 0, 0, 0, 0, 0, 0, 1334687Sdlw /* 230 */ 0, 0, 0, 0, 0, 0, 0, 0, 1344687Sdlw /* 240 */ 0, 0, 0, 0, 0, 0, 0, 0, 1354687Sdlw /* 250 */ 0, 0, 0, 0, 0, 0, 0, 0, 1364687Sdlw /* 260 */ 0, 0, 0, 0, 0, 0, 0, 0, 1374687Sdlw /* 270 */ 0, 0, 0, 0, 0, 0, 0, 0, 1384687Sdlw /* 300 */ 0, 0, 0, 0, 0, 0, 0, 0, 1394687Sdlw /* 310 */ 0, 0, 0, 0, 0, 0, 0, 0, 1404687Sdlw /* 320 */ 0, 0, 0, 0, 0, 0, 0, 0, 1414687Sdlw /* 330 */ 0, 0, 0, 0, 0, 0, 0, 0, 1424687Sdlw /* 340 */ 0, 0, 0, 0, 0, 0, 0, 0, 1434687Sdlw /* 350 */ 0, 0, 0, 0, 0, 0, 0, 0, 1444687Sdlw /* 360 */ 0, 0, 0, 0, 0, 0, 0, 0, 1454687Sdlw /* 370 */ 0, 0, 0, 0, 0, 0, 0, 0, 1464687Sdlw }; 1474687Sdlw 1484687Sdlw 1494492Sdlw main(argc, argv) 1504687Sdlw int argc; 1514687Sdlw char **argv; 1524492Sdlw { 1534492Sdlw register char *p; 1544492Sdlw register char *l; 1554492Sdlw register n, same; 1564492Sdlw struct dfmt *d; 1574492Sdlw struct dfmt **cv = conv_vec; 1584492Sdlw int showall = NO; 1594492Sdlw int field, llen, nelm; 1604492Sdlw int max_llen = 0; 1614492Sdlw 1624492Sdlw argv++; 1634530Sdlw argc--; 1644492Sdlw max_llen = max_nelm = 0; 1654492Sdlw 1664687Sdlw if(argc > 0) 1674687Sdlw { 1684492Sdlw p = *argv; 1694687Sdlw if(*p == '-') 1704687Sdlw { 1714687Sdlw while(*++p != '\0') 1724687Sdlw { 1734687Sdlw switch(*p) 1744687Sdlw { 1754492Sdlw case 'a': 1764492Sdlw d = &ascii; 1774492Sdlw break; 1784492Sdlw case 'b': 1794492Sdlw d = &byte; 1804492Sdlw break; 1814492Sdlw case 'c': 1824492Sdlw d = &cchar; 1834492Sdlw break; 1844492Sdlw case 'd': 1854492Sdlw d = &u_s_dec; 1864492Sdlw break; 1874492Sdlw case 'D': 1884492Sdlw d = &u_l_dec; 1894492Sdlw break; 1904492Sdlw case 'e': 1914492Sdlw case 'F': 1924492Sdlw d = &dble; 1934492Sdlw break; 1944492Sdlw case 'f': 1954492Sdlw d = &flt; 1964492Sdlw break; 1974492Sdlw case 'h': 1984492Sdlw case 'x': 1994492Sdlw d = &u_s_hex; 2004492Sdlw break; 2014492Sdlw case 'H': 2024492Sdlw case 'X': 2034492Sdlw d = &u_l_hex; 2044492Sdlw break; 2054492Sdlw case 'i': 2064492Sdlw d = &s_s_dec; 2074492Sdlw break; 2084492Sdlw case 'I': 2094492Sdlw case 'l': 2104492Sdlw case 'L': 2114492Sdlw d = &s_l_dec; 2124492Sdlw break; 2134492Sdlw case 'o': 2144687Sdlw case 'B': 2154492Sdlw d = &u_s_oct; 2164492Sdlw break; 2174492Sdlw case 'O': 2184492Sdlw d = &u_l_oct; 2194492Sdlw break; 2204492Sdlw case 'p': 2214492Sdlw _parity = EVEN; 2224492Sdlw continue; 2234492Sdlw case 'P': 2244492Sdlw _parity = ODD; 2254492Sdlw continue; 2264687Sdlw case 's': 2274687Sdlw d = &string; 2284687Sdlw *(cv++) = d; 2294687Sdlw if (addr_base == 0) 2304687Sdlw addr_base = d->df_radix; 2314687Sdlw while (isdigit(p[1])) 2324687Sdlw d->df_size = (10 * d->df_size) + (*++p - '0'); 2334687Sdlw if (d->df_size <= 0) 2344687Sdlw d->df_size = MIN_SLEN; 2354687Sdlw showall = YES; 2364687Sdlw continue; 2374492Sdlw case 'v': 2384492Sdlw showall = YES; 2394492Sdlw continue; 2404530Sdlw default: 2414530Sdlw printf("od: bad flag -%c\n", *p); 2424530Sdlw puts(usage); 2434530Sdlw exit(1); 2444492Sdlw } 2454687Sdlw nelm = DBUF_SIZE / d->df_size; 2464492Sdlw llen = (d->df_field + 1) * nelm; 2474492Sdlw if (llen > max_llen) 2484492Sdlw max_llen = llen; 2494492Sdlw if (nelm > max_nelm) 2504492Sdlw max_nelm = nelm; 2514492Sdlw /* 2524492Sdlw * nelm will always be a power of 2. 2534492Sdlw * line length must always be multiple 2544492Sdlw * of max_nelm. 2554492Sdlw */ 2564492Sdlw nelm = max_nelm - 1; 2574492Sdlw max_llen = (max_llen + nelm) & (~nelm); 2584492Sdlw if (addr_base == 0) 2594492Sdlw addr_base = d->df_radix; 2604492Sdlw *(cv++) = d; 2614492Sdlw } 2624492Sdlw argc--; 2634492Sdlw argv++; 2644492Sdlw } 2654492Sdlw } 2664492Sdlw 2674687Sdlw /* 2684687Sdlw * if nothing spec'd, setup default conversion. 2694687Sdlw */ 2704687Sdlw if(cv == conv_vec) 2714687Sdlw { 2724492Sdlw addr_base = 8; 2734492Sdlw *(cv++) = &u_s_oct; 2744687Sdlw max_nelm = DBUF_SIZE / u_s_oct.df_size; 2754530Sdlw max_llen = max_nelm * (u_s_oct.df_field + 1); 2764492Sdlw } 2774492Sdlw *cv = (struct dfmt *)0; 2784492Sdlw 2794687Sdlw /* 2804687Sdlw * setup df_fmt to point to uniform output fields. 2814687Sdlw */ 2824492Sdlw cv = conv_vec; 2834687Sdlw while (d = *cv++) 2844687Sdlw { 2854687Sdlw if (d->df_field) /* only if external field is known */ 2864687Sdlw { 2874687Sdlw nelm = DBUF_SIZE / d->df_size; 2884687Sdlw field = max_llen / nelm; 2894687Sdlw d->df_fmt = fmt + 12 - (field - d->df_field); 2904687Sdlw } 2914492Sdlw } 2924492Sdlw 2934687Sdlw /* 2944687Sdlw * input file specified ? 2954687Sdlw */ 2964687Sdlw if(argc > 0 && **argv != '+') 2974687Sdlw { 2984687Sdlw if (freopen(*argv, "r", stdin) == NULL) 2994687Sdlw { 3004492Sdlw printf("od: cannot open %s\n", *argv); 3014492Sdlw exit(1); 3024492Sdlw } 3034492Sdlw argv++; 3044492Sdlw argc--; 3054492Sdlw } 3064492Sdlw 3074687Sdlw /* 3084687Sdlw * check for possible offset [label] 3094687Sdlw */ 3104530Sdlw if (argc > 0) 3114530Sdlw { 3124530Sdlw addr = get_addr(*argv); 3134530Sdlw offset(addr); 3144530Sdlw argv++; 3154530Sdlw argc--; 3164492Sdlw 3174530Sdlw if (argc > 0) 3184530Sdlw label = get_addr(*argv); 3194530Sdlw } 3204530Sdlw 3214687Sdlw /* 3224687Sdlw * main dump loop 3234687Sdlw */ 3244492Sdlw same = -1; 3254687Sdlw while ((n = fread(dbuf, 1, DBUF_SIZE, stdin)) > 0) 3264687Sdlw { 327*4875Sdlw if (same>=0 && bufncmp(dbuf, lastdbuf, DBUF_SIZE) == 0 && !showall) 3284687Sdlw { 3294687Sdlw if (same==0) 3304687Sdlw { 3314492Sdlw printf("*\n"); 3324492Sdlw same = 1; 3334492Sdlw } 3344492Sdlw } 3354687Sdlw else 3364687Sdlw { 3374492Sdlw line(n); 3384492Sdlw same = 0; 3394492Sdlw p = dbuf; 3404492Sdlw l = lastdbuf; 3414687Sdlw for (nelm = 0; nelm < DBUF_SIZE; nelm++) 3424687Sdlw { 3434492Sdlw *l++ = *p; 3444492Sdlw *p++ = '\0'; 3454492Sdlw } 3464492Sdlw } 3474492Sdlw addr += n; 3484530Sdlw if (label >= 0) 3494530Sdlw label += n; 3504492Sdlw } 3514687Sdlw 3524687Sdlw /* 3534687Sdlw * Some conversions require "flushing". 3544687Sdlw */ 3554687Sdlw n = 0; 3564687Sdlw for (cv = conv_vec; *cv; cv++) 3574687Sdlw { 3584687Sdlw if ((*cv)->df_paddr) 3594687Sdlw { 3604687Sdlw if (n++ == 0) 3614687Sdlw put_addr(addr, label, '\n'); 3624687Sdlw } 3634687Sdlw else 3644687Sdlw (*((*cv)->df_put))(0, *cv); 3654687Sdlw } 3664492Sdlw } 3674492Sdlw 3684687Sdlw put_addr(a, l, c) 3694687Sdlw long a; 3704687Sdlw long l; 3714530Sdlw char c; 3724530Sdlw { 3734687Sdlw fputs(icvt(a, addr_base, UNSIGNED, 7), stdout); 3744687Sdlw if (l >= 0) 3754687Sdlw printf(" (%s)", icvt(l, addr_base, UNSIGNED, 7)); 3764530Sdlw putchar(c); 3774530Sdlw } 3784530Sdlw 3794492Sdlw line(n) 3804492Sdlw int n; 3814492Sdlw { 3824492Sdlw register i, first; 3834492Sdlw register struct dfmt *c; 3844492Sdlw register struct dfmt **cv = conv_vec; 3854492Sdlw 3864492Sdlw first = YES; 3874687Sdlw while (c = *cv++) 3884687Sdlw { 3894687Sdlw if (c->df_paddr) 3904687Sdlw { 3914687Sdlw if (first) 3924687Sdlw { 3934687Sdlw put_addr(addr, label, ' '); 3944687Sdlw first = NO; 3954687Sdlw } 3964687Sdlw else 3974687Sdlw { 3984687Sdlw putchar('\t'); 3994687Sdlw if (label >= 0) 4004687Sdlw fputs("\t ", stdout); 4014687Sdlw } 4024530Sdlw } 4034492Sdlw i = 0; 4044492Sdlw while (i < n) 4054492Sdlw i += (*(c->df_put))(dbuf+i, c); 4064687Sdlw if (c->df_paddr) 4074687Sdlw putchar('\n'); 4084492Sdlw } 4094492Sdlw } 4104492Sdlw 4114492Sdlw s_put(n, d) 4124492Sdlw short *n; 4134492Sdlw struct dfmt *d; 4144492Sdlw { 4154492Sdlw printf(d->df_fmt, icvt((long)*n, d->df_radix, d->df_signed, d->df_field)); 4164492Sdlw return(d->df_size); 4174492Sdlw } 4184492Sdlw 4194492Sdlw us_put(n, d) 4204492Sdlw unsigned short *n; 4214492Sdlw struct dfmt *d; 4224492Sdlw { 4234492Sdlw printf(d->df_fmt, icvt((long)*n, d->df_radix, d->df_signed, d->df_field)); 4244492Sdlw return(d->df_size); 4254492Sdlw } 4264492Sdlw 4274492Sdlw l_put(n, d) 4284492Sdlw long *n; 4294492Sdlw struct dfmt *d; 4304492Sdlw { 4314492Sdlw printf(d->df_fmt, icvt(*n, d->df_radix, d->df_signed, d->df_field)); 4324492Sdlw return(d->df_size); 4334492Sdlw } 4344492Sdlw 4354492Sdlw d_put(f, d) 4364492Sdlw double *f; 4374492Sdlw struct dfmt *d; 4384492Sdlw { 4394492Sdlw char fbuf[24]; 4404500Sdlw struct l { long n[2]; }; 4414500Sdlw 4424500Sdlw #if vax 4434500Sdlw if ((((struct l *)f)->n[0] & 0xff00) == 0x8000) /* Vax illegal f.p. */ 4444500Sdlw sprintf(fbuf, " %08x %08x", 4454500Sdlw ((struct l *)f)->n[0], ((struct l *)f)->n[1]); 4464500Sdlw else 4474500Sdlw #endif 4484500Sdlw 4494500Sdlw sprintf(fbuf, "%21.14e", *f); 4504492Sdlw printf(d->df_fmt, fbuf); 4514492Sdlw return(d->df_size); 4524492Sdlw } 4534492Sdlw 4544492Sdlw f_put(f, d) 4554492Sdlw float *f; 4564492Sdlw struct dfmt *d; 4574492Sdlw { 4584492Sdlw char fbuf[16]; 4594500Sdlw 4604500Sdlw #if vax 4614500Sdlw if ((*(long *)f & 0xff00) == 0x8000) /* Vax illegal f.p. form */ 4624500Sdlw sprintf(fbuf, " %08x", *(long *)f); 4634500Sdlw else 4644500Sdlw #endif 4654500Sdlw sprintf(fbuf, "%14.7e", *f); 4664492Sdlw printf(d->df_fmt, fbuf); 4674492Sdlw return(d->df_size); 4684492Sdlw } 4694492Sdlw 4704492Sdlw 4714492Sdlw char asc_name[34][4] = { 4724687Sdlw /* 000 */ "nul", "soh", "stx", "etx", "eot", "enq", "ack", "bel", 4734687Sdlw /* 010 */ " bs", " ht", " nl", " vt", " ff", " cr", " so", " si", 4744687Sdlw /* 020 */ "dle", "dc1", "dc2", "dc3", "dc4", "nak", "syn", "etb", 4754687Sdlw /* 030 */ "can", " em", "sub", "esc", " fs", " gs", " rs", " us", 4764687Sdlw /* 040 */ " sp", "del" 4774492Sdlw }; 4784492Sdlw 4794492Sdlw a_put(cc, d) 4804492Sdlw char *cc; 4814492Sdlw struct dfmt *d; 4824492Sdlw { 4834492Sdlw int c = *cc; 4844492Sdlw register char *s = " "; 4854492Sdlw register pbit = parity((int)c & 0377); 4864492Sdlw 4874492Sdlw c &= 0177; 4884687Sdlw if (isgraphic(c)) 4894492Sdlw { 4904687Sdlw s[2] = c; 4914492Sdlw if (pbit == _parity) 4924503Sdlw printf(d->df_fmt, underline(s)); 4934492Sdlw else 4944492Sdlw printf(d->df_fmt, s); 4954492Sdlw } 4964492Sdlw else 4974492Sdlw { 4984492Sdlw if (c == 0177) 4994492Sdlw c = ' ' + 1; 5004492Sdlw if (pbit == _parity) 5014503Sdlw printf(d->df_fmt, underline(asc_name[c])); 5024492Sdlw else 5034492Sdlw printf(d->df_fmt, asc_name[c]); 5044492Sdlw } 5054492Sdlw return(1); 5064492Sdlw } 5074492Sdlw 5084492Sdlw parity(word) 5094492Sdlw int word; 5104492Sdlw { 5114492Sdlw register int p = 0; 5124492Sdlw register int w = word; 5134492Sdlw 5144492Sdlw if (w) 5154687Sdlw do 5164687Sdlw { 5174492Sdlw p ^= 1; 5184492Sdlw } while(w &= (~(-w))); 5194492Sdlw return (p? ODD:EVEN); 5204492Sdlw } 5214492Sdlw 5224492Sdlw char * 5234503Sdlw underline(s) 5244492Sdlw char *s; 5254492Sdlw { 5264492Sdlw static char ulbuf[16]; 5274492Sdlw register char *u = ulbuf; 5284492Sdlw 5294687Sdlw while (*s) 5304687Sdlw { 5314687Sdlw if (*s != ' ') 5324687Sdlw { 5334492Sdlw *u++ = '_'; 5344492Sdlw *u++ = '\b'; 5354492Sdlw } 5364492Sdlw *u++ = *s++; 5374492Sdlw } 5384492Sdlw *u = '\0'; 5394492Sdlw return(ulbuf); 5404492Sdlw } 5414492Sdlw 5424492Sdlw b_put(b, d) 5434492Sdlw char *b; 5444492Sdlw struct dfmt *d; 5454492Sdlw { 5464492Sdlw printf(d->df_fmt, icvt((long)*b & 0377, d->df_radix, d->df_signed, d->df_field)); 5474492Sdlw return(1); 5484492Sdlw } 5494492Sdlw 5504492Sdlw c_put(cc, d) 5514492Sdlw char *cc; 5524492Sdlw struct dfmt *d; 5534492Sdlw { 5544687Sdlw register char *s; 5554687Sdlw register int n; 5564687Sdlw register int c = *cc & 0377; 5574492Sdlw 5584687Sdlw s = scvt(c, d); 5594687Sdlw for (n = d->df_field - strlen(s); n > 0; n--) 5604687Sdlw putchar(' '); 5614687Sdlw printf(d->df_fmt, s); 5624687Sdlw return(1); 5634687Sdlw } 5644687Sdlw 5654687Sdlw char *scvt(c, d) 5664687Sdlw int c; 5674687Sdlw struct dfmt *d; 5684687Sdlw { 5694687Sdlw static char s[2]; 5704687Sdlw 5714687Sdlw switch(c) 5724687Sdlw { 5734687Sdlw case '\0': 5744687Sdlw return("\\0"); 5754687Sdlw 5764687Sdlw case '\b': 5774687Sdlw return("\\b"); 5784687Sdlw 5794687Sdlw case '\f': 5804687Sdlw return("\\f"); 5814687Sdlw 5824687Sdlw case '\n': 5834687Sdlw return("\\n"); 5844687Sdlw 5854687Sdlw case '\r': 5864687Sdlw return("\\r"); 5874687Sdlw 5884687Sdlw case '\t': 5894687Sdlw return("\\t"); 5904687Sdlw 5914687Sdlw default: 5924687Sdlw if (isprint(c)) 5934687Sdlw { 5944687Sdlw s[0] = c; 5954687Sdlw return(s); 5964687Sdlw } 5974687Sdlw return(icvt((long)c, d->df_radix, d->df_signed, d->df_field)); 5984492Sdlw } 5994687Sdlw } 6004492Sdlw 6014687Sdlw /* 6024687Sdlw * Look for strings. 6034687Sdlw * A string contains bytes > 037 && < 177, and ends with a null. 6044687Sdlw * The minimum length is given in the dfmt structure. 6054687Sdlw */ 6064687Sdlw 6074687Sdlw #define CNULL '\0' 6084687Sdlw #define S_EMPTY 0 6094687Sdlw #define S_FILL 1 6104687Sdlw #define S_CONT 2 6114687Sdlw #define SBUFSIZE 1024 6124687Sdlw 6134687Sdlw static char str_buf[SBUFSIZE]; 6144687Sdlw static int str_mode = S_EMPTY; 6154687Sdlw static char *str_ptr; 6164687Sdlw static long str_addr; 6174687Sdlw static long str_label; 6184687Sdlw 6194716Sdlw st_put(cc, d) 6204716Sdlw char *cc; 6214687Sdlw struct dfmt *d; 6224687Sdlw { 6234716Sdlw register int c; 6244716Sdlw 6254716Sdlw if (cc == 0) 6264687Sdlw { 6274687Sdlw pr_sbuf(d, YES); 6284716Sdlw return(1); 6294492Sdlw } 6304716Sdlw 6314716Sdlw c = (*cc & 0377); 6324716Sdlw 6334716Sdlw if (str_mode & S_FILL) 6344687Sdlw { 6354716Sdlw if (isascii(c)) 6364716Sdlw put_sbuf(c, d); 6374687Sdlw else 6384687Sdlw { 6394687Sdlw *str_ptr = CNULL; 6404716Sdlw if (c == NULL) 6414687Sdlw pr_sbuf(d, YES); 6424687Sdlw str_mode = S_EMPTY; 6434687Sdlw } 6444687Sdlw } 6454716Sdlw else if (isascii(c)) 6464687Sdlw { 6474687Sdlw str_mode = S_FILL; 6484716Sdlw str_addr = addr + (cc - dbuf); /* ugly */ 6494687Sdlw if ((str_label = label) >= 0) 6504716Sdlw str_label += (cc - dbuf); /* '' */ 6514687Sdlw str_ptr = str_buf; 6524716Sdlw put_sbuf(c, d); 6534687Sdlw } 6544687Sdlw 6554492Sdlw return(1); 6564492Sdlw } 6574492Sdlw 6584687Sdlw put_sbuf(c, d) 6594716Sdlw int c; 6604687Sdlw struct dfmt *d; 6614687Sdlw { 6624687Sdlw *str_ptr++ = c; 6634687Sdlw if (str_ptr >= (str_buf + SBUFSIZE)) 6644687Sdlw { 6654687Sdlw pr_sbuf(d, NO); 6664687Sdlw str_ptr = str_buf; 6674687Sdlw str_mode |= S_CONT; 6684687Sdlw } 6694687Sdlw } 6704687Sdlw 6714687Sdlw pr_sbuf(d, end) 6724687Sdlw struct dfmt *d; 6734687Sdlw int end; 6744687Sdlw { 6754687Sdlw register char *p = str_buf; 6764687Sdlw 6774687Sdlw if (str_mode == S_EMPTY 6784687Sdlw || (!(str_mode & S_CONT) && (str_ptr - str_buf) < d->df_size)) 6794687Sdlw return; 6804687Sdlw 6814687Sdlw if (!(str_mode & S_CONT)) 6824687Sdlw put_addr(str_addr, str_label, ' '); 6834687Sdlw 6844687Sdlw while (p < str_ptr) 6854687Sdlw fputs(scvt(*p++, d), stdout); 6864687Sdlw 6874687Sdlw if (end) 6884687Sdlw putchar('\n'); 6894687Sdlw } 6904687Sdlw 6914492Sdlw /* 6924492Sdlw * integer to ascii conversion 6934492Sdlw * 6944492Sdlw * This code has been rearranged to produce optimized runtime code. 6954492Sdlw */ 6964492Sdlw 6974492Sdlw #define MAXINTLENGTH 32 6984492Sdlw static char _digit[] = "0123456789abcdef"; 6994492Sdlw static char _icv_buf[MAXINTLENGTH+1]; 7004492Sdlw static long _mask = 0x7fffffff; 7014492Sdlw 7024492Sdlw char * 7034492Sdlw icvt (value, radix, signed, ndigits) 7044492Sdlw long value; 7054492Sdlw int radix; 7064492Sdlw int signed; 7074492Sdlw int ndigits; 7084492Sdlw { 7094492Sdlw register long val = value; 7104492Sdlw register long rad = radix; 7114492Sdlw register char *b = &_icv_buf[MAXINTLENGTH]; 7124492Sdlw register char *d = _digit; 7134492Sdlw register long tmp1; 7144492Sdlw register long tmp2; 7154492Sdlw long rem; 7164492Sdlw long kludge; 7174492Sdlw int sign; 7184492Sdlw 7194492Sdlw if (val == 0) 7204492Sdlw { 7214492Sdlw *--b = '0'; 7224492Sdlw sign = 0; 7234492Sdlw goto done; /*return(b);*/ 7244492Sdlw } 7254492Sdlw 7264492Sdlw if (signed && (sign = (val < 0))) /* signed conversion */ 7274492Sdlw { 7284492Sdlw /* 7294492Sdlw * It is necessary to do the first divide 7304492Sdlw * before the absolute value, for the case -2^31 7314492Sdlw * 7324492Sdlw * This is actually what is being done... 7334492Sdlw * tmp1 = (int)(val % rad); 7344492Sdlw * val /= rad; 7354492Sdlw * val = -val 7364492Sdlw * *--b = d[-tmp1]; 7374492Sdlw */ 7384492Sdlw tmp1 = val / rad; 7394492Sdlw *--b = d[(tmp1 * rad) - val]; 7404492Sdlw val = -tmp1; 7414492Sdlw } 7424492Sdlw else /* unsigned conversion */ 7434492Sdlw { 7444492Sdlw sign = 0; 7454492Sdlw if (val < 0) 7464492Sdlw { /* ALL THIS IS TO SIMULATE UNSIGNED LONG MOD & DIV */ 7474492Sdlw kludge = _mask - (rad - 1); 7484492Sdlw val &= _mask; 7494492Sdlw /* 7504492Sdlw * This is really what's being done... 7514492Sdlw * rem = (kludge % rad) + (val % rad); 7524492Sdlw * val = (kludge / rad) + (val / rad) + (rem / rad) + 1; 7534492Sdlw * *--b = d[rem % rad]; 7544492Sdlw */ 7554492Sdlw tmp1 = kludge / rad; 7564492Sdlw tmp2 = val / rad; 7574492Sdlw rem = (kludge - (tmp1 * rad)) + (val - (tmp2 * rad)); 7584492Sdlw val = ++tmp1 + tmp2; 7594492Sdlw tmp1 = rem / rad; 7604492Sdlw val += tmp1; 7614492Sdlw *--b = d[rem - (tmp1 * rad)]; 7624492Sdlw } 7634492Sdlw } 7644492Sdlw 7654492Sdlw while (val) 7664492Sdlw { 7674492Sdlw /* 7684492Sdlw * This is really what's being done ... 7694492Sdlw * *--b = d[val % rad]; 7704492Sdlw * val /= rad; 7714492Sdlw */ 7724492Sdlw tmp1 = val / rad; 7734492Sdlw *--b = d[val - (tmp1 * rad)]; 7744492Sdlw val = tmp1; 7754492Sdlw } 7764492Sdlw 7774492Sdlw done: 7784492Sdlw if (sign) 7794492Sdlw *--b = '-'; 7804492Sdlw 7814492Sdlw tmp1 = ndigits - (&_icv_buf[MAXINTLENGTH] - b); 7824492Sdlw tmp2 = signed? ' ':'0'; 7834492Sdlw while (tmp1 > 0) 7844492Sdlw { 7854492Sdlw *--b = tmp2; 7864492Sdlw tmp1--; 7874492Sdlw } 7884492Sdlw 7894492Sdlw return(b); 7904492Sdlw } 7914492Sdlw 7924687Sdlw long get_addr(s) 7934492Sdlw register char *s; 7944492Sdlw { 7954492Sdlw register char *p; 7964530Sdlw register long a; 7974492Sdlw register int d; 7984492Sdlw 7994492Sdlw if (*s=='+') 8004492Sdlw s++; 8014687Sdlw if (*s=='x') 8024687Sdlw { 8034492Sdlw s++; 8044492Sdlw addr_base = 16; 8054687Sdlw } 8064687Sdlw else if (*s=='0' && s[1]=='x') 8074687Sdlw { 8084492Sdlw s += 2; 8094492Sdlw addr_base = 16; 8104687Sdlw } 8114687Sdlw else if (*s == '0') 8124492Sdlw addr_base = 8; 8134492Sdlw p = s; 8144687Sdlw while(*p) 8154687Sdlw { 8164492Sdlw if (*p++=='.') 8174492Sdlw addr_base = 10; 8184492Sdlw } 8194687Sdlw for (a=0; *s; s++) 8204687Sdlw { 8214492Sdlw d = *s; 8224687Sdlw if(isdigit(d)) 8234492Sdlw a = a*addr_base + d - '0'; 8244687Sdlw else if (ishex(d) && addr_base==16) 8254492Sdlw a = a*addr_base + d + 10 - 'a'; 8264492Sdlw else 8274492Sdlw break; 8284492Sdlw } 8294530Sdlw 8304492Sdlw if (*s == '.') 8314492Sdlw s++; 8324530Sdlw if(*s=='b') 8334492Sdlw a *= 512; 8344530Sdlw if(*s=='B') 8354530Sdlw a *= 1024; 8364530Sdlw 8374530Sdlw return(a); 8384530Sdlw } 8394530Sdlw 840*4875Sdlw bufncmp(a, b, n) 841*4875Sdlw char *a; 842*4875Sdlw char *b; 843*4875Sdlw int n; 844*4875Sdlw { 845*4875Sdlw while (n--) 846*4875Sdlw if (*a++ != *b++) 847*4875Sdlw return(1); 848*4875Sdlw } 849*4875Sdlw 8504530Sdlw offset(a) 8514530Sdlw long a; 8524530Sdlw { 8534492Sdlw if (canseek(stdin)) 8544492Sdlw fseek(stdin, a, 0); 8554492Sdlw else 8564492Sdlw dumbseek(stdin, a); 8574492Sdlw } 8584492Sdlw 8594492Sdlw dumbseek(s, offset) 8604492Sdlw FILE *s; 8614492Sdlw long offset; 8624492Sdlw { 8634492Sdlw char buf[BUFSIZ]; 8644492Sdlw int n; 8654492Sdlw int nr; 8664492Sdlw 8674492Sdlw while (offset > 0) 8684492Sdlw { 8694492Sdlw nr = (offset > BUFSIZ) ? BUFSIZ : (int)offset; 8704492Sdlw if ((n = fread(buf, 1, nr, s)) != nr) 8714492Sdlw { 8724492Sdlw fprintf(stderr, "EOF\n"); 8734492Sdlw exit(1); 8744492Sdlw } 8754492Sdlw offset -= n; 8764492Sdlw } 8774492Sdlw } 8784492Sdlw 8794492Sdlw #include <sys/types.h> 8804492Sdlw #include <sys/stat.h> 8814492Sdlw 8824492Sdlw canseek(f) 8834492Sdlw FILE *f; 8844492Sdlw { 8854492Sdlw struct stat statb; 8864492Sdlw 8874492Sdlw return( (fstat(fileno(f),&statb)==0) && 8884492Sdlw (statb.st_nlink > 0) && /*!pipe*/ 8894492Sdlw (!isatty(fileno(f))) ); 8904492Sdlw } 891