diff options
-rw-r--r-- | coreutils/od.c | 33 | ||||
-rw-r--r-- | include/dump.h | 1 | ||||
-rw-r--r-- | libbb/dump.c | 21 | ||||
-rwxr-xr-x | testsuite/od.tests | 43 |
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 |