* src/ls.c (calculate_columns): Treat width as inclusive max.
(print_with_separator): Likewise.  Also handle commas explicitly,
since they're not catered for by an implicit newline in the count.
* tests/ls/w-option.sh: Adjust exact-fit column tests.
Note this change also makes the existing `ls -w4 -x -T0 a b` test
behave consistently with other output width limits.
Also add the test case from:
https://github.com/coreutils/coreutils/pull/213
* tests/ls/m-option.sh: Add a test case to ensure appropriate
wrapping when trailing comma at the line limit.
* NEWS: Mention the change in behavior.
---
 NEWS                 |  5 +++++
 src/ls.c             |  8 +++++---
 tests/ls/m-option.sh | 13 +++++++++++++
 tests/ls/w-option.sh | 17 +++++++++++++++--
 4 files changed, 38 insertions(+), 5 deletions(-)

diff --git a/NEWS b/NEWS
index 8e041272e..c7dac54c4 100644
--- a/NEWS
+++ b/NEWS
@@ -18,6 +18,11 @@ GNU coreutils NEWS                                    -*- 
outline -*-
   'uniq -w' no longer overruns the read buffer in multibyte locales.
   [bug introduced in coreutils-9.5]
 
+** Changes in behavior
+
+  'ls' -w,--width no longer includes '\n' in the width of a line.
+  I.e., the specified width is interpreted to be an _inclusive_ maximum.
+
 ** Improvements
 
   'sort' will now better use available memory and parallel operation
diff --git a/src/ls.c b/src/ls.c
index fa7926f86..394e7d267 100644
--- a/src/ls.c
+++ b/src/ls.c
@@ -5170,10 +5170,12 @@ print_with_separator (char sep)
       if (filesno != 0)
         {
           char separator;
+          size_t next_pos = 2 + (sep == ',' && filesno < cwd_n_used - 1);
 
           if (! line_length
-              || ((pos + len + 2 < line_length)
-                  && (pos <= SIZE_MAX - len - 2)))
+              || (! ckd_add (&next_pos, next_pos, pos)
+                  && ! ckd_add (&next_pos, next_pos, len)
+                  && next_pos <= line_length))
             {
               pos += 2;
               separator = ' ';
@@ -5317,7 +5319,7 @@ calculate_columns (bool by_columns)
                                               - column_info[i].col_arr[idx]);
                   column_info[i].col_arr[idx] = real_length;
                   column_info[i].valid_len = (column_info[i].line_len
-                                              < line_length);
+                                              <= line_length);
                 }
             }
         }
diff --git a/tests/ls/m-option.sh b/tests/ls/m-option.sh
index ce500b767..c9502e915 100755
--- a/tests/ls/m-option.sh
+++ b/tests/ls/m-option.sh
@@ -37,4 +37,17 @@ EOF
 
 compare exp out || fail=1
 
+# Ensure exact-fit comma output accounts for the trailing separator.
+touch bb c || framework_failure_
+cat <<\EOF > exp || framework_failure_
+a,
+bb, c
+EOF
+ls -w5 -m a bb c > out || fail=1
+compare exp out || fail=1
+
+printf '%s\n' 'a, bb' > exp || framework_failure_
+ls -w5 -m a bb > out || fail=1
+compare exp out || fail=1
+
 Exit $fail
diff --git a/tests/ls/w-option.sh b/tests/ls/w-option.sh
index 288f9a571..418121f97 100755
--- a/tests/ls/w-option.sh
+++ b/tests/ls/w-option.sh
@@ -51,7 +51,7 @@ cat <<\EOF > exp || framework_failure_
 aa  b
 c
 EOF
-ls -w6 -x -T0 aa b c > out || fail=1
+ls -w5 -x -T0 aa b c > out || fail=1
 compare exp out || fail=1
 
 # coreutils <= 9.11 could display 1 column too few
@@ -59,7 +59,20 @@ cat <<\EOF > exp || framework_failure_
 aa  c
 b
 EOF
-ls -w6 -C -T0 aa b c > out || fail=1
+ls -w5 -C -T0 aa b c > out || fail=1
 compare exp out || fail=1
 
+# These entries span 79 columns with a separator of two spaces
+# coreutils <= 9.11, and BSDs wrap with -w79 as new line included
+# Solaris 11 wraps with width <= 84? (COLUMNS=84 ls -m)
+# uutils 0.7.0 wraps with width <= 96?
+files="\
+Desktop  Documents  Downloads  Music  Pictures  Public  Templates  Videos  
code"
+mkdir subdir2 && (cd subdir2 && touch $files) || framework_failure_
+printf '%s\n' "$files" > exp || framework_failure_
+ls -x -T0 -w79 subdir2 > out || fail=1  # Should not wrap at 79
+compare exp out || fail=1
+ls -x -T0 -w78 subdir2 > out || fail=1  # Should wrap at 78
+test "$(wc -l < out)" -gt 1 || fail=1
+
 Exit $fail
-- 
2.54.0


Reply via email to