Clinkの日本語パス問題ふたたび(3)

clink.get_env()でUTF-8を返すように修正するわけですが、clink.get_env()の実体は回りまわってlua.cにありました。
また、Win32 APIではMBCS(ShiftJIS)→UTF-8への直接的な変換はできないので、いったんWideChar(UTF-16)を経由して変換します。

ということで最終的なパッチです。一番最初のdirent.cへのパッチは元に戻したうえで適用してください。

--- Temp/797fUb_lua.c	Sun Dec 15 18:07:53 2013
+++ clink/clink/dll/lua.c	Sun Dec 15 18:07:11 2013
@@ -291,15 +291,37 @@
     rl_filename_completion_desired = 1;
     return 0;
 }
 
 //------------------------------------------------------------------------------
+static char* mbcs_to_utf8(char* buff)
+{
+    wchar_t* buf_wchar;
+    char* buf_utf8;
+    int len_wchar, len_utf8;
+    
+    // Convert MBCS to WideChar.
+    len_wchar = MultiByteToWideChar(CP_ACP, 0, buff, -1, NULL, 0);
+    buf_wchar = (wchar_t*)malloc((len_wchar + 1) * sizeof(wchar_t));
+    MultiByteToWideChar(CP_ACP, 0, buff, -1, buf_wchar, len_wchar);
+
+    // Convert WideChar to UTF8.
+    len_utf8 = WideCharToMultiByte(CP_UTF8, 0, buf_wchar, len_wchar, NULL, 0, NULL, NULL);
+    buf_utf8 = (char*)malloc(len_utf8 + 1);
+    WideCharToMultiByte(CP_UTF8, 0, buf_wchar, len_wchar, buf_utf8, len_utf8, NULL, NULL);
+
+    free(buf_wchar);
+    return buf_utf8;
+}
+
+//------------------------------------------------------------------------------
 static int get_env(lua_State* state)
 {
     unsigned size;
     const char* name;
     char* buffer;
+    char* buf_utf8;
 
     if (lua_gettop(state) == 0)
     {
         return 0;
     }
@@ -316,11 +338,13 @@
         return 0;
     }
     
     buffer = (char*)malloc(size);
     GetEnvironmentVariable(name, buffer, size);
-    lua_pushstring(state, buffer);
+    buf_utf8 = mbcs_to_utf8(buffer);
+    lua_pushstring(state, buf_utf8);
+    free(buf_utf8);
     free(buffer);
     
     return 1;
 }