[git commit] xxd: implement -i "C style output"

Denys Vlasenko vda.linux at googlemail.com
Thu Jun 17 22:59:17 UTC 2021


commit: https://git.busybox.net/busybox/commit/?id=2c436679fbb5fa38b0e7a505022a2075fab87d84
branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master

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 at googlemail.com>
---
 include/dump.h           |  1 +
 libbb/dump.c             | 29 ++++++++++++++--------------
 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 {
 	smallint dump_vflag;            /*enum dump_vflag_t*/
 	FS *fshead;
 	const char *xxd_eofstring;
+	off_t address;           /* address/offset in stream */
 	long long xxd_displayoff;
 } dumper_t;
 
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 {
 	FU *endfu;
 	off_t savaddress;        /* saved address/offset in stream */
 	off_t eaddress;          /* end address */
-	off_t address;           /* address/offset in stream */
 	int blocksize;
 	smallint exitval;        /* final exit value */
 
@@ -335,14 +334,14 @@ static void do_skip(priv_dumper_t *dumper, const char *fname)
 	) {
 		/* If st_size is valid and pub.dump_skip >= st_size */
 		dumper->pub.dump_skip -= sbuf.st_size;
-		dumper->address += sbuf.st_size;
+		dumper->pub.address += sbuf.st_size;
 		return;
 	}
 	if (fseeko(stdin, dumper->pub.dump_skip, SEEK_SET)) {
 		bb_simple_perror_msg_and_die(fname);
 	}
-	dumper->address += dumper->pub.dump_skip;
-	dumper->savaddress = dumper->address;
+	dumper->pub.address += dumper->pub.dump_skip;
+	dumper->savaddress = dumper->pub.address;
 	dumper->pub.dump_skip = 0;
 }
 
@@ -381,7 +380,7 @@ static unsigned char *get(priv_dumper_t *dumper)
 	int blocksize = dumper->blocksize;
 
 	if (!dumper->get__curp) {
-		dumper->address = (off_t)0; /*DBU:[dave at cray.com] initialize,initialize..*/
+		dumper->pub.address = (off_t)0; /*DBU:[dave at cray.com] initialize,initialize..*/
 		dumper->get__curp = xmalloc(blocksize);
 		dumper->get__savp = xzalloc(blocksize); /* need to be initialized */
 	} else {
@@ -389,7 +388,7 @@ static unsigned char *get(priv_dumper_t *dumper)
 		dumper->get__curp = dumper->get__savp;
 		dumper->get__savp = tmp;
 		dumper->savaddress += blocksize;
-		dumper->address = dumper->savaddress;
+		dumper->pub.address = dumper->savaddress;
 	}
 	need = blocksize;
 	nread = 0;
@@ -412,7 +411,7 @@ static unsigned char *get(priv_dumper_t *dumper)
 				}
 			}
 			memset(dumper->get__curp + nread, 0, need);
-			dumper->eaddress = dumper->address + nread;
+			dumper->eaddress = dumper->pub.address + nread;
 			return dumper->get__curp;
 		}
 		n = fread(dumper->get__curp + nread, sizeof(unsigned char),
@@ -444,7 +443,7 @@ static unsigned char *get(priv_dumper_t *dumper)
 			}
 			dumper->pub.dump_vflag = DUP;
 			dumper->savaddress += blocksize;
