Fix T72878: Alphabetical sorting in Outliner sorts shorter names last

E.g. "Cube" would be placed after "Cube.001", which is not what you'd
expect. 2.80 handled this correctly.

Loosely based on D6525 by @radcapricorn, but found a bug in that and
prefered to do some further adjustments.

Also activates test for this case.
This commit is contained in:
Julian Eisel
2020-01-08 16:04:00 +01:00
parent 525b0e0ccb
commit f52d9a878d
2 changed files with 14 additions and 7 deletions

View File

@@ -685,6 +685,7 @@ int BLI_strcasecmp_natural(const char *s1, const char *s2)
return numcompare; return numcompare;
} }
/* Some wasted work here, left_number_strcmp already consumes at least some digits. */
d1++; d1++;
while (isdigit(s1[d1])) { while (isdigit(s1[d1])) {
d1++; d1++;
@@ -695,14 +696,22 @@ int BLI_strcasecmp_natural(const char *s1, const char *s2)
} }
} }
/* Test for end of strings first so that shorter strings are ordered in front. */
if (ELEM(0, s1[d1], s2[d2])) {
break;
}
c1 = tolower(s1[d1]); c1 = tolower(s1[d1]);
c2 = tolower(s2[d2]); c2 = tolower(s2[d2]);
/* first check for '.' so "foo.bar" comes before "foo 1.bar" */ if (c1 == c2) {
if (c1 == '.' && c2 != '.') { /* Continue iteration */
}
/* Check for '.' so "foo.bar" comes before "foo 1.bar". */
else if (c1 == '.') {
return -1; return -1;
} }
if (c1 != '.' && c2 == '.') { else if (c2 == '.') {
return 1; return 1;
} }
else if (c1 < c2) { else if (c1 < c2) {
@@ -711,9 +720,7 @@ int BLI_strcasecmp_natural(const char *s1, const char *s2)
else if (c1 > c2) { else if (c1 > c2) {
return 1; return 1;
} }
else if (c1 == 0) {
break;
}
d1++; d1++;
d2++; d2++;
} }

View File

@@ -801,7 +801,7 @@ TEST_F(StringCasecmpNatural, TextAndNumbers)
const CompareWordsArray negative{ const CompareWordsArray negative{
{"00je møder0", "00je møder1"}, {"00je møder0", "00je møder1"},
{"05je møder0", "06je møder1"}, {"05je møder0", "06je møder1"},
// {"Cube", "Cube.001"}, {"Cube", "Cube.001"},
{"Cube.001", "Cube.002"}, {"Cube.001", "Cube.002"},
{"CUbe.001", "Cube.002"}, {"CUbe.001", "Cube.002"},
{"CUbe.002", "Cube.002"}, {"CUbe.002", "Cube.002"},