mirror of
https://code.blicky.net/yorhel/ncdu.git
synced 2026-01-14 17:58:40 -09:00
parent
41f7ecafcb
commit
edf48f6f11
2 changed files with 108 additions and 3 deletions
|
|
@ -103,11 +103,10 @@ fn sortLt(_: void, ap: ?*model.Entry, bp: ?*model.Entry) bool {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Unicode-aware sorting might be nice (and slow)
|
|
||||||
const an = a.name();
|
const an = a.name();
|
||||||
const bn = b.name();
|
const bn = b.name();
|
||||||
return if (main.config.sort_order == .asc) std.mem.lessThan(u8, an, bn)
|
return if (main.config.sort_order == .asc) util.strnatcmp(an, bn) == .lt
|
||||||
else std.mem.lessThan(u8, bn, an);
|
else util.strnatcmp(bn, an) == .lt;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Should be called when:
|
// Should be called when:
|
||||||
|
|
|
||||||
106
src/util.zig
106
src/util.zig
|
|
@ -36,3 +36,109 @@ pub fn arrayListBufZ(buf: *std.ArrayList(u8)) [:0]const u8 {
|
||||||
defer buf.items.len -= 1;
|
defer buf.items.len -= 1;
|
||||||
return buf.items[0..buf.items.len-1:0];
|
return buf.items[0..buf.items.len-1:0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Straightforward Zig port of strnatcmp() from https://github.com/sourcefrog/natsort/
|
||||||
|
// (Requiring nul-terminated strings is ugly, but we've got them anyway and it does simplify the code)
|
||||||
|
pub fn strnatcmp(a: [:0]const u8, b: [:0]const u8) std.math.Order {
|
||||||
|
var ai: usize = 0;
|
||||||
|
var bi: usize = 0;
|
||||||
|
const isDigit = std.ascii.isDigit;
|
||||||
|
while (true) {
|
||||||
|
while (std.ascii.isSpace(a[ai])) ai += 1;
|
||||||
|
while (std.ascii.isSpace(b[bi])) bi += 1;
|
||||||
|
|
||||||
|
if (isDigit(a[ai]) and isDigit(b[bi])) {
|
||||||
|
if (a[ai] == '0' or b[bi] == '0') { // compare_left
|
||||||
|
while (true) {
|
||||||
|
if (!isDigit(a[ai]) and !isDigit(b[bi])) break;
|
||||||
|
if (!isDigit(a[ai])) return .lt;
|
||||||
|
if (!isDigit(b[bi])) return .gt;
|
||||||
|
if (a[ai] < b[bi]) return .lt;
|
||||||
|
if (a[ai] > b[bi]) return .gt;
|
||||||
|
ai += 1;
|
||||||
|
bi += 1;
|
||||||
|
}
|
||||||
|
} else { // compare_right - for right-aligned numbers
|
||||||
|
var bias = std.math.Order.eq;
|
||||||
|
while (true) {
|
||||||
|
if (!isDigit(a[ai]) and !isDigit(b[bi])) {
|
||||||
|
if (bias != .eq or (a[ai] == 0 and b[bi] == 0)) return bias
|
||||||
|
else break;
|
||||||
|
}
|
||||||
|
if (!isDigit(a[ai])) return .lt;
|
||||||
|
if (!isDigit(b[bi])) return .gt;
|
||||||
|
if (bias == .eq) {
|
||||||
|
if (a[ai] < b[bi]) bias = .lt;
|
||||||
|
if (a[ai] > b[bi]) bias = .gt;
|
||||||
|
}
|
||||||
|
ai += 1;
|
||||||
|
bi += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (a[ai] == 0 and b[bi] == 0) return .eq;
|
||||||
|
if (a[ai] < b[bi]) return .lt;
|
||||||
|
if (a[ai] > b[bi]) return .gt;
|
||||||
|
ai += 1;
|
||||||
|
bi += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
test "strnatcmp" {
|
||||||
|
// Test strings from https://github.com/sourcefrog/natsort/
|
||||||
|
// Includes sorted-words, sorted-dates and sorted-fractions.
|
||||||
|
const w = [_][:0]const u8{
|
||||||
|
"1-02",
|
||||||
|
"1-2",
|
||||||
|
"1-20",
|
||||||
|
"1.002.01",
|
||||||
|
"1.002.03",
|
||||||
|
"1.002.08",
|
||||||
|
"1.009.02",
|
||||||
|
"1.009.10",
|
||||||
|
"1.009.20",
|
||||||
|
"1.010.12",
|
||||||
|
"1.011.02",
|
||||||
|
"10-20",
|
||||||
|
"1999-3-3",
|
||||||
|
"1999-12-25",
|
||||||
|
"2000-1-2",
|
||||||
|
"2000-1-10",
|
||||||
|
"2000-3-23",
|
||||||
|
"fred",
|
||||||
|
"jane",
|
||||||
|
"pic01",
|
||||||
|
"pic02",
|
||||||
|
"pic02a",
|
||||||
|
"pic02000",
|
||||||
|
"pic05",
|
||||||
|
"pic2",
|
||||||
|
"pic3",
|
||||||
|
"pic4",
|
||||||
|
"pic 4 else",
|
||||||
|
"pic 5",
|
||||||
|
"pic 5 ",
|
||||||
|
"pic 5 something",
|
||||||
|
"pic 6",
|
||||||
|
"pic 7",
|
||||||
|
"pic100",
|
||||||
|
"pic100a",
|
||||||
|
"pic120",
|
||||||
|
"pic121",
|
||||||
|
"tom",
|
||||||
|
"x2-g8",
|
||||||
|
"x2-y08",
|
||||||
|
"x2-y7",
|
||||||
|
"x8-y8",
|
||||||
|
};
|
||||||
|
// Test each string against each other string, simple and thorough.
|
||||||
|
const eq = std.testing.expectEqual;
|
||||||
|
var i: usize = 0;
|
||||||
|
while (i < w.len) : (i += 1) {
|
||||||
|
var j: usize = 0;
|
||||||
|
try eq(strnatcmp(w[i], w[i]), .eq);
|
||||||
|
while (j < i) : (j += 1) try eq(strnatcmp(w[i], w[j]), .gt);
|
||||||
|
j += 1;
|
||||||
|
while (j < w.len) : (j += 1) try eq(strnatcmp(w[i], w[j]), .lt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue