1
2
3
4
5
6
7
8
9
10
11
12
13
14
15#include "libbb.h"
16#if ENABLE_DESKTOP
17
18#include "od_bloaty.c"
19#else
20
21#include "dump.h"
22
23#define isdecdigit(c) isdigit(c)
24#define ishexdigit(c) (isxdigit)(c)
25
26static void
27odoffset(dumper_t *dumper, int argc, char ***argvp)
28{
29 char *num, *p;
30 int base;
31 char *end;
32
33
34
35
36
37
38
39
40
41
42
43
44
45 p = **argvp;
46
47 if (!p) {
48
49 return;
50 }
51
52 if ((*p != '+')
53 && (argc < 2
54 || (!isdecdigit(p[0])
55 && ((p[0] != 'x') || !ishexdigit(p[1])))))
56 return;
57
58 base = 0;
59
60
61
62
63 if (p[0] == '+')
64 ++p;
65 if (p[0] == 'x' && ishexdigit(p[1])) {
66 ++p;
67 base = 16;
68 } else if (p[0] == '0' && p[1] == 'x') {
69 p += 2;
70 base = 16;
71 }
72
73
74 if (base == 16)
75 for (num = p; ishexdigit(*p); ++p)
76 continue;
77 else
78 for (num = p; isdecdigit(*p); ++p)
79 continue;
80
81
82 if (num == p)
83 return;
84
85
86 if (*p == '.') {
87 if (base)
88 return;
89 base = 10;
90 }
91
92 dumper->dump_skip = strtol(num, &end, base ? base : 8);
93
94
95 if (end != p)
96 dumper->dump_skip = 0;
97 else {
98 if (*p) {
99 if (*p == 'b') {
100 dumper->dump_skip *= 512;
101 ++p;
102 } else if (*p == 'B') {
103 dumper->dump_skip *= 1024;
104 ++p;
105 }
106 }
107 if (*p)
108 dumper->dump_skip = 0;
109 else {
110 ++*argvp;
111
112
113
114
115
116#define TYPE_OFFSET 7
117 {
118 char x_or_d;
119 if (base == 16) {
120 x_or_d = 'x';
121 goto DO_X_OR_D;
122 }
123 if (base == 10) {
124 x_or_d = 'd';
125 DO_X_OR_D:
126 dumper->fshead->nextfu->fmt[TYPE_OFFSET]
127 = dumper->fshead->nextfs->nextfu->fmt[TYPE_OFFSET]
128 = x_or_d;
129 }
130 }
131 }
132 }
133}
134
135static const char *const add_strings[] = {
136 "16/1 \"%3_u \" \"\\n\"",
137 "8/2 \" %06o \" \"\\n\"",
138 "16/1 \"%03o \" \"\\n\"",
139 "16/1 \"%3_c \" \"\\n\"",
140 "8/2 \" %05u \" \"\\n\"",
141 "4/4 \" %010u \" \"\\n\"",
142 "2/8 \" %21.14e \" \"\\n\"",
143 "4/4 \" %14.7e \" \"\\n\"",
144 "4/4 \" %08x \" \"\\n\"",
145 "8/2 \" %04x \" \"\\n\"",
146 "4/4 \" %11d \" \"\\n\"",
147 "8/2 \" %6d \" \"\\n\"",
148 "4/4 \" %011o \" \"\\n\"",
149};
150
151static const char od_opts[] ALIGN1 = "aBbcDdeFfHhIiLlOoXxv";
152
153static const char od_o2si[] ALIGN1 = {
154 0, 1, 2, 3, 5,
155 4, 6, 6, 7, 8,
156 9, 0xa, 0xb, 0xa, 0xa,
157 0xb, 1, 8, 9,
158};
159
160int od_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
161int od_main(int argc, char **argv)
162{
163 int ch;
164 int first = 1;
165 char *p;
166 dumper_t *dumper = alloc_dumper();
167
168 while ((ch = getopt(argc, argv, od_opts)) > 0) {
169 if (ch == 'v') {
170 dumper->dump_vflag = ALL;
171 } else if (((p = strchr(od_opts, ch)) != NULL) && (*p != '\0')) {
172 if (first) {
173 first = 0;
174 bb_dump_add(dumper, "\"%07.7_Ao\n\"");
175 bb_dump_add(dumper, "\"%07.7_ao \"");
176 } else {
177 bb_dump_add(dumper, "\" \"");
178 }
179 bb_dump_add(dumper, add_strings[(int)od_o2si[(p - od_opts)]]);
180 } else {
181 bb_show_usage();
182 }
183 }
184 if (!dumper->fshead) {
185 bb_dump_add(dumper, "\"%07.7_Ao\n\"");
186 bb_dump_add(dumper, "\"%07.7_ao \" 8/2 \"%06o \" \"\\n\"");
187 }
188
189 argc -= optind;
190 argv += optind;
191
192 odoffset(dumper, argc, &argv);
193
194 return bb_dump_dump(dumper, argv);
195}
196#endif
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226