From nobody Mon Sep 07 04:21:23 2026 X-Original-To: dev-commits-src-branches@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 4hdYmN4Ptyz6rMVD for ; Mon, 07 Sep 2026 04:21:24 +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 "YR2" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4hdYmM696gz3TVt for ; Mon, 07 Sep 2026 04:21:23 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1788754883; 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=Zx6KZHIqzekEwTNlG8lvUp2g9MAsHBh0Kx+e3Meva9U=; b=E+fbDSIWOtPePUEwdevaLIFQUovktCRS9pQC1+4sG3NmZtMj999tO8ytnKrJWdReTwdFA/ N0XE2z4eDYV18mCPw/YsgY63jp+bCfwTVhDo6GcvN8xKeprWcodGy6f3NXagoNivVS5rXC TaFUqMX0cASiqTaImB+pHTMb+sMfs1guiqS5BtNH9HxBjXtseiW3S4YbPA7AgyqEch4m+a Z9FIuyZHc6FL/yIrYset0wkU6KuhS9yJiIOtkZ+kfIbJto0D3aiklpUExORHHHvVy6UGzs ySWLWGptZoGom53mW5ck7uK9CwrBhSD8XEvbo0BGs+hrB3bOkOWmo+3Q8VFikw== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1788754883; a=rsa-sha256; cv=none; b=k13zSfj/LyNKB5iqIRNzv/eHNYdtJIE/ioiWPov+y+PrcgzDWRnBG+2qdpySaK3weI5WfQ bIi+Xu7+aeIQUyTAcmcA2dudwRhSy3s6DTE89915aepxoBQhmNSOhPp2LdTJr3FgyQu5Bk z6hyCAzX/+DgAk0w/84s/Ubx1Si3sgA6JqXe+KRSe44JFeQYIRR4I2YxEHOgc7C9CCIKaZ S5UjWo1hhDYmcPNqdsZQLOUvd1rAZ8N073ML6uM7/Q24jALfbjAKcaQvy2nE8XThdZl27N GzWVJWCnD1NL+68NorNob5gxrcd3w5/vcaqyNpRce8A+OV8VrZPUb77yP24oZA== 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=1788754883; 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=Zx6KZHIqzekEwTNlG8lvUp2g9MAsHBh0Kx+e3Meva9U=; b=u0jnc6OlPsJLe1SyAtUTKsBU8LSR8ssG/xR9rZlO2hUmddE7va+uTL8biqGaOLusQ3IXUR Vb0KSeuhF4fZDuPGxH6scOI+KLLYiZF9Z1qUSLnaC1e0F8P0aXw03RiUEZdEN/8EVbC2A2 ZPcwzBJ2VhyCmmQyn2iJjJdUUYL9lCQY+oPoYTOrrUK7GVr07vZYeZLKK4rwx3TR0fp+E3 k3ZaKVcs0JKYj2aLxjbkX2hqqw/hc6o2TsoEuOYKFuR9S+W7pck7ewHaSz3BbHRW1jGJEL KGjzAO6TmAVFtfD/ukQDVoiI2IoM/Sf3UkcJavRZ9Fp47TReDurDZRMhCbJvAA== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4hdYmM57pnz12jr for ; Mon, 07 Sep 2026 04:21:23 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 1c5c5 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Mon, 07 Sep 2026 04:21:23 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Baptiste Daroussin Subject: git: d8c4785e1e41 - stable/15 - cat: add -A, -E and -T flags List-Id: Commits to the stable branches of the FreeBSD src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-branches List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-branches@freebsd.org Sender: owner-dev-commits-src-branches@FreeBSD.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: bapt X-Git-Repository: src X-Git-Refname: refs/heads/stable/15 X-Git-Reftype: branch X-Git-Commit: d8c4785e1e41860ad469ac3f67149d0d84ee6590 Auto-Submitted: auto-generated Date: Mon, 07 Sep 2026 04:21:23 +0000 Message-Id: <6a9e3bc3.1c5c5.85cc664@gitrepo.freebsd.org> The branch stable/15 has been updated by bapt: URL: https://cgit.FreeBSD.org/src/commit/?id=d8c4785e1e41860ad469ac3f67149d0d84ee6590 commit d8c4785e1e41860ad469ac3f67149d0d84ee6590 Author: Baptiste Daroussin AuthorDate: 2026-08-21 14:41:54 +0000 Commit: Baptiste Daroussin CommitDate: 2026-09-07 04:21:07 +0000 cat: add -A, -E and -T flags Support cat -A, -E and -T, which are commonly used by Linux shell scripts. -E prints a "$" at the end of each line, -T renders tabs as ^I, and -A is equivalent to -vET. MFC After: 1 week Discussed with: jrtc27 Reviewed by: jrtc27, ziaee Differential Revision: https://reviews.freebsd.org/D59250 (cherry picked from commit d2cfdf4c12a76db3612c83575403150811f5aa9a) --- bin/cat/cat.1 | 32 ++++++++++++++++------ bin/cat/cat.c | 25 +++++++++++------ bin/cat/tests/Makefile | 1 + bin/cat/tests/cat_extra_test.sh | 59 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 101 insertions(+), 16 deletions(-) diff --git a/bin/cat/cat.1 b/bin/cat/cat.1 index 59e0dff80ed0..7112b8167eef 100644 --- a/bin/cat/cat.1 +++ b/bin/cat/cat.1 @@ -29,7 +29,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd January 29, 2013 +.Dd August 21, 2026 .Dt CAT 1 .Os .Sh NAME @@ -37,7 +37,7 @@ .Nd concatenate and print files .Sh SYNOPSIS .Nm -.Op Fl belnstuv +.Op Fl AbeElnstTuv .Op Ar .Sh DESCRIPTION The @@ -68,12 +68,24 @@ domain binding capability available in .Pp The options are as follows: .Bl -tag -width indent +.It Fl A +Equivalent to specifying the +.Fl v +, +.Fl E +and +.Fl T +options. .It Fl b Number the non-blank output lines, starting at 1. .It Fl e -Display non-printing characters (see the +Equivalent to specifying the +.Fl E +and .Fl v -option), and display a dollar sign +options. +.It Fl E +Display a dollar sign .Pq Ql \&$ at the end of each line. .It Fl l @@ -91,11 +103,15 @@ Number the output lines, starting at 1. .It Fl s Squeeze multiple adjacent empty lines, causing the output to be single spaced. +.It Fl T +Display tab characters as +.Ql ^I . .It Fl t -Display non-printing characters (see the +Equivalent to specifying the +.Fl T +and .Fl v -option), and display tab characters as -.Ql ^I . +options. .It Fl u Disable output buffering. .It Fl v @@ -183,7 +199,7 @@ utility is compliant with the specification. .Pp The flags -.Op Fl belnstv +.Op Fl AbeElnstTv are extensions to the specification. .Sh HISTORY A diff --git a/bin/cat/cat.c b/bin/cat/cat.c index 8c10faf7cff9..20a20b44d9f7 100644 --- a/bin/cat/cat.c +++ b/bin/cat/cat.c @@ -58,7 +58,7 @@ #include #include -static int bflag, eflag, lflag, nflag, sflag, tflag, vflag; +static int bflag, Eflag, lflag, nflag, sflag, Tflag, vflag; static int rval; static const char *filename; static fileargs_t *fa; @@ -103,7 +103,7 @@ static int udom_open(const char *path, int flags); #ifdef BOOTSTRAP_CAT #define SUPPORTED_FLAGS "lu" #else -#define SUPPORTED_FLAGS "belnstuv" +#define SUPPORTED_FLAGS "belnstuvAET" #endif #ifndef NO_UDOM_SUPPORT @@ -166,8 +166,14 @@ main(int argc, char *argv[]) case 'b': bflag = nflag = 1; /* -b implies -n */ break; + case 'A': + Eflag = Tflag = vflag = 1; /* -A implies -v -E -T */ + break; case 'e': - eflag = vflag = 1; /* -e implies -v */ + Eflag = vflag = 1; /* -e implies -v */ + break; + case 'E': + Eflag = 1; break; case 'l': lflag = 1; @@ -179,7 +185,10 @@ main(int argc, char *argv[]) sflag = 1; break; case 't': - tflag = vflag = 1; /* -t implies -v */ + Tflag = vflag = 1; /* -t implies -v */ + break; + case 'T': + Tflag = 1; break; case 'u': setbuf(stdout, NULL); @@ -209,7 +218,7 @@ main(int argc, char *argv[]) if (caph_enter_casper() != 0) err(EXIT_FAILURE, "capsicum"); - if (bflag || eflag || nflag || sflag || tflag || vflag) + if (bflag || Eflag || nflag || sflag || Tflag || vflag) scanfiles(argv, 1); else scanfiles(argv, 0); @@ -313,7 +322,7 @@ cook_cat(FILE *fp) (void)fprintf(stdout, "%6d\t", ++line); if (ferror(stdout)) break; - } else if (eflag) { + } else if (Eflag) { (void)fprintf(stdout, "%6s\t", ""); if (ferror(stdout)) break; @@ -321,10 +330,10 @@ cook_cat(FILE *fp) } } if (ch == '\n') { - if (eflag && putchar('$') == EOF) + if (Eflag && putchar('$') == EOF) break; } else if (ch == '\t') { - if (tflag) { + if (Tflag) { if (putchar('^') == EOF || putchar('I') == EOF) break; continue; diff --git a/bin/cat/tests/Makefile b/bin/cat/tests/Makefile index 347f4826ba4d..38fcff5eaf36 100644 --- a/bin/cat/tests/Makefile +++ b/bin/cat/tests/Makefile @@ -1,5 +1,6 @@ PACKAGE= tests +ATF_TESTS_SH= cat_extra_test NETBSD_ATF_TESTS_SH= cat_test ${PACKAGE}FILES+= d_align.in diff --git a/bin/cat/tests/cat_extra_test.sh b/bin/cat/tests/cat_extra_test.sh new file mode 100644 index 000000000000..87d617122abf --- /dev/null +++ b/bin/cat/tests/cat_extra_test.sh @@ -0,0 +1,59 @@ +# +# SPDX-License-Identifier: BSD-2-Clause +# +# Copyright (c) 2026 Baptiste Daroussin +# +# + +atf_test_case E_output +E_output_body() +{ + printf 'a\tb\n\001c\n\177\n' > input + atf_check -o 'inline:a\tb$\n\001c$\n\0177$\n' cat -E input +} + +atf_test_case T_output +T_output_body() +{ + printf 'a\tb\n\001c\n\177\n' > input + atf_check -o 'inline:a^Ib\n\001c\n\0177\n' cat -T input +} + +atf_test_case A_output +A_output_body() +{ + printf 'a\tb\n\001c\n\177\n' > input + + # -A implies -v, -E and -T. + expected='a^Ib$\n^Ac$\n^?$\n' + atf_check -o "inline:${expected}" cat -A input + atf_check -o "inline:${expected}" cat -vET input + atf_check -o "inline:${expected}" cat -AET input +} + +atf_test_case e_implies_v +e_implies_v_body() +{ + printf 'a\tb\n\001c\n\177\n' > input + + atf_check -o 'inline:a\tb$\n^Ac$\n^?$\n' cat -e input + atf_check -o 'inline:a\tb$\n^Ac$\n^?$\n' cat -Ev input +} + +atf_test_case t_implies_v +t_implies_v_body() +{ + printf 'a\tb\n\001c\n\177\n' > input + + atf_check -o 'inline:a^Ib\n^Ac\n^?\n' cat -t input + atf_check -o 'inline:a^Ib\n^Ac\n^?\n' cat -Tv input +} + +atf_init_test_cases() +{ + atf_add_test_case E_output + atf_add_test_case T_output + atf_add_test_case A_output + atf_add_test_case e_implies_v + atf_add_test_case t_implies_v +}