diff --git a/src/utils/file.c b/src/utils/file.c index 1588b27c..ab3691d0 100644 --- a/src/utils/file.c +++ b/src/utils/file.c @@ -9,13 +9,26 @@ #if defined(_WIN32) || defined(_WIN64) #include #include "../windows/realpath.c" + #include "../windows/utf16.c" + // use wide char functions for unicode support / longer paths (potentially) + // opendir() is provided by mingw and does unicode convertion already #endif FILE* file_open(B path, char* desc, char* mode) { // doesn't consume +#if !defined(_WIN32) char* p = toCStr(path); FILE* f = fopen(p, mode); freeCStr(p); +#else + WCHAR wmode[8] = {0}; + u64 len = strlen(mode); + assert(len<(sizeof(wmode)/sizeof(WCHAR))); + for (u64 i = 0; ia = data; #if !defined(_WIN32) @@ -379,39 +393,61 @@ void mmap_init() { } #include bool dir_create(B path) { +#if !defined(_WIN32) char* p = toCStr(path); - #if defined(_WIN32) || defined(_WIN64) - bool r = _mkdir(p) == 0; - #else - bool r = mkdir(p, S_IRWXU) == 0; - #endif + bool r = mkdir(p, S_IRWXU) == 0; freeCStr(p); +#else + WCHAR* p = toWStr(path); + bool r = _wmkdir(p) == 0; + freeWStr(p); +#endif return r; } bool path_rename(B old_path, B new_path) { +#if !defined(_WIN32) char* old = toCStr(old_path); char* new = toCStr(new_path); // TODO Fix race condition, e.g., with renameat2 on Linux, etc. bool ok = access(new, F_OK) != 0 && rename(old, new) == 0; freeCStr(new); freeCStr(old); +#else + WCHAR* old = toWStr(old_path); + WCHAR* new = toWStr(new_path); + bool ok = _waccess(new, F_OK) != 0 && _wrename(old, new) == 0; + freeWStr(new); + freeWStr(old); +#endif dec(old_path); return ok; } bool path_remove(B path) { +#if !defined(_WIN32) char* p = toCStr(path); bool ok = unlink(p) == 0; freeCStr(p); +#else + WCHAR* p = toWStr(path); + bool ok = _wunlink(p) == 0; + freeWStr(p); +#endif dec(path); return ok; } int path_stat(struct stat* s, B path) { // doesn't consume; get stat of s; errors if path isn't string; returns non-zero on failure +#if !defined(_WIN32) char* p = toCStr(path); int r = stat(p, s); freeCStr(p); +#else + WCHAR* p = toWStr(path); + int r = wstat(p, s); + freeWStr(p); +#endif return r; } diff --git a/src/windows/utf16.c b/src/windows/utf16.c index 99cbc642..d606b40f 100644 --- a/src/windows/utf16.c +++ b/src/windows/utf16.c @@ -26,13 +26,13 @@ FORCE_INLINE void utf16_w(WCHAR** buf_i, u32 c) *buf_i = buf; } -void toUTF16(B x, WCHAR* p) { +static void toUTF16(B x, WCHAR* p) { SGetU(x) usz ia = IA(x); for (u64 i = 0; i < ia; ++i) utf16_w(&p, o2cG(GetU(x,i))); } -B utf16Decode(const WCHAR* s, i64 len) { +static B utf16Decode(const WCHAR* s, i64 len) { #define UTF16_MASK 0xFC00 #define UTF16_IS_HI(WC) ((UTF16_MASK&(WC))==0xD800) /* 0xD800..0xDBFF */ #define UTF16_IS_LO(WC) ((UTF16_MASK&(WC))==0xDC00) /* 0xDC00..0xDFFF */ @@ -64,13 +64,13 @@ B utf16Decode(const WCHAR* s, i64 len) { #undef UTF16_SURROGATE } -static WCHAR* toWideStr(B x) { // doesn't consume +static WCHAR* toWStr(B x) { // doesn't consume u64 len = utf16lenB(x); TALLOC(WCHAR, p, len+1); toUTF16(x, p); p[len] = 0; return p; } -static void freeWideStr(WCHAR* p) { +static void freeWStr(WCHAR* p) { TFREE(p); }