Skip to content

Commit bd2e33b

Browse files
yonatan-linikRenjiSann
authored andcommitted
sort: Support hexadecimal numbers/floats correctly
Fixes #8060
1 parent d2b95eb commit bd2e33b

File tree

5 files changed

+31
-7
lines changed

5 files changed

+31
-7
lines changed

src/uu/sort/src/sort.rs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
// https://pubs.opengroup.org/onlinepubs/9699919799/utilities/sort.html
88
// https://www.gnu.org/software/coreutils/manual/html_node/sort-invocation.html
99

10-
// spell-checker:ignore (misc) HFKJFK Mbdfhn getrlimit RLIMIT_NOFILE rlim bigdecimal extendedbigdecimal
10+
// spell-checker:ignore (misc) HFKJFK Mbdfhn getrlimit RLIMIT_NOFILE rlim bigdecimal extendedbigdecimal hexdigit
1111

1212
mod check;
1313
mod chunks;
@@ -1834,15 +1834,27 @@ fn get_leading_gen(input: &str) -> Range<usize> {
18341834

18351835
let mut had_e_notation = false;
18361836
let mut had_decimal_pt = false;
1837+
let mut had_hex_notation: bool = false;
18371838
while let Some((idx, c)) = char_indices.next() {
1839+
if had_hex_notation && c.is_ascii_hexdigit() {
1840+
continue;
1841+
}
1842+
18381843
if c.is_ascii_digit() {
1844+
if c == '0' && matches!(char_indices.peek(), Some((_, 'x' | 'X'))) {
1845+
had_hex_notation = true;
1846+
char_indices.next();
1847+
}
18391848
continue;
18401849
}
1850+
18411851
if c == DECIMAL_PT && !had_decimal_pt && !had_e_notation {
18421852
had_decimal_pt = true;
18431853
continue;
18441854
}
1845-
if (c == 'e' || c == 'E') && !had_e_notation {
1855+
let is_decimal_e = (c == 'e' || c == 'E') && !had_hex_notation;
1856+
let is_hex_e = (c == 'p' || c == 'P') && had_hex_notation;
1857+
if (is_decimal_e || is_hex_e) && !had_e_notation {
18461858
// we can only consume the 'e' if what follow is either a digit, or a sign followed by a digit.
18471859
if let Some(&(_, next_char)) = char_indices.peek() {
18481860
if (next_char == '+' || next_char == '-')

tests/by-util/test_sort.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1556,3 +1556,15 @@ fn test_g_arbitrary() {
15561556
.succeeds()
15571557
.stdout_is(output);
15581558
}
1559+
1560+
#[test]
1561+
// Test hexadecimal numbers (and hex floats)
1562+
fn test_g_float_hex() {
1563+
let input = "0x123\n0x0\n0x2p10\n0x9p-10\n";
1564+
let output = "0x0\n0x9p-10\n0x123\n0x2p10\n";
1565+
new_ucmd!()
1566+
.args(&["-g"])
1567+
.pipe_in(input)
1568+
.succeeds()
1569+
.stdout_is(output);
1570+
}

tests/fixtures/sort/exponents_general.expected

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@
88

99
-12e-5555.5
1010
0b10 // binary not supported
11-
0x10 // hexadecimal not supported, but it should be
1211
55e-20
1312
55e-20.10
1413
5.5.5.5
1514
10E
15+
0x10
1616
64e+
1717
99e-
1818
1000EDKLD

tests/fixtures/sort/exponents_general.expected.debug

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,6 @@ ______________
2828
0b10 // binary not supported
2929
_
3030
____________________________
31-
0x10 // hexadecimal not supported, but it should be
32-
_
33-
___________________________________________________
3431
55e-20
3532
______
3633
______
@@ -43,6 +40,9 @@ _______
4340
10E
4441
__
4542
___
43+
0x10
44+
____
45+
____
4646
64e+
4747
__
4848
____

tests/fixtures/sort/exponents_general.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
+100000
55

66
10000K78
7-
0x10 // hexadecimal not supported, but it should be
7+
0x10
88
10E
99
0b10 // binary not supported
1010
64e+

0 commit comments

Comments
 (0)