From e1a9f0e9ceffe1140ca8e787f5a97915092bc4f1 Mon Sep 17 00:00:00 2001 From: Andrei Drexler Date: Sun, 3 Mar 2024 10:24:19 +0100 Subject: [PATCH] Support negative numbers in q_strnaturalcmp Note: we only support negative numbers at the beginning of strings so that "-2" is sorted before "-1", but "file-2345.ext" *after* "file-1234.ext". --- Quake/common.c | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/Quake/common.c b/Quake/common.c index 59b7906b6..6e7933598 100644 --- a/Quake/common.c +++ b/Quake/common.c @@ -225,9 +225,20 @@ void MultiString_Append (char **pvec, const char *str) int q_strnaturalcmp (const char *s1, const char *s2) { + qboolean neg1, neg2, sign1, sign2; + if (s1 == s2) return 0; + neg1 = *s1 == '-'; + neg2 = *s2 == '-'; + sign1 = neg1 || *s1 == '+'; + sign2 = neg2 || *s2 == '+'; + + // early out if strings start with different signs followed by digits + if (neg1 != neg2 && q_isdigit (s1[sign1]) && q_isdigit (s1[sign2])) + return neg2 - neg1; + skip_prefix: while (*s1 && !q_isdigit (*s1) && q_toupper (*s1) == q_toupper (*s2)) { @@ -240,7 +251,7 @@ int q_strnaturalcmp (const char *s1, const char *s2) { const char *begin1 = s1++; const char *begin2 = s2++; - int diff; + int diff, sign; while (*begin1 == '0') begin1++; @@ -252,17 +263,23 @@ int q_strnaturalcmp (const char *s1, const char *s2) while (q_isdigit (*s2)) s2++; + sign = neg1 ? -1 : 1; + diff = (s1 - begin1) - (s2 - begin2); if (diff) - return diff; + return diff * sign; while (begin1 != s1) { diff = *begin1++ - *begin2++; if (diff) - return diff; + return diff * sign; } + // We only support negative numbers at the beginning of strings so that + // "-2" is sorted before "-1", but "file-2345.ext" *after* "file-1234.ext". + neg1 = neg2 = false; + goto skip_prefix; }