mirror of
https://github.com/OpenTTD/OpenTTD.git
synced 2025-01-31 11:23:21 +00:00
Codechange: replace strnatcmp with C++ string capable version
This commit is contained in:
parent
df19673fbd
commit
c829930440
@ -156,7 +156,7 @@ static bool EngineNameSorter(const GUIEngineListItem &a, const GUIEngineListItem
|
||||
GetString(last_name[1], STR_ENGINE_NAME, lastof(last_name[1]));
|
||||
}
|
||||
|
||||
int r = strnatcmp(last_name[0], last_name[1]); // Sort by name (natural sorting).
|
||||
int r = StrNaturalCompare(last_name[0], last_name[1]); // Sort by name (natural sorting).
|
||||
|
||||
/* Use EngineID to sort instead since we want consistent sorting */
|
||||
if (r == 0) return EngineNumberSorter(a, b);
|
||||
|
@ -156,13 +156,10 @@ span<const CargoSpec *> _sorted_standard_cargo_specs; ///< Standard cargo specif
|
||||
/** Sort cargo specifications by their name. */
|
||||
static bool CargoSpecNameSorter(const CargoSpec * const &a, const CargoSpec * const &b)
|
||||
{
|
||||
static char a_name[64];
|
||||
static char b_name[64];
|
||||
std::string a_name = GetString(a->name);
|
||||
std::string b_name = GetString(b->name);
|
||||
|
||||
GetString(a_name, a->name, lastof(a_name));
|
||||
GetString(b_name, b->name, lastof(b_name));
|
||||
|
||||
int res = strnatcmp(a_name, b_name); // Sort by name (natural sorting).
|
||||
int res = StrNaturalCompare(a_name, b_name); // Sort by name (natural sorting).
|
||||
|
||||
/* If the names are equal, sort by cargo bitnum. */
|
||||
return (res != 0) ? res < 0 : (a->bitnum < b->bitnum);
|
||||
|
@ -735,7 +735,7 @@ private:
|
||||
GetString(last_name[1], STR_GROUP_NAME, lastof(last_name[1]));
|
||||
}
|
||||
|
||||
int r = strnatcmp(last_name[0], last_name[1]); // Sort by name (natural sorting).
|
||||
int r = StrNaturalCompare(last_name[0], last_name[1]); // Sort by name (natural sorting).
|
||||
if (r == 0) return a->index < b->index;
|
||||
return r < 0;
|
||||
});
|
||||
|
@ -58,7 +58,7 @@ bool FiosItem::operator< (const FiosItem &other) const
|
||||
if ((_savegame_sort_order & SORT_BY_NAME) == 0 && (*this).mtime != other.mtime) {
|
||||
r = (*this).mtime - other.mtime;
|
||||
} else {
|
||||
r = strnatcmp((*this).title, other.title);
|
||||
r = StrNaturalCompare((*this).title, other.title);
|
||||
}
|
||||
if (r == 0) return false;
|
||||
return (_savegame_sort_order & SORT_DESCENDING) ? r > 0 : r < 0;
|
||||
|
@ -191,7 +191,7 @@ private:
|
||||
GetString(last_name[1], STR_GROUP_NAME, lastof(last_name[1]));
|
||||
}
|
||||
|
||||
int r = strnatcmp(last_name[0], last_name[1]); // Sort by name (natural sorting).
|
||||
int r = StrNaturalCompare(last_name[0], last_name[1]); // Sort by name (natural sorting).
|
||||
if (r == 0) return a->index < b->index;
|
||||
return r < 0;
|
||||
});
|
||||
|
@ -202,7 +202,7 @@ static bool IndustryTypeNameSorter(const IndustryType &a, const IndustryType &b)
|
||||
const IndustrySpec *indsp2 = GetIndustrySpec(b);
|
||||
GetString(industry_name[1], indsp2->name, lastof(industry_name[1]));
|
||||
|
||||
int r = strnatcmp(industry_name[0], industry_name[1]); // Sort by name (natural sorting).
|
||||
int r = StrNaturalCompare(industry_name[0], industry_name[1]); // Sort by name (natural sorting).
|
||||
|
||||
/* If the names are equal, sort by industry type. */
|
||||
return (r != 0) ? r < 0 : (a < b);
|
||||
@ -1498,7 +1498,7 @@ protected:
|
||||
/** Sort industries by name */
|
||||
static bool IndustryNameSorter(const Industry * const &a, const Industry * const &b)
|
||||
{
|
||||
int r = strnatcmp(a->GetCachedName(), b->GetCachedName()); // Sort by name (natural sorting).
|
||||
int r = StrNaturalCompare(a->GetCachedName(), b->GetCachedName()); // Sort by name (natural sorting).
|
||||
if (r == 0) return a->index < b->index;
|
||||
return r < 0;
|
||||
}
|
||||
|
@ -432,7 +432,7 @@ class NetworkContentListWindow : public Window, ContentCallback {
|
||||
/** Sort content by name. */
|
||||
static bool NameSorter(const ContentInfo * const &a, const ContentInfo * const &b)
|
||||
{
|
||||
return strnatcmp(a->name.c_str(), b->name.c_str(), true) < 0; // Sort by name (natural sorting).
|
||||
return StrNaturalCompare(a->name, b->name, true) < 0; // Sort by name (natural sorting).
|
||||
}
|
||||
|
||||
/** Sort content by type. */
|
||||
@ -440,7 +440,7 @@ class NetworkContentListWindow : public Window, ContentCallback {
|
||||
{
|
||||
int r = 0;
|
||||
if (a->type != b->type) {
|
||||
r = strnatcmp(content_type_strs[a->type], content_type_strs[b->type]);
|
||||
r = StrNaturalCompare(content_type_strs[a->type], content_type_strs[b->type]);
|
||||
}
|
||||
if (r == 0) return NameSorter(a, b);
|
||||
return r < 0;
|
||||
|
@ -289,7 +289,7 @@ protected:
|
||||
/** Sort servers by name. */
|
||||
static bool NGameNameSorter(NetworkGameList * const &a, NetworkGameList * const &b)
|
||||
{
|
||||
int r = strnatcmp(a->info.server_name.c_str(), b->info.server_name.c_str(), true); // Sort by name (natural sorting).
|
||||
int r = StrNaturalCompare(a->info.server_name, b->info.server_name, true); // Sort by name (natural sorting).
|
||||
if (r == 0) r = a->connection_string.compare(b->connection_string);
|
||||
|
||||
return r < 0;
|
||||
|
@ -670,7 +670,7 @@ bool GRFFileScanner::AddFile(const std::string &filename, size_t basepath_length
|
||||
*/
|
||||
static bool GRFSorter(GRFConfig * const &c1, GRFConfig * const &c2)
|
||||
{
|
||||
return strnatcmp(c1->GetName(), c2->GetName()) < 0;
|
||||
return StrNaturalCompare(c1->GetName(), c2->GetName()) < 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1428,7 +1428,7 @@ private:
|
||||
/** Sort grfs by name. */
|
||||
static bool NameSorter(const GRFConfig * const &a, const GRFConfig * const &b)
|
||||
{
|
||||
int i = strnatcmp(a->GetName(), b->GetName(), true); // Sort by name (natural sorting).
|
||||
int i = StrNaturalCompare(a->GetName(), b->GetName(), true); // Sort by name (natural sorting).
|
||||
if (i != 0) return i < 0;
|
||||
|
||||
i = a->version - b->version;
|
||||
|
@ -322,15 +322,15 @@ void MacOSSetCurrentLocaleName(const char *iso_code)
|
||||
* @param s2 Second string to compare.
|
||||
* @return 1 if s1 < s2, 2 if s1 == s2, 3 if s1 > s2, or 0 if not supported by the OS.
|
||||
*/
|
||||
int MacOSStringCompare(const char *s1, const char *s2)
|
||||
int MacOSStringCompare(std::string_view s1, std::string_view s2)
|
||||
{
|
||||
static bool supported = MacOSVersionIsAtLeast(10, 5, 0);
|
||||
if (!supported) return 0;
|
||||
|
||||
CFStringCompareFlags flags = kCFCompareCaseInsensitive | kCFCompareNumerically | kCFCompareLocalized | kCFCompareWidthInsensitive | kCFCompareForcedOrdering;
|
||||
|
||||
CFAutoRelease<CFStringRef> cf1(CFStringCreateWithCString(kCFAllocatorDefault, s1, kCFStringEncodingUTF8));
|
||||
CFAutoRelease<CFStringRef> cf2(CFStringCreateWithCString(kCFAllocatorDefault, s2, kCFStringEncodingUTF8));
|
||||
CFAutoRelease<CFStringRef> cf1(CFStringCreateWithBytes(kCFAllocatorDefault, (const UInt8 *)s1.data(), s1.size(), kCFStringEncodingUTF8, false));
|
||||
CFAutoRelease<CFStringRef> cf2(CFStringCreateWithBytes(kCFAllocatorDefault, (const UInt8 *)s2.data(), s2.size(), kCFStringEncodingUTF8, false));
|
||||
|
||||
/* If any CFString could not be created (e.g., due to UTF8 invalid chars), return OS unsupported functionality */
|
||||
if (cf1 == nullptr || cf2 == nullptr) return 0;
|
||||
|
@ -83,7 +83,7 @@ public:
|
||||
|
||||
void MacOSResetScriptCache(FontSize size);
|
||||
void MacOSSetCurrentLocaleName(const char *iso_code);
|
||||
int MacOSStringCompare(const char *s1, const char *s2);
|
||||
int MacOSStringCompare(std::string_view s1, std::string_view s2);
|
||||
|
||||
void MacOSRegisterExternalFont(const char *file_path);
|
||||
|
||||
|
@ -567,7 +567,7 @@ void Win32SetCurrentLocaleName(const char *iso_code)
|
||||
MultiByteToWideChar(CP_UTF8, 0, iso, -1, _cur_iso_locale, lengthof(_cur_iso_locale));
|
||||
}
|
||||
|
||||
int OTTDStringCompare(const char *s1, const char *s2)
|
||||
int OTTDStringCompare(std::string_view s1, std::string_view s2)
|
||||
{
|
||||
typedef int (WINAPI *PFNCOMPARESTRINGEX)(LPCWSTR, DWORD, LPCWCH, int, LPCWCH, int, LPVOID, LPVOID, LPARAM);
|
||||
static PFNCOMPARESTRINGEX _CompareStringEx = nullptr;
|
||||
@ -588,15 +588,15 @@ int OTTDStringCompare(const char *s1, const char *s2)
|
||||
|
||||
if (_CompareStringEx != nullptr) {
|
||||
/* CompareStringEx takes UTF-16 strings, even in ANSI-builds. */
|
||||
int len_s1 = MultiByteToWideChar(CP_UTF8, 0, s1, -1, nullptr, 0);
|
||||
int len_s2 = MultiByteToWideChar(CP_UTF8, 0, s2, -1, nullptr, 0);
|
||||
int len_s1 = MultiByteToWideChar(CP_UTF8, 0, s1.data(), (int)s1.size(), nullptr, 0);
|
||||
int len_s2 = MultiByteToWideChar(CP_UTF8, 0, s2.data(), (int)s2.size(), nullptr, 0);
|
||||
|
||||
if (len_s1 != 0 && len_s2 != 0) {
|
||||
std::wstring str_s1(len_s1, L'\0'); // len includes terminating null
|
||||
std::wstring str_s2(len_s2, L'\0');
|
||||
|
||||
MultiByteToWideChar(CP_UTF8, 0, s1, -1, str_s1.data(), len_s1);
|
||||
MultiByteToWideChar(CP_UTF8, 0, s2, -1, str_s2.data(), len_s2);
|
||||
MultiByteToWideChar(CP_UTF8, 0, s1.data(), (int)s1.size(), str_s1.data(), len_s1);
|
||||
MultiByteToWideChar(CP_UTF8, 0, s2.data(), (int)s2.size(), str_s2.data(), len_s2);
|
||||
|
||||
int result = _CompareStringEx(_cur_iso_locale, LINGUISTIC_IGNORECASE | SORT_DIGITSASNUMBERS, str_s1.c_str(), -1, str_s2.c_str(), -1, nullptr, nullptr, 0);
|
||||
if (result != 0) return result;
|
||||
|
@ -59,6 +59,6 @@ char *convert_from_fs(const wchar_t *name, char *utf8_buf, size_t buflen);
|
||||
wchar_t *convert_to_fs(const std::string_view name, wchar_t *utf16_buf, size_t buflen);
|
||||
|
||||
void Win32SetCurrentLocaleName(const char *iso_code);
|
||||
int OTTDStringCompare(const char *s1, const char *s2);
|
||||
int OTTDStringCompare(std::string_view s1, std::string_view s2);
|
||||
|
||||
#endif /* WIN32_H */
|
||||
|
@ -47,7 +47,7 @@ struct SignList {
|
||||
|
||||
StringFilter string_filter; ///< The match string to be used when the GUIList is (re)-sorted.
|
||||
static bool match_case; ///< Should case sensitive matching be used?
|
||||
static char default_name[64]; ///< Default sign name, used if Sign::name is nullptr.
|
||||
static std::string default_name; ///< Default sign name, used if Sign::name is nullptr.
|
||||
|
||||
/**
|
||||
* Creates a SignList with filtering disabled by default.
|
||||
@ -79,10 +79,10 @@ struct SignList {
|
||||
* a lot of them. Therefore a worthwhile performance gain can be made by
|
||||
* directly comparing Sign::name instead of going through the string
|
||||
* system for each comparison. */
|
||||
const char *a_name = a->name.empty() ? SignList::default_name : a->name.c_str();
|
||||
const char *b_name = b->name.empty() ? SignList::default_name : b->name.c_str();
|
||||
const std::string &a_name = a->name.empty() ? SignList::default_name : a->name;
|
||||
const std::string &b_name = b->name.empty() ? SignList::default_name : b->name;
|
||||
|
||||
int r = strnatcmp(a_name, b_name); // Sort by name (natural sorting).
|
||||
int r = StrNaturalCompare(a_name, b_name); // Sort by name (natural sorting).
|
||||
|
||||
return r != 0 ? r < 0 : (a->index < b->index);
|
||||
}
|
||||
@ -96,10 +96,10 @@ struct SignList {
|
||||
static bool CDECL SignNameFilter(const Sign * const *a, StringFilter &filter)
|
||||
{
|
||||
/* Same performance benefit as above for sorting. */
|
||||
const char *a_name = (*a)->name.empty() ? SignList::default_name : (*a)->name.c_str();
|
||||
const std::string &a_name = (*a)->name.empty() ? SignList::default_name : (*a)->name;
|
||||
|
||||
filter.ResetState();
|
||||
filter.AddLine(a_name);
|
||||
filter.AddLine(a_name.c_str());
|
||||
return filter.GetState();
|
||||
}
|
||||
|
||||
@ -130,7 +130,7 @@ struct SignList {
|
||||
};
|
||||
|
||||
bool SignList::match_case = false;
|
||||
char SignList::default_name[64];
|
||||
std::string SignList::default_name;
|
||||
|
||||
/** Enum referring to the Hotkeys in the sign list window */
|
||||
enum SignListHotkeys {
|
||||
@ -165,7 +165,7 @@ struct SignListWindow : Window, SignList {
|
||||
void OnInit() override
|
||||
{
|
||||
/* Default sign name, used if Sign::name is nullptr. */
|
||||
GetString(SignList::default_name, STR_DEFAULT_SIGN_NAME, lastof(SignList::default_name));
|
||||
SignList::default_name = GetString(STR_DEFAULT_SIGN_NAME);
|
||||
this->signs.ForceResort();
|
||||
this->SortSignsList();
|
||||
this->SetDirty();
|
||||
|
@ -258,7 +258,7 @@ protected:
|
||||
/** Sort stations by their name */
|
||||
static bool StationNameSorter(const Station * const &a, const Station * const &b)
|
||||
{
|
||||
int r = strnatcmp(a->GetCachedName(), b->GetCachedName()); // Sort by name (natural sorting).
|
||||
int r = StrNaturalCompare(a->GetCachedName(), b->GetCachedName()); // Sort by name (natural sorting).
|
||||
if (r == 0) return a->index < b->index;
|
||||
return r < 0;
|
||||
}
|
||||
@ -1186,7 +1186,7 @@ bool CargoSorter::SortStation(StationID st1, StationID st2) const
|
||||
return order == SO_DESCENDING;
|
||||
}
|
||||
|
||||
int res = strnatcmp(Station::Get(st1)->GetCachedName(), Station::Get(st2)->GetCachedName()); // Sort by name (natural sorting).
|
||||
int res = StrNaturalCompare(Station::Get(st1)->GetCachedName(), Station::Get(st2)->GetCachedName()); // Sort by name (natural sorting).
|
||||
if (res == 0) {
|
||||
return this->SortId(st1, st2);
|
||||
} else {
|
||||
|
@ -36,7 +36,7 @@
|
||||
#endif
|
||||
|
||||
#ifdef WITH_ICU_I18N
|
||||
/* Required by strnatcmp. */
|
||||
/* Required by StrNaturalCompare. */
|
||||
# include <unicode/ustring.h>
|
||||
# include "language.h"
|
||||
# include "gfx_func.h"
|
||||
@ -766,9 +766,9 @@ char *strcasestr(const char *haystack, const char *needle)
|
||||
* @param str The string to skip the initial garbage of.
|
||||
* @return The string with the garbage skipped.
|
||||
*/
|
||||
static const char *SkipGarbage(const char *str)
|
||||
static std::string_view SkipGarbage(std::string_view str)
|
||||
{
|
||||
while (*str != '\0' && (*str < '0' || IsInsideMM(*str, ';', '@' + 1) || IsInsideMM(*str, '[', '`' + 1) || IsInsideMM(*str, '{', '~' + 1))) str++;
|
||||
while (str.size() != 0 && (str[0] < '0' || IsInsideMM(str[0], ';', '@' + 1) || IsInsideMM(str[0], '[', '`' + 1) || IsInsideMM(str[0], '{', '~' + 1))) str.remove_prefix(1);
|
||||
return str;
|
||||
}
|
||||
|
||||
@ -780,7 +780,7 @@ static const char *SkipGarbage(const char *str)
|
||||
* @param ignore_garbage_at_front Skip punctuation characters in the front
|
||||
* @return Less than zero if s1 < s2, zero if s1 == s2, greater than zero if s1 > s2.
|
||||
*/
|
||||
int strnatcmp(const char *s1, const char *s2, bool ignore_garbage_at_front)
|
||||
int StrNaturalCompare(std::string_view s1, std::string_view s2, bool ignore_garbage_at_front)
|
||||
{
|
||||
if (ignore_garbage_at_front) {
|
||||
s1 = SkipGarbage(s1);
|
||||
|
@ -58,6 +58,7 @@ void StrTrimInPlace(std::string &str);
|
||||
|
||||
[[nodiscard]] int StrCompareIgnoreCase(const std::string_view str1, const std::string_view str2);
|
||||
[[nodiscard]] bool StrEqualsIgnoreCase(const std::string_view str1, const std::string_view str2);
|
||||
[[nodiscard]] int StrNaturalCompare(std::string_view s1, std::string_view s2, bool ignore_garbage_at_front = false);
|
||||
|
||||
/**
|
||||
* Check if a string buffer is empty.
|
||||
@ -277,6 +278,4 @@ static inline bool IsWhitespace(WChar c)
|
||||
char *strcasestr(const char *haystack, const char *needle);
|
||||
#endif /* strcasestr is available */
|
||||
|
||||
int strnatcmp(const char *s1, const char *s2, bool ignore_garbage_at_front = false);
|
||||
|
||||
#endif /* STRING_FUNC_H */
|
||||
|
@ -1956,12 +1956,10 @@ const char *GetCurrentLocale(const char *param);
|
||||
|
||||
bool StringIDSorter(const StringID &a, const StringID &b)
|
||||
{
|
||||
char stra[512];
|
||||
char strb[512];
|
||||
GetString(stra, a, lastof(stra));
|
||||
GetString(strb, b, lastof(strb));
|
||||
std::string stra = GetString(a);
|
||||
std::string strb = GetString(b);
|
||||
|
||||
return strnatcmp(stra, strb) < 0;
|
||||
return StrNaturalCompare(stra, strb) < 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -746,7 +746,7 @@ private:
|
||||
/** Sort by town name */
|
||||
static bool TownNameSorter(const Town * const &a, const Town * const &b)
|
||||
{
|
||||
return strnatcmp(a->GetCachedName(), b->GetCachedName()) < 0; // Sort by name (natural sorting).
|
||||
return StrNaturalCompare(a->GetCachedName(), b->GetCachedName()) < 0; // Sort by name (natural sorting).
|
||||
}
|
||||
|
||||
/** Sort by population (default descending, as big towns are of the most interest). */
|
||||
|
@ -1345,7 +1345,7 @@ static bool VehicleNameSorter(const Vehicle * const &a, const Vehicle * const &b
|
||||
GetString(last_name[1], STR_VEHICLE_NAME, lastof(last_name[1]));
|
||||
}
|
||||
|
||||
int r = strnatcmp(last_name[0], last_name[1]); // Sort by name (natural sorting).
|
||||
int r = StrNaturalCompare(last_name[0], last_name[1]); // Sort by name (natural sorting).
|
||||
return (r != 0) ? r < 0: VehicleNumberSorter(a, b);
|
||||
}
|
||||
|
||||
|
@ -52,10 +52,9 @@ void DropDownListStringItem::Draw(const Rect &r, bool sel, Colours bg_colour) co
|
||||
*/
|
||||
/* static */ bool DropDownListStringItem::NatSortFunc(std::unique_ptr<const DropDownListItem> const &first, std::unique_ptr<const DropDownListItem> const &second)
|
||||
{
|
||||
char buffer1[512], buffer2[512];
|
||||
GetString(buffer1, static_cast<const DropDownListStringItem*>(first.get())->String(), lastof(buffer1));
|
||||
GetString(buffer2, static_cast<const DropDownListStringItem*>(second.get())->String(), lastof(buffer2));
|
||||
return strnatcmp(buffer1, buffer2) < 0;
|
||||
std::string str1 = GetString(static_cast<const DropDownListStringItem*>(first.get())->String());
|
||||
std::string str2 = GetString(static_cast<const DropDownListStringItem*>(second.get())->String());
|
||||
return StrNaturalCompare(str1, str2) < 0;
|
||||
}
|
||||
|
||||
StringID DropDownListParamStringItem::String() const
|
||||
|
Loading…
Reference in New Issue
Block a user