diff --git a/src/modes/world.cpp b/src/modes/world.cpp index 142479dce..adf24aba1 100644 --- a/src/modes/world.cpp +++ b/src/modes/world.cpp @@ -411,8 +411,8 @@ void World::removeKart(int kart_number) else { std::string s = _("'%s' has\nbeen eliminated."); - m->addMessage( StringUtils::insert_string(s, kart->getName()), - *i, 2.0f, 60); + m->addMessage( StringUtils::insert_values(s, kart->getName()), + *i, 2.0f, 60); } } // for i in kart } // if raceMenu exist diff --git a/src/user_config.cpp b/src/user_config.cpp index fc5d143bc..649de0f37 100644 --- a/src/user_config.cpp +++ b/src/user_config.cpp @@ -32,9 +32,6 @@ #else # include #endif -#if defined(WIN32) && !defined(__CYGWIN__) -# define snprintf _snprintf -#endif #include #define _WINSOCKAPI_ @@ -49,6 +46,7 @@ #include "lisp/parser.hpp" #include "lisp/writer.hpp" #include "utils/translation.hpp" +#include "utils/string_utils.hpp" UserConfig *user_config; @@ -918,7 +916,6 @@ void UserConfig::writeInput(lisp::Writer *writer, const Input &input) // ----------------------------------------------------------------------------- std::string UserConfig::getInputAsString(const Input &input) { - char msg[MAX_MESSAGE_LENGTH]; std::string s; switch (input.type) @@ -930,26 +927,27 @@ std::string UserConfig::getInputAsString(const Input &input) s = SDL_GetKeyName((SDLKey) input.id0); break; case Input::IT_STICKMOTION: - snprintf(msg, sizeof(msg), _("joy %d axis %d %c"), - input.id0, input.id1, - (input.id2 == Input::AD_NEGATIVE) ? '-' : '+'); - s = msg; + s = StringUtils::insert_values( _("joy %d axis %d %s"), input.id0, + input.id1, + (input.id2 == Input::AD_NEGATIVE) + ? '-' : '+' ); break; case Input::IT_STICKBUTTON: - snprintf(msg, sizeof(msg), _("joy %d btn %d"), input.id0, input.id1); - s = msg; + s = StringUtils::insert_values( _("joy %d btn %d"), + input.id0, input.id1); break; case Input::IT_STICKHAT: - snprintf(msg, sizeof(msg), _("joy %d hat %d"), input.id0, input.id1); - s = msg; + s = StringUtils::insert_values( _("joy %d hat %d"), + input.id0, input.id1); break; case Input::IT_MOUSEBUTTON: - snprintf(msg, sizeof(msg), _("mouse btn %d"), input.id0); - s = msg; + s = StringUtils::insert_values( _("mouse btn %d"), input.id0); break; case Input::IT_MOUSEMOTION: - snprintf(msg, sizeof(msg), _("mouse axis %d %c"), - input.id0, ((input.id1 == Input::AD_NEGATIVE) ? '-' : '+')); + s = StringUtils::insert_values( _("mouse axis %d %s"), + input.id0, + (input.id1 == Input::AD_NEGATIVE) + ? '-': '+' ); break; default: s = _("Invalid"); diff --git a/src/utils/string_utils.hpp b/src/utils/string_utils.hpp index c822aa439..a69246d99 100644 --- a/src/utils/string_utils.hpp +++ b/src/utils/string_utils.hpp @@ -72,23 +72,65 @@ namespace StringUtils std::string upcase (const std::string&); std::string downcase (const std::string&); std::vector split(const std::string& s, char c); + // ------------------------------------------------------------------------ - /** Replaces all '%s' or '%d' in the first string with the 2nd string. So - * this is basically a simplified s(n)printf replacement, which doesn't - * rely on s(n)printf (which is not that portable). - * \param s String in which all %s or %dare replaced. - * \param a Value to replace all %s or %d with. + /** Overloaded insert_values taking one value, see below for + * full docs. + * \param s String in which all %s or %d are replaced. + * \param v1 Value to replace. */ - template - std::string insert_string(const std::string &s, const T &a) + template + std::string insert_values(const std::string &s, const T1 &v1) { + return insert_values(s, v1, "", ""); + } + // ------------------------------------------------------------------------ + /** Overloaded insert_values taking two values, see below for + * full docs. + * \param s String in which all %s or %d are replaced. + * \param v1,v2 Value(s) to replace all %s or %d with. + */ + template + std::string insert_values(const std::string &s, const T1 &v1, + const T2 &v2=0) + { + return insert_values(s, v1, v2, ""); + } + // ------------------------------------------------------------------------ + /** Replaces the first %s or %d in the string with the first value + * converted to a string), the 2nd %s or %d with the second value etc. + * So this is basically a simplified s(n)printf replacement, but doesn't + * do any fancy formatting (and no type checks either - so you can print + * a string into a %d field). This is basically a replacement for + * sprintf (and similar functions), mostly meant for strings that are + * translated (otherwise just use ostringstream) - since e.g. a + * translated string like _("Player %s - chose your kart") would + * be broken into two strings: + * << _("Player ") << name << _(" - chose your kart") + * and this is in the best case very confusing for translators (which get + * to see two strings instead of one sentence, see xgettext manual + * for why this is a bad idea) + * \param s String in which all %s or %d are replaced. + * \param v1,v2,v3 Value(s) to replace all %s or %d with. + */ + template + std::string insert_values(const std::string &s, const T1 &v1, + const T2 &v2=0, const T3 &v3=0) + { + std::vector all_vals; + std::ostringstream dummy; + dummy< sv = StringUtils::split(s, '%'); std::string new_string=""; for(unsigned int i=0; i