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
This commit is contained in:
Kyle Evans 2021-09-23 00:46:30 -05:00
parent 8d546b6832
commit f66b9b40f4
11 changed files with 70 additions and 16 deletions

View File

@ -40,7 +40,7 @@
.Sh SYNOPSIS .Sh SYNOPSIS
.Nm .Nm
.Op Fl l | s | x .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 -ignore-initial Ns Cm = Ns Ar num1 Ns Op :num2
.Op Fl -bytes Ns Cm = Ns Ar num .Op Fl -bytes Ns Cm = Ns Ar num
.Ar file1 file2 .Ar file1 file2
@ -59,6 +59,8 @@ Bytes and lines are numbered beginning with one.
.Pp .Pp
The following options are available: The following options are available:
.Bl -tag -width indent .Bl -tag -width indent
.It Fl b , Fl -print-bytes
Print each byte when a difference is found.
.It Fl h .It Fl h
Do not follow symbolic links. Do not follow symbolic links.
.It Fl i Ar num1 Ns Oo :num2 Oc , Fl -ignore-initial= Ns Ar num1 Ns Op :num2 .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 .St -p1003.2
compatible. compatible.
The The
.Fl b ,
.Fl h , .Fl h ,
.Fl i , .Fl i ,
.Fl n , .Fl n ,

View File

@ -62,10 +62,11 @@ __FBSDID("$FreeBSD$");
#include "extern.h" #include "extern.h"
bool lflag, sflag, xflag, zflag; bool bflag, lflag, sflag, xflag, zflag;
static const struct option long_opts[] = static const struct option long_opts[] =
{ {
{"print-bytes", no_argument, NULL, 'b'},
{"ignore-initial", required_argument, NULL, 'i'}, {"ignore-initial", required_argument, NULL, 'i'},
{"verbose", no_argument, NULL, 'l'}, {"verbose", no_argument, NULL, 'l'},
{"bytes", required_argument, NULL, 'n'}, {"bytes", required_argument, NULL, 'n'},
@ -106,8 +107,11 @@ main(int argc, char *argv[])
skip1 = skip2 = 0; skip1 = skip2 = 0;
oflag = O_RDONLY; 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) { switch (ch) {
case 'b': /* Print bytes */
bflag = true;
break;
case 'h': /* Don't follow symlinks */ case 'h': /* Don't follow symlinks */
oflag |= O_NOFOLLOW; oflag |= O_NOFOLLOW;
break; break;

View File

@ -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, void c_regular(int, const char *, off_t, off_t, int, const char *, off_t,
off_t, off_t); off_t, off_t);
void c_special(int, const char *, off_t, int, const char *, 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 *); void eofmsg(const char *);
extern bool lflag, sflag, xflag, zflag; extern bool bflag, lflag, sflag, xflag, zflag;

View File

@ -82,10 +82,14 @@ c_link(const char *file1, off_t skip1, const char *file2, off_t skip2,
(long long)byte - 1, ch, *p2); (long long)byte - 1, ch, *p2);
} else if (lflag) { } else if (lflag) {
dfound = 1; dfound = 1;
if (bflag)
(void)printf("%6lld %3o %c %3o %c\n",
(long long)byte, ch, ch, *p2, *p2);
else
(void)printf("%6lld %3o %3o\n", (void)printf("%6lld %3o %3o\n",
(long long)byte, ch, *p2); (long long)byte, ch, *p2);
} else } else
diffmsg(file1, file2, byte, 1); diffmsg(file1, file2, byte, 1, ch, *p2);
/* NOTREACHED */ /* NOTREACHED */
} }
byte++; byte++;

View File

@ -56,10 +56,20 @@ eofmsg(const char *file)
} }
void 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", (void)printf("%s %s differ: char %lld, line %lld\n",
file1, file2, (long long)byte, (long long)line); file1, file2, (long long)byte, (long long)line);
}
out:
exit(DIFF_EXIT); exit(DIFF_EXIT);
} }

View File

@ -127,10 +127,14 @@ c_regular(int fd1, const char *file1, off_t skip1, off_t len1,
(long long)byte - 1, ch, *p2); (long long)byte - 1, ch, *p2);
} else if (lflag) { } else if (lflag) {
dfound = 1; dfound = 1;
if (bflag)
(void)printf("%6lld %3o %c %3o %c\n",
(long long)byte, ch, ch, *p2, *p2);
else
(void)printf("%6lld %3o %3o\n", (void)printf("%6lld %3o %3o\n",
(long long)byte, ch, *p2); (long long)byte, ch, *p2);
} else } else
diffmsg(file1, file2, byte, line); diffmsg(file1, file2, byte, line, ch, *p2);
/* NOTREACHED */ /* NOTREACHED */
} }
if (ch == '\n') if (ch == '\n')

View File

@ -88,10 +88,15 @@ c_special(int fd1, const char *file1, off_t skip1,
(long long)byte - 1, ch1, ch2); (long long)byte - 1, ch1, ch2);
} else if (lflag) { } else if (lflag) {
dfound = 1; dfound = 1;
if (bflag)
(void)printf("%6lld %3o %c %3o %c\n",
(long long)byte, ch1, ch1, ch2,
ch2);
else
(void)printf("%6lld %3o %3o\n", (void)printf("%6lld %3o %3o\n",
(long long)byte, ch1, ch2); (long long)byte, ch1, ch2);
} else { } else {
diffmsg(file1, file2, byte, line); diffmsg(file1, file2, byte, line, ch1, ch2);
/* NOTREACHED */ /* NOTREACHED */
} }
} }

View File

@ -2,9 +2,14 @@
.include <bsd.own.mk> .include <bsd.own.mk>
PACKAGE= tests
ATF_TESTS_SH+= cmp_test2 ATF_TESTS_SH+= cmp_test2
NETBSD_ATF_TESTS_SH= cmp_test NETBSD_ATF_TESTS_SH= cmp_test
${PACKAGE}FILES+= b_flag.out
${PACKAGE}FILES+= bl_flag.out
.include <netbsd-tests.test.mk> .include <netbsd-tests.test.mk>
.include <bsd.test.mk> .include <bsd.test.mk>

View File

@ -0,0 +1 @@
a b differ: char 3, line 1 is 143 c 144 d

View File

@ -0,0 +1 @@
3 143 c 144 d

View File

@ -118,6 +118,22 @@ limit_body()
atf_check -s exit:1 -o ignore -x "cat a | cmp -sn 5 b -" 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_init_test_cases()
{ {
atf_add_test_case special atf_add_test_case special
@ -125,4 +141,5 @@ atf_init_test_cases()
atf_add_test_case pr252542 atf_add_test_case pr252542
atf_add_test_case skipsuff atf_add_test_case skipsuff
atf_add_test_case limit atf_add_test_case limit
atf_add_test_case bflag
} }