BSD 4_1_snap release
[unix-history] / usr / src / cmd / od.c
index 6fe9ddb..fdc6804 100644 (file)
@@ -1,30 +1,46 @@
-static char *sccsid = "@(#)od.c        4.1 (Berkeley) 10/1/80";
+static char *sccsid = "@(#)od.c        4.2 (Berkeley) 2/7/81";
 /*
  * od -- octal (also hex, decimal, and character) dump
  */
 
 #include <stdio.h>
 
 /*
  * od -- octal (also hex, decimal, and character) dump
  */
 
 #include <stdio.h>
 
-unsigned short word[8];
-unsigned short lastword[8];
+typedef        unsigned long   ulong;
+
+unsigned short word[16];
+unsigned short lastword[16];
+short nword =  8;
 int    conv;
 int    base =  010;
 int    max;
 int    conv;
 int    base =  010;
 int    max;
-long   addr;
+ulong  addr;
+#define        DWORD   0700    /* bitmask for double word output formats */
 
 main(argc, argv)
 char **argv;
 {
        register char *p;
        register n, f, same;
 
 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;
 
        argv++;
        f = 0;
-       if(argc > 1) {
+       if(argc > 1)
+       {
                p = *argv;
                p = *argv;
-               if(*p == '-') {
-                       while(*p != '\0') {
-                               switch(*p++) {
+               if(*p == '-')
+               {
+                       while(*p != '\0')
+                       {
+                               switch(*p++)
+                               {
                                case 'o':
                                        conv |= 001;
                                        f = 6;
                                case 'o':
                                        conv |= 001;
                                        f = 6;
@@ -46,6 +62,22 @@ char **argv;
                                        conv |= 040;
                                        f = 7;
                                        break;
                                        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;
                                }
                                if(f > max)
                                        max = f;
@@ -54,64 +86,83 @@ char **argv;
                        argv++;
                }
        }
                        argv++;
                }
        }
-       if(!conv) {
+       if(!conv)
+       {
                max = 6;
                conv = 1;
        }
        if(argc > 1)
                max = 6;
                conv = 1;
        }
        if(argc > 1)
-       if(**argv != '+') {
-               if (freopen(*argv, "r", stdin) == NULL) {
-                       printf("cannot open %s\n", *argv);
-                       exit(1);
+               if(**argv != '+')
+               {
+                       if (freopen(*argv, "r", stdin) == NULL)
+                       {
+                               fprintf(stderr, "od: cannot open %s\n", *argv);
+                               exit(2);
+                       }
+                       argv++;
+                       argc--;
                }
                }
-               argv++;
-               argc--;
-       }
        if(argc > 1)
                offset(*argv);
 
        same = -1;
        if(argc > 1)
                offset(*argv);
 
        same = -1;
-       for ( ; (n = fread((char *)word, 1, sizeof(word), stdin)) > 0; addr += n) {
-               if (same>=0) {
-                       for (f=0; f<8; f++)
+       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 (lastword[f] != word[f])
                                        goto notsame;
-                       if (same==0) {
+                       if (same==0)
+                       {
                                printf("*\n");
                                same = 1;
                        }
                        continue;
                }
                                printf("*\n");
                                same = 1;
                        }
                        continue;
                }
-       notsame:
+notsame:
                line(addr, word, (n+sizeof(word[0])-1)/sizeof(word[0]));
                same = 0;
                line(addr, word, (n+sizeof(word[0])-1)/sizeof(word[0]));
                same = 0;
-               for (f=0; f<8; f++)
+               for (f=0; f<nword; f++)
                        lastword[f] = word[f];
                        lastword[f] = word[f];
-               for (f=0; f<8; f++)
+               for (f=0; f<nword; f++)
                        word[f] = 0;
        }
        putn(addr, base, 7);
        putchar('\n');
                        word[f] = 0;
        }
        putn(addr, base, 7);
        putchar('\n');
+       exit(0);
 }
 
 line(a, w, n)
 }
 
 line(a, w, n)
