[git commit] od: stop printing extra trailing spaces

Denys Vlasenko vda.linux at googlemail.com
Thu May 25 21:48:13 UTC 2023


commit: https://git.busybox.net/busybox/commit/?id=0c3270f7e55e0ca7b8d664851468511d2c8995cf
branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master

function                                             old     new   delta
.rodata                                           104598  104613     +15
display                                             1475    1485     +10
od_main                                              549     556      +7
rewrite                                              971     967      -4
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 3/1 up/down: 32/-4)              Total: 28 bytes

Signed-off-by: Denys Vlasenko <vda.linux at googlemail.com>
---
 coreutils/od.c     | 33 +++++++++++++++++----------------
 include/dump.h     |  1 +
 libbb/dump.c       | 21 ++++++++++++++-------
 testsuite/od.tests | 43 +++++++++++++++++++------------------------
 4 files changed, 51 insertions(+), 47 deletions(-)

diff --git a/coreutils/od.c b/coreutils/od.c
index bd82487e5..abedb40a7 100644
--- a/coreutils/od.c
+++ b/coreutils/od.c
@@ -157,22 +157,22 @@ odoffset(dumper_t *dumper, int argc, char ***argvp)
 // The format is required and must be surrounded by " "s.
 // It is a printf-style format.
 static const char *const add_strings[] ALIGN_PTR = {
-	"16/1 \"%3_u \" \"\\n\"",              /* 0: a */
-	"8/2 \"%06o \" \"\\n\"",               /* 1: B (undocumented in od), o */
-	"16/1 \"%03o \" \"\\n\"",              /* 2: b */
-	"16/1 \"%3_c \" \"\\n\"",              /* 3: c */
-	"8/2 \"%5u \" \"\\n\"",                /* 4: d */
-	"4/4 \"%10u \" \"\\n\"",               /* 5: D */
-	"2/8 \"%24.14e \" \"\\n\"",            /* 6: e (undocumented in od), F */
-	"4/4 \"%15.7e \" \"\\n\"",             /* 7: f */
-	"4/4 \"%08x \" \"\\n\"",               /* 8: H, X */
-	"8/2 \"%04x \" \"\\n\"",               /* 9: h, x */
+	"16/1 \" %3_u\" \"\\n\"",              /* 0: a */
+	"8/2 \" %06o\" \"\\n\"",               /* 1: B (undocumented in od), o */
+	"16/1 \" %03o\" \"\\n\"",              /* 2: b */
+	"16/1 \" %3_c\" \"\\n\"",              /* 3: c */
+	"8/2 \" %5u\" \"\\n\"",                /* 4: d */
+	"4/4 \" %10u\" \"\\n\"",               /* 5: D */
+	"2/8 \" %24.14e\" \"\\n\"",            /* 6: e (undocumented in od), F */
+	"4/4 \" %15.7e\" \"\\n\"",             /* 7: f */
+	"4/4 \" %08x\" \"\\n\"",               /* 8: H, X */
+	"8/2 \" %04x\" \"\\n\"",               /* 9: h, x */
 	/* This probably also depends on word width of the arch (what is "long"?) */
 	/* should be "2/8" or "4/4" depending on sizeof(long)? */
-	"2/8 \"%20lld \" \"\\n\"",             /* 10: I, L, l */
-	"4/4 \"%11d \" \"\\n\"",               /* 11: i */
-	"4/4 \"%011o \" \"\\n\"",              /* 12: O */
-	"8/2 \"%6d \" \"\\n\"",                /* 13: s */
+	"2/8 \" %20lld\" \"\\n\"",             /* 10: I, L, l */
+	"4/4 \" %11d\" \"\\n\"",               /* 11: i */
+	"4/4 \" %011o\" \"\\n\"",              /* 12: O */
+	"8/2 \" %6d\" \"\\n\"",                /* 13: s */
 };
 
 static const char od_opts[] ALIGN1 = "aBbcDdeFfHhIiLlOoXxsv";
@@ -199,9 +199,9 @@ int od_main(int argc, char **argv)
 			if (first) {
 				first = 0;
 				bb_dump_add(dumper, "\"%07.7_Ao\n\"");
-				bb_dump_add(dumper, "\"%07.7_ao \"");
+				bb_dump_add(dumper, "\"%07.7_ao\"");
 			} else {
-				bb_dump_add(dumper, "\"        \"");
+				bb_dump_add(dumper, "\"       \"");
 			}
 			bb_dump_add(dumper, add_strings[(int)od_o2si[(p - od_opts)]]);
 		} else {  /* P, p, s, w, or other unhandled */
@@ -212,6 +212,7 @@ int od_main(int argc, char **argv)
 		bb_dump_add(dumper, "\"%07.7_Ao\n\"");
 		bb_dump_add(dumper, "\"%07.7_ao  \" 8/2 \"%06o \" \"\\n\"");
 	}
