Merge pull request #2106 from Flakebi/test

Simplify StringUtils::insertValues
This commit is contained in:
auriamg 2015-08-16 19:48:05 -04:00
commit 6a26010bc8
11 changed files with 106 additions and 231 deletions

View File

@ -417,10 +417,8 @@ void PlayerKartWidget::markAsReady()
// 'playerNameString' is already fribidize, so we need to use
// 'insertValues' and not _("...", a) so it's not flipped again
m_ready_text =
GUIEngine::getGUIEnv()->addStaticText(
StringUtils::insertValues(_("%s is ready"),
playerNameString).c_str(),
rect );
GUIEngine::getGUIEnv()->addStaticText(_("%s is ready", playerNameString),
rect);
m_ready_text->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_CENTER );
m_children.remove(m_player_ident_spinner);

View File

@ -452,7 +452,7 @@ public:
*/
core::stringw getName() const
{
return core::stringw(translations->w_gettext(m_name.c_str()));
return _LTR(m_name.c_str());
}
// ------------------------------------------------------------------------

View File

@ -199,9 +199,8 @@ void EasterEggHunt::getKartsDisplayInfo(
{
RaceGUIBase::KartIconDisplayInfo& rank_info = (*info)[i];
//I18n: number of collected eggs / overall number of eggs
rank_info.m_text = StringUtils::insertValues(_("Eggs: %d / %d"),
m_eggs_collected[i],
m_number_of_eggs);
rank_info.m_text = _("Eggs: %d / %d", m_eggs_collected[i],
m_number_of_eggs);
rank_info.m_color = video::SColor(255, 255, 255, 255);
}
} // getKartDisplayInfo

View File

@ -167,8 +167,8 @@ public:
// -------------------------------------------------------------------------
enum GPReverseType getReverseType()
const { return m_reverse_type; }
static const char* getRandomGPID() { return "random"; }
static const wchar_t* getRandomGPName() { return _LTR("Random Grand Prix");}
static const char* getRandomGPID() { return "random"; }
static irr::core::stringw getRandomGPName() { return _LTR("Random Grand Prix"); }
}; // GrandPrixData
#endif

View File

@ -356,9 +356,8 @@ void AddonsLoading::doInstall()
bool error = !addons_manager->install(m_addon);
if(error)
{
core::stringw msg = StringUtils::insertValues(
_("Problems installing the addon '%s'."),
core::stringw(m_addon.getName().c_str()));
const core::stringw &name = m_addon.getName();
core::stringw msg = _("Problems installing the addon '%s'.", name);
getWidget<BubbleWidget>("description")->setText(msg.c_str());
}
@ -394,8 +393,8 @@ void AddonsLoading::doUninstall()
Log::warn("Addons", "Directory '%s' can not be removed.",
m_addon.getDataDir().c_str());
Log::warn("Addons", "Please remove this directory manually.");
core::stringw msg = StringUtils::insertValues(_("Problems removing the addon '%s'."),
core::stringw(m_addon.getName().c_str()));
const core::stringw &name = m_addon.getName();
core::stringw msg = _("Problems removing the addon '%s'.", name);
getWidget<BubbleWidget>("description")->setText(msg.c_str());
}

View File

@ -98,10 +98,6 @@ RaceGUIBase::RaceGUIBase()
m_dist_show_overlap = 2;
m_icons_inertia = 2;
//I18N: When some GlobalPlayerIcons are hidden, write "Top 10" to show it
m_string_top = _("Top %i");
m_referee = NULL;
} // RaceGUIBase
@ -812,7 +808,8 @@ void RaceGUIBase::drawGlobalPlayerIcons(int bottom_margin)
static video::SColor color = video::SColor(255, 255, 255, 255);
pos_top.LowerRightCorner = pos_top.UpperLeftCorner;
font->draw(StringUtils::insertValues( m_string_top, position-1 ), pos_top, color);
//I18N: When some GlobalPlayerIcons are hidden, write "Top 10" to show it
font->draw(_("Top %i", position-1 ), pos_top, color);
break;
}

View File

@ -129,9 +129,6 @@ private:
/** Translated strings 'ready', 'set', 'go'. */
core::stringw m_string_ready, m_string_set, m_string_go, m_string_goal;
/** Translated string 'Top %d' displayed every frame. */
core::stringw m_string_top;
/** The position of the referee for all karts. */
std::vector<Vec3> m_referee_pos;

View File

