Rework unicode encoding/decoding (Windows)

This commit is contained in:
Lynix 2017-04-04 09:03:29 +02:00
parent d83689d7ee
commit 9c4c998a2b
10 changed files with 75 additions and 62 deletions

View File

@ -14,8 +14,14 @@ int do_chdir(lua_State* L, const char* path)
(void)(L); /* warning: unused parameter */
#if PLATFORM_WINDOWS
z = SetCurrentDirectoryW(utf8_towide(L, path));
lua_pop(L, 1);
wchar_t wide_buffer[PATH_MAX];
if (MultiByteToWideChar(CP_UTF8, 0, path, -1, wide_buffer, PATH_MAX) == 0)
{
lua_pushstring(L, "unable to encode path");
return lua_error(L);
}
z = SetCurrentDirectoryW(wide_buffer);
#else
z = !chdir(path);
#endif

View File

@ -14,8 +14,22 @@ int os_copyfile(lua_State* L)
const char* dst = luaL_checkstring(L, 2);
#if PLATFORM_WINDOWS
z = CopyFileW(utf8_towide(L, src), utf8_towide(L, dst), FALSE);
lua_pop(L, 2);
wchar_t wide_src[PATH_MAX];
wchar_t wide_dst[PATH_MAX];
if (MultiByteToWideChar(CP_UTF8, 0, src, -1, wide_src, PATH_MAX) == 0)
{
lua_pushstring(L, "unable to encode source path");
return lua_error(L);
}
if (MultiByteToWideChar(CP_UTF8, 0, dst, -1, wide_dst, PATH_MAX) == 0)
{
lua_pushstring(L, "unable to encode source path");
return lua_error(L);
}
z = CopyFileW(wide_src, wide_dst, FALSE);
#else
lua_pushfstring(L, "cp \"%s\" \"%s\"", src, dst);
z = (system(lua_tostring(L, -1)) == 0);

View File

@ -24,9 +24,9 @@ int do_getcwd(char* buffer, size_t size)
int result;
#if PLATFORM_WINDOWS
wchar_t wbuffer[MAX_PATH];
result = (GetCurrentDirectoryW(MAX_PATH, wbuffer) != 0);
wchar_t wbuffer[PATH_MAX];
result = (GetCurrentDirectoryW(PATH_MAX, wbuffer) != 0);
if (result) {
WideCharToMultiByte(CP_UTF8, 0, wbuffer, -1, buffer, size, NULL, NULL);

View File

@ -18,8 +18,13 @@ int os_isdir(lua_State* L)
const char* path = luaL_checkstring(L, 1);
#ifdef _WIN32
int attr;
const wchar_t* wide_path = utf8_towide(L, path);
wchar_t wide_path[PATH_MAX];
if (MultiByteToWideChar(CP_UTF8, 0, path, -1, wide_path, PATH_MAX) == 0)
{
lua_pushstring(L, "unable to encode path");
return lua_error(L);
}
#endif
/* empty path is equivalent to ".", must be true */
@ -44,10 +49,6 @@ int os_isdir(lua_State* L)
{
lua_pushboolean(L, 0);
}
#ifdef _WIN32
lua_remove(L, -2); /* pop wide string */
#endif
return 1;
}

View File

