From nobody Thu Aug 01 16:46:56 2024 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4WZZcd5vRCz5T3Dc; Thu, 01 Aug 2024 16:46:57 +0000 (UTC) (envelope-from git@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) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R11" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4WZZcd0nnYz4nGy; Thu, 1 Aug 2024 16:46:57 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1722530817; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=0fA4c8UaMAsp/+qjhBS0mKdb9bCLrrRCsnP+rZGunoQ=; b=LN7HAjeFOfOZo80d0gTG7kSbFmXb/kk9pIMcvGQOzwAQRZZhTgqObhD3JSa+Q2wMenXwgp VCoViqZQx8KlQU3fFr1LRpcJvQFAVbptvXJnrIEplRUHwwGFfODo41ogBOjpvcvfx+qANW X9h3gSnDtRzC0rlBPKAmnZ64MBqqEK546JON7ClD9sa5w5c0E6I7pP0thp8VT5MXIIGY0C zeoZvQlh8RS9TEGbJpxke8v6otmaAL6sfXC0UY9fCtcmbYRlYwUJzy6CuQdtwGsb8zRrSK ByMRyggishrHe12O8a/vKB5WsFFgLiog8XhorV3y8anad8kGOgA8oUvVhXPIvg== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1722530817; a=rsa-sha256; cv=none; b=ZoSAGIP+YeycL+v1HpcSxQBEg98t/DEqsoT/LrshNAn5PmaPnmWOlQb8ljZ2pXzByC6Gcr Sc/SR8c5CeXruKVDa/4nRi/d+zGXv495LmT92Hn6iNTn0tBxm4nWmAOwKoJfUTbkfe8RGN jTMrGIE6p363vkUTpAMXINwwb52N+o+qEVOBEsvL50fc56NHvv1+VyMrFI7dw4kvPPEHwW GD/U89Ken7CR9wGI3aF0j5WKsW6IJ9TabEtQeWFFquZiVdLXdwlBoUutmS8j495mWLV30v pY+sY5vtLUDGyKkog3dz/nP5JlxLhVsJjmt4uecy54pGCwvySTfoLcgewwce6w== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1722530817; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=0fA4c8UaMAsp/+qjhBS0mKdb9bCLrrRCsnP+rZGunoQ=; b=iNIgcfPaX2Nyz2qhmxFnlMd95oa2bK4s9QTlYegqp+fCnGl0RkXQt5cCAS/RatWbgDMx8D zc7Qd2or4Fy2Owino73UtHbd7fg4+agPpGDNAug2DjNcfpTq7iPX1Tc3sGTsyW6jJj4sLf ojZ2DJaRpPbOpb5mEYZBuGY7ocLT3qJGxvPtFKJ5iay0hLSxDcLoELfTkuC3cYZ5cpYN7V jsbwI5pLekuqdi8afdLtD3YqK/mY65XpO5WHe5FsLEqMlJztyFKsGP+ehOv3E6CCW23DiI DS7aeiTer+TXRrK7jrsxr5KchbVjTx/m6bT/n1nGUgNrjm+7Sj6VTB1QvRIPbQ== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4WZZcd0Gt8zsSq; Thu, 1 Aug 2024 16:46:57 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.18.1/8.18.1) with ESMTP id 471GkuSo046654; Thu, 1 Aug 2024 16:46:56 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 471Gku6i046651; Thu, 1 Aug 2024 16:46:56 GMT (envelope-from git) Date: Thu, 1 Aug 2024 16:46:56 GMT Message-Id: <202408011646.471Gku6i046651@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Dag-Erling =?utf-8?Q?Sm=C3=B8rgrav?= Subject: git: 174337b9eca0 - stable/13 - sdiff: Fix --expand-tabs and --tabsize. List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: des X-Git-Repository: src X-Git-Refname: refs/heads/stable/13 X-Git-Reftype: branch X-Git-Commit: 174337b9eca0d28b96f2749b44ff4e29d201c144 Auto-Submitted: auto-generated The branch stable/13 has been updated by des: URL: https://cgit.FreeBSD.org/src/commit/?id=174337b9eca0d28b96f2749b44ff4e29d201c144 commit 174337b9eca0d28b96f2749b44ff4e29d201c144 Author: Dag-Erling Smørgrav AuthorDate: 2024-02-18 17:39:28 +0000 Commit: Dag-Erling Smørgrav CommitDate: 2024-08-01 16:46:18 +0000 sdiff: Fix --expand-tabs and --tabsize. MFC after: 1 week Sponsored by: Klara, Inc. Reviewed by: markj Differential Revision: https://reviews.freebsd.org/D43941 (cherry picked from commit a834edfccd14a8c0f152a3b0078469af8e05f3fd) sdiff: Fix binary case. MFC after: 1 week Sponsored by: Klara, Inc. Reviewed by: markj Differential Revision: https://reviews.freebsd.org/D43942 (cherry picked from commit ad7bef8b890768e68a48bbfa6b92ebf635068504) sdiff: Fix usage message. The `--ignore-all-space` option was incorrectly documented as `--ignore-all-spaces`. MFC after: 3 days Sponsored by: Klara, Inc. Reviewed by: 0mp, markj Differential Revision: https://reviews.freebsd.org/D46161 (cherry picked from commit ca75b7dac886de66fc06fd31facfa2c561f7567e) --- usr.bin/sdiff/sdiff.1 | 4 +- usr.bin/sdiff/sdiff.c | 134 ++++++++++++++++++++++---------------- usr.bin/sdiff/tests/sdiff_test.sh | 36 ++++++++++ 3 files changed, 116 insertions(+), 58 deletions(-) diff --git a/usr.bin/sdiff/sdiff.1 b/usr.bin/sdiff/sdiff.1 index ef9bb95a0990..ca6594c6479a 100644 --- a/usr.bin/sdiff/sdiff.1 +++ b/usr.bin/sdiff/sdiff.1 @@ -3,7 +3,7 @@ .\" Written by Raymond Lai . .\" Public domain. .\" -.Dd April 8, 2017 +.Dd February 16, 2024 .Dt SDIFF 1 .Os .Sh NAME @@ -117,8 +117,6 @@ Ignore all spaces. Ignore blank lines. .It Fl E -ignore-tab-expansion Treat tabs and eight spaces as the same. -.It Fl t -ignore-tabs -Ignore tabs. .It Fl H -speed-large-files Assume scattered small changes in a large file. .It Fl -ignore-file-name-case diff --git a/usr.bin/sdiff/sdiff.c b/usr.bin/sdiff/sdiff.c index 3dcf18caed0c..daa0f43e0b0e 100644 --- a/usr.bin/sdiff/sdiff.c +++ b/usr.bin/sdiff/sdiff.c @@ -51,7 +51,7 @@ static void astrcat(char **, const char *); static void enqueue(char *, char, char *); static char *mktmpcpy(const char *); static int istextfile(FILE *); -static void binexec(char *, char *, char *) __dead2; +static int bindiff(FILE *, char *, FILE *, char *); static void freediff(struct diffline *); static void int_usage(void); static int parsecmd(FILE *, FILE *, FILE *); @@ -72,6 +72,8 @@ static size_t file1ln, file2ln; /* line number of file1 and file2 */ static bool Iflag; /* ignore sets matching regexp */ static bool lflag; /* print only left column for identical lines */ static bool sflag; /* skip identical lines */ +static bool tflag; /* expand tabs */ +static int tabsize = 8; /* tab size */ FILE *outfp; /* file to save changes to */ const char *tmpdir; /* TMPDIR or /tmp */ @@ -127,8 +129,8 @@ static const char *help_msg[] = { "\t-d, --minimal: minimize diff size.", "\t-I RE, --ignore-matching-lines=RE: ignore changes whose line matches RE.", "\t-i, --ignore-case: do a case-insensitive comparison.", - "\t-t, --expand-tabs: sxpand tabs to spaces.", - "\t-W, --ignore-all-spaces: ignore all spaces.", + "\t-t, --expand-tabs: expand tabs to spaces.", + "\t-W, --ignore-all-space: ignore all whitespace.", "\t--speed-large-files: assume large file with scattered changes.", "\t--strip-trailing-cr: strip trailing carriage return.", "\t--ignore-file-name-case: ignore case of file names.", @@ -208,7 +210,7 @@ main(int argc, char **argv) { FILE *diffpipe, *file1, *file2; size_t diffargc = 0, flagc = 0, wval = WIDTH; - int ch, fd[2], i, status; + int ch, fd[2], i, ret, status; pid_t pid; const char *errstr, *outfile = NULL; char **diffargv, *diffprog = diff_path, *flagv; @@ -247,7 +249,6 @@ main(int argc, char **argv) case FCASE_IGNORE_OPT: case FCASE_SENSITIVE_OPT: case STRIPCR_OPT: - case TSIZE_OPT: case 'S': break; /* combine no-arg single switches */ @@ -257,7 +258,6 @@ main(int argc, char **argv) case 'd': case 'E': case 'i': - case 't': case 'W': flagc++; flagv = realloc(flagv, flagc + 2); @@ -287,6 +287,9 @@ main(int argc, char **argv) case 's': sflag = true; break; + case 't': + tflag = true; + break; case 'w': wval = strtonum(optarg, WIDTH_MIN, INT_MAX, &errstr); @@ -298,6 +301,11 @@ main(int argc, char **argv) printf("%s\n", help_msg[i]); exit(0); break; + case TSIZE_OPT: + tabsize = strtonum(optarg, 1, INT_MAX, &errstr); + if (errstr) + errx(2, "tabsize is %s: %s", errstr, optarg); + break; default: usage(); break; @@ -348,6 +356,15 @@ main(int argc, char **argv) filename2 = tmp2; } + if ((file1 = fopen(filename1, "r")) == NULL) + err(2, "could not open %s", filename1); + if ((file2 = fopen(filename2, "r")) == NULL) + err(2, "could not open %s", filename2); + if (!istextfile(file1) || !istextfile(file2)) { + ret = bindiff(file1, filename1, file2, filename2); + goto done; + } + diffargv[diffargc++] = filename1; diffargv[diffargc++] = filename2; /* Add NULL to end of array to indicate end of array. */ @@ -385,26 +402,6 @@ main(int argc, char **argv) if ((diffpipe = fdopen(fd[0], "r")) == NULL) err(2, "could not open diff pipe"); - if ((file1 = fopen(filename1, "r")) == NULL) - err(2, "could not open %s", filename1); - if ((file2 = fopen(filename2, "r")) == NULL) - err(2, "could not open %s", filename2); - if (!istextfile(file1) || !istextfile(file2)) { - /* Close open files and pipe, delete temps */ - fclose(file1); - fclose(file2); - if (diffpipe != NULL) - fclose(diffpipe); - if (tmp1) - if (unlink(tmp1)) - warn("Error deleting %s.", tmp1); - if (tmp2) - if (unlink(tmp2)) - warn("Error deleting %s.", tmp2); - free(tmp1); - free(tmp2); - binexec(diffprog, filename1, filename2); - } /* Line numbers start at one. */ file1ln = file2ln = 1; @@ -416,20 +413,10 @@ main(int argc, char **argv) /* Wait for diff to exit. */ if (waitpid(pid, &status, 0) == -1 || !WIFEXITED(status) || WEXITSTATUS(status) >= 2) - err(2, "diff exited abnormally."); + errx(2, "diff exited abnormally"); + ret = WEXITSTATUS(status); - /* Delete and free unneeded temporary files. */ - if (tmp1) - if (unlink(tmp1)) - warn("Error deleting %s.", tmp1); - if (tmp2) - if (unlink(tmp2)) - warn("Error deleting %s.", tmp2); - free(tmp1); - free(tmp2); - filename1 = filename2 = tmp1 = tmp2 = NULL; - - /* No more diffs, so print common lines. */ + /* No more diffs, so enqueue common lines. */ if (lflag) while ((s1 = xfgets(file1))) enqueue(s1, ' ', NULL); @@ -447,26 +434,55 @@ main(int argc, char **argv) /* Process unmodified lines. */ processq(); +done: + /* Delete and free unneeded temporary files. */ + if (tmp1 != NULL) { + if (unlink(tmp1) != 0) + warn("failed to delete %s", tmp1); + free(tmp1); + } + if (tmp2 != NULL) { + if (unlink(tmp2) != 0) + warn("failed to delete %s", tmp2); + free(tmp2); + } + /* Return diff exit status. */ free(diffargv); if (flagc > 0) free(flagv); - return (WEXITSTATUS(status)); + return (ret); } /* - * When sdiff detects a binary file as input, executes them with - * diff to maintain the same behavior as GNU sdiff with binary input. + * When sdiff detects a binary file as input. */ -static void -binexec(char *diffprog, char *f1, char *f2) +static int +bindiff(FILE *f1, char *fn1, FILE *f2, char *fn2) { - - char *args[] = {diffprog, f1, f2, (char *) 0}; - execv(diffprog, args); - - /* If execv() fails, sdiff's execution will continue below. */ - errx(1, "could not execute diff process"); + int ch1, ch2; + + flockfile(f1); + flockfile(f2); + do { + ch1 = getc_unlocked(f1); + ch2 = getc_unlocked(f2); + } while (ch1 != EOF && ch2 != EOF && ch1 == ch2); + funlockfile(f2); + funlockfile(f1); + if (ferror(f1)) { + warn("%s", fn1); + return (2); + } + if (ferror(f2)) { + warn("%s", fn2); + return (2); + } + if (ch1 != EOF || ch2 != EOF) { + printf("Binary files %s and %s differ\n", fn1, fn2); + return (1); + } + return (0); } /* @@ -512,11 +528,11 @@ printcol(const char *s, size_t *col, const size_t col_max) * If rounding to next multiple of eight causes * an integer overflow, just return. */ - if (*col > SIZE_MAX - 8) + if (*col > SIZE_MAX - tabsize) return; /* Round to next multiple of eight. */ - new_col = (*col / 8 + 1) * 8; + new_col = (*col / tabsize + 1) * tabsize; /* * If printing the tab goes past the column @@ -524,12 +540,20 @@ printcol(const char *s, size_t *col, const size_t col_max) */ if (new_col > col_max) return; - *col = new_col; + + if (tflag) { + do { + putchar(' '); + } while (++*col < new_col); + } else { + putchar(*s); + *col = new_col; + } break; default: - ++(*col); + ++*col; + putchar(*s); } - putchar(*s); } } diff --git a/usr.bin/sdiff/tests/sdiff_test.sh b/usr.bin/sdiff/tests/sdiff_test.sh index 100fa1b123b0..83ed93503f18 100755 --- a/usr.bin/sdiff/tests/sdiff_test.sh +++ b/usr.bin/sdiff/tests/sdiff_test.sh @@ -191,6 +191,40 @@ short_body() $(atf_get_srcdir)/d_input2 >/dev/null ; cat merge.out" } +atf_test_case tflag +tflag_head() +{ + atf_set "descr" "Checks tab expansion" +} +tflag_body() +{ + printf "a\tb\n" >a + printf "b\ta\n" >b + atf_check -s exit:1 -o match:$'a\tb' \ + sdiff a b + atf_check -s exit:1 -o match:"a {7}b" \ + sdiff -t a b + atf_check -s exit:1 -o match:"a {3}b" \ + sdiff -t --tabsize 4 a b +} + +atf_test_case binary +binary_head() +{ + atf_set "descr" "Checks binary file handling" +} +binary_body() +{ + printf "a\0\n" >a + printf "b\0\n" >b + atf_check -o empty sdiff a a + atf_check -o empty sdiff a -