From nobody Mon Aug 31 12:38:02 2026 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 4hYT6g2qHPz6qhhF for ; Mon, 31 Aug 2026 12:38:03 +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 4hYT6g0fzfz3G6p for ; Mon, 31 Aug 2026 12:38:03 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1788179883; 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=pOaXgKDZsaaUh1dslF26kVKXo0zXyBNY+ocEz6c6I7M=; b=xmn358vKLAQyaONEhgET+9z38mFNmj4EhDmTUUZGjQkw4OsDunDRoDWx/uGOpPyDjnior9 VKEtQORO1mp1aV02UyG2HbYWodGwbAOHRsR4sHnmGCcJWYOkxEDNUAw8dq+nKWlqg62lje fX2ZWlaQKPafUozfsmu60dK3qWErvAgnaLaY1NJu/W1nQJUeswNke6XWLwrkat34yhOk6V Fj6uVCluuC5yNNutHUfHnK8bdAO2iYjNLTHnR2YgA+SLTbPHBrO8RgOkQ/cDwjX2sqBztj J5k87Cm3JNq/9XmXbVUiBNj/AUccZoYKXyoN8q8AJ0UU/iCZcPHCgaMtpy+rEA== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1788179883; a=rsa-sha256; cv=none; b=ReV4ja9isa70vcJVJLlUGJ/MU+AcgkH1aCnKZkYZORdyTzvPy0gmJ+weyc8W6dpUlzbgY9 bxNya7TMDSrWthGEEhqEWN3hb3GWkZt6mvKmk2/V8dTHndYZdoNIPJKdz6JXDcXlQGY8RP sCXBgdLc6EyVwQgd2Mvq6ENycfQXBMjmwwbsoZPnJ6TvtWaRXo5qldLlATFFVdpdyrjus3 cAr8vYQCjKXQZJVnbAvmNCaYtIg/g8Ou0pmwJ8W3aIy8lOgHe+3a+syqcD8MrFKUqk4Nx4 m7YbRfQJBwikPWmU4DeDSq177aEER/J3KAvoQxkpz/neusZgXWjKb5R+CV1RdQ== 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=1788179883; 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=pOaXgKDZsaaUh1dslF26kVKXo0zXyBNY+ocEz6c6I7M=; b=aGiAo0uv+wYeXoDgBlG1nDPtSqtodL7lerdBVyz6rCwowEBZ8p8iUotnpgYFpOautmnzK6 tsmtakpWZF0UYqy/mT0fNuL6/ZTwt+0o/OBUfSiop3XvYusUxjMXEa6O7DAiP3E6/f6d3M U7DpDdhieJqaBAT1N/eO/2seEIb7guOTTA4K1Yj5DLr0MGMG81WQv1E5rN6ZH2pQfRDoy8 OBqkErbf/sCz3IGFxQLpNiDW3ouFqpYwv0HH5ud8idvTFnXQsXPMyFA70kuwUXBd+BqPXd 9c3E3lfucxic+roN4EFCodbnuDMvwIrgbOJtE0As+vfIkz3DBy6CcLICW0/lOg== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4hYT6f6ZvZz1B0p for ; Mon, 31 Aug 2026 12:38:02 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 39074 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Mon, 31 Aug 2026 12:38:02 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Baptiste Daroussin Subject: git: d2cfdf4c12a7 - main - cat: add -A, -E and -T flags 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 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/main X-Git-Reftype: branch X-Git-Commit: d2cfdf4c12a76db3612c83575403150811f5aa9a Auto-Submitted: auto-generated Date: Mon, 31 Aug 2026 12:38:02 +0000 Message-Id: <6a9575aa.39074.4264a7f8@gitrepo.freebsd.org> The branch main has been updated by bapt: URL: https://cgit.FreeBSD.org/src/commit/?id=d2cfdf4c12a76db3612c83575403150811f5aa9a commit d2cfdf4c12a76db3612c83575403150811f5aa9a Author: Baptiste Daroussin AuthorDate: 2026-08-21 14:41:54 +0000 Commit: Baptiste Daroussin CommitDate: 2026-08-31 12:35:21 +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 --- 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 +}