From f66b9b40f403f7c30fec3c4ceed93c6e8fafa8ac Mon Sep 17 00:00:00 2001 From: Kyle Evans Date: Thu, 23 Sep 2021 00:46:30 -0500 Subject: [PATCH] cmp: add -b, --print-bytes This is compatible with GNU cmp. Reviewed by: bapt, markj (earlier version) Sponsored by: Klara, Inc. Differential Revision: https://reviews.freebsd.org/D32074 --- usr.bin/cmp/cmp.1 | 5 ++++- usr.bin/cmp/cmp.c | 8 ++++++-- usr.bin/cmp/extern.h | 4 ++-- usr.bin/cmp/link.c | 10 +++++++--- usr.bin/cmp/misc.c | 14 ++++++++++++-- usr.bin/cmp/regular.c | 10 +++++++--- usr.bin/cmp/special.c | 11 ++++++++--- usr.bin/cmp/tests/Makefile | 5 +++++ usr.bin/cmp/tests/b_flag.out | 1 + usr.bin/cmp/tests/bl_flag.out | 1 + usr.bin/cmp/tests/cmp_test2.sh | 17 +++++++++++++++++ 11 files changed, 70 insertions(+), 16 deletions(-) create mode 100644 usr.bin/cmp/tests/b_flag.out create mode 100644 usr.bin/cmp/tests/bl_flag.out diff --git a/usr.bin/cmp/cmp.1 b/usr.bin/cmp/cmp.1 index 5a56802bd22e..3e616bbe806e 100644 --- a/usr.bin/cmp/cmp.1 +++ b/usr.bin/cmp/cmp.1 @@ -40,7 +40,7 @@ .Sh SYNOPSIS .Nm .Op Fl l | s | x -.Op Fl hz +.Op Fl bhz .Op Fl -ignore-initial Ns Cm = Ns Ar num1 Ns Op :num2 .Op Fl -bytes Ns Cm = Ns Ar num .Ar file1 file2 @@ -59,6 +59,8 @@ Bytes and lines are numbered beginning with one. .Pp The following options are available: .Bl -tag -width indent +.It Fl b , Fl -print-bytes +Print each byte when a difference is found. .It Fl h Do not follow symbolic links. .It Fl i Ar num1 Ns Oo :num2 Oc , Fl -ignore-initial= Ns Ar num1 Ns Op :num2 @@ -187,6 +189,7 @@ utility is expected to be .St -p1003.2 compatible. The +.Fl b , .Fl h , .Fl i , .Fl n , diff --git a/usr.bin/cmp/cmp.c b/usr.bin/cmp/cmp.c index 256cef8a0c31..98ae96c73375 100644 --- a/usr.bin/cmp/cmp.c +++ b/usr.bin/cmp/cmp.c @@ -62,10 +62,11 @@ __FBSDID("$FreeBSD$"); #include "extern.h" -bool lflag, sflag, xflag, zflag; +bool bflag, lflag, sflag, xflag, zflag; static const struct option long_opts[] = { + {"print-bytes", no_argument, NULL, 'b'}, {"ignore-initial", required_argument, NULL, 'i'}, {"verbose", no_argument, NULL, 'l'}, {"bytes", required_argument, NULL, 'n'}, @@ -106,8 +107,11 @@ main(int argc, char *argv[]) skip1 = skip2 = 0; oflag = O_RDONLY; - while ((ch = getopt_long(argc, argv, "+hi:ln:sxz", long_opts, NULL)) != -1) + while ((ch = getopt_long(argc, argv, "+bhi:ln:sxz", long_opts, NULL)) != -1) switch (ch) { + case 'b': /* Print bytes */ + bflag = true; + break; case 'h': /* Don't follow symlinks */ oflag |= O_NOFOLLOW; break; diff --git a/usr.bin/cmp/extern.h b/usr.bin/cmp/extern.h index 803319a50ca4..d98daf424995 100644 --- a/usr.bin/cmp/extern.h +++ b/usr.bin/cmp/extern.h @@ -42,7 +42,7 @@ void c_link(const char *, off_t, const char *, off_t, off_t); void c_regular(int, const char *, off_t, off_t, int, const char *, off_t, off_t, off_t); void c_special(int, const char *, off_t, int, const char *, off_t, off_t); -void diffmsg(const char *, const char *, off_t, off_t); +void diffmsg(const char *, const char *, off_t, off_t, int, int); void eofmsg(const char *); -extern bool lflag, sflag, xflag, zflag; +extern bool bflag, lflag, sflag, xflag, zflag; diff --git a/usr.bin/cmp/link.c b/usr.bin/cmp/link.c index f0b4482a5792..e01a5911faf7 100644 --- a/usr.bin/cmp/link.c +++ b/usr.bin/cmp/link.c @@ -82,10 +82,14 @@ c_link(const char *file1, off_t skip1, const char *file2, off_t skip2, (long long)byte - 1, ch, *p2); } else if (lflag) { dfound = 1; - (void)printf("%6lld %3o %3o\n", - (long long)byte, ch, *p2); + if (bflag) + (void)printf("%6lld %3o %c %3o %c\n", + (long long)byte, ch, ch, *p2, *p2); + else + (void)printf("%6lld %3o %3o\n", + (long long)byte, ch, *p2); } else - diffmsg(file1, file2, byte, 1); + diffmsg(file1, file2, byte, 1, ch, *p2); /* NOTREACHED */ } byte++; diff --git a/usr.bin/cmp/misc.c b/usr.bin/cmp/misc.c index 1e84f0d7a527..1dba34d28792 100644 --- a/usr.bin/cmp/misc.c +++ b/usr.bin/cmp/misc.c @@ -56,10 +56,20 @@ eofmsg(const char *file) } void -diffmsg(const char *file1, const char *file2, off_t byte, off_t line) +diffmsg(const char *file1, const char *file2, off_t byte, off_t line, + int b1, int b2) { - if (!sflag) + if (sflag) + goto out; + + if (bflag) { + (void)printf("%s %s differ: char %lld, line %lld is %3o %c %3o %c\n", + file1, file2, (long long)byte, (long long)line, b1, b1, + b2, b2); + } else { (void)printf("%s %s differ: char %lld, line %lld\n", file1, file2, (long long)byte, (long long)line); + } +out: exit(DIFF_EXIT); } diff --git a/usr.bin/cmp/regular.c b/usr.bin/cmp/regular.c index a60398620282..d270aeeac396 100644 --- a/usr.bin/cmp/regular.c +++ b/usr.bin/cmp/regular.c @@ -127,10 +127,14 @@ c_regular(int fd1, const char *file1, off_t skip1, off_t len1, (long long)byte - 1, ch, *p2); } else if (lflag) { dfound = 1; - (void)printf("%6lld %3o %3o\n", - (long long)byte, ch, *p2); + if (bflag) + (void)printf("%6lld %3o %c %3o %c\n", + (long long)byte, ch, ch, *p2, *p2); + else + (void)printf("%6lld %3o %3o\n", + (long long)byte, ch, *p2); } else - diffmsg(file1, file2, byte, line); + diffmsg(file1, file2, byte, line, ch, *p2); /* NOTREACHED */ } if (ch == '\n') diff --git a/usr.bin/cmp/special.c b/usr.bin/cmp/special.c index 25f755f6e70a..c206a317c0ef 100644 --- a/usr.bin/cmp/special.c +++ b/usr.bin/cmp/special.c @@ -88,10 +88,15 @@ c_special(int fd1, const char *file1, off_t skip1, (long long)byte - 1, ch1, ch2); } else if (lflag) { dfound = 1; - (void)printf("%6lld %3o %3o\n", - (long long)byte, ch1, ch2); + if (bflag) + (void)printf("%6lld %3o %c %3o %c\n", + (long long)byte, ch1, ch1, ch2, + ch2); + else + (void)printf("%6lld %3o %3o\n", + (long long)byte, ch1, ch2); } else { - diffmsg(file1, file2, byte, line); + diffmsg(file1, file2, byte, line, ch1, ch2); /* NOTREACHED */ } } diff --git a/usr.bin/cmp/tests/Makefile b/usr.bin/cmp/tests/Makefile index 087f32f4185f..99469ba42243 100644 --- a/usr.bin/cmp/tests/Makefile +++ b/usr.bin/cmp/tests/Makefile @@ -2,9 +2,14 @@ .include +PACKAGE= tests + ATF_TESTS_SH+= cmp_test2 NETBSD_ATF_TESTS_SH= cmp_test +${PACKAGE}FILES+= b_flag.out +${PACKAGE}FILES+= bl_flag.out + .include .include diff --git a/usr.bin/cmp/tests/b_flag.out b/usr.bin/cmp/tests/b_flag.out new file mode 100644 index 000000000000..bb3d288716b0 --- /dev/null +++ b/usr.bin/cmp/tests/b_flag.out @@ -0,0 +1 @@ +a b differ: char 3, line 1 is 143 c 144 d diff --git a/usr.bin/cmp/tests/bl_flag.out b/usr.bin/cmp/tests/bl_flag.out new file mode 100644 index 000000000000..8ec9007d7ed3 --- /dev/null +++ b/usr.bin/cmp/tests/bl_flag.out @@ -0,0 +1 @@ + 3 143 c 144 d diff --git a/usr.bin/cmp/tests/cmp_test2.sh b/usr.bin/cmp/tests/cmp_test2.sh index 893ee59076c3..c264827646ca 100755 --- a/usr.bin/cmp/tests/cmp_test2.sh +++ b/usr.bin/cmp/tests/cmp_test2.sh @@ -118,6 +118,22 @@ limit_body() atf_check -s exit:1 -o ignore -x "cat a | cmp -sn 5 b -" } +atf_test_case bflag +bflag_head() +{ + atf_set "descr" "Test cmp(1) -b (print bytes)" +} +bflag_body() +{ + echo -n "abcd" > a + echo -n "abdd" > b + + atf_check -s exit:1 -o file:$(atf_get_srcdir)/b_flag.out \ + cmp -b a b + atf_check -s exit:1 -o file:$(atf_get_srcdir)/bl_flag.out \ + cmp -bl a b +} + atf_init_test_cases() { atf_add_test_case special @@ -125,4 +141,5 @@ atf_init_test_cases() atf_add_test_case pr252542 atf_add_test_case skipsuff atf_add_test_case limit + atf_add_test_case bflag }