[git commit] xxd: implement -o DISPLAYOFFSET

Denys Vlasenko vda.linux at googlemail.com
Thu Jun 17 21:53:30 UTC 2021


commit: https://git.busybox.net/busybox/commit/?id=4d1616179745ee3883a726aaf13468e9c44dff9e
branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master

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 at googlemail.com>
---
 include/dump.h           |  3 ++-
 libbb/dump.c             | 11 ++++++-----
 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 {
 	off_t dump_skip;                /* bytes to skip */
 	int dump_length;                /* max bytes to read */
 	smallint dump_vflag;            /*enum dump_vflag_t*/
-	const char *eofstring;
 	FS *fshead;
+	const char *xxd_eofstring;
+	long long xxd_displayoff;
 } dumper_t;
 
 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)
 					if ((p1[2] != 'd') && (p1[2] != 'o') && (p1[2] != 'x')) {
 						goto DO_BAD_CONV_CHAR;
 					}
-					*p1 = p1[2];
+					*p1++ = 'l';
+					*p1++ = 'l';
 					break;
 				case 'c':	/* %_c: chars, \ooo, \n \r \t etc */
 					pr->flags = F_C;
@@ -558,9 +559,9 @@ static void display(priv_dumper_t* dumper)
 						if (dumper->eaddress
 						 && dumper->address >= dumper->eaddress
 						) {
-							if (dumper->pub.eofstring) {
+							if (dumper->pub.xxd_eofstring) {
 								/* xxd support: requested to not pad incomplete blocks */
-								fputs_stdout(dumper->pub.eofstring);
+								fputs_stdout(dumper->pub.xxd_eofstring);
 								return;
 							}
 							if (!(pr->flags & (F_TEXT | F_BPAD)))
@@ -572,7 +573,7 @@ static void display(priv_dumper_t* dumper)
 						}
 						switch (pr->flags) {
 						case F_ADDRESS:
-							printf(pr->fmt, (unsigned) dumper->address);
+							printf(pr->fmt, (unsigned long long) dumper->address + dumper->pub.xxd_displayoff);
 							break;
 						case F_BPAD:
 							printf(pr->fmt, "");
@@ -674,7 +675,7 @@ static void display(priv_dumper_t* dumper)
 		for (pr = dumper->endfu->nextpr; pr; pr = pr->nextpr) {
 			switch (pr->flags) {
 			case F_ADDRESS:
-				printf(pr->fmt, (unsigned) dumper->eaddress);
+				printf(pr->fmt, (unsigned long long) dumper->eaddress + dumper->pub.xxd_displayoff);
 				break;
 			case F_TEXT:
 				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 @@
 //    -u          use upper case hex letters.
 
 //usage:#define xxd_trivial_usage
-//usage:       "[-pr] [-g N] [-c N] [-n LEN] [-s OFS] [FILE]"
+//usage:       "[-pr] [-g N] [-c N] [-n LEN] [-s OFS] [-o OFS] [FILE]"
 //usage:#define xxd_full_usage "\n\n"
 //usage:       "Hex dump FILE (or stdin)\n"
 //usage:     "\n	-g N		Bytes per group"
@@ -50,6 +50,7 @@
 // exactly the same help text lines in hexdump and xxd:
 //usage:     "\n	-l LENGTH	Show only first LENGTH bytes"
 //usage:     "\n	-s OFFSET	Skip OFFSET bytes"
+//usage:     "\n	-o OFFSET	Add OFFSET to displayed offset"
 //usage:     "\n	-r		Reverse (with -p, assumes no offsets in input)"
 
 #include "libbb.h"
@@ -62,6 +63,9 @@
 #define OPT_a (1 << 2)
 #define OPT_p (1 << 3)
 #define OPT_r (1 << 4)
+#define OPT_g (1 << 5)
+#define OPT_c (1 << 6)
+#define OPT_o (1 << 7)
 
 static void reverse(unsigned opt, unsigned cols, const char *filename)
 {
@@ -127,15 +131,15 @@ int xxd_main(int argc UNUSED_PARAM, char **argv)
 {
 	char buf[80];
 	dumper_t *dumper;
-	char *opt_l, *opt_s;
+	char *opt_l, *opt_s, *opt_o;
 	unsigned bytes = 2;
 	unsigned cols = 0;
 	unsigned opt;
 
 	dumper = alloc_dumper();
 
-	opt = getopt32(argv, "^" "l:s:aprg:+c:+" "\0" "?1" /* 1 argument max */,
-			&opt_l, &opt_s, &bytes, &cols
+	opt = getopt32(argv, "^" "l:s:aprg:+c:+o:" "\0" "?1" /* 1 argument max */,
+			&opt_l, &opt_s, &bytes, &cols, &opt_o
 	);
 	argv += optind;
 
@@ -158,6 +162,11 @@ int xxd_main(int argc UNUSED_PARAM, char **argv)
 		//BUGGY for /proc/version (unseekable?)
 	}
 
+	if (opt & OPT_o) {
+		/* -o accepts negative numbers too */
+		dumper->xxd_displayoff = xstrtoll(opt_o, /*base:*/ 0);
+	}
+
 	if (opt & OPT_p) {
 		if (cols == 0)
 			cols = 30;
@@ -206,7 +215,7 @@ int xxd_main(int argc UNUSED_PARAM, char **argv)
 		bb_dump_add(dumper, buf);
 	} else {
 		bb_dump_add(dumper, "\"\n\"");
-		dumper->eofstring = "\n";
+		dumper->xxd_eofstring = "\n";
 	}
 
 	return bb_dump_dump(dumper, argv);


More information about the busybox-cvs mailing list