diff options
author | RĂ©mi Verschelde <rverschelde@gmail.com> | 2020-10-07 13:59:14 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-10-07 13:59:14 +0200 |
commit | cb77e8d6cfefab19835f2a3053dacf24f6ded910 (patch) | |
tree | 59994a9e0dd337f92c3aa8cc5bab8460bf324075 /core | |
parent | e93af13959e2840e6fed58fb79ec4f7b9fdfec6a (diff) | |
parent | de46c92711f83b14a532702060d17b4269b9e1e9 (diff) |
Merge pull request #40097 from mrushyendra/file_sort_master
Fix natural sort comparison for strings with large numbers
Diffstat (limited to 'core')
-rw-r--r-- | core/ustring.cpp | 41 |
1 files changed, 29 insertions, 12 deletions
diff --git a/core/ustring.cpp b/core/ustring.cpp index 0033c31e20..18603f37eb 100644 --- a/core/ustring.cpp +++ b/core/ustring.cpp @@ -787,29 +787,46 @@ signed char String::naturalnocasecmp_to(const String &p_str) const { if (!*that_str) { return 1; } else if (IS_DIGIT(*this_str)) { - int64_t this_int, that_int; - if (!IS_DIGIT(*that_str)) { return -1; } - /* Compare the numbers */ - this_int = to_int(this_str, -1, true); - that_int = to_int(that_str, -1, true); + // Keep ptrs to start of numerical sequences + const CharType *this_substr = this_str; + const CharType *that_substr = that_str; - if (this_int < that_int) { - return -1; - } else if (this_int > that_int) { - return 1; - } - - /* Skip */ + // Compare lengths of both numerical sequences, ignoring leading zeros while (IS_DIGIT(*this_str)) { this_str++; } while (IS_DIGIT(*that_str)) { that_str++; } + while (*this_substr == '0') { + this_substr++; + } + while (*that_substr == '0') { + that_substr++; + } + int this_len = this_str - this_substr; + int that_len = that_str - that_substr; + + if (this_len < that_len) { + return -1; + } else if (this_len > that_len) { + return 1; + } + + // If lengths equal, compare lexicographically + while (this_substr != this_str && that_substr != that_str) { + if (*this_substr < *that_substr) { + return -1; + } else if (*this_substr > *that_substr) { + return 1; + } + this_substr++; + that_substr++; + } } else if (IS_DIGIT(*that_str)) { return 1; } else { |