From nobody Sun Oct 30 23:12:56 2022 X-Original-To: dev-commits-src-main@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 4N0sWs08RVz4gt7f; Sun, 30 Oct 2022 23:12: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 "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4N0sWr6XjSz3Cmv; Sun, 30 Oct 2022 23:12:56 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1667171576; 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=s93Q6MfwNn+UeTAwDmjoKrUvGm0PD3Y3Xu2qxmQBHgg=; b=oYmLSMmFovStqtML8uTJOxTF+teT6plsjFAvzAKeWMNumPHTriZkfgWHpDAckLW9oR3vsI z6BVknPyMROsnpPfeO+mVGQeKAn9ULeHtdslGFn8T16zAMF/fQ13YhYxJD1+K0B9dADGpe Ed/CFiXY+BT5/+gWpYkLZlZvzAS/gvDR/garnr7zY2zpkMGzbF9idtxOPUah993N/w5lAH Yi9NZZ3NgCVp9wJhYSk7mwjt/6hslsNln7RqcgrlI8mT6/IVr8Ja61/Pxv1hG7IhEwRC0u wkUS6HuKbOT3/Bd4pn2nOCYqN5Y3zMtHXGjApljdI2UGkeCP2EdHR+K3hcaaMA== 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 4N0sWr5ZQjzFZP; Sun, 30 Oct 2022 23:12:56 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 29UNCupO079192; Sun, 30 Oct 2022 23:12:56 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 29UNCupR079191; Sun, 30 Oct 2022 23:12:56 GMT (envelope-from git) Date: Sun, 30 Oct 2022 23:12:56 GMT Message-Id: <202210302312.29UNCupR079191@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Piotr Pawel Stefaniak Subject: git: e2662256cdbc - main - ls(1): add a -v flag to sort naturally List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-main@freebsd.org X-BeenThere: dev-commits-src-main@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: pstef X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: e2662256cdbc6ca9be49a66837f9725081cfa9d3 Auto-Submitted: auto-generated ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1667171576; 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=s93Q6MfwNn+UeTAwDmjoKrUvGm0PD3Y3Xu2qxmQBHgg=; b=npESmo6egsq9DP9ja7gHdbpxbuKHhdeoYAmTuoSjKEsj+Rf1dVhbOks4XsAJEvJR6XLBMk 9roIqH+aPw9tnBqpJPcR53edtZnfX2VVIVT+5DAQRmSWORUTZpw/ZyZcWf/o3ed3roeo8o mJRC59ngpslB7IzP65bRvrDWEKWvrzm86nLhwm2ULWMYOKQXC0y12O5zIqfqHIk3gLWP6o 1CK3joFnm+OzYYv3QKs5/L7N1HOs5BfkF9C5uPINm6zccI7BwwkDHLj1xByAQ16ijYz17e ypFf208UElDSVFttu8JFR3qjv8ft91i+IYPgT6k30iGS9xgCGQTvpsySU1/hVg== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1667171576; a=rsa-sha256; cv=none; b=GzVe8XwRypbz+7bV+hcnwQXRgq35gEGO4Wd+YZY2TweZfLd0R8/CvoIoV6U8SnZeHYERtz P5NX22S2xSq41YYn8B8WVN0zF9j1d7wJtz4CXldKZDkCgo0EQkwvyP+4j1J5IzZdKsDrnA 781O9XBhdav2KRgUai3EzDnKCS2bVPJRtxp48c+fT8YN9L2cg6fWra0H74uyrivm9VuqE9 PLptUDRyj9pBW+n55KLqleSu6OYYVGy55YbyVNnmzUB2AZMB6cl0C0f/MIdTZzTKuBvlIX y5lEQl7V8sCj6JuFfbbEGtdGdFW/l02wB/R1lwICm5EtsasL0oiMuRvJVoCxXg== ARC-Authentication-Results: i=1; mx1.freebsd.org; none X-ThisMailContainsUnwantedMimeParts: N The branch main has been updated by pstef: URL: https://cgit.FreeBSD.org/src/commit/?id=e2662256cdbc6ca9be49a66837f9725081cfa9d3 commit e2662256cdbc6ca9be49a66837f9725081cfa9d3 Author: Aymeric Wibo AuthorDate: 2022-10-23 07:46:27 +0000 Commit: Piotr Pawel Stefaniak CommitDate: 2022-10-30 23:00:42 +0000 ls(1): add a -v flag to sort naturally Add a -v flag for ls which sorts entries following a natural ordering using strverscmp(3) (e.g. "bloem1 bloem9 bloem10" as opposed to "bloem1 bloem10 bloem9"). Update the manual page and add a test case. Reviewed by: pauamma, bcr Tested by: pstef Differential Revision: https://reviews.freebsd.org/D36407 --- bin/ls/cmp.c | 14 ++++++++++++++ bin/ls/extern.h | 2 ++ bin/ls/ls.1 | 22 +++++++++++++++++++--- bin/ls/ls.c | 22 +++++++++++++++------- bin/ls/tests/ls_tests.sh | 15 +++++++++++++++ bin/ls/util.c | 4 ++-- 6 files changed, 67 insertions(+), 12 deletions(-) diff --git a/bin/ls/cmp.c b/bin/ls/cmp.c index 13ba3ff47a99..4f2c8bcfc846 100644 --- a/bin/ls/cmp.c +++ b/bin/ls/cmp.c @@ -64,6 +64,20 @@ revnamecmp(const FTSENT *a, const FTSENT *b) return (strcoll(b->fts_name, a->fts_name)); } +int +verscmp(const FTSENT *a, const FTSENT *b) +{ + + return (strverscmp(a->fts_name, b->fts_name)); +} + +int +revverscmp(const FTSENT *a, const FTSENT *b) +{ + + return (strverscmp(b->fts_name, a->fts_name)); +} + int modcmp(const FTSENT *a, const FTSENT *b) { diff --git a/bin/ls/extern.h b/bin/ls/extern.h index 247c2c4a1d5b..0e577a885474 100644 --- a/bin/ls/extern.h +++ b/bin/ls/extern.h @@ -42,6 +42,8 @@ int modcmp(const FTSENT *, const FTSENT *); int revmodcmp(const FTSENT *, const FTSENT *); int namecmp(const FTSENT *, const FTSENT *); int revnamecmp(const FTSENT *, const FTSENT *); +int verscmp(const FTSENT *, const FTSENT *); +int revverscmp(const FTSENT *, const FTSENT *); int statcmp(const FTSENT *, const FTSENT *); int revstatcmp(const FTSENT *, const FTSENT *); int sizecmp(const FTSENT *, const FTSENT *); diff --git a/bin/ls/ls.1 b/bin/ls/ls.1 index 450985fcfb4f..fb1b4f6ba606 100644 --- a/bin/ls/ls.1 +++ b/bin/ls/ls.1 @@ -32,7 +32,7 @@ .\" @(#)ls.1 8.7 (Berkeley) 7/29/94 .\" $FreeBSD$ .\" -.Dd August 31, 2020 +.Dd October 31, 2022 .Dt LS 1 .Os .Sh NAME @@ -40,7 +40,7 @@ .Nd list directory contents .Sh SYNOPSIS .Nm -.Op Fl ABCFGHILPRSTUWZabcdfghiklmnopqrstuwxy1\&, +.Op Fl ABCFGHILPRSTUWZabcdfghiklmnopqrstuvwxy1\&, .Op Fl -color Ns = Ns Ar when .Op Fl D Ar format .Op Ar @@ -399,6 +399,15 @@ of the file for sorting .Pq Fl t or printing .Pq Fl l . +.It Fl v +Sort following a natural ordering, using +.Xr strverscmp 3 +instead of +.Xr strcoll 3 +as the comparison function. +E.g., files lexicographically ordered +"bloem1", "bloem10", and "bloem9" would instead be ordered +"bloem1", "bloem9", and "bloem10", as one would perhaps expect. .It Fl w Force raw printing of non-printable characters. This is the default @@ -883,8 +892,10 @@ specification. .Xr sort 1 , .Xr xterm 1 Pq Pa ports/x11/xterm , .Xr localeconv 3 , +.Xr strcoll 3 , .Xr strftime 3 , .Xr strmode 3 , +.Xr strverscmp 3 , .Xr termcap 5 , .Xr maclabel 7 , .Xr sticky 7 , @@ -902,7 +913,7 @@ utility conforms to and .St -p1003.1-2008 . The options -.Fl B , D , G , I , T , U , W , Z , b , h , w , y +.Fl B , D , G , I , T , U , W , Z , b , h , v , w , y and .Fl , are non-standard extensions. @@ -918,6 +929,11 @@ An .Nm command appeared in .At v1 . +.Pp +The +.Fl v +option was added in +.Fx 14.0 . .Sh BUGS To maintain backward compatibility, the relationships between the many options are quite complex. diff --git a/bin/ls/ls.c b/bin/ls/ls.c index 8a30dd326b4e..bd7bd283c317 100644 --- a/bin/ls/ls.c +++ b/bin/ls/ls.c @@ -136,6 +136,7 @@ static int f_numericonly; /* don't convert uid/gid to name */ int f_octal_escape; /* like f_octal but use C escapes if possible */ static int f_recursive; /* ls subdirectories also */ static int f_reversesort; /* reverse whatever sort is used */ +static int f_verssort; /* sort names using strverscmp(3) rather than strcoll(3) */ int f_samesort; /* sort time and name in same direction */ int f_sectime; /* print full time information */ static int f_singlecol; /* use single column output */ @@ -275,7 +276,7 @@ main(int argc, char *argv[]) colorflag = COLORFLAG_AUTO; #endif while ((ch = getopt_long(argc, argv, - "+1ABCD:FGHILPRSTUWXZabcdfghiklmnopqrstuwxy,", long_opts, + "+1ABCD:FGHILPRSTUWXZabcdfghiklmnopqrstuvwxy,", long_opts, NULL)) != -1) { switch (ch) { /* @@ -439,6 +440,9 @@ main(int argc, char *argv[]) case 's': f_size = 1; break; + case 'v': + f_verssort = 1; + break; case 'w': f_nonprint = 0; f_octal = 0; @@ -566,10 +570,12 @@ main(int argc, char *argv[]) } /* Select a sort function. */ if (f_reversesort) { - if (!f_timesort && !f_sizesort) - sortfcn = revnamecmp; - else if (f_sizesort) + if (f_sizesort) sortfcn = revsizecmp; + else if (f_verssort) + sortfcn = revverscmp; + else if (!f_timesort) + sortfcn = revnamecmp; else if (f_accesstime) sortfcn = revacccmp; else if (f_birthtime) @@ -579,10 +585,12 @@ main(int argc, char *argv[]) else /* Use modification time. */ sortfcn = revmodcmp; } else { - if (!f_timesort && !f_sizesort) - sortfcn = namecmp; - else if (f_sizesort) + if (f_sizesort) sortfcn = sizecmp; + else if (f_verssort) + sortfcn = verscmp; + else if (!f_timesort) + sortfcn = namecmp; else if (f_accesstime) sortfcn = acccmp; else if (f_birthtime) diff --git a/bin/ls/tests/ls_tests.sh b/bin/ls/tests/ls_tests.sh index 14f7895e699c..117156b5cb0e 100755 --- a/bin/ls/tests/ls_tests.sh +++ b/bin/ls/tests/ls_tests.sh @@ -846,6 +846,20 @@ u_flag_body() atf_check -e empty -o match:'a\.file.*b\.file' -s exit:0 ls -Cu } +atf_test_case v_flag +v_flag_head() +{ + atf_set "descr" "Verify that the output from ls -v sorts based on strverscmp(3)" +} + +v_flag_body() +{ + create_test_dir + + atf_check -e empty -o empty -s exit:0 touch 000 00 01 010 09 0 1 9 10 + atf_check -e empty -o match:"000.00.01.010.09.0.1.9.10" -s exit:0 sh -c 'ls -Cv' +} + atf_test_case x_flag x_flag_head() { @@ -960,6 +974,7 @@ atf_init_test_cases() atf_add_test_case s_flag atf_add_test_case t_flag atf_add_test_case u_flag + atf_add_test_case v_flag atf_add_test_case x_flag atf_add_test_case y_flag atf_add_test_case 1_flag diff --git a/bin/ls/util.c b/bin/ls/util.c index 44012de58bba..0b1cba848239 100644 --- a/bin/ls/util.c +++ b/bin/ls/util.c @@ -227,9 +227,9 @@ usage(void) { (void)fprintf(stderr, #ifdef COLORLS - "usage: ls [-ABCFGHILPRSTUWZabcdfghiklmnopqrstuwxy1,] [--color=when] [-D format]" + "usage: ls [-ABCFGHILPRSTUWZabcdfghiklmnopqrstuvwxy1,] [--color=when] [-D format]" #else - "usage: ls [-ABCFHILPRSTUWZabcdfghiklmnopqrstuwxy1,] [-D format]" + "usage: ls [-ABCFHILPRSTUWZabcdfghiklmnopqrstuvwxy1,] [-D format]" #endif " [file ...]\n"); exit(1);