Changeset - r28497:706f2f6ea5ba
[Not reviewed]
master
0 16 0
Rubidium - 3 months ago 2024-01-17 05:30:44
rubidium@openttd.org
Codechange: replace StrStartsWith/StrEndsWith with starts_with and ends_with
16 files changed with 21 insertions and 231 deletions:
0 comments (0 inline, 0 general)
src/fileio.cpp
Show inline comments
 
@@ -608,7 +608,7 @@ bool TarScanner::AddFile(const std::stri
 
				/* 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;
 
				}
src/fios.cpp
Show inline comments
 
@@ -729,7 +729,7 @@ FiosNumberedSaveName::FiosNumberedSaveNa
 

	
 
	/* 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{});
 
	};
 

	
src/network/core/address.cpp
Show inline comments
 
@@ -449,7 +449,7 @@ void NetworkAddress::Listen(int socktype
 
 */
 
/* 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));
 
	}
src/network/core/http_curl.cpp
Show inline comments
 
@@ -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");
src/network/core/http_winhttp.cpp
Show inline comments
 
@@ -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));
 
	}
 
}
src/network/network_chat_gui.cpp
Show inline comments
 
@@ -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;
src/network/network_coordinator.cpp
Show inline comments
 
@@ -514,7 +514,7 @@ void ClientNetworkCoordinatorSocketHandl
 
 */
 
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
src/network/network_gui.cpp
Show inline comments
 
@@ -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);
src/openttd.cpp
Show inline comments
 
@@ -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);
 
	}
 
}
src/screenshot.cpp
Show inline comments
 
@@ -679,7 +679,7 @@ static const char *MakeScreenshotName(co
 
	}
 

	
 
	/* Handle user-specified filenames ending in # with automatic numbering */
 
	if (StrEndsWith(_screenshot_name, "#")) {
 
	if (_screenshot_name.ends_with("#")) {
 
		generate = true;
 
		_screenshot_name.pop_back();
 
	}
src/script/api/script_text.cpp
Show inline comments
 
@@ -140,7 +140,7 @@ SQInteger ScriptText::_set(HSQUIRRELVM v
 
		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) {
src/settings.cpp
Show inline comments
 
@@ -1604,7 +1604,7 @@ static const SettingDesc *GetSettingFrom
 
	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(Setting
 
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);
 
}
 

	
src/string.cpp
Show inline comments
 
@@ -292,19 +292,6 @@ void StrTrimInPlace(std::string &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.
 
 * @param prefix The prefix to look for.
 
@@ -316,19 +303,6 @@ bool StrStartsWithIgnoreCase(std::string
 
	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); }
src/string_func.h
Show inline comments
 
@@ -30,9 +30,7 @@ bool strtolower(std::string &str, std::s
 
[[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);
src/tests/string_func.cpp
Show inline comments
 
@@ -163,97 +163,6 @@ TEST_CASE("StrEqualsIgnoreCase - std::st
 

	
 
/**** 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 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. */
src/textfile_gui.cpp
Show inline comments
 
@@ -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
 
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 *
 

	
 
#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 *
 
	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;
0 comments (0 inline, 0 general)