From 99c67f7daca34ad01ed570f2216ce178891cd68a Mon Sep 17 00:00:00 2001 From: Birunthan Mohanathas Date: Fri, 13 Jul 2012 14:36:59 +0300 Subject: [PATCH] Script: Added Unicode support The script file can now be UTF8 encoded. There are some limitations with UTF8 data and the Lua string library, check: http://lua-users.org/lists/lua-l/2012-02/msg00241.html --- Library/MeasureScript.cpp | 12 ++---- Library/MeasureScript.h | 2 +- Library/lua/LuaManager.cpp | 16 +------- Library/lua/LuaScript.cpp | 71 ++++++++++++++++++++++++++++------ Library/lua/LuaScript.h | 2 +- Library/lua/glue/LuaGlobal.cpp | 2 +- 6 files changed, 69 insertions(+), 36 deletions(-) diff --git a/Library/MeasureScript.cpp b/Library/MeasureScript.cpp index ac0a2142..9dfb0ad2 100644 --- a/Library/MeasureScript.cpp +++ b/Library/MeasureScript.cpp @@ -122,15 +122,14 @@ void CMeasureScript::ReadOptions(CConfigParser& parser, const WCHAR* section) { m_MeterWindow->MakePathAbsolute(file); } - std::string scriptFile = ConvertToAscii(file.c_str()); if (!m_Initialized || - strcmp(scriptFile.c_str(), m_ScriptFile.c_str()) != 0) + wcscmp(file.c_str(), m_ScriptFile.c_str()) != 0) { DeleteLuaScript(); lua_State* L = LuaManager::GetState(); - m_ScriptFile = scriptFile; + m_ScriptFile = file; m_LuaScript = new LuaScript(m_ScriptFile.c_str()); if (m_LuaScript->IsInitialized()) @@ -173,10 +172,7 @@ void CMeasureScript::ReadOptions(CConfigParser& parser, const WCHAR* section) if (!wstrValue.empty()) { - std::string strStrVal = ConvertToAscii(wstrValue.c_str()); - const char* strValue = strStrVal.c_str(); - - lua_pushstring(L, strValue); + LuaManager::PushWide(L, wstrValue.c_str()); lua_setfield(L, -3, strKey); } } @@ -204,7 +200,7 @@ void CMeasureScript::ReadOptions(CConfigParser& parser, const WCHAR* section) */ void CMeasureScript::Command(const std::wstring& command) { - std::string str = ConvertToAscii(command.c_str()); + std::string str = ConvertToUTF8(command.c_str()); m_LuaScript->RunString(str.c_str()); } diff --git a/Library/MeasureScript.h b/Library/MeasureScript.h index a10376a9..0a6b9d7d 100644 --- a/Library/MeasureScript.h +++ b/Library/MeasureScript.h @@ -50,7 +50,7 @@ private: std::wstring m_StringValue; - std::string m_ScriptFile; + std::wstring m_ScriptFile; }; #endif \ No newline at end of file diff --git a/Library/lua/LuaManager.cpp b/Library/lua/LuaManager.cpp index 332e8525..7abd4777 100644 --- a/Library/lua/LuaManager.cpp +++ b/Library/lua/LuaManager.cpp @@ -61,27 +61,15 @@ void LuaManager::ReportErrors(lua_State* L) const char* error = lua_tostring(L, -1); lua_pop(L, 1); - const char* pos = error + 4; // Skip the drive - - // Get rid of everything up to the filename - while (*pos != ':') - { - if (*pos == '\\') - { - error = pos + 1; - } - ++pos; - } - LogWithArgs(LOG_ERROR, L"Script: %S", error); } void LuaManager::PushWide(lua_State* L, const WCHAR* str) { - lua_pushstring(L, ConvertToAscii(str).c_str()); + lua_pushstring(L, ConvertToUTF8(str).c_str()); } std::wstring LuaManager::ToWide(lua_State* L, int narg) { - return ConvertToWide(lua_tostring(L, narg)); + return ConvertUTF8ToWide(lua_tostring(L, narg)); } diff --git a/Library/lua/LuaScript.cpp b/Library/lua/LuaScript.cpp index 92fcb82d..bbb99246 100644 --- a/Library/lua/LuaScript.cpp +++ b/Library/lua/LuaScript.cpp @@ -25,15 +25,62 @@ ** The constructor ** */ -LuaScript::LuaScript(const char* file) : +LuaScript::LuaScript(const WCHAR* scriptFile) : m_Ref(LUA_NOREF), - m_Initialized(true) + m_Initialized(false) { lua_State* L = LuaManager::GetState(); - int result = luaL_loadfile(L, file); - // If the file loaded okay. - if (result == 0) + FILE* file = _wfopen(scriptFile, L"rb"); + if (!file) + { + return; + } + + fseek(file, 0, SEEK_END); + long fileSize = ftell(file); + if (fileSize < 3) + { + return; + } + + int load = 0; + std::string scriptName = ConvertToUTF8(wcsrchr(scriptFile, L'\\') + 1); + const char* scriptNameSz = scriptName.c_str(); + + BYTE* fileData = new BYTE[fileSize]; + fseek(file, 0, SEEK_SET); + fread(fileData, fileSize, 1, file); + + if (fileData[0] == 0xEF && fileData[1] == 0xBB && fileData[2] == 0xBF) + { + // Has UTF8 BOM, so assume that data is already in UTF8. + const char* utf8Data = (char*)fileData + 3; + int utf8Size = fileSize - 3; + + load = luaL_loadbuffer(L, utf8Data, utf8Size, scriptNameSz); + delete [] fileData; + } + else + { + // Convert the file contents first to WCHAR with respect to the current + // code page and then to UTF8 in order to preserve code page specific chars. + + int wideSize = MultiByteToWideChar(CP_ACP, 0, (char*)fileData, fileSize, NULL, 0); + WCHAR* wideData = new WCHAR[wideSize]; + MultiByteToWideChar(CP_ACP, 0, (char*)fileData, fileSize, wideData, wideSize); + delete [] fileData; + + int utf8Size = WideCharToMultiByte(CP_UTF8, 0, wideData, wideSize, NULL, 0, NULL, NULL); + char* utf8Data = new char[utf8Size]; + WideCharToMultiByte(CP_UTF8, 0, wideData, wideSize, utf8Data, utf8Size, NULL, NULL); + delete [] wideData; + + load = luaL_loadbuffer(L, utf8Data, utf8Size, scriptNameSz); + delete [] utf8Data; + } + + if (load == 0) { // Create the table this script will reside in lua_newtable(L); @@ -60,11 +107,12 @@ LuaScript::LuaScript(const char* file) : lua_setfenv(L, -2); // Execute the Lua script - result = lua_pcall(L, 0, 0, 0); - - if (result) + if (lua_pcall(L, 0, 0, 0) == 0) + { + m_Initialized = true; + } + else { - m_Initialized = false; LuaManager::ReportErrors(L); luaL_unref(L, LUA_GLOBALSINDEX, m_Ref); @@ -73,9 +121,10 @@ LuaScript::LuaScript(const char* file) : } else { - m_Initialized = false; LuaManager::ReportErrors(L); } + + fclose(file); } /* @@ -174,7 +223,7 @@ int LuaScript::RunFunctionWithReturn(const char* funcName, double& numValue, std else if (type == LUA_TSTRING) { const char* str = lua_tostring(L, -1); - strValue = ConvertToWide(str); + strValue = ConvertUTF8ToWide(str); numValue = strtod(str, NULL); } diff --git a/Library/lua/LuaScript.h b/Library/lua/LuaScript.h index d87f792e..5d9ff8ce 100644 --- a/Library/lua/LuaScript.h +++ b/Library/lua/LuaScript.h @@ -24,7 +24,7 @@ class LuaScript { public: - LuaScript(const char* file); + LuaScript(const WCHAR* scriptFile); ~LuaScript(); bool IsInitialized() { return m_Initialized; } diff --git a/Library/lua/glue/LuaGlobal.cpp b/Library/lua/glue/LuaGlobal.cpp index 26f54d8b..94d43aa9 100644 --- a/Library/lua/glue/LuaGlobal.cpp +++ b/Library/lua/glue/LuaGlobal.cpp @@ -53,7 +53,7 @@ static int Print(lua_State* L) lua_pop(L, 1); } - Log(LOG_DEBUG, ConvertToWide(message.c_str()).c_str()); + Log(LOG_DEBUG, ConvertUTF8ToWide(message.c_str()).c_str()); return 0; }