diff --git a/src/console.cpp b/src/console.cpp index d486e780c1..926a868c68 100644 --- a/src/console.cpp +++ b/src/console.cpp @@ -437,6 +437,10 @@ void IConsoleCmdExec(const char *cmdstr) break; case '"': // Tokens enclosed in "" are one token longtoken = !longtoken; + if (!foundtoken) { + tokens[t_index++] = &tokenstream[tstream_i]; + foundtoken = true; + } break; case '\\': // Escape character for "" if (cmdptr[1] == '"' && tstream_i + 1 < lengthof(tokenstream)) { diff --git a/src/currency.cpp b/src/currency.cpp index 05ff9b884e..5d3d88acdd 100644 --- a/src/currency.cpp +++ b/src/currency.cpp @@ -14,43 +14,44 @@ #include "news_func.h" #include "settings_type.h" #include "date_func.h" +#include "string_type.h" #include "table/strings.h" - /* exchange rate prefix symbol_pos - * | separator | postfix | - * | | Euro year | | | name - * | | | | | | | */ + /* exchange rate prefix symbol_pos + * | separator | postfix | + * | | Euro year | | | name + * | | | | | | | */ static const CurrencySpec origin_currency_specs[NUM_CURRENCY] = { - { 1, "", CF_NOEURO, "\xC2\xA3", "", 0, STR_GAME_OPTIONS_CURRENCY_GBP }, ///< british pounds - { 2, "", CF_NOEURO, "$", "", 0, STR_GAME_OPTIONS_CURRENCY_USD }, ///< us dollars - { 2, "", CF_ISEURO, "\xE2\x82\xAC", "", 0, STR_GAME_OPTIONS_CURRENCY_EUR }, ///< Euro - { 220, "", CF_NOEURO, "\xC2\xA5", "", 0, STR_GAME_OPTIONS_CURRENCY_YEN }, ///< yen - { 20, "", 2002, "", " S.", 1, STR_GAME_OPTIONS_CURRENCY_ATS }, ///< austrian schilling - { 59, "", 2002, "BEF ", "", 0, STR_GAME_OPTIONS_CURRENCY_BEF }, ///< belgian franc - { 2, "", CF_NOEURO, "CHF ", "", 0, STR_GAME_OPTIONS_CURRENCY_CHF }, ///< swiss franc - { 41, "", CF_NOEURO, "", " K\xC4\x8D", 1, STR_GAME_OPTIONS_CURRENCY_CZK }, ///< czech koruna - { 3, "", 2002, "DM ", "", 0, STR_GAME_OPTIONS_CURRENCY_DEM }, ///< deutsche mark - { 11, "", CF_NOEURO, "", " kr", 1, STR_GAME_OPTIONS_CURRENCY_DKK }, ///< danish krone - { 245, "", 2002, "Pts ", "", 0, STR_GAME_OPTIONS_CURRENCY_ESP }, ///< spanish pesetas - { 9, "", 2002, "", " mk", 1, STR_GAME_OPTIONS_CURRENCY_FIM }, ///< finnish markka - { 10, "", 2002, "FF ", "", 0, STR_GAME_OPTIONS_CURRENCY_FRF }, ///< french francs - { 500, "", 2002, "", "Dr.", 1, STR_GAME_OPTIONS_CURRENCY_GRD }, ///< greek drachma - { 378, "", CF_NOEURO, "", " Ft", 1, STR_GAME_OPTIONS_CURRENCY_HUF }, ///< hungarian forint - { 130, "", CF_NOEURO, "", " Kr", 1, STR_GAME_OPTIONS_CURRENCY_ISK }, ///< icelandic krona - { 2850, "", 2002, "", " L.", 1, STR_GAME_OPTIONS_CURRENCY_ITL }, ///< italian lira - { 3, "", 2002, "NLG ", "", 0, STR_GAME_OPTIONS_CURRENCY_NLG }, ///< dutch gulden - { 12, "", CF_NOEURO, "", " Kr", 1, STR_GAME_OPTIONS_CURRENCY_NOK }, ///< norwegian krone - { 6, "", CF_NOEURO, "", " z\xC5\x82", 1, STR_GAME_OPTIONS_CURRENCY_PLN }, ///< polish zloty - { 5, "", CF_NOEURO, "", " Lei", 1, STR_GAME_OPTIONS_CURRENCY_RON }, ///< romanian Lei - { 50, "", CF_NOEURO, "", " p", 1, STR_GAME_OPTIONS_CURRENCY_RUR }, ///< russian rouble - { 352, "", 2007, "", " SIT", 1, STR_GAME_OPTIONS_CURRENCY_SIT }, ///< slovenian tolar - { 13, "", CF_NOEURO, "", " Kr", 1, STR_GAME_OPTIONS_CURRENCY_SEK }, ///< swedish krona - { 3, "", CF_NOEURO, "", " TL", 1, STR_GAME_OPTIONS_CURRENCY_TRY }, ///< turkish lira - { 52, "", 2009, "", " Sk", 1, STR_GAME_OPTIONS_CURRENCY_SKK }, ///< slovak koruna - { 4, "", CF_NOEURO, "R$ ", "", 0, STR_GAME_OPTIONS_CURRENCY_BRL }, ///< brazil real - { 20, "", CF_NOEURO, "", " EEK", 1, STR_GAME_OPTIONS_CURRENCY_EEK }, ///< estonian krooni - { 1, "", CF_NOEURO, "", "", 2, STR_GAME_OPTIONS_CURRENCY_CUSTOM }, ///< custom currency + { 1, "", CF_NOEURO, "\xC2\xA3", "", 0, STR_GAME_OPTIONS_CURRENCY_GBP }, ///< british pounds + { 2, "", CF_NOEURO, "$", "", 0, STR_GAME_OPTIONS_CURRENCY_USD }, ///< us dollars + { 2, "", CF_ISEURO, "\xE2\x82\xAC", "", 0, STR_GAME_OPTIONS_CURRENCY_EUR }, ///< Euro + { 220, "", CF_NOEURO, "\xC2\xA5", "", 0, STR_GAME_OPTIONS_CURRENCY_YEN }, ///< yen + { 20, "", 2002, "", NBSP"S.", 1, STR_GAME_OPTIONS_CURRENCY_ATS }, ///< austrian schilling + { 59, "", 2002, "BEF"NBSP, "", 0, STR_GAME_OPTIONS_CURRENCY_BEF }, ///< belgian franc + { 2, "", CF_NOEURO, "CHF"NBSP, "", 0, STR_GAME_OPTIONS_CURRENCY_CHF }, ///< swiss franc + { 41, "", CF_NOEURO, "", NBSP"K\xC4\x8D", 1, STR_GAME_OPTIONS_CURRENCY_CZK }, ///< czech koruna + { 3, "", 2002, "DM"NBSP, "", 0, STR_GAME_OPTIONS_CURRENCY_DEM }, ///< deutsche mark + { 11, "", CF_NOEURO, "", NBSP"kr", 1, STR_GAME_OPTIONS_CURRENCY_DKK }, ///< danish krone + { 245, "", 2002, "Pts"NBSP, "", 0, STR_GAME_OPTIONS_CURRENCY_ESP }, ///< spanish pesetas + { 9, "", 2002, "", NBSP"mk", 1, STR_GAME_OPTIONS_CURRENCY_FIM }, ///< finnish markka + { 10, "", 2002, "FF"NBSP, "", 0, STR_GAME_OPTIONS_CURRENCY_FRF }, ///< french francs + { 500, "", 2002, "", "Dr.", 1, STR_GAME_OPTIONS_CURRENCY_GRD }, ///< greek drachma + { 378, "", CF_NOEURO, "", NBSP"Ft", 1, STR_GAME_OPTIONS_CURRENCY_HUF }, ///< hungarian forint + { 130, "", CF_NOEURO, "", NBSP"Kr", 1, STR_GAME_OPTIONS_CURRENCY_ISK }, ///< icelandic krona + { 2850, "", 2002, "", NBSP"L.", 1, STR_GAME_OPTIONS_CURRENCY_ITL }, ///< italian lira + { 3, "", 2002, "NLG"NBSP, "", 0, STR_GAME_OPTIONS_CURRENCY_NLG }, ///< dutch gulden + { 12, "", CF_NOEURO, "", NBSP"Kr", 1, STR_GAME_OPTIONS_CURRENCY_NOK }, ///< norwegian krone + { 6, "", CF_NOEURO, "", NBSP"z\xC5\x82", 1, STR_GAME_OPTIONS_CURRENCY_PLN }, ///< polish zloty + { 5, "", CF_NOEURO, "", NBSP"Lei", 1, STR_GAME_OPTIONS_CURRENCY_RON }, ///< romanian Lei + { 50, "", CF_NOEURO, "", NBSP"p", 1, STR_GAME_OPTIONS_CURRENCY_RUR }, ///< russian rouble + { 352, "", 2007, "", NBSP"SIT", 1, STR_GAME_OPTIONS_CURRENCY_SIT }, ///< slovenian tolar + { 13, "", CF_NOEURO, "", NBSP"Kr", 1, STR_GAME_OPTIONS_CURRENCY_SEK }, ///< swedish krona + { 3, "", CF_NOEURO, "", NBSP"TL", 1, STR_GAME_OPTIONS_CURRENCY_TRY }, ///< turkish lira + { 52, "", 2009, "", NBSP"Sk", 1, STR_GAME_OPTIONS_CURRENCY_SKK }, ///< slovak koruna + { 4, "", CF_NOEURO, "R$"NBSP, "", 0, STR_GAME_OPTIONS_CURRENCY_BRL }, ///< brazil real + { 20, "", CF_NOEURO, "", NBSP"EEK", 1, STR_GAME_OPTIONS_CURRENCY_EEK }, ///< estonian krooni + { 1, "", CF_NOEURO, "", "", 2, STR_GAME_OPTIONS_CURRENCY_CUSTOM }, ///< custom currency }; /* Array of currencies used by the system */ diff --git a/src/network/network.cpp b/src/network/network.cpp index 0d1e84d788..ba80da4642 100644 --- a/src/network/network.cpp +++ b/src/network/network.cpp @@ -936,7 +936,10 @@ void NetworkDisconnect(bool blocking) NetworkClose(); } -/* Receives something from the network */ +/** + * Receives something from the network. + * @return true if everthing went fine, false when the connection got closed. + */ static bool NetworkReceive() { NetworkClientSocket *cs; @@ -991,7 +994,7 @@ static bool NetworkReceive() } } } - return true; + return _networking; } /* This sends all buffered commands (if possible) */ diff --git a/src/pathfinder/yapf/yapf_road.cpp b/src/pathfinder/yapf/yapf_road.cpp index 91a721da03..baed8d4140 100644 --- a/src/pathfinder/yapf/yapf_road.cpp +++ b/src/pathfinder/yapf/yapf_road.cpp @@ -326,8 +326,11 @@ public: FORCEINLINE Trackdir ChooseRoadTrack(const RoadVehicle *v, TileIndex tile, DiagDirection enterdir) { - /* handle special case - when next tile is destination tile */ - if (tile == v->dest_tile) { + /* Handle special case - when next tile is destination tile. + * However, when going to a station the (initial) destination + * tile might not be a station, but a junction, in which case + * this method forces the vehicle to jump in circles. */ + if (tile == v->dest_tile && !v->current_order.IsType(OT_GOTO_STATION)) { /* choose diagonal trackdir reachable from enterdir */ return DiagDirToDiagTrackdir(enterdir); } diff --git a/src/settings.cpp b/src/settings.cpp index 2e6c425013..a3ccaf1a5d 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -1643,15 +1643,22 @@ uint GetCompanySettingIndex(const char *name) * Set a setting value with a string. * @param index the settings index. * @param value the value to write - * @note CANNOT BE SAVED IN THE SAVEGAME. + * @param force_newgame force the newgame settings + * @note Strings WILL NOT be synced over the network */ -bool SetSettingValue(uint index, const char *value) +bool SetSettingValue(uint index, const char *value, bool force_newgame) { const SettingDesc *sd = &_settings[index]; assert(sd->save.conv & SLF_NETWORK_NO); - char *var = (char*)GetVariableAddress(NULL, &sd->save); - ttd_strlcpy(var, value, sd->save.length); + if (GetVarMemType(sd->save.conv) == SLE_VAR_STRQ) { + char **var = (char**)GetVariableAddress((_game_mode == GM_MENU || force_newgame) ? &_settings_newgame : &_settings_game, &sd->save); + free(*var); + *var = strcmp(value, "(null)") == 0 ? NULL : strdup(value); + } else { + char *var = (char*)GetVariableAddress(NULL, &sd->save); + ttd_strlcpy(var, value, sd->save.length); + } if (sd->desc.proc != NULL) sd->desc.proc(0); return true; @@ -1708,7 +1715,7 @@ void IConsoleSetSetting(const char *name, const char *value, bool force_newgame) bool success; if (sd->desc.cmd == SDT_STRING) { - success = SetSettingValue(index, value); + success = SetSettingValue(index, value, force_newgame); } else { uint32 val; extern bool GetArgumentInteger(uint32 *value, const char *arg); @@ -1758,7 +1765,7 @@ void IConsoleGetSetting(const char *name, bool force_newgame) ptr = GetVariableAddress((_game_mode == GM_MENU || force_newgame) ? &_settings_newgame : &_settings_game, &sd->save); if (sd->desc.cmd == SDT_STRING) { - IConsolePrintF(CC_WARNING, "Current value for '%s' is: '%s'", name, (const char *)ptr); + IConsolePrintF(CC_WARNING, "Current value for '%s' is: '%s'", name, (GetVarMemType(sd->save.conv) == SLE_VAR_STRQ) ? *(const char **)ptr : (const char *)ptr); } else { if (sd->desc.cmd == SDT_BOOLX) { snprintf(value, sizeof(value), (*(bool*)ptr == 1) ? "on" : "off"); @@ -1789,7 +1796,7 @@ void IConsoleListSettings(const char *prefilter) if (sd->desc.cmd == SDT_BOOLX) { snprintf(value, lengthof(value), (*(bool*)ptr == 1) ? "on" : "off"); } else if (sd->desc.cmd == SDT_STRING) { - snprintf(value, sizeof(value), "%s", (const char *)ptr); + snprintf(value, sizeof(value), "%s", (GetVarMemType(sd->save.conv) == SLE_VAR_STRQ) ? *(const char **)ptr : (const char *)ptr); } else { snprintf(value, lengthof(value), "%d", (uint32)ReadValue(ptr, sd->save.conv)); } diff --git a/src/settings_internal.h b/src/settings_internal.h index 009e50f962..bf01f8acc9 100644 --- a/src/settings_internal.h +++ b/src/settings_internal.h @@ -86,7 +86,7 @@ typedef SettingDesc SettingDescGlobVarList; const SettingDesc *GetSettingFromName(const char *name, uint *i); bool SetSettingValue(uint index, int32 value, bool force_newgame = false); -bool SetSettingValue(uint index, const char *value); +bool SetSettingValue(uint index, const char *value, bool force_newgame = false); void SetCompanySetting(uint index, int32 value); extern VehicleDefaultSettings _old_vds; diff --git a/src/strgen/strgen.cpp b/src/strgen/strgen.cpp index 22450bddfe..c97bb58703 100644 --- a/src/strgen/strgen.cpp +++ b/src/strgen/strgen.cpp @@ -536,13 +536,13 @@ static void HandlePragma(char *str) } } else if (!memcmp(str, "digitsep ", 9)) { str += 9; - strecpy(_lang_digit_group_separator, strcmp(str, "{NBSP}") == 0 ? "\xC2\xA0" : str, lastof(_lang_digit_group_separator)); + strecpy(_lang_digit_group_separator, strcmp(str, "{NBSP}") == 0 ? NBSP : str, lastof(_lang_digit_group_separator)); } else if (!memcmp(str, "digitsepcur ", 12)) { str += 12; - strecpy(_lang_digit_group_separator_currency, strcmp(str, "{NBSP}") == 0 ? "\xC2\xA0" : str, lastof(_lang_digit_group_separator_currency)); + strecpy(_lang_digit_group_separator_currency, strcmp(str, "{NBSP}") == 0 ? NBSP : str, lastof(_lang_digit_group_separator_currency)); } else if (!memcmp(str, "decimalsep ", 11)) { str += 11; - strecpy(_lang_digit_decimal_separator, strcmp(str, "{NBSP}") == 0 ? "\xC2\xA0" : str, lastof(_lang_digit_decimal_separator)); + strecpy(_lang_digit_decimal_separator, strcmp(str, "{NBSP}") == 0 ? NBSP : str, lastof(_lang_digit_decimal_separator)); } else if (!memcmp(str, "winlangid ", 10)) { const char *buf = str + 10; long langid = strtol(buf, NULL, 16); diff --git a/src/string.cpp b/src/string.cpp index 16e1e7099d..9309c71990 100644 --- a/src/string.cpp +++ b/src/string.cpp @@ -397,7 +397,7 @@ size_t Utf8TrimString(char *s, size_t maxlen) return length; } -#ifndef _GNU_SOURCE +#ifdef DEFINE_STRNDUP #include "core/math_func.hpp" char *strndup(const char *s, size_t len) { @@ -406,7 +406,7 @@ char *strndup(const char *s, size_t len) memcpy(tmp, s, len); return tmp; } -#endif /* !_GNU_SOURCE */ +#endif /* DEFINE_STRNDUP */ #ifdef DEFINE_STRCASESTR char *strcasestr(const char *haystack, const char *needle) diff --git a/src/string_func.h b/src/string_func.h index 942873593a..f921397a0b 100644 --- a/src/string_func.h +++ b/src/string_func.h @@ -251,13 +251,16 @@ static inline bool IsWhitespace(WChar c) #include #endif -#if !defined(_GNU_SOURCE) && !(defined(__NetBSD_Version__) && 400000000 < __NetBSD_Version__ ) /* strndup is a GNU extension */ +#if defined(_GNU_SOURCE) || (defined(__NetBSD_Version__) && 400000000 <= __NetBSD_Version__) +# undef DEFINE_STRNDUP +#else +# define DEFINE_STRNDUP char *strndup(const char *s, size_t len); -#endif /* !_GNU_SOURCE */ +#endif /* strndup is available */ /* strcasestr is available for _GNU_SOURCE, BSD and some Apple */ -#if defined(_GNU_SOURCE) || (defined(__BSD_VISIBLE) && __BSD_VISIBLE) || (defined(__APPLE__) && (!defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE))) || _NETBSD_SOURCE +#if defined(_GNU_SOURCE) || (defined(__BSD_VISIBLE) && __BSD_VISIBLE) || (defined(__APPLE__) && (!defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE))) || defined(_NETBSD_SOURCE) # undef DEFINE_STRCASESTR #else # define DEFINE_STRCASESTR diff --git a/src/string_type.h b/src/string_type.h index 40c1e2dc7e..4afbaa9d30 100644 --- a/src/string_type.h +++ b/src/string_type.h @@ -12,6 +12,9 @@ #ifndef STRING_TYPE_H #define STRING_TYPE_H +/** A non-breaking space. */ +#define NBSP "\xC2\xA0" + /** * Valid filter types for IsValidChar. */ diff --git a/src/table/settings.h b/src/table/settings.h index 9bc07b9798..7afe20fd21 100644 --- a/src/table/settings.h +++ b/src/table/settings.h @@ -532,11 +532,11 @@ const SettingDesc _settings[] = { SDT_CONDVAR(GameSettings, game_creation.custom_town_number, SLE_UINT16,115, SL_MAX_VERSION, 0, 0, 1, 1, 5000, 0, STR_NULL, NULL), SDT_CONDVAR(GameSettings, construction.extra_tree_placement, SLE_UINT8,132, SL_MAX_VERSION, 0,MS, 2, 0, 2, 0, STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT, NULL), - SDT_CONDOMANY(GameSettings, locale.currency, SLE_UINT8, 97, SL_MAX_VERSION, N, 0, 0, CUSTOM_CURRENCY_ID, _locale_currencies, STR_NULL, NULL, NULL), - SDT_CONDOMANY(GameSettings, locale.units, SLE_UINT8, 97, SL_MAX_VERSION, N, 0, 1, 2, _locale_units, STR_NULL, NULL, NULL), - SDT_CONDSTR(GameSettings, locale.digit_group_separator, SLE_STRQ,118, SL_MAX_VERSION, N, 0, NULL, STR_NULL, NULL), - SDT_CONDSTR(GameSettings, locale.digit_group_separator_currency, SLE_STRQ,118, SL_MAX_VERSION, N, 0, NULL, STR_NULL, NULL), - SDT_CONDSTR(GameSettings, locale.digit_decimal_separator, SLE_STRQ,126, SL_MAX_VERSION, N, 0, NULL, STR_NULL, NULL), + SDT_CONDOMANY(GameSettings, locale.currency, SLE_UINT8, 97, SL_MAX_VERSION, N, 0, 0, CUSTOM_CURRENCY_ID, _locale_currencies, STR_NULL, RedrawScreen, NULL), + SDT_CONDOMANY(GameSettings, locale.units, SLE_UINT8, 97, SL_MAX_VERSION, N, 0, 1, 2, _locale_units, STR_NULL, RedrawScreen, NULL), + SDT_CONDSTR(GameSettings, locale.digit_group_separator, SLE_STRQ,118, SL_MAX_VERSION, N, 0, NULL, STR_NULL, RedrawScreen), + SDT_CONDSTR(GameSettings, locale.digit_group_separator_currency, SLE_STRQ,118, SL_MAX_VERSION, N, 0, NULL, STR_NULL, RedrawScreen), + SDT_CONDSTR(GameSettings, locale.digit_decimal_separator, SLE_STRQ,126, SL_MAX_VERSION, N, 0, NULL, STR_NULL, RedrawScreen), /***************************************************************************/ /* Unsaved setting variables. */