git: 647d4a8cafd2 - main - ls: Make -, apply to -s as well as -l.

From: Dag-Erling Smørgrav <des_at_FreeBSD.org>
Date: Wed, 24 Jul 2024 20:07:09 UTC
The branch main has been updated by des:

URL: https://cgit.FreeBSD.org/src/commit/?id=647d4a8cafd2c9b291cab388191bc7fcfe12a66b

commit 647d4a8cafd2c9b291cab388191bc7fcfe12a66b
Author:     Dag-Erling Smørgrav <des@FreeBSD.org>
AuthorDate: 2024-07-24 20:06:39 +0000
Commit:     Dag-Erling Smørgrav <des@FreeBSD.org>
CommitDate: 2024-07-24 20:07:06 +0000

    ls: Make -, apply to -s as well as -l.
    
    While here, remove a bogus comment about a gcc bug.  The bug was in ls,
    which used an incorrect format string, and in libc, which accepted it.
    
    MFC after:      1 week
    Reviewed by:    brooks
    Differential Revision:  https://reviews.freebsd.org/D46067
---
 bin/ls/ls.1              |  4 +++-
 bin/ls/ls.c              |  3 ++-
 bin/ls/print.c           | 14 ++++++--------
 bin/ls/tests/ls_tests.sh | 16 ++++++++++++++++
 4 files changed, 27 insertions(+), 10 deletions(-)

diff --git a/bin/ls/ls.1 b/bin/ls/ls.1
index 9d4c55b9b17d..d86250b82db2 100644
--- a/bin/ls/ls.1
+++ b/bin/ls/ls.1
@@ -29,7 +29,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.Dd February 21, 2024
+.Dd July 22, 2024
 .Dt LS 1
 .Os
 .Sh NAME
@@ -434,6 +434,8 @@ output is not to a terminal.
 .It Fl ,
 (Comma) When the
 .Fl l
+or
+.Fl s
 option is set, print file sizes grouped and separated by thousands using the
 non-monetary separator returned by
 .Xr localeconv 3 ,
diff --git a/bin/ls/ls.c b/bin/ls/ls.c
index b5e3578f27bb..a285838e2ee1 100644
--- a/bin/ls/ls.c
+++ b/bin/ls/ls.c
@@ -969,7 +969,8 @@ label_out:
 	d.maxlen = maxlen;
 	if (needstats) {
 		d.btotal = btotal;
-		d.s_block = snprintf(NULL, 0, "%lu", howmany(maxblock, blocksize));
+		d.s_block = snprintf(NULL, 0, f_thousands ? "%'ld" : "%ld",
+		    howmany(maxblock, blocksize));
 		d.s_flags = maxflags;
 		d.s_label = maxlabelstr;
 		d.s_group = maxgroup;
diff --git a/bin/ls/print.c b/bin/ls/print.c
index 979ad0ffc43e..f651dea5de90 100644
--- a/bin/ls/print.c
+++ b/bin/ls/print.c
@@ -221,7 +221,7 @@ printlong(const DISPLAY *dp)
 			(void)printf("%*ju ",
 			    dp->s_inode, (uintmax_t)sp->st_ino);
 		if (f_size)
-			(void)printf("%*jd ",
+			(void)printf(f_thousands ? "%'*jd " : "%*jd ",
 			    dp->s_block, howmany(sp->st_blocks, blocksize));
 		strmode(sp->st_mode, buf);
 		aclmode(buf, p);
@@ -400,7 +400,7 @@ printaname(const FTSENT *p, u_long inodefield, u_long sizefield)
 		chcnt += printf("%*ju ",
 		    (int)inodefield, (uintmax_t)sp->st_ino);
 	if (f_size)
-		chcnt += printf("%*jd ",
+		chcnt += printf(f_thousands ? "%'*jd " : "%*jd ",
 		    (int)sizefield, howmany(sp->st_blocks, blocksize));
 #ifdef COLORLS
 	if (f_color)
@@ -753,12 +753,10 @@ printsize(size_t width, off_t bytes)
 		humanize_number(buf, sizeof(buf), (int64_t)bytes, "",
 		    HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL);
 		(void)printf("%*s ", (u_int)width, buf);
-	} else if (f_thousands) {		/* with commas */
-		/* This format assignment needed to work round gcc bug. */
-		const char *format = "%*j'd ";
-		(void)printf(format, (u_int)width, bytes);
-	} else
-		(void)printf("%*jd ", (u_int)width, bytes);
+	} else {
+		(void)printf(f_thousands ? "%'*jd " : "%*jd ",
+		    (u_int)width, bytes);
+	}
 }
 
 /*
diff --git a/bin/ls/tests/ls_tests.sh b/bin/ls/tests/ls_tests.sh
index c82b4e8c8851..c732b60b21a4 100755
--- a/bin/ls/tests/ls_tests.sh
+++ b/bin/ls/tests/ls_tests.sh
@@ -800,6 +800,21 @@ s_flag_body()
 	done
 }
 
+atf_test_case scomma_flag
+scomma_flag_head()
+{
+	atf_set "descr" "Verify that -s, prints out the size with ',' delimiters"
+}
+
+scomma_flag_body()
+{
+	export LC_ALL=en_US.UTF-8
+	atf_check -e ignore dd if=/dev/urandom of=file bs=65536 count=64
+	blocks=$(stat -f "%b" file)
+	cblocks=$(printf "%'d" $blocks)
+	atf_check -e empty -o match:"$cblocks[[:space:]]+file" ls -s, file
+}
+
 atf_test_case t_flag
 t_flag_head()
 {
@@ -972,6 +987,7 @@ atf_init_test_cases()
 	atf_add_test_case q_flag_and_w_flag
 	atf_add_test_case r_flag
 	atf_add_test_case s_flag
+	atf_add_test_case scomma_flag
 	atf_add_test_case t_flag
 	atf_add_test_case u_flag
 	atf_add_test_case v_flag