@ -25,12 +25,13 @@
#include "utils/utf8.h"
#include "coreutil.h"
#include <math.h>
#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <stdio.h>
#include <cwchar>
#include <exception>
#include <assert.h>
namespace StringUtils
{
@ -167,7 +168,7 @@ namespace StringUtils
try
{
std::string::size_type start=0;
while(start!=std::string::npos && start<(unsigned int)s.size())
while(start < (unsigned int) s.size())
{
std::string::size_type i=s.find(c, start);
if (i!=std::string::npos)
@ -185,11 +186,11 @@ namespace StringUtils
}
else // end of string reached
{
if (keepSplitChar)
if (keepSplitChar && start != 0)
result.push_back(std::string(s,start-1));
else
result.push_back(std::string(s,start));
start = i;
return result;
}
}
return result;
@ -243,14 +244,13 @@ namespace StringUtils
}
else
{
if (keepSplitChar)
if (keepSplitChar && start != 0)
result.push_back( s.subString(start - 1,
s.size()-start + 1) );
else
result.push_back( s.subString(start, s.size()-start) );
return result;
//start = i+1;
}
}
return result;

View File

@ -136,210 +136,71 @@ namespace StringUtils
std::string insertValues(const std::string &s,
std::vector<std::string>& all_vals);
/** This no-op is useful when using variadic arguments, so that we may
* support the case with 0 variadic arguments */
template <class T1>
T1 insertValues(const T1& s) { return s; }
// ------------------------------------------------------------------------
/** Same as above but for wide-strings */
irr::core::stringw insertValues(const irr::core::stringw &s,
std::vector<irr::core::stringw>& all_vals);
// ------------------------------------------------------------------------
// Note: the order in which the templates are specified is important, since
// otherwise some compilers will not find the right template to use.
template <class T1, class T2, class T3, class T4, class T5, class T6>
std::string insertValues(const std::string &s, const T1 &v1,
const T2 &v2, const T3 &v3, const T4 &v4,
const T5 &v5,const T6 &v6)
{
std::vector<std::string> all_vals;
std::ostringstream dummy;
dummy << v1; all_vals.push_back(dummy.str()); dummy.str("");
dummy << v2; all_vals.push_back(dummy.str()); dummy.str("");
dummy << v3; all_vals.push_back(dummy.str()); dummy.str("");
dummy << v4; all_vals.push_back(dummy.str()); dummy.str("");
dummy << v5; all_vals.push_back(dummy.str()); dummy.str("");
dummy << v6; all_vals.push_back(dummy.str());
return insertValues(s, all_vals);
} // insertValues(s, v1, ..., v6)
// ------------------------------------------------------------------------
template <class T1, class T2, class T3, class T4, class T5>
std::string insertValues(const std::string &s, const T1 &v1,
const T2 &v2, const T3 &v3, const T4 &v4,
const T5 &v5)
{
std::vector<std::string> all_vals;
std::ostringstream dummy;
dummy << v1; all_vals.push_back(dummy.str()); dummy.str("");
dummy << v2; all_vals.push_back(dummy.str()); dummy.str("");
dummy << v3; all_vals.push_back(dummy.str()); dummy.str("");
dummy << v4; all_vals.push_back(dummy.str()); dummy.str("");
dummy << v5; all_vals.push_back(dummy.str());
return insertValues(s, all_vals);
} // insertValues(s, v1, ..., v5)
// ------------------------------------------------------------------------
template <class T1, class T2, class T3, class T4>
std::string insertValues(const std::string &s, const T1 &v1,
const T2 &v2, const T3 &v3, const T4 &v4)
{
std::vector<std::string> all_vals;
std::ostringstream dummy;
dummy << v1; all_vals.push_back(dummy.str()); dummy.str("");
dummy << v2; all_vals.push_back(dummy.str()); dummy.str("");
dummy << v3; all_vals.push_back(dummy.str()); dummy.str("");
dummy << v4; all_vals.push_back(dummy.str());
return insertValues(s, all_vals);
} // insertValues(s, v1, ..., v4)
// ------------------------------------------------------------------------
/** Shortcut insert_values taking three values, see above for
* full docs.
* \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 <class T1, class T2, class T3>
std::string insertValues(const std::string &s, const T1 &v1,
const T2 &v2, const T3 &v3)
{
std::vector<std::string> all_vals;
std::ostringstream dummy;
dummy << v1; all_vals.push_back(dummy.str()); dummy.str("");
dummy << v2; all_vals.push_back(dummy.str()); dummy.str("");
dummy << v3; all_vals.push_back(dummy.str());
return insertValues(s, all_vals);
} // insertValues(s, v1, ..., v3)
// ------------------------------------------------------------------------
// Note: the order in which the templates are specified is important, since
// otherwise some compilers will not find the right template to use.
/** Shortcut insert_values taking three values, see above 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 <class T1, class T2>
std::string insertValues(const std::string &s, const T1 &v1,
const T2 &v2)
{
std::vector<std::string> all_vals;
std::ostringstream dummy;
dummy << v1; all_vals.push_back(dummy.str()); dummy.str("");
dummy << v2; all_vals.push_back(dummy.str()); dummy.str("");
return insertValues(s, all_vals);
} // insertValues(s, v1, v2)
// ------------------------------------------------------------------------
/** Shortcut insert_values taking three values, see above for
* full docs.
* \param s String in which all %s, %d are replaced.
* \param v1 Value to replace.
*/
template <class T1>
std::string insertValues(const std::string &s, const T1 &v1)
{
std::vector<std::string> all_vals;
std::ostringstream dummy;
dummy << v1; all_vals.push_back(dummy.str()); dummy.str("");
return insertValues(s, all_vals);
} // insertValues(s, v1)
// ------------------------------------------------------------------------
/** Intermediate struct to fill a vector using variadic templates */
struct __FillStringwVector
struct FillStringVector
{
/** FillS takes a vector as the first argument and a variadic list of
* arguments. The arguments are recursively inserted into the vector
* which will contain all the arguments converted to strings in the end.
*/
template<typename T, typename...Args>
static void __Fill(std::vector<irr::core::stringw> &all_vals, T&& v, Args &&...args)
static void FillS(std::vector<std::string> &all_vals, T&& v, Args &&...args)
{
std::ostringstream oss;
oss << v;
all_vals.push_back(oss.str());
FillS(all_vals, std::forward<Args>(args)...);
}
static void FillS(std::vector<std::string>&) {}
/** This functions does the same as FillS but for wide strings. */
template<typename T, typename...Args>
static void FillW(std::vector<irr::core::stringw> &all_vals, T&& v, Args &&...args)
{
all_vals.push_back(irr::core::stringw(std::forward<T>(v)));
__Fill(all_vals, std::forward<Args>(args)...);
FillW(all_vals, std::forward<Args>(args)...);
}
static void __Fill(std::vector<irr::core::stringw>&) {}
static void FillW(std::vector<irr::core::stringw>&) {}
};
template <typename...Args>
std::string insertValues(const std::string &s, Args ...args)
{
std::vector<std::string> all_vals;
all_vals.reserve(sizeof...(args));
FillStringVector::FillS(all_vals, std::forward<Args>(args)...);
return insertValues(s, all_vals);
}
template <typename...Args>
std::string insertValues(const char *s, Args ...args)
{
return insertValues(std::string(s), std::forward<Args>(args)...);
}
/** Like the other ones above but for wide strings */
template <typename...Args>
irr::core::stringw insertValues(const irr::core::stringw &s, Args ...args)
{
std::vector<irr::core::stringw> all_vals;
__FillStringwVector::__Fill(all_vals, std::forward<Args>(args)...);
all_vals.reserve(sizeof...(args));
FillStringVector::FillW(all_vals, std::forward<Args>(args)...);
return insertValues(s, all_vals);
}
// ------------------------------------------------------------------------
/** Like the other ones above but for wide strings */
template <class T1, class T2, class T3, class T4, class T5>
irr::core::stringw insertValues(const wchar_t* chars, const T1 &v1,
const T2 &v2, const T3 &v3, const T4 &v4,
const T5 &v5)
template <typename...Args>
irr::core::stringw insertValues(const wchar_t *s, Args ...args)
{
irr::core::stringw s(chars);
return insertValues(s, v1, v2, v3, v4, v5);
} // insertValues(s, v1, ..., v5)
// ------------------------------------------------------------------------
/** Like the other ones above but for wide strings */
template <class T1, class T2, class T3>
irr::core::stringw insertValues(const wchar_t* chars, const T1 &v1,
const T2 &v2, const T3 &v3)
{
irr::core::stringw s(chars);
return insertValues(s, v1, v2, v3);
} // insertValues(s, v1, ..., v3)
// ------------------------------------------------------------------------
/** Like the other ones above but for wide strings */
template <class T1, class T2>
irr::core::stringw insertValues(const wchar_t* chars, const T1 &v1,
const T2 &v2)
{
irr::core::stringw s(chars);
return insertValues(s, v1, v2);
} // insertValues(s, v1, v2)
// ------------------------------------------------------------------------
/** Like the other ones above but for wide strings */
template <class T1>
irr::core::stringw insertValues(const wchar_t* chars, const T1 &v1)
{
irr::core::stringw s(chars);
return insertValues(s, v1);
} // insertValues(s, v1)
// ------------------------------------------------------------------------
/** Like the other ones above but for C strings */
template <class T1, class T2, class T3>
std::string insertValues(const char* chars, const T1 &v1,
const T2 &v2, const T3 &v3)
{
std::string s(chars);
return insertValues(s, v1, v2, v3);
} // insertValues(s, v1, ..., v3)
// ------------------------------------------------------------------------
/** Like the other ones above but for C strings */
template <class T1, class T2>
std::string insertValues(const char* chars, const T1 &v1,
const T2 &v2)
{
std::string s(chars);
return insertValues(s, v1, v2);
} // insertValues(s, v1, v2)
// ------------------------------------------------------------------------
/** Like the other ones above but for C strings */
template <class T1>
std::string insertValues(const char* chars, const T1 &v1)
{
std::string s(chars);
return insertValues(s, v1);
} // insertValues(s, v1)
return insertValues(irr::core::stringw(s), std::forward<Args>(args)...);
}
// ------------------------------------------------------------------------
template<typename T>
@ -371,5 +232,3 @@ namespace StringUtils
} // namespace StringUtils
#endif
/* EOF */

