xref: /original-bsd/usr.bin/hexdump/odsyntax.c (revision 331bfa8d)
1 /*-
2  * Copyright (c) 1990 The Regents of the University of California.
3  * All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  */
7 
8 #ifndef lint
9 static char sccsid[] = "@(#)odsyntax.c	5.3 (Berkeley) 09/06/90";
10 #endif /* not lint */
11 
12 #include <sys/types.h>
13 #include <stdlib.h>
14 #include <stdio.h>
15 #include "hexdump.h"
16 
17 int deprecated;
18 
19 oldsyntax(argc, argvp)
20 	int argc;
21 	char ***argvp;
22 {
23 	extern enum _vflag vflag;
24 	extern FS *fshead;
25 	extern char *optarg;
26 	extern int length, optind;
27 	int ch, first;
28 	char **argv;
29 
30 	deprecated = 1;
31 	first = 0;
32 	argv = *argvp;
33 	while ((ch = getopt(argc, argv, "aBbcDdeFfHhIiLlOoPpswvXx")) != EOF)
34 		switch (ch) {
35 		case 'a':
36 			if (!first++) {
37 				add("\"%07.7_Ao\n\"");
38 				add("\"%07.7_ao  \"");
39 			} else
40 				add("\"         \"");
41 			add("16/1 \"%3_u \" \"\\n\"");
42 			break;
43 		case 'B':
44 		case 'o':
45 			if (!first++) {
46 				add("\"%07.7_Ao\n\"");
47 				add("\"%07.7_ao  \"");
48 			} else
49 				add("\"         \"");
50 			add("8/2 \" %06o \" \"\\n\"");
51 			break;
52 		case 'b':
53 			if (!first++) {
54 				add("\"%07.7_Ao\n\"");
55 				add("\"%07.7_ao  \"");
56 			} else
57 				add("\"         \"");
58 			add("16/1 \"%03o \" \"\\n\"");
59 			break;
60 		case 'c':
61 			if (!first++) {
62 				add("\"%07.7_Ao\n\"");
63 				add("\"%07.7_ao  \"");
64 			} else
65 				add("\"         \"");
66 			add("16/1 \"%3_c \" \"\\n\"");
67 			break;
68 		case 'd':
69 			if (!first++) {
70 				add("\"%07.7_Ao\n\"");
71 				add("\"%07.7_ao  \"");
72 			} else
73 				add("\"         \"");
74 			add("8/2 \"  %05u \" \"\\n\"");
75 			break;
76 		case 'D':
77 			if (!first++) {
78 				add("\"%07.7_Ao\n\"");
79 				add("\"%07.7_ao  \"");
80 			} else
81 				add("\"         \"");
82 			add("4/4 \"     %010u \" \"\\n\"");
83 			break;
84 		case 'e':		/* undocumented in od */
85 		case 'F':
86 			if (!first++) {
87 				add("\"%07.7_Ao\n\"");
88 				add("\"%07.7_ao  \"");
89 			} else
90 				add("\"         \"");
91 			add("2/8 \"          %21.14e \" \"\\n\"");
92 			break;
93 
94 		case 'f':
95 			if (!first++) {
96 				add("\"%07.7_Ao\n\"");
97 				add("\"%07.7_ao  \"");
98 			} else
99 				add("\"         \"");
100 			add("4/4 \" %14.7e \" \"\\n\"");
101 			break;
102 		case 'H':
103 		case 'X':
104 			if (!first++) {
105 				add("\"%07.7_Ao\n\"");
106 				add("\"%07.7_ao  \"");
107 			} else
108 				add("\"         \"");
109 			add("4/4 \"       %08x \" \"\\n\"");
110 			break;
111 		case 'h':
112 		case 'x':
113 			if (!first++) {
114 				add("\"%07.7_Ao\n\"");
115 				add("\"%07.7_ao  \"");
116 			} else
117 				add("\"         \"");
118 			add("8/2 \"   %04x \" \"\\n\"");
119 			break;
120 		case 'I':
121 		case 'L':
122 		case 'l':
123 			if (!first++) {
124 				add("\"%07.7_Ao\n\"");
125 				add("\"%07.7_ao  \"");
126 			} else
127 				add("\"         \"");
128 			add("4/4 \"    %11d \" \"\\n\"");
129 			break;
130 		case 'i':
131 			if (!first++) {
132 				add("\"%07.7_Ao\n\"");
133 				add("\"%07.7_ao  \"");
134 			} else
135 				add("\"         \"");
136 			add("8/2 \" %6d \" \"\\n\"");
137 			break;
138 		case 'O':
139 			if (!first++) {
140 				add("\"%07.7_Ao\n\"");
141 				add("\"%07.7_ao  \"");
142 			} else
143 				add("\"         \"");
144 			add("4/4 \"    %011o \" \"\\n\"");
145 			break;
146 		case 'v':
147 			vflag = ALL;
148 			break;
149 		case 'P':
150 		case 'p':
151 		case 's':
152 		case 'w':
153 		case '?':
154 		default:
155 			(void)fprintf(stderr,
156 			    "od: od(1) has been deprecated for hexdump(1).\n");
157 			if (ch != '?')
158 				(void)fprintf(stderr,
159 "od: hexdump(1) compatibility doesn't support the -%c option%s\n",
160 				    ch, ch == 's' ? "; see strings(1)." : ".");
161 			usage();
162 		}
163 
164 	if (!fshead) {
165 		add("\"%07.7_Ao\n\"");
166 		add("\"%07.7_ao  \" 8/2 \"%06o \" \"\\n\"");
167 	}
168 
169 	argc -= optind;
170 	*argvp += optind;
171 
172 	odoffset(argc, argvp);
173 }
174 
175 #define	ishexdigit(c) \
176 	(c >= '0' && c <= '9' || c >= 'a' && c <= 'f' || c >= 'A' && c <= 'F')
177 
178 odoffset(argc, argvp)
179 	int argc;
180 	char ***argvp;
181 {
182 	extern off_t skip;
183 	register char *num, *p;
184 	int base;
185 	char *end;
186 
187 	/*
188 	 * The offset syntax of od(1) was genuinely bizarre.  First, if
189 	 * it started with a plus it had to be an offset.  Otherwise, if
190 	 * there were at least two arguments, a number or lower-case 'x'
191 	 * followed by a number makes it an offset.  By default it was
192 	 * octal; if it started with 'x' or '0x' it was hex.  If it ended
193 	 * in a '.', it was decimal.  If a 'b' or 'B' was appended, it
194 	 * multiplied the number by 512 or 1024 byte units.  There was
195 	 * no way to assign a block count to a hex offset.
196 	 *
197 	 * We assumes it's a file if the offset is bad.
198 	 */
199 	p = **argvp;
200 	if (*p != '+' && (argc < 2 ||
201 	    (!isdigit(p[0]) && (p[0] != 'x' || !ishexdigit(p[1])))))
202 		return;
203 
204 	base = 0;
205 	/*
206 	 * skip over leading '+', 'x[0-9a-fA-f]' or '0x', and
207 	 * set base.
208 	 */
209 	if (p[0] == '+')
210 		++p;
211 	if (p[0] == 'x' && ishexdigit(p[1])) {
212 		++p;
213 		base = 16;
214 	} else if (p[0] == '0' && p[1] == 'x') {
215 		p += 2;
216 		base = 16;
217 	}
218 
219 	/* skip over the number */
220 	if (base == 16)
221 		for (num = p; ishexdigit(*p); ++p);
222 	else
223 		for (num = p; isdigit(*p); ++p);
224 
225 	/* check for no number */
226 	if (num == p)
227 		return;
228 
229 	/* if terminates with a '.', base is decimal */
230 	if (*p == '.') {
231 		if (base)
232 			return;
233 		base = 10;
234 	}
235 
236 	skip = strtol(num, &end, base ? base : 8);
237 
238 	/* if end isn't the same as p, we got a non-octal digit */
239 	if (end != p)
240 		skip = 0;
241 	else {
242 		if (*p) {
243 			if (*p == 'b')
244 				skip *= 512;
245 			else if (*p == 'B')
246 				skip *= 1024;
247 			++p;
248 		}
249 		if (*p)
250 			skip = 0;
251 		else {
252 			++*argvp;
253 			/*
254 			 * If the offset uses a non-octal base, the base of
255 			 * the offset is changed as well.  This isn't pretty,
256 			 * but it's easy.
257 			 */
258 #define	TYPE_OFFSET	7
259 			if (base == 16) {
260 				fshead->nextfu->fmt[TYPE_OFFSET] = 'x';
261 				fshead->nextfs->nextfu->fmt[TYPE_OFFSET] = 'x';
262 			} else if (base == 10) {
263 				fshead->nextfu->fmt[TYPE_OFFSET] = 'd';
264 				fshead->nextfs->nextfu->fmt[TYPE_OFFSET] = 'd';
265 			}
266 		}
267 	}
268 }
269