51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-#ifndef GETTEXT_HEADER
-#define GETTEXT_HEADER
+#pragma once
#include "config.h" // for USE_GETTEXT
#include <string>
+#include "porting.h"
#if USE_GETTEXT
#include <libintl.h>
extern wchar_t *utf8_to_wide_c(const char *str);
-// You must free the returned string!
-// The returned string is allocated using new
+// The returned string must be freed using delete[]
inline const wchar_t *wgettext(const char *str)
{
- return utf8_to_wide_c(gettext(str));
+ // We must check here that is not an empty string to avoid trying to translate it
+ return str[0] ? utf8_to_wide_c(gettext(str)) : utf8_to_wide_c("");
}
inline std::string strgettext(const std::string &text)
{
- return gettext(text.c_str());
+ return text.empty() ? "" : gettext(text.c_str());
}
-#endif
+/**
+ * Returns translated string with format args applied
+ *
+ * @tparam Args Template parameter for format args
+ * @param src Translation source string
+ * @param args Variable format args
+ * @return translated string
+ */
+template <typename ...Args>
+inline std::wstring fwgettext(const char *src, Args&&... args)
+{
+ wchar_t buf[255];
+ const wchar_t* str = wgettext(src);
+ swprintf(buf, sizeof(buf) / sizeof(wchar_t), str, std::forward<Args>(args)...);
+ delete[] str;
+ return std::wstring(buf);
+}
+
+/**
+ * Returns translated string with format args applied
+ *
+ * @tparam Args Template parameter for format args
+ * @param format Translation source string
+ * @param args Variable format args
+ * @return translated string.
+ */
+template <typename ...Args>
+inline std::string fmtgettext(const char *format, Args&&... args)
+{
+ std::string buf;
+ std::size_t buf_size = 256;
+ buf.resize(buf_size);
+
+ format = gettext(format);
+
+ int len = porting::mt_snprintf(&buf[0], buf_size, format, std::forward<Args>(args)...);
+ if (len <= 0) throw std::runtime_error("gettext format error: " + std::string(format));
+ if ((size_t)len >= buf.size()) {
+ buf.resize(len+1); // extra null byte
+ porting::mt_snprintf(&buf[0], buf.size(), format, std::forward<Args>(args)...);
+ }
+ buf.resize(len); // remove null bytes
+
+ return buf;
+}