summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPádraig Brady <P@draigBrady.com>2015-10-20 14:42:39 +0100
committerPádraig Brady <P@draigBrady.com>2015-10-21 01:40:02 +0100
commit0e997681d4497fe9ba6db035909e413a5af050a9 (patch)
tree3a6e4bbf904902dbb71124567942198e3142147a
parent069961924efb64349914df085d6b0ac76bdaf7ae (diff)
downloadcoreutils-0e997681d4497fe9ba6db035909e413a5af050a9.tar.xz
ls: allow -w0 to mean no limit on line length
* src/ls.c (print_with_separator): Renamed from print_with_commas, and parameterized to accept the separator to print. Also fix an edge case where '\n' not printed when the POS variable overflows SIZE_MAX. (print_current_files): Degenerate -x and -C to using the cheaper print_with_separator() in the -w0 case. * doc/coreutils.texi (ls invocation): Document the new feature. * tests/ls/w-option.sh: A new test. * tests/local.mk: Reference the new test. * NEWS: Mention the improvement. Fixes http://bugs.gnu.org/21325
-rw-r--r--NEWS2
-rw-r--r--doc/coreutils.texi4
-rw-r--r--src/ls.c33
-rw-r--r--tests/local.mk1
-rwxr-xr-xtests/ls/w-option.sh44
5 files changed, 72 insertions, 12 deletions
diff --git a/NEWS b/NEWS
index 80f99f3ee..07b88b09c 100644
--- a/NEWS
+++ b/NEWS
@@ -29,6 +29,8 @@ GNU coreutils NEWS -*- outline -*-
upon detection of a directory cycle.
[issue introduced in coreutils-8.20]
+ ls -w0 is now interpreted as no limit on the length of the outputted line.
+
* Noteworthy changes in release 8.24 (2015-07-03) [stable]
diff --git a/doc/coreutils.texi b/doc/coreutils.texi
index 0359867f5..1b81daa99 100644
--- a/doc/coreutils.texi
+++ b/doc/coreutils.texi
@@ -7445,7 +7445,9 @@ TAB following a non-ASCII byte. You can avoid that issue by using the
Assume the screen is @var{cols} columns wide. The default is taken
from the terminal settings if possible; otherwise the environment
variable @env{COLUMNS} is used if it is set; otherwise the default
-is 80.
+is 80. With a @var{cols} value of @samp{0}, there is no limit on
+the length of the output line, and that single output line will
+be delimited with spaces, not tabs.
@end table
diff --git a/src/ls.c b/src/ls.c
index 382253484..0c9dc78db 100644
--- a/src/ls.c
+++ b/src/ls.c
@@ -279,7 +279,7 @@ static size_t print_name_with_quoting (const struct fileinfo *f,
static void prep_non_filename_text (void);
static bool print_type_indicator (bool stat_ok, mode_t mode,
enum filetype type);
-static void print_with_commas (void);
+static void print_with_separator (char sep);
static void queue_directory (char const *name, char const *realname,
bool command_line_arg);
static void sort_files (void);
@@ -1524,7 +1524,7 @@ main (int argc, char **argv)
}
/* Set the line length to the value given by SPEC. Return true if
- successful. */
+ successful. 0 means no limit on line length. */
static bool
set_line_length (char const *spec)
@@ -3647,15 +3647,21 @@ print_current_files (void)
break;
case many_per_line:
- print_many_per_line ();
+ if (! line_length)
+ print_with_separator (' ');
+ else
+ print_many_per_line ();
break;
case horizontal:
- print_horizontal ();
+ if (! line_length)
+ print_with_separator (' ');
+ else
+ print_horizontal ();
break;
case with_commas:
- print_with_commas ();
+ print_with_separator (',');
break;
case long_format:
@@ -4242,7 +4248,8 @@ print_name_with_quoting (const struct fileinfo *f,
if (used_color_this_time)
{
prep_non_filename_text ();
- if (start_col / line_length != (start_col + width - 1) / line_length)
+ if (line_length
+ && (start_col / line_length != (start_col + width - 1) / line_length))
put_indicator (&color_indicator[C_CLR_TO_EOL]);
}
@@ -4583,8 +4590,10 @@ print_horizontal (void)
putchar ('\n');
}
+/* Output name + SEP + ' '. */
+
static void
-print_with_commas (void)
+print_with_separator (char sep)
{
size_t filesno;
size_t pos = 0;
@@ -4592,13 +4601,15 @@ print_with_commas (void)
for (filesno = 0; filesno < cwd_n_used; filesno++)
{
struct fileinfo const *f = sorted_file[filesno];
- size_t len = length_of_file_name_and_frills (f);
+ size_t len = line_length ? length_of_file_name_and_frills (f) : 0;
if (filesno != 0)
{
char separator;
- if (pos + len + 2 < line_length)
+ if (! line_length
+ || ((pos + len + 2 < line_length)
+ && (pos <= SIZE_MAX - len - 2)))
{
pos += 2;
separator = ' ';
@@ -4609,7 +4620,7 @@ print_with_commas (void)
separator = '\n';
}
- putchar (',');
+ putchar (sep);
putchar (separator);
}
@@ -4935,7 +4946,7 @@ Sort entries alphabetically if none of -cftuvSUX nor --sort is specified.\n\
-v natural sort of (version) numbers within text\n\
"), stdout);
fputs (_("\
- -w, --width=COLS assume screen width instead of current value\n\
+ -w, --width=COLS set output width to COLS. 0 means no limit\n\
-x list entries by lines instead of by columns\n\
-X sort alphabetically by entry extension\n\
-Z, --context print any security context of each file\n\
diff --git a/tests/local.mk b/tests/local.mk
index 0471f5e4e..ee4068d64 100644
--- a/tests/local.mk
+++ b/tests/local.mk
@@ -568,6 +568,7 @@ all_tests = \
tests/ls/infloop.sh \
tests/ls/inode.sh \
tests/ls/m-option.sh \
+ tests/ls/w-option.sh \
tests/ls/multihardlink.sh \
tests/ls/no-arg.sh \
tests/ls/no-cap.sh \
diff --git a/tests/ls/w-option.sh b/tests/ls/w-option.sh
new file mode 100755
index 000000000..f49c02815
--- /dev/null
+++ b/tests/ls/w-option.sh
@@ -0,0 +1,44 @@
+#!/bin/sh
+# exercise the -w option
+
+# Copyright (C) 2015 Free Software Foundation, Inc.
+
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
+print_ver_ ls
+getlimits_
+
+touch a b || framework_failure_
+chmod a+x a || framework_failure_
+
+# Negative values disallowed
+returns_ 2 ls -w-1 || fail=1
+
+# Verify octal parsing (especially since 0 is allowed)
+returns_ 2 ls -w08 || fail=1
+
+# Overflowed values are capped at SIZE_MAX
+ls -w$SIZE_OFLOW || fail=1
+
+# After coreutils 8.24 -w0 means no limit
+# and delimiting with spaces
+ls -w0 -x -T1 a b > out || fail=1
+printf '%s\n' 'a b' > exp || framework_failure_
+compare exp out || fail=1
+
+# Ensure that 0 line length doesn't cause division by zero
+TERM=xterm ls -w0 -x --color=always || fail=1
+
+Exit $fail