xref: /csrg-svn/usr.bin/hexdump/odsyntax.c (revision 52141)
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*52141Sbostic static char sccsid[] = "@(#)odsyntax.c	5.5 (Berkeley) 01/08/92";
1041457Sbostic #endif /* not lint */
1141457Sbostic 
1241457Sbostic #include <sys/types.h>
1345217Sbostic #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;
2747154Sbostic 	int ch;
2841457Sbostic 	char **argv;
2947154Sbostic 	static void odprecede();
3041457Sbostic 
3141457Sbostic 	deprecated = 1;
3241457Sbostic 	argv = *argvp;
3341457Sbostic 	while ((ch = getopt(argc, argv, "aBbcDdeFfHhIiLlOoPpswvXx")) != EOF)
3441457Sbostic 		switch (ch) {
3541457Sbostic 		case 'a':
3647154Sbostic 			odprecede();
3742362Sbostic 			add("16/1 \"%3_u \" \"\\n\"");
3841457Sbostic 			break;
3941457Sbostic 		case 'B':
4041457Sbostic 		case 'o':
4147154Sbostic 			odprecede();
4242362Sbostic 			add("8/2 \" %06o \" \"\\n\"");
4341457Sbostic 			break;
4441457Sbostic 		case 'b':
4547154Sbostic 			odprecede();
4642362Sbostic 			add("16/1 \"%03o \" \"\\n\"");
4741457Sbostic 			break;
4841457Sbostic 		case 'c':
4947154Sbostic 			odprecede();
5042362Sbostic 			add("16/1 \"%3_c \" \"\\n\"");
5141457Sbostic 			break;
5241457Sbostic 		case 'd':
5347154Sbostic 			odprecede();
5442362Sbostic 			add("8/2 \"  %05u \" \"\\n\"");
5541457Sbostic 			break;
5641457Sbostic 		case 'D':
5747154Sbostic 			odprecede();
5842362Sbostic 			add("4/4 \"     %010u \" \"\\n\"");
5941457Sbostic 			break;
6041457Sbostic 		case 'e':		/* undocumented in od */
6141457Sbostic 		case 'F':
6247154Sbostic 			odprecede();
6342362Sbostic 			add("2/8 \"          %21.14e \" \"\\n\"");
6441457Sbostic 			break;
6541457Sbostic 
6641457Sbostic 		case 'f':
6747154Sbostic 			odprecede();
6842362Sbostic 			add("4/4 \" %14.7e \" \"\\n\"");
6941457Sbostic 			break;
7041457Sbostic 		case 'H':
7141457Sbostic 		case 'X':
7247154Sbostic 			odprecede();
7342362Sbostic 			add("4/4 \"       %08x \" \"\\n\"");
7441457Sbostic 			break;
7541457Sbostic 		case 'h':
7641457Sbostic 		case 'x':
7747154Sbostic 			odprecede();
7842362Sbostic 			add("8/2 \"   %04x \" \"\\n\"");
7941457Sbostic 			break;
8041457Sbostic 		case 'I':
8141457Sbostic 		case 'L':
8241457Sbostic 		case 'l':
8347154Sbostic 			odprecede();
8442362Sbostic 			add("4/4 \"    %11d \" \"\\n\"");
8541457Sbostic 			break;
8641457Sbostic 		case 'i':
8747154Sbostic 			odprecede();
8842362Sbostic 			add("8/2 \" %6d \" \"\\n\"");
8941457Sbostic 			break;
9041457Sbostic 		case 'O':
9147154Sbostic 			odprecede();
9242362Sbostic 			add("4/4 \"    %011o \" \"\\n\"");
9341457Sbostic 			break;
9441457Sbostic 		case 'v':
9541457Sbostic 			vflag = ALL;
9641457Sbostic 			break;
9741457Sbostic 		case 'P':
9841457Sbostic 		case 'p':
9941457Sbostic 		case 's':
10041457Sbostic 		case 'w':
10141457Sbostic 		case '?':
10241457Sbostic 		default:
10341457Sbostic 			(void)fprintf(stderr,
10441457Sbostic 			    "od: od(1) has been deprecated for hexdump(1).\n");
10541457Sbostic 			if (ch != '?')
10641457Sbostic 				(void)fprintf(stderr,
10741457Sbostic "od: hexdump(1) compatibility doesn't support the -%c option%s\n",
10841457Sbostic 				    ch, ch == 's' ? "; see strings(1)." : ".");
10941457Sbostic 			usage();
11041457Sbostic 		}
11141457Sbostic 
11241457Sbostic 	if (!fshead) {
11341457Sbostic 		add("\"%07.7_Ao\n\"");
11441457Sbostic 		add("\"%07.7_ao  \" 8/2 \"%06o \" \"\\n\"");
11541457Sbostic 	}
11641457Sbostic 
11745217Sbostic 	argc -= optind;
11841457Sbostic 	*argvp += optind;
11945217Sbostic 
120*52141Sbostic 	if (argc)
121*52141Sbostic 		odoffset(argc, argvp);
12241457Sbostic }
12345217Sbostic 
12445217Sbostic odoffset(argc, argvp)
12545217Sbostic 	int argc;
12645217Sbostic 	char ***argvp;
12745217Sbostic {
12845217Sbostic 	extern off_t skip;
12945217Sbostic 	register char *num, *p;
13045217Sbostic 	int base;
13145217Sbostic 	char *end;
13245217Sbostic 
13345217Sbostic 	/*
13445217Sbostic 	 * The offset syntax of od(1) was genuinely bizarre.  First, if
13545217Sbostic 	 * it started with a plus it had to be an offset.  Otherwise, if
13645217Sbostic 	 * there were at least two arguments, a number or lower-case 'x'
13745217Sbostic 	 * followed by a number makes it an offset.  By default it was
13845217Sbostic 	 * octal; if it started with 'x' or '0x' it was hex.  If it ended
13945217Sbostic 	 * in a '.', it was decimal.  If a 'b' or 'B' was appended, it
14045217Sbostic 	 * multiplied the number by 512 or 1024 byte units.  There was
14145217Sbostic 	 * no way to assign a block count to a hex offset.
14245217Sbostic 	 *
143*52141Sbostic 	 * We assume it's a file if the offset is bad.
14445217Sbostic 	 */
14545217Sbostic 	p = **argvp;
14645217Sbostic 	if (*p != '+' && (argc < 2 ||
147*52141Sbostic 	    (!isdigit(p[0]) && (p[0] != 'x' || !isxdigit(p[1])))))
14845217Sbostic 		return;
14945217Sbostic 
15045217Sbostic 	base = 0;
15145217Sbostic 	/*
15245217Sbostic 	 * skip over leading '+', 'x[0-9a-fA-f]' or '0x', and
15345217Sbostic 	 * set base.
15445217Sbostic 	 */
15545217Sbostic 	if (p[0] == '+')
15645217Sbostic 		++p;
157*52141Sbostic 	if (p[0] == 'x' && isxdigit(p[1])) {
15845217Sbostic 		++p;
15945217Sbostic 		base = 16;
16045217Sbostic 	} else if (p[0] == '0' && p[1] == 'x') {
16145217Sbostic 		p += 2;
16245217Sbostic 		base = 16;
16345217Sbostic 	}
16445217Sbostic 
16545217Sbostic 	/* skip over the number */
16645217Sbostic 	if (base == 16)
167*52141Sbostic 		for (num = p; isxdigit(*p); ++p);
16845217Sbostic 	else
16945217Sbostic 		for (num = p; isdigit(*p); ++p);
17045217Sbostic 
17145217Sbostic 	/* check for no number */
17245217Sbostic 	if (num == p)
17345217Sbostic 		return;
17445217Sbostic 
17545217Sbostic 	/* if terminates with a '.', base is decimal */
17645217Sbostic 	if (*p == '.') {
17745217Sbostic 		if (base)
17845217Sbostic 			return;
17945217Sbostic 		base = 10;
18045217Sbostic 	}
18145217Sbostic 
18245217Sbostic 	skip = strtol(num, &end, base ? base : 8);
18345217Sbostic 
18445217Sbostic 	/* if end isn't the same as p, we got a non-octal digit */
18545217Sbostic 	if (end != p)
18645217Sbostic 		skip = 0;
18745217Sbostic 	else {
18845217Sbostic 		if (*p) {
18945217Sbostic 			if (*p == 'b')
19045217Sbostic 				skip *= 512;
19145217Sbostic 			else if (*p == 'B')
19245217Sbostic 				skip *= 1024;
19345217Sbostic 			++p;
19445217Sbostic 		}
19545217Sbostic 		if (*p)
19645217Sbostic 			skip = 0;
19745217Sbostic 		else {
19845217Sbostic 			++*argvp;
19945217Sbostic 			/*
20045217Sbostic 			 * If the offset uses a non-octal base, the base of
20145217Sbostic 			 * the offset is changed as well.  This isn't pretty,
20245217Sbostic 			 * but it's easy.
20345217Sbostic 			 */
20445217Sbostic #define	TYPE_OFFSET	7
20545217Sbostic 			if (base == 16) {
20645217Sbostic 				fshead->nextfu->fmt[TYPE_OFFSET] = 'x';
20745217Sbostic 				fshead->nextfs->nextfu->fmt[TYPE_OFFSET] = 'x';
20845217Sbostic 			} else if (base == 10) {
20945217Sbostic 				fshead->nextfu->fmt[TYPE_OFFSET] = 'd';
21045217Sbostic 				fshead->nextfs->nextfu->fmt[TYPE_OFFSET] = 'd';
21145217Sbostic 			}
21245217Sbostic 		}
21345217Sbostic 	}
21445217Sbostic }
21547154Sbostic 
21647154Sbostic static void
21747154Sbostic odprecede()
21847154Sbostic {
21947154Sbostic 	static int first = 1;
22047154Sbostic 
22147154Sbostic 	if (first) {
22247154Sbostic 		first = 0;
22347154Sbostic 		add("\"%07.7_Ao\n\"");
22447154Sbostic 		add("\"%07.7_ao  \"");
22547154Sbostic 	} else
22647154Sbostic 		add("\"         \"");
22747154Sbostic }
228