Skip to content

Conversation

@karanabe
Copy link
Contributor

This change translates GNU’s legacy +POS1 [-POS2] sort key syntax into -k form before clap parsing, gating it by _POSIX2_VERSION to match GNU behavior, and adds by-util tests to ensure acceptance/rejection behavior matches GNU and that the sort-field-limit compatibility test passes.

#9127

Support GNU’s obsolescent +POS1 [-POS2] syntax by translating it to -k
before clap parses args, gated by _POSIX2_VERSION. Adds tests for accept
and reject cases to ensure sort-field-limit GNU test passes.
@github-actions
Copy link

GNU testsuite comparison:

Congrats! The gnu test tests/sort/sort-field-limit is no longer failing!

@karanabe karanabe requested a review from cakebaker December 1, 2025 17:00
@github-actions
Copy link

github-actions bot commented Dec 1, 2025

GNU testsuite comparison:

Skip an intermittent issue tests/tail/overlay-headers (fails in this run but passes in the 'main' branch)
Congrats! The gnu test tests/sort/sort-field-limit is no longer failing!

Comment on lines 1112 to 1116
let mut idx = 0;
let bytes = spec.as_bytes();
while idx < bytes.len() && bytes[idx].is_ascii_digit() {
idx += 1;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think a functional approach is cleaner. Something like:

Suggested change
let mut idx = 0;
let bytes = spec.as_bytes();
while idx < bytes.len() && bytes[idx].is_ascii_digit() {
idx += 1;
}
let idx = spec.chars().take_while(|c| c.is_ascii_digit()).count();

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was fixed in this commit. 3b52b5d

Comment on lines 1126 to 1130
let mut char_idx = 0;
let stripped_bytes = stripped.as_bytes();
while char_idx < stripped_bytes.len() && stripped_bytes[char_idx].is_ascii_digit() {
char_idx += 1;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here.

Suggested change
let mut char_idx = 0;
let stripped_bytes = stripped.as_bytes();
while char_idx < stripped_bytes.len() && stripped_bytes[char_idx].is_ascii_digit() {
char_idx += 1;
}
let char_idx = stripped.chars().take_while(|c| c.is_ascii_digit()).count();

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was fixed in this commit. 3b52b5d

#[derive(Debug, Clone)]
struct LegacyKeyPart {
field: usize,
char: usize,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The name char is a bit unlucky.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was fixed in this commit. 3b52b5d

to.field.saturating_add(1)
};

let mut end_part = end_field.to_string();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the reason for introducing end_part? Couldn't you reorder things a bit and push directly to keydef?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was fixed in this commit. bf7a8ab

}
}

fn parse_legacy_part(spec: &str, default_char: usize) -> Option<LegacyKeyPart> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the default_char param necessary? It's 0 in both places this function is called.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was fixed in this commit. 3b52b5d

Comment on lines 1214 to 1218
if stripped
.as_bytes()
.first()
.is_some_and(|c| c.is_ascii_digit())
{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you can simplify it with starts_with:

Suggested change
if stripped
.as_bytes()
.first()
.is_some_and(|c| c.is_ascii_digit())
{
if stripped.starts_with(|c: char| c.is_ascii_digit()) {

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was fixed in this commit. e477de9

@codspeed-hq
Copy link

codspeed-hq bot commented Dec 14, 2025

CodSpeed Performance Report

Merging #9501 will degrade performances by 4.51%

Comparing karanabe:test/fix-sort-field-limit (a10c06e) with main (64203e3)

Summary

⚡ 1 improvement
❌ 2 regressions
✅ 124 untouched
⏩ 6 skipped1

⚠️ Please fix the performance issues or acknowledge them on CodSpeed.

Benchmarks breakdown

Benchmark BASE HEAD Change
sort_ascii_c_locale 21.6 ms 22.6 ms -4.51%
sort_numeric 24 ms 23.5 ms +2.04%
tsort_input_parsing_heavy[5000] 82.1 ms 83.8 ms -2.04%

Footnotes

  1. 6 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

@github-actions
Copy link

GNU testsuite comparison:

Skipping an intermittent issue tests/tail/overlay-headers (passes in this run but fails in the 'main' branch)
Congrats! The gnu test tests/sort/sort-field-limit is no longer failing!

@github-actions
Copy link

GNU testsuite comparison:

Skipping an intermittent issue tests/tail/overlay-headers (passes in this run but fails in the 'main' branch)
Congrats! The gnu test tests/sort/sort-field-limit is no longer failing!

@karanabe karanabe requested a review from cakebaker December 14, 2025 11:48
@karanabe
Copy link
Contributor Author

@cakebaker Thanks for the review! I've addressed all the comments.
Regarding the test failure, test_tail::test_retry6 stdout does not seem to be related to this change and appears to be failing elsewhere as well.
Could you please take another look?

@cakebaker cakebaker merged commit 06d843f into uutils:main Dec 15, 2025
125 of 127 checks passed
@cakebaker
Copy link
Contributor

Congrats! The gnu test tests/sort/sort-field-limit is no longer failing!

Kudos, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants