aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2008-07-16 11:00:16 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2008-07-16 11:00:16 +0000
commit55f7912ddaea7c21068a48841a6eb933e5f286ee (patch)
tree8e048772811061a8db2429c3ef99e8205e1de1f6
parent8ddb6410edb0c4e87b4c6b9d0887868977c8eff5 (diff)
downloadbusybox-w32-55f7912ddaea7c21068a48841a6eb933e5f286ee.tar.gz
busybox-w32-55f7912ddaea7c21068a48841a6eb933e5f286ee.tar.bz2
busybox-w32-55f7912ddaea7c21068a48841a6eb933e5f286ee.zip
libbb: get rid of statics in dump.c; code shrinks a lot too
function old new delta alloc_dumper - 26 +26 hexdump_main 600 601 +1 static.done 1 - -1 static.ateof 1 - -1 bb_dump_vflag 1 - -1 static.savp 4 - -4 static.nextfs 4 - -4 static.curp 4 - -4 exitval 4 - -4 endfu 4 - -4 bb_dump_length 4 - -4 bb_dump_fshead 4 - -4 bb_dump_blocksize 4 - -4 _argv 4 - -4 bb_dump_add 365 358 -7 savaddress 8 - -8 eaddress 8 - -8 bb_dump_skip 8 - -8 address 8 - -8 bb_dump_dump 2748 2672 -76 next 538 445 -93 ------------------------------------------------------------------------------ (add/remove: 1/16 grow/shrink: 1/3 up/down: 27/-247) Total: -220 bytes text data bss dec hex filename 789458 607 6764 796829 c289d busybox_old 789309 601 6696 796606 c27be busybox_unstripped
-rw-r--r--coreutils/od.c51
-rw-r--r--include/dump.h35
-rw-r--r--libbb/dump.c298
-rw-r--r--util-linux/hexdump.c38
4 files changed, 222 insertions, 200 deletions
diff --git a/coreutils/od.c b/coreutils/od.c
index 94a6b95df..e4179a36d 100644
--- a/coreutils/od.c
+++ b/coreutils/od.c
@@ -24,7 +24,7 @@
24#define ishexdigit(c) (isxdigit)(c) 24#define ishexdigit(c) (isxdigit)(c)
25 25
26static void 26static void
27odoffset(int argc, char ***argvp) 27odoffset(dumper_t *dumper, int argc, char ***argvp)
28{ 28{
29 char *num, *p; 29 char *num, *p;
30 int base; 30 int base;
@@ -57,7 +57,7 @@ odoffset(int argc, char ***argvp)
57 57
58 base = 0; 58 base = 0;
59 /* 59 /*
60 * bb_dump_skip over leading '+', 'x[0-9a-fA-f]' or '0x', and 60 * skip over leading '+', 'x[0-9a-fA-f]' or '0x', and
61 * set base. 61 * set base.
62 */ 62 */
63 if (p[0] == '+') 63 if (p[0] == '+')
@@ -70,11 +70,13 @@ odoffset(int argc, char ***argvp)
70 base = 16; 70 base = 16;
71 } 71 }
72 72
73 /* bb_dump_skip over the number */ 73 /* skip over the number */
74 if (base == 16) 74 if (base == 16)
75 for (num = p; ishexdigit(*p); ++p); 75 for (num = p; ishexdigit(*p); ++p)
76 continue;
76 else 77 else
77 for (num = p; isdecdigit(*p); ++p); 78 for (num = p; isdecdigit(*p); ++p)
79 continue;
78 80
79 /* check for no number */ 81 /* check for no number */
80 if (num == p) 82 if (num == p)
@@ -87,23 +89,23 @@ odoffset(int argc, char ***argvp)
87 base = 10; 89 base = 10;
88 } 90 }
89 91
90 bb_dump_skip = strtol(num, &end, base ? base : 8); 92 dumper->dump_skip = strtol(num, &end, base ? base : 8);
91 93
92 /* if end isn't the same as p, we got a non-octal digit */ 94 /* if end isn't the same as p, we got a non-octal digit */
93 if (end != p) 95 if (end != p)
94 bb_dump_skip = 0; 96 dumper->dump_skip = 0;
95 else { 97 else {
96 if (*p) { 98 if (*p) {
97 if (*p == 'b') { 99 if (*p == 'b') {
98 bb_dump_skip *= 512; 100 dumper->dump_skip *= 512;
99 ++p; 101 ++p;
100 } else if (*p == 'B') { 102 } else if (*p == 'B') {
101 bb_dump_skip *= 1024; 103 dumper->dump_skip *= 1024;
102 ++p; 104 ++p;
103 } 105 }
104 } 106 }
105 if (*p) 107 if (*p)
106 bb_dump_skip = 0; 108 dumper->dump_skip = 0;
107 else { 109 else {
108 ++*argvp; 110 ++*argvp;
109 /* 111 /*
@@ -120,9 +122,9 @@ odoffset(int argc, char ***argvp)
120 } 122 }
121 if (base == 10) { 123 if (base == 10) {
122 x_or_d = 'd'; 124 x_or_d = 'd';
123 DO_X_OR_D: 125 DO_X_OR_D:
124 bb_dump_fshead->nextfu->fmt[TYPE_OFFSET] 126 dumper->fshead->nextfu->fmt[TYPE_OFFSET]
125 = bb_dump_fshead->nextfs->nextfu->fmt[TYPE_OFFSET] 127 = dumper->fshead->nextfs->nextfu->fmt[TYPE_OFFSET]
126 = x_or_d; 128 = x_or_d;
127 } 129 }
128 } 130 }
@@ -161,36 +163,35 @@ int od_main(int argc, char **argv)
161 int ch; 163 int ch;
162 int first = 1; 164 int first = 1;
163 char *p; 165 char *p;
164 bb_dump_vflag = FIRST; 166 dumper_t *dumper = alloc_dumper();
165 bb_dump_length = -1;
166 167
167 while ((ch = getopt(argc, argv, od_opts)) > 0) { 168 while ((ch = getopt(argc, argv, od_opts)) > 0) {
168 if (ch == 'v') { 169 if (ch == 'v') {
169 bb_dump_vflag = ALL; 170 dumper->dump_vflag = ALL;
170 } else if (((p = strchr(od_opts, ch)) != NULL) && (*p != '\0')) { 171 } else if (((p = strchr(od_opts, ch)) != NULL) && (*p != '\0')) {
171 if (first) { 172 if (first) {
172 first = 0; 173 first = 0;
173 bb_dump_add("\"%07.7_Ao\n\""); 174 bb_dump_add(dumper, "\"%07.7_Ao\n\"");
174 bb_dump_add("\"%07.7_ao \""); 175 bb_dump_add(dumper, "\"%07.7_ao \"");
175 } else { 176 } else {
176 bb_dump_add("\" \""); 177 bb_dump_add(dumper, "\" \"");
177 } 178 }
178 bb_dump_add(add_strings[(int)od_o2si[(p-od_opts)]]); 179 bb_dump_add(dumper, add_strings[(int)od_o2si[(p - od_opts)]]);
179 } else { /* P, p, s, w, or other unhandled */ 180 } else { /* P, p, s, w, or other unhandled */
180 bb_show_usage(); 181 bb_show_usage();
181 } 182 }
182 } 183 }
183 if (!bb_dump_fshead) { 184 if (!dumper->fshead) {
184 bb_dump_add("\"%07.7_Ao\n\""); 185 bb_dump_add(dumper, "\"%07.7_Ao\n\"");
185 bb_dump_add("\"%07.7_ao \" 8/2 \"%06o \" \"\\n\""); 186 bb_dump_add(dumper, "\"%07.7_ao \" 8/2 \"%06o \" \"\\n\"");
186 } 187 }
187 188
188 argc -= optind; 189 argc -= optind;
189 argv += optind; 190 argv += optind;
190 191
191 odoffset(argc, &argv); 192 odoffset(dumper, argc, &argv);
192 193
193 return bb_dump_dump(argv); 194 return bb_dump_dump(dumper, argv);
194} 195}
195#endif /* ENABLE_DESKTOP */ 196#endif /* ENABLE_DESKTOP */
196 197
diff --git a/include/dump.h b/include/dump.h
index da3e66da9..44f2082b7 100644
--- a/include/dump.h
+++ b/include/dump.h
@@ -18,10 +18,10 @@
18#define F_UINT 0x200 /* %[ouXx] */ 18#define F_UINT 0x200 /* %[ouXx] */
19#define F_TEXT 0x400 /* no conversions */ 19#define F_TEXT 0x400 /* no conversions */
20 20
21enum _vflag { ALL, DUP, FIRST, WAIT }; /* -v values */ 21enum dump_vflag_t { ALL, DUP, FIRST, WAIT }; /* -v values */
22 22
23typedef struct _pr { 23typedef struct PR {
24 struct _pr *nextpr; /* next print unit */ 24 struct PR *nextpr; /* next print unit */
25 unsigned flags; /* flag values */ 25 unsigned flags; /* flag values */
26 int bcnt; /* byte count */ 26 int bcnt; /* byte count */
27 char *cchar; /* conversion character */ 27 char *cchar; /* conversion character */
@@ -29,30 +29,31 @@ typedef struct _pr {
29 char *nospace; /* no whitespace version */ 29 char *nospace; /* no whitespace version */
30} PR; 30} PR;
31 31
32typedef struct _fu { 32typedef struct FU {
33 struct _fu *nextfu; /* next format unit */ 33 struct FU *nextfu; /* next format unit */
34 struct _pr *nextpr; /* next print unit */ 34 struct PR *nextpr; /* next print unit */
35 unsigned flags; /* flag values */ 35 unsigned flags; /* flag values */
36 int reps; /* repetition count */ 36 int reps; /* repetition count */
37 int bcnt; /* byte count */ 37 int bcnt; /* byte count */
38 char *fmt; /* format string */ 38 char *fmt; /* format string */
39} FU; 39} FU;
40 40
41typedef struct _fs { /* format strings */ 41typedef struct FS { /* format strings */
42 struct _fs *nextfs; /* linked list of format strings */ 42 struct FS *nextfs; /* linked list of format strings */
43 struct _fu *nextfu; /* linked list of format units */ 43 struct FU *nextfu; /* linked list of format units */
44 int bcnt; 44 int bcnt;
45} FS; 45} FS;
46 46
47extern void bb_dump_add(const char *fmt) FAST_FUNC; 47typedef struct dumper_t {
48extern int bb_dump_dump(char **argv) FAST_FUNC; 48 off_t dump_skip; /* bytes to skip */
49extern int bb_dump_size(FS * fs) FAST_FUNC; 49 int dump_length; /* max bytes to read */
50 smallint dump_vflag; /*enum dump_vflag_t*/
51 FS *fshead;
52} dumper_t;
50 53
51extern FS *bb_dump_fshead; /* head of format strings */ 54dumper_t* alloc_dumper(void) FAST_FUNC;
52extern int bb_dump_blocksize; /* data block size */ 55extern void bb_dump_add(dumper_t *dumper, const char *fmt) FAST_FUNC;
53extern int bb_dump_length; /* max bytes to read */ 56extern int bb_dump_dump(dumper_t *dumper, char **argv) FAST_FUNC;
54extern smallint /*enum _vflag*/ bb_dump_vflag;
55extern off_t bb_dump_skip; /* bytes to skip */
56 57
57#if __GNUC_PREREQ(4,1) 58#if __GNUC_PREREQ(4,1)
58# pragma GCC visibility pop 59# pragma GCC visibility pop
diff --git a/libbb/dump.c b/libbb/dump.c
index 29c2c85ee..0d553d4d0 100644
--- a/libbb/dump.c
+++ b/libbb/dump.c
@@ -14,19 +14,6 @@
14#include "libbb.h" 14#include "libbb.h"
15#include "dump.h" 15#include "dump.h"
16 16
17FS *bb_dump_fshead; /* head of format strings */
18off_t bb_dump_skip; /* bytes to skip */
19int bb_dump_blocksize; /* data block size */
20int bb_dump_length = -1; /* max bytes to read */
21smallint /*enum _vflag*/ bb_dump_vflag = FIRST;
22
23static FU *endfu;
24static char **_argv;
25static off_t savaddress; /* saved address/offset in stream */
26static off_t eaddress; /* end address */
27static off_t address; /* address/offset in stream */
28static int exitval; /* final exit value */
29
30static const char index_str[] ALIGN1 = ".#-+ 0123456789"; 17static const char index_str[] ALIGN1 = ".#-+ 0123456789";
31 18
32static const char size_conv_str[] ALIGN1 = 19static const char size_conv_str[] ALIGN1 =
@@ -34,7 +21,36 @@ static const char size_conv_str[] ALIGN1 =
34 21
35static const char lcc[] ALIGN1 = "diouxX"; 22static const char lcc[] ALIGN1 = "diouxX";
36 23
37int FAST_FUNC bb_dump_size(FS *fs) 24
25typedef struct priv_dumper_t {
26 dumper_t pub;
27
28 char **argv;
29 FU *endfu;
30 off_t savaddress; /* saved address/offset in stream */
31 off_t eaddress; /* end address */
32 off_t address; /* address/offset in stream */
33 int blocksize;
34 smallint exitval; /* final exit value */
35
36 /* former statics */
37 smallint next__done;
38 smallint get__ateof; // = 1;
39 unsigned char *get__curp;
40 unsigned char *get__savp;
41} priv_dumper_t;
42
43dumper_t* FAST_FUNC alloc_dumper(void)
44{
45 priv_dumper_t *dumper = xzalloc(sizeof(*dumper));
46 dumper->pub.dump_length = -1;
47 dumper->pub.dump_vflag = FIRST;
48 dumper->get__ateof = 1;
49 return &dumper->pub;
50}
51
52
53static NOINLINE int bb_dump_size(FS *fs)
38{ 54{
39 FU *fu; 55 FU *fu;
40 int bcnt, cur_size; 56 int bcnt, cur_size;
@@ -52,13 +68,14 @@ int FAST_FUNC bb_dump_size(FS *fs)
52 if (*fmt != '%') 68 if (*fmt != '%')
53 continue; 69 continue;
54 /* 70 /*
55 * bb_dump_skip any special chars -- save precision in 71 * skip any special chars -- save precision in
56 * case it's a %s format. 72 * case it's a %s format.
57 */ 73 */
58 while (strchr(index_str + 1, *++fmt)); 74 while (strchr(index_str + 1, *++fmt));
59 if (*fmt == '.' && isdigit(*++fmt)) { 75 if (*fmt == '.' && isdigit(*++fmt)) {
60 prec = atoi(fmt); 76 prec = atoi(fmt);
61 while (isdigit(*++fmt)); 77 while (isdigit(*++fmt))
78 continue;
62 } 79 }
63 p = strchr(size_conv_str + 12, *fmt); 80 p = strchr(size_conv_str + 12, *fmt);
64 if (!p) { 81 if (!p) {
@@ -79,7 +96,7 @@ int FAST_FUNC bb_dump_size(FS *fs)
79 return cur_size; 96 return cur_size;
80} 97}
81 98
82static void rewrite(FS *fs) 99static void rewrite(priv_dumper_t *dumper, FS *fs)
83{ 100{
84 enum { NOTOKAY, USEBCNT, USEPREC } sokay; 101 enum { NOTOKAY, USEBCNT, USEPREC } sokay;
85 PR *pr, **nextpr = NULL; 102 PR *pr, **nextpr = NULL;
@@ -104,7 +121,7 @@ static void rewrite(FS *fs)
104 * uninitialized 1st time through. 121 * uninitialized 1st time through.
105 */ 122 */
106 123
107 /* bb_dump_skip preceding text and up to the next % sign */ 124 /* skip preceding text and up to the next % sign */
108 for (p1 = fmtp; *p1 && *p1 != '%'; ++p1) 125 for (p1 = fmtp; *p1 && *p1 != '%'; ++p1)
109 continue; 126 continue;
110 127
@@ -121,11 +138,11 @@ static void rewrite(FS *fs)
121 */ 138 */
122 if (fu->bcnt) { 139 if (fu->bcnt) {
123 sokay = USEBCNT; 140 sokay = USEBCNT;
124 /* bb_dump_skip to conversion character */ 141 /* skip to conversion character */
125 for (++p1; strchr(index_str, *p1); ++p1) 142 for (++p1; strchr(index_str, *p1); ++p1)
126 continue; 143 continue;
127 } else { 144 } else {
128 /* bb_dump_skip any special chars, field width */ 145 /* skip any special chars, field width */
129 while (strchr(index_str + 1, *++p1)) 146 while (strchr(index_str + 1, *++p1))
130 continue; 147 continue;
131 if (*p1 == '.' && isdigit(*++p1)) { 148 if (*p1 == '.' && isdigit(*++p1)) {
@@ -137,7 +154,7 @@ static void rewrite(FS *fs)
137 sokay = NOTOKAY; 154 sokay = NOTOKAY;
138 } 155 }
139 156
140 p2 = p1 + 1; /* set end pointer */ 157 p2 = p1 + 1; /* set end pointer */
141 158
142 /* 159 /*
143 * figure out the byte count for each conversion; 160 * figure out the byte count for each conversion;
@@ -198,7 +215,7 @@ static void rewrite(FS *fs)
198 ++p2; 215 ++p2;
199 switch (p1[1]) { 216 switch (p1[1]) {
200 case 'A': 217 case 'A':
201 endfu = fu; 218 dumper->endfu = fu;
202 fu->flags |= F_IGNORE; 219 fu->flags |= F_IGNORE;
203 /* FALLTHROUGH */ 220 /* FALLTHROUGH */
204 case 'a': 221 case 'a':
@@ -274,7 +291,7 @@ static void rewrite(FS *fs)
274 } 291 }
275 /* 292 /*
276 * if the format string interprets any data at all, and it's 293 * if the format string interprets any data at all, and it's
277 * not the same as the bb_dump_blocksize, and its last format unit 294 * not the same as the blocksize, and its last format unit
278 * interprets any data at all, and has no iteration count, 295 * interprets any data at all, and has no iteration count,
279 * repeat it as necessary. 296 * repeat it as necessary.
280 * 297 *
@@ -282,10 +299,10 @@ static void rewrite(FS *fs)
282 * gets output from the last iteration of the format unit. 299 * gets output from the last iteration of the format unit.
283 */ 300 */
284 for (fu = fs->nextfu;; fu = fu->nextfu) { 301 for (fu = fs->nextfu;; fu = fu->nextfu) {
285 if (!fu->nextfu && fs->bcnt < bb_dump_blocksize 302 if (!fu->nextfu && fs->bcnt < dumper->blocksize
286 && !(fu->flags & F_SETREP) && fu->bcnt 303 && !(fu->flags & F_SETREP) && fu->bcnt
287 ) { 304 ) {
288 fu->reps += (bb_dump_blocksize - fs->bcnt) / fu->bcnt; 305 fu->reps += (dumper->blocksize - fs->bcnt) / fu->bcnt;
289 } 306 }
290 if (fu->reps > 1) { 307 if (fu->reps > 1) {
291 for (pr = fu->nextpr;; pr = pr->nextpr) 308 for (pr = fu->nextpr;; pr = pr->nextpr)
@@ -301,7 +318,7 @@ static void rewrite(FS *fs)
301 } 318 }
302} 319}
303 320
304static void do_skip(const char *fname, int statok) 321static void do_skip(priv_dumper_t *dumper, const char *fname, int statok)
305{ 322{
306 struct stat sbuf; 323 struct stat sbuf;
307 324
@@ -309,125 +326,122 @@ static void do_skip(const char *fname, int statok)
309 if (fstat(STDIN_FILENO, &sbuf)) { 326 if (fstat(STDIN_FILENO, &sbuf)) {
310 bb_simple_perror_msg_and_die(fname); 327 bb_simple_perror_msg_and_die(fname);
311 } 328 }
312 if ((!(S_ISCHR(sbuf.st_mode) || 329 if (!(S_ISCHR(sbuf.st_mode) || S_ISBLK(sbuf.st_mode) || S_ISFIFO(sbuf.st_mode))
313 S_ISBLK(sbuf.st_mode) || 330 && dumper->pub.dump_skip >= sbuf.st_size
314 S_ISFIFO(sbuf.st_mode))) && bb_dump_skip >= sbuf.st_size) { 331 ) {
315 /* If bb_dump_size valid and bb_dump_skip >= size */ 332 /* If bb_dump_size valid and pub.dump_skip >= size */
316 bb_dump_skip -= sbuf.st_size; 333 dumper->pub.dump_skip -= sbuf.st_size;
317 address += sbuf.st_size; 334 dumper->address += sbuf.st_size;
318 return; 335 return;
319 } 336 }
320 } 337 }
321 if (fseek(stdin, bb_dump_skip, SEEK_SET)) { 338 if (fseek(stdin, dumper->pub.dump_skip, SEEK_SET)) {
322 bb_simple_perror_msg_and_die(fname); 339 bb_simple_perror_msg_and_die(fname);
323 } 340 }
324 savaddress = address += bb_dump_skip; 341 dumper->address += dumper->pub.dump_skip;
325 bb_dump_skip = 0; 342 dumper->savaddress = dumper->address;
343 dumper->pub.dump_skip = 0;
326} 344}
327 345
328static int next(char **argv) 346static NOINLINE int next(priv_dumper_t *dumper)
329{ 347{
330 static smallint done;
331
332 int statok; 348 int statok;
333 349
334 if (argv) {
335 _argv = argv;
336 return 1;
337 }
338 for (;;) { 350 for (;;) {
339 if (*_argv) { 351 if (*dumper->argv) {
340 if (!(freopen(*_argv, "r", stdin))) { 352 if (!(freopen(*dumper->argv, "r", stdin))) {
341 bb_simple_perror_msg(*_argv); 353 bb_simple_perror_msg(*dumper->argv);
342 exitval = 1; 354 dumper->exitval = 1;
343 ++_argv; 355 ++dumper->argv;
344 continue; 356 continue;
345 } 357 }
346 done = statok = 1; 358 dumper->next__done = statok = 1;
347 } else { 359 } else {
348 if (done) 360 if (dumper->next__done)
349 return 0; 361 return 0;
350 done = 1; 362 dumper->next__done = 1;
351 statok = 0; 363 statok = 0;
352 } 364 }
353 if (bb_dump_skip) 365 if (dumper->pub.dump_skip)
354 do_skip(statok ? *_argv : "stdin", statok); 366 do_skip(dumper, statok ? *dumper->argv : "stdin", statok);
355 if (*_argv) 367 if (*dumper->argv)
356 ++_argv; 368 ++dumper->argv;
357 if (!bb_dump_skip) 369 if (!dumper->pub.dump_skip)
358 return 1; 370 return 1;
359 } 371 }
360 /* NOTREACHED */ 372 /* NOTREACHED */
361} 373}
362 374
363static unsigned char *get(void) 375static unsigned char *get(priv_dumper_t *dumper)
364{ 376{
365 static smallint ateof = 1;
366 static unsigned char *curp = NULL, *savp; /*DBU:[dave@cray.com]initialize curp */
367
368 int n; 377 int n;
369 int need, nread; 378 int need, nread;
370 unsigned char *tmpp; 379 unsigned char *tmpp;
380 int blocksize = dumper->blocksize;
371 381
372 if (!curp) { 382 if (!dumper->get__curp) {
373 address = (off_t)0; /*DBU:[dave@cray.com] initialize,initialize..*/ 383 dumper->address = (off_t)0; /*DBU:[dave@cray.com] initialize,initialize..*/
374 curp = xmalloc(bb_dump_blocksize); 384 dumper->get__curp = xmalloc(blocksize);
375 savp = xmalloc(bb_dump_blocksize); 385 dumper->get__savp = xmalloc(blocksize);
376 } else { 386 } else {
377 tmpp = curp; 387 tmpp = dumper->get__curp;
378 curp = savp; 388 dumper->get__curp = dumper->get__savp;
379 savp = tmpp; 389 dumper->get__savp = tmpp;
380 address = savaddress += bb_dump_blocksize; 390 dumper->savaddress += blocksize;
391 dumper->address = dumper->savaddress;
381 } 392 }
382 for (need = bb_dump_blocksize, nread = 0;;) { 393 need = blocksize;
394 nread = 0;
395 while (1) {
383 /* 396 /*
384 * if read the right number of bytes, or at EOF for one file, 397 * if read the right number of bytes, or at EOF for one file,
385 * and no other files are available, zero-pad the rest of the 398 * and no other files are available, zero-pad the rest of the
386 * block and set the end flag. 399 * block and set the end flag.
387 */ 400 */
388 if (!bb_dump_length || (ateof && !next(NULL))) { 401 if (!dumper->pub.dump_length || (dumper->get__ateof && !next(dumper))) {
389 if (need == bb_dump_blocksize) { 402 if (need == blocksize) {
390 return NULL; 403 return NULL;
391 } 404 }
392 if (bb_dump_vflag != ALL && !memcmp(curp, savp, nread)) { 405 if (dumper->pub.dump_vflag != ALL && !memcmp(dumper->get__curp, dumper->get__savp, nread)) {
393 if (bb_dump_vflag != DUP) { 406 if (dumper->pub.dump_vflag != DUP) {
394 puts("*"); 407 puts("*");
395 } 408 }
396 return NULL; 409 return NULL;
397 } 410 }
398 memset(curp + nread, 0, need); 411 memset(dumper->get__curp + nread, 0, need);
399 eaddress = address + nread; 412 dumper->eaddress = dumper->address + nread;
400 return curp; 413 return dumper->get__curp;
401 } 414 }
402 n = fread(curp + nread, sizeof(unsigned char), 415 n = fread(dumper->get__curp + nread, sizeof(unsigned char),
403 bb_dump_length == -1 ? need : MIN(bb_dump_length, need), stdin); 416 dumper->pub.dump_length == -1 ? need : MIN(dumper->pub.dump_length, need), stdin);
404 if (!n) { 417 if (!n) {
405 if (ferror(stdin)) { 418 if (ferror(stdin)) {
406 bb_simple_perror_msg(_argv[-1]); 419 bb_simple_perror_msg(dumper->argv[-1]);
407 } 420 }
408 ateof = 1; 421 dumper->get__ateof = 1;
409 continue; 422 continue;
410 } 423 }
411 ateof = 0; 424 dumper->get__ateof = 0;
412 if (bb_dump_length != -1) { 425 if (dumper->pub.dump_length != -1) {
413 bb_dump_length -= n; 426 dumper->pub.dump_length -= n;
414 } 427 }
415 need -= n; 428 need -= n;
416 if (!need) { 429 if (!need) {
417 if (bb_dump_vflag == ALL || bb_dump_vflag == FIRST 430 if (dumper->pub.dump_vflag == ALL || dumper->pub.dump_vflag == FIRST
418 || memcmp(curp, savp, bb_dump_blocksize) 431 || memcmp(dumper->get__curp, dumper->get__savp, blocksize)
419 ) { 432 ) {
420 if (bb_dump_vflag == DUP || bb_dump_vflag == FIRST) { 433 if (dumper->pub.dump_vflag == DUP || dumper->pub.dump_vflag == FIRST) {
421 bb_dump_vflag = WAIT; 434 dumper->pub.dump_vflag = WAIT;
422 } 435 }
423 return curp; 436 return dumper->get__curp;
424 } 437 }
425 if (bb_dump_vflag == WAIT) { 438 if (dumper->pub.dump_vflag == WAIT) {
426 puts("*"); 439 puts("*");
427 } 440 }
428 bb_dump_vflag = DUP; 441 dumper->pub.dump_vflag = DUP;
429 address = savaddress += bb_dump_blocksize; 442 dumper->savaddress += blocksize;
430 need = bb_dump_blocksize; 443 dumper->address = dumper->savaddress;
444 need = blocksize;
431 nread = 0; 445 nread = 0;
432 } else { 446 } else {
433 nread += n; 447 nread += n;
@@ -515,29 +529,31 @@ static void conv_u(PR *pr, unsigned char *p)
515 } 529 }
516} 530}
517 531
518static void display(void) 532static void display(priv_dumper_t* dumper)
519{ 533{
520/* extern FU *endfu; */
521 FS *fs; 534 FS *fs;
522 FU *fu; 535 FU *fu;
523 PR *pr; 536 PR *pr;
524 int cnt; 537 int cnt;
525 unsigned char *bp; 538 unsigned char *bp, *savebp;
526 off_t saveaddress; 539 off_t saveaddress;
527 unsigned char savech = 0, *savebp; 540 unsigned char savech = '\0';
528 541
529 while ((bp = get()) != NULL) { 542 while ((bp = get(dumper)) != NULL) {
530 for (fs = bb_dump_fshead, savebp = bp, saveaddress = address; fs; 543 fs = dumper->pub.fshead;
531 fs = fs->nextfs, bp = savebp, address = saveaddress) { 544 savebp = bp;
545 saveaddress = dumper->address;
546 for (; fs; fs = fs->nextfs, bp = savebp, dumper->address = saveaddress) {
532 for (fu = fs->nextfu; fu; fu = fu->nextfu) { 547 for (fu = fs->nextfu; fu; fu = fu->nextfu) {
533 if (fu->flags & F_IGNORE) { 548 if (fu->flags & F_IGNORE) {
534 break; 549 break;
535 } 550 }
536 for (cnt = fu->reps; cnt; --cnt) { 551 for (cnt = fu->reps; cnt; --cnt) {
537 for (pr = fu->nextpr; pr; address += pr->bcnt, 552 for (pr = fu->nextpr; pr; dumper->address += pr->bcnt,
538 bp += pr->bcnt, pr = pr->nextpr) { 553 bp += pr->bcnt, pr = pr->nextpr) {
539 if (eaddress && address >= eaddress && 554 if (dumper->eaddress && dumper->address >= dumper->eaddress
540 !(pr->flags & (F_TEXT | F_BPAD))) { 555 && !(pr->flags & (F_TEXT | F_BPAD))
556 ) {
541 bpad(pr); 557 bpad(pr);
542 } 558 }
543 if (cnt == 1 && pr->nospace) { 559 if (cnt == 1 && pr->nospace) {
@@ -547,7 +563,7 @@ static void display(void)
547/* PRINT; */ 563/* PRINT; */
548 switch (pr->flags) { 564 switch (pr->flags) {
549 case F_ADDRESS: 565 case F_ADDRESS:
550 printf(pr->fmt, (unsigned) address); 566 printf(pr->fmt, (unsigned) dumper->address);
551 break; 567 break;
552 case F_BPAD: 568 case F_BPAD:
553 printf(pr->fmt, ""); 569 printf(pr->fmt, "");
@@ -558,7 +574,7 @@ static void display(void)
558 case F_CHAR: 574 case F_CHAR:
559 printf(pr->fmt, *bp); 575 printf(pr->fmt, *bp);
560 break; 576 break;
561 case F_DBL:{ 577 case F_DBL: {
562 double dval; 578 double dval;
563 float fval; 579 float fval;
564 580
@@ -574,7 +590,7 @@ static void display(void)
574 } 590 }
575 break; 591 break;
576 } 592 }
577 case F_INT:{ 593 case F_INT: {
578 int ival; 594 int ival;
579 short sval; 595 short sval;
580 596
@@ -605,7 +621,7 @@ static void display(void)
605 case F_U: 621 case F_U:
606 conv_u(pr, bp); 622 conv_u(pr, bp);
607 break; 623 break;
608 case F_UINT:{ 624 case F_UINT: {
609 unsigned ival; 625 unsigned ival;
610 unsigned short sval; 626 unsigned short sval;
611 627
@@ -633,21 +649,21 @@ static void display(void)
633 } 649 }
634 } 650 }
635 } 651 }
636 if (endfu) { 652 if (dumper->endfu) {
637 /* 653 /*
638 * if eaddress not set, error or file bb_dump_size was multiple of 654 * if eaddress not set, error or file size was multiple
639 * bb_dump_blocksize, and no partial block ever found. 655 * of blocksize, and no partial block ever found.
640 */ 656 */
641 if (!eaddress) { 657 if (!dumper->eaddress) {
642 if (!address) { 658 if (!dumper->address) {
643 return; 659 return;
644 } 660 }
645 eaddress = address; 661 dumper->eaddress = dumper->address;
646 } 662 }
647 for (pr = endfu->nextpr; pr; pr = pr->nextpr) { 663 for (pr = dumper->endfu->nextpr; pr; pr = pr->nextpr) {
648 switch (pr->flags) { 664 switch (pr->flags) {
649 case F_ADDRESS: 665 case F_ADDRESS:
650 printf(pr->fmt, (unsigned) eaddress); 666 printf(pr->fmt, (unsigned) dumper->eaddress);
651 break; 667 break;
652 case F_TEXT: 668 case F_TEXT:
653 printf(pr->fmt); 669 printf(pr->fmt);
@@ -657,52 +673,58 @@ static void display(void)
657 } 673 }
658} 674}
659 675
660int FAST_FUNC bb_dump_dump(char **argv) 676#define dumper ((priv_dumper_t*)pub_dumper)
677int FAST_FUNC bb_dump_dump(dumper_t *pub_dumper, char **argv)
661{ 678{
662 FS *tfs; 679 FS *tfs;
680 int blocksize;
663 681
664 /* figure out the data block bb_dump_size */ 682 /* figure out the data block bb_dump_size */
665 for (bb_dump_blocksize = 0, tfs = bb_dump_fshead; tfs; tfs = tfs->nextfs) { 683 blocksize = 0;
684 tfs = dumper->pub.fshead;
685 while (tfs) {
666 tfs->bcnt = bb_dump_size(tfs); 686 tfs->bcnt = bb_dump_size(tfs);
667 if (bb_dump_blocksize < tfs->bcnt) { 687 if (blocksize < tfs->bcnt) {
668 bb_dump_blocksize = tfs->bcnt; 688 blocksize = tfs->bcnt;
669 } 689 }
690 tfs = tfs->nextfs;
670 } 691 }
692 dumper->blocksize = blocksize;
693
671 /* rewrite the rules, do syntax checking */ 694 /* rewrite the rules, do syntax checking */
672 for (tfs = bb_dump_fshead; tfs; tfs = tfs->nextfs) { 695 for (tfs = dumper->pub.fshead; tfs; tfs = tfs->nextfs) {
673 rewrite(tfs); 696 rewrite(dumper, tfs);
674 } 697 }
675 698
676 next(argv); 699 dumper->argv = argv;
677 display(); 700 display(dumper);
678 701
679 return exitval; 702 return dumper->exitval;
680} 703}
681 704
682void FAST_FUNC bb_dump_add(const char *fmt) 705void FAST_FUNC bb_dump_add(dumper_t* pub_dumper, const char *fmt)
683{ 706{
684 static FS **nextfs;
685
686 const char *p; 707 const char *p;
687 char *p1; 708 char *p1;
688 char *p2; 709 char *p2;
689 FS *tfs; 710 FS *tfs;
690 FU *tfu, **nextfu; 711 FU *tfu, **nextfupp;
691 const char *savep; 712 const char *savep;
692 713
693 /* start new linked list of format units */ 714 /* start new linked list of format units */
694 tfs = xzalloc(sizeof(FS)); /*DBU:[dave@cray.com] start out NULL */ 715 tfs = xzalloc(sizeof(FS)); /*DBU:[dave@cray.com] start out NULL */
695 if (!bb_dump_fshead) { 716 if (!dumper->pub.fshead) {
696 bb_dump_fshead = tfs; 717 dumper->pub.fshead = tfs;
697 } else { 718 } else {
698 *nextfs = tfs; 719 FS *fslast = dumper->pub.fshead;
720 while (fslast->nextfs)
721 fslast = fslast->nextfs;
722 fslast->nextfs = tfs;
699 } 723 }
700 nextfs = &tfs->nextfs; 724 nextfupp = &tfs->nextfu;
701 nextfu = &tfs->nextfu;
702 725
703 /* take the format string and break it up into format units */ 726 /* take the format string and break it up into format units */
704 for (p = fmt;;) { 727 for (p = fmt;;) {
705 /* bb_dump_skip leading white space */
706 p = skip_whitespace(p); 728 p = skip_whitespace(p);
707 if (!*p) { 729 if (!*p) {
708 break; 730 break;
@@ -712,8 +734,8 @@ void FAST_FUNC bb_dump_add(const char *fmt)
712 /* NOSTRICT */ 734 /* NOSTRICT */
713 /* DBU:[dave@cray.com] zalloc so that forward pointers start out NULL */ 735 /* DBU:[dave@cray.com] zalloc so that forward pointers start out NULL */
714 tfu = xzalloc(sizeof(FU)); 736 tfu = xzalloc(sizeof(FU));
715 *nextfu = tfu; 737 *nextfupp = tfu;
716 nextfu = &tfu->nextfu; 738 nextfupp = &tfu->nextfu;
717 tfu->reps = 1; 739 tfu->reps = 1;
718 740
719 /* if leading digit, repetition count */ 741 /* if leading digit, repetition count */
@@ -726,11 +748,11 @@ void FAST_FUNC bb_dump_add(const char *fmt)
726 /* may overwrite either white space or slash */ 748 /* may overwrite either white space or slash */
727 tfu->reps = atoi(savep); 749 tfu->reps = atoi(savep);
728 tfu->flags = F_SETREP; 750 tfu->flags = F_SETREP;
729 /* bb_dump_skip trailing white space */ 751 /* skip trailing white space */
730 p = skip_whitespace(++p); 752 p = skip_whitespace(++p);
731 } 753 }
732 754
733 /* bb_dump_skip slash and trailing white space */ 755 /* skip slash and trailing white space */
734 if (*p == '/') { 756 if (*p == '/') {
735 p = skip_whitespace(++p); 757 p = skip_whitespace(++p);
736 } 758 }
@@ -745,7 +767,7 @@ void FAST_FUNC bb_dump_add(const char *fmt)
745 bb_error_msg_and_die("bad format {%s}", fmt); 767 bb_error_msg_and_die("bad format {%s}", fmt);
746 } 768 }
747 tfu->bcnt = atoi(savep); 769 tfu->bcnt = atoi(savep);
748 /* bb_dump_skip trailing white space */ 770 /* skip trailing white space */
749 p = skip_whitespace(++p); 771 p = skip_whitespace(++p);
750 } 772 }
751 773
diff --git a/util-linux/hexdump.c b/util-linux/hexdump.c
index 7630153e7..4d2b0592b 100644
--- a/util-linux/hexdump.c
+++ b/util-linux/hexdump.c
@@ -15,7 +15,7 @@
15/* This is a NOEXEC applet. Be very careful! */ 15/* This is a NOEXEC applet. Be very careful! */
16 16
17 17
18static void bb_dump_addfile(char *name) 18static void bb_dump_addfile(dumper_t *dumper, char *name)
19{ 19{
20 char *p; 20 char *p;
21 FILE *fp; 21 FILE *fp;
@@ -27,7 +27,7 @@ static void bb_dump_addfile(char *name)
27 p = skip_whitespace(buf); 27 p = skip_whitespace(buf);
28 28
29 if (*p && (*p != '#')) { 29 if (*p && (*p != '#')) {
30 bb_dump_add(p); 30 bb_dump_add(dumper, p);
31 } 31 }
32 free(buf); 32 free(buf);
33 } 33 }
@@ -56,6 +56,7 @@ static const struct suffix_mult suffixes[] = {
56int hexdump_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 56int hexdump_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
57int hexdump_main(int argc, char **argv) 57int hexdump_main(int argc, char **argv)
58{ 58{
59 dumper_t *dumper = alloc_dumper();
59 const char *p; 60 const char *p;
60 int ch; 61 int ch;
61#if ENABLE_FEATURE_HEXDUMP_REVERSE 62#if ENABLE_FEATURE_HEXDUMP_REVERSE
@@ -63,9 +64,6 @@ int hexdump_main(int argc, char **argv)
63 smallint rdump = 0; 64 smallint rdump = 0;
64#endif 65#endif
65 66
66 bb_dump_vflag = FIRST;
67 bb_dump_length = -1;
68
69 if (ENABLE_HD && !applet_name[2]) { /* we are "hd" */ 67 if (ENABLE_HD && !applet_name[2]) { /* we are "hd" */
70 ch = 'C'; 68 ch = 'C';
71 goto hd_applet; 69 goto hd_applet;
@@ -78,30 +76,30 @@ int hexdump_main(int argc, char **argv)
78 if (!p) 76 if (!p)
79 bb_show_usage(); 77 bb_show_usage();
80 if ((p - hexdump_opts) < 5) { 78 if ((p - hexdump_opts) < 5) {
81 bb_dump_add(add_first); 79 bb_dump_add(dumper, add_first);
82 bb_dump_add(add_strings[(int)(p - hexdump_opts)]); 80 bb_dump_add(dumper, add_strings[(int)(p - hexdump_opts)]);
83 } 81 }
84 /* Save a little bit of space below by omitting the 'else's. */ 82 /* Save a little bit of space below by omitting the 'else's. */
85 if (ch == 'C') { 83 if (ch == 'C') {
86 hd_applet: 84 hd_applet:
87 bb_dump_add("\"%08.8_Ax\n\""); 85 bb_dump_add(dumper, "\"%08.8_Ax\n\"");
88 bb_dump_add("\"%08.8_ax \" 8/1 \"%02x \" \" \" 8/1 \"%02x \" "); 86 bb_dump_add(dumper, "\"%08.8_ax \" 8/1 \"%02x \" \" \" 8/1 \"%02x \" ");
89 bb_dump_add("\" |\" 16/1 \"%_p\" \"|\\n\""); 87 bb_dump_add(dumper, "\" |\" 16/1 \"%_p\" \"|\\n\"");
90 } 88 }
91 if (ch == 'e') { 89 if (ch == 'e') {
92 bb_dump_add(optarg); 90 bb_dump_add(dumper, optarg);
93 } /* else */ 91 } /* else */
94 if (ch == 'f') { 92 if (ch == 'f') {
95 bb_dump_addfile(optarg); 93 bb_dump_addfile(dumper, optarg);
96 } /* else */ 94 } /* else */
97 if (ch == 'n') { 95 if (ch == 'n') {
98 bb_dump_length = xatoi_u(optarg); 96 dumper->dump_length = xatoi_u(optarg);
99 } /* else */ 97 } /* else */
100 if (ch == 's') { 98 if (ch == 's') {
101 bb_dump_skip = xatoul_range_sfx(optarg, 0, LONG_MAX, suffixes); 99 dumper->dump_skip = xatoul_range_sfx(optarg, 0, LONG_MAX, suffixes);
102 } /* else */ 100 } /* else */
103 if (ch == 'v') { 101 if (ch == 'v') {
104 bb_dump_vflag = ALL; 102 dumper->dump_vflag = ALL;
105 } 103 }
106#if ENABLE_FEATURE_HEXDUMP_REVERSE 104#if ENABLE_FEATURE_HEXDUMP_REVERSE
107 if (ch == 'R') { 105 if (ch == 'R') {
@@ -110,18 +108,18 @@ int hexdump_main(int argc, char **argv)
110#endif 108#endif
111 } 109 }
112 110
113 if (!bb_dump_fshead) { 111 if (!dumper->fshead) {
114 bb_dump_add(add_first); 112 bb_dump_add(dumper, add_first);
115 bb_dump_add("\"%07.7_ax \" 8/2 \"%04x \" \"\\n\""); 113 bb_dump_add(dumper, "\"%07.7_ax \" 8/2 \"%04x \" \"\\n\"");
116 } 114 }
117 115
118 argv += optind; 116 argv += optind;
119 117
120#if !ENABLE_FEATURE_HEXDUMP_REVERSE 118#if !ENABLE_FEATURE_HEXDUMP_REVERSE
121 return bb_dump_dump(argv); 119 return bb_dump_dump(dumper, argv);
122#else 120#else
123 if (!rdump) { 121 if (!rdump) {
124 return bb_dump_dump(argv); 122 return bb_dump_dump(dumper, argv);
125 } 123 }
126 124
127 /* -R: reverse of 'hexdump -Cv' */ 125 /* -R: reverse of 'hexdump -Cv' */