BSD 4 release
[unix-history] / usr / src / cmd / od.c
CommitLineData
31cef89c 1static char *sccsid = "@(#)od.c 4.1 (Berkeley) 10/1/80";
9c79dca0
BJ
2/*
3 * od -- octal (also hex, decimal, and character) dump
4 */
5
6#include <stdio.h>
7
8unsigned short word[8];
9unsigned short lastword[8];
10int conv;
11int base = 010;
12int max;
13long addr;
14
15main(argc, argv)
16char **argv;
17{
18 register char *p;
19 register n, f, same;
20
9c79dca0
BJ
21 argv++;
22 f = 0;
23 if(argc > 1) {
24 p = *argv;
25 if(*p == '-') {
26 while(*p != '\0') {
27 switch(*p++) {
28 case 'o':
29 conv |= 001;
30 f = 6;
31 break;
32 case 'd':
33 conv |= 002;
34 f = 5;
35 break;
36 case 'x':
37 case 'h':
38 conv |= 010;
39 f = 4;
40 break;
41 case 'c':
42 conv |= 020;
43 f = 7;
44 break;
45 case 'b':
46 conv |= 040;
47 f = 7;
48 break;
49 }
50 if(f > max)
51 max = f;
52 }
53 argc--;
54 argv++;
55 }
56 }
57 if(!conv) {
58 max = 6;
59 conv = 1;
60 }
61 if(argc > 1)
62 if(**argv != '+') {
63 if (freopen(*argv, "r", stdin) == NULL) {
64 printf("cannot open %s\n", *argv);
65 exit(1);
66 }
67 argv++;
68 argc--;
69 }
70 if(argc > 1)
71 offset(*argv);
72
73 same = -1;
74 for ( ; (n = fread((char *)word, 1, sizeof(word), stdin)) > 0; addr += n) {
75 if (same>=0) {
76 for (f=0; f<8; f++)
77 if (lastword[f] != word[f])
78 goto notsame;
79 if (same==0) {
80 printf("*\n");
81 same = 1;
82 }
83 continue;
84 }
85 notsame:
86 line(addr, word, (n+sizeof(word[0])-1)/sizeof(word[0]));
87 same = 0;
88 for (f=0; f<8; f++)
89 lastword[f] = word[f];
90 for (f=0; f<8; f++)
91 word[f] = 0;
92 }
93 putn(addr, base, 7);
94 putchar('\n');
95}
96
97line(a, w, n)
98long a;
99unsigned short *w;
100{
101 register i, f, c;
102
103 f = 1;
104 for(c=1; c; c<<=1) {
105 if((c&conv) == 0)
106 continue;
107 if(f) {
108 putn(a, base, 7);
109 putchar(' ');
110 f = 0;
111 } else
112 putchar('\t');
113 for (i=0; i<n; i++) {
114 putx(w[i], c);
115 putchar(i==n-1? '\n': ' ');
116 }
117 }
118}
119
120putx(n, c)
121unsigned n;
122{
123
124 switch(c) {
125 case 001:
126 pre(6);
127 putn((long)n, 8, 6);
128 break;
129 case 002:
130 pre(5);
131 putn((long)n, 10, 5);
132 break;
133 case 010:
134 pre(4);
135 putn((long)n, 16, 4);
136 break;
137 case 020:
138 pre(7);
139 {
140 unsigned short sn = n;
141 cput(*(char *)&sn);
142 putchar(' ');
143 cput(*((char *)&sn + 1));
144 break;
145 }
146 case 040:
147 pre(7);
148 {
149 unsigned short sn = n;
150 putn((long)(*(char *)&sn)&0377, 8, 3);
151 putchar(' ');
152 putn((long)(*((char *)&sn + 1))&0377, 8, 3);
153 break;
154 }
155 }
156}
157
158cput(c)
159{
160 c &= 0377;
161 if(c>037 && c<0177) {
162 printf(" ");
163 putchar(c);
164 return;
165 }
166 switch(c) {
167 case '\0':
168 printf(" \\0");
169 break;
170 case '\b':
171 printf(" \\b");
172 break;
173 case '\f':
174 printf(" \\f");
175 break;
176 case '\n':
177 printf(" \\n");
178 break;
179 case '\r':
180 printf(" \\r");
181 break;
182 case '\t':
183 printf(" \\t");
184 break;
185 default:
186 putn((long)c, 8, 3);
187 }
188}
189
190putn(n, b, c)
191long n;
192{
193 register d;
194
195 if(!c)
196 return;
197 putn(n/b, b, c-1);
198 d = n%b;
199 if (d > 9)
200 putchar(d-10+'a');
201 else
202 putchar(d+'0');
203}
204
205pre(n)
206{
207 int i;
208
209 for(i=n; i<max; i++)
210 putchar(' ');
211}
212
213offset(s)
214register char *s;
215{
216 register char *p;
217 long a;
218 register int d;
219
220 if (*s=='+')
221 s++;
222 if (*s=='x') {
223 s++;
224 base = 16;
225 } else if (*s=='0' && s[1]=='x') {
226 s += 2;
227 base = 16;
228 } else if (*s == '0')
229 base = 8;
230 p = s;
231 while(*p) {
232 if (*p++=='.')
233 base = 10;
234 }
235 for (a=0; *s; s++) {
236 d = *s;
237 if(d>='0' && d<='9')
238 a = a*base + d - '0';
239 else if (d>='a' && d<='f' && base==16)
240 a = a*base + d + 10 - 'a';
241 else
242 break;
243 }
244 if (*s == '.')
245 s++;
246 if(*s=='b' || *s=='B')
247 a *= 512;
248 fseek(stdin, a, 0);
249 addr = a;
250}