Add support of unicode to all file operations
This commit is contained in:
parent
00aa7e3673
commit
98c381468b
@ -14,7 +14,8 @@ int do_chdir(lua_State* L, const char* path)
|
||||
(void)(L); /* warning: unused parameter */
|
||||
|
||||
#if PLATFORM_WINDOWS
|
||||
z = SetCurrentDirectoryA(path);
|
||||
z = SetCurrentDirectoryW(utf8_towide(L, path));
|
||||
lua_pop(L, 1);
|
||||
#else
|
||||
z = !chdir(path);
|
||||
#endif
|
||||
|
@ -14,7 +14,8 @@ int os_copyfile(lua_State* L)
|
||||
const char* dst = luaL_checkstring(L, 2);
|
||||
|
||||
#if PLATFORM_WINDOWS
|
||||
z = CopyFileA(src, dst, FALSE);
|
||||
z = CopyFileW(utf8_towide(L, src), utf8_towide(L, dst), FALSE);
|
||||
lua_pop(L, 2);
|
||||
#else
|
||||
lua_pushfstring(L, "cp \"%s\" \"%s\"", src, dst);
|
||||
z = (system(lua_tostring(L, -1)) == 0);
|
||||
|
@ -5,6 +5,7 @@
|
||||
*/
|
||||
|
||||
#include "premake.h"
|
||||
#include "assert.h"
|
||||
|
||||
int os_getcwd(lua_State* L)
|
||||
{
|
||||
@ -24,8 +25,13 @@ int do_getcwd(char* buffer, size_t size)
|
||||
int result;
|
||||
|
||||
#if PLATFORM_WINDOWS
|
||||
result = (GetCurrentDirectoryA(size, buffer) != 0);
|
||||
assert(size == 0x4000);
|
||||
wchar_t wbuffer[0x4000];
|
||||
|
||||
result = (GetCurrentDirectoryW(size, wbuffer) != 0);
|
||||
if (result) {
|
||||
WideCharToMultiByte(CP_UTF8, 0, wbuffer, -1, buffer, size, NULL, NULL);
|
||||
|
||||
do_translate(buffer, '/');
|
||||
}
|
||||
#else
|
||||
|
@ -18,6 +18,8 @@ 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);
|
||||
#endif
|
||||
|
||||
/* empty path is equivalent to ".", must be true */
|
||||
@ -27,7 +29,7 @@ int os_isdir(lua_State* L)
|
||||
}
|
||||
#ifdef _WIN32
|
||||
// Use Windows-specific GetFileAttributes since it deals with symbolic links.
|
||||
else if ((attr = GetFileAttributesA(path)) != INVALID_FILE_ATTRIBUTES)
|
||||
else if ((attr = GetFileAttributesW(wide_path)) != INVALID_FILE_ATTRIBUTES)
|
||||
{
|
||||
int isdir = (attr & FILE_ATTRIBUTE_DIRECTORY) != 0;
|
||||
lua_pushboolean(L, isdir);
|
||||
@ -42,6 +44,10 @@ int os_isdir(lua_State* L)
|
||||
{
|
||||
lua_pushboolean(L, 0);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
lua_pop(L, -2); /* pop wide string */
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -11,15 +11,19 @@
|
||||
int os_isfile(lua_State* L)
|
||||
{
|
||||
const char* filename = luaL_checkstring(L, 1);
|
||||
lua_pushboolean(L, do_isfile(filename));
|
||||
lua_pushboolean(L, do_isfile(L, filename));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int do_isfile(const char* filename)
|
||||
int do_isfile(lua_State* L, const char* filename)
|
||||
{
|
||||
(void)(L); /* warning: unused parameter */
|
||||
|
||||
#if PLATFORM_WINDOWS
|
||||
DWORD attrib = GetFileAttributesA(filename);
|
||||
DWORD attrib = GetFileAttributesW(utf8_towide(L, filename));
|
||||
lua_pop(L, 1);
|
||||
|
||||
if (attrib != INVALID_FILE_ATTRIBUTES)
|
||||
{
|
||||
return (attrib & FILE_ATTRIBUTE_DIRECTORY) == 0;
|
||||
|
@ -14,7 +14,9 @@ int os_islink(lua_State* L)
|
||||
|
||||
#if PLATFORM_WINDOWS
|
||||
{
|
||||
DWORD attr = GetFileAttributesA(path);
|
||||
DWORD attr = GetFileAttributesW(utf8_towide(L, path));
|
||||
lua_pop(L, 1);
|
||||
|
||||
if (attr != INVALID_FILE_ATTRIBUTES) {
|
||||
lua_pushboolean(L, (attr & FILE_ATTRIBUTE_REPARSE_POINT) != 0);
|
||||
return 1;
|
||||
|
@ -37,7 +37,7 @@ int os_locate(lua_State* L)
|
||||
const char* name = lua_tostring(L, i);
|
||||
|
||||
/* Direct path to file? Return as absolute path */
|
||||
if (do_isfile(name)) {
|
||||
if (do_isfile(L, name)) {
|
||||
lua_pushcfunction(L, path_getabsolute);
|
||||
lua_pushvalue(L, i);
|
||||
lua_call(L, 1, 1);
|
||||
|
@ -15,14 +15,17 @@ typedef struct struct_MatchInfo
|
||||
{
|
||||
HANDLE handle;
|
||||
int is_first;
|
||||
WIN32_FIND_DATAA entry;
|
||||
WIN32_FIND_DATAW entry;
|
||||
} MatchInfo;
|
||||
|
||||
int os_matchstart(lua_State* L)
|
||||
{
|
||||
const char* mask = luaL_checkstring(L, 1);
|
||||
MatchInfo* m = (MatchInfo*)malloc(sizeof(MatchInfo));
|
||||
m->handle = FindFirstFileA(mask, &m->entry);
|
||||
|
||||
m->handle = FindFirstFileW(utf8_towide(L, mask), &m->entry);
|
||||
lua_pop(L, 1);
|
||||
|
||||
m->is_first = 1;
|
||||
lua_pushlightuserdata(L, m);
|
||||
return 1;
|
||||
@ -40,7 +43,7 @@ int os_matchdone(lua_State* L)
|
||||
int os_matchname(lua_State* L)
|
||||
{
|
||||
MatchInfo* m = (MatchInfo*)lua_touserdata(L, 1);
|
||||
lua_pushstring(L, m->entry.cFileName);
|
||||
utf8_fromwide(L, m->entry.cFileName);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -64,11 +67,11 @@ int os_matchnext(lua_State* L)
|
||||
m->is_first = 0;
|
||||
else
|
||||
{
|
||||
if (!FindNextFileA(m->handle, &m->entry))
|
||||
if (!FindNextFileW(m->handle, &m->entry))
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (strcmp(m->entry.cFileName, ".") != 0 && strcmp(m->entry.cFileName, "..") != 0)
|
||||
if (wcscmp(m->entry.cFileName, L".") != 0 && wcscmp(m->entry.cFileName, L"..") != 0)
|
||||
{
|
||||
lua_pushboolean(L, 1);
|
||||
return 1;
|
||||
@ -159,7 +162,7 @@ int os_matchisfile(lua_State* L)
|
||||
fname = lua_tostring(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_pushboolean(L, do_isfile(fname));
|
||||
lua_pushboolean(L, do_isfile(L, fname));
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
@ -58,7 +58,7 @@ int do_pathsearch(lua_State* L, const char* filename, const char* path)
|
||||
lua_concat(L, 3);
|
||||
|
||||
/* test it - if it exists, return the absolute path */
|
||||
if (do_isfile(lua_tostring(L, -1)))
|
||||
if (do_isfile(L, lua_tostring(L, -1)))
|
||||
{
|
||||
lua_pop(L, 1);
|
||||
lua_pushcfunction(L, path_getabsolute);
|
||||
|
@ -14,7 +14,8 @@ int os_rmdir(lua_State* L)
|
||||
const char* path = luaL_checkstring(L, 1);
|
||||
|
||||
#if PLATFORM_WINDOWS
|
||||
z = RemoveDirectoryA(path);
|
||||
z = RemoveDirectoryW(utf8_towide(L, path));
|
||||
lua_pop(L, 1);
|
||||
#else
|
||||
z = (0 == rmdir(path));
|
||||
#endif
|
||||
|
@ -75,7 +75,7 @@ int os_writefile_ifnotequal(lua_State* L)
|
||||
const char* dst = luaL_checkstring(L, 2);
|
||||
|
||||
// if destination exist, and they are the same, no need to copy.
|
||||
if (do_isfile(dst) && compare_file(content, length, dst))
|
||||
if (do_isfile(L, dst) && compare_file(content, length, dst))
|
||||
{
|
||||
lua_pushinteger(L, 0);
|
||||
return 1;
|
||||
|
@ -229,9 +229,13 @@ int premake_locate_executable(lua_State* L, const char* argv0)
|
||||
const char* path = NULL;
|
||||
|
||||
#if PLATFORM_WINDOWS
|
||||
DWORD len = GetModuleFileNameA(NULL, buffer, PATH_MAX);
|
||||
wchar_t widebuffer[PATH_MAX];
|
||||
|
||||
DWORD len = GetModuleFileNameW(NULL, widebuffer, PATH_MAX);
|
||||
if (len > 0)
|
||||
{
|
||||
WideCharToMultiByte(CP_UTF8, 0, widebuffer, len, buffer, PATH_MAX, NULL, NULL);
|
||||
|
||||
buffer[len] = 0;
|
||||
path = buffer;
|
||||
}
|
||||
@ -320,7 +324,7 @@ int premake_locate_executable(lua_State* L, const char* argv0)
|
||||
int premake_test_file(lua_State* L, const char* filename, int searchMask)
|
||||
{
|
||||
if (searchMask & TEST_LOCAL) {
|
||||
if (do_isfile(filename)) {
|
||||
if (do_isfile(L, filename)) {
|
||||
lua_pushcfunction(L, path_getabsolute);
|
||||
lua_pushstring(L, filename);
|
||||
lua_call(L, 1, 1);
|
||||
|
@ -80,12 +80,17 @@ unsigned long do_hash(const char* str, int seed);
|
||||
void do_getabsolute(char* result, const char* value, const char* relative_to);
|
||||
int do_getcwd(char* buffer, size_t size);
|
||||
int do_isabsolute(const char* path);
|
||||
int do_isfile(const char* filename);
|
||||
int do_isfile(lua_State* L, const char* filename);
|
||||
int do_locate(lua_State* L, const char* filename, const char* path);
|
||||
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);
|
||||
|
33
src/host/utf8handling.c
Normal file
33
src/host/utf8handling.c
Normal file
@ -0,0 +1,33 @@
|
||||
/**
|
||||
* \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
|
Reference in New Issue
Block a user