Reduce gettext wide/narrow and string/char* conversions
authorShadowNinja <shadowninja@minetest.net>
Sun, 1 Feb 2015 22:59:23 +0000 (17:59 -0500)
committerkwolekr <kwolekr@minetest.net>
Thu, 5 Feb 2015 08:24:22 +0000 (03:24 -0500)
15 files changed:
src/client.cpp
src/game.cpp
src/gettext.cpp
src/gettext.h
src/guiChatConsole.cpp
src/guiFormSpecMenu.cpp
src/guiKeyChangeMenu.cpp
src/guiKeyChangeMenu.h
src/guiPasswordChange.cpp
src/guiVolumeChange.cpp
src/main.cpp
src/script/lua_api/l_mainmenu.cpp
src/util/string.cpp
src/util/string.h
util/updatepo.sh

index cb6419fade8f2f0d7e5a4451a774a417543e3ab3..2f70d624c4a1f46e1d861507bf94a521a64086bc 100644 (file)
@@ -2716,7 +2716,7 @@ void Client::afterContentReceived(IrrlichtDevice *device, gui::IGUIFont* font)
        assert(m_nodedef_received);
        assert(mediaReceived());
 
-       wchar_t* text = wgettext("Loading textures...");
+       const wchar_t* text = wgettext("Loading textures...");
 
        // Rebuild inherited images and recreate textures
        infostream<<"- Rebuilding images and textures"<<std::endl;
index acc7a3a31fab77ab880bd20fc8848f2e14c81e23..b674fd83b281bffd382db35562b95490321f1691 100644 (file)
@@ -1806,9 +1806,7 @@ void Game::run()
 
 void Game::shutdown()
 {
-       wchar_t *msg = wgettext("Shutting down...");
-       showOverlayMessage(msg, 0, 0, false);
-       delete [] msg;
+       showOverlayMessage(wgettext("Shutting down..."), 0, 0, false);
 
        if (clouds)
                clouds->drop();
@@ -1857,9 +1855,7 @@ bool Game::init(
                u16 port,
                const SubgameSpec &gamespec)
 {
-       wchar_t *msg = wgettext("Loading...");
-       showOverlayMessage(msg, 0, 0);
-       delete [] msg;
+       showOverlayMessage(wgettext("Loading..."), 0, 0);
 
        texture_src = createTextureSource(device);
        shader_src = createShaderSource(device);
@@ -1916,9 +1912,7 @@ bool Game::initSound()
 bool Game::createSingleplayerServer(const std::string map_dir,
                const SubgameSpec &gamespec, u16 port, std::string *address)
 {
-       wchar_t *msg = wgettext("Creating server...");
-       showOverlayMessage(msg, 0, 5);
-       delete [] msg;
+       showOverlayMessage(wgettext("Creating server..."), 0, 5);
 
        std::string bind_str = g_settings->get("bind_address");
        Address bind_addr(0, 0, 0, 0, port);
@@ -1955,9 +1949,7 @@ bool Game::createClient(const std::string &playername,
                const std::string &password, std::string *address, u16 port,
                std::wstring *error_message)
 {
-       wchar_t *msg = wgettext("Creating client...");
-       showOverlayMessage(msg, 0, 10);
-       delete [] msg;
+       showOverlayMessage(wgettext("Creating client..."), 0, 10);
 
        draw_control = new MapDrawControl;
        if (!draw_control)
@@ -2130,9 +2122,7 @@ bool Game::connectToServer(const std::string &playername,
        *aborted = false;
        bool local_server_mode = false;
 
-       wchar_t *msg = wgettext("Resolving address...");
-       showOverlayMessage(msg, 0, 15);
-       delete [] msg;
+       showOverlayMessage(wgettext("Resolving address..."), 0, 15);
 
        Address connect_address(0, 0, 0, 0, port);
 
@@ -2223,9 +2213,7 @@ bool Game::connectToServer(const std::string &playername,
                        }
 
                        // Update status
-                       wchar_t *msg = wgettext("Connecting to server...");
-                       showOverlayMessage(msg, dtime, 20);
-                       delete [] msg;
+                       showOverlayMessage(wgettext("Connecting to server..."), dtime, 20);
                }
        } catch (con::PeerNotFoundException &e) {
                // TODO: Should something be done here? At least an info/error
@@ -2283,12 +2271,12 @@ bool Game::getServerContent(bool *aborted)
                int progress = 25;
 
                if (!client->itemdefReceived()) {
-                       wchar_t *text = wgettext("Item definitions...");
+                       const wchar_t *text = wgettext("Item definitions...");
                        progress = 25;
                        draw_load_screen(text, device, guienv, dtime, progress);
                        delete[] text;
                } else if (!client->nodedefReceived()) {
-                       wchar_t *text = wgettext("Node definitions...");
+                       const wchar_t *text = wgettext("Node definitions...");
                        progress = 30;
                        draw_load_screen(text, device, guienv, dtime, progress);
                        delete[] text;
@@ -2311,7 +2299,7 @@ bool Game::getServerContent(bool *aborted)
                        }
 
                        progress = 30 + client->mediaReceiveProgress() * 35 + 0.5;
-                       draw_load_screen(narrow_to_wide(message.str().c_str()), device,
+                       draw_load_screen(narrow_to_wide(message.str()), device,
                                        guienv, dtime, progress);
                }
        }
@@ -4127,6 +4115,7 @@ void Game::showOverlayMessage(const wchar_t *msg, float dtime,
                int percent, bool draw_clouds)
 {
        draw_load_screen(msg, device, guienv, dtime, percent, draw_clouds);
+       delete[] msg;
 }
 
 
@@ -4206,8 +4195,7 @@ void the_game(bool *kill,
                errorstream << "ServerError: " << e.what() << std::endl;
        } catch (ModError &e) {
                errorstream << "ModError: " << e.what() << std::endl;
-               wchar_t *check_msg = wgettext("\nCheck debug.txt for details.");
-               error_message = narrow_to_wide(e.what()) + check_msg;
-               delete [] check_msg;
+               error_message = narrow_to_wide(e.what()) + wstrgettext("\nCheck debug.txt for details.");
        }
 }
+
index 0c0e520ca169e4322834edc5cfb647e0f92e6959..688a225707f642e74ff66aea048720e34fd06880 100644 (file)
@@ -23,6 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include <stdlib.h>
 #include "gettext.h"
 #include "util/string.h"
+#include "log.h"
 
 #if USE_GETTEXT && defined(_MSC_VER)
 #include <WinNls.h>
@@ -116,9 +117,9 @@ const char* MSVC_LocaleLookup(const char* raw_shortname) {
 
 /******************************************************************************/
 #ifdef _MSC_VER
-void init_gettext(const char *path,std::string configured_language,int argc, char** argv) {
+void init_gettext(const char *path, const std::string &configured_language, int argc, char** argv) {
 #else
-void init_gettext(const char *path,std::string configured_language) {
+void init_gettext(const char *path, const std::string &configured_language) {
 #endif
 #if USE_GETTEXT
        /** first try to set user override environment **/
@@ -173,15 +174,15 @@ void init_gettext(const char *path,std::string configured_language) {
                        }
 
                        if (!CreateProcess(appname.c_str(),
-                                                               (char*) ptr_parameters,
-                                                               NULL,
-                                                               NULL,
-                                                               false,
-                                                               DETACHED_PROCESS | CREATE_UNICODE_ENVIRONMENT,
-                                                               NULL,
-                                                               NULL,
-                                                               &startupinfo,
-                                                               &processinfo)) {
+                                       (char*) ptr_parameters,
+                                       NULL,
+                                       NULL,
+                                       false,
+                                       DETACHED_PROCESS | CREATE_UNICODE_ENVIRONMENT,
+                                       NULL,
+                                       NULL,
+                                       &startupinfo,
+                                       &processinfo)) {
                                char buffer[1024];              
                                FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
                                        NULL,
@@ -261,9 +262,6 @@ void init_gettext(const char *path,std::string configured_language) {
 
        setlocale(LC_NUMERIC,"C");
        infostream << "Message locale is now set to: "
-                       << setlocale(LC_ALL,0) << std::endl;
+                       << setlocale(LC_ALL, 0) << std::endl;
 }
 
-
-
-
index 81510aed6578ccf58813787dd0fa5ff087c7da2d..77fab895b9f96f33e4070f43c03e247faf98b54d 100644 (file)
@@ -20,8 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #ifndef GETTEXT_HEADER
 #define GETTEXT_HEADER
 
-#include "config.h" // for USE_GETTEXT
-#include "log.h"
+//#include "config.h" // for USE_GETTEXT
 
 #if USE_GETTEXT
 #include <libintl.h>
@@ -33,64 +32,30 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #define gettext_noop(String) String
 #define N_(String) gettext_noop (String)
 
-#if defined(_WIN32)
-#define WIN32_LEAN_AND_MEAN
-#ifndef _WIN32_WINNT
-       #define _WIN32_WINNT 0x0501
-#endif
-#include <windows.h>
-
-#endif // #if defined(_WIN32)
-
 #ifdef _MSC_VER
-void init_gettext(const char *path,std::string configured_language,int argc, char** argv);
+void init_gettext(const char *path, const std::string &configured_language, int argc, char** argv);
 #else
-void init_gettext(const char *path,std::string configured_language);
+void init_gettext(const char *path, const std::string &configured_language);
 #endif
 
-extern std::wstring narrow_to_wide(const std::string& mbs);
-#include "util/numeric.h"
+extern const wchar_t *narrow_to_wide_c(const char *mbs);
+extern std::wstring narrow_to_wide(const std::string &mbs);
 
 
-/******************************************************************************/
-inline wchar_t* chartowchar_t(const char *str)
+// You must free the returned string!
+inline const wchar_t *wgettext(const char *str)
 {
-       wchar_t* nstr = 0;
-#if defined(_WIN32)
-       int nResult = MultiByteToWideChar( CP_UTF8, 0, (LPCSTR) str, -1, 0, 0 );
-       if( nResult == 0 )
-       {
-               errorstream<<"gettext: MultiByteToWideChar returned null"<<std::endl;
-       }
-       else
-       {
-               nstr = new wchar_t[nResult];
-               MultiByteToWideChar( CP_UTF8, 0, (LPCSTR) str, -1, (WCHAR *) nstr, nResult );
-       }
-#else
-       size_t l = strlen(str);
-       nstr = new wchar_t[l+1];
-
-       std::wstring intermediate = narrow_to_wide(str);
-       memset(nstr, 0, (l+1)*sizeof(wchar_t));
-       memcpy(nstr, intermediate.c_str(), l*sizeof(wchar_t));
-#endif
-
-       return nstr;
+       return narrow_to_wide_c(gettext(str));
 }
 
-/******************************************************************************/
-inline wchar_t* wgettext(const char *str)
+inline std::wstring wstrgettext(const std::string &text)
 {
-       return chartowchar_t(gettext(str));
+       return narrow_to_wide(gettext(text.c_str()));
 }
 
-/******************************************************************************/
-inline std::wstring wstrgettext(std::string text) {
-       wchar_t* wlabel = wgettext(text.c_str());
-       std::wstring out = (std::wstring)wlabel;
-       delete[] wlabel;
-       return out;
+inline std::string strgettext(const std::string &text)
+{
+       return gettext(text.c_str());
 }
 
 #endif
index 19d9e3007e8a116cc3d266a52b0275296d00a815..bdce7c872f94cb18fab9883982af6e0276cdf054 100644 (file)
@@ -28,9 +28,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "porting.h"
 #include "tile.h"
 #include "fontengine.h"
-#include <string>
-
+#include "log.h"
 #include "gettext.h"
+#include <string>
 
 #if USE_FREETYPE
 #include "xCGUITTFont.h"
index c85bc16d7ef7ba87b14ca727cf5b48616f75b39f..20c9ecde77b982ec4e287ee3cf4ee5733dd1f7f3 100644 (file)
@@ -2000,7 +2000,7 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
                        mydata.rect =
                                        core::rect<s32>(size.X/2-70, pos.Y,
                                                        (size.X/2-70)+140, pos.Y + (m_btn_height*2));
-                       wchar_t* text = wgettext("Proceed");
+                       const wchar_t *text = wgettext("Proceed");
                        Environment->addButton(mydata.rect, this, 257, text);
                        delete[] text;
                }
index 8b0bb8278bea0d95b0542ab79dccbeb729608c92..9bc8118a103d391d2f24d668e0ef392811b6aa6e 100644 (file)
@@ -122,7 +122,7 @@ void GUIKeyChangeMenu::regenerateGui(v2u32 screensize)
                core::rect < s32 > rect(0, 0, 600, 40);
                rect += topleft + v2s32(25, 3);
                //gui::IGUIStaticText *t =
-               wchar_t* text = wgettext("Keybindings. (If this menu screws up, remove stuff from minetest.conf)");
+               const wchar_t *text = wgettext("Keybindings. (If this menu screws up, remove stuff from minetest.conf)");
                Environment->addStaticText(text,
                                                                   rect, false, true, this, -1);
                delete[] text;
@@ -145,8 +145,8 @@ void GUIKeyChangeMenu::regenerateGui(v2u32 screensize)
                {
                        core::rect < s32 > rect(0, 0, 100, 30);
                        rect += topleft + v2s32(offset.X + 105, offset.Y - 5);
-                       wchar_t* text = wgettext(k->key.name());
-                       k->button = Environment->addButton(rect, this, k->id, text );
+                       const wchar_t *text = wgettext(k->key.name());
+                       k->button = Environment->addButton(rect, this, k->id, text);
                        delete[] text;
                }
                if(i + 1 == KMaxButtonPerColumns)
@@ -162,7 +162,7 @@ void GUIKeyChangeMenu::regenerateGui(v2u32 screensize)
                {
                        core::rect<s32> rect(0, 0, option_w, 30);
                        rect += topleft + v2s32(option_x, option_y);
-                       wchar_t* text = wgettext("\"Use\" = climb down");
+                       const wchar_t *text = wgettext("\"Use\" = climb down");
                        Environment->addCheckBox(g_settings->getBool("aux1_descends"), rect, this,
                                        GUI_ID_CB_AUX1_DESCENDS, text);
                        delete[] text;
@@ -177,7 +177,7 @@ void GUIKeyChangeMenu::regenerateGui(v2u32 screensize)
                {
                        core::rect<s32> rect(0, 0, option_w, 30);
                        rect += topleft + v2s32(option_x, option_y);
-                       wchar_t* text = wgettext("Double tap \"jump\" to toggle fly");
+                       const wchar_t *text = wgettext("Double tap \"jump\" to toggle fly");
                        Environment->addCheckBox(g_settings->getBool("doubletap_jump"), rect, this,
                                        GUI_ID_CB_DOUBLETAP_JUMP, text);
                        delete[] text;
@@ -188,17 +188,17 @@ void GUIKeyChangeMenu::regenerateGui(v2u32 screensize)
        {
                core::rect < s32 > rect(0, 0, 100, 30);
                rect += topleft + v2s32(size.X - 100 - 20, size.Y - 40);
-               wchar_t* text =  wgettext("Save");
+               const wchar_t *text =  wgettext("Save");
                Environment->addButton(rect, this, GUI_ID_BACK_BUTTON,
-                                                        text);
+                                text);
                delete[] text;
        }
        {
                core::rect < s32 > rect(0, 0, 100, 30);
                rect += topleft + v2s32(size.X - 100 - 20 - 100 - 20, size.Y - 40);
-               wchar_t* text = wgettext("Cancel");
+               const wchar_t *text = wgettext("Cancel");
                Environment->addButton(rect, this, GUI_ID_ABORT_BUTTON,
-                                                        text );
+                               text);
                delete[] text;
        }       
 }
@@ -255,7 +255,7 @@ bool GUIKeyChangeMenu::resetMenu()
                        key_setting *k = key_settings.at(i);
                        if(k->id == activeKey)
                        {
-                               wchar_t* text = wgettext(k->key.name());
+                               const wchar_t *text = wgettext(k->key.name());
                                k->button->setText(text);
                                delete[] text;
                                break;
@@ -293,9 +293,9 @@ bool GUIKeyChangeMenu::OnEvent(const SEvent& event)
                {
                        core::rect < s32 > rect(0, 0, 600, 40);
                        rect += v2s32(0, 0) + v2s32(25, 30);
-                       wchar_t* text = wgettext("Key already in use");
+                       const wchar_t *text = wgettext("Key already in use");
                        this->key_used_text = Environment->addStaticText(text,
-                                                                       rect, false, true, this, -1);
+                                       rect, false, true, this, -1);
                        delete[] text;
                        //infostream << "Key already in use" << std::endl;
                }
@@ -313,7 +313,7 @@ bool GUIKeyChangeMenu::OnEvent(const SEvent& event)
                        }
                        assert(k);
                        k->key = kp;
-                       wchar_t* text = wgettext(k->key.name());
+                       const wchar_t *text = wgettext(k->key.name());
                        k->button->setText(text);
                        delete[] text;
 
@@ -368,7 +368,7 @@ bool GUIKeyChangeMenu::OnEvent(const SEvent& event)
                                        resetMenu();
                                        shift_down = false;
                                        activeKey = event.GUIEvent.Caller->getID();
-                                       wchar_t* text = wgettext("press key");
+                                       const wchar_t *text = wgettext("press key");
                                        k->button->setText(text);
                                        delete[] text;
                                        this->key_used.erase(std::remove(this->key_used.begin(),
@@ -381,7 +381,7 @@ bool GUIKeyChangeMenu::OnEvent(const SEvent& event)
        return Parent ? Parent->OnEvent(event) : false;
 }
 
-void GUIKeyChangeMenu::add_key(int id, wchar_t* button_name, std::string setting_name)
+void GUIKeyChangeMenu::add_key(int id, const wchar_t *button_name, const std::string &setting_name)
 {
        key_setting *k = new key_setting;
        k->id = id;
@@ -412,3 +412,4 @@ void GUIKeyChangeMenu::init_keys()
        this->add_key(GUI_ID_KEY_RANGE_BUTTON,     wgettext("Range select"),  "keymap_rangeselect");
        this->add_key(GUI_ID_KEY_DUMP_BUTTON,      wgettext("Print stacks"),  "keymap_print_debug_stacks");
 }
+
index 833514c1d98d2e8478d86afb6d614294bec4d49d..19a07620d242c2804418b3c488dcddf2d062139f 100644 (file)
 #include <string>
 #include <vector>
 
-typedef struct {
+struct key_setting {
        int id;
-       wchar_t *button_name;
+       const wchar_t *button_name;
        KeyPress key;
        std::string setting_name;
        gui::IGUIButton *button;
-} key_setting;
+};
 
 
 class GUIKeyChangeMenu: public GUIModalMenu
@@ -64,7 +64,7 @@ private:
 
        bool resetMenu();
 
-       void add_key(int id, wchar_t* button_name, std::string setting_name);
+       void add_key(int id, const wchar_t *button_name, const std::string &setting_name);
 
        bool shift_down;
        
index c8a2214b6e2ea1ddc76ce5e93df1bf657e5f472c..d9a5cc48b9b20ea09f3c88cb07a487919b292080 100644 (file)
@@ -96,6 +96,8 @@ void GUIPasswordChange::regenerateGui(v2u32 screensize)
        v2s32 size = rect.getSize();
        v2s32 topleft_client(40, 0);
 
+       const wchar_t *text;
+
        /*
                Add stuff
        */
@@ -103,7 +105,7 @@ void GUIPasswordChange::regenerateGui(v2u32 screensize)
        {
                core::rect<s32> rect(0, 0, 110, 20);
                rect += topleft_client + v2s32(35, ypos+6);
-               wchar_t* text = wgettext("Old Password");
+               text = wgettext("Old Password");
                Environment->addStaticText(text, rect, false, true, this, -1);
                delete[] text;
        }
@@ -119,7 +121,7 @@ void GUIPasswordChange::regenerateGui(v2u32 screensize)
        {
                core::rect<s32> rect(0, 0, 110, 20);
                rect += topleft_client + v2s32(35, ypos+6);
-               wchar_t* text = wgettext("New Password");
+               text = wgettext("New Password");
                Environment->addStaticText(text, rect, false, true, this, -1);
                delete[] text;
        }
@@ -134,7 +136,7 @@ void GUIPasswordChange::regenerateGui(v2u32 screensize)
        {
                core::rect<s32> rect(0, 0, 110, 20);
                rect += topleft_client + v2s32(35, ypos+6);
-               wchar_t* text = wgettext("Confirm Password");
+               text = wgettext("Confirm Password");
                Environment->addStaticText(text, rect, false, true, this, -1);
                delete[] text;
        }
@@ -150,7 +152,7 @@ void GUIPasswordChange::regenerateGui(v2u32 screensize)
        {
                core::rect<s32> rect(0, 0, 140, 30);
                rect = rect + v2s32(size.X/2-140/2, ypos);
-               wchar_t* text = wgettext("Change");
+               text = wgettext("Change");
                Environment->addButton(rect, this, ID_change, text);
                delete[] text;
        }
@@ -159,7 +161,7 @@ void GUIPasswordChange::regenerateGui(v2u32 screensize)
        {
                core::rect<s32> rect(0, 0, 300, 20);
                rect += topleft_client + v2s32(35, ypos);
-               wchar_t* text = wgettext("Passwords do not match!");
+               text = wgettext("Passwords do not match!");
                IGUIElement *e = 
                Environment->addStaticText(
                        text,
index f31c650f3108688ac425dd1c4c39ea5e1e4af023..b31b99a983de46431155556c41a229e640a36dab 100644 (file)
@@ -103,7 +103,7 @@ void GUIVolumeChange::regenerateGui(v2u32 screensize)
        {
                core::rect<s32> rect(0, 0, 120, 20);
                rect = rect + v2s32(size.X/2-60, size.Y/2-35);
-               wchar_t* text = wgettext("Sound Volume: ");
+               const wchar_t *text = wgettext("Sound Volume: ");
                Environment->addStaticText(text, rect, false,
                                true, this, ID_soundText1);
                delete[] text;
@@ -117,7 +117,7 @@ void GUIVolumeChange::regenerateGui(v2u32 screensize)
        {
                core::rect<s32> rect(0, 0, 80, 30);
                rect = rect + v2s32(size.X/2-80/2, size.Y/2+55);
-               wchar_t* text = wgettext("Exit");
+               const wchar_t *text = wgettext("Exit");
                Environment->addButton(rect, this, ID_soundExitButton,
                        text);
                delete[] text;
index e7108a3e8e5b0e66e97e541d2ad3b9ab1ffdd76b..bbf88e80d7a04bcad13e4ec723e776567061a27a 100644 (file)
@@ -1684,7 +1684,7 @@ bool ClientLauncher::run(GameParams &game_params, const Settings &cmd_args)
        while (device->run() && !*kill && !g_gamecallback->shutdown_requested)
        {
                // Set the window caption
-               wchar_t *text = wgettext("Main Menu");
+               const wchar_t *text = wgettext("Main Menu");
                device->setWindowCaption((std::wstring(L"Minetest [") + text + L"]").c_str());
                delete[] text;
 
index 0f903ba5e972210faf5326ee032eab042b7170b2..28c3d193d6cc715b7d9d7c93e4ba9502bc6c5c4e 100644 (file)
@@ -35,6 +35,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "sound.h"
 #include "settings.h"
 #include "main.h" // for g_settings
+#include "log.h"
 #include "EDriverTypes.h"
 
 #include <IFileArchive.h>
index 1d95606081220c0df8daee9770f1d26ddc84aa22..b4908d62d71ac16cccde4028c9b267a615a2b3de 100644 (file)
@@ -32,6 +32,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include <iomanip>
 #include <map>
 
+#if defined(_WIN32)
+#include <windows.h>  // MultiByteToWideChar
+#endif
+
 static bool parseHexColorString(const std::string &value, video::SColor &color);
 static bool parseNamedColorString(const std::string &value, video::SColor &color);
 
@@ -58,51 +62,72 @@ int wctomb(char *s, wchar_t wc)
 
 int mbtowc(wchar_t *pwc, const char *s, size_t n)
 {
-       std::wstring intermediate = narrow_to_wide(s);
+       wchar_t *intermediate = narrow_to_wide(s);
 
        if (intermediate.length() > 0) {
                *pwc = intermediate[0];
                return 1;
-       }
-       else {
+       } else {
                return -1;
        }
 }
+// You must free the returned string!
+const wchar_t *narrow_to_wide_c(const char *mbs)
+{
+       size_t mbl = strlen(mbs);
+       wchar_t wcs = new wchar_t[mbl + 1];
 
-std::wstring narrow_to_wide(const std::string& mbs) {
-       size_t wcl = mbs.size();
-
-       std::wstring retval = L"";
-
-       for (unsigned int i = 0; i < wcl; i++) {
-               if (((unsigned char) mbs[i] >31) &&
-                ((unsigned char) mbs[i] < 127)) {
-
-                       retval += wide_chars[(unsigned char) mbs[i] -32];
+       for (size_t i = 0; i < mbl; i++) {
+               if (((unsigned char) mbs[i] > 31) &&
+                               ((unsigned char) mbs[i] < 127)) {
+                       wcs[i] = wide_chars[(unsigned char) mbs[i] - 32];
                }
                //handle newline
                else if (mbs[i] == '\n') {
-                       retval += L'\n';
+                       wcs[i] = L'\n';
                }
        }
 
-       return retval;
+       return wcs;
 }
+
 #else
 
-std::wstring narrow_to_wide(const std::string& mbs)
+// You must free the returned string!
+const wchar_t *narrow_to_wide_c(const char *mbs)
 {
-       size_t wcl = mbs.size();
-       Buffer<wchar_t> wcs(wcl+1);
-       size_t l = mbstowcs(*wcs, mbs.c_str(), wcl);
-       if(l == (size_t)(-1))
-               return L"<invalid multibyte string>";
-       wcs[l] = 0;
-       return *wcs;
+       wchar_t *wcs = NULL;
+#if defined(_WIN32)
+       int wcl = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR) mbs, -1, NULL, 0);
+       if (!wcl)
+               return NULL;
+       wcs = new wchar_t[wcl];
+       MultiByteToWideChar(CP_UTF8, 0, (LPCSTR) mbs, -1, (WCHAR *) wcs, wcl);
+#else
+       size_t wcl = mbstowcs(NULL, mbs, 0);
+       if (wcl == (size_t) -1)
+               return NULL;
+       wcs = new wchar_t[wcl + 1];
+       size_t l = mbstowcs(wcs, mbs, wcl);
+       assert(l != (size_t) -1); // Should never happen if the last call worked
+       wcs[l] = '\0';
+#endif
+
+       return wcs;
 }
 
 #endif
 
+std::wstring narrow_to_wide(const std::string& mbs)
+{
+       const wchar_t *wcs = narrow_to_wide_c(mbs.c_str());
+       if (!wcs)
+               return L"<invalid multibyte string>";
+       std::wstring wstr(wcs);
+       delete [] wcs;
+       return wstr;
+}
+
 #ifdef __ANDROID__
 std::string wide_to_narrow(const std::wstring& wcs) {
        size_t mbl = wcs.size()*4;
index 3ece2371d6c0d0f20765e31a8db438f9239bcf75..388184ca49a645cdd480ebd042892f97763ce7a7 100644 (file)
@@ -36,6 +36,9 @@ struct FlagDesc {
        u32 flag;
 };
 
+// You must free the returned string!
+const wchar_t *narrow_to_wide_c(const char *mbs);
+
 std::wstring narrow_to_wide(const std::string& mbs);
 std::string wide_to_narrow(const std::wstring& wcs);
 std::string translatePassword(std::string playername, std::wstring password);
index e9c1132243817fb694d35b72deea749bb9e72fdf..28755b1fe6c5fe1f2536319098032cb4f957ef9d 100755 (executable)
@@ -54,6 +54,7 @@ xgettext --package-name=minetest \
        --keyword=N_ \
        --keyword=wgettext \
        --keyword=fgettext \
+       --keyword=strgettext \
        --keyword=wstrgettext \
        --output $potfile \
        `find src/ -name '*.cpp' -o -name '*.h'` \