4.1cBSD/usr/src/bin/od.c
static char *sccsid = "@(#)od.c 4.2 (Berkeley) 2/7/81";
/*
* od -- octal (also hex, decimal, and character) dump
*/
#include <stdio.h>
typedef unsigned long ulong;
unsigned short word[16];
unsigned short lastword[16];
short nword = 8;
int conv;
int base = 010;
int max;
ulong addr;
#define DWORD 0700 /* bitmask for double word output formats */
main(argc, argv)
char **argv;
{
register char *p;
register n, f, same;
char outbuf[BUFSIZ];
#ifdef STANDALONE
if (argv[0][0] == '\0')
argc = getargv("od", &argv, 0);
#else
setbuf(stdout, outbuf);
#endif
argv++;
f = 0;
if(argc > 1)
{
p = *argv;
if(*p == '-')
{
while(*p != '\0')
{
switch(*p++)
{
case 'o':
conv |= 001;
f = 6;
break;
case 'd':
conv |= 002;
f = 5;
break;
case 'x':
case 'h':
conv |= 010;
f = 4;
break;
case 'c':
conv |= 020;
f = 7;
break;
case 'b':
conv |= 040;
f = 7;
break;
case 'O':
conv |= 0100;
f = 6;
break;
case 'D':
conv |= 0200;
f = 5;
break;
case 'H':
case 'X':
conv |= 0400;
f = 4;
break;
case 'w':
nword = 16;
break;
}
if(f > max)
max = f;
}
argc--;
argv++;
}
}
if(!conv)
{
max = 6;
conv = 1;
}
if(argc > 1)
if(**argv != '+')
{
if (freopen(*argv, "r", stdin) == NULL)
{
fprintf(stderr, "od: cannot open %s\n", *argv);
exit(2);
}
argv++;
argc--;
}
if(argc > 1)
offset(*argv);
same = -1;
for ( ; (n = fread((char *)word, 1, sizeof(word[0])*nword, stdin)) > 0; addr += n)
{
if (same>=0)
{
for (f=0; f<nword; f++)
if (lastword[f] != word[f])
goto notsame;
if (same==0)
{
printf("*\n");
same = 1;
}
continue;
}
notsame:
line(addr, word, (n+sizeof(word[0])-1)/sizeof(word[0]));
same = 0;
for (f=0; f<nword; f++)
lastword[f] = word[f];
for (f=0; f<nword; f++)
word[f] = 0;
}
putn(addr, base, 7);
putchar('\n');
exit(0);
}
line(a, w, n)
ulong a;
unsigned short *w;
{
register i, f, c;
f = 1;
for(c=1; c; c<<=1)
{
if((c&conv) == 0)
continue;
if(f)
{
putn(a, base, 7);
putchar(' ');
f = 0;
}
else
putchar('\t');
if ( c&DWORD && conv&~DWORD )
putchar(' ');
for (i=0; i<n; i++)
{
if(c&DWORD)
{
if ((i&01) == 0)
putlx((ulong *)(w+i), c);
}
else
putx(w[i], c);
putchar(i==n-1? '\n': ' ');
}
}
}
putx(n, c)
unsigned n;
{
switch(c)
{
case 001:
pre(6);
putn((ulong)n, 8, 6);
break;
case 002:
pre(5);
putn((ulong)n, 10, 5);
break;
case 010:
pre(4);
putn((ulong)n, 16, 4);
break;
case 020:
pre(7);
{
unsigned short sn = n;
cput(*(char *)&sn);
putchar(' ');
cput(*((char *)&sn + 1));
break;
}
case 040:
pre(7);
{
unsigned short sn = n;
putn((ulong)(*(char *)&sn)&0377, 8, 3);
putchar(' ');
putn((ulong)(*((char *)&sn + 1))&0377, 8, 3);
break;
}
}
}
putlx(n, c)
ulong *n;
{
switch(c)
{
case 0100:
pre(6); pre(6);
putn(*n, 8, 12);
break;
case 0200:
pre(5); pre(5);
putn(*n, 10, 10);
break;
case 0400:
pre(4); pre(4);
putn(*n, 16, 8);
break;
}
}
cput(c)
{
c &= 0377;
if(c>037 && c<0177)
{
printf(" ");
putchar(c);
return;
}
switch(c)
{
case '\0':
printf(" \\0");
break;
case '\b':
printf(" \\b");
break;
case '\f':
printf(" \\f");
break;
case '\n':
printf(" \\n");
break;
case '\r':
printf(" \\r");
break;
case '\t':
printf(" \\t");
break;
default:
putn((ulong)c, 8, 3);
}
}
putn(n, b, c)
ulong n;
unsigned b;
{
unsigned d;
if(!c)
return;
putn(n/b, b, c-1);
d = n%b;
if (d > 9)
putchar(d-10+'a');
else
putchar(d+'0');
}
pre(n)
{
int i;
for(i=n; i<max; i++)
putchar(' ');
}
offset(s)
register char *s;
{
register char *p;
ulong a;
register int d;
if (*s=='+')
s++;
if (*s=='x')
{
s++;
base = 16;
}
else if (*s=='0' && s[1]=='x')
{
s += 2;
base = 16;
}
else if (*s == '0')
base = 8;
p = s;
while(*p)
{
if (*p++=='.')
base = 10;
}
for (a=0; *s; s++)
{
d = *s;
if(d>='0' && d<='9')
a = a*base + d - '0';
else if (d>='a' && d<='f' && base==16)
a = a*base + d + 10 - 'a';
else
break;
}
if (*s == '.')
s++;
if(*s=='b' || *s=='B')
a *= 512;
fseek(stdin, a, 0);
addr = a;
}