From owner-svn-src-head@freebsd.org Mon Apr 20 16:14:45 2020 Return-Path: Delivered-To: svn-src-head@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 74BFE2C6CF5; Mon, 20 Apr 2020 16:14:45 +0000 (UTC) (envelope-from kevans@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 495WxK2XD4z4cLH; Mon, 20 Apr 2020 16:14:45 +0000 (UTC) (envelope-from kevans@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4DCA51A1A8; Mon, 20 Apr 2020 16:14:45 +0000 (UTC) (envelope-from kevans@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id 03KGEjuo073884; Mon, 20 Apr 2020 16:14:45 GMT (envelope-from kevans@FreeBSD.org) Received: (from kevans@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id 03KGEitC073880; Mon, 20 Apr 2020 16:14:44 GMT (envelope-from kevans@FreeBSD.org) Message-Id: <202004201614.03KGEitC073880@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: kevans set sender to kevans@FreeBSD.org using -f From: Kyle Evans Date: Mon, 20 Apr 2020 16:14:44 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r360125 - in head/usr.bin/diff: . tests X-SVN-Group: head X-SVN-Commit-Author: kevans X-SVN-Commit-Paths: in head/usr.bin/diff: . tests X-SVN-Commit-Revision: 360125 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 20 Apr 2020 16:14:45 -0000 Author: kevans Date: Mon Apr 20 16:14:44 2020 New Revision: 360125 URL: https://svnweb.freebsd.org/changeset/base/360125 Log: diff(1): reject conflicting formatting options This matches GNU diff(1) behavior and, more importantly, eliminates any source of confusion if multiple formatting options are specified. Note that the committed diff differs slightly from the submitted: I've modified it so that we initialize diff_format to something that isn't an accepted format option so that we can also reject --normal -c and -c --normal, which would've otherwise been accepted because the default was --normal. After option parsing we default it to D_NORMAL if it's still unset. PR: 243975 Submitted by: fehmi noyan isi MFC after: 1 week Modified: head/usr.bin/diff/diff.c head/usr.bin/diff/diff.h head/usr.bin/diff/tests/diff_test.sh Modified: head/usr.bin/diff/diff.c ============================================================================== --- head/usr.bin/diff/diff.c Mon Apr 20 15:41:40 2020 (r360124) +++ head/usr.bin/diff/diff.c Mon Apr 20 16:14:44 2020 (r360125) @@ -100,6 +100,7 @@ static struct option longopts[] = { }; void usage(void) __dead2; +void conflicting_format(void) __dead2; void push_excludes(char *); void push_ignore_pats(char *); void read_excludes_file(char *file); @@ -120,7 +121,7 @@ main(int argc, char **argv) prevoptind = 1; newarg = 1; diff_context = 3; - diff_format = 0; + diff_format = D_UNSET; while ((ch = getopt_long(argc, argv, OPTIONS, longopts, NULL)) != -1) { switch (ch) { case '0': case '1': case '2': case '3': case '4': @@ -141,6 +142,8 @@ main(int argc, char **argv) break; case 'C': case 'c': + if (diff_format != D_UNSET) + conflicting_format(); cflag = 1; diff_format = D_CONTEXT; if (optarg != NULL) { @@ -154,13 +157,19 @@ main(int argc, char **argv) dflags |= D_MINIMAL; break; case 'D': + if (diff_format != D_UNSET) + conflicting_format(); diff_format = D_IFDEF; ifdefname = optarg; break; case 'e': + if (diff_format != D_UNSET) + conflicting_format(); diff_format = D_EDIT; break; case 'f': + if (diff_format != D_UNSET) + conflicting_format(); diff_format = D_REVERSE; break; case 'H': @@ -193,10 +202,12 @@ main(int argc, char **argv) Nflag = 1; break; case 'n': + if (diff_format != D_UNSET) + conflicting_format(); diff_format = D_NREVERSE; break; case 'p': - if (diff_format == 0) + if (diff_format == D_UNSET) diff_format = D_CONTEXT; dflags |= D_PROTOTYPE; break; @@ -207,6 +218,8 @@ main(int argc, char **argv) rflag = 1; break; case 'q': + if (diff_format != D_UNSET) + conflicting_format(); diff_format = D_BRIEF; break; case 'S': @@ -223,6 +236,8 @@ main(int argc, char **argv) break; case 'U': case 'u': + if (diff_format != D_UNSET) + conflicting_format(); diff_format = D_UNIFIED; if (optarg != NULL) { l = strtol(optarg, &ep, 10); @@ -249,9 +264,13 @@ main(int argc, char **argv) push_excludes(optarg); break; case 'y': + if (diff_format != D_UNSET) + conflicting_format(); diff_format = D_SIDEBYSIDE; break; case OPT_CHANGED_GROUP_FORMAT: + if (diff_format != D_UNSET) + conflicting_format(); diff_format = D_GFORMAT; group_format = optarg; break; @@ -264,6 +283,8 @@ main(int argc, char **argv) ignore_file_case = 0; break; case OPT_NORMAL: + if (diff_format != D_UNSET) + conflicting_format(); diff_format = D_NORMAL; break; case OPT_TSIZE: @@ -287,6 +308,8 @@ main(int argc, char **argv) newarg = optind != prevoptind; prevoptind = optind; } + if (diff_format == D_UNSET) + diff_format = D_NORMAL; argc -= optind; argv += optind; @@ -490,4 +513,12 @@ usage(void) " -y | --side-by-side file1 file2\n"); exit(2); +} + +void +conflicting_format(void) +{ + + fprintf(stderr, "error: conflicting output format options.\n"); + usage(); } Modified: head/usr.bin/diff/diff.h ============================================================================== --- head/usr.bin/diff/diff.h Mon Apr 20 15:41:40 2020 (r360124) +++ head/usr.bin/diff/diff.h Mon Apr 20 16:14:44 2020 (r360125) @@ -50,6 +50,9 @@ #define D_GFORMAT 7 /* Diff with defined changed group format */ #define D_SIDEBYSIDE 8 /* Side by side */ +#define D_UNSET -2 + + /* * Output flags */ Modified: head/usr.bin/diff/tests/diff_test.sh ============================================================================== --- head/usr.bin/diff/tests/diff_test.sh Mon Apr 20 15:41:40 2020 (r360124) +++ head/usr.bin/diff/tests/diff_test.sh Mon Apr 20 16:14:44 2020 (r360125) @@ -11,6 +11,7 @@ atf_test_case brief_format atf_test_case b230049 atf_test_case Bflag atf_test_case tabsize +atf_test_case conflicting_format simple_body() { @@ -49,8 +50,6 @@ unified_body() { atf_check -o file:$(atf_get_srcdir)/unified_p.out -s eq:1 \ diff -up -L input_c1.in -L input_c2.in "$(atf_get_srcdir)/input_c1.in" "$(atf_get_srcdir)/input_c2.in" - atf_check -o file:$(atf_get_srcdir)/unified_c9999.out -s eq:1 \ - diff -u -c9999 -L input_c1.in -L input_c2.in "$(atf_get_srcdir)/input_c1.in" "$(atf_get_srcdir)/input_c2.in" atf_check -o file:$(atf_get_srcdir)/unified_9999.out -s eq:1 \ diff -u9999 -L input_c1.in -L input_c2.in "$(atf_get_srcdir)/input_c1.in" "$(atf_get_srcdir)/input_c2.in" } @@ -175,6 +174,20 @@ tabsize_body() diff -t --tabsize 1 A B } +conflicting_format_body() +{ + printf "\tA\n" > A + printf "\tB\n" > B + + atf_check -s exit:2 -e ignore diff -c -u A B + atf_check -s exit:2 -e ignore diff -e -f A B + atf_check -s exit:2 -e ignore diff -y -q A B + atf_check -s exit:2 -e ignore diff -q -u A B + 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_init_test_cases() { atf_add_test_case simple @@ -188,4 +201,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 }