View File

@ -26,12 +26,13 @@
#include "utils/translation.hpp"
#include <algorithm>
#include <assert.h>
#include <locale.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <cassert>
#include <cerrno>
#include <clocale>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cwchar>
#include <iostream>
#include <vector>
@ -359,10 +360,23 @@ Translations::Translations() //: m_dictionary_manager("UTF-16")
// ----------------------------------------------------------------------------
Translations::~Translations()
{
} // ~Translations
// ----------------------------------------------------------------------------
const wchar_t* Translations::fribidize(const wchar_t* in_ptr)
{
if (isRTLText(in_ptr))
{
// Test if this string was already fribidized
std::map<const irr::core::stringw, const irr::core::stringw>::const_iterator
found = m_fribidized_strings.find(in_ptr);
if (found != m_fribidized_strings.cend())
return found->second.c_str();
// Use fribidi to fribidize the string
// Split text into lines
std::vector<core::stringw> input_lines = StringUtils::split(in_ptr, '\n');
// Reverse lines for RTL strings, irrlicht will reverse them back
@ -371,18 +385,25 @@ const wchar_t* Translations::fribidize(const wchar_t* in_ptr)
std::reverse(input_lines.begin(), input_lines.end());
// Fribidize and concat lines
core::stringw converted_string;
for (std::vector<core::stringw>::iterator it = input_lines.begin();
it != input_lines.end(); it++)
{
if (it == input_lines.begin())
m_converted_string = fribidizeLine(*it);
converted_string = fribidizeLine(*it);
else
{
m_converted_string += "\n";
m_converted_string += fribidizeLine(*it);
converted_string += "\n";
converted_string += fribidizeLine(*it);
}
}
return m_converted_string.c_str();
// Save it in the map
m_fribidized_strings.insert(std::pair<const irr::core::stringw, const irr::core::stringw>(
in_ptr, converted_string));
found = m_fribidized_strings.find(in_ptr);
return found->second.c_str();
}
else
return in_ptr;
@ -448,12 +469,13 @@ const wchar_t* Translations::w_gettext(const char* original, const char* context
if (original_t == original)
{
m_converted_string = StringUtils::utf8_to_wide(original);
static irr::core::stringw converted_string;
converted_string = StringUtils::utf8_to_wide(original);
#if TRANSLATE_VERBOSE
std::wcout << L" translation : " << m_converted_string << std::endl;
std::wcout << L" translation : " << converted_string << std::endl;
#endif
return m_converted_string.c_str();
return converted_string.c_str();
}
// print
@ -572,4 +594,3 @@ core::stringw Translations::fribidizeLine(const core::stringw &str)
return core::stringw(str);
#endif // ENABLE_BIDI
}

View File

@ -20,11 +20,14 @@
#define TRANSLATION_HPP
#include <irrString.h>
#include <vector>
#include <map>
#include <string>
#include <utility>
#include <vector>
#include "utils/string_utils.hpp"
# include "tinygettext/tinygettext.hpp"
#include "tinygettext/tinygettext.hpp"
# define _(String, ...) (translations->fribidize(StringUtils::insertValues(translations->w_gettext(String), ##__VA_ARGS__)))
#undef _C
@ -46,13 +49,15 @@ private:
tinygettext::DictionaryManager m_dictionary_manager;
tinygettext::Dictionary m_dictionary;
irr::core::stringw m_converted_string;
/** A map that saves all fribidized strings: Original string, fribidized string */
std::map<const irr::core::stringw, const irr::core::stringw> m_fribidized_strings;
bool m_rtl;
std::string m_current_language_name;
public:
Translations();
~Translations();
const wchar_t *w_gettext(const wchar_t* original, const char* context=NULL);
const wchar_t *w_gettext(const char* original, const char* context=NULL);