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