@ -21,9 +21,15 @@ int do_isfile(lua_State* L, const char* filename)
(void)(L); /* warning: unused parameter */
#if PLATFORM_WINDOWS
DWORD attrib = GetFileAttributesW(utf8_towide(L, filename));
lua_pop(L, 1);
wchar_t wide_path[PATH_MAX];
if (MultiByteToWideChar(CP_UTF8, 0, filename, -1, wide_path, PATH_MAX) == 0)
{
lua_pushstring(L, "unable to encode filepath");
return lua_error(L);
}
DWORD attrib = GetFileAttributesW(wide_path);
if (attrib != INVALID_FILE_ATTRIBUTES)
{
return (attrib & FILE_ATTRIBUTE_DIRECTORY) == 0;

View File

@ -14,9 +14,14 @@ int os_islink(lua_State* L)
#if PLATFORM_WINDOWS
{
DWORD attr = GetFileAttributesW(utf8_towide(L, path));
lua_pop(L, 1);
wchar_t wide_path[PATH_MAX];
if (MultiByteToWideChar(CP_UTF8, 0, path, -1, wide_path, PATH_MAX) == 0)
{
lua_pushstring(L, "unable to encode path");
return lua_error(L);
}
DWORD attr = GetFileAttributesW(wide_path);
if (attr != INVALID_FILE_ATTRIBUTES) {
lua_pushboolean(L, (attr & FILE_ATTRIBUTE_REPARSE_POINT) != 0);
return 1;

View File

@ -21,11 +21,17 @@ typedef struct struct_MatchInfo
int os_matchstart(lua_State* L)
{
const char* mask = luaL_checkstring(L, 1);
wchar_t wide_mask[PATH_MAX];
if (MultiByteToWideChar(CP_UTF8, 0, mask, -1, wide_mask, PATH_MAX) == 0)
{
lua_pushstring(L, "unable to encode mask");
return lua_error(L);
}
MatchInfo* m = (MatchInfo*)malloc(sizeof(MatchInfo));
m->handle = FindFirstFileW(utf8_towide(L, mask), &m->entry);
lua_pop(L, 1);
m->handle = FindFirstFileW(wide_mask, &m->entry);
m->is_first = 1;
lua_pushlightuserdata(L, m);
return 1;
@ -43,7 +49,15 @@ int os_matchdone(lua_State* L)
int os_matchname(lua_State* L)
{
MatchInfo* m = (MatchInfo*)lua_touserdata(L, 1);
utf8_fromwide(L, m->entry.cFileName);
char filename[PATH_MAX];
if (WideCharToMultiByte(CP_UTF8, 0, m->entry.cFileName, -1, filename, PATH_MAX, NULL, NULL) == 0)
{
lua_pushstring(L, "unable to decode filename");
return lua_error(L);
}
lua_pushstring(L, filename);
return 1;
}

View File

@ -14,8 +14,14 @@ int os_rmdir(lua_State* L)
const char* path = luaL_checkstring(L, 1);
#if PLATFORM_WINDOWS
z = RemoveDirectoryW(utf8_towide(L, path));
lua_pop(L, 1);
wchar_t wide_path[PATH_MAX];
if (MultiByteToWideChar(CP_UTF8, 0, path, -1, wide_path, PATH_MAX) == 0)
{
lua_pushstring(L, "unable to encode path");
return lua_error(L);
}
z = RemoveDirectoryW(wide_path);
#else
z = (0 == rmdir(path));
#endif

View File

@ -87,12 +87,6 @@ void do_normalize(lua_State* L, char* buffer, const char* path);
int do_pathsearch(lua_State* L, const char* filename, const char* path);
void do_translate(char* value, const char sep);
/* Unicode conversion helper functions (required for Windows systems) */
#ifdef PLATFORM_WINDOWS
const char* utf8_fromwide(lua_State* L, const wchar_t* wstr);
const wchar_t* utf8_towide(lua_State* L, const char* str);
#endif
/* Built-in functions */
int criteria_compile(lua_State* L);
int criteria_delete(lua_State* L);

View File

@ -1,33 +0,0 @@
/**
* \file utf8handking.c
* \brief Handles conversions between Unicode (UTF-8) and system native encoding (wide chars on Windows)
* \author Copyright (c) 2017 Jérôme Leclercq and the Premake project
*/
#include "premake.h"
#include "stdlib.h"
#ifdef PLATFORM_WINDOWS
const char* utf8_fromwide(lua_State* L, const wchar_t* wstr)
{
int size_required = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, NULL, 0, NULL, NULL);
char* unicode_str = (char*) malloc(size_required * sizeof(char));
WideCharToMultiByte(CP_UTF8, 0, wstr, -1, unicode_str, size_required, NULL, NULL);
lua_pushstring(L, unicode_str);
free(unicode_str);
return unicode_str;
}
const wchar_t* utf8_towide(lua_State* L, const char* str)
{
int size_required = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0);
wchar_t* wide_string = (wchar_t*) lua_newuserdata(L, size_required * sizeof(wchar_t));
MultiByteToWideChar(CP_UTF8, 0, str, -1, wide_string, size_required);
return wide_string;
}
#endif