File: | src/usr.bin/hexdump/odsyntax.c |
Warning: | line 244, column 4 Value stored to 'y' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* $OpenBSD: odsyntax.c,v 1.28 2017/05/30 05:58:44 tedu Exp $ */ |
2 | /* $NetBSD: odsyntax.c,v 1.15 2001/12/07 15:14:29 bjh21 Exp $ */ |
3 | |
4 | /*- |
5 | * Copyright (c) 1990, 1993 |
6 | * The Regents of the University of California. All rights reserved. |
7 | * |
8 | * Redistribution and use in source and binary forms, with or without |
9 | * modification, are permitted provided that the following conditions |
10 | * are met: |
11 | * 1. Redistributions of source code must retain the above copyright |
12 | * notice, this list of conditions and the following disclaimer. |
13 | * 2. Redistributions in binary form must reproduce the above copyright |
14 | * notice, this list of conditions and the following disclaimer in the |
15 | * documentation and/or other materials provided with the distribution. |
16 | * 3. Neither the name of the University nor the names of its contributors |
17 | * may be used to endorse or promote products derived from this software |
18 | * without specific prior written permission. |
19 | * |
20 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
21 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
22 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
23 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
24 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
25 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
26 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
27 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
28 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
29 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
30 | * SUCH DAMAGE. |
31 | */ |
32 | |
33 | #include <sys/types.h> |
34 | |
35 | #include <ctype.h> |
36 | #include <err.h> |
37 | #include <stdio.h> |
38 | #include <stdlib.h> |
39 | #include <unistd.h> |
40 | |
41 | #include "hexdump.h" |
42 | |
43 | #define PADDING" " " " |
44 | |
45 | int odmode; |
46 | |
47 | static void odadd(const char *); |
48 | static void odoffset(int, char ***); |
49 | static __dead__attribute__((__noreturn__)) void oldusage(void); |
50 | static void posixtypes(char *); |
51 | |
52 | /* |
53 | * formats used for -t |
54 | */ |
55 | static const char *fmt[4][4] = { |
56 | { |
57 | "16/1 \"%3d \" \"\\n\"", |
58 | "8/2 \" %05d \" \"\\n\"", |
59 | "4/4 \" %010d \" \"\\n\"", |
60 | "2/8 \" %019d \" \"\\n\"" |
61 | }, { |
62 | "16/1 \"%03o \" \"\\n\"", |
63 | "8/2 \" %06o \" \"\\n\"", |
64 | "4/4 \" %011o\" \"\\n\"", |
65 | "2/8 \" %022o \" \"\\n\"" |
66 | }, { |
67 | "16/1 \"%03u \" \"\\n\"", |
68 | "8/2 \" %05u \" \"\\n\"", |
69 | "4/4 \" %010u \" \"\\n\"", |
70 | "2/8 \" %020u \" \"\\n\"" |
71 | }, { |
72 | "16/1 \" %02x \" \"\\n\"", |
73 | "8/2 \" %04x \" \"\\n\"", |
74 | "4/4 \" %08x \" \"\\n\"", |
75 | "2/8 \" %16x \" \"\\n\"" |
76 | } |
77 | }; |
78 | |
79 | void |
80 | oldsyntax(int argc, char ***argvp) |
81 | { |
82 | static char empty[] = "", padding[] = PADDING" "; |
83 | int ch; |
84 | char *p, **argv; |
85 | |
86 | #define TYPE_OFFSET7 7 |
87 | add("\"%07.7_Ao\n\""); |
88 | add("\"%07.7_ao \""); |
89 | |
90 | odmode = 1; |
91 | argv = *argvp; |
92 | while ((ch = getopt(argc, argv, |
93 | "A:aBbcDdeFfHhIij:LlN:Oost:vXx")) != -1) |
94 | switch (ch) { |
95 | case 'A': |
96 | switch (*optarg) { |
97 | case 'd': case 'o': case 'x': |
98 | fshead->nextfu->fmt[TYPE_OFFSET7] = *optarg; |
99 | fshead->nextfs->nextfu->fmt[TYPE_OFFSET7] = |
100 | *optarg; |
101 | break; |
102 | case 'n': |
103 | fshead->nextfu->fmt = empty; |
104 | fshead->nextfs->nextfu->fmt = padding; |
105 | break; |
106 | default: |
107 | errx(1, "%s: invalid address base", optarg); |
108 | } |
109 | break; |
110 | case 'a': |
111 | odadd("16/1 \"%3_u \" \"\\n\""); |
112 | break; |
113 | case 'B': |
114 | case 'o': |
115 | odadd("8/2 \" %06o \" \"\\n\""); |
116 | break; |
117 | case 'b': |
118 | odadd("16/1 \"%03o \" \"\\n\""); |
119 | break; |
120 | case 'c': |
121 | odadd("16/1 \"%3_c \" \"\\n\""); |
122 | break; |
123 | case 'd': |
124 | odadd("8/2 \" %05u \" \"\\n\""); |
125 | break; |
126 | case 'D': |
127 | odadd("4/4 \" %010u \" \"\\n\""); |
128 | break; |
129 | case 'e': |
130 | case 'F': |
131 | odadd("2/8 \" %21.14e \" \"\\n\""); |
132 | break; |
133 | case 'f': |
134 | odadd("4/4 \" %14.7e \" \"\\n\""); |
135 | break; |
136 | case 'H': |
137 | case 'X': |
138 | odadd("4/4 \" %08x \" \"\\n\""); |
139 | break; |
140 | case 'h': |
141 | case 'x': |
142 | odadd("8/2 \" %04x \" \"\\n\""); |
143 | break; |
144 | case 'I': |
145 | case 'L': |
146 | case 'l': |
147 | odadd("4/4 \" %11d \" \"\\n\""); |
148 | break; |
149 | case 'i': |
150 | odadd("8/2 \" %6d \" \"\\n\""); |
151 | break; |
152 | case 'j': |
153 | if ((skip = strtol(optarg, &p, 0)) < 0) |
154 | errx(1, "%s: bad skip value", optarg); |
155 | switch(*p) { |
156 | case 'b': |
157 | skip *= 512; |
158 | break; |
159 | case 'k': |
160 | skip *= 1024; |
161 | break; |
162 | case 'm': |
163 | skip *= 1048576; |
164 | break; |
165 | } |
166 | break; |
167 | case 'N': |
168 | if ((length = atoi(optarg)) < 0) |
169 | errx(1, "%s: bad length value", optarg); |
170 | break; |
171 | case 'O': |
172 | odadd("4/4 \" %011o \" \"\\n\""); |
173 | break; |
174 | case 's': |
175 | odadd("8/2 \" %05d \" \"\\n\""); |
176 | break; |
177 | case 't': |
178 | posixtypes(optarg); |
179 | break; |
180 | case 'v': |
181 | vflag = ALL; |
182 | break; |
183 | default: |
184 | oldusage(); |
185 | } |
186 | |
187 | if (fshead->nextfs->nextfs == NULL((void *)0)) |
188 | odadd(" 8/2 \"%06o \" \"\\n\""); |
189 | |
190 | argc -= optind; |
191 | *argvp += optind; |
192 | |
193 | if (argc) |
194 | odoffset(argc, argvp); |
195 | } |
196 | |
197 | /* |
198 | * Interpret a POSIX-style -t argument. |
199 | */ |
200 | static void |
201 | posixtypes(char *type_string) |
202 | { |
203 | int x, y, nbytes; |
204 | |
205 | while (*type_string) { |
206 | switch (*type_string) { |
207 | case 'a': |
208 | type_string++; |
209 | odadd("16/1 \"%3_u \" \"\\n\""); |
210 | break; |
211 | case 'c': |
212 | type_string++; |
213 | odadd("16/1 \"%3_c \" \"\\n\""); |
214 | break; |
215 | case 'f': |
216 | type_string++; |
217 | if (*type_string == 'F' || |
218 | *type_string == '4') { |
219 | type_string++; |
220 | odadd("4/4 \" %14.7e\" \"\\n\""); |
221 | } else if (*type_string == 'L' || |
222 | *type_string == '8') { |
223 | type_string++; |
224 | odadd("2/8 \" %16.14e\" \"\\n\""); |
225 | } else if (*type_string == 'D') |
226 | /* long doubles vary in size */ |
227 | oldusage(); |
228 | else |
229 | odadd("2/8 \" %16.14e\" \"\\n\""); |
230 | break; |
231 | case 'd': |
232 | x = 0; |
233 | goto extensions; |
234 | case 'o': |
235 | x = 1; |
236 | goto extensions; |
237 | case 'u': |
238 | x = 2; |
239 | goto extensions; |
240 | case 'x': |
241 | x = 3; |
242 | extensions: |
243 | type_string++; |
244 | y = 2; |
Value stored to 'y' is never read | |
245 | if (isupper((unsigned char)*type_string)) { |
246 | switch(*type_string) { |
247 | case 'C': |
248 | nbytes = sizeof(char); |
249 | break; |
250 | case 'S': |
251 | nbytes = sizeof(short); |
252 | break; |
253 | case 'I': |
254 | nbytes = sizeof(int); |
255 | break; |
256 | case 'L': |
257 | nbytes = sizeof(long); |
258 | break; |
259 | default: |
260 | warnx("Bad type-size qualifier '%c'", |
261 | *type_string); |
262 | oldusage(); |
263 | } |
264 | type_string++; |
265 | } else if (isdigit((unsigned char)*type_string)) |
266 | nbytes = strtol(type_string, &type_string, 10); |
267 | else |
268 | nbytes = 4; |
269 | |
270 | switch (nbytes) { |
271 | case 1: |
272 | y = 0; |
273 | break; |
274 | case 2: |
275 | y = 1; |
276 | break; |
277 | case 4: |
278 | y = 2; |
279 | break; |
280 | case 8: |
281 | y = 3; |
282 | break; |
283 | default: |
284 | warnx("%d-byte integer formats are not " |
285 | "supported", nbytes); |
286 | oldusage(); |
287 | } |
288 | odadd(fmt[x][y]); |
289 | break; |
290 | default: |
291 | oldusage(); |
292 | } |
293 | } |
294 | } |
295 | |
296 | static __dead__attribute__((__noreturn__)) void |
297 | oldusage(void) |
298 | { |
299 | extern char *__progname; |
300 | fprintf(stderr(&__sF[2]), "usage: %s [-aBbcDdeFfHhIiLlOosvXx] [-A base] " |
301 | "[-j offset] [-N length]\n" |
302 | "\t[-t type_string] [file ...]\n", __progname); |
303 | exit(1); |
304 | } |
305 | |
306 | static void |
307 | odoffset(int argc, char ***argvp) |
308 | { |
309 | char *num, *p; |
310 | int base; |
311 | char *end; |
312 | |
313 | /* |
314 | * The offset syntax of od(1) was genuinely bizarre. First, if |
315 | * it started with a plus it had to be an offset. Otherwise, if |
316 | * there were at least two arguments, a number or lower-case 'x' |
317 | * followed by a number makes it an offset. By default it was |
318 | * octal; if it started with 'x' or '0x' it was hex. If it ended |
319 | * in a '.', it was decimal. If a 'b' or 'B' was appended, it |
320 | * multiplied the number by 512 or 1024 byte units. There was |
321 | * no way to assign a block count to a hex offset. |
322 | * |
323 | * We assume it's a file if the offset is bad. |
324 | */ |
325 | p = argc == 1 ? (*argvp)[0] : (*argvp)[1]; |
326 | if (!p) |
327 | return; |
328 | |
329 | if (*p != '+' && (argc < 2 || |
330 | (!isdigit((unsigned char)p[0]) && |
331 | (p[0] != 'x' || !isxdigit((unsigned char)p[1]))))) |
332 | return; |
333 | |
334 | base = 0; |
335 | /* |
336 | * skip over leading '+', 'x[0-9a-fA-f]' or '0x', and |
337 | * set base. |
338 | */ |
339 | if (p[0] == '+') |
340 | ++p; |
341 | if (p[0] == 'x' && isxdigit((unsigned char)p[1])) { |
342 | ++p; |
343 | base = 16; |
344 | } else if (p[0] == '0' && p[1] == 'x') { |
345 | p += 2; |
346 | base = 16; |
347 | } |
348 | |
349 | /* skip over the number */ |
350 | if (base == 16) |
351 | for (num = p; isxdigit((unsigned char)*p); ++p); |
352 | else |
353 | for (num = p; isdigit((unsigned char)*p); ++p); |
354 | |
355 | /* check for no number */ |
356 | if (num == p) |
357 | return; |
358 | |
359 | /* if terminates with a '.', base is decimal */ |
360 | if (*p == '.') { |
361 | if (base) |
362 | return; |
363 | base = 10; |
364 | } |
365 | |
366 | skip = strtol(num, &end, base ? base : 8); |
367 | |
368 | /* if end isn't the same as p, we got a non-octal digit */ |
369 | if (end != p) { |
370 | skip = 0; |
371 | return; |
372 | } |
373 | |
374 | if (*p == '.') |
375 | ++p; |
376 | if (*p) { |
377 | if (*p == 'B') { |
378 | skip *= 1024; |
379 | ++p; |
380 | } else if (*p == 'b') { |
381 | skip *= 512; |
382 | ++p; |
383 | } |
384 | } |
385 | if (*p) { |
386 | skip = 0; |
387 | return; |
388 | } |
389 | /* |
390 | * If the offset uses a non-octal base, the base of the offset |
391 | * is changed as well. This isn't pretty, but it's easy. |
392 | */ |
393 | if (base == 16) { |
394 | fshead->nextfu->fmt[TYPE_OFFSET7] = 'x'; |
395 | fshead->nextfs->nextfu->fmt[TYPE_OFFSET7] = 'x'; |
396 | } else if (base == 10) { |
397 | fshead->nextfu->fmt[TYPE_OFFSET7] = 'd'; |
398 | fshead->nextfs->nextfu->fmt[TYPE_OFFSET7] = 'd'; |
399 | } |
400 | |
401 | /* Terminate file list. */ |
402 | (*argvp)[argc > 1] = NULL((void *)0); |
403 | } |
404 | |
405 | static void |
406 | odadd(const char *format) |
407 | { |
408 | static int needpad; |
409 | |
410 | if (needpad) |
411 | add("\""PADDING" ""\""); |
412 | add(format); |
413 | needpad = 1; |
414 | } |