odsyntax.c revision 23693
1272343Sngie/*-
2272343Sngie * Copyright (c) 1990, 1993
3272343Sngie *	The Regents of the University of California.  All rights reserved.
4272343Sngie *
5272343Sngie * Redistribution and use in source and binary forms, with or without
6272343Sngie * modification, are permitted provided that the following conditions
7272343Sngie * are met:
8272343Sngie * 1. Redistributions of source code must retain the above copyright
9272343Sngie *    notice, this list of conditions and the following disclaimer.
10272343Sngie * 2. Redistributions in binary form must reproduce the above copyright
11272343Sngie *    notice, this list of conditions and the following disclaimer in the
12272343Sngie *    documentation and/or other materials provided with the distribution.
13272343Sngie * 3. All advertising materials mentioning features or use of this software
14272343Sngie *    must display the following acknowledgement:
15272343Sngie *	This product includes software developed by the University of
16272343Sngie *	California, Berkeley and its contributors.
17272343Sngie * 4. Neither the name of the University nor the names of its contributors
18272343Sngie *    may be used to endorse or promote products derived from this software
19272343Sngie *    without specific prior written permission.
20272343Sngie *
21272343Sngie * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22272343Sngie * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23272343Sngie * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24272343Sngie * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25272343Sngie * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26272343Sngie * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27272343Sngie * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28272343Sngie * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29272343Sngie * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30272343Sngie * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31272343Sngie * SUCH DAMAGE.
32272343Sngie */
33272343Sngie
34272343Sngie#ifndef lint
35272343Sngiestatic char sccsid[] = "@(#)odsyntax.c	8.2 (Berkeley) 5/4/95";
36272343Sngie#endif /* not lint */
37272343Sngie
38272343Sngie#include <sys/types.h>
39272343Sngie
40272343Sngie#include <ctype.h>
41272343Sngie#include <stdio.h>
42272343Sngie#include <stdlib.h>
43272343Sngie#include <unistd.h>
44272343Sngie
45272343Sngie#include "hexdump.h"
46272343Sngie
47272343Sngieint deprecated;
48272343Sngie
49272343Sngiestatic void odoffset __P((int, char ***));
50272343Sngiestatic void odprecede __P((void));
51272343Sngie
52272343Sngievoid
53272343Sngieoldsyntax(argc, argvp)
54272343Sngie	int argc;
55272343Sngie	char ***argvp;
56272343Sngie{
57272343Sngie	extern enum _vflag vflag;
58272343Sngie	extern FS *fshead;
59272343Sngie	int ch;
60272343Sngie	char **argv;
61272343Sngie
62272343Sngie	deprecated = 1;
63272343Sngie	argv = *argvp;
64272343Sngie	while ((ch = getopt(argc, argv, "aBbcDdeFfHhIiLlOoPpswvXx")) != EOF)
65272343Sngie		switch (ch) {
66272343Sngie		case 'a':
67272343Sngie			odprecede();
68272343Sngie			add("16/1 \"%3_u \" \"\\n\"");
69272343Sngie			break;
70272343Sngie		case 'B':
71272343Sngie		case 'o':
72272343Sngie			odprecede();
73272343Sngie			add("8/2 \" %06o \" \"\\n\"");
74272343Sngie			break;
75272343Sngie		case 'b':
76272343Sngie			odprecede();
77272343Sngie			add("16/1 \"%03o \" \"\\n\"");
78272343Sngie			break;
79272343Sngie		case 'c':
80272343Sngie			odprecede();
81272343Sngie			add("16/1 \"%3_c \" \"\\n\"");
82272343Sngie			break;
83272343Sngie		case 'd':
84272343Sngie			odprecede();
85272343Sngie			add("8/2 \"  %05u \" \"\\n\"");
86272343Sngie			break;
87272343Sngie		case 'D':
88272343Sngie			odprecede();
89272343Sngie			add("4/4 \"     %010u \" \"\\n\"");
90272343Sngie			break;
91272343Sngie		case 'e':		/* undocumented in od */
92272343Sngie		case 'F':
93272343Sngie			odprecede();
94272343Sngie			add("2/8 \"          %21.14e \" \"\\n\"");
95272343Sngie			break;
96272343Sngie
97272343Sngie		case 'f':
98272343Sngie			odprecede();
99272343Sngie			add("4/4 \" %14.7e \" \"\\n\"");
100272343Sngie			break;
101272343Sngie		case 'H':
102272343Sngie		case 'X':
103272343Sngie			odprecede();
104272343Sngie			add("4/4 \"       %08x \" \"\\n\"");
105272343Sngie			break;
106272343Sngie		case 'h':
107272343Sngie		case 'x':
108272343Sngie			odprecede();
109272343Sngie			add("8/2 \"   %04x \" \"\\n\"");
110			break;
111		case 'I':
112		case 'L':
113		case 'l':
114			odprecede();
115			add("4/4 \"    %11d \" \"\\n\"");
116			break;
117		case 'i':
118			odprecede();
119			add("8/2 \" %6d \" \"\\n\"");
120			break;
121		case 'O':
122			odprecede();
123			add("4/4 \"    %011o \" \"\\n\"");
124			break;
125		case 'v':
126			vflag = ALL;
127			break;
128		case 'P':
129		case 'p':
130		case 's':
131		case 'w':
132		case '?':
133		default:
134			(void)fprintf(stderr,
135			    "od: od(1) has been deprecated for hexdump(1).\n");
136			if (ch != '?')
137				(void)fprintf(stderr,
138"od: hexdump(1) compatibility doesn't support the -%c option%s\n",
139				    ch, ch == 's' ? "; see strings(1)." : ".");
140			usage();
141		}
142
143	if (!fshead) {
144		add("\"%07.7_Ao\n\"");
145		add("\"%07.7_ao  \" 8/2 \"%06o \" \"\\n\"");
146	}
147
148	argc -= optind;
149	*argvp += optind;
150
151	if (argc)
152		odoffset(argc, argvp);
153}
154
155static void
156odoffset(argc, argvp)
157	int argc;
158	char ***argvp;
159{
160	extern off_t skip;
161	register char *num, *p;
162	int base;
163	char *end;
164
165	/*
166	 * The offset syntax of od(1) was genuinely bizarre.  First, if
167	 * it started with a plus it had to be an offset.  Otherwise, if
168	 * there were at least two arguments, a number or lower-case 'x'
169	 * followed by a number makes it an offset.  By default it was
170	 * octal; if it started with 'x' or '0x' it was hex.  If it ended
171	 * in a '.', it was decimal.  If a 'b' or 'B' was appended, it
172	 * multiplied the number by 512 or 1024 byte units.  There was
173	 * no way to assign a block count to a hex offset.
174	 *
175	 * We assume it's a file if the offset is bad.
176	 */
177	p = argc == 1 ? (*argvp)[0] : (*argvp)[1];
178
179	if (*p != '+' && (argc < 2 ||
180	    (!isdigit(p[0]) && (p[0] != 'x' || !isxdigit(p[1])))))
181		return;
182
183	base = 0;
184	/*
185	 * skip over leading '+', 'x[0-9a-fA-f]' or '0x', and
186	 * set base.
187	 */
188	if (p[0] == '+')
189		++p;
190	if (p[0] == 'x' && isxdigit(p[1])) {
191		++p;
192		base = 16;
193	} else if (p[0] == '0' && p[1] == 'x') {
194		p += 2;
195		base = 16;
196	}
197
198	/* skip over the number */
199	if (base == 16)
200		for (num = p; isxdigit(*p); ++p);
201	else
202		for (num = p; isdigit(*p); ++p);
203
204	/* check for no number */
205	if (num == p)
206		return;
207
208	/* if terminates with a '.', base is decimal */
209	if (*p == '.') {
210		if (base)
211			return;
212		base = 10;
213	}
214
215	skip = strtol(num, &end, base ? base : 8);
216
217	/* if end isn't the same as p, we got a non-octal digit */
218	if (end != p) {
219		skip = 0;
220		return;
221	}
222
223	if (*p)
224		if (*p == 'B') {
225			skip *= 1024;
226			++p;
227		} else if (*p == 'b') {
228			skip *= 512;
229			++p;
230		}
231
232	if (*p) {
233		skip = 0;
234		return;
235	}
236
237	/*
238	 * If the offset uses a non-octal base, the base of the offset
239	 * is changed as well.  This isn't pretty, but it's easy.
240	 */
241#define	TYPE_OFFSET	7
242	if (base == 16) {
243		fshead->nextfu->fmt[TYPE_OFFSET] = 'x';
244		fshead->nextfs->nextfu->fmt[TYPE_OFFSET] = 'x';
245	} else if (base == 10) {
246		fshead->nextfu->fmt[TYPE_OFFSET] = 'd';
247		fshead->nextfs->nextfu->fmt[TYPE_OFFSET] = 'd';
248	}
249
250	/* Terminate file list. */
251	(*argvp)[1] = NULL;
252}
253
254static void
255odprecede()
256{
257	static int first = 1;
258
259	if (first) {
260		first = 0;
261		add("\"%07.7_Ao\n\"");
262		add("\"%07.7_ao  \"");
263	} else
264		add("\"         \"");
265}
266