884 lines
20 KiB
C
884 lines
20 KiB
C
/*
|
|
* od -- octal, hex, decimal, character dump of data in a file.
|
|
*
|
|
* usage: od [-abBcdDefFhHiIlLopPs[n]vw[n]xX] [file] [[+]offset[.][b] [label]]
|
|
*
|
|
* where the option flags have the following meaning:
|
|
* character object radix signed?
|
|
* a byte (10) (n.a.) ASCII named byte stream
|
|
* b byte 8 no byte octal
|
|
* c byte (8) (no) character with octal non-graphic bytes
|
|
* d short 10 no
|
|
* D long 10 no
|
|
* e,F double (10) double precision floating pt.
|
|
* f float (10) single precision floating pt.
|
|
* h,x short 16 no
|
|
* H,X long 16 no
|
|
* i short 10 yes
|
|
* I,l,L long 10 yes
|
|
* o,B short 8 no (default conversion)
|
|
* O long 8 no
|
|
* s[n] string (8) ASCII graphic strings
|
|
*
|
|
* p indicate EVEN parity on 'a' conversion
|
|
* P indicate ODD parity on 'a' conversion
|
|
* v show all data - don't skip like lines.
|
|
* w[n] bytes per display line
|
|
*
|
|
* More than one format character may be given.
|
|
* If {file} is not specified, standard input is read.
|
|
* If {file} is not specified, then {offset} must start with '+'.
|
|
* {Offset} may be HEX (0xnnn), OCTAL (0nn), or decimal (nnn.).
|
|
* The default is octal. The same radix will be used to display the address.
|
|
*/
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#define DBUF_SIZE BUFSIZ
|
|
#define BIG_DBUF 32
|
|
#define NO 0
|
|
#define YES 1
|
|
#define EVEN -1
|
|
#define ODD 1
|
|
#define UNSIGNED 0
|
|
#define SIGNED 1
|
|
#define PADDR 1
|
|
#define MIN_SLEN 3
|
|
|
|
int a_put();
|
|
int b_put();
|
|
int c_put();
|
|
int s_put();
|
|
int us_put();
|
|
int l_put();
|
|
int f_put();
|
|
int d_put();
|
|
int st_put();
|
|
|
|
struct dfmt {
|
|
int df_field; /* external field required for object */
|
|
int df_size; /* size (bytes) of object */
|
|
int df_radix; /* conversion radix */
|
|
int df_signed; /* signed? flag */
|
|
int df_paddr; /* "put address on each line?" flag */
|
|
int (*df_put)(); /* function to output object */
|
|
char *df_fmt; /* output string format */
|
|
} *conv_vec[32]; /* vector of conversions to be done */
|
|
|
|
struct dfmt ascii = { 3, sizeof (char), 10, 0, PADDR, a_put, 0};
|
|
struct dfmt byte = { 3, sizeof (char), 8, UNSIGNED, PADDR, b_put, 0};
|
|
struct dfmt cchar = { 3, sizeof (char), 8, UNSIGNED, PADDR, c_put, 0};
|
|
struct dfmt u_s_oct = { 6, sizeof (short), 8, UNSIGNED, PADDR, us_put, 0};
|
|
struct dfmt u_s_dec = { 5, sizeof (short), 10, UNSIGNED, PADDR, us_put, 0};
|
|
struct dfmt u_s_hex = { 4, sizeof (short), 16, UNSIGNED, PADDR, us_put, 0};
|
|
struct dfmt u_l_oct = {11, sizeof (long), 8, UNSIGNED, PADDR, l_put, 0};
|
|
struct dfmt u_l_dec = {10, sizeof (long), 10, UNSIGNED, PADDR, l_put, 0};
|
|
struct dfmt u_l_hex = { 8, sizeof (long), 16, UNSIGNED, PADDR, l_put, 0};
|
|
struct dfmt s_s_dec = { 6, sizeof (short), 10, SIGNED, PADDR, s_put, 0};
|
|
struct dfmt s_l_dec = {11, sizeof (long), 10, SIGNED, PADDR, l_put, 0};
|
|
struct dfmt flt = {14, sizeof (float), 10, SIGNED, PADDR, f_put, 0};
|
|
struct dfmt dble = {21, sizeof (double), 10, SIGNED, PADDR, d_put, 0};
|
|
struct dfmt string = { 0, 0, 8, 0, NO, st_put, 0};
|
|
|
|
|
|
char usage[] ="usage: od [-abcdfhilopswvx] [file] [[+]offset[.][b] [label]]";
|
|
char dbuf[DBUF_SIZE];
|
|
char lastdbuf[DBUF_SIZE];
|
|
int addr_base = 8; /* default address base is OCTAL */
|
|
long addr = 0L; /* current file offset */
|
|
long label = -1L; /* current label; -1 is "off" */
|
|
int dbuf_size = 16; /* file bytes / display line */
|
|
int _parity = NO; /* show parity on ascii bytes */
|
|
char fmt[] = " %s"; /* 12 blanks */
|
|
char *icvt();
|
|
char *scvt();
|
|
char *underline();
|
|
long get_addr();
|
|
|
|
|
|
/*
|
|
* special form of _ctype
|
|
*/
|
|
|
|
#define A 01
|
|
#define G 02
|
|
#define D 04
|
|
#define P 010
|
|
#define X 020
|
|
#define isdigit(c) (_ctype[c] & D)
|
|
#define isascii(c) (_ctype[c] & A)
|
|
#define isgraphic(c) (_ctype[c] & G)
|
|
#define isprint(c) (_ctype[c] & P)
|
|
#define ishex(c) (_ctype[c] & (X|D))
|
|
|
|
char _ctype[256] = {
|
|
/* 000 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 010 */ A, A, A, 0, A, A, 0, 0,
|
|
/* 020 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 030 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 040 */ P|A, P|G|A, P|G|A, P|G|A, P|G|A, P|G|A, P|G|A, P|G|A,
|
|
/* 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,
|
|
/* 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,
|
|
/* 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,
|
|
/* 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,
|
|
/* 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,
|
|
/* 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,
|
|
/* 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,
|
|
/* 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,
|
|
/* 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,
|
|
/* 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,
|
|
/* 170 */ P|G|A, P|G|A, P|G|A, P|G|A, P|G|A, P|G|A, P|G|A, 0,
|
|
/* 200 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 210 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 220 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 230 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 240 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 250 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 260 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 270 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 300 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 310 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 320 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 330 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 340 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 350 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 360 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 370 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
};
|
|
|
|
|
|
main(argc, argv)
|
|
int argc;
|
|
char **argv;
|
|
{
|
|
register char *p;
|
|
register char *l;
|
|
register n, same;
|
|
struct dfmt *d;
|
|
struct dfmt **cv = conv_vec;
|
|
int showall = NO;
|
|
int field, llen, nelm;
|
|
int max_llen = 0;
|
|
|
|
argv++;
|
|
argc--;
|
|
|
|
if(argc > 0)
|
|
{
|
|
p = *argv;
|
|
if(*p == '-')
|
|
{
|
|
while(*++p != '\0')
|
|
{
|
|
switch(*p)
|
|
{
|
|
case 'a':
|
|
d = &ascii;
|
|
break;
|
|
case 'b':
|
|
d = &byte;
|
|
break;
|
|
case 'c':
|
|
d = &cchar;
|
|
break;
|
|
case 'd':
|
|
d = &u_s_dec;
|
|
break;
|
|
case 'D':
|
|
d = &u_l_dec;
|
|
break;
|
|
case 'e':
|
|
case 'F':
|
|
d = &dble;
|
|
break;
|
|
case 'f':
|
|
d = &flt;
|
|
break;
|
|
case 'h':
|
|
case 'x':
|
|
d = &u_s_hex;
|
|
break;
|
|
case 'H':
|
|
case 'X':
|
|
d = &u_l_hex;
|
|
break;
|
|
case 'i':
|
|
d = &s_s_dec;
|
|
break;
|
|
case 'I':
|
|
case 'l':
|
|
case 'L':
|
|
d = &s_l_dec;
|
|
break;
|
|
case 'o':
|
|
case 'B':
|
|
d = &u_s_oct;
|
|
break;
|
|
case 'O':
|
|
d = &u_l_oct;
|
|
break;
|
|
case 'p':
|
|
_parity = EVEN;
|
|
continue;
|
|
case 'P':
|
|
_parity = ODD;
|
|
continue;
|
|
case 's':
|
|
d = &string;
|
|
*(cv++) = d;
|
|
while (isdigit(p[1]))
|
|
d->df_size = (10 * d->df_size) + (*++p - '0');
|
|
if (d->df_size <= 0)
|
|
d->df_size = MIN_SLEN;
|
|
showall = YES;
|
|
continue;
|
|
case 'w':
|
|
dbuf_size = 0;
|
|
while (isdigit(p[1]))
|
|
dbuf_size = (10 * dbuf_size) + (*++p - '0');
|
|
if (dbuf_size == 0)
|
|
dbuf_size = BIG_DBUF;
|
|
continue;
|
|
case 'v':
|
|
showall = YES;
|
|
continue;
|
|
default:
|
|
printf("od: bad flag -%c\n", *p);
|
|
puts(usage);
|
|
exit(1);
|
|
}
|
|
*(cv++) = d;
|
|
}
|
|
argc--;
|
|
argv++;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* if nothing spec'd, setup default conversion.
|
|
*/
|
|
if(cv == conv_vec)
|
|
*(cv++) = &u_s_oct;
|
|
|
|
*cv = (struct dfmt *)0;
|
|
|
|
/*
|
|
* calculate display parameters
|
|
*/
|
|
for (cv = conv_vec; d = *cv; cv++)
|
|
{
|
|
nelm = (dbuf_size + d->df_size - 1) / d->df_size;
|
|
llen = nelm * (d->df_field + 1);
|
|
if (llen > max_llen)
|
|
max_llen = llen;
|
|
}
|
|
|
|
/*
|
|
* setup df_fmt to point to uniform output fields.
|
|
*/
|
|
for (cv = conv_vec; d = *cv; cv++)
|
|
{
|
|
if (d->df_field) /* only if external field is known */
|
|
{
|
|
nelm = (dbuf_size + d->df_size - 1) / d->df_size;
|
|
field = max_llen / nelm;
|
|
d->df_fmt = fmt + 12 - (field - d->df_field);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* input file specified ?
|
|
*/
|
|
if(argc > 0 && **argv != '+')
|
|
{
|
|
if (freopen(*argv, "r", stdin) == NULL)
|
|
{
|
|
perror(*argv);
|
|
exit(1);
|
|
}
|
|
argv++;
|
|
argc--;
|
|
}
|
|
|
|
/*
|
|
* check for possible offset [label]
|
|
*/
|
|
if (argc > 0)
|
|
{
|
|
addr = get_addr(*argv);
|
|
offset(addr);
|
|
argv++;
|
|
argc--;
|
|
|
|
if (argc > 0)
|
|
label = get_addr(*argv);
|
|
}
|
|
|
|
/*
|
|
* main dump loop
|
|
*/
|
|
same = -1;
|
|
while ((n = fread(dbuf, 1, dbuf_size, stdin)) > 0)
|
|
{
|
|
if (same>=0 && bcmp(dbuf, lastdbuf, dbuf_size) == 0 && !showall)
|
|
{
|
|
if (same==0)
|
|
{
|
|
printf("*\n");
|
|
same = 1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
line(n);
|
|
same = 0;
|
|
p = dbuf;
|
|
l = lastdbuf;
|
|
for (nelm = 0; nelm < dbuf_size; nelm++)
|
|
{
|
|
*l++ = *p;
|
|
*p++ = '\0';
|
|
}
|
|
}
|
|
addr += n;
|
|
if (label >= 0)
|
|
label += n;
|
|
}
|
|
|
|
/*
|
|
* Some conversions require "flushing".
|
|
*/
|
|
n = 0;
|
|
for (cv = conv_vec; *cv; cv++)
|
|
{
|
|
if ((*cv)->df_paddr)
|
|
{
|
|
if (n++ == 0)
|
|
put_addr(addr, label, '\n');
|
|
}
|
|
else
|
|
(*((*cv)->df_put))(0, *cv);
|
|
}
|
|
}
|
|
|
|
put_addr(a, l, c)
|
|
long a;
|
|
long l;
|
|
char c;
|
|
{
|
|
fputs(icvt(a, addr_base, UNSIGNED, 7), stdout);
|
|
if (l >= 0)
|
|
printf(" (%s)", icvt(l, addr_base, UNSIGNED, 7));
|
|
putchar(c);
|
|
}
|
|
|
|
line(n)
|
|
int n;
|
|
{
|
|
register i, first;
|
|
register struct dfmt *c;
|
|
register struct dfmt **cv = conv_vec;
|
|
|
|
first = YES;
|
|
while (c = *cv++)
|
|
{
|
|
if (c->df_paddr)
|
|
{
|
|
if (first)
|
|
{
|
|
put_addr(addr, label, ' ');
|
|
first = NO;
|
|
}
|
|
else
|
|
{
|
|
putchar('\t');
|
|
if (label >= 0)
|
|
fputs("\t ", stdout);
|
|
}
|
|
}
|
|
i = 0;
|
|
while (i < n)
|
|
i += (*(c->df_put))(dbuf+i, c);
|
|
if (c->df_paddr)
|
|
putchar('\n');
|
|
}
|
|
}
|
|
|
|
s_put(n, d)
|
|
short *n;
|
|
struct dfmt *d;
|
|
{
|
|
printf(d->df_fmt, icvt((long)*n, d->df_radix, d->df_signed, d->df_field));
|
|
return(d->df_size);
|
|
}
|
|
|
|
us_put(n, d)
|
|
unsigned short *n;
|
|
struct dfmt *d;
|
|
{
|
|
printf(d->df_fmt, icvt((long)*n, d->df_radix, d->df_signed, d->df_field));
|
|
return(d->df_size);
|
|
}
|
|
|
|
l_put(n, d)
|
|
long *n;
|
|
struct dfmt *d;
|
|
{
|
|
printf(d->df_fmt, icvt(*n, d->df_radix, d->df_signed, d->df_field));
|
|
return(d->df_size);
|
|
}
|
|
|
|
d_put(f, d)
|
|
double *f;
|
|
struct dfmt *d;
|
|
{
|
|
char fbuf[24];
|
|
struct l { long n[2]; };
|
|
|
|
#if vax
|
|
if ((((struct l *)f)->n[0] & 0xff00) == 0x8000) /* Vax illegal f.p. */
|
|
sprintf(fbuf, " %08x %08x",
|
|
((struct l *)f)->n[0], ((struct l *)f)->n[1]);
|
|
else
|
|
#endif
|
|
|
|
sprintf(fbuf, "%21.14e", *f);
|
|
printf(d->df_fmt, fbuf);
|
|
return(d->df_size);
|
|
}
|
|
|
|
f_put(f, d)
|
|
float *f;
|
|
struct dfmt *d;
|
|
{
|
|
char fbuf[16];
|
|
|
|
#if vax
|
|
if ((*(long *)f & 0xff00) == 0x8000) /* Vax illegal f.p. form */
|
|
sprintf(fbuf, " %08x", *(long *)f);
|
|
else
|
|
#endif
|
|
sprintf(fbuf, "%14.7e", *f);
|
|
printf(d->df_fmt, fbuf);
|
|
return(d->df_size);
|
|
}
|
|
|
|
|
|
char asc_name[34][4] = {
|
|
/* 000 */ "nul", "soh", "stx", "etx", "eot", "enq", "ack", "bel",
|
|
/* 010 */ " bs", " ht", " nl", " vt", " ff", " cr", " so", " si",
|
|
/* 020 */ "dle", "dc1", "dc2", "dc3", "dc4", "nak", "syn", "etb",
|
|
/* 030 */ "can", " em", "sub", "esc", " fs", " gs", " rs", " us",
|
|
/* 040 */ " sp", "del"
|
|
};
|
|
|
|
a_put(cc, d)
|
|
char *cc;
|
|
struct dfmt *d;
|
|
{
|
|
int c = *cc;
|
|
register char *s = " ";
|
|
register pbit = parity((int)c & 0377);
|
|
|
|
c &= 0177;
|
|
if (isgraphic(c))
|
|
{
|
|
s[2] = c;
|
|
if (pbit == _parity)
|
|
printf(d->df_fmt, underline(s));
|
|
else
|
|
printf(d->df_fmt, s);
|
|
}
|
|
else
|
|
{
|
|
if (c == 0177)
|
|
c = ' ' + 1;
|
|
if (pbit == _parity)
|
|
printf(d->df_fmt, underline(asc_name[c]));
|
|
else
|
|
printf(d->df_fmt, asc_name[c]);
|
|
}
|
|
return(1);
|
|
}
|
|
|
|
parity(word)
|
|
int word;
|
|
{
|
|
register int p = 0;
|
|
register int w = word;
|
|
|
|
if (w)
|
|
do
|
|
{
|
|
p ^= 1;
|
|
} while(w &= (~(-w)));
|
|
return (p? ODD:EVEN);
|
|
}
|
|
|
|
char *
|
|
underline(s)
|
|
char *s;
|
|
{
|
|
static char ulbuf[16];
|
|
register char *u = ulbuf;
|
|
|
|
while (*s)
|
|
{
|
|
if (*s != ' ')
|
|
{
|
|
*u++ = '_';
|
|
*u++ = '\b';
|
|
}
|
|
*u++ = *s++;
|
|
}
|
|
*u = '\0';
|
|
return(ulbuf);
|
|
}
|
|
|
|
b_put(b, d)
|
|
char *b;
|
|
struct dfmt *d;
|
|
{
|
|
printf(d->df_fmt, icvt((long)*b & 0377, d->df_radix, d->df_signed, d->df_field));
|
|
return(1);
|
|
}
|
|
|
|
c_put(cc, d)
|
|
char *cc;
|
|
struct dfmt *d;
|
|
{
|
|
register char *s;
|
|
register int n;
|
|
register int c = *cc & 0377;
|
|
|
|
s = scvt(c, d);
|
|
for (n = d->df_field - strlen(s); n > 0; n--)
|
|
putchar(' ');
|
|
printf(d->df_fmt, s);
|
|
return(1);
|
|
}
|
|
|
|
char *scvt(c, d)
|
|
int c;
|
|
struct dfmt *d;
|
|
{
|
|
static char s[2];
|
|
|
|
switch(c)
|
|
{
|
|
case '\0':
|
|
return("\\0");
|
|
|
|
case '\b':
|
|
return("\\b");
|
|
|
|
case '\f':
|
|
return("\\f");
|
|
|
|
case '\n':
|
|
return("\\n");
|
|
|
|
case '\r':
|
|
return("\\r");
|
|
|
|
case '\t':
|
|
return("\\t");
|
|
|
|
default:
|
|
if (isprint(c))
|
|
{
|
|
s[0] = c;
|
|
return(s);
|
|
}
|
|
return(icvt((long)c, d->df_radix, d->df_signed, d->df_field));
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Look for strings.
|
|
* A string contains bytes > 037 && < 177, and ends with a null.
|
|
* The minimum length is given in the dfmt structure.
|
|
*/
|
|
|
|
#define CNULL '\0'
|
|
#define S_EMPTY 0
|
|
#define S_FILL 1
|
|
#define S_CONT 2
|
|
#define SBUFSIZE 1024
|
|
|
|
static char str_buf[SBUFSIZE];
|
|
static int str_mode = S_EMPTY;
|
|
static char *str_ptr;
|
|
static long str_addr;
|
|
static long str_label;
|
|
|
|
st_put(cc, d)
|
|
char *cc;
|
|
struct dfmt *d;
|
|
{
|
|
register int c;
|
|
|
|
if (cc == 0)
|
|
{
|
|
pr_sbuf(d, YES);
|
|
return(1);
|
|
}
|
|
|
|
c = (*cc & 0377);
|
|
|
|
if (str_mode & S_FILL)
|
|
{
|
|
if (isascii(c))
|
|
put_sbuf(c, d);
|
|
else
|
|
{
|
|
*str_ptr = CNULL;
|
|
if (c == NULL)
|
|
pr_sbuf(d, YES);
|
|
str_mode = S_EMPTY;
|
|
}
|
|
}
|
|
else if (isascii(c))
|
|
{
|
|
str_mode = S_FILL;
|
|
str_addr = addr + (cc - dbuf); /* ugly */
|
|
if ((str_label = label) >= 0)
|
|
str_label += (cc - dbuf); /* '' */
|
|
str_ptr = str_buf;
|
|
put_sbuf(c, d);
|
|
}
|
|
|
|
return(1);
|
|
}
|
|
|
|
put_sbuf(c, d)
|
|
int c;
|
|
struct dfmt *d;
|
|
{
|
|
*str_ptr++ = c;
|
|
if (str_ptr >= (str_buf + SBUFSIZE))
|
|
{
|
|
pr_sbuf(d, NO);
|
|
str_ptr = str_buf;
|
|
str_mode |= S_CONT;
|
|
}
|
|
}
|
|
|
|
pr_sbuf(d, end)
|
|
struct dfmt *d;
|
|
int end;
|
|
{
|
|
register char *p = str_buf;
|
|
|
|
if (str_mode == S_EMPTY
|
|
|| (!(str_mode & S_CONT) && (str_ptr - str_buf) < d->df_size))
|
|
return;
|
|
|
|
if (!(str_mode & S_CONT))
|
|
put_addr(str_addr, str_label, ' ');
|
|
|
|
while (p < str_ptr)
|
|
fputs(scvt(*p++, d), stdout);
|
|
|
|
if (end)
|
|
putchar('\n');
|
|
}
|
|
|
|
/*
|
|
* integer to ascii conversion
|
|
*
|
|
* This code has been rearranged to produce optimized runtime code.
|
|
*/
|
|
|
|
#define MAXINTLENGTH 32
|
|
static char _digit[] = "0123456789abcdef";
|
|
static char _icv_buf[MAXINTLENGTH+1];
|
|
static long _mask = 0x7fffffff;
|
|
|
|
char *
|
|
icvt (value, radix, signd, ndigits)
|
|
long value;
|
|
int radix;
|
|
int signd;
|
|
int ndigits;
|
|
{
|
|
register long val = value;
|
|
register long rad = radix;
|
|
register char *b = &_icv_buf[MAXINTLENGTH];
|
|
register char *d = _digit;
|
|
register long tmp1;
|
|
register long tmp2;
|
|
long rem;
|
|
long kludge;
|
|
int sign;
|
|
|
|
if (val == 0)
|
|
{
|
|
*--b = '0';
|
|
sign = 0;
|
|
goto done; /*return(b);*/
|
|
}
|
|
|
|
if (signd && (sign = (val < 0))) /* signed conversion */
|
|
{
|
|
/*
|
|
* It is necessary to do the first divide
|
|
* before the absolute value, for the case -2^31
|
|
*
|
|
* This is actually what is being done...
|
|
* tmp1 = (int)(val % rad);
|
|
* val /= rad;
|
|
* val = -val
|
|
* *--b = d[-tmp1];
|
|
*/
|
|
tmp1 = val / rad;
|
|
*--b = d[(tmp1 * rad) - val];
|
|
val = -tmp1;
|
|
}
|
|
else /* unsigned conversion */
|
|
{
|
|
sign = 0;
|
|
if (val < 0)
|
|
{ /* ALL THIS IS TO SIMULATE UNSIGNED LONG MOD & DIV */
|
|
kludge = _mask - (rad - 1);
|
|
val &= _mask;
|
|
/*
|
|
* This is really what's being done...
|
|
* rem = (kludge % rad) + (val % rad);
|
|
* val = (kludge / rad) + (val / rad) + (rem / rad) + 1;
|
|
* *--b = d[rem % rad];
|
|
*/
|
|
tmp1 = kludge / rad;
|
|
tmp2 = val / rad;
|
|
rem = (kludge - (tmp1 * rad)) + (val - (tmp2 * rad));
|
|
val = ++tmp1 + tmp2;
|
|
tmp1 = rem / rad;
|
|
val += tmp1;
|
|
*--b = d[rem - (tmp1 * rad)];
|
|
}
|
|
}
|
|
|
|
while (val)
|
|
{
|
|
/*
|
|
* This is really what's being done ...
|
|
* *--b = d[val % rad];
|
|
* val /= rad;
|
|
*/
|
|
tmp1 = val / rad;
|
|
*--b = d[val - (tmp1 * rad)];
|
|
val = tmp1;
|
|
}
|
|
|
|
done:
|
|
if (sign)
|
|
*--b = '-';
|
|
|
|
tmp1 = ndigits - (&_icv_buf[MAXINTLENGTH] - b);
|
|
tmp2 = signd ? ' ' : '0';
|
|
while (tmp1 > 0)
|
|
{
|
|
*--b = tmp2;
|
|
tmp1--;
|
|
}
|
|
|
|
return(b);
|
|
}
|
|
|
|
long get_addr(s)
|
|
register char *s;
|
|
{
|
|
register char *p;
|
|
register long a;
|
|
register int d;
|
|
|
|
if (*s=='+')
|
|
s++;
|
|
if (*s=='x')
|
|
{
|
|
s++;
|
|
addr_base = 16;
|
|
}
|
|
else if (*s=='0' && s[1]=='x')
|
|
{
|
|
s += 2;
|
|
addr_base = 16;
|
|
}
|
|
else if (*s == '0')
|
|
addr_base = 8;
|
|
p = s;
|
|
while(*p)
|
|
{
|
|
if (*p++=='.')
|
|
addr_base = 10;
|
|
}
|
|
for (a=0; *s; s++)
|
|
{
|
|
d = *s;
|
|
if(isdigit(d))
|
|
a = a*addr_base + d - '0';
|
|
else if (ishex(d) && addr_base==16)
|
|
a = a*addr_base + d + 10 - 'a';
|
|
else
|
|
break;
|
|
}
|
|
|
|
if (*s == '.')
|
|
s++;
|
|
if(*s=='b')
|
|
a *= 512;
|
|
if(*s=='B')
|
|
a *= 1024;
|
|
|
|
return(a);
|
|
}
|
|
|
|
offset(a)
|
|
long a;
|
|
{
|
|
if (canseek(stdin))
|
|
{
|
|
/*
|
|
* in case we're accessing a raw disk,
|
|
* we have to seek in multiples of a physical block.
|
|
*/
|
|
fseek(stdin, a & 0xfffffe00L, 0);
|
|
a &= 0x1ffL;
|
|
}
|
|
dumbseek(stdin, a);
|
|
}
|
|
|
|
dumbseek(s, offset)
|
|
FILE *s;
|
|
long offset;
|
|
{
|
|
char buf[BUFSIZ];
|
|
int n;
|
|
int nr;
|
|
|
|
while (offset > 0)
|
|
{
|
|
nr = (offset > BUFSIZ) ? BUFSIZ : (int)offset;
|
|
if ((n = fread(buf, 1, nr, s)) != nr)
|
|
{
|
|
fprintf(stderr, "EOF\n");
|
|
exit(1);
|
|
}
|
|
offset -= n;
|
|
}
|
|
}
|
|
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
|
|
canseek(f)
|
|
FILE *f;
|
|
{
|
|
struct stat statb;
|
|
|
|
return( (fstat(fileno(f),&statb)==0) &&
|
|
(statb.st_nlink > 0) && /*!pipe*/
|
|
(!isatty(fileno(f))) );
|
|
}
|