odsyntax.c revision 1.1.1.2 1 /*-
2 * Copyright (c) 1990, 1993
3 * The Regents of the University of California. 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[] = "@(#)odsyntax.c 8.2 (Berkeley) 5/4/95";
36 #endif /* not lint */
37
38 #include <sys/types.h>
39
40 #include <ctype.h>
41 #include <stdio.h>
42 #include <stdlib.h>
43 #include <unistd.h>
44
45 #include "hexdump.h"
46
47 int deprecated;
48
49 static void odoffset __P((int, char ***));
50 static void odprecede __P((void));
51
52 void
53 oldsyntax(argc, argvp)
54 int argc;
55 char ***argvp;
56 {
57 extern enum _vflag vflag;
58 extern FS *fshead;
59 int ch;
60 char **argv;
61
62 deprecated = 1;
63 argv = *argvp;
64 while ((ch = getopt(argc, argv, "aBbcDdeFfHhIiLlOoPpswvXx")) != EOF)
65 switch (ch) {
66 case 'a':
67 odprecede();
68 add("16/1 \"%3_u \" \"\\n\"");
69 break;
70 case 'B':
71 case 'o':
72 odprecede();
73 add("8/2 \" %06o \" \"\\n\"");
74 break;
75 case 'b':
76 odprecede();
77 add("16/1 \"%03o \" \"\\n\"");
78 break;
79 case 'c':
80 odprecede();
81 add("16/1 \"%3_c \" \"\\n\"");
82 break;
83 case 'd':
84 odprecede();
85 add("8/2 \" %05u \" \"\\n\"");
86 break;
87 case 'D':
88 odprecede();
89 add("4/4 \" %010u \" \"\\n\"");
90 break;
91 case 'e': /* undocumented in od */
92 case 'F':
93 odprecede();
94 add("2/8 \" %21.14e \" \"\\n\"");
95 break;
96
97 case 'f':
98 odprecede();
99 add("4/4 \" %14.7e \" \"\\n\"");
100 break;
101 case 'H':
102 case 'X':
103 odprecede();
104 add("4/4 \" %08x \" \"\\n\"");
105 break;
106 case 'h':
107 case 'x':
108 odprecede();
109 add("8/2 \" %04x \" \"\\n\"");
110 break;
111 case 'I':
112 case 'L':
113 case 'l':
114 odprecede();
115 add("4/4 \" %11d \" \"\\n\"");
116 break;
117 case 'i':
118 odprecede();
119 add("8/2 \" %6d \" \"\\n\"");
120 break;
121 case 'O':
122 odprecede();
123 add("4/4 \" %011o \" \"\\n\"");
124 break;
125 case 'v':
126 vflag = ALL;
127 break;
128 case 'P':
129 case 'p':
130 case 's':
131 case 'w':
132 case '?':
133 default:
134 (void)fprintf(stderr,
135 "od: od(1) has been deprecated for hexdump(1).\n");
136 if (ch != '?')
137 (void)fprintf(stderr,
138 "od: hexdump(1) compatibility doesn't support the -%c option%s\n",
139 ch, ch == 's' ? "; see strings(1)." : ".");
140 usage();
141 }
142
143 if (!fshead) {
144 add("\"%07.7_Ao\n\"");
145 add("\"%07.7_ao \" 8/2 \"%06o \" \"\\n\"");
146 }
147
148 argc -= optind;
149 *argvp += optind;
150
151 if (argc)
152 odoffset(argc, argvp);
153 }
154
155 static void
156 odoffset(argc, argvp)
157 int argc;
158 char ***argvp;
159 {
160 extern off_t skip;
161 register char *num, *p;
162 int base;
163 char *end;
164
165 /*
166 * The offset syntax of od(1) was genuinely bizarre. First, if
167 * it started with a plus it had to be an offset. Otherwise, if
168 * there were at least two arguments, a number or lower-case 'x'
169 * followed by a number makes it an offset. By default it was
170 * octal; if it started with 'x' or '0x' it was hex. If it ended
171 * in a '.', it was decimal. If a 'b' or 'B' was appended, it
172 * multiplied the number by 512 or 1024 byte units. There was
173 * no way to assign a block count to a hex offset.
174 *
175 * We assume it's a file if the offset is bad.
176 */
177 p = argc == 1 ? (*argvp)[0] : (*argvp)[1];
178
179 if (*p != '+' && (argc < 2 ||
180 (!isdigit(p[0]) && (p[0] != 'x' || !isxdigit(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' && isxdigit(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; isxdigit(*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 return;
221 }
222
223 if (*p)
224 if (*p == 'B') {
225 skip *= 1024;
226 ++p;
227 } else if (*p == 'b') {
228 skip *= 512;
229 ++p;
230 }
231
232 if (*p) {
233 skip = 0;
234 return;
235 }
236
237 /*
238 * If the offset uses a non-octal base, the base of the offset
239 * is changed as well. This isn't pretty, but it's easy.
240 */
241 #define TYPE_OFFSET 7
242 if (base == 16) {
243 fshead->nextfu->fmt[TYPE_OFFSET] = 'x';
244 fshead->nextfs->nextfu->fmt[TYPE_OFFSET] = 'x';
245 } else if (base == 10) {
246 fshead->nextfu->fmt[TYPE_OFFSET] = 'd';
247 fshead->nextfs->nextfu->fmt[TYPE_OFFSET] = 'd';
248 }
249
250 /* Terminate file list. */
251 (*argvp)[1] = NULL;
252 }
253
254 static void
255 odprecede()
256 {
257 static int first = 1;
258
259 if (first) {
260 first = 0;
261 add("\"%07.7_Ao\n\"");
262 add("\"%07.7_ao \"");
263 } else
264 add("\" \"");
265 }
266