1*11071Sdlw static char *sccsid = "@(#)od.c 5.9 (Berkeley) 02/15/83"; 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]; 874875Sdlw 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 while (isdigit(p[1])) 2304687Sdlw d->df_size = (10 * d->df_size) + (*++p - '0'); 2314687Sdlw if (d->df_size <= 0) 2324687Sdlw d->df_size = MIN_SLEN; 2334687Sdlw showall = YES; 2344687Sdlw continue; 2354492Sdlw case 'v': 2364492Sdlw showall = YES; 2374492Sdlw continue; 2384530Sdlw default: 2394530Sdlw printf("od: bad flag -%c\n", *p); 2404530Sdlw puts(usage); 2414530Sdlw exit(1); 2424492Sdlw } 2434687Sdlw nelm = DBUF_SIZE / d->df_size; 2444492Sdlw llen = (d->df_field + 1) * nelm; 2454492Sdlw if (llen > max_llen) 2464492Sdlw max_llen = llen; 2474492Sdlw if (nelm > max_nelm) 2484492Sdlw max_nelm = nelm; 2494492Sdlw /* 2504492Sdlw * nelm will always be a power of 2. 2514492Sdlw * line length must always be multiple 2524492Sdlw * of max_nelm. 2534492Sdlw */ 2544492Sdlw nelm = max_nelm - 1; 2554492Sdlw max_llen = (max_llen + nelm) & (~nelm); 2564492Sdlw *(cv++) = d; 2574492Sdlw } 2584492Sdlw argc--; 2594492Sdlw argv++; 2604492Sdlw } 2614492Sdlw } 2624492Sdlw 2634687Sdlw /* 2644687Sdlw * if nothing spec'd, setup default conversion. 2654687Sdlw */ 2664687Sdlw if(cv == conv_vec) 2674687Sdlw { 2684492Sdlw *(cv++) = &u_s_oct; 2694687Sdlw max_nelm = DBUF_SIZE / u_s_oct.df_size; 2704530Sdlw max_llen = max_nelm * (u_s_oct.df_field + 1); 2714492Sdlw } 2724492Sdlw *cv = (struct dfmt *)0; 2734492Sdlw 2744687Sdlw /* 2754687Sdlw * setup df_fmt to point to uniform output fields. 2764687Sdlw */ 2774492Sdlw cv = conv_vec; 2784687Sdlw while (d = *cv++) 2794687Sdlw { 2804687Sdlw if (d->df_field) /* only if external field is known */ 2814687Sdlw { 2824687Sdlw nelm = DBUF_SIZE / d->df_size; 2834687Sdlw field = max_llen / nelm; 2844687Sdlw d->df_fmt = fmt + 12 - (field - d->df_field); 2854687Sdlw } 2864492Sdlw } 2874492Sdlw 2884687Sdlw /* 2894687Sdlw * input file specified ? 2904687Sdlw */ 2914687Sdlw if(argc > 0 && **argv != '+') 2924687Sdlw { 2934687Sdlw if (freopen(*argv, "r", stdin) == NULL) 2944687Sdlw { 2954492Sdlw printf("od: cannot open %s\n", *argv); 2964492Sdlw exit(1); 2974492Sdlw } 2984492Sdlw argv++; 2994492Sdlw argc--; 3004492Sdlw } 3014492Sdlw 3024687Sdlw /* 3034687Sdlw * check for possible offset [label] 3044687Sdlw */ 3054530Sdlw if (argc > 0) 3064530Sdlw { 3074530Sdlw addr = get_addr(*argv); 3084530Sdlw offset(addr); 3094530Sdlw argv++; 3104530Sdlw argc--; 3114492Sdlw 3124530Sdlw if (argc > 0) 3134530Sdlw label = get_addr(*argv); 3144530Sdlw } 3154530Sdlw 3164687Sdlw /* 3174687Sdlw * main dump loop 3184687Sdlw */ 3194492Sdlw same = -1; 3204687Sdlw while ((n = fread(dbuf, 1, DBUF_SIZE, stdin)) > 0) 3214687Sdlw { 3224875Sdlw if (same>=0 && bufncmp(dbuf, lastdbuf, DBUF_SIZE) == 0 && !showall) 3234687Sdlw { 3244687Sdlw if (same==0) 3254687Sdlw { 3264492Sdlw printf("*\n"); 3274492Sdlw same = 1; 3284492Sdlw } 3294492Sdlw } 3304687Sdlw else 3314687Sdlw { 3324492Sdlw line(n); 3334492Sdlw same = 0; 3344492Sdlw p = dbuf; 3354492Sdlw l = lastdbuf; 3364687Sdlw for (nelm = 0; nelm < DBUF_SIZE; nelm++) 3374687Sdlw { 3384492Sdlw *l++ = *p; 3394492Sdlw *p++ = '\0'; 3404492Sdlw } 3414492Sdlw } 3424492Sdlw addr += n; 3434530Sdlw if (label >= 0) 3444530Sdlw label += n; 3454492Sdlw } 3464687Sdlw 3474687Sdlw /* 3484687Sdlw * Some conversions require "flushing". 3494687Sdlw */ 3504687Sdlw n = 0; 3514687Sdlw for (cv = conv_vec; *cv; cv++) 3524687Sdlw { 3534687Sdlw if ((*cv)->df_paddr) 3544687Sdlw { 3554687Sdlw if (n++ == 0) 3564687Sdlw put_addr(addr, label, '\n'); 3574687Sdlw } 3584687Sdlw else 3594687Sdlw (*((*cv)->df_put))(0, *cv); 3604687Sdlw } 3614492Sdlw } 3624492Sdlw 3634687Sdlw put_addr(a, l, c) 3644687Sdlw long a; 3654687Sdlw long l; 3664530Sdlw char c; 3674530Sdlw { 3684687Sdlw fputs(icvt(a, addr_base, UNSIGNED, 7), stdout); 3694687Sdlw if (l >= 0) 3704687Sdlw printf(" (%s)", icvt(l, addr_base, UNSIGNED, 7)); 3714530Sdlw putchar(c); 3724530Sdlw } 3734530Sdlw 3744492Sdlw line(n) 3754492Sdlw int n; 3764492Sdlw { 3774492Sdlw register i, first; 3784492Sdlw register struct dfmt *c; 3794492Sdlw register struct dfmt **cv = conv_vec; 3804492Sdlw 3814492Sdlw first = YES; 3824687Sdlw while (c = *cv++) 3834687Sdlw { 3844687Sdlw if (c->df_paddr) 3854687Sdlw { 3864687Sdlw if (first) 3874687Sdlw { 3884687Sdlw put_addr(addr, label, ' '); 3894687Sdlw first = NO; 3904687Sdlw } 3914687Sdlw else 3924687Sdlw { 3934687Sdlw putchar('\t'); 3944687Sdlw if (label >= 0) 3954687Sdlw fputs("\t ", stdout); 3964687Sdlw } 3974530Sdlw } 3984492Sdlw i = 0; 3994492Sdlw while (i < n) 4004492Sdlw i += (*(c->df_put))(dbuf+i, c); 4014687Sdlw if (c->df_paddr) 4024687Sdlw putchar('\n'); 4034492Sdlw } 4044492Sdlw } 4054492Sdlw 4064492Sdlw s_put(n, d) 4074492Sdlw short *n; 4084492Sdlw struct dfmt *d; 4094492Sdlw { 4104492Sdlw printf(d->df_fmt, icvt((long)*n, d->df_radix, d->df_signed, d->df_field)); 4114492Sdlw return(d->df_size); 4124492Sdlw } 4134492Sdlw 4144492Sdlw us_put(n, d) 4154492Sdlw unsigned short *n; 4164492Sdlw struct dfmt *d; 4174492Sdlw { 4184492Sdlw printf(d->df_fmt, icvt((long)*n, d->df_radix, d->df_signed, d->df_field)); 4194492Sdlw return(d->df_size); 4204492Sdlw } 4214492Sdlw 4224492Sdlw l_put(n, d) 4234492Sdlw long *n; 4244492Sdlw struct dfmt *d; 4254492Sdlw { 4264492Sdlw printf(d->df_fmt, icvt(*n, d->df_radix, d->df_signed, d->df_field)); 4274492Sdlw return(d->df_size); 4284492Sdlw } 4294492Sdlw 4304492Sdlw d_put(f, d) 4314492Sdlw double *f; 4324492Sdlw struct dfmt *d; 4334492Sdlw { 4344492Sdlw char fbuf[24]; 4354500Sdlw struct l { long n[2]; }; 4364500Sdlw 4374500Sdlw #if vax 4384500Sdlw if ((((struct l *)f)->n[0] & 0xff00) == 0x8000) /* Vax illegal f.p. */ 4394500Sdlw sprintf(fbuf, " %08x %08x", 4404500Sdlw ((struct l *)f)->n[0], ((struct l *)f)->n[1]); 4414500Sdlw else 4424500Sdlw #endif 4434500Sdlw 4444500Sdlw sprintf(fbuf, "%21.14e", *f); 4454492Sdlw printf(d->df_fmt, fbuf); 4464492Sdlw return(d->df_size); 4474492Sdlw } 4484492Sdlw 4494492Sdlw f_put(f, d) 4504492Sdlw float *f; 4514492Sdlw struct dfmt *d; 4524492Sdlw { 4534492Sdlw char fbuf[16]; 4544500Sdlw 4554500Sdlw #if vax 4564500Sdlw if ((*(long *)f & 0xff00) == 0x8000) /* Vax illegal f.p. form */ 4574500Sdlw sprintf(fbuf, " %08x", *(long *)f); 4584500Sdlw else 4594500Sdlw #endif 4604500Sdlw sprintf(fbuf, "%14.7e", *f); 4614492Sdlw printf(d->df_fmt, fbuf); 4624492Sdlw return(d->df_size); 4634492Sdlw } 4644492Sdlw 4654492Sdlw 4664492Sdlw char asc_name[34][4] = { 4674687Sdlw /* 000 */ "nul", "soh", "stx", "etx", "eot", "enq", "ack", "bel", 4684687Sdlw /* 010 */ " bs", " ht", " nl", " vt", " ff", " cr", " so", " si", 4694687Sdlw /* 020 */ "dle", "dc1", "dc2", "dc3", "dc4", "nak", "syn", "etb", 4704687Sdlw /* 030 */ "can", " em", "sub", "esc", " fs", " gs", " rs", " us", 4714687Sdlw /* 040 */ " sp", "del" 4724492Sdlw }; 4734492Sdlw 4744492Sdlw a_put(cc, d) 4754492Sdlw char *cc; 4764492Sdlw struct dfmt *d; 4774492Sdlw { 4784492Sdlw int c = *cc; 4794492Sdlw register char *s = " "; 4804492Sdlw register pbit = parity((int)c & 0377); 4814492Sdlw 4824492Sdlw c &= 0177; 4834687Sdlw if (isgraphic(c)) 4844492Sdlw { 4854687Sdlw s[2] = c; 4864492Sdlw if (pbit == _parity) 4874503Sdlw printf(d->df_fmt, underline(s)); 4884492Sdlw else 4894492Sdlw printf(d->df_fmt, s); 4904492Sdlw } 4914492Sdlw else 4924492Sdlw { 4934492Sdlw if (c == 0177) 4944492Sdlw c = ' ' + 1; 4954492Sdlw if (pbit == _parity) 4964503Sdlw printf(d->df_fmt, underline(asc_name[c])); 4974492Sdlw else 4984492Sdlw printf(d->df_fmt, asc_name[c]); 4994492Sdlw } 5004492Sdlw return(1); 5014492Sdlw } 5024492Sdlw 5034492Sdlw parity(word) 5044492Sdlw int word; 5054492Sdlw { 5064492Sdlw register int p = 0; 5074492Sdlw register int w = word; 5084492Sdlw 5094492Sdlw if (w) 5104687Sdlw do 5114687Sdlw { 5124492Sdlw p ^= 1; 5134492Sdlw } while(w &= (~(-w))); 5144492Sdlw return (p? ODD:EVEN); 5154492Sdlw } 5164492Sdlw 5174492Sdlw char * 5184503Sdlw underline(s) 5194492Sdlw char *s; 5204492Sdlw { 5214492Sdlw static char ulbuf[16]; 5224492Sdlw register char *u = ulbuf; 5234492Sdlw 5244687Sdlw while (*s) 5254687Sdlw { 5264687Sdlw if (*s != ' ') 5274687Sdlw { 5284492Sdlw *u++ = '_'; 5294492Sdlw *u++ = '\b'; 5304492Sdlw } 5314492Sdlw *u++ = *s++; 5324492Sdlw } 5334492Sdlw *u = '\0'; 5344492Sdlw return(ulbuf); 5354492Sdlw } 5364492Sdlw 5374492Sdlw b_put(b, d) 5384492Sdlw char *b; 5394492Sdlw struct dfmt *d; 5404492Sdlw { 5414492Sdlw printf(d->df_fmt, icvt((long)*b & 0377, d->df_radix, d->df_signed, d->df_field)); 5424492Sdlw return(1); 5434492Sdlw } 5444492Sdlw 5454492Sdlw c_put(cc, d) 5464492Sdlw char *cc; 5474492Sdlw struct dfmt *d; 5484492Sdlw { 5494687Sdlw register char *s; 5504687Sdlw register int n; 5514687Sdlw register int c = *cc & 0377; 5524492Sdlw 5534687Sdlw s = scvt(c, d); 5544687Sdlw for (n = d->df_field - strlen(s); n > 0; n--) 5554687Sdlw putchar(' '); 5564687Sdlw printf(d->df_fmt, s); 5574687Sdlw return(1); 5584687Sdlw } 5594687Sdlw 5604687Sdlw char *scvt(c, d) 5614687Sdlw int c; 5624687Sdlw struct dfmt *d; 5634687Sdlw { 5644687Sdlw static char s[2]; 5654687Sdlw 5664687Sdlw switch(c) 5674687Sdlw { 5684687Sdlw case '\0': 5694687Sdlw return("\\0"); 5704687Sdlw 5714687Sdlw case '\b': 5724687Sdlw return("\\b"); 5734687Sdlw 5744687Sdlw case '\f': 5754687Sdlw return("\\f"); 5764687Sdlw 5774687Sdlw case '\n': 5784687Sdlw return("\\n"); 5794687Sdlw 5804687Sdlw case '\r': 5814687Sdlw return("\\r"); 5824687Sdlw 5834687Sdlw case '\t': 5844687Sdlw return("\\t"); 5854687Sdlw 5864687Sdlw default: 5874687Sdlw if (isprint(c)) 5884687Sdlw { 5894687Sdlw s[0] = c; 5904687Sdlw return(s); 5914687Sdlw } 5924687Sdlw return(icvt((long)c, d->df_radix, d->df_signed, d->df_field)); 5934492Sdlw } 5944687Sdlw } 5954492Sdlw 5964687Sdlw /* 5974687Sdlw * Look for strings. 5984687Sdlw * A string contains bytes > 037 && < 177, and ends with a null. 5994687Sdlw * The minimum length is given in the dfmt structure. 6004687Sdlw */ 6014687Sdlw 6024687Sdlw #define CNULL '\0' 6034687Sdlw #define S_EMPTY 0 6044687Sdlw #define S_FILL 1 6054687Sdlw #define S_CONT 2 6064687Sdlw #define SBUFSIZE 1024 6074687Sdlw 6084687Sdlw static char str_buf[SBUFSIZE]; 6094687Sdlw static int str_mode = S_EMPTY; 6104687Sdlw static char *str_ptr; 6114687Sdlw static long str_addr; 6124687Sdlw static long str_label; 6134687Sdlw 6144716Sdlw st_put(cc, d) 6154716Sdlw char *cc; 6164687Sdlw struct dfmt *d; 6174687Sdlw { 6184716Sdlw register int c; 6194716Sdlw 6204716Sdlw if (cc == 0) 6214687Sdlw { 6224687Sdlw pr_sbuf(d, YES); 6234716Sdlw return(1); 6244492Sdlw } 6254716Sdlw 6264716Sdlw c = (*cc & 0377); 6274716Sdlw 6284716Sdlw if (str_mode & S_FILL) 6294687Sdlw { 6304716Sdlw if (isascii(c)) 6314716Sdlw put_sbuf(c, d); 6324687Sdlw else 6334687Sdlw { 6344687Sdlw *str_ptr = CNULL; 6354716Sdlw if (c == NULL) 6364687Sdlw pr_sbuf(d, YES); 6374687Sdlw str_mode = S_EMPTY; 6384687Sdlw } 6394687Sdlw } 6404716Sdlw else if (isascii(c)) 6414687Sdlw { 6424687Sdlw str_mode = S_FILL; 6434716Sdlw str_addr = addr + (cc - dbuf); /* ugly */ 6444687Sdlw if ((str_label = label) >= 0) 6454716Sdlw str_label += (cc - dbuf); /* '' */ 6464687Sdlw str_ptr = str_buf; 6474716Sdlw put_sbuf(c, d); 6484687Sdlw } 6494687Sdlw 6504492Sdlw return(1); 6514492Sdlw } 6524492Sdlw 6534687Sdlw put_sbuf(c, d) 6544716Sdlw int c; 6554687Sdlw struct dfmt *d; 6564687Sdlw { 6574687Sdlw *str_ptr++ = c; 6584687Sdlw if (str_ptr >= (str_buf + SBUFSIZE)) 6594687Sdlw { 6604687Sdlw pr_sbuf(d, NO); 6614687Sdlw str_ptr = str_buf; 6624687Sdlw str_mode |= S_CONT; 6634687Sdlw } 6644687Sdlw } 6654687Sdlw 6664687Sdlw pr_sbuf(d, end) 6674687Sdlw struct dfmt *d; 6684687Sdlw int end; 6694687Sdlw { 6704687Sdlw register char *p = str_buf; 6714687Sdlw 6724687Sdlw if (str_mode == S_EMPTY 6734687Sdlw || (!(str_mode & S_CONT) && (str_ptr - str_buf) < d->df_size)) 6744687Sdlw return; 6754687Sdlw 6764687Sdlw if (!(str_mode & S_CONT)) 6774687Sdlw put_addr(str_addr, str_label, ' '); 6784687Sdlw 6794687Sdlw while (p < str_ptr) 6804687Sdlw fputs(scvt(*p++, d), stdout); 6814687Sdlw 6824687Sdlw if (end) 6834687Sdlw putchar('\n'); 6844687Sdlw } 6854687Sdlw 6864492Sdlw /* 6874492Sdlw * integer to ascii conversion 6884492Sdlw * 6894492Sdlw * This code has been rearranged to produce optimized runtime code. 6904492Sdlw */ 6914492Sdlw 6924492Sdlw #define MAXINTLENGTH 32 6934492Sdlw static char _digit[] = "0123456789abcdef"; 6944492Sdlw static char _icv_buf[MAXINTLENGTH+1]; 6954492Sdlw static long _mask = 0x7fffffff; 6964492Sdlw 6974492Sdlw char * 6984492Sdlw icvt (value, radix, signed, ndigits) 6994492Sdlw long value; 7004492Sdlw int radix; 7014492Sdlw int signed; 7024492Sdlw int ndigits; 7034492Sdlw { 7044492Sdlw register long val = value; 7054492Sdlw register long rad = radix; 7064492Sdlw register char *b = &_icv_buf[MAXINTLENGTH]; 7074492Sdlw register char *d = _digit; 7084492Sdlw register long tmp1; 7094492Sdlw register long tmp2; 7104492Sdlw long rem; 7114492Sdlw long kludge; 7124492Sdlw int sign; 7134492Sdlw 7144492Sdlw if (val == 0) 7154492Sdlw { 7164492Sdlw *--b = '0'; 7174492Sdlw sign = 0; 7184492Sdlw goto done; /*return(b);*/ 7194492Sdlw } 7204492Sdlw 7214492Sdlw if (signed && (sign = (val < 0))) /* signed conversion */ 7224492Sdlw { 7234492Sdlw /* 7244492Sdlw * It is necessary to do the first divide 7254492Sdlw * before the absolute value, for the case -2^31 7264492Sdlw * 7274492Sdlw * This is actually what is being done... 7284492Sdlw * tmp1 = (int)(val % rad); 7294492Sdlw * val /= rad; 7304492Sdlw * val = -val 7314492Sdlw * *--b = d[-tmp1]; 7324492Sdlw */ 7334492Sdlw tmp1 = val / rad; 7344492Sdlw *--b = d[(tmp1 * rad) - val]; 7354492Sdlw val = -tmp1; 7364492Sdlw } 7374492Sdlw else /* unsigned conversion */ 7384492Sdlw { 7394492Sdlw sign = 0; 7404492Sdlw if (val < 0) 7414492Sdlw { /* ALL THIS IS TO SIMULATE UNSIGNED LONG MOD & DIV */ 7424492Sdlw kludge = _mask - (rad - 1); 7434492Sdlw val &= _mask; 7444492Sdlw /* 7454492Sdlw * This is really what's being done... 7464492Sdlw * rem = (kludge % rad) + (val % rad); 7474492Sdlw * val = (kludge / rad) + (val / rad) + (rem / rad) + 1; 7484492Sdlw * *--b = d[rem % rad]; 7494492Sdlw */ 7504492Sdlw tmp1 = kludge / rad; 7514492Sdlw tmp2 = val / rad; 7524492Sdlw rem = (kludge - (tmp1 * rad)) + (val - (tmp2 * rad)); 7534492Sdlw val = ++tmp1 + tmp2; 7544492Sdlw tmp1 = rem / rad; 7554492Sdlw val += tmp1; 7564492Sdlw *--b = d[rem - (tmp1 * rad)]; 7574492Sdlw } 7584492Sdlw } 7594492Sdlw 7604492Sdlw while (val) 7614492Sdlw { 7624492Sdlw /* 7634492Sdlw * This is really what's being done ... 7644492Sdlw * *--b = d[val % rad]; 7654492Sdlw * val /= rad; 7664492Sdlw */ 7674492Sdlw tmp1 = val / rad; 7684492Sdlw *--b = d[val - (tmp1 * rad)]; 7694492Sdlw val = tmp1; 7704492Sdlw } 7714492Sdlw 7724492Sdlw done: 7734492Sdlw if (sign) 7744492Sdlw *--b = '-'; 7754492Sdlw 7764492Sdlw tmp1 = ndigits - (&_icv_buf[MAXINTLENGTH] - b); 7774492Sdlw tmp2 = signed? ' ':'0'; 7784492Sdlw while (tmp1 > 0) 7794492Sdlw { 7804492Sdlw *--b = tmp2; 7814492Sdlw tmp1--; 7824492Sdlw } 7834492Sdlw 7844492Sdlw return(b); 7854492Sdlw } 7864492Sdlw 7874687Sdlw long get_addr(s) 7884492Sdlw register char *s; 7894492Sdlw { 7904492Sdlw register char *p; 7914530Sdlw register long a; 7924492Sdlw register int d; 7934492Sdlw 7944492Sdlw if (*s=='+') 7954492Sdlw s++; 7964687Sdlw if (*s=='x') 7974687Sdlw { 7984492Sdlw s++; 7994492Sdlw addr_base = 16; 8004687Sdlw } 8014687Sdlw else if (*s=='0' && s[1]=='x') 8024687Sdlw { 8034492Sdlw s += 2; 8044492Sdlw addr_base = 16; 8054687Sdlw } 8064687Sdlw else if (*s == '0') 8074492Sdlw addr_base = 8; 8084492Sdlw p = s; 8094687Sdlw while(*p) 8104687Sdlw { 8114492Sdlw if (*p++=='.') 8124492Sdlw addr_base = 10; 8134492Sdlw } 8144687Sdlw for (a=0; *s; s++) 8154687Sdlw { 8164492Sdlw d = *s; 8174687Sdlw if(isdigit(d)) 8184492Sdlw a = a*addr_base + d - '0'; 8194687Sdlw else if (ishex(d) && addr_base==16) 8204492Sdlw a = a*addr_base + d + 10 - 'a'; 8214492Sdlw else 8224492Sdlw break; 8234492Sdlw } 8244530Sdlw 8254492Sdlw if (*s == '.') 8264492Sdlw s++; 8274530Sdlw if(*s=='b') 8284492Sdlw a *= 512; 8294530Sdlw if(*s=='B') 8304530Sdlw a *= 1024; 8314530Sdlw 8324530Sdlw return(a); 8334530Sdlw } 8344530Sdlw 8354875Sdlw bufncmp(a, b, n) 8364875Sdlw char *a; 8374875Sdlw char *b; 8384875Sdlw int n; 8394875Sdlw { 8404875Sdlw while (n--) 8414875Sdlw if (*a++ != *b++) 8424875Sdlw return(1); 8434875Sdlw } 8444875Sdlw 8454530Sdlw offset(a) 8464530Sdlw long a; 8474530Sdlw { 8484492Sdlw if (canseek(stdin)) 849*11071Sdlw { 850*11071Sdlw /* 851*11071Sdlw * in case we're accessing a raw disk, 852*11071Sdlw * we have to seek in multiples of a physical block. 853*11071Sdlw */ 854*11071Sdlw fseek(stdin, a & 0xfffffe00L, 0); 855*11071Sdlw a &= 0x1ffL; 856*11071Sdlw } 857*11071Sdlw dumbseek(stdin, a); 8584492Sdlw } 8594492Sdlw 8604492Sdlw dumbseek(s, offset) 8614492Sdlw FILE *s; 8624492Sdlw long offset; 8634492Sdlw { 8644492Sdlw char buf[BUFSIZ]; 8654492Sdlw int n; 8664492Sdlw int nr; 8674492Sdlw 8684492Sdlw while (offset > 0) 8694492Sdlw { 8704492Sdlw nr = (offset > BUFSIZ) ? BUFSIZ : (int)offset; 8714492Sdlw if ((n = fread(buf, 1, nr, s)) != nr) 8724492Sdlw { 8734492Sdlw fprintf(stderr, "EOF\n"); 8744492Sdlw exit(1); 8754492Sdlw } 8764492Sdlw offset -= n; 8774492Sdlw } 8784492Sdlw } 8794492Sdlw 8804492Sdlw #include <sys/types.h> 8814492Sdlw #include <sys/stat.h> 8824492Sdlw 8834492Sdlw canseek(f) 8844492Sdlw FILE *f; 8854492Sdlw { 8864492Sdlw struct stat statb; 8874492Sdlw 8884492Sdlw return( (fstat(fileno(f),&statb)==0) && 8894492Sdlw (statb.st_nlink > 0) && /*!pipe*/ 8904492Sdlw (!isatty(fileno(f))) ); 8914492Sdlw } 892