xref: /csrg-svn/usr.bin/hexdump/odsyntax.c (revision 45217)
141457Sbostic /*-
241457Sbostic  * Copyright (c) 1990 The Regents of the University of California.
341457Sbostic  * All rights reserved.
441457Sbostic  *
541457Sbostic  * %sccs.include.redist.c%
641457Sbostic  */
741457Sbostic 
841457Sbostic #ifndef lint
9*45217Sbostic static char sccsid[] = "@(#)odsyntax.c	5.3 (Berkeley) 09/06/90";
1041457Sbostic #endif /* not lint */
1141457Sbostic 
1241457Sbostic #include <sys/types.h>
13*45217Sbostic #include <stdlib.h>
1441457Sbostic #include <stdio.h>
1541457Sbostic #include "hexdump.h"
1641457Sbostic 
1741457Sbostic int deprecated;
1841457Sbostic 
1941457Sbostic oldsyntax(argc, argvp)
2041457Sbostic 	int argc;
2141457Sbostic 	char ***argvp;
2241457Sbostic {
2341457Sbostic 	extern enum _vflag vflag;
2441457Sbostic 	extern FS *fshead;
2541457Sbostic 	extern char *optarg;
2641457Sbostic 	extern int length, optind;
2742362Sbostic 	int ch, first;
2841457Sbostic 	char **argv;
2941457Sbostic 
3041457Sbostic 	deprecated = 1;
3142362Sbostic 	first = 0;
3241457Sbostic 	argv = *argvp;
3341457Sbostic 	while ((ch = getopt(argc, argv, "aBbcDdeFfHhIiLlOoPpswvXx")) != EOF)
3441457Sbostic 		switch (ch) {
3541457Sbostic 		case 'a':
3642362Sbostic 			if (!first++) {
3742362Sbostic 				add("\"%07.7_Ao\n\"");
3842362Sbostic 				add("\"%07.7_ao  \"");
3942362Sbostic 			} else
4042362Sbostic 				add("\"         \"");
4142362Sbostic 			add("16/1 \"%3_u \" \"\\n\"");
4241457Sbostic 			break;
4341457Sbostic 		case 'B':
4441457Sbostic 		case 'o':
4542362Sbostic 			if (!first++) {
4642362Sbostic 				add("\"%07.7_Ao\n\"");
4742362Sbostic 				add("\"%07.7_ao  \"");
4842362Sbostic 			} else
4942362Sbostic 				add("\"         \"");
5042362Sbostic 			add("8/2 \" %06o \" \"\\n\"");
5141457Sbostic 			break;
5241457Sbostic 		case 'b':
5342362Sbostic 			if (!first++) {
5442362Sbostic 				add("\"%07.7_Ao\n\"");
5542362Sbostic 				add("\"%07.7_ao  \"");
5642362Sbostic 			} else
5742362Sbostic 				add("\"         \"");
5842362Sbostic 			add("16/1 \"%03o \" \"\\n\"");
5941457Sbostic 			break;
6041457Sbostic 		case 'c':
6142362Sbostic 			if (!first++) {
6242362Sbostic 				add("\"%07.7_Ao\n\"");
6342362Sbostic 				add("\"%07.7_ao  \"");
6442362Sbostic 			} else
6542362Sbostic 				add("\"         \"");
6642362Sbostic 			add("16/1 \"%3_c \" \"\\n\"");
6741457Sbostic 			break;
6841457Sbostic 		case 'd':
6942362Sbostic 			if (!first++) {
7042362Sbostic 				add("\"%07.7_Ao\n\"");
7142362Sbostic 				add("\"%07.7_ao  \"");
7242362Sbostic 			} else
7342362Sbostic 				add("\"         \"");
7442362Sbostic 			add("8/2 \"  %05u \" \"\\n\"");
7541457Sbostic 			break;
7641457Sbostic 		case 'D':
7742362Sbostic 			if (!first++) {
7842362Sbostic 				add("\"%07.7_Ao\n\"");
7942362Sbostic 				add("\"%07.7_ao  \"");
8042362Sbostic 			} else
8142362Sbostic 				add("\"         \"");
8242362Sbostic 			add("4/4 \"     %010u \" \"\\n\"");
8341457Sbostic 			break;
8441457Sbostic 		case 'e':		/* undocumented in od */
8541457Sbostic 		case 'F':
8642362Sbostic 			if (!first++) {
8742362Sbostic 				add("\"%07.7_Ao\n\"");
8842362Sbostic 				add("\"%07.7_ao  \"");
8942362Sbostic 			} else
9042362Sbostic 				add("\"         \"");
9142362Sbostic 			add("2/8 \"          %21.14e \" \"\\n\"");
9241457Sbostic 			break;
9341457Sbostic 
9441457Sbostic 		case 'f':
9542362Sbostic 			if (!first++) {
9642362Sbostic 				add("\"%07.7_Ao\n\"");
9742362Sbostic 				add("\"%07.7_ao  \"");
9842362Sbostic 			} else
9942362Sbostic 				add("\"         \"");
10042362Sbostic 			add("4/4 \" %14.7e \" \"\\n\"");
10141457Sbostic 			break;
10241457Sbostic 		case 'H':
10341457Sbostic 		case 'X':
10442362Sbostic 			if (!first++) {
10542362Sbostic 				add("\"%07.7_Ao\n\"");
10642362Sbostic 				add("\"%07.7_ao  \"");
10742362Sbostic 			} else
10842362Sbostic 				add("\"         \"");
10942362Sbostic 			add("4/4 \"       %08x \" \"\\n\"");
11041457Sbostic 			break;
11141457Sbostic 		case 'h':
11241457Sbostic 		case 'x':
11342362Sbostic 			if (!first++) {
11442362Sbostic 				add("\"%07.7_Ao\n\"");
11542362Sbostic 				add("\"%07.7_ao  \"");
11642362Sbostic 			} else
11742362Sbostic 				add("\"         \"");
11842362Sbostic 			add("8/2 \"   %04x \" \"\\n\"");
11941457Sbostic 			break;
12041457Sbostic 		case 'I':
12141457Sbostic 		case 'L':
12241457Sbostic 		case 'l':
12342362Sbostic 			if (!first++) {
12442362Sbostic 				add("\"%07.7_Ao\n\"");
12542362Sbostic 				add("\"%07.7_ao  \"");
12642362Sbostic 			} else
12742362Sbostic 				add("\"         \"");
12842362Sbostic 			add("4/4 \"    %11d \" \"\\n\"");
12941457Sbostic 			break;
13041457Sbostic 		case 'i':
13142362Sbostic 			if (!first++) {
13242362Sbostic 				add("\"%07.7_Ao\n\"");
13342362Sbostic 				add("\"%07.7_ao  \"");
13442362Sbostic 			} else
13542362Sbostic 				add("\"         \"");
13642362Sbostic 			add("8/2 \" %6d \" \"\\n\"");
13741457Sbostic 			break;
13841457Sbostic 		case 'O':
13942362Sbostic 			if (!first++) {
14042362Sbostic 				add("\"%07.7_Ao\n\"");
14142362Sbostic 				add("\"%07.7_ao  \"");
14242362Sbostic 			} else
14342362Sbostic 				add("\"         \"");
14442362Sbostic 			add("4/4 \"    %011o \" \"\\n\"");
14541457Sbostic 			break;
14641457Sbostic 		case 'v':
14741457Sbostic 			vflag = ALL;
14841457Sbostic 			break;
14941457Sbostic 		case 'P':
15041457Sbostic 		case 'p':
15141457Sbostic 		case 's':
15241457Sbostic 		case 'w':
15341457Sbostic 		case '?':
15441457Sbostic 		default:
15541457Sbostic 			(void)fprintf(stderr,
15641457Sbostic 			    "od: od(1) has been deprecated for hexdump(1).\n");
15741457Sbostic 			if (ch != '?')
15841457Sbostic 				(void)fprintf(stderr,
15941457Sbostic "od: hexdump(1) compatibility doesn't support the -%c option%s\n",
16041457Sbostic 				    ch, ch == 's' ? "; see strings(1)." : ".");
16141457Sbostic 			usage();
16241457Sbostic 		}
16341457Sbostic 
16441457Sbostic 	if (!fshead) {
16541457Sbostic 		add("\"%07.7_Ao\n\"");
16641457Sbostic 		add("\"%07.7_ao  \" 8/2 \"%06o \" \"\\n\"");
16741457Sbostic 	}
16841457Sbostic 
169*45217Sbostic 	argc -= optind;
17041457Sbostic 	*argvp += optind;
171*45217Sbostic 
172*45217Sbostic 	odoffset(argc, argvp);
17341457Sbostic }
174*45217Sbostic 
175*45217Sbostic #define	ishexdigit(c) \
176*45217Sbostic 	(c >= '0' && c <= '9' || c >= 'a' && c <= 'f' || c >= 'A' && c <= 'F')
177*45217Sbostic 
178*45217Sbostic odoffset(argc, argvp)
179*45217Sbostic 	int argc;
180*45217Sbostic 	char ***argvp;
181*45217Sbostic {
182*45217Sbostic 	extern off_t skip;
183*45217Sbostic 	register char *num, *p;
184*45217Sbostic 	int base;
185*45217Sbostic 	char *end;
186*45217Sbostic 
187*45217Sbostic 	/*
188*45217Sbostic 	 * The offset syntax of od(1) was genuinely bizarre.  First, if
189*45217Sbostic 	 * it started with a plus it had to be an offset.  Otherwise, if
190*45217Sbostic 	 * there were at least two arguments, a number or lower-case 'x'
191*45217Sbostic 	 * followed by a number makes it an offset.  By default it was
192*45217Sbostic 	 * octal; if it started with 'x' or '0x' it was hex.  If it ended
193*45217Sbostic 	 * in a '.', it was decimal.  If a 'b' or 'B' was appended, it
194*45217Sbostic 	 * multiplied the number by 512 or 1024 byte units.  There was
195*45217Sbostic 	 * no way to assign a block count to a hex offset.
196*45217Sbostic 	 *
197*45217Sbostic 	 * We assumes it's a file if the offset is bad.
198*45217Sbostic 	 */
199*45217Sbostic 	p = **argvp;
200*45217Sbostic 	if (*p != '+' && (argc < 2 ||
201*45217Sbostic 	    (!isdigit(p[0]) && (p[0] != 'x' || !ishexdigit(p[1])))))
202*45217Sbostic 		return;
203*45217Sbostic 
204*45217Sbostic 	base = 0;
205*45217Sbostic 	/*
206*45217Sbostic 	 * skip over leading '+', 'x[0-9a-fA-f]' or '0x', and
207*45217Sbostic 	 * set base.
208*45217Sbostic 	 */
209*45217Sbostic 	if (p[0] == '+')
210*45217Sbostic 		++p;
211*45217Sbostic 	if (p[0] == 'x' && ishexdigit(p[1])) {
212*45217Sbostic 		++p;
213*45217Sbostic 		base = 16;
214*45217Sbostic 	} else if (p[0] == '0' && p[1] == 'x') {
215*45217Sbostic 		p += 2;
216*45217Sbostic 		base = 16;
217*45217Sbostic 	}
218*45217Sbostic 
219*45217Sbostic 	/* skip over the number */
220*45217Sbostic 	if (base == 16)
221*45217Sbostic 		for (num = p; ishexdigit(*p); ++p);
222*45217Sbostic 	else
223*45217Sbostic 		for (num = p; isdigit(*p); ++p);
224*45217Sbostic 
225*45217Sbostic 	/* check for no number */
226*45217Sbostic 	if (num == p)
227*45217Sbostic 		return;
228*45217Sbostic 
229*45217Sbostic 	/* if terminates with a '.', base is decimal */
230*45217Sbostic 	if (*p == '.') {
231*45217Sbostic 		if (base)
232*45217Sbostic 			return;
233*45217Sbostic 		base = 10;
234*45217Sbostic 	}
235*45217Sbostic 
236*45217Sbostic 	skip = strtol(num, &end, base ? base : 8);
237*45217Sbostic 
238*45217Sbostic 	/* if end isn't the same as p, we got a non-octal digit */
239*45217Sbostic 	if (end != p)
240*45217Sbostic 		skip = 0;
241*45217Sbostic 	else {
242*45217Sbostic 		if (*p) {
243*45217Sbostic 			if (*p == 'b')
244*45217Sbostic 				skip *= 512;
245*45217Sbostic 			else if (*p == 'B')
246*45217Sbostic 				skip *= 1024;
247*45217Sbostic 			++p;
248*45217Sbostic 		}
249*45217Sbostic 		if (*p)
250*45217Sbostic 			skip = 0;
251*45217Sbostic 		else {
252*45217Sbostic 			++*argvp;
253*45217Sbostic 			/*
254*45217Sbostic 			 * If the offset uses a non-octal base, the base of
255*45217Sbostic 			 * the offset is changed as well.  This isn't pretty,
256*45217Sbostic 			 * but it's easy.
257*45217Sbostic 			 */
258*45217Sbostic #define	TYPE_OFFSET	7
259*45217Sbostic 			if (base == 16) {
260*45217Sbostic 				fshead->nextfu->fmt[TYPE_OFFSET] = 'x';
261*45217Sbostic 				fshead->nextfs->nextfu->fmt[TYPE_OFFSET] = 'x';
262*45217Sbostic 			} else if (base == 10) {
263*45217Sbostic 				fshead->nextfu->fmt[TYPE_OFFSET] = 'd';
264*45217Sbostic 				fshead->nextfs->nextfu->fmt[TYPE_OFFSET] = 'd';
265*45217Sbostic 			}
266*45217Sbostic 		}
267*45217Sbostic 	}
268*45217Sbostic }
269