mirror of
git://git.sv.gnu.org/coreutils.git
synced 2026-04-21 11:16:16 +02:00
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
This commit is contained in:
2
NEWS
2
NEWS
@@ -29,6 +29,8 @@ GNU coreutils NEWS -*- outline -*-
|
|||||||
upon detection of a directory cycle.
|
upon detection of a directory cycle.
|
||||||
[issue introduced in coreutils-8.20]
|
[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]
|
* Noteworthy changes in release 8.24 (2015-07-03) [stable]
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
Assume the screen is @var{cols} columns wide. The default is taken
|
||||||
from the terminal settings if possible; otherwise the environment
|
from the terminal settings if possible; otherwise the environment
|
||||||
variable @env{COLUMNS} is used if it is set; otherwise the default
|
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
|
@end table
|
||||||
|
|
||||||
|
|||||||
33
src/ls.c
33
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 void prep_non_filename_text (void);
|
||||||
static bool print_type_indicator (bool stat_ok, mode_t mode,
|
static bool print_type_indicator (bool stat_ok, mode_t mode,
|
||||||
enum filetype type);
|
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,
|
static void queue_directory (char const *name, char const *realname,
|
||||||
bool command_line_arg);
|
bool command_line_arg);
|
||||||
static void sort_files (void);
|
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
|
/* Set the line length to the value given by SPEC. Return true if
|
||||||
successful. */
|
successful. 0 means no limit on line length. */
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
set_line_length (char const *spec)
|
set_line_length (char const *spec)
|
||||||
@@ -3647,15 +3647,21 @@ print_current_files (void)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case many_per_line:
|
case many_per_line:
|
||||||
print_many_per_line ();
|
if (! line_length)
|
||||||
|
print_with_separator (' ');
|
||||||
|
else
|
||||||
|
print_many_per_line ();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case horizontal:
|
case horizontal:
|
||||||
print_horizontal ();
|
if (! line_length)
|
||||||
|
print_with_separator (' ');
|
||||||
|
else
|
||||||
|
print_horizontal ();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case with_commas:
|
case with_commas:
|
||||||
print_with_commas ();
|
print_with_separator (',');
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case long_format:
|
case long_format:
|
||||||
@@ -4242,7 +4248,8 @@ print_name_with_quoting (const struct fileinfo *f,
|
|||||||
if (used_color_this_time)
|
if (used_color_this_time)
|
||||||
{
|
{
|
||||||
prep_non_filename_text ();
|
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]);
|
put_indicator (&color_indicator[C_CLR_TO_EOL]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4583,8 +4590,10 @@ print_horizontal (void)
|
|||||||
putchar ('\n');
|
putchar ('\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Output name + SEP + ' '. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
print_with_commas (void)
|
print_with_separator (char sep)
|
||||||
{
|
{
|
||||||
size_t filesno;
|
size_t filesno;
|
||||||
size_t pos = 0;
|
size_t pos = 0;
|
||||||
@@ -4592,13 +4601,15 @@ print_with_commas (void)
|
|||||||
for (filesno = 0; filesno < cwd_n_used; filesno++)
|
for (filesno = 0; filesno < cwd_n_used; filesno++)
|
||||||
{
|
{
|
||||||
struct fileinfo const *f = sorted_file[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)
|
if (filesno != 0)
|
||||||
{
|
{
|
||||||
char separator;
|
char separator;
|
||||||
|
|
||||||
if (pos + len + 2 < line_length)
|
if (! line_length
|
||||||
|
|| ((pos + len + 2 < line_length)
|
||||||
|
&& (pos <= SIZE_MAX - len - 2)))
|
||||||
{
|
{
|
||||||
pos += 2;
|
pos += 2;
|
||||||
separator = ' ';
|
separator = ' ';
|
||||||
@@ -4609,7 +4620,7 @@ print_with_commas (void)
|
|||||||
separator = '\n';
|
separator = '\n';
|
||||||
}
|
}
|
||||||
|
|
||||||
putchar (',');
|
putchar (sep);
|
||||||
putchar (separator);
|
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\
|
-v natural sort of (version) numbers within text\n\
|
||||||
"), stdout);
|
"), stdout);
|
||||||
fputs (_("\
|
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 list entries by lines instead of by columns\n\
|
||||||
-X sort alphabetically by entry extension\n\
|
-X sort alphabetically by entry extension\n\
|
||||||
-Z, --context print any security context of each file\n\
|
-Z, --context print any security context of each file\n\
|
||||||
|
|||||||
@@ -568,6 +568,7 @@ all_tests = \
|
|||||||
tests/ls/infloop.sh \
|
tests/ls/infloop.sh \
|
||||||
tests/ls/inode.sh \
|
tests/ls/inode.sh \
|
||||||
tests/ls/m-option.sh \
|
tests/ls/m-option.sh \
|
||||||
|
tests/ls/w-option.sh \
|
||||||
tests/ls/multihardlink.sh \
|
tests/ls/multihardlink.sh \
|
||||||
tests/ls/no-arg.sh \
|
tests/ls/no-arg.sh \
|
||||||
tests/ls/no-cap.sh \
|
tests/ls/no-cap.sh \
|
||||||
|
|||||||
44
tests/ls/w-option.sh
Executable file
44
tests/ls/w-option.sh
Executable file
@@ -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
|
||||||
Reference in New Issue
Block a user