From 65cbde4b30f8fdf6d4cf1196f6a596a5550c9aee Mon Sep 17 00:00:00 2001 From: rubidium42 Date: Wed, 28 Apr 2021 16:46:24 +0200 Subject: Codechange: move currency settings to std::string --- src/currency.h | 16 +++++++--------- src/newgrf.cpp | 26 ++++++++++++++++++++------ src/settings_gui.cpp | 12 ++++++------ src/strings.cpp | 6 +++--- src/table/currency_settings.ini | 18 +++++++++--------- 5 files changed, 45 insertions(+), 33 deletions(-) diff --git a/src/currency.h b/src/currency.h index e97fc6cb8..10caa59d3 100644 --- a/src/currency.h +++ b/src/currency.h @@ -70,11 +70,11 @@ enum Currencies { /** Specification of a currency. */ struct CurrencySpec { - uint16 rate; - char separator[8]; - Year to_euro; ///< %Year of switching to the Euro. May also be #CF_NOEURO or #CF_ISEURO. - char prefix[16]; - char suffix[16]; + uint16 rate; ///< The conversion rate compared to the base currency. + std::string separator; ///< The thousands separator for this currency. + Year to_euro; ///< %Year of switching to the Euro. May also be #CF_NOEURO or #CF_ISEURO. + std::string prefix; ///< Prefix to apply when formatting money in this currency. + std::string suffix; ///< Suffix to apply when formatting money in this currency. /** * The currency symbol is represented by two possible values, prefix and suffix * Usage of one or the other is determined by #symbol_pos. @@ -89,11 +89,9 @@ struct CurrencySpec { CurrencySpec() = default; - CurrencySpec(uint16 rate, const char *separator, Year to_euro, const char *prefix, const char *suffix, byte symbol_pos, StringID name) : rate(rate), to_euro(to_euro), symbol_pos(symbol_pos), name(name) + CurrencySpec(uint16 rate, const char *separator, Year to_euro, const char *prefix, const char *suffix, byte symbol_pos, StringID name) : + rate(rate), separator(separator), to_euro(to_euro), prefix(prefix), suffix(suffix), symbol_pos(symbol_pos), name(name) { - strecpy(this->separator, separator, lastof(this->separator)); - strecpy(this->prefix, prefix, lastof(this->prefix)); - strecpy(this->suffix, suffix, lastof(this->suffix)); } }; diff --git a/src/newgrf.cpp b/src/newgrf.cpp index c372f033a..3473cbdc2 100644 --- a/src/newgrf.cpp +++ b/src/newgrf.cpp @@ -2587,6 +2587,22 @@ static ChangeInfoResult LoadTranslationTable(uint gvid, int numinfo, ByteReader return CIR_SUCCESS; } +/** + * Helper to read a DWord worth of bytes from the reader + * and to return it as a valid string. + * @param reader The source of the DWord. + * @return The read DWord as string. + */ +static std::string ReadDWordAsString(ByteReader *reader) +{ + char output[5]; + for (int i = 0; i < 4; i++) output[i] = reader->ReadByte(); + output[4] = '\0'; + str_validate(output, lastof(output)); + + return std::string(output); +} + /** * Define properties for global variables * @param gvid ID of the global variable. @@ -2674,11 +2690,10 @@ static ChangeInfoResult GlobalVarChangeInfo(uint gvid, int numinfo, int prop, By case 0x0D: { // Currency prefix symbol uint curidx = GetNewgrfCurrencyIdConverted(gvid + i); - uint32 tempfix = buf->ReadDWord(); + std::string prefix = ReadDWordAsString(buf); if (curidx < CURRENCY_END) { - memcpy(_currency_specs[curidx].prefix, &tempfix, 4); - _currency_specs[curidx].prefix[4] = 0; + _currency_specs[curidx].prefix = prefix; } else { grfmsg(1, "GlobalVarChangeInfo: Currency symbol %d out of range, ignoring", curidx); } @@ -2687,11 +2702,10 @@ static ChangeInfoResult GlobalVarChangeInfo(uint gvid, int numinfo, int prop, By case 0x0E: { // Currency suffix symbol uint curidx = GetNewgrfCurrencyIdConverted(gvid + i); - uint32 tempfix = buf->ReadDWord(); + std::string suffix = ReadDWordAsString(buf); if (curidx < CURRENCY_END) { - memcpy(&_currency_specs[curidx].suffix, &tempfix, 4); - _currency_specs[curidx].suffix[4] = 0; + _currency_specs[curidx].suffix = suffix; } else { grfmsg(1, "GlobalVarChangeInfo: Currency symbol %d out of range, ignoring", curidx); } diff --git a/src/settings_gui.cpp b/src/settings_gui.cpp index 15c6a887e..664cfbd21 100644 --- a/src/settings_gui.cpp +++ b/src/settings_gui.cpp @@ -2668,7 +2668,7 @@ struct CustomCurrencyWindow : Window { case WID_CC_SEPARATOR: SetDParamStr(0, _custom_currency.separator); str = STR_JUST_RAW_STRING; - len = sizeof(_custom_currency.separator) - 1; // Number of characters excluding '\0' termination + len = 7; line = WID_CC_SEPARATOR; break; @@ -2676,7 +2676,7 @@ struct CustomCurrencyWindow : Window { case WID_CC_PREFIX: SetDParamStr(0, _custom_currency.prefix); str = STR_JUST_RAW_STRING; - len = sizeof(_custom_currency.prefix) - 1; // Number of characters excluding '\0' termination + len = 15; line = WID_CC_PREFIX; break; @@ -2684,7 +2684,7 @@ struct CustomCurrencyWindow : Window { case WID_CC_SUFFIX: SetDParamStr(0, _custom_currency.suffix); str = STR_JUST_RAW_STRING; - len = sizeof(_custom_currency.suffix) - 1; // Number of characters excluding '\0' termination + len = 15; line = WID_CC_SUFFIX; break; @@ -2728,15 +2728,15 @@ struct CustomCurrencyWindow : Window { break; case WID_CC_SEPARATOR: // Thousands separator - strecpy(_custom_currency.separator, str, lastof(_custom_currency.separator)); + _custom_currency.separator = str; break; case WID_CC_PREFIX: - strecpy(_custom_currency.prefix, str, lastof(_custom_currency.prefix)); + _custom_currency.prefix = str; break; case WID_CC_SUFFIX: - strecpy(_custom_currency.suffix, str, lastof(_custom_currency.suffix)); + _custom_currency.suffix = str; break; case WID_CC_YEAR: { // Year to switch to euro diff --git a/src/strings.cpp b/src/strings.cpp index 3c2c07bde..b5cb59d20 100644 --- a/src/strings.cpp +++ b/src/strings.cpp @@ -486,7 +486,7 @@ static char *FormatGenericCurrency(char *buff, const CurrencySpec *spec, Money n /* Add prefix part, following symbol_pos specification. * Here, it can can be either 0 (prefix) or 2 (both prefix and suffix). * The only remaining value is 1 (suffix), so everything that is not 1 */ - if (spec->symbol_pos != 1) buff = strecpy(buff, spec->prefix, last); + if (spec->symbol_pos != 1) buff = strecpy(buff, spec->prefix.c_str(), last); /* for huge numbers, compact the number into k or M */ if (compact) { @@ -502,7 +502,7 @@ static char *FormatGenericCurrency(char *buff, const CurrencySpec *spec, Money n } const char *separator = _settings_game.locale.digit_group_separator_currency.c_str(); - if (StrEmpty(separator)) separator = _currency->separator; + if (StrEmpty(separator)) separator = _currency->separator.c_str(); if (StrEmpty(separator)) separator = _langpack.langpack->digit_group_separator_currency; buff = FormatNumber(buff, number, last, separator); buff = strecpy(buff, multiplier, last); @@ -510,7 +510,7 @@ static char *FormatGenericCurrency(char *buff, const CurrencySpec *spec, Money n /* Add suffix part, following symbol_pos specification. * Here, it can can be either 1 (suffix) or 2 (both prefix and suffix). * The only remaining value is 1 (prefix), so everything that is not 0 */ - if (spec->symbol_pos != 0) buff = strecpy(buff, spec->suffix, last); + if (spec->symbol_pos != 0) buff = strecpy(buff, spec->suffix.c_str(), last); if (negative) { if (buff + Utf8CharLen(SCC_POP_COLOUR) > last) return buff; diff --git a/src/table/currency_settings.ini b/src/table/currency_settings.ini index 3e51d0240..d2f12473e 100644 --- a/src/table/currency_settings.ini +++ b/src/table/currency_settings.ini @@ -9,9 +9,9 @@ static const SettingDesc _currency_settings[] = { [post-amble] }; [templates] -SDT_VAR = SDT_VAR($base, $var, $type, $flags, $guiflags, $def, $min, $max, $interval, $str, $strhelp, $strval, $proc, $from, $to, $cat, $extra, $startup), -SDT_STR = SDT_STR($base, $var, $type, $flags, $guiflags, $def, $str, $strhelp, $strval, $proc, $from, $to, $cat, $extra, $startup), -SDT_END = SDT_END() +SDT_VAR = SDT_VAR ($base, $var, $type, $flags, $guiflags, $def, $min, $max, $interval, $str, $strhelp, $strval, $proc, $from, $to, $cat, $extra, $startup), +SDT_SSTR = SDT_SSTR($base, $var, $type, $flags, $guiflags, $def, $str, $strhelp, $strval, $proc, $from, $to, $cat, $extra, $startup), +SDT_END = SDT_END() [validation] SDT_VAR = static_assert($max <= MAX_$type, "Maximum value for $base.$var exceeds storage size"); @@ -41,10 +41,10 @@ def = 1 min = 0 max = UINT16_MAX -[SDT_STR] +[SDT_SSTR] base = CurrencySpec var = separator -type = SLE_STRBQ +type = SLE_STRQ def = ""."" cat = SC_BASIC @@ -56,16 +56,16 @@ def = 0 min = MIN_YEAR max = MAX_YEAR -[SDT_STR] +[SDT_SSTR] base = CurrencySpec var = prefix -type = SLE_STRBQ +type = SLE_STRQ def = nullptr -[SDT_STR] +[SDT_SSTR] base = CurrencySpec var = suffix -type = SLE_STRBQ +type = SLE_STRQ def = "" credits"" [SDT_END] -- cgit v1.2.3-54-g00ecf