-			dumper->address = dumper->savaddress;
+			dumper->pub.address = dumper->savaddress;
 			need = blocksize;
 			nread = 0;
 		} else {
@@ -545,8 +544,8 @@ static void display(priv_dumper_t* dumper)
 
 		fs = dumper->pub.fshead;
 		savebp = bp;
-		saveaddress = dumper->address;
-		for (; fs; fs = fs->nextfs, bp = savebp, dumper->address = saveaddress) {
+		saveaddress = dumper->pub.address;
+		for (; fs; fs = fs->nextfs, bp = savebp, dumper->pub.address = saveaddress) {
 			FU *fu;
 			for (fu = fs->nextfu; fu; fu = fu->nextfu) {
 				int cnt;
@@ -555,10 +554,10 @@ static void display(priv_dumper_t* dumper)
 				}
 				for (cnt = fu->reps; cnt; --cnt) {
 					PR *pr;
-					for (pr = fu->nextpr; pr; dumper->address += pr->bcnt,
+					for (pr = fu->nextpr; pr; dumper->pub.address += pr->bcnt,
 								bp += pr->bcnt, pr = pr->nextpr) {
 						if (dumper->eaddress
-						 && dumper->address >= dumper->eaddress
+						 && dumper->pub.address >= dumper->eaddress
 						) {
 							if (dumper->pub.xxd_eofstring) {
 								/* xxd support: requested to not pad incomplete blocks */
@@ -574,7 +573,7 @@ static void display(priv_dumper_t* dumper)
 						}
 						switch (pr->flags) {
 						case F_ADDRESS:
-							printf(pr->fmt, (unsigned long long) dumper->address + dumper->pub.xxd_displayoff);
+							printf(pr->fmt, (unsigned long long) dumper->pub.address + dumper->pub.xxd_displayoff);
 							break;
 						case F_BPAD:
 							printf(pr->fmt, "");
@@ -668,10 +667,10 @@ static void display(priv_dumper_t* dumper)
 		 * of blocksize, and no partial block ever found.
 		 */
 		if (!dumper->eaddress) {
-			if (!dumper->address) {
+			if (!dumper->pub.address) {
 				return;
 			}
-			dumper->eaddress = dumper->address;
+			dumper->eaddress = dumper->pub.address;
 		}
 		for (pr = dumper->endfu->nextpr; pr; pr = pr->nextpr) {
 			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 @@
 //    -u          use upper case hex letters.
 
 //usage:#define xxd_trivial_usage
-//usage:       "[-pr] [-g N] [-c N] [-n LEN] [-s OFS] [-o OFS] [FILE]"
+//usage:       "[-pri] [-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"
 //usage:     "\n	-c N		Bytes per line"
 //usage:     "\n	-p		Show only hex bytes, assumes -c30"
+//usage:     "\n	-i		C include file style"
 // 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"
@@ -62,10 +63,11 @@
 #define OPT_s (1 << 1)
 #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)
+#define OPT_i (1 << 4)
+#define OPT_r (1 << 5)
+#define OPT_g (1 << 6)
+#define OPT_c (1 << 7)
+#define OPT_o (1 << 8)
 
 static void reverse(unsigned opt, unsigned cols, const char *filename)
 {
@@ -126,6 +128,15 @@ static void reverse(unsigned opt, unsigned cols, const char *filename)
 	fflush_stdout_and_exit(EXIT_SUCCESS);
 }
 
+static void print_C_style(const char *p, const char *hdr)
+{
+	printf(hdr, isdigit(p[0]) ? "__" : "");
+	while (*p) {
+		bb_putchar(isalnum(*p) ? *p : '_');
+		p++;
+	}
+}
+
 int xxd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
 int xxd_main(int argc UNUSED_PARAM, char **argv)
 {
@@ -135,10 +146,11 @@ int xxd_main(int argc UNUSED_PARAM, char **argv)
 	unsigned bytes = 2;
 	unsigned cols = 0;
 	unsigned opt;
+	int r;
 
 	dumper = alloc_dumper();
 
-	opt = getopt32(argv, "^" "l:s:aprg:+c:+o:" "\0" "?1" /* 1 argument max */,
+	opt = getopt32(argv, "^" "l:s:apirg:+c:+o:" "\0" "?1" /* 1 argument max */,
 			&opt_l, &opt_s, &bytes, &cols, &opt_o
 	);
 	argv += optind;
@@ -173,8 +185,11 @@ int xxd_main(int argc UNUSED_PARAM, char **argv)
 		bytes = cols; /* -p ignores -gN */
 	} else {
 		if (cols == 0)
-			cols = 16;
-		bb_dump_add(dumper, "\"%08.8_ax: \""); // "address: "
+			cols = (opt & OPT_i) ? 12 : 16;
+		if (opt & OPT_i)
+			bytes = 1; /* -i ignores -gN */
+		else
+			bb_dump_add(dumper, "\"%08.8_ax: \""); // "address: "
 	}
 
 	if (opt & OPT_r) {
@@ -186,7 +201,10 @@ int xxd_main(int argc UNUSED_PARAM, char **argv)
 		bb_dump_add(dumper, buf);
 	}
 	else if (bytes == 1) {
-		sprintf(buf, "%u/1 \"%%02x \"", cols); // cols * "xx "
+		if (opt & OPT_i)
+			sprintf(buf, "%u/1 \" 0x%%02x,\"", cols); // cols * " 0xxx,"
+		else
+			sprintf(buf, "%u/1 \"%%02x \"", cols); // cols * "xx "
 		bb_dump_add(dumper, buf);
 	}
 	else {
@@ -210,7 +228,7 @@ int xxd_main(int argc UNUSED_PARAM, char **argv)
 		free(bigbuf);
 	}
 
-	if (!(opt & OPT_p)) {
+	if (!(opt & (OPT_p|OPT_i))) {
 		sprintf(buf, "\"  \"%u/1 \"%%_p\"\"\n\"", cols); // "  ASCII\n"
 		bb_dump_add(dumper, buf);
 	} else {
@@ -218,5 +236,14 @@ int xxd_main(int argc UNUSED_PARAM, char **argv)
 		dumper->xxd_eofstring = "\n";
 	}
 
-	return bb_dump_dump(dumper, argv);
+	if ((opt & OPT_i) && argv[0]) {
+		print_C_style(argv[0], "unsigned char %s");
+		printf("[] = {\n");
+	}
+	r = bb_dump_dump(dumper, argv);
+	if (r == 0 && (opt & OPT_i) && argv[0]) {
+		print_C_style(argv[0], "};\nunsigned int %s");
+		printf("_len = %"OFF_FMT"u;\n", dumper->address);
+	}
+	return r;
 }


More information about the busybox-cvs mailing list