1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-28 11:37:44 +00:00

Merge pull request #5013 from shinhs0506/core-version-cmp

uucore: leading zeros are ignored in version compare
This commit is contained in:
Sylvestre Ledru 2023-07-09 09:21:18 +02:00 committed by GitHub
commit 78fd0efab9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 33 additions and 64 deletions

View file

@ -106,7 +106,7 @@ pub fn version_cmp(mut a: &str, mut b: &str) -> Ordering {
// 1. Compare leading non-numerical part
// 2. Compare leading numerical part
// 3. Repeat
loop {
while !a.is_empty() || !b.is_empty() {
let a_numerical_start = a.find(|c: char| c.is_ascii_digit()).unwrap_or(a.len());
let b_numerical_start = b.find(|c: char| c.is_ascii_digit()).unwrap_or(b.len());
@ -139,12 +139,9 @@ pub fn version_cmp(mut a: &str, mut b: &str) -> Ordering {
a = &a[a_numerical_end..];
b = &b[b_numerical_end..];
if a.is_empty() && b.is_empty() {
// Default to the lexical comparison.
return str_cmp;
}
}
Ordering::Equal
}
#[cfg(test)]
@ -229,14 +226,14 @@ mod tests {
// Leading zeroes
assert_eq!(
version_cmp("012", "12"),
Ordering::Less,
"A single leading zero can make a difference"
Ordering::Equal,
"A single leading zero does not make a difference"
);
assert_eq!(
version_cmp("000800", "0000800"),
Ordering::Greater,
"Leading number of zeroes is used even if both non-zero number of zeros"
Ordering::Equal,
"Multiple leading zeros do not make a difference"
);
// Numbers and other characters combined
@ -280,14 +277,8 @@ mod tests {
assert_eq!(
version_cmp("aa10aa0022", "aa010aa022"),
Ordering::Greater,
"The leading zeroes of the first number has priority."
);
assert_eq!(
version_cmp("aa10aa0022", "aa10aa022"),
Ordering::Less,
"The leading zeroes of other numbers than the first are used."
Ordering::Equal,
"Test multiple numeric values with leading zeros"
);
assert_eq!(
@ -307,7 +298,7 @@ mod tests {
assert_eq!(
version_cmp("aa2000000000000000000000bb", "aa002000000000000000000000bb"),
Ordering::Greater,
Ordering::Equal,
"Leading zeroes for numbers larger than u64::MAX are \
handled correctly without crashing"
);

View file

@ -2312,56 +2312,15 @@ fn test_ls_version_sort() {
let scene = TestScenario::new(util_name!());
let at = &scene.fixtures;
for filename in [
"a2",
"b1",
"b20",
"a1.4",
"a1.40",
"b3",
"b11",
"b20b",
"b20a",
"a100",
"a1.13",
"aa",
"a1",
"aaa",
"a1.00000040",
"abab",
"ab",
"a01.40",
"a001.001",
"a01.0000001",
"a01.001",
"a001.01",
"a2", "b1", "b20", "a1.4", "b3", "b11", "b20b", "b20a", "a100", "a1.13", "aa", "a1", "aaa",
"abab", "ab", "a01.40", "a001.001",
] {
at.touch(filename);
}
let mut expected = vec![
"a1",
"a001.001",
"a001.01",
"a01.0000001",
"a01.001",
"a1.4",
"a1.13",
"a01.40",
"a1.00000040",
"a1.40",
"a2",
"a100",
"aa",
"aaa",
"ab",
"abab",
"b1",
"b3",
"b11",
"b20",
"b20a",
"b20b",
"", // because of '\n' at the end of the output
"a1", "a001.001", "a1.4", "a1.13", "a01.40", "a2", "a100", "aa", "aaa", "ab", "abab", "b1",
"b3", "b11", "b20", "b20a", "b20b", "", // because of '\n' at the end of the output
];
let result = scene.ucmd().arg("-1v").succeeds();

View file

@ -134,6 +134,25 @@ fn test_version_empty_lines() {
test_helper("version-empty-lines", &["-V", "--version-sort"]);
}
#[test]
fn test_version_sort_unstable() {
new_ucmd!()
.arg("--sort=version")
.pipe_in("0.1\n0.02\n0.2\n0.002\n0.3\n")
.succeeds()
.stdout_is("0.1\n0.002\n0.02\n0.2\n0.3\n");
}
#[test]
fn test_version_sort_stable() {
new_ucmd!()
.arg("--stable")
.arg("--sort=version")
.pipe_in("0.1\n0.02\n0.2\n0.002\n0.3\n")
.succeeds()
.stdout_is("0.1\n0.02\n0.2\n0.002\n0.3\n");
}
#[test]
fn test_human_numeric_whitespace() {
test_helper(