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
This commit is contained in:
kevans 2020-04-28 14:33:33 +00:00
parent afa3646dbf
commit 277d224e09
2 changed files with 29 additions and 11 deletions

View File

@ -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;

View File

@ -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()