+	dumper->od_eofstring = "\n";
 
 	argc -= optind;
 	argv += optind;
diff --git a/include/dump.h b/include/dump.h
index 10fc5d900..11dcf4523 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;
+	const char *od_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 cfb9d94f9..77d76611b 100644
--- a/libbb/dump.c
+++ b/libbb/dump.c
@@ -242,7 +242,7 @@ static NOINLINE void rewrite(priv_dumper_t *dumper, FS *fs)
 					pr->flags = F_P;
 					*p1 = 'c';
 					goto DO_BYTE_COUNT_1;
-				case 'u':	/* %_p: chars, 'nul', 'esc' etc for nonprintable */
+				case 'u':	/* %_u: chars, 'nul', 'esc' etc for nonprintable */
 					pr->flags = F_U;
 					/* *p1 = 'c';   set in conv_u */
 					goto DO_BYTE_COUNT_1;
@@ -322,8 +322,7 @@ static NOINLINE void rewrite(priv_dumper_t *dumper, FS *fs)
 			p2 = NULL;
 			for (p1 = pr->fmt; *p1; ++p1)
 				p2 = isspace(*p1) ? p1 : NULL;
-			if (p2)
-				pr->nospace = p2;
+			pr->nospace = p2;
 		}
 	}
 }
@@ -477,7 +476,7 @@ static void bpad(PR *pr)
 
 static const char conv_str[] ALIGN1 =
 	"\0"  "\\""0""\0"
-	"\007""\\""a""\0"  /* \a */
+	"\007""\\""a""\0"
 	"\b"  "\\""b""\0"
 	"\f"  "\\""f""\0"
 	"\n"  "\\""n""\0"
@@ -539,7 +538,6 @@ static void conv_u(PR *pr, unsigned char *p)
 static NOINLINE void display(priv_dumper_t* dumper)
 {
 	unsigned char *bp;
-	unsigned char savech = '\0';
 
 	while ((bp = get(dumper)) != NULL) {
 		FS *fs;
@@ -560,6 +558,8 @@ static NOINLINE void display(priv_dumper_t* dumper)
 					PR *pr;
 					for (pr = fu->nextpr; pr; dumper->pub.address += pr->bcnt,
 								bp += pr->bcnt, pr = pr->nextpr) {
+						unsigned char savech;
+
 						if (dumper->eaddress
 						 && dumper->pub.address >= dumper->eaddress
 						) {
@@ -568,9 +568,16 @@ static NOINLINE void display(priv_dumper_t* dumper)
 								fputs_stdout(dumper->pub.xxd_eofstring);
 								return;
 							}
+							if (dumper->pub.od_eofstring) {
+								/* od support: requested to not pad incomplete blocks */
+								/* ... but do print final offset */
+								fputs_stdout(dumper->pub.od_eofstring);
+								goto endfu;
+							}
 							if (!(pr->flags & (F_TEXT | F_BPAD)))
 								bpad(pr);
 						}
+						savech = '\0';
 						if (cnt == 1 && pr->nospace) {
 							savech = *pr->nospace;
 							*pr->nospace = '\0';
@@ -665,7 +672,7 @@ static NOINLINE void display(priv_dumper_t* dumper)
 							break;
 						}
 						}
-						if (cnt == 1 && pr->nospace) {
+						if (savech) {
 							*pr->nospace = savech;
 						}
 					}
@@ -673,7 +680,7 @@ static NOINLINE void display(priv_dumper_t* dumper)
 			}
 		}
 	}
-
+ endfu:
 	if (dumper->endfu) {
 		PR *pr;
 		/*
diff --git a/testsuite/od.tests b/testsuite/od.tests
index 29ca829d5..4b1525620 100755
--- a/testsuite/od.tests
+++ b/testsuite/od.tests
@@ -12,14 +12,9 @@ le=false
 { printf '\0\1' | od -s | grep -q 256; } && le=true
 readonly le
 
-# NB: for !DESKTOP,
-# sed 's/ *$//' truncates trailing spaces.
-# This needs to be fixed properly (by not outputting them).
-# For now, the tests ignore them (do not require a match).
-
 optional !DESKTOP
 testing "od -a (!DESKTOP)" \
-        "od -a | sed 's/ *$//'" \
+        "od -a" \
 "\
 0000000 soh stx etx  lf   A   B   C  fe
 0000010
@@ -39,7 +34,7 @@ testing "od -a (DESKTOP)" \
 SKIP=
 
 testing "od -B" \
-        "od -B | sed 's/ *$//'" \
+        "od -B" \
 "\
 0000000 001001 005003 041101 177103
 0000010
@@ -49,7 +44,7 @@ SKIP=
 
 $le || SKIP=1
 testing "od -o (little-endian)" \
-        "od -o | sed 's/ *$//'" \
+        "od -o" \
 "\
 0000000 001001 005003 041101 177103
 0000010
@@ -58,7 +53,7 @@ testing "od -o (little-endian)" \
 SKIP=
 
 testing "od -b" \
-        "od -b | sed 's/ *$//'" \
+        "od -b" \
 "\
 0000000 001 002 003 012 101 102 103 376
 0000010
@@ -67,7 +62,7 @@ testing "od -b" \
 SKIP=
 
 testing "od -c" \
-        "od -c | sed 's/ *$//'" \
+        "od -c" \
 "\
 0000000 001 002 003  \\\\n   A   B   C 376
 0000010
@@ -77,7 +72,7 @@ SKIP=
 
 $le || SKIP=1
 testing "od -d (little-endian)" \
-        "od -d | sed 's/ *$//'" \
+        "od -d" \
 "\
 0000000   513  2563 16961 65091
 0000010
@@ -88,7 +83,7 @@ SKIP=
 optional !DESKTOP  #DESKTOP: unrecognized option: D
 $le || SKIP=1
 testing "od -D (!DESKTOP little-endian)" \
-        "od -D | sed 's/ *$//'" \
+        "od -D" \
 "\
 0000000  167969281 4265820737
 0000010
@@ -99,7 +94,7 @@ SKIP=
 optional !DESKTOP  #DESKTOP: unrecognized option: e
 $le || SKIP=1
 testing "od -e (!DESKTOP little-endian)" \
-        "od -e | sed 's/ *$//'" \
+        "od -e" \
 "\
 0000000   -1.61218556514036e+300
 0000010
@@ -110,7 +105,7 @@ SKIP=
 optional !DESKTOP  #DESKTOP: unrecognized option: F
 $le || SKIP=1
 testing "od -F (!DESKTOP little-endian)" \
-        "od -F | sed 's/ *$//'" \
+        "od -F" \
 "\
 0000000   -1.61218556514036e+300
 0000010
@@ -120,7 +115,7 @@ SKIP=
 
 $le || SKIP=1
 testing "od -f (little-endian)" \
-        "od -f | sed 's/ *$//'" \
+        "od -f" \
 "\
 0000000   6.3077975e-33  -6.4885867e+37
 0000010
@@ -131,7 +126,7 @@ SKIP=
 optional !DESKTOP  #DESKTOP: unrecognized option: H
 $le || SKIP=1
 testing "od -H (!DESKTOP little-endian)" \
-        "od -H | sed 's/ *$//'" \
+        "od -H" \
 "\
 0000000 0a030201 fe434241
 0000010
@@ -142,7 +137,7 @@ SKIP=
 optional !DESKTOP  #DESKTOP: unrecognized option: X
 $le || SKIP=1
 testing "od -X (!DESKTOP little-endian)" \
-        "od -X | sed 's/ *$//'" \
+        "od -X" \
 "\
 0000000 0a030201 fe434241
 0000010
@@ -152,7 +147,7 @@ SKIP=
 
 $le || SKIP=1
 testing "od -h (little-endian)" \
-        "od -h | sed 's/ *$//'" \
+        "od -h" \
 "\
 0000000 0201 0a03 4241 fe43
 0000010
@@ -162,7 +157,7 @@ SKIP=
 
 $le || SKIP=1
 testing "od -x (little-endian)" \
-        "od -x | sed 's/ *$//'" \
+        "od -x" \
 "\
 0000000 0201 0a03 4241 fe43
 0000010
@@ -173,7 +168,7 @@ SKIP=
 optional !DESKTOP  #DESKTOP: unrecognized option: I
 $le || SKIP=1
 testing "od -I (!DESKTOP little-endian)" \
-        "od -I | sed 's/ *$//'" \
+        "od -I" \
 "\
 0000000  -125183517527965183
 0000010
@@ -184,7 +179,7 @@ SKIP=
 optional !DESKTOP  #DESKTOP: unrecognized option: L
 $le || SKIP=1
 testing "od -L (!DESKTOP little-endian)" \
-        "od -L | sed 's/ *$//'" \
+        "od -L" \
 "\
 0000000  -125183517527965183
 0000010
@@ -194,7 +189,7 @@ SKIP=
 
 $le || SKIP=1
 testing "od -i (little-endian)" \
-        "od -i | sed 's/ *$//'" \
+        "od -i" \
 "\
 0000000   167969281   -29146559
 0000010
@@ -205,7 +200,7 @@ SKIP=
 optional !DESKTOP  #DESKTOP: unrecognized option: O
 $le || SKIP=1
 testing "od -O (!DESKTOP little-endian)" \
-        "od -O | sed 's/ *$//'" \
+        "od -O" \
 "\
 0000000 01200601001 37620641101
 0000010
@@ -216,7 +211,7 @@ SKIP=
 # This probably also depends on word width of the arch (what is "long"?)
 $le || SKIP=1
 testing "od -l (little-endian)" \
-        "od -l | sed 's/ *$//'" \
+        "od -l" \
 "\
 0000000  -125183517527965183
 0000010


More information about the busybox-cvs mailing list