diff options
| author | LEE Wondong <wdlee91@gmail.com> | 2013-10-20 15:02:03 +0900 |
|---|---|---|
| committer | LEE Wondong <wdlee91@gmail.com> | 2013-10-20 15:02:03 +0900 |
| commit | 3e53c929a2298e59d9abd3973094db3d34d59e98 (patch) | |
| tree | 4c71a86df71ca96203455f7c9a16e4c14f4d5d8b /src/rt/rust_builtin.cpp | |
| parent | a1848bc755411285afb15f2453df7567e10ebc04 (diff) | |
| download | rust-3e53c929a2298e59d9abd3973094db3d34d59e98.tar.gz rust-3e53c929a2298e59d9abd3973094db3d34d59e98.zip | |
Fix unicode errors on Windows in path_is_dir, path_exists, getcwd and rust_localtime.
This make these functions use wchar_t version of APIs, instead of char version.
Diffstat (limited to 'src/rt/rust_builtin.cpp')
| -rw-r--r-- | src/rt/rust_builtin.cpp | 46 |
1 files changed, 42 insertions, 4 deletions
diff --git a/src/rt/rust_builtin.cpp b/src/rt/rust_builtin.cpp index 9750e22e945..d20e91f3917 100644 --- a/src/rt/rust_builtin.cpp +++ b/src/rt/rust_builtin.cpp @@ -107,7 +107,7 @@ rust_list_dir_wfd_fp_buf(void* wfd) { #endif extern "C" CDECL int -rust_path_is_dir(char *path) { +rust_path_is_dir(const char *path) { struct stat buf; if (stat(path, &buf)) { return 0; @@ -116,7 +116,25 @@ rust_path_is_dir(char *path) { } extern "C" CDECL int -rust_path_exists(char *path) { +#if defined(__WIN32__) +rust_path_is_dir_u16(const wchar_t *path) { + struct _stat buf; + // Don't use GetFileAttributesW, it cannot get attributes of + // some system files (e.g. pagefile.sys). + if (_wstat(path, &buf)) { + return 0; + } + return S_ISDIR(buf.st_mode); +} +#else +rust_path_is_dir_u16(const void *path) { + // Wide version of function is only used on Windows. + return 0; +} +#endif + +extern "C" CDECL int +rust_path_exists(const char *path) { struct stat buf; if (stat(path, &buf)) { return 0; @@ -124,6 +142,22 @@ rust_path_exists(char *path) { return 1; } +extern "C" CDECL int +#if defined(__WIN32__) +rust_path_exists_u16(const wchar_t *path) { + struct _stat buf; + if (_wstat(path, &buf)) { + return 0; + } + return 1; +} +#else +rust_path_exists_u16(const void *path) { + // Wide version of function is only used on Windows. + return 0; +} +#endif + extern "C" CDECL FILE* rust_get_stdin() {return stdin;} extern "C" CDECL FILE* rust_get_stdout() {return stdout;} extern "C" CDECL FILE* rust_get_stderr() {return stderr;} @@ -294,8 +328,12 @@ rust_localtime(int64_t sec, int32_t nsec, rust_tm *timeptr) { const char* zone = NULL; #if defined(__WIN32__) int32_t gmtoff = -timezone; - char buffer[64]; - if (strftime(buffer, sizeof(buffer), "%Z", &tm) > 0) { + wchar_t wbuffer[64]; + char buffer[256]; + // strftime("%Z") can contain non-UTF-8 characters on non-English locale (issue #9418), + // so time zone should be converted from UTF-16 string set by wcsftime. + if (wcsftime(wbuffer, sizeof(wbuffer) / sizeof(wchar_t), L"%Z", &tm) > 0) { + WideCharToMultiByte(CP_UTF8, 0, wbuffer, -1, buffer, sizeof(buffer), NULL, NULL); zone = buffer; } #else |
