20158 Commits
Author SHA1 Message Date
Daniel Hofstetter 28b6856d7b cut: use then_some instead of then 0.10.0 2026-08-05 22:36:22 +02:00
Daniel Hofstetter 6ab8da775e cut: rename function & vars 2026-08-05 22:36:22 +02:00
Daniel Hofstetter bd7d89640d cut: simplify match 2026-08-05 22:36:22 +02:00
Daniel Hofstetter 813dc15faa cut: move code to new get_selected_mode_arg fn 2026-08-05 22:36:22 +02:00
Daniel Hofstetter cfbfccb1ad cut: return early if invalid arg combinations 2026-08-05 22:36:22 +02:00
Daniel Hofstetter 9bbb13d40f cut: return early if incorrect number of mode args 2026-08-05 22:36:22 +02:00
renovate[bot] 21d4e9635b chore(deps): update rust crate similar to v3.1.2 2026-08-04 17:06:19 +02:00
oech3 e7906a06c3 cp: simplify loop by while let 2026-08-04 15:57:12 +02:00
oech3 0b214ccdc8 paste: simplify 2 loop by while 2026-08-04 14:11:37 +02:00
oech3 61cac11c3b od: remove enum var not used at production 2026-08-04 13:36:30 +02:00
Dorian Péron a0e62f41fa du: Refactor loop into while let 2026-08-04 13:22:33 +02:00
xtqqczze cb0806a02a error: clarify UUsageError documentation 2026-08-04 11:49:32 +02:00
MeGaurav4 46cf6db3d9 head/tail: fix bare suffix regression from zero count change
A bare suffix with no digits at all (e.g. head -c kiB) must still
parse as 1 of that unit. Only a suffix that remains after stripping
leading zeros (e.g. 0K) means zero.

Closes #13703
2026-08-04 11:23:13 +02:00
MeGaurav4 64723bb78b head/tail: parse zero byte counts with size suffix as 0
0K, 00K and similar inputs were being parsed as 1KiB because the
leading zeros were stripped before suffix interpretation, leaving a
bare suffix that parse_size treats as 1 unit. The leading zeros mean
the value is zero, so a bare suffix must still produce 0.

GNU coreutils prints nothing for head -c 0K and tail -c 0K.

Closes #13703
2026-08-04 11:23:13 +02:00
0xfandom 67c5e6111a chmod: report the real error when a target's metadata is inaccessible (#13637)
* chmod: report the real error when a target's metadata is inaccessible

chmod used Path::exists() to decide whether a target exists, but exists() returns false on any metadata error, so a file whose parent directory lacks search permission was reported as "No such file or directory" instead of "Permission denied". Use try_exists() to distinguish a genuine ENOENT from a permission error, matching GNU. Fixes #9789.

* tests/chmod: use digit separators in octal mode literal

Satisfy clippy::unreadable_literal (0o100644 -> 0o100_644) so the
Style and Lint job passes.
2026-08-04 10:45:01 +02:00
oech3 8d68f13d05 cp: remove feat_acl & exacl (dupe of copy_acls) 2026-08-04 10:18:04 +02:00
oech3 04c4f77262 od: remove Box from enum CurrentReader 2026-08-04 10:04:07 +02:00
Dorian Péron b5a0db8bc1 cksum: locale-aware escape file name 2026-08-04 09:54:20 +02:00
xtqqczze d49785eb65 uucore: use workspace for direct dependencies 2026-08-04 09:13:39 +02:00
xtqqczze 3f14cb60c5 uucore: sort dependencies that are no longer pinned 2026-08-04 09:13:39 +02:00
Sylvestre Ledru 8d48201bbf cut: speed up the multibyte character path
The character path walked the line one character at a time through the
encoding decoder and looked the locale encoding up per character, which
dominated the per-line cost on mixed ASCII and multi-byte text.

Take runs of ASCII bytes a machine word at a time. They are single-byte
characters in every encoding handled here, so byte offset and character
position move together across a run, and only the bytes above 0x7F need
the decoder. Bundle the parts that are fixed for the whole run -- the
ranges, the output delimiter and whether it was given, the position mode
and the encoding -- into a CharCut built once by cut_chars, and make the
line body a method on it, so the per-line call passes one pointer rather
than seven arguments.

In uucore, MbEncoding becomes the public Encoding and locale_encoding()
returns it by value, so a caller decoding many characters resolves the
locale once and keeps it in a register instead of reaching through a
OnceLock per character. is_multibyte_locale() had no callers left.

Instruction counts against the parent commit (cachegrind, LC_ALL=C.UTF-8):

  -c 5-30, 100k mixed short lines       30.44M -> 28.95M
  -c 20-70, 20k long multibyte lines    44.38M -> 41.02M

That is roughly 1.1x in wall clock on both shapes; the machine was too
loaded to quote a tighter figure. The single-byte path (LC_ALL=C) and
field mode are unchanged.

Selecting a range of characters still costs more than the same range of
bytes, and always will: -c used to be an alias for -b, and characters
have to be decoded to be counted.

Tests cover advance directly -- character counting for -c, byte counting
for -b -n, and the word boundary crossings -- plus a cut -c case over
mixed ASCII and multi-byte lines.
2026-08-04 08:44:47 +02:00
Sylvestre Ledru 676d8feab2 cut: skip WASI-incompatible non-UTF-8 delimiter test under wasi_runner
wasmtime's argument marshaling requires valid UTF-8, so a raw non-UTF-8
byte delimiter can't be passed through to the WASI binary the way it
can natively on Linux.
2026-08-04 08:44:47 +02:00
Sylvestre Ledru f305791c6b cut: support multibyte characters in non-UTF-8 locales 2026-08-04 08:44:47 +02:00
oech3 89bdbb8662 cp: fix 2 clippy expections 2026-08-03 22:50:50 +02:00
dhruv-15-03andCopilot App fe9420b8f0 test: compare integers of any width
integers() parsed both operands with i128, so an operand needing more
digits than that range holds was rejected as an invalid integer with exit
code 2. GNU compares integers of arbitrary width and returns 0 or 1
instead of erroring.

Parse each operand into a sign and its decimal digits and compare those
directly: sign first, then digit count, then bytewise over the remaining
digits. This lifts the width limit from all six integer operators
(-eq, -ne, -lt, -le, -gt, -ge) without adding a dependency, and leaves the
set of accepted operands unchanged.

Fixes #12874

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
2026-08-03 22:40:01 +02:00