From 8d546b6832eea031f95f30eaec3232ec1256a281 Mon Sep 17 00:00:00 2001 From: Kyle Evans Date: Thu, 23 Sep 2021 00:43:32 -0500 Subject: [PATCH] cmp: add -i, --ignore-initial, an alternative to skip1/skip2 args This is compatible with GNU cmp. Reviewed by: markj Sponsored by: Klara, Inc. Differential Revision: https://reviews.freebsd.org/D32073 --- usr.bin/cmp/cmp.1 | 19 +++++++++++++++++++ usr.bin/cmp/cmp.c | 30 +++++++++++++++++++++++++++++- usr.bin/cmp/tests/cmp_test2.sh | 5 +++++ 3 files changed, 53 insertions(+), 1 deletion(-) diff --git a/usr.bin/cmp/cmp.1 b/usr.bin/cmp/cmp.1 index 511e09ac8628..5a56802bd22e 100644 --- a/usr.bin/cmp/cmp.1 +++ b/usr.bin/cmp/cmp.1 @@ -41,6 +41,7 @@ .Nm .Op Fl l | s | x .Op Fl hz +.Op Fl -ignore-initial Ns Cm = Ns Ar num1 Ns Op :num2 .Op Fl -bytes Ns Cm = Ns Ar num .Ar file1 file2 .Op Ar skip1 Op Ar skip2 @@ -60,6 +61,23 @@ The following options are available: .Bl -tag -width indent .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 +Skip +.Ar num1 +bytes from +.Ar file1 , +and optionally skip +.Ar num2 +bytes from +.Ar file2 . +If +.Ar num2 +is not specified, then +.Ar num1 +is applied for both +.Ar file1 +and +.Ar file2 . .It Fl l , Fl -verbose Print the byte number (decimal) and the differing byte values (octal) for each difference. @@ -170,6 +188,7 @@ utility is expected to be compatible. The .Fl h , +.Fl i , .Fl n , .Fl x , and diff --git a/usr.bin/cmp/cmp.c b/usr.bin/cmp/cmp.c index 384c273f4632..256cef8a0c31 100644 --- a/usr.bin/cmp/cmp.c +++ b/usr.bin/cmp/cmp.c @@ -66,6 +66,7 @@ bool lflag, sflag, xflag, zflag; static const struct option long_opts[] = { + {"ignore-initial", required_argument, NULL, 'i'}, {"verbose", no_argument, NULL, 'l'}, {"bytes", required_argument, NULL, 'n'}, {"silent", no_argument, NULL, 's'}, @@ -75,6 +76,25 @@ static const struct option long_opts[] = static void usage(void); +static bool +parse_iskipspec(char *spec, off_t *skip1, off_t *skip2) +{ + char *colon; + + colon = strchr(spec, ':'); + if (colon != NULL) + *colon++ = '\0'; + + if (expand_number(spec, skip1) < 0) + return (false); + + if (colon != NULL) + return (expand_number(colon, skip2) == 0); + + *skip2 = *skip1; + return (true); +} + int main(int argc, char *argv[]) { @@ -86,11 +106,19 @@ main(int argc, char *argv[]) skip1 = skip2 = 0; oflag = O_RDONLY; - while ((ch = getopt_long(argc, argv, "+hln:sxz", long_opts, NULL)) != -1) + while ((ch = getopt_long(argc, argv, "+hi:ln:sxz", long_opts, NULL)) != -1) switch (ch) { case 'h': /* Don't follow symlinks */ oflag |= O_NOFOLLOW; break; + case 'i': + if (!parse_iskipspec(optarg, &skip1, &skip2)) { + fprintf(stderr, + "Invalid --ignore-initial: %s\n", + optarg); + usage(); + } + break; case 'l': /* print all differences */ lflag = true; break; diff --git a/usr.bin/cmp/tests/cmp_test2.sh b/usr.bin/cmp/tests/cmp_test2.sh index c513984daf8b..893ee59076c3 100755 --- a/usr.bin/cmp/tests/cmp_test2.sh +++ b/usr.bin/cmp/tests/cmp_test2.sh @@ -71,8 +71,13 @@ pr252542_body() { echo -n '1234567890' > a echo -n 'abc567890' > b + echo -n 'xbc567890' > c atf_check -s exit:0 cmp -s a b 4 3 + atf_check -s exit:0 cmp -i 4:3 -s a b + atf_check -s exit:0 cmp -i 1 -s b c atf_check -s exit:1 -o ignore cmp -z a b 4 3 + atf_check -s exit:1 -o ignore cmp -i 4:3 -z a b + atf_check -s exit:1 -o ignore cmp -i 1 -z a b } atf_test_case skipsuff