Fix #25910: Folders starting with numbers sort incorrectly (#25914)

Commit 43f7d2d91 introduced a regression where logicalCmp compared digit starting strings lexicographically instead of numerically, causing folders to sort as "1, 10, 11, 2..." instead of "1, 2... 10, 11". This commit removes the broken special case,  the main loop already handles
numeric comparison correctly
This commit is contained in:
frozensnowy
2026-02-05 21:50:21 +01:00
committed by GitHub
parent 1723925c5c
commit b3217703fe
3 changed files with 10 additions and 33 deletions
+1
View File
@@ -3,6 +3,7 @@
- Feature: [#22704] Rides can be made invisible more easily.
- Improved: [#25941] The command line sprite build command is now faster.
- Fix: [#25237] Wrong colours on the Knight costume.
- Fix: [#25910] Folders starting with numbers are sorted incorrectly (e.g. 1, 10, 2 instead of 1, 2, 10).
0.4.31 (2026-02-01)
------------------------------------------------------------------------
+4 -30
View File
@@ -721,13 +721,8 @@ namespace OpenRCT2::String
return escaped.str();
}
/* Case insensitive logical compare, produces the same output as Notepad++ lexicographical sort */
// Example:
// - Guest 10
// - Guest 99
// - Guest 100
// - John v2.0
// - John v2.1
// Case insensitive natural sort (numbers compared numerically).
// Strings starting with digits sort before alphabetic strings.
int32_t logicalCmp(const char* s1, const char* s2)
{
const auto isDigit = [](char c) { return std::isdigit(static_cast<unsigned char>(c)); };
@@ -737,30 +732,9 @@ namespace OpenRCT2::String
bool s1StartsDigit = isDigit(*s1);
bool s2StartsDigit = isDigit(*s2);
if (s1StartsDigit && !s2StartsDigit)
{
return -1; // s1 (starts with digit) comes before s2
}
return -1;
if (!s1StartsDigit && s2StartsDigit)
{
return 1; // s2 (starts with digit) comes before s1
}
// If both start with digits, compare lexicographically
if (s1StartsDigit && s2StartsDigit)
{
while (*s1 != '\0' && *s2 != '\0')
{
char c1 = toUpper(*s1);
char c2 = toUpper(*s2);
if (c1 != c2)
{
return c1 - c2;
}
s1++;
s2++;
}
return *s1 == '\0' ? (*s2 == '\0' ? 0 : -1) : 1;
}
return 1;
while (*s1 != '\0' && *s2 != '\0')
{
+5 -3
View File
@@ -255,10 +255,12 @@ TEST_F(CodepointViewTest, CodepointView_iterate)
TEST_F(StringTest, LogicalCompare)
{
// Strings starting with digits come first, sorted numerically
// Then alphabetic strings sorted case-insensitively
std::vector<std::string> expected = {
"1001 Troubles", "3D Cinema 1", "Aerial Cycles", "Batflyer", "bpb",
"bpb.sv6", "Drive-by", "foo", "foobar", "Guest 10",
"Guest 99", "Guest 100", "John v2.0", "John v2.1", "River of the Damned",
"3D Cinema 1", "1001 Troubles", "Aerial Cycles", "Batflyer", "bpb",
"bpb.sv6", "Drive-by", "foo", "foobar", "Guest 10",
"Guest 99", "Guest 100", "John v2.0", "John v2.1", "River of the Damned",
"Terror-dactyl",
};