diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2021-06-17 23:53:30 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2021-06-17 23:53:30 +0200 |
commit | 4d1616179745ee3883a726aaf13468e9c44dff9e (patch) | |
tree | bed5bc2f6afc768df587db7058b968f6e920b897 | |
parent | a0f8076d19d721996b95b64eba95adae011215af (diff) | |
download | busybox-w32-4d1616179745ee3883a726aaf13468e9c44dff9e.tar.gz busybox-w32-4d1616179745ee3883a726aaf13468e9c44dff9e.tar.bz2 busybox-w32-4d1616179745ee3883a726aaf13468e9c44dff9e.zip |
xxd: implement -o DISPLAYOFFSET
function old new delta
xxd_main 680 710 +30
xstrtoll - 30 +30
bb_dump_dump 1511 1531 +20
rewrite 941 951 +10
packed_usage 33629 33639 +10
.rodata 103250 103252 +2
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 5/0 up/down: 102/0) Total: 102 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | include/dump.h | 3 | ||||
-rw-r--r-- | libbb/dump.c | 11 | ||||
-rw-r--r-- | util-linux/hexdump_xxd.c | 19 |
3 files changed, 22 insertions, 11 deletions
diff --git a/include/dump.h b/include/dump.h index 9193a6925..54f5629a7 100644 --- a/include/dump.h +++ b/include/dump.h | |||
@@ -32,8 +32,9 @@ typedef struct dumper_t { | |||
32 | off_t dump_skip; /* bytes to skip */ | 32 | off_t dump_skip; /* bytes to skip */ |
33 | int dump_length; /* max bytes to read */ | 33 | int dump_length; /* max bytes to read */ |
34 | smallint dump_vflag; /*enum dump_vflag_t*/ | 34 | smallint dump_vflag; /*enum dump_vflag_t*/ |
35 | const char *eofstring; | ||
36 | FS *fshead; | 35 | FS *fshead; |
36 | const char *xxd_eofstring; | ||
37 | long long xxd_displayoff; | ||
37 | } dumper_t; | 38 | } dumper_t; |
38 | 39 | ||
39 | dumper_t* alloc_dumper(void) FAST_FUNC; | 40 | dumper_t* alloc_dumper(void) FAST_FUNC; |
diff --git a/libbb/dump.c b/libbb/dump.c index e83633c1d..8c2a370d0 100644 --- a/libbb/dump.c +++ b/libbb/dump.c | |||
@@ -228,7 +228,8 @@ static NOINLINE void rewrite(priv_dumper_t *dumper, FS *fs) | |||
228 | if ((p1[2] != 'd') && (p1[2] != 'o') && (p1[2] != 'x')) { | 228 | if ((p1[2] != 'd') && (p1[2] != 'o') && (p1[2] != 'x')) { |
229 | goto DO_BAD_CONV_CHAR; | 229 | goto DO_BAD_CONV_CHAR; |
230 | } | 230 | } |
231 | *p1 = p1[2]; | 231 | *p1++ = 'l'; |
232 | *p1++ = 'l'; | ||
232 | break; | 233 | break; |
233 | case 'c': /* %_c: chars, \ooo, \n \r \t etc */ | 234 | case 'c': /* %_c: chars, \ooo, \n \r \t etc */ |
234 | pr->flags = F_C; | 235 | pr->flags = F_C; |
@@ -558,9 +559,9 @@ static void display(priv_dumper_t* dumper) | |||
558 | if (dumper->eaddress | 559 | if (dumper->eaddress |
559 | && dumper->address >= dumper->eaddress | 560 | && dumper->address >= dumper->eaddress |
560 | ) { | 561 | ) { |
561 | if (dumper->pub.eofstring) { | 562 | if (dumper->pub.xxd_eofstring) { |
562 | /* xxd support: requested to not pad incomplete blocks */ | 563 | /* xxd support: requested to not pad incomplete blocks */ |
563 | fputs_stdout(dumper->pub.eofstring); | 564 | fputs_stdout(dumper->pub.xxd_eofstring); |
564 | return; | 565 | return; |
565 | } | 566 | } |
566 | if (!(pr->flags & (F_TEXT | F_BPAD))) | 567 | if (!(pr->flags & (F_TEXT | F_BPAD))) |
@@ -572,7 +573,7 @@ static void display(priv_dumper_t* dumper) | |||
572 | } | 573 | } |
573 | switch (pr->flags) { | 574 | switch (pr->flags) { |
574 | case F_ADDRESS: | 575 | case F_ADDRESS: |
575 | printf(pr->fmt, (unsigned) dumper->address); | 576 | printf(pr->fmt, (unsigned long long) dumper->address + dumper->pub.xxd_displayoff); |
576 | break; | 577 | break; |
577 | case F_BPAD: | 578 | case F_BPAD: |
578 | printf(pr->fmt, ""); | 579 | printf(pr->fmt, ""); |
@@ -674,7 +675,7 @@ static void display(priv_dumper_t* dumper) | |||
674 | for (pr = dumper->endfu->nextpr; pr; pr = pr->nextpr) { | 675 | for (pr = dumper->endfu->nextpr; pr; pr = pr->nextpr) { |
675 | switch (pr->flags) { | 676 | switch (pr->flags) { |
676 | case F_ADDRESS: | 677 | case F_ADDRESS: |
677 | printf(pr->fmt, (unsigned) dumper->eaddress); | 678 | printf(pr->fmt, (unsigned long long) dumper->eaddress + dumper->pub.xxd_displayoff); |
678 | break; | 679 | break; |
679 | case F_TEXT: | 680 | case F_TEXT: |
680 | printf(pr->fmt); | 681 | printf(pr->fmt); |
diff --git a/util-linux/hexdump_xxd.c b/util-linux/hexdump_xxd.c index 29bbc6633..817250c69 100644 --- a/util-linux/hexdump_xxd.c +++ b/util-linux/hexdump_xxd.c | |||
@@ -41,7 +41,7 @@ | |||
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] [FILE]" | 44 | //usage: "[-pr] [-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" |
@@ -50,6 +50,7 @@ | |||
50 | // exactly the same help text lines in hexdump and xxd: | 50 | // exactly the same help text lines in hexdump and xxd: |
51 | //usage: "\n -l LENGTH Show only first LENGTH bytes" | 51 | //usage: "\n -l LENGTH Show only first LENGTH bytes" |
52 | //usage: "\n -s OFFSET Skip OFFSET bytes" | 52 | //usage: "\n -s OFFSET Skip OFFSET bytes" |
53 | //usage: "\n -o OFFSET Add OFFSET to displayed offset" | ||
53 | //usage: "\n -r Reverse (with -p, assumes no offsets in input)" | 54 | //usage: "\n -r Reverse (with -p, assumes no offsets in input)" |
54 | 55 | ||
55 | #include "libbb.h" | 56 | #include "libbb.h" |
@@ -62,6 +63,9 @@ | |||
62 | #define OPT_a (1 << 2) | 63 | #define OPT_a (1 << 2) |
63 | #define OPT_p (1 << 3) | 64 | #define OPT_p (1 << 3) |
64 | #define OPT_r (1 << 4) | 65 | #define OPT_r (1 << 4) |
66 | #define OPT_g (1 << 5) | ||
67 | #define OPT_c (1 << 6) | ||
68 | #define OPT_o (1 << 7) | ||
65 | 69 | ||
66 | static void reverse(unsigned opt, unsigned cols, const char *filename) | 70 | static void reverse(unsigned opt, unsigned cols, const char *filename) |
67 | { | 71 | { |
@@ -127,15 +131,15 @@ int xxd_main(int argc UNUSED_PARAM, char **argv) | |||
127 | { | 131 | { |
128 | char buf[80]; | 132 | char buf[80]; |
129 | dumper_t *dumper; | 133 | dumper_t *dumper; |
130 | char *opt_l, *opt_s; | 134 | char *opt_l, *opt_s, *opt_o; |
131 | unsigned bytes = 2; | 135 | unsigned bytes = 2; |
132 | unsigned cols = 0; | 136 | unsigned cols = 0; |
133 | unsigned opt; | 137 | unsigned opt; |
134 | 138 | ||
135 | dumper = alloc_dumper(); | 139 | dumper = alloc_dumper(); |
136 | 140 | ||
137 | opt = getopt32(argv, "^" "l:s:aprg:+c:+" "\0" "?1" /* 1 argument max */, | 141 | opt = getopt32(argv, "^" "l:s:aprg:+c:+o:" "\0" "?1" /* 1 argument max */, |
138 | &opt_l, &opt_s, &bytes, &cols | 142 | &opt_l, &opt_s, &bytes, &cols, &opt_o |
139 | ); | 143 | ); |
140 | argv += optind; | 144 | argv += optind; |
141 | 145 | ||
@@ -158,6 +162,11 @@ int xxd_main(int argc UNUSED_PARAM, char **argv) | |||
158 | //BUGGY for /proc/version (unseekable?) | 162 | //BUGGY for /proc/version (unseekable?) |
159 | } | 163 | } |
160 | 164 | ||
165 | if (opt & OPT_o) { | ||
166 | /* -o accepts negative numbers too */ | ||
167 | dumper->xxd_displayoff = xstrtoll(opt_o, /*base:*/ 0); | ||
168 | } | ||
169 | |||
161 | if (opt & OPT_p) { | 170 | if (opt & OPT_p) { |
162 | if (cols == 0) | 171 | if (cols == 0) |
163 | cols = 30; | 172 | cols = 30; |
@@ -206,7 +215,7 @@ int xxd_main(int argc UNUSED_PARAM, char **argv) | |||
206 | bb_dump_add(dumper, buf); | 215 | bb_dump_add(dumper, buf); |
207 | } else { | 216 | } else { |
208 | bb_dump_add(dumper, "\"\n\""); | 217 | bb_dump_add(dumper, "\"\n\""); |
209 | dumper->eofstring = "\n"; | 218 | dumper->xxd_eofstring = "\n"; |
210 | } | 219 | } |
211 | 220 | ||
212 | return bb_dump_dump(dumper, argv); | 221 | return bb_dump_dump(dumper, argv); |