Codechange: replace strnatcmp with C++ string capable version

pull/532/head
Rubidium 1 year ago committed by rubidium42
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…
Cancel
Save