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