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