diff --git a/src/strgen/strgen.cpp b/src/strgen/strgen.cpp index 63f5c02b4d..0c5e1dfa3f 100644 --- a/src/strgen/strgen.cpp +++ b/src/strgen/strgen.cpp @@ -108,11 +108,11 @@ void FileStringReader::HandlePragma(char *str) if (!memcmp(str, "id ", 3)) { this->data.next_string_id = std::strtoul(str + 3, nullptr, 0); } else if (!memcmp(str, "name ", 5)) { - strecpy(_lang.name, str + 5, lastof(_lang.name)); + strecpy(_lang.name, str + 5); } else if (!memcmp(str, "ownname ", 8)) { - strecpy(_lang.own_name, str + 8, lastof(_lang.own_name)); + strecpy(_lang.own_name, str + 8); } else if (!memcmp(str, "isocode ", 8)) { - strecpy(_lang.isocode, str + 8, lastof(_lang.isocode)); + strecpy(_lang.isocode, str + 8); } else if (!memcmp(str, "textdir ", 8)) { if (!memcmp(str + 8, "ltr", 3)) { _lang.text_dir = TD_LTR; @@ -123,13 +123,13 @@ void FileStringReader::HandlePragma(char *str) } } else if (!memcmp(str, "digitsep ", 9)) { str += 9; - strecpy(_lang.digit_group_separator, strcmp(str, "{NBSP}") == 0 ? NBSP : str, lastof(_lang.digit_group_separator)); + strecpy(_lang.digit_group_separator, strcmp(str, "{NBSP}") == 0 ? NBSP : str); } else if (!memcmp(str, "digitsepcur ", 12)) { str += 12; - strecpy(_lang.digit_group_separator_currency, strcmp(str, "{NBSP}") == 0 ? NBSP : str, lastof(_lang.digit_group_separator_currency)); + strecpy(_lang.digit_group_separator_currency, strcmp(str, "{NBSP}") == 0 ? NBSP : str); } else if (!memcmp(str, "decimalsep ", 11)) { str += 11; - strecpy(_lang.digit_decimal_separator, strcmp(str, "{NBSP}") == 0 ? NBSP : str, lastof(_lang.digit_decimal_separator)); + strecpy(_lang.digit_decimal_separator, strcmp(str, "{NBSP}") == 0 ? NBSP : str); } else if (!memcmp(str, "winlangid ", 10)) { const char *buf = str + 10; long langid = std::strtol(buf, nullptr, 16); @@ -153,7 +153,7 @@ void FileStringReader::HandlePragma(char *str) if (s == nullptr) break; if (_lang.num_genders >= MAX_NUM_GENDERS) FatalError("Too many genders, max {}", MAX_NUM_GENDERS); - strecpy(_lang.genders[_lang.num_genders], s, lastof(_lang.genders[_lang.num_genders])); + strecpy(_lang.genders[_lang.num_genders], s); _lang.num_genders++; } } else if (!memcmp(str, "case ", 5)) { @@ -165,7 +165,7 @@ void FileStringReader::HandlePragma(char *str) if (s == nullptr) break; if (_lang.num_cases >= MAX_NUM_CASES) FatalError("Too many cases, max {}", MAX_NUM_CASES); - strecpy(_lang.cases[_lang.num_cases], s, lastof(_lang.cases[_lang.num_cases])); + strecpy(_lang.cases[_lang.num_cases], s); _lang.num_cases++; } } else { diff --git a/src/strgen/strgen_base.cpp b/src/strgen/strgen_base.cpp index e05c324e2d..cfb603ed55 100644 --- a/src/strgen/strgen_base.cpp +++ b/src/strgen/strgen_base.cpp @@ -756,9 +756,9 @@ void StringReader::ParseFile() /* For each new file we parse, reset the genders, and language codes. */ MemSetT(&_lang, 0); - strecpy(_lang.digit_group_separator, ",", lastof(_lang.digit_group_separator)); - strecpy(_lang.digit_group_separator_currency, ",", lastof(_lang.digit_group_separator_currency)); - strecpy(_lang.digit_decimal_separator, ".", lastof(_lang.digit_decimal_separator)); + strecpy(_lang.digit_group_separator, ","); + strecpy(_lang.digit_group_separator_currency, ","); + strecpy(_lang.digit_decimal_separator, "."); _cur_line = 1; while (this->data.next_string_id < this->data.max_strings) { diff --git a/src/string.cpp b/src/string.cpp index 0174213d00..727fd80681 100644 --- a/src/string.cpp +++ b/src/string.cpp @@ -50,34 +50,27 @@ * Copies characters from one buffer to another. * * Copies the source string to the destination buffer with respect of the - * terminating null-character and the last pointer to the last element in - * the destination buffer. If the last pointer is set to nullptr no boundary - * check is performed. + * terminating null-character and the size of the destination buffer. * - * @note usage: strecpy(dst, src, lastof(dst)); - * @note lastof() applies only to fixed size arrays + * @note usage: strecpy(dst, src); * * @param dst The destination buffer * @param src The buffer containing the string to copy - * @param last The pointer to the last element of the destination buffer - * @return The pointer to the terminating null-character in the destination buffer */ -char *strecpy(char *dst, const char *src, const char *last) +void strecpy(std::span dst, std::string_view src) { - assert(dst <= last); - while (dst != last && *src != '\0') { - *dst++ = *src++; - } - *dst = '\0'; - - if (dst == last && *src != '\0') { + /* Ensure source string fits with NUL terminator; dst must be at least 1 character longer than src. */ + if (std::empty(dst) || std::size(src) >= std::size(dst) - 1U) { #if defined(STRGEN) || defined(SETTINGSGEN) FatalError("String too long for destination buffer"); #else /* STRGEN || SETTINGSGEN */ Debug(misc, 0, "String too long for destination buffer"); + src = src.substr(0, std::size(dst) - 1U); #endif /* STRGEN || SETTINGSGEN */ } - return dst; + + auto it = std::copy(std::begin(src), std::end(src), std::begin(dst)); + *it = '\0'; } /** diff --git a/src/string_func.h b/src/string_func.h index 7567cedd17..eda01a566d 100644 --- a/src/string_func.h +++ b/src/string_func.h @@ -17,7 +17,7 @@ #include "core/bitmath_func.hpp" #include "string_type.h" -char *strecpy(char *dst, const char *src, const char *last) NOACCESS(3); +void strecpy(std::span dst, std::string_view src); std::string FormatArrayAsHex(std::span data);