-long a;
+ulong a;
 unsigned short *w;
 {
        register i, f, c;
 
        f = 1;
 unsigned short *w;
 {
        register i, f, c;
 
        f = 1;
-       for(c=1; c; c<<=1) {
+       for(c=1; c; c<<=1)
+       {
                if((c&conv) == 0)
                        continue;
                if((c&conv) == 0)
                        continue;
-               if(f) {
+               if(f)
+               {
                        putn(a, base, 7);
                        putchar(' ');
                        f = 0;
                        putn(a, base, 7);
                        putchar(' ');
                        f = 0;
-               } else
+               } 
+               else
                        putchar('\t');
                        putchar('\t');
-               for (i=0; i<n; i++) {
-                       putx(w[i], c);
+               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': ' ');
                }
        }
                        putchar(i==n-1? '\n': ' ');
                }
        }
@@ -121,18 +172,19 @@ putx(n, c)
 unsigned n;
 {
 
 unsigned n;
 {
 
-       switch(c) {
+       switch(c)
+       {
        case 001:
                pre(6);
        case 001:
                pre(6);
-               putn((long)n, 8, 6);
+               putn((ulong)n, 8, 6);
                break;
        case 002:
                pre(5);
                break;
        case 002:
                pre(5);
-               putn((long)n, 10, 5);
+               putn((ulong)n, 10, 5);
                break;
        case 010:
                pre(4);
                break;
        case 010:
                pre(4);
-               putn((long)n, 16, 4);
+               putn((ulong)n, 16, 4);
                break;
        case 020:
                pre(7);
                break;
        case 020:
                pre(7);
@@ -147,23 +199,45 @@ unsigned n;
                pre(7);
                {
                        unsigned short sn = n;
                pre(7);
                {
                        unsigned short sn = n;
-                       putn((long)(*(char *)&sn)&0377, 8, 3);
+                       putn((ulong)(*(char *)&sn)&0377, 8, 3);
                        putchar(' ');
                        putchar(' ');
-                       putn((long)(*((char *)&sn + 1))&0377, 8, 3);
+                       putn((ulong)(*((char *)&sn + 1))&0377, 8, 3);
                        break;
                }
        }
 }
 
                        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;
 cput(c)
 {
        c &= 0377;
-       if(c>037 && c<0177) {
+       if(c>037 && c<0177)
+       {
                printf("  ");
                putchar(c);
                return;
        }
                printf("  ");
                putchar(c);
                return;
        }
-       switch(c) {
+       switch(c)
+       {
        case '\0':
                printf(" \\0");
                break;
        case '\0':
                printf(" \\0");
                break;
@@ -183,14 +257,15 @@ cput(c)
                printf(" \\t");
                break;
        default:
                printf(" \\t");
                break;
        default:
-               putn((long)c, 8, 3);
+               putn((ulong)c, 8, 3);
        }
 }
 
 putn(n, b, c)
        }
 }
 
 putn(n, b, c)
-long n;
+ulong n;
+unsigned b;
 {
 {
-       register d;
+       unsigned d;
 
        if(!c)
                return;
 
        if(!c)
                return;
@@ -214,25 +289,31 @@ offset(s)
 register char *s;
 {
        register char *p;
 register char *s;
 {
        register char *p;
-       long a;
+       ulong a;
        register int d;
 
        if (*s=='+')
                s++;
        register int d;
 
        if (*s=='+')
                s++;
-       if (*s=='x') {
+       if (*s=='x')
+       {
                s++;
                base = 16;
                s++;
                base = 16;
-       } else if (*s=='0' && s[1]=='x') {
+       } 
+       else if (*s=='0' && s[1]=='x')
+       {
                s += 2;
                base = 16;
                s += 2;
                base = 16;
-       } else if (*s == '0')
+       } 
+       else if (*s == '0')
                base = 8;
        p = s;
                base = 8;
        p = s;
-       while(*p) {
+       while(*p)
+       {
                if (*p++=='.')
                        base = 10;
        }
                if (*p++=='.')
                        base = 10;
        }
-       for (a=0; *s; s++) {
+       for (a=0; *s; s++)
+       {
                d = *s;
                if(d>='0' && d<='9')
                        a = a*base + d - '0';
                d = *s;
                if(d>='0' && d<='9')
                        a = a*base + d - '0';