aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2021-06-17 23:53:30 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2021-06-17 23:53:30 +0200
commit4d1616179745ee3883a726aaf13468e9c44dff9e (patch)
treebed5bc2f6afc768df587db7058b968f6e920b897
parenta0f8076d19d721996b95b64eba95adae011215af (diff)
downloadbusybox-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.h3
-rw-r--r--libbb/dump.c11
-rw-r--r--util-linux/hexdump_xxd.c19
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
39dumper_t* alloc_dumper(void) FAST_FUNC; 40dumper_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
66static void reverse(unsigned opt, unsigned cols, const char *filename) 70static 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);