odsyntax.c revision 1.5 1 /* $NetBSD: odsyntax.c,v 1.5 1997/01/09 20:19:58 tls Exp $ */
2
3 /*-
4 * Copyright (c) 1990 The Regents of the University of California.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by the University of
18 * California, Berkeley and its contributors.
19 * 4. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 */
35
36 #ifndef lint
37 /*static char sccsid[] = "from: @(#)odsyntax.c 5.4 (Berkeley) 3/8/91";*/
38 static char rcsid[] = "$NetBSD: odsyntax.c,v 1.5 1997/01/09 20:19:58 tls Exp $";
39 #endif /* not lint */
40
41 #include <sys/types.h>
42 #include <stdlib.h>
43 #include <stdio.h>
44 #include "hexdump.h"
45
46 int deprecated;
47
48 oldsyntax(argc, argvp)
49 int argc;
50 char ***argvp;
51 {
52 extern enum _vflag vflag;
53 extern FS *fshead;
54 extern char *optarg;
55 extern int length, optind;
56 int ch;
57 char **argv;
58 static void odprecede();
59
60 deprecated = 1;
61 argv = *argvp;
62 while ((ch = getopt(argc, argv, "aBbcDdeFfHhIiLlOoPpswvXx")) != EOF)
63 switch (ch) {
64 case 'a':
65 odprecede();
66 add("16/1 \"%3_u \" \"\\n\"");
67 break;
68 case 'B':
69 case 'o':
70 odprecede();
71 add("8/2 \" %06o \" \"\\n\"");
72 break;
73 case 'b':
74 odprecede();
75 add("16/1 \"%03o \" \"\\n\"");
76 break;
77 case 'c':
78 odprecede();
79 add("16/1 \"%3_c \" \"\\n\"");
80 break;
81 case 'd':
82 odprecede();
83 add("8/2 \" %05u \" \"\\n\"");
84 break;
85 case 'D':
86 odprecede();
87 add("4/4 \" %010u \" \"\\n\"");
88 break;
89 case 'e': /* undocumented in od */
90 case 'F':
91 odprecede();
92 add("2/8 \" %21.14e \" \"\\n\"");
93 break;
94
95 case 'f':
96 odprecede();
97 add("4/4 \" %14.7e \" \"\\n\"");
98 break;
99 case 'H':
100 case 'X':
101 odprecede();
102 add("4/4 \" %08x \" \"\\n\"");
103 break;
104 case 'h':
105 case 'x':
106 odprecede();
107 add("8/2 \" %04x \" \"\\n\"");
108 break;
109 case 'I':
110 case 'L':
111 case 'l':
112 odprecede();
113 add("4/4 \" %11d \" \"\\n\"");
114 break;
115 case 'i':
116 odprecede();
117 add("8/2 \" %6d \" \"\\n\"");
118 break;
119 case 'O':
120 odprecede();
121 add("4/4 \" %011o \" \"\\n\"");
122 break;
123 case 'v':
124 vflag = ALL;
125 break;
126 case 'P':
127 case 'p':
128 case 's':
129 case 'w':
130 case '?':
131 default:
132 (void)fprintf(stderr,
133 "od: od(1) has been deprecated for hexdump(1).\n");
134 if (ch != '?')
135 (void)fprintf(stderr,
136 "od: hexdump(1) compatibility doesn't support the -%c option%s\n",
137 ch, ch == 's' ? "; see strings(1)." : ".");
138 usage();
139 }
140
141 if (!fshead) {
142 add("\"%07.7_Ao\n\"");
143 add("\"%07.7_ao \" 8/2 \"%06o \" \"\\n\"");
144 }
145
146 argc -= optind;
147 *argvp += optind;
148
149 odoffset(argc, argvp);
150 }
151
152 #define ishexdigit(c) \
153 (c >= '0' && c <= '9' || c >= 'a' && c <= 'f' || c >= 'A' && c <= 'F')
154
155 odoffset(argc, argvp)
156 int argc;
157 char ***argvp;
158 {
159 extern off_t skip;
160 register char *num, *p;
161 int base;
162 char *end;
163
164 /*
165 * The offset syntax of od(1) was genuinely bizarre. First, if
166 * it started with a plus it had to be an offset. Otherwise, if
167 * there were at least two arguments, a number or lower-case 'x'
168 * followed by a number makes it an offset. By default it was
169 * octal; if it started with 'x' or '0x' it was hex. If it ended
170 * in a '.', it was decimal. If a 'b' or 'B' was appended, it
171 * multiplied the number by 512 or 1024 byte units. There was
172 * no way to assign a block count to a hex offset.
173 *
174 * We assumes it's a file if the offset is bad.
175 */
176 p = **argvp;
177 if (!p)
178 return;
179 if (*p != '+' && (argc < 2 ||
180 (!isdigit(p[0]) && (p[0] != 'x' || !ishexdigit(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' && ishexdigit(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; ishexdigit(*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 else {
221 if (*p) {
222 if (*p == 'b')
223 skip *= 512;
224 else if (*p == 'B')
225 skip *= 1024;
226 ++p;
227 }
228 if (*p)
229 skip = 0;
230 else {
231 ++*argvp;
232 /*
233 * If the offset uses a non-octal base, the base of
234 * the offset is changed as well. This isn't pretty,
235 * but it's easy.
236 */
237 #define TYPE_OFFSET 7
238 if (base == 16) {
239 fshead->nextfu->fmt[TYPE_OFFSET] = 'x';
240 fshead->nextfs->nextfu->fmt[TYPE_OFFSET] = 'x';
241 } else if (base == 10) {
242 fshead->nextfu->fmt[TYPE_OFFSET] = 'd';
243 fshead->nextfs->nextfu->fmt[TYPE_OFFSET] = 'd';
244 }
245 }
246 }
247 }
248
249 static void
250 odprecede()
251 {
252 static int first = 1;
253
254 if (first) {
255 first = 0;
256 add("\"%07.7_Ao\n\"");
257 add("\"%07.7_ao \"");
258 } else
259 add("\" \"");
260 }
261