diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2021-06-18 00:59:17 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2021-06-18 00:59:17 +0200 |
commit | 2c436679fbb5fa38b0e7a505022a2075fab87d84 (patch) | |
tree | 01cc2527c1026abe489b48ee9e6db79a830f0473 | |
parent | 25fe2d50bd75097861db9eac8c8c9f238283ff5f (diff) | |
download | busybox-w32-2c436679fbb5fa38b0e7a505022a2075fab87d84.tar.gz busybox-w32-2c436679fbb5fa38b0e7a505022a2075fab87d84.tar.bz2 busybox-w32-2c436679fbb5fa38b0e7a505022a2075fab87d84.zip |
xxd: implement -i "C style output"
function old new delta
xxd_main 710 888 +178
.rodata 103252 103331 +79
print_C_style - 78 +78
packed_usage 33639 33652 +13
next 276 278 +2
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 4/0 up/down: 350/0) Total: 350 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | include/dump.h | 1 | ||||
-rw-r--r-- | libbb/dump.c | 29 | ||||
-rw-r--r-- | util-linux/hexdump_xxd.c | 49 |
3 files changed, 53 insertions, 26 deletions
diff --git a/include/dump.h b/include/dump.h index 54f5629a7..10fc5d900 100644 --- a/include/dump.h +++ b/include/dump.h | |||
@@ -34,6 +34,7 @@ typedef struct dumper_t { | |||
34 | smallint dump_vflag; /*enum dump_vflag_t*/ | 34 | smallint dump_vflag; /*enum dump_vflag_t*/ |
35 | FS *fshead; | 35 | FS *fshead; |
36 | const char *xxd_eofstring; | 36 | const char *xxd_eofstring; |
37 | off_t address; /* address/offset in stream */ | ||
37 | long long xxd_displayoff; | 38 | long long xxd_displayoff; |
38 | } dumper_t; | 39 | } dumper_t; |
39 | 40 | ||
diff --git a/libbb/dump.c b/libbb/dump.c index 9c16f1f94..f8bb6fd03 100644 --- a/libbb/dump.c +++ b/libbb/dump.c | |||
@@ -34,7 +34,6 @@ typedef struct priv_dumper_t { | |||
34 | FU *endfu; | 34 | FU *endfu; |
35 | off_t savaddress; /* saved address/offset in stream */ | 35 | off_t savaddress; /* saved address/offset in stream */ |
36 | off_t eaddress; /* end address */ | 36 | off_t eaddress; /* end address */ |
37 | off_t address; /* address/offset in stream */ | ||
38 | int blocksize; | 37 | int blocksize; |
39 | smallint exitval; /* final exit value */ | 38 | smallint exitval; /* final exit value */ |
40 | 39 | ||
@@ -335,14 +334,14 @@ static void do_skip(priv_dumper_t *dumper, const char *fname) | |||
335 | ) { | 334 | ) { |
336 | /* If st_size is valid and pub.dump_skip >= st_size */ | 335 | /* If st_size is valid and pub.dump_skip >= st_size */ |
337 | dumper->pub.dump_skip -= sbuf.st_size; | 336 | dumper->pub.dump_skip -= sbuf.st_size; |
338 | dumper->address += sbuf.st_size; | 337 | dumper->pub.address += sbuf.st_size; |
339 | return; | 338 | return; |
340 | } | 339 | } |
341 | if (fseeko(stdin, dumper->pub.dump_skip, SEEK_SET)) { | 340 | if (fseeko(stdin, dumper->pub.dump_skip, SEEK_SET)) { |
342 | bb_simple_perror_msg_and_die(fname); | 341 | bb_simple_perror_msg_and_die(fname); |
343 | } | 342 | } |
344 | dumper->address += dumper->pub.dump_skip; | 343 | dumper->pub.address += dumper->pub.dump_skip; |
345 | dumper->savaddress = dumper->address; | 344 | dumper->savaddress = dumper->pub.address; |
346 | dumper->pub.dump_skip = 0; | 345 | dumper->pub.dump_skip = 0; |
347 | } | 346 | } |
348 | 347 | ||
@@ -381,7 +380,7 @@ static unsigned char *get(priv_dumper_t *dumper) | |||
381 | int blocksize = dumper->blocksize; | 380 | int blocksize = dumper->blocksize; |
382 | 381 | ||
383 | if (!dumper->get__curp) { | 382 | if (!dumper->get__curp) { |
384 | dumper->address = (off_t)0; /*DBU:[dave@cray.com] initialize,initialize..*/ | 383 | dumper->pub.address = (off_t)0; /*DBU:[dave@cray.com] initialize,initialize..*/ |
385 | dumper->get__curp = xmalloc(blocksize); | 384 | dumper->get__curp = xmalloc(blocksize); |
386 | dumper->get__savp = xzalloc(blocksize); /* need to be initialized */ | 385 | dumper->get__savp = xzalloc(blocksize); /* need to be initialized */ |
387 | } else { | 386 | } else { |
@@ -389,7 +388,7 @@ static unsigned char *get(priv_dumper_t *dumper) | |||
389 | dumper->get__curp = dumper->get__savp; | 388 | dumper->get__curp = dumper->get__savp; |
390 | dumper->get__savp = tmp; | 389 | dumper->get__savp = tmp; |
391 | dumper->savaddress += blocksize; | 390 | dumper->savaddress += blocksize; |
392 | dumper->address = dumper->savaddress; | 391 | dumper->pub.address = dumper->savaddress; |
393 | } | 392 | } |
394 | need = blocksize; | 393 | need = blocksize; |
395 | nread = 0; | 394 | nread = 0; |
@@ -412,7 +411,7 @@ static unsigned char *get(priv_dumper_t *dumper) | |||
412 | } | 411 | } |
413 | } | 412 | } |
414 | memset(dumper->get__curp + nread, 0, need); | 413 | memset(dumper->get__curp + nread, 0, need); |
415 | dumper->eaddress = dumper->address + nread; | 414 | dumper->eaddress = dumper->pub.address + nread; |
416 | return dumper->get__curp; | 415 | return dumper->get__curp; |
417 | } | 416 | } |
418 | n = fread(dumper->get__curp + nread, sizeof(unsigned char), | 417 | n = fread(dumper->get__curp + nread, sizeof(unsigned char), |
@@ -444,7 +443,7 @@ static unsigned char *get(priv_dumper_t *dumper) | |||
444 | } | 443 | } |
445 | dumper->pub.dump_vflag = DUP; | 444 | dumper->pub.dump_vflag = DUP; |
446 | dumper->savaddress += blocksize; | 445 | dumper->savaddress += blocksize; |
447 | dumper->address = dumper->savaddress; | 446 | dumper->pub.address = dumper->savaddress; |
448 | need = blocksize; | 447 | need = blocksize; |
449 | nread = 0; | 448 | nread = 0; |
450 | } else { | 449 | } else { |
@@ -545,8 +544,8 @@ static void display(priv_dumper_t* dumper) | |||
545 | 544 | ||
546 | fs = dumper->pub.fshead; | 545 | fs = dumper->pub.fshead; |
547 | savebp = bp; | 546 | savebp = bp; |
548 | saveaddress = dumper->address; | 547 | saveaddress = dumper->pub.address; |
549 | for (; fs; fs = fs->nextfs, bp = savebp, dumper->address = saveaddress) { | 548 | for (; fs; fs = fs->nextfs, bp = savebp, dumper->pub.address = saveaddress) { |
550 | FU *fu; | 549 | FU *fu; |
551 | for (fu = fs->nextfu; fu; fu = fu->nextfu) { | 550 | for (fu = fs->nextfu; fu; fu = fu->nextfu) { |
552 | int cnt; | 551 | int cnt; |
@@ -555,10 +554,10 @@ static void display(priv_dumper_t* dumper) | |||
555 | } | 554 | } |
556 | for (cnt = fu->reps; cnt; --cnt) { | 555 | for (cnt = fu->reps; cnt; --cnt) { |
557 | PR *pr; | 556 | PR *pr; |
558 | for (pr = fu->nextpr; pr; dumper->address += pr->bcnt, | 557 | for (pr = fu->nextpr; pr; dumper->pub.address += pr->bcnt, |
559 | bp += pr->bcnt, pr = pr->nextpr) { | 558 | bp += pr->bcnt, pr = pr->nextpr) { |
560 | if (dumper->eaddress | 559 | if (dumper->eaddress |
561 | && dumper->address >= dumper->eaddress | 560 | && dumper->pub.address >= dumper->eaddress |
562 | ) { | 561 | ) { |
563 | if (dumper->pub.xxd_eofstring) { | 562 | if (dumper->pub.xxd_eofstring) { |
564 | /* xxd support: requested to not pad incomplete blocks */ | 563 | /* xxd support: requested to not pad incomplete blocks */ |
@@ -574,7 +573,7 @@ static void display(priv_dumper_t* dumper) | |||
574 | } | 573 | } |
575 | switch (pr->flags) { | 574 | switch (pr->flags) { |
576 | case F_ADDRESS: | 575 | case F_ADDRESS: |
577 | printf(pr->fmt, (unsigned long long) dumper->address + dumper->pub.xxd_displayoff); | 576 | printf(pr->fmt, (unsigned long long) dumper->pub.address + dumper->pub.xxd_displayoff); |
578 | break; | 577 | break; |
579 | case F_BPAD: | 578 | case F_BPAD: |
580 | printf(pr->fmt, ""); | 579 | printf(pr->fmt, ""); |
@@ -668,10 +667,10 @@ static void display(priv_dumper_t* dumper) | |||
668 | * of blocksize, and no partial block ever found. | 667 | * of blocksize, and no partial block ever found. |
669 | */ | 668 | */ |
670 | if (!dumper->eaddress) { | 669 | if (!dumper->eaddress) { |
671 | if (!dumper->address) { | 670 | if (!dumper->pub.address) { |
672 | return; | 671 | return; |
673 | } | 672 | } |
674 | dumper->eaddress = dumper->address; | 673 | dumper->eaddress = dumper->pub.address; |
675 | } | 674 | } |
676 | for (pr = dumper->endfu->nextpr; pr; pr = pr->nextpr) { | 675 | for (pr = dumper->endfu->nextpr; pr; pr = pr->nextpr) { |
677 | switch (pr->flags) { | 676 | switch (pr->flags) { |
diff --git a/util-linux/hexdump_xxd.c b/util-linux/hexdump_xxd.c index 817250c69..aa215569f 100644 --- a/util-linux/hexdump_xxd.c +++ b/util-linux/hexdump_xxd.c | |||
@@ -41,12 +41,13 @@ | |||
41 | // -u use upper case hex letters. | 41 | // -u use upper case hex letters. |
42 | 42 | ||
43 | //usage:#define xxd_trivial_usage | 43 | //usage:#define xxd_trivial_usage |
44 | //usage: "[-pr] [-g N] [-c N] [-n LEN] [-s OFS] [-o OFS] [FILE]" | 44 | //usage: "[-pri] [-g N] [-c N] [-n LEN] [-s OFS] [-o OFS] [FILE]" |
45 | //usage:#define xxd_full_usage "\n\n" | 45 | //usage:#define xxd_full_usage "\n\n" |
46 | //usage: "Hex dump FILE (or stdin)\n" | 46 | //usage: "Hex dump FILE (or stdin)\n" |
47 | //usage: "\n -g N Bytes per group" | 47 | //usage: "\n -g N Bytes per group" |
48 | //usage: "\n -c N Bytes per line" | 48 | //usage: "\n -c N Bytes per line" |
49 | //usage: "\n -p Show only hex bytes, assumes -c30" | 49 | //usage: "\n -p Show only hex bytes, assumes -c30" |
50 | //usage: "\n -i C include file style" | ||
50 | // exactly the same help text lines in hexdump and xxd: | 51 | // exactly the same help text lines in hexdump and xxd: |
51 | //usage: "\n -l LENGTH Show only first LENGTH bytes" | 52 | //usage: "\n -l LENGTH Show only first LENGTH bytes" |
52 | //usage: "\n -s OFFSET Skip OFFSET bytes" | 53 | //usage: "\n -s OFFSET Skip OFFSET bytes" |
@@ -62,10 +63,11 @@ | |||
62 | #define OPT_s (1 << 1) | 63 | #define OPT_s (1 << 1) |
63 | #define OPT_a (1 << 2) | 64 | #define OPT_a (1 << 2) |
64 | #define OPT_p (1 << 3) | 65 | #define OPT_p (1 << 3) |
65 | #define OPT_r (1 << 4) | 66 | #define OPT_i (1 << 4) |
66 | #define OPT_g (1 << 5) | 67 | #define OPT_r (1 << 5) |
67 | #define OPT_c (1 << 6) | 68 | #define OPT_g (1 << 6) |
68 | #define OPT_o (1 << 7) | 69 | #define OPT_c (1 << 7) |
70 | #define OPT_o (1 << 8) | ||
69 | 71 | ||
70 | static void reverse(unsigned opt, unsigned cols, const char *filename) | 72 | static void reverse(unsigned opt, unsigned cols, const char *filename) |
71 | { | 73 | { |
@@ -126,6 +128,15 @@ static void reverse(unsigned opt, unsigned cols, const char *filename) | |||
126 | fflush_stdout_and_exit(EXIT_SUCCESS); | 128 | fflush_stdout_and_exit(EXIT_SUCCESS); |
127 | } | 129 | } |
128 | 130 | ||
131 | static void print_C_style(const char *p, const char *hdr) | ||
132 | { | ||
133 | printf(hdr, isdigit(p[0]) ? "__" : ""); | ||
134 | while (*p) { | ||
135 | bb_putchar(isalnum(*p) ? *p : '_'); | ||
136 | p++; | ||
137 | } | ||
138 | } | ||
139 | |||
129 | int xxd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 140 | int xxd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
130 | int xxd_main(int argc UNUSED_PARAM, char **argv) | 141 | int xxd_main(int argc UNUSED_PARAM, char **argv) |
131 | { | 142 | { |
@@ -135,10 +146,11 @@ int xxd_main(int argc UNUSED_PARAM, char **argv) | |||
135 | unsigned bytes = 2; | 146 | unsigned bytes = 2; |
136 | unsigned cols = 0; | 147 | unsigned cols = 0; |
137 | unsigned opt; | 148 | unsigned opt; |
149 | int r; | ||
138 | 150 | ||
139 | dumper = alloc_dumper(); | 151 | dumper = alloc_dumper(); |
140 | 152 | ||
141 | opt = getopt32(argv, "^" "l:s:aprg:+c:+o:" "\0" "?1" /* 1 argument max */, | 153 | opt = getopt32(argv, "^" "l:s:apirg:+c:+o:" "\0" "?1" /* 1 argument max */, |
142 | &opt_l, &opt_s, &bytes, &cols, &opt_o | 154 | &opt_l, &opt_s, &bytes, &cols, &opt_o |
143 | ); | 155 | ); |
144 | argv += optind; | 156 | argv += optind; |
@@ -173,8 +185,11 @@ int xxd_main(int argc UNUSED_PARAM, char **argv) | |||
173 | bytes = cols; /* -p ignores -gN */ | 185 | bytes = cols; /* -p ignores -gN */ |
174 | } else { | 186 | } else { |
175 | if (cols == 0) | 187 | if (cols == 0) |
176 | cols = 16; | 188 | cols = (opt & OPT_i) ? 12 : 16; |
177 | bb_dump_add(dumper, "\"%08.8_ax: \""); // "address: " | 189 | if (opt & OPT_i) |
190 | bytes = 1; /* -i ignores -gN */ | ||
191 | else | ||
192 | bb_dump_add(dumper, "\"%08.8_ax: \""); // "address: " | ||
178 | } | 193 | } |
179 | 194 | ||
180 | if (opt & OPT_r) { | 195 | if (opt & OPT_r) { |
@@ -186,7 +201,10 @@ int xxd_main(int argc UNUSED_PARAM, char **argv) | |||
186 | bb_dump_add(dumper, buf); | 201 | bb_dump_add(dumper, buf); |
187 | } | 202 | } |
188 | else if (bytes == 1) { | 203 | else if (bytes == 1) { |
189 | sprintf(buf, "%u/1 \"%%02x \"", cols); // cols * "xx " | 204 | if (opt & OPT_i) |
205 | sprintf(buf, "%u/1 \" 0x%%02x,\"", cols); // cols * " 0xxx," | ||
206 | else | ||
207 | sprintf(buf, "%u/1 \"%%02x \"", cols); // cols * "xx " | ||
190 | bb_dump_add(dumper, buf); | 208 | bb_dump_add(dumper, buf); |
191 | } | 209 | } |
192 | else { | 210 | else { |
@@ -210,7 +228,7 @@ int xxd_main(int argc UNUSED_PARAM, char **argv) | |||
210 | free(bigbuf); | 228 | free(bigbuf); |
211 | } | 229 | } |
212 | 230 | ||
213 | if (!(opt & OPT_p)) { | 231 | if (!(opt & (OPT_p|OPT_i))) { |
214 | sprintf(buf, "\" \"%u/1 \"%%_p\"\"\n\"", cols); // " ASCII\n" | 232 | sprintf(buf, "\" \"%u/1 \"%%_p\"\"\n\"", cols); // " ASCII\n" |
215 | bb_dump_add(dumper, buf); | 233 | bb_dump_add(dumper, buf); |
216 | } else { | 234 | } else { |
@@ -218,5 +236,14 @@ int xxd_main(int argc UNUSED_PARAM, char **argv) | |||
218 | dumper->xxd_eofstring = "\n"; | 236 | dumper->xxd_eofstring = "\n"; |
219 | } | 237 | } |
220 | 238 | ||
221 | return bb_dump_dump(dumper, argv); | 239 | if ((opt & OPT_i) && argv[0]) { |
240 | print_C_style(argv[0], "unsigned char %s"); | ||
241 | printf("[] = {\n"); | ||
242 | } | ||
243 | r = bb_dump_dump(dumper, argv); | ||
244 | if (r == 0 && (opt & OPT_i) && argv[0]) { | ||
245 | print_C_style(argv[0], "};\nunsigned int %s"); | ||
246 | printf("_len = %"OFF_FMT"u;\n", dumper->address); | ||
247 | } | ||
248 | return r; | ||
222 | } | 249 | } |