1*4687Sdlw static char *sccsid = "@(#)od.c 5.5 (Berkeley) 10/31/81"; 24492Sdlw /* 34492Sdlw * od -- octal, hex, decimal, character dump of data in a file. 44492Sdlw * 5*4687Sdlw * 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 20*4687Sdlw * o,B short 8 no (default conversion) 214492Sdlw * O long 8 no 22*4687Sdlw * 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 38*4687Sdlw #define DBUF_SIZE 16 39*4687Sdlw #define NO 0 40*4687Sdlw #define YES 1 41*4687Sdlw #define EVEN -1 42*4687Sdlw #define ODD 1 43*4687Sdlw #define UNSIGNED 0 44*4687Sdlw #define SIGNED 1 45*4687Sdlw #define PADDR 1 46*4687Sdlw #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(); 56*4687Sdlw 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 */ 63*4687Sdlw int df_paddr; /* "put address on each line?" flag */ 644492Sdlw int (*df_put)(); /* function to output object */ 65*4687Sdlw char *df_fmt; /* output string format */ 664492Sdlw } *conv_vec[32]; /* vector of conversions to be done */ 674492Sdlw 68*4687Sdlw struct dfmt ascii = { 3, sizeof (char), 10, 0, PADDR, a_put, 0}; 69*4687Sdlw struct dfmt byte = { 3, sizeof (char), 8, UNSIGNED, PADDR, b_put, 0}; 70*4687Sdlw struct dfmt cchar = { 3, sizeof (char), 8, UNSIGNED, PADDR, c_put, 0}; 71*4687Sdlw struct dfmt u_s_oct = { 6, sizeof (short), 8, UNSIGNED, PADDR, us_put, 0}; 72*4687Sdlw struct dfmt u_s_dec = { 5, sizeof (short), 10, UNSIGNED, PADDR, us_put, 0}; 73*4687Sdlw struct dfmt u_s_hex = { 4, sizeof (short), 16, UNSIGNED, PADDR, us_put, 0}; 74*4687Sdlw struct dfmt u_l_oct = {11, sizeof (long), 8, UNSIGNED, PADDR, l_put, 0}; 75*4687Sdlw struct dfmt u_l_dec = {10, sizeof (long), 10, UNSIGNED, PADDR, l_put, 0}; 76*4687Sdlw struct dfmt u_l_hex = { 8, sizeof (long), 16, UNSIGNED, PADDR, l_put, 0}; 77*4687Sdlw struct dfmt s_s_dec = { 6, sizeof (short), 10, SIGNED, PADDR, s_put, 0}; 78*4687Sdlw struct dfmt s_l_dec = {11, sizeof (long), 10, SIGNED, PADDR, l_put, 0}; 79*4687Sdlw struct dfmt flt = {14, sizeof (float), 10, SIGNED, PADDR, f_put, 0}; 80*4687Sdlw struct dfmt dble = {21, sizeof (double), 10, SIGNED, PADDR, d_put, 0}; 81*4687Sdlw struct dfmt string = { 0, 0, 8, 0, NO, st_put, 0}; 824492Sdlw 834530Sdlw 84*4687Sdlw char usage[] = "usage: od [-abcdfhilopsvx] [file] [[+]offset[.][b] [label]]"; 85*4687Sdlw char dbuf[DBUF_SIZE]; 86*4687Sdlw char lastdbuf[DBUF_SIZE]; 874492Sdlw int addr_base; 884492Sdlw long addr; 894530Sdlw long label = -1L; 904492Sdlw int _parity = NO; 914492Sdlw char fmt[] = " %s"; /* 12 blanks */ 924492Sdlw char *icvt(); 93*4687Sdlw char *scvt(); 944492Sdlw char *underline(); 954530Sdlw long get_addr(); 964492Sdlw 974530Sdlw 98*4687Sdlw /* 99*4687Sdlw * special form of _ctype 100*4687Sdlw */ 101*4687Sdlw 102*4687Sdlw #define A 01 103*4687Sdlw #define G 02 104*4687Sdlw #define D 04 105*4687Sdlw #define P 010 106*4687Sdlw #define X 020 107*4687Sdlw #define isdigit(c) (_ctype[c] & D) 108*4687Sdlw #define isascii(c) (_ctype[c] & A) 109*4687Sdlw #define isgraphic(c) (_ctype[c] & G) 110*4687Sdlw #define isprint(c) (_ctype[c] & P) 111*4687Sdlw #define ishex(c) (_ctype[c] & (X|D)) 112*4687Sdlw 113*4687Sdlw char _ctype[256] = { 114*4687Sdlw /* 000 */ 0, 0, 0, 0, 0, 0, 0, 0, 115*4687Sdlw /* 010 */ A, A, A, 0, A, A, 0, 0, 116*4687Sdlw /* 020 */ 0, 0, 0, 0, 0, 0, 0, 0, 117*4687Sdlw /* 030 */ 0, 0, 0, 0, 0, 0, 0, 0, 118*4687Sdlw /* 040 */ P|A, P|G|A, P|G|A, P|G|A, P|G|A, P|G|A, P|G|A, P|G|A, 119*4687Sdlw /* 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, 120*4687Sdlw /* 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, 121*4687Sdlw /* 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, 122*4687Sdlw /* 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, 123*4687Sdlw /* 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, 124*4687Sdlw /* 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, 125*4687Sdlw /* 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, 126*4687Sdlw /* 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, 127*4687Sdlw /* 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, 128*4687Sdlw /* 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, 129*4687Sdlw /* 170 */ P|G|A, P|G|A, P|G|A, P|G|A, P|G|A, P|G|A, P|G|A, 0, 130*4687Sdlw /* 200 */ 0, 0, 0, 0, 0, 0, 0, 0, 131*4687Sdlw /* 210 */ 0, 0, 0, 0, 0, 0, 0, 0, 132*4687Sdlw /* 220 */ 0, 0, 0, 0, 0, 0, 0, 0, 133*4687Sdlw /* 230 */ 0, 0, 0, 0, 0, 0, 0, 0, 134*4687Sdlw /* 240 */ 0, 0, 0, 0, 0, 0, 0, 0, 135*4687Sdlw /* 250 */ 0, 0, 0, 0, 0, 0, 0, 0, 136*4687Sdlw /* 260 */ 0, 0, 0, 0, 0, 0, 0, 0, 137*4687Sdlw /* 270 */ 0, 0, 0, 0, 0, 0, 0, 0, 138*4687Sdlw /* 300 */ 0, 0, 0, 0, 0, 0, 0, 0, 139*4687Sdlw /* 310 */ 0, 0, 0, 0, 0, 0, 0, 0, 140*4687Sdlw /* 320 */ 0, 0, 0, 0, 0, 0, 0, 0, 141*4687Sdlw /* 330 */ 0, 0, 0, 0, 0, 0, 0, 0, 142*4687Sdlw /* 340 */ 0, 0, 0, 0, 0, 0, 0, 0, 143*4687Sdlw /* 350 */ 0, 0, 0, 0, 0, 0, 0, 0, 144*4687Sdlw /* 360 */ 0, 0, 0, 0, 0, 0, 0, 0, 145*4687Sdlw /* 370 */ 0, 0, 0, 0, 0, 0, 0, 0, 146*4687Sdlw }; 147*4687Sdlw 148*4687Sdlw 1494492Sdlw main(argc, argv) 150*4687Sdlw int argc; 151*4687Sdlw 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 166*4687Sdlw if(argc > 0) 167*4687Sdlw { 1684492Sdlw p = *argv; 169*4687Sdlw if(*p == '-') 170*4687Sdlw { 171*4687Sdlw while(*++p != '\0') 172*4687Sdlw { 173*4687Sdlw switch(*p) 174*4687Sdlw { 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': 214*4687Sdlw 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; 226*4687Sdlw case 's': 227*4687Sdlw d = &string; 228*4687Sdlw *(cv++) = d; 229*4687Sdlw if (addr_base == 0) 230*4687Sdlw addr_base = d->df_radix; 231*4687Sdlw while (isdigit(p[1])) 232*4687Sdlw d->df_size = (10 * d->df_size) + (*++p - '0'); 233*4687Sdlw if (d->df_size <= 0) 234*4687Sdlw d->df_size = MIN_SLEN; 235*4687Sdlw showall = YES; 236*4687Sdlw 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 } 245*4687Sdlw 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 267*4687Sdlw /* 268*4687Sdlw * if nothing spec'd, setup default conversion. 269*4687Sdlw */ 270*4687Sdlw if(cv == conv_vec) 271*4687Sdlw { 2724492Sdlw addr_base = 8; 2734492Sdlw *(cv++) = &u_s_oct; 274*4687Sdlw 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 279*4687Sdlw /* 280*4687Sdlw * setup df_fmt to point to uniform output fields. 281*4687Sdlw */ 2824492Sdlw cv = conv_vec; 283*4687Sdlw while (d = *cv++) 284*4687Sdlw { 285*4687Sdlw if (d->df_field) /* only if external field is known */ 286*4687Sdlw { 287*4687Sdlw nelm = DBUF_SIZE / d->df_size; 288*4687Sdlw field = max_llen / nelm; 289*4687Sdlw d->df_fmt = fmt + 12 - (field - d->df_field); 290*4687Sdlw } 2914492Sdlw } 2924492Sdlw 293*4687Sdlw /* 294*4687Sdlw * input file specified ? 295*4687Sdlw */ 296*4687Sdlw if(argc > 0 && **argv != '+') 297*4687Sdlw { 298*4687Sdlw if (freopen(*argv, "r", stdin) == NULL) 299*4687Sdlw { 3004492Sdlw printf("od: cannot open %s\n", *argv); 3014492Sdlw exit(1); 3024492Sdlw } 3034492Sdlw argv++; 3044492Sdlw argc--; 3054492Sdlw } 3064492Sdlw 307*4687Sdlw /* 308*4687Sdlw * check for possible offset [label] 309*4687Sdlw */ 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 321*4687Sdlw /* 322*4687Sdlw * main dump loop 323*4687Sdlw */ 3244492Sdlw same = -1; 325*4687Sdlw while ((n = fread(dbuf, 1, DBUF_SIZE, stdin)) > 0) 326*4687Sdlw { 327*4687Sdlw if (same>=0 && strncmp(dbuf, lastdbuf, DBUF_SIZE) == 0 && !showall) 328*4687Sdlw { 329*4687Sdlw if (same==0) 330*4687Sdlw { 3314492Sdlw printf("*\n"); 3324492Sdlw same = 1; 3334492Sdlw } 3344492Sdlw } 335*4687Sdlw else 336*4687Sdlw { 3374492Sdlw line(n); 3384492Sdlw same = 0; 3394492Sdlw p = dbuf; 3404492Sdlw l = lastdbuf; 341*4687Sdlw for (nelm = 0; nelm < DBUF_SIZE; nelm++) 342*4687Sdlw { 3434492Sdlw *l++ = *p; 3444492Sdlw *p++ = '\0'; 3454492Sdlw } 3464492Sdlw } 3474492Sdlw addr += n; 3484530Sdlw if (label >= 0) 3494530Sdlw label += n; 3504492Sdlw } 351*4687Sdlw 352*4687Sdlw /* 353*4687Sdlw * Some conversions require "flushing". 354*4687Sdlw */ 355*4687Sdlw n = 0; 356*4687Sdlw for (cv = conv_vec; *cv; cv++) 357*4687Sdlw { 358*4687Sdlw if ((*cv)->df_paddr) 359*4687Sdlw { 360*4687Sdlw if (n++ == 0) 361*4687Sdlw put_addr(addr, label, '\n'); 362*4687Sdlw } 363*4687Sdlw else 364*4687Sdlw (*((*cv)->df_put))(0, *cv); 365*4687Sdlw } 3664492Sdlw } 3674492Sdlw 368*4687Sdlw put_addr(a, l, c) 369*4687Sdlw long a; 370*4687Sdlw long l; 3714530Sdlw char c; 3724530Sdlw { 373*4687Sdlw fputs(icvt(a, addr_base, UNSIGNED, 7), stdout); 374*4687Sdlw if (l >= 0) 375*4687Sdlw 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; 387*4687Sdlw while (c = *cv++) 388*4687Sdlw { 389*4687Sdlw if (c->df_paddr) 390*4687Sdlw { 391*4687Sdlw if (first) 392*4687Sdlw { 393*4687Sdlw put_addr(addr, label, ' '); 394*4687Sdlw first = NO; 395*4687Sdlw } 396*4687Sdlw else 397*4687Sdlw { 398*4687Sdlw putchar('\t'); 399*4687Sdlw if (label >= 0) 400*4687Sdlw fputs("\t ", stdout); 401*4687Sdlw } 4024530Sdlw } 4034492Sdlw i = 0; 4044492Sdlw while (i < n) 4054492Sdlw i += (*(c->df_put))(dbuf+i, c); 406*4687Sdlw if (c->df_paddr) 407*4687Sdlw 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] = { 472*4687Sdlw /* 000 */ "nul", "soh", "stx", "etx", "eot", "enq", "ack", "bel", 473*4687Sdlw /* 010 */ " bs", " ht", " nl", " vt", " ff", " cr", " so", " si", 474*4687Sdlw /* 020 */ "dle", "dc1", "dc2", "dc3", "dc4", "nak", "syn", "etb", 475*4687Sdlw /* 030 */ "can", " em", "sub", "esc", " fs", " gs", " rs", " us", 476*4687Sdlw /* 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; 488*4687Sdlw if (isgraphic(c)) 4894492Sdlw { 490*4687Sdlw 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) 515*4687Sdlw do 516*4687Sdlw { 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 529*4687Sdlw while (*s) 530*4687Sdlw { 531*4687Sdlw if (*s != ' ') 532*4687Sdlw { 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 { 554*4687Sdlw register char *s; 555*4687Sdlw register int n; 556*4687Sdlw register int c = *cc & 0377; 5574492Sdlw 558*4687Sdlw s = scvt(c, d); 559*4687Sdlw for (n = d->df_field - strlen(s); n > 0; n--) 560*4687Sdlw putchar(' '); 561*4687Sdlw printf(d->df_fmt, s); 562*4687Sdlw return(1); 563*4687Sdlw } 564*4687Sdlw 565*4687Sdlw char *scvt(c, d) 566*4687Sdlw int c; 567*4687Sdlw struct dfmt *d; 568*4687Sdlw { 569*4687Sdlw static char s[2]; 570*4687Sdlw 571*4687Sdlw switch(c) 572*4687Sdlw { 573*4687Sdlw case '\0': 574*4687Sdlw return("\\0"); 575*4687Sdlw 576*4687Sdlw case '\b': 577*4687Sdlw return("\\b"); 578*4687Sdlw 579*4687Sdlw case '\f': 580*4687Sdlw return("\\f"); 581*4687Sdlw 582*4687Sdlw case '\n': 583*4687Sdlw return("\\n"); 584*4687Sdlw 585*4687Sdlw case '\r': 586*4687Sdlw return("\\r"); 587*4687Sdlw 588*4687Sdlw case '\t': 589*4687Sdlw return("\\t"); 590*4687Sdlw 591*4687Sdlw default: 592*4687Sdlw if (isprint(c)) 593*4687Sdlw { 594*4687Sdlw s[0] = c; 595*4687Sdlw return(s); 596*4687Sdlw } 597*4687Sdlw return(icvt((long)c, d->df_radix, d->df_signed, d->df_field)); 5984492Sdlw } 599*4687Sdlw } 6004492Sdlw 601*4687Sdlw /* 602*4687Sdlw * Look for strings. 603*4687Sdlw * A string contains bytes > 037 && < 177, and ends with a null. 604*4687Sdlw * The minimum length is given in the dfmt structure. 605*4687Sdlw */ 606*4687Sdlw 607*4687Sdlw #define CNULL '\0' 608*4687Sdlw #define S_EMPTY 0 609*4687Sdlw #define S_FILL 1 610*4687Sdlw #define S_CONT 2 611*4687Sdlw #define SBUFSIZE 1024 612*4687Sdlw 613*4687Sdlw static char str_buf[SBUFSIZE]; 614*4687Sdlw static int str_mode = S_EMPTY; 615*4687Sdlw static char *str_ptr; 616*4687Sdlw static long str_addr; 617*4687Sdlw static long str_label; 618*4687Sdlw 619*4687Sdlw st_put(c, d) 620*4687Sdlw register char *c; 621*4687Sdlw struct dfmt *d; 622*4687Sdlw { 623*4687Sdlw if (c == 0) 624*4687Sdlw { 625*4687Sdlw pr_sbuf(d, YES); 6264492Sdlw } 627*4687Sdlw else if (str_mode & S_FILL) 628*4687Sdlw { 629*4687Sdlw if (isascii(*c)) 630*4687Sdlw put_sbuf(*c, d); 631*4687Sdlw else 632*4687Sdlw { 633*4687Sdlw *str_ptr = CNULL; 634*4687Sdlw if (*c == CNULL) 635*4687Sdlw pr_sbuf(d, YES); 636*4687Sdlw str_mode = S_EMPTY; 637*4687Sdlw } 638*4687Sdlw } 639*4687Sdlw else if (isascii(*c)) 640*4687Sdlw { 641*4687Sdlw str_mode = S_FILL; 642*4687Sdlw str_addr = addr + (c - dbuf); /* ugly */ 643*4687Sdlw if ((str_label = label) >= 0) 644*4687Sdlw str_label += (c - dbuf);/* '' */ 645*4687Sdlw str_ptr = str_buf; 646*4687Sdlw put_sbuf(*c, d); 647*4687Sdlw } 648*4687Sdlw 6494492Sdlw return(1); 6504492Sdlw } 6514492Sdlw 652*4687Sdlw put_sbuf(c, d) 653*4687Sdlw char c; 654*4687Sdlw struct dfmt *d; 655*4687Sdlw { 656*4687Sdlw *str_ptr++ = c; 657*4687Sdlw if (str_ptr >= (str_buf + SBUFSIZE)) 658*4687Sdlw { 659*4687Sdlw pr_sbuf(d, NO); 660*4687Sdlw str_ptr = str_buf; 661*4687Sdlw str_mode |= S_CONT; 662*4687Sdlw } 663*4687Sdlw } 664*4687Sdlw 665*4687Sdlw pr_sbuf(d, end) 666*4687Sdlw struct dfmt *d; 667*4687Sdlw int end; 668*4687Sdlw { 669*4687Sdlw register char *p = str_buf; 670*4687Sdlw 671*4687Sdlw if (str_mode == S_EMPTY 672*4687Sdlw || (!(str_mode & S_CONT) && (str_ptr - str_buf) < d->df_size)) 673*4687Sdlw return; 674*4687Sdlw 675*4687Sdlw if (!(str_mode & S_CONT)) 676*4687Sdlw put_addr(str_addr, str_label, ' '); 677*4687Sdlw 678*4687Sdlw while (p < str_ptr) 679*4687Sdlw fputs(scvt(*p++, d), stdout); 680*4687Sdlw 681*4687Sdlw if (end) 682*4687Sdlw putchar('\n'); 683*4687Sdlw } 684*4687Sdlw 6854492Sdlw /* 6864492Sdlw * integer to ascii conversion 6874492Sdlw * 6884492Sdlw * This code has been rearranged to produce optimized runtime code. 6894492Sdlw */ 6904492Sdlw 6914492Sdlw #define MAXINTLENGTH 32 6924492Sdlw static char _digit[] = "0123456789abcdef"; 6934492Sdlw static char _icv_buf[MAXINTLENGTH+1]; 6944492Sdlw static long _mask = 0x7fffffff; 6954492Sdlw 6964492Sdlw char * 6974492Sdlw icvt (value, radix, signed, ndigits) 6984492Sdlw long value; 6994492Sdlw int radix; 7004492Sdlw int signed; 7014492Sdlw int ndigits; 7024492Sdlw { 7034492Sdlw register long val = value; 7044492Sdlw register long rad = radix; 7054492Sdlw register char *b = &_icv_buf[MAXINTLENGTH]; 7064492Sdlw register char *d = _digit; 7074492Sdlw register long tmp1; 7084492Sdlw register long tmp2; 7094492Sdlw long rem; 7104492Sdlw long kludge; 7114492Sdlw int sign; 7124492Sdlw 7134492Sdlw if (val == 0) 7144492Sdlw { 7154492Sdlw *--b = '0'; 7164492Sdlw sign = 0; 7174492Sdlw goto done; /*return(b);*/ 7184492Sdlw } 7194492Sdlw 7204492Sdlw if (signed && (sign = (val < 0))) /* signed conversion */ 7214492Sdlw { 7224492Sdlw /* 7234492Sdlw * It is necessary to do the first divide 7244492Sdlw * before the absolute value, for the case -2^31 7254492Sdlw * 7264492Sdlw * This is actually what is being done... 7274492Sdlw * tmp1 = (int)(val % rad); 7284492Sdlw * val /= rad; 7294492Sdlw * val = -val 7304492Sdlw * *--b = d[-tmp1]; 7314492Sdlw */ 7324492Sdlw tmp1 = val / rad; 7334492Sdlw *--b = d[(tmp1 * rad) - val]; 7344492Sdlw val = -tmp1; 7354492Sdlw } 7364492Sdlw else /* unsigned conversion */ 7374492Sdlw { 7384492Sdlw sign = 0; 7394492Sdlw if (val < 0) 7404492Sdlw { /* ALL THIS IS TO SIMULATE UNSIGNED LONG MOD & DIV */ 7414492Sdlw kludge = _mask - (rad - 1); 7424492Sdlw val &= _mask; 7434492Sdlw /* 7444492Sdlw * This is really what's being done... 7454492Sdlw * rem = (kludge % rad) + (val % rad); 7464492Sdlw * val = (kludge / rad) + (val / rad) + (rem / rad) + 1; 7474492Sdlw * *--b = d[rem % rad]; 7484492Sdlw */ 7494492Sdlw tmp1 = kludge / rad; 7504492Sdlw tmp2 = val / rad; 7514492Sdlw rem = (kludge - (tmp1 * rad)) + (val - (tmp2 * rad)); 7524492Sdlw val = ++tmp1 + tmp2; 7534492Sdlw tmp1 = rem / rad; 7544492Sdlw val += tmp1; 7554492Sdlw *--b = d[rem - (tmp1 * rad)]; 7564492Sdlw } 7574492Sdlw } 7584492Sdlw 7594492Sdlw while (val) 7604492Sdlw { 7614492Sdlw /* 7624492Sdlw * This is really what's being done ... 7634492Sdlw * *--b = d[val % rad]; 7644492Sdlw * val /= rad; 7654492Sdlw */ 7664492Sdlw tmp1 = val / rad; 7674492Sdlw *--b = d[val - (tmp1 * rad)]; 7684492Sdlw val = tmp1; 7694492Sdlw } 7704492Sdlw 7714492Sdlw done: 7724492Sdlw if (sign) 7734492Sdlw *--b = '-'; 7744492Sdlw 7754492Sdlw tmp1 = ndigits - (&_icv_buf[MAXINTLENGTH] - b); 7764492Sdlw tmp2 = signed? ' ':'0'; 7774492Sdlw while (tmp1 > 0) 7784492Sdlw { 7794492Sdlw *--b = tmp2; 7804492Sdlw tmp1--; 7814492Sdlw } 7824492Sdlw 7834492Sdlw return(b); 7844492Sdlw } 7854492Sdlw 786*4687Sdlw long get_addr(s) 7874492Sdlw register char *s; 7884492Sdlw { 7894492Sdlw register char *p; 7904530Sdlw register long a; 7914492Sdlw register int d; 7924492Sdlw 7934492Sdlw if (*s=='+') 7944492Sdlw s++; 795*4687Sdlw if (*s=='x') 796*4687Sdlw { 7974492Sdlw s++; 7984492Sdlw addr_base = 16; 799*4687Sdlw } 800*4687Sdlw else if (*s=='0' && s[1]=='x') 801*4687Sdlw { 8024492Sdlw s += 2; 8034492Sdlw addr_base = 16; 804*4687Sdlw } 805*4687Sdlw else if (*s == '0') 8064492Sdlw addr_base = 8; 8074492Sdlw p = s; 808*4687Sdlw while(*p) 809*4687Sdlw { 8104492Sdlw if (*p++=='.') 8114492Sdlw addr_base = 10; 8124492Sdlw } 813*4687Sdlw for (a=0; *s; s++) 814*4687Sdlw { 8154492Sdlw d = *s; 816*4687Sdlw if(isdigit(d)) 8174492Sdlw a = a*addr_base + d - '0'; 818*4687Sdlw else if (ishex(d) && addr_base==16) 8194492Sdlw a = a*addr_base + d + 10 - 'a'; 8204492Sdlw else 8214492Sdlw break; 8224492Sdlw } 8234530Sdlw 8244492Sdlw if (*s == '.') 8254492Sdlw s++; 8264530Sdlw if(*s=='b') 8274492Sdlw a *= 512; 8284530Sdlw if(*s=='B') 8294530Sdlw a *= 1024; 8304530Sdlw 8314530Sdlw return(a); 8324530Sdlw } 8334530Sdlw 8344530Sdlw offset(a) 8354530Sdlw long a; 8364530Sdlw { 8374492Sdlw if (canseek(stdin)) 8384492Sdlw fseek(stdin, a, 0); 8394492Sdlw else 8404492Sdlw dumbseek(stdin, a); 8414492Sdlw } 8424492Sdlw 8434492Sdlw dumbseek(s, offset) 8444492Sdlw FILE *s; 8454492Sdlw long offset; 8464492Sdlw { 8474492Sdlw char buf[BUFSIZ]; 8484492Sdlw int n; 8494492Sdlw int nr; 8504492Sdlw 8514492Sdlw while (offset > 0) 8524492Sdlw { 8534492Sdlw nr = (offset > BUFSIZ) ? BUFSIZ : (int)offset; 8544492Sdlw if ((n = fread(buf, 1, nr, s)) != nr) 8554492Sdlw { 8564492Sdlw fprintf(stderr, "EOF\n"); 8574492Sdlw exit(1); 8584492Sdlw } 8594492Sdlw offset -= n; 8604492Sdlw } 8614492Sdlw } 8624492Sdlw 8634492Sdlw #include <sys/types.h> 8644492Sdlw #include <sys/stat.h> 8654492Sdlw 8664492Sdlw canseek(f) 8674492Sdlw FILE *f; 8684492Sdlw { 8694492Sdlw struct stat statb; 8704492Sdlw 8714492Sdlw return( (fstat(fileno(f),&statb)==0) && 8724492Sdlw (statb.st_nlink > 0) && /*!pipe*/ 8734492Sdlw (!isatty(fileno(f))) ); 8744492Sdlw } 875