Codechange: replace StrStartsWith/StrEndsWith with starts_with and ends_with

pull/642/head
Rubidium 5 months ago committed by rubidium42
parent 384b804f9c
commit 2d77cf9c80

@ -608,7 +608,7 @@ bool TarScanner::AddFile(const std::string &filename, size_t, [[maybe_unused]] c
/* Process relative path.
* Note: The destination of links must not contain any directory-links. */
std::string dest = (std::filesystem::path(name).remove_filename() /= link).lexically_normal().string();
if (dest[0] == PATHSEPCHAR || StrStartsWith(dest, "..")) {
if (dest[0] == PATHSEPCHAR || dest.starts_with("..")) {
Debug(misc, 5, "Ignoring link pointing outside of data directory: {} -> {}", name, link);
break;
}

@ -729,7 +729,7 @@ FiosNumberedSaveName::FiosNumberedSaveName(const std::string &prefix) : prefix(p
/* Callback for FiosFileScanner. */
static FiosGetTypeAndNameProc *proc = [](SaveLoadOperation, const std::string &file, const std::string_view ext) {
if (StrEqualsIgnoreCase(ext, ".sav") && StrStartsWith(file, _prefix)) return std::tuple(FIOS_TYPE_FILE, std::string{});
if (StrEqualsIgnoreCase(ext, ".sav") && file.starts_with(_prefix)) return std::tuple(FIOS_TYPE_FILE, std::string{});
return std::tuple(FIOS_TYPE_INVALID, std::string{});
};

@ -449,7 +449,7 @@ void NetworkAddress::Listen(int socktype, SocketList *sockets)
*/
/* static */ ServerAddress ServerAddress::Parse(const std::string &connection_string, uint16_t default_port, CompanyID *company_id)
{
if (StrStartsWith(connection_string, "+")) {
if (connection_string.starts_with("+")) {
std::string_view invite_code = ParseCompanyFromConnectionString(connection_string, company_id);
return ServerAddress(SERVER_ADDRESS_INVITE_CODE, std::string(invite_code));
}

@ -176,7 +176,7 @@ void HttpThread()
/* Prepare POST body and URI. */
if (!request->data.empty()) {
/* When the payload starts with a '{', it is a JSON payload. */
if (StrStartsWith(request->data, "{")) {
if (request->data.starts_with("{")) {
headers = curl_slist_append(headers, "Content-Type: application/json");
} else {
headers = curl_slist_append(headers, "Content-Type: application/x-www-form-urlencoded");

@ -252,7 +252,7 @@ void NetworkHTTPRequest::Connect()
WinHttpSendRequest(this->request, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, reinterpret_cast<DWORD_PTR>(this));
} else {
/* When the payload starts with a '{', it is a JSON payload. */
LPCWSTR content_type = StrStartsWith(data, "{") ? L"Content-Type: application/json\r\n" : L"Content-Type: application/x-www-form-urlencoded\r\n";
LPCWSTR content_type = data.starts_with("{") ? L"Content-Type: application/json\r\n" : L"Content-Type: application/x-www-form-urlencoded\r\n";
WinHttpSendRequest(this->request, content_type, -1, const_cast<char *>(data.c_str()), static_cast<DWORD>(data.size()), static_cast<DWORD>(data.size()), reinterpret_cast<DWORD_PTR>(this));
}
}

@ -408,7 +408,7 @@ struct NetworkChatWindow : public Window {
/* Now any match we make on _chat_tab_completion_buf after this, is perfect */
}
if (tb_buf.size() < cur_name.size() && StrStartsWith(cur_name, tb_buf)) {
if (tb_buf.size() < cur_name.size() && cur_name.starts_with(tb_buf)) {
/* Save the data it was before completion */
if (!second_scan) _chat_tab_completion_buf = tb->buf;
_chat_tab_completion_active = true;

@ -514,7 +514,7 @@ void ClientNetworkCoordinatorSocketHandler::GetListing()
*/
void ClientNetworkCoordinatorSocketHandler::ConnectToServer(const std::string &invite_code, TCPServerConnecter *connecter)
{
assert(StrStartsWith(invite_code, "+"));
assert(invite_code.starts_with("+"));
if (this->connecter_pre.find(invite_code) != this->connecter_pre.end()) {
/* If someone is hammering the refresh key, one can sent out two

@ -649,7 +649,7 @@ public:
tr.top = DrawStringMultiLine(tr, STR_NETWORK_SERVER_LIST_SERVER_VERSION); // server version
SetDParamStr(0, sel->connection_string);
StringID invite_or_address = StrStartsWith(sel->connection_string, "+") ? STR_NETWORK_SERVER_LIST_INVITE_CODE : STR_NETWORK_SERVER_LIST_SERVER_ADDRESS;
StringID invite_or_address = sel->connection_string.starts_with("+") ? STR_NETWORK_SERVER_LIST_INVITE_CODE : STR_NETWORK_SERVER_LIST_SERVER_ADDRESS;
tr.top = DrawStringMultiLine(tr, invite_or_address); // server address / invite code
SetDParam(0, sel->info.start_date);

@ -372,7 +372,7 @@ void MakeNewgameSettingsLive()
void OpenBrowser(const std::string &url)
{
/* Make sure we only accept urls that are sure to open a browser. */
if (StrStartsWith(url, "http://") || StrStartsWith(url, "https://")) {
if (url.starts_with("http://") || url.starts_with("https://")) {
OSOpenBrowser(url);
}
}

@ -679,7 +679,7 @@ static const char *MakeScreenshotName(const char *default_fn, const char *ext, b
}
/* Handle user-specified filenames ending in # with automatic numbering */
if (StrEndsWith(_screenshot_name, "#")) {
if (_screenshot_name.ends_with("#")) {
generate = true;
_screenshot_name.pop_back();
}

@ -140,7 +140,7 @@ SQInteger ScriptText::_set(HSQUIRRELVM vm)
sq_getstring(vm, 2, &key_string);
std::string str = StrMakeValid(key_string);
if (!StrStartsWith(str, "param_") || str.size() > 8) return SQ_ERROR;
if (!str.starts_with("param_") || str.size() > 8) return SQ_ERROR;
k = stoi(str.substr(6));
} else if (sq_gettype(vm, 2) == OT_INTEGER) {

@ -1604,7 +1604,7 @@ static const SettingDesc *GetSettingFromName(const std::string_view name, const
for (auto &desc : settings) {
const SettingDesc *sd = GetSettingDesc(desc);
if (!SlIsObjectCurrentlyValid(sd->save.version_from, sd->save.version_to)) continue;
if (StrEndsWith(sd->GetName(), short_name_suffix)) return sd;
if (sd->GetName().ends_with(short_name_suffix)) return sd;
}
return nullptr;
@ -1633,7 +1633,7 @@ void GetSaveLoadFromSettingTable(SettingTable settings, std::vector<SaveLoad> &s
static const SettingDesc *GetCompanySettingFromName(std::string_view name)
{
static const std::string_view company_prefix = "company.";
if (StrStartsWith(name, company_prefix)) name.remove_prefix(company_prefix.size());
if (name.starts_with(company_prefix)) name.remove_prefix(company_prefix.size());
return GetSettingFromName(name, _company_settings);
}

@ -291,19 +291,6 @@ void StrTrimInPlace(std::string &str)
StrRightTrimInPlace(str);
}
/**
* Check whether the given string starts with the given prefix.
* @param str The string to look at.
* @param prefix The prefix to look for.
* @return True iff the begin of the string is the same as the prefix.
*/
bool StrStartsWith(const std::string_view str, const std::string_view prefix)
{
size_t prefix_len = prefix.size();
if (str.size() < prefix_len) return false;
return str.compare(0, prefix_len, prefix, 0, prefix_len) == 0;
}
/**
* Check whether the given string starts with the given prefix, ignoring case.
* @param str The string to look at.
@ -316,19 +303,6 @@ bool StrStartsWithIgnoreCase(std::string_view str, const std::string_view prefix
return StrEqualsIgnoreCase(str.substr(0, prefix.size()), prefix);
}
/**
* Check whether the given string ends with the given suffix.
* @param str The string to look at.
* @param suffix The suffix to look for.
* @return True iff the end of the string is the same as the suffix.
*/
bool StrEndsWith(const std::string_view str, const std::string_view suffix)
{
size_t suffix_len = suffix.size();
if (str.size() < suffix_len) return false;
return str.compare(str.size() - suffix_len, suffix_len, suffix, 0, suffix_len) == 0;
}
/** Case insensitive implementation of the standard character type traits. */
struct CaseInsensitiveCharTraits : public std::char_traits<char> {
static bool eq(char c1, char c2) { return toupper(c1) == toupper(c2); }

@ -30,9 +30,7 @@ bool strtolower(std::string &str, std::string::size_type offs = 0);
[[nodiscard]] bool StrValid(const char *str, const char *last) NOACCESS(2);
void StrTrimInPlace(std::string &str);
[[nodiscard]] bool StrStartsWith(const std::string_view str, const std::string_view prefix);
[[nodiscard]] bool StrStartsWithIgnoreCase(std::string_view str, const std::string_view prefix);
[[nodiscard]] bool StrEndsWith(const std::string_view str, const std::string_view suffix);
[[nodiscard]] bool StrEndsWithIgnoreCase(std::string_view str, const std::string_view suffix);
[[nodiscard]] int StrCompareIgnoreCase(const std::string_view str1, const std::string_view str2);

@ -163,97 +163,6 @@ TEST_CASE("StrEqualsIgnoreCase - std::string_view")
/**** String starts with *****/
TEST_CASE("StrStartsWith - std::string")
{
/* Everything starts with an empty prefix. */
CHECK(StrStartsWith(std::string{""}, std::string{""}));
CHECK(StrStartsWith(std::string{"a"}, std::string{""}));
/* Equal strings. */
CHECK(StrStartsWith(std::string{"a"}, std::string{"a"}));
CHECK(StrStartsWith(std::string{"A"}, std::string{"A"}));
/* Starts with same. */
CHECK(StrStartsWith(std::string{"ab"}, std::string{"a"}));
CHECK(StrStartsWith(std::string{"Ab"}, std::string{"A"}));
/* Different cases. */
CHECK(!StrStartsWith(std::string{"a"}, std::string{"A"}));
CHECK(!StrStartsWith(std::string{"A"}, std::string{"a"}));
CHECK(!StrStartsWith(std::string{"ab"}, std::string{"A"}));
CHECK(!StrStartsWith(std::string{"Ab"}, std::string{"a"}));
/* Does not start the same. */
CHECK(!StrStartsWith(std::string{""}, std::string{"b"}));
CHECK(!StrStartsWith(std::string{"a"}, std::string{"b"}));
CHECK(!StrStartsWith(std::string{"b"}, std::string{"a"}));
CHECK(!StrStartsWith(std::string{"a"}, std::string{"aa"}));
}
TEST_CASE("StrStartsWith - char pointer")
{
CHECK(StrStartsWith("", ""));
CHECK(StrStartsWith("a", ""));
/* Equal strings. */
CHECK(StrStartsWith("a", "a"));
CHECK(StrStartsWith("A", "A"));
/* Starts with same. */
CHECK(StrStartsWith("ab", "a"));
CHECK(StrStartsWith("Ab", "A"));
/* Different cases. */
CHECK(!StrStartsWith("a", "A"));
CHECK(!StrStartsWith("A", "a"));
CHECK(!StrStartsWith("ab", "A"));
CHECK(!StrStartsWith("Ab", "a"));
/* Does not start the same. */
CHECK(!StrStartsWith("", "b"));
CHECK(!StrStartsWith("a", "b"));
CHECK(!StrStartsWith("b", "a"));
CHECK(!StrStartsWith("a", "aa"));
}
TEST_CASE("StrStartsWith - std::string_view")
{
/*
* With std::string_view the only way to access the data is via .data(),
* which does not guarantee the termination that would be required by
* things such as stricmp/strcasecmp. So, just passing .data() into stricmp
* or strcasecmp would fail if it does not account for the length of the
* view. Thus, contrary to the string/char* tests, this uses the same base
* string but gets different sections to trigger these corner cases.
*/
std::string_view base{"aabAb"};
/* Everything starts with an empty prefix. */
CHECK(StrStartsWith(base.substr(0, 0), base.substr(1, 0))); // Different positions
CHECK(StrStartsWith(base.substr(0, 1), base.substr(0, 0)));
/* Equals string. */
CHECK(StrStartsWith(base.substr(0, 1), base.substr(1, 1))); // Different positions
CHECK(StrStartsWith(base.substr(3, 1), base.substr(3, 1)));
/* Starts with same. */
CHECK(StrStartsWith(base.substr(1, 2), base.substr(0, 1)));
CHECK(StrStartsWith(base.substr(3, 2), base.substr(3, 1)));
/* Different cases. */
CHECK(!StrStartsWith(base.substr(0, 1), base.substr(3, 1)));
CHECK(!StrStartsWith(base.substr(3, 1), base.substr(0, 1)));
CHECK(!StrStartsWith(base.substr(1, 2), base.substr(3, 1)));
CHECK(!StrStartsWith(base.substr(3, 2), base.substr(0, 1)));
/* Does not start the same. */
CHECK(!StrStartsWith(base.substr(2, 0), base.substr(2, 1)));
CHECK(!StrStartsWith(base.substr(0, 1), base.substr(2, 1)));
CHECK(!StrStartsWith(base.substr(2, 1), base.substr(0, 1)));
CHECK(!StrStartsWith(base.substr(0, 1), base.substr(0, 2)));
}
TEST_CASE("StrStartsWithIgnoreCase - std::string")
{
/* Everything starts with an empty prefix. */
@ -341,97 +250,6 @@ TEST_CASE("StrStartsWithIgnoreCase - std::string_view")
/**** String ends with *****/
TEST_CASE("StrEndsWith - std::string")
{
/* Everything ends with an empty prefix. */
CHECK(StrEndsWith(std::string{""}, std::string{""}));
CHECK(StrEndsWith(std::string{"a"}, std::string{""}));
/* Equal strings. */
CHECK(StrEndsWith(std::string{"a"}, std::string{"a"}));
CHECK(StrEndsWith(std::string{"A"}, std::string{"A"}));
/* Ends with same. */
CHECK(StrEndsWith(std::string{"ba"}, std::string{"a"}));
CHECK(StrEndsWith(std::string{"bA"}, std::string{"A"}));
/* Different cases. */
CHECK(!StrEndsWith(std::string{"a"}, std::string{"A"}));
CHECK(!StrEndsWith(std::string{"A"}, std::string{"a"}));
CHECK(!StrEndsWith(std::string{"ba"}, std::string{"A"}));
CHECK(!StrEndsWith(std::string{"bA"}, std::string{"a"}));
/* Does not end the same. */
CHECK(!StrEndsWith(std::string{""}, std::string{"b"}));
CHECK(!StrEndsWith(std::string{"a"}, std::string{"b"}));
CHECK(!StrEndsWith(std::string{"b"}, std::string{"a"}));
CHECK(!StrEndsWith(std::string{"a"}, std::string{"aa"}));
}
TEST_CASE("StrEndsWith - char pointer")
{
CHECK(StrEndsWith("", ""));
CHECK(StrEndsWith("a", ""));
/* Equal strings. */
CHECK(StrEndsWith("a", "a"));
CHECK(StrEndsWith("A", "A"));
/* Ends with same. */
CHECK(StrEndsWith("ba", "a"));
CHECK(StrEndsWith("bA", "A"));
/* Different cases. */
CHECK(!StrEndsWith("a", "A"));
CHECK(!StrEndsWith("A", "a"));
CHECK(!StrEndsWith("ba", "A"));
CHECK(!StrEndsWith("bA", "a"));
/* Does not end the same. */
CHECK(!StrEndsWith("", "b"));
CHECK(!StrEndsWith("a", "b"));
CHECK(!StrEndsWith("b", "a"));
CHECK(!StrEndsWith("a", "aa"));
}
TEST_CASE("StrEndsWith - std::string_view")
{
/*
* With std::string_view the only way to access the data is via .data(),
* which does not guarantee the termination that would be required by
* things such as stricmp/strcasecmp. So, just passing .data() into stricmp
* or strcasecmp would fail if it does not account for the length of the
* view. Thus, contrary to the string/char* tests, this uses the same base
* string but gets different sections to trigger these corner cases.
*/
std::string_view base{"aabAba"};
/* Everything ends with an empty prefix. */
CHECK(StrEndsWith(base.substr(0, 0), base.substr(1, 0))); // Different positions
CHECK(StrEndsWith(base.substr(0, 1), base.substr(0, 0)));
/* Equals string. */
CHECK(StrEndsWith(base.substr(0, 1), base.substr(1, 1))); // Different positions
CHECK(StrEndsWith(base.substr(3, 1), base.substr(3, 1)));
/* Ends with same. */
CHECK(StrEndsWith(base.substr(4, 2), base.substr(0, 1)));
CHECK(StrEndsWith(base.substr(2, 2), base.substr(3, 1)));
/* Different cases. */
CHECK(!StrEndsWith(base.substr(0, 1), base.substr(3, 1)));
CHECK(!StrEndsWith(base.substr(3, 1), base.substr(0, 1)));
CHECK(!StrEndsWith(base.substr(4, 2), base.substr(3, 1)));
CHECK(!StrEndsWith(base.substr(2, 2), base.substr(0, 1)));
/* Does not end the same. */
CHECK(!StrEndsWith(base.substr(2, 0), base.substr(2, 1)));
CHECK(!StrEndsWith(base.substr(0, 1), base.substr(2, 1)));
CHECK(!StrEndsWith(base.substr(2, 1), base.substr(0, 1)));
CHECK(!StrEndsWith(base.substr(0, 1), base.substr(0, 2)));
}
TEST_CASE("StrEndsWithIgnoreCase - std::string")
{
/* Everything ends with an empty prefix. */

@ -177,14 +177,14 @@ enum class HyperlinkType {
static HyperlinkType ClassifyHyperlink(const std::string &destination, bool trusted)
{
if (destination.empty()) return HyperlinkType::Unknown;
if (StrStartsWith(destination, "#")) return HyperlinkType::Internal;
if (destination.starts_with("#")) return HyperlinkType::Internal;
/* Only allow external / internal links for sources we trust. */
if (!trusted) return HyperlinkType::Unknown;
if (StrStartsWith(destination, "http://")) return HyperlinkType::Web;
if (StrStartsWith(destination, "https://")) return HyperlinkType::Web;
if (StrStartsWith(destination, "./")) return HyperlinkType::File;
if (destination.starts_with("http://")) return HyperlinkType::Web;
if (destination.starts_with("https://")) return HyperlinkType::Web;
if (destination.starts_with("./")) return HyperlinkType::File;
return HyperlinkType::Unknown;
}
@ -428,7 +428,7 @@ void TextfileWindow::NavigateHistory(int delta)
void TextfileWindow::NavigateToFile(std::string newfile, size_t line)
{
/* Double-check that the file link begins with ./ as a relative path. */
if (!StrStartsWith(newfile, "./")) return;
if (!newfile.starts_with("./")) return;
/* Get the path portion of the current file path. */
std::string newpath = this->filepath;
@ -783,12 +783,12 @@ static void Xunzip(byte **bufp, size_t *sizep)
#if defined(WITH_ZLIB)
/* In-place gunzip */
if (StrEndsWith(textfile, ".gz")) Gunzip((byte**)&buf, &filesize);
if (textfile.ends_with(".gz")) Gunzip((byte**)&buf, &filesize);
#endif
#if defined(WITH_LIBLZMA)
/* In-place xunzip */
if (StrEndsWith(textfile, ".xz")) Xunzip((byte**)&buf, &filesize);
if (textfile.ends_with(".xz")) Xunzip((byte**)&buf, &filesize);
#endif
if (buf == nullptr) return;
@ -796,7 +796,7 @@ static void Xunzip(byte **bufp, size_t *sizep)
std::string_view sv_buf(buf, filesize);
/* Check for the byte-order-mark, and skip it if needed. */
if (StrStartsWith(sv_buf, "\ufeff")) sv_buf.remove_prefix(3);
if (sv_buf.starts_with("\ufeff")) sv_buf.remove_prefix(3);
/* Update the filename. */
this->filepath = textfile;

Loading…
Cancel
Save