From 9e2a9b55e185b92074b32d3df336920f33b29e5a Mon Sep 17 00:00:00 2001 From: ShadowNinja Date: Sun, 1 Feb 2015 17:59:23 -0500 Subject: [PATCH] Reduce gettext wide/narrow and string/char* conversions --- src/client.cpp | 2 +- src/game.cpp | 36 ++++++---------- src/gettext.cpp | 28 ++++++------ src/gettext.h | 61 ++++++-------------------- src/guiChatConsole.cpp | 4 +- src/guiFormSpecMenu.cpp | 2 +- src/guiKeyChangeMenu.cpp | 31 +++++++------- src/guiKeyChangeMenu.h | 8 ++-- src/guiPasswordChange.cpp | 12 +++--- src/guiVolumeChange.cpp | 4 +- src/main.cpp | 2 +- src/script/lua_api/l_mainmenu.cpp | 1 + src/util/string.cpp | 71 +++++++++++++++++++++---------- src/util/string.h | 3 ++ util/updatepo.sh | 1 + 15 files changed, 125 insertions(+), 141 deletions(-) diff --git a/src/client.cpp b/src/client.cpp index cb6419fa..2f70d624 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -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"<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."); } } + diff --git a/src/gettext.cpp b/src/gettext.cpp index 0c0e520c..688a2257 100644 --- a/src/gettext.cpp +++ b/src/gettext.cpp @@ -23,6 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #include "gettext.h" #include "util/string.h" +#include "log.h" #if USE_GETTEXT && defined(_MSC_VER) #include @@ -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; } - - - diff --git a/src/gettext.h b/src/gettext.h index 81510aed..77fab895 100644 --- a/src/gettext.h +++ b/src/gettext.h @@ -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 @@ -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 - -#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"< - +#include "log.h" #include "gettext.h" +#include #if USE_FREETYPE #include "xCGUITTFont.h" diff --git a/src/guiFormSpecMenu.cpp b/src/guiFormSpecMenu.cpp index c85bc16d..20c9ecde 100644 --- a/src/guiFormSpecMenu.cpp +++ b/src/guiFormSpecMenu.cpp @@ -2000,7 +2000,7 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize) mydata.rect = core::rect(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; } diff --git a/src/guiKeyChangeMenu.cpp b/src/guiKeyChangeMenu.cpp index 8b0bb827..9bc8118a 100644 --- a/src/guiKeyChangeMenu.cpp +++ b/src/guiKeyChangeMenu.cpp @@ -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 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 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"); } + diff --git a/src/guiKeyChangeMenu.h b/src/guiKeyChangeMenu.h index 833514c1..19a07620 100644 --- a/src/guiKeyChangeMenu.h +++ b/src/guiKeyChangeMenu.h @@ -30,13 +30,13 @@ #include #include -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; diff --git a/src/guiPasswordChange.cpp b/src/guiPasswordChange.cpp index c8a2214b..d9a5cc48 100644 --- a/src/guiPasswordChange.cpp +++ b/src/guiPasswordChange.cpp @@ -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 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 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 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 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 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, diff --git a/src/guiVolumeChange.cpp b/src/guiVolumeChange.cpp index f31c650f..b31b99a9 100644 --- a/src/guiVolumeChange.cpp +++ b/src/guiVolumeChange.cpp @@ -103,7 +103,7 @@ void GUIVolumeChange::regenerateGui(v2u32 screensize) { core::rect 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 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; diff --git a/src/main.cpp b/src/main.cpp index e7108a3e..bbf88e80 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -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; diff --git a/src/script/lua_api/l_mainmenu.cpp b/src/script/lua_api/l_mainmenu.cpp index 0f903ba5..28c3d193 100644 --- a/src/script/lua_api/l_mainmenu.cpp +++ b/src/script/lua_api/l_mainmenu.cpp @@ -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 diff --git a/src/util/string.cpp b/src/util/string.cpp index 1d956060..b4908d62 100644 --- a/src/util/string.cpp +++ b/src/util/string.cpp @@ -32,6 +32,10 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #include +#if defined(_WIN32) +#include // 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 wcs(wcl+1); - size_t l = mbstowcs(*wcs, mbs.c_str(), wcl); - if(l == (size_t)(-1)) - return L""; - 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""; + 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; diff --git a/src/util/string.h b/src/util/string.h index 3ece2371..388184ca 100644 --- a/src/util/string.h +++ b/src/util/string.h @@ -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); diff --git a/util/updatepo.sh b/util/updatepo.sh index e9c11322..28755b1f 100755 --- a/util/updatepo.sh +++ b/util/updatepo.sh @@ -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'` \