diff --git a/usr.bin/cmp/cmp.1 b/usr.bin/cmp/cmp.1 --- 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 @@ .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 @@ 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 --- a/usr.bin/cmp/cmp.c +++ b/usr.bin/cmp/cmp.c @@ -66,6 +66,7 @@ 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 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 @@ 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 --- a/usr.bin/cmp/tests/cmp_test2.sh +++ b/usr.bin/cmp/tests/cmp_test2.sh @@ -71,8 +71,13 @@ { 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