diff options
Diffstat (limited to 'coreutils/od.c')
-rw-r--r-- | coreutils/od.c | 203 |
1 files changed, 81 insertions, 122 deletions
diff --git a/coreutils/od.c b/coreutils/od.c index 6187cadf2..5eaaf5024 100644 --- a/coreutils/od.c +++ b/coreutils/od.c | |||
@@ -23,22 +23,18 @@ | |||
23 | */ | 23 | */ |
24 | 24 | ||
25 | #include <ctype.h> | 25 | #include <ctype.h> |
26 | #include <string.h> | ||
26 | #include <getopt.h> | 27 | #include <getopt.h> |
27 | #include <stdlib.h> | 28 | #include <stdlib.h> |
28 | #include "dump.h" | ||
29 | #include "busybox.h" | 29 | #include "busybox.h" |
30 | #include "dump.h" | ||
30 | 31 | ||
31 | extern FS *fshead; /* head of format strings */ | 32 | #define isdecdigit(c) (isdigit)(c) |
32 | extern int blocksize; /* data block size */ | 33 | #define ishexdigit(c) (isxdigit)(c) |
33 | extern int length; /* max bytes to read */ | ||
34 | |||
35 | #define ishexdigit(c) \ | ||
36 | ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')) | ||
37 | 34 | ||
38 | static void | 35 | static void |
39 | odoffset(int argc, char ***argvp) | 36 | odoffset(int argc, char ***argvp) |
40 | { | 37 | { |
41 | extern off_t skip; | ||
42 | register char *num, *p; | 38 | register char *num, *p; |
43 | int base; | 39 | int base; |
44 | char *end; | 40 | char *end; |
@@ -62,13 +58,15 @@ odoffset(int argc, char ***argvp) | |||
62 | return; | 58 | return; |
63 | } | 59 | } |
64 | 60 | ||
65 | if (*p != '+' && (argc < 2 || | 61 | if ((*p != '+') |
66 | (!isdigit(p[0]) && (p[0] != 'x' || !ishexdigit(p[1]))))) | 62 | && (argc < 2 |
63 | || (!isdecdigit(p[0]) | ||
64 | && ((p[0] != 'x') || !ishexdigit(p[1]))))) | ||
67 | return; | 65 | return; |
68 | 66 | ||
69 | base = 0; | 67 | base = 0; |
70 | /* | 68 | /* |
71 | * skip over leading '+', 'x[0-9a-fA-f]' or '0x', and | 69 | * bb_dump_skip over leading '+', 'x[0-9a-fA-f]' or '0x', and |
72 | * set base. | 70 | * set base. |
73 | */ | 71 | */ |
74 | if (p[0] == '+') | 72 | if (p[0] == '+') |
@@ -81,11 +79,11 @@ odoffset(int argc, char ***argvp) | |||
81 | base = 16; | 79 | base = 16; |
82 | } | 80 | } |
83 | 81 | ||
84 | /* skip over the number */ | 82 | /* bb_dump_skip over the number */ |
85 | if (base == 16) | 83 | if (base == 16) |
86 | for (num = p; ishexdigit(*p); ++p); | 84 | for (num = p; ishexdigit(*p); ++p); |
87 | else | 85 | else |
88 | for (num = p; isdigit(*p); ++p); | 86 | for (num = p; isdecdigit(*p); ++p); |
89 | 87 | ||
90 | /* check for no number */ | 88 | /* check for no number */ |
91 | if (num == p) | 89 | if (num == p) |
@@ -98,21 +96,23 @@ odoffset(int argc, char ***argvp) | |||
98 | base = 10; | 96 | base = 10; |
99 | } | 97 | } |
100 | 98 | ||
101 | skip = strtol(num, &end, base ? base : 8); | 99 | bb_dump_skip = strtol(num, &end, base ? base : 8); |
102 | 100 | ||
103 | /* if end isn't the same as p, we got a non-octal digit */ | 101 | /* if end isn't the same as p, we got a non-octal digit */ |
104 | if (end != p) | 102 | if (end != p) |
105 | skip = 0; | 103 | bb_dump_skip = 0; |
106 | else { | 104 | else { |
107 | if (*p) { | 105 | if (*p) { |
108 | if (*p == 'b') | 106 | if (*p == 'b') { |
109 | skip *= 512; | 107 | bb_dump_skip *= 512; |
110 | else if (*p == 'B') | 108 | ++p; |
111 | skip *= 1024; | 109 | } else if (*p == 'B') { |
112 | ++p; | 110 | bb_dump_skip *= 1024; |
111 | ++p; | ||
112 | } | ||
113 | } | 113 | } |
114 | if (*p) | 114 | if (*p) |
115 | skip = 0; | 115 | bb_dump_skip = 0; |
116 | else { | 116 | else { |
117 | ++*argvp; | 117 | ++*argvp; |
118 | /* | 118 | /* |
@@ -121,117 +121,76 @@ odoffset(int argc, char ***argvp) | |||
121 | * but it's easy. | 121 | * but it's easy. |
122 | */ | 122 | */ |
123 | #define TYPE_OFFSET 7 | 123 | #define TYPE_OFFSET 7 |
124 | if (base == 16) { | 124 | { |
125 | fshead->nextfu->fmt[TYPE_OFFSET] = 'x'; | 125 | char x_or_d; |
126 | fshead->nextfs->nextfu->fmt[TYPE_OFFSET] = 'x'; | 126 | if (base == 16) { |
127 | } else if (base == 10) { | 127 | x_or_d = 'x'; |
128 | fshead->nextfu->fmt[TYPE_OFFSET] = 'd'; | 128 | goto DO_X_OR_D; |
129 | fshead->nextfs->nextfu->fmt[TYPE_OFFSET] = 'd'; | 129 | } |
130 | if (base == 10) { | ||
131 | x_or_d = 'd'; | ||
132 | DO_X_OR_D: | ||
133 | bb_dump_fshead->nextfu->fmt[TYPE_OFFSET] | ||
134 | = bb_dump_fshead->nextfs->nextfu->fmt[TYPE_OFFSET] | ||
135 | = x_or_d; | ||
136 | } | ||
130 | } | 137 | } |
131 | } | 138 | } |
132 | } | 139 | } |
133 | } | 140 | } |
134 | 141 | ||
135 | static void odprecede(void) | 142 | static const char * const add_strings[] = { |
136 | { | 143 | "16/1 \"%3_u \" \"\\n\"", /* a */ |
137 | static int first = 1; | 144 | "8/2 \" %06o \" \"\\n\"", /* B, o */ |
138 | 145 | "16/1 \"%03o \" \"\\n\"", /* b */ | |
139 | if (first) { | 146 | "16/1 \"%3_c \" \"\\n\"", /* c */ |
140 | first = 0; | 147 | "8/2 \" %05u \" \"\\n\"", /* d */ |
141 | add("\"%07.7_Ao\n\""); | 148 | "4/4 \" %010u \" \"\\n\"", /* D */ |
142 | add("\"%07.7_ao \""); | 149 | "2/8 \" %21.14e \" \"\\n\"", /* e (undocumented in od), F */ |
143 | } else | 150 | "4/4 \" %14.7e \" \"\\n\"", /* f */ |
144 | add("\" \""); | 151 | "4/4 \" %08x \" \"\\n\"", /* H, X */ |
145 | } | 152 | "8/2 \" %04x \" \"\\n\"", /* h, x */ |
153 | "4/4 \" %11d \" \"\\n\"", /* I, L, l */ | ||
154 | "8/2 \" %6d \" \"\\n\"", /* i */ | ||
155 | "4/4 \" %011o \" \"\\n\"", /* O */ | ||
156 | }; | ||
157 | |||
158 | static const signed char od_opts[] = "aBbcDdeFfHhIiLlOovXx"; | ||
159 | |||
160 | static const signed char od_o2si[] = { | ||
161 | 0, 1, 2, 3, 5, | ||
162 | 4, 6, 6, 7, 8, | ||
163 | 9, 0xa, 0xb, 0xa, 0xa, | ||
164 | 0xb, 1, -1, 8, 9, | ||
165 | }; | ||
146 | 166 | ||
147 | int od_main(int argc, char **argv) | 167 | int od_main(int argc, char **argv) |
148 | { | 168 | { |
149 | int ch; | 169 | int ch; |
150 | extern enum _vflag vflag; | 170 | bb_dump_vflag = FIRST; |
151 | vflag = FIRST; | 171 | bb_dump_length = -1; |
152 | length = -1; | 172 | int first = 1; |
153 | 173 | signed char *p; | |
154 | while ((ch = getopt(argc, argv, "aBbcDdeFfHhIiLlOoPpswvXx")) != EOF) | 174 | |
155 | switch (ch) { | 175 | while ((ch = getopt(argc, argv, od_opts)) > 0) { |
156 | case 'a': | 176 | if (((p = strchr(od_opts, ch)) != NULL) && (*p >= 0)) { |
157 | odprecede(); | 177 | if (first) { |
158 | add("16/1 \"%3_u \" \"\\n\""); | 178 | first = 0; |
159 | break; | 179 | bb_dump_add("\"%07.7_Ao\n\""); |
160 | case 'B': | 180 | bb_dump_add("\"%07.7_ao \""); |
161 | case 'o': | 181 | } else { |
162 | odprecede(); | 182 | bb_dump_add("\" \""); |
163 | add("8/2 \" %06o \" \"\\n\""); | ||
164 | break; | ||
165 | case 'b': | ||
166 | odprecede(); | ||
167 | add("16/1 \"%03o \" \"\\n\""); | ||
168 | break; | ||
169 | case 'c': | ||
170 | odprecede(); | ||
171 | add("16/1 \"%3_c \" \"\\n\""); | ||
172 | break; | ||
173 | case 'd': | ||
174 | odprecede(); | ||
175 | add("8/2 \" %05u \" \"\\n\""); | ||
176 | break; | ||
177 | case 'D': | ||
178 | odprecede(); | ||
179 | add("4/4 \" %010u \" \"\\n\""); | ||
180 | break; | ||
181 | case 'e': /* undocumented in od */ | ||
182 | case 'F': | ||
183 | odprecede(); | ||
184 | add("2/8 \" %21.14e \" \"\\n\""); | ||
185 | break; | ||
186 | |||
187 | case 'f': | ||
188 | odprecede(); | ||
189 | add("4/4 \" %14.7e \" \"\\n\""); | ||
190 | break; | ||
191 | case 'H': | ||
192 | case 'X': | ||
193 | odprecede(); | ||
194 | add("4/4 \" %08x \" \"\\n\""); | ||
195 | break; | ||
196 | case 'h': | ||
197 | case 'x': | ||
198 | odprecede(); | ||
199 | add("8/2 \" %04x \" \"\\n\""); | ||
200 | break; | ||
201 | case 'I': | ||
202 | case 'L': | ||
203 | case 'l': | ||
204 | odprecede(); | ||
205 | add("4/4 \" %11d \" \"\\n\""); | ||
206 | break; | ||
207 | case 'i': | ||
208 | odprecede(); | ||
209 | add("8/2 \" %6d \" \"\\n\""); | ||
210 | break; | ||
211 | case 'O': | ||
212 | odprecede(); | ||
213 | add("4/4 \" %011o \" \"\\n\""); | ||
214 | break; | ||
215 | case 'v': | ||
216 | vflag = ALL; | ||
217 | break; | ||
218 | case 'P': | ||
219 | case 'p': | ||
220 | case 's': | ||
221 | case 'w': | ||
222 | case '?': | ||
223 | default: | ||
224 | error_msg("od: od(1) has been deprecated for hexdump(1).\n"); | ||
225 | if (ch != '?') { | ||
226 | error_msg("od: hexdump(1) compatibility doesn't support the -%c option%s\n", | ||
227 | ch, ch == 's' ? "; see strings(1)." : "."); | ||
228 | } | 183 | } |
229 | show_usage(); | 184 | bb_dump_add(add_strings[od_o2si[(int)(p-od_opts)]]); |
185 | } else if (ch == 'v') { | ||
186 | bb_dump_vflag = ALL; | ||
187 | } else { /* P, p, s, w, or other unhandled */ | ||
188 | bb_show_usage(); | ||
230 | } | 189 | } |
231 | 190 | } | |
232 | if (!fshead) { | 191 | if (!bb_dump_fshead) { |
233 | add("\"%07.7_Ao\n\""); | 192 | bb_dump_add("\"%07.7_Ao\n\""); |
234 | add("\"%07.7_ao \" 8/2 \"%06o \" \"\\n\""); | 193 | bb_dump_add("\"%07.7_ao \" 8/2 \"%06o \" \"\\n\""); |
235 | } | 194 | } |
236 | 195 | ||
237 | argc -= optind; | 196 | argc -= optind; |
@@ -239,7 +198,7 @@ int od_main(int argc, char **argv) | |||
239 | 198 | ||
240 | odoffset(argc, &argv); | 199 | odoffset(argc, &argv); |
241 | 200 | ||
242 | return(dump(argv)); | 201 | return(bb_dump_dump(argv)); |
243 | } | 202 | } |
244 | 203 | ||
245 | /*- | 204 | /*- |