From 277d224e0917901373cd6ed1fbbccb2058cf6b27 Mon Sep 17 00:00:00 2001 From: kevans Date: Tue, 28 Apr 2020 14:33:33 +0000 Subject: [PATCH] diff(1): don't reject specifying the same format multiple times This may happen, for instance, if one happens to have an alias of diff to diff -up and attempts to specify the amount of context on top of that. Aliases like this may cause other problems, but if they're really not ever generating non-unified diffs then we should at least not break that use-case. In addition, we'll now pick up a format mismatch if -p is specified with !contextual && !unified && !unset. Fix up a small trailing whitespace nit in the tests while we're here, and add tests to make sure that we can double up all the formatting options. Reported by: jbeich MFC after: 3 days --- usr.bin/diff/diff.c | 31 +++++++++++++++++++++---------- usr.bin/diff/tests/diff_test.sh | 9 ++++++++- 2 files changed, 29 insertions(+), 11 deletions(-) diff --git a/usr.bin/diff/diff.c b/usr.bin/diff/diff.c index 91928651b188..7755419f2a45 100644 --- a/usr.bin/diff/diff.c +++ b/usr.bin/diff/diff.c @@ -122,6 +122,8 @@ main(int argc, char **argv) newarg = 1; diff_context = 3; diff_format = D_UNSET; +#define FORMAT_MISMATCHED(type) \ + (diff_format != D_UNSET && diff_format != (type)) while ((ch = getopt_long(argc, argv, OPTIONS, longopts, NULL)) != -1) { switch (ch) { case '0': case '1': case '2': case '3': case '4': @@ -142,7 +144,7 @@ main(int argc, char **argv) break; case 'C': case 'c': - if (diff_format != D_UNSET) + if (FORMAT_MISMATCHED(D_CONTEXT)) conflicting_format(); cflag = 1; diff_format = D_CONTEXT; @@ -157,18 +159,18 @@ main(int argc, char **argv) dflags |= D_MINIMAL; break; case 'D': - if (diff_format != D_UNSET) + if (FORMAT_MISMATCHED(D_IFDEF)) conflicting_format(); diff_format = D_IFDEF; ifdefname = optarg; break; case 'e': - if (diff_format != D_UNSET) + if (FORMAT_MISMATCHED(D_EDIT)) conflicting_format(); diff_format = D_EDIT; break; case 'f': - if (diff_format != D_UNSET) + if (FORMAT_MISMATCHED(D_REVERSE)) conflicting_format(); diff_format = D_REVERSE; break; @@ -202,11 +204,20 @@ main(int argc, char **argv) Nflag = 1; break; case 'n': - if (diff_format != D_UNSET) + if (FORMAT_MISMATCHED(D_NREVERSE)) conflicting_format(); diff_format = D_NREVERSE; break; case 'p': + /* + * If it's not unset and it's not set to context or + * unified, we'll error out here as a conflicting + * format. If it's unset, we'll go ahead and set it to + * context. + */ + if (FORMAT_MISMATCHED(D_CONTEXT) && + FORMAT_MISMATCHED(D_UNIFIED)) + conflicting_format(); if (diff_format == D_UNSET) diff_format = D_CONTEXT; dflags |= D_PROTOTYPE; @@ -218,7 +229,7 @@ main(int argc, char **argv) rflag = 1; break; case 'q': - if (diff_format != D_UNSET) + if (FORMAT_MISMATCHED(D_BRIEF)) conflicting_format(); diff_format = D_BRIEF; break; @@ -236,7 +247,7 @@ main(int argc, char **argv) break; case 'U': case 'u': - if (diff_format != D_UNSET) + if (FORMAT_MISMATCHED(D_UNIFIED)) conflicting_format(); diff_format = D_UNIFIED; if (optarg != NULL) { @@ -264,12 +275,12 @@ main(int argc, char **argv) push_excludes(optarg); break; case 'y': - if (diff_format != D_UNSET) + if (FORMAT_MISMATCHED(D_SIDEBYSIDE)) conflicting_format(); diff_format = D_SIDEBYSIDE; break; case OPT_CHANGED_GROUP_FORMAT: - if (diff_format != D_UNSET) + if (FORMAT_MISMATCHED(D_GFORMAT)) conflicting_format(); diff_format = D_GFORMAT; group_format = optarg; @@ -283,7 +294,7 @@ main(int argc, char **argv) ignore_file_case = 0; break; case OPT_NORMAL: - if (diff_format != D_UNSET) + if (FORMAT_MISMATCHED(D_NORMAL)) conflicting_format(); diff_format = D_NORMAL; break; diff --git a/usr.bin/diff/tests/diff_test.sh b/usr.bin/diff/tests/diff_test.sh index 8385a6224865..6f4b484b3a37 100755 --- a/usr.bin/diff/tests/diff_test.sh +++ b/usr.bin/diff/tests/diff_test.sh @@ -186,6 +186,13 @@ conflicting_format_body() atf_check -s exit:2 -e ignore diff -q -c A B atf_check -s exit:2 -e ignore diff --normal -c A B atf_check -s exit:2 -e ignore diff -c --normal A B + + atf_check -s exit:1 -o ignore -e ignore diff -u -u A B + atf_check -s exit:1 -o ignore -e ignore diff -e -e A B + atf_check -s exit:1 -o ignore -e ignore diff -y -y A B + atf_check -s exit:1 -o ignore -e ignore diff -q -q A B + atf_check -s exit:1 -o ignore -e ignore diff -c -c A B + atf_check -s exit:1 -o ignore -e ignore diff --normal --normal A B } atf_init_test_cases() @@ -201,5 +208,5 @@ atf_init_test_cases() atf_add_test_case b230049 atf_add_test_case Bflag atf_add_test_case tabsize - atf_add_test_case conflicting_format + atf_add_test_case conflicting_format }