summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--coreutils/od.c33
-rw-r--r--include/dump.h1
-rw-r--r--libbb/dump.c21
-rwxr-xr-xtestsuite/od.tests43
4 files changed, 51 insertions, 47 deletions
diff --git a/coreutils/od.c b/coreutils/od.c
index bd82487..abedb40 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 10fc5d9..11dcf45 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 cfb9d94..77d7661 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 29ca829..4b15256 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