diff options
author | Tamito Kajiyama <rd6t-kjym@asahi-net.or.jp> | 2014-06-23 05:07:06 +0400 |
---|---|---|
committer | Tamito Kajiyama <rd6t-kjym@asahi-net.or.jp> | 2014-06-23 05:07:06 +0400 |
commit | 77f357728f708dd7a19a62110f34fa9afa5e9213 (patch) | |
tree | 5a3ef21544f4141ab13bfc12f69b7de6000e8b9a /source | |
parent | 489937e1e7f89b3c21a4e13feaffbd400527f118 (diff) |
D605: Fixes for proper handling of wchar_t paths in MinGW.
* Fixed different not-in-sync #ifdef blocks for struct stat variants under Windows.
Comments have been left to indicate the portions of BLI_fileops.h and
BLI_fileops_types.h that need to stay in sync.
* Added BLI_wstat() to de-duplicate #ifdef blocks for stat() variants on Windows.
* Fix for opendir() and associate functions in MinGW not working properly with
non-ASCII, MBCS-compatible paths.
MinGW (FREE_WINDOWS) has opendir() and _wopendir(), and only the
latter accepts a path name of wchar_t type. Rather than messing up with
extra #ifdef's here and there, Blender's own implementations of opendir()
and related functions are used to properly support paths with non-ASCII,
MBCS-compatible characters.
Tested with MSVC 2013 Express, MinGW32 (gcc 4.6.2) and MinGW-w64 (gcc 4.7.1).
Differential Revision: https://developer.blender.org/D605
Reviewed By: campbellbarton
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenlib/BLI_fileops.h | 12 | ||||
-rw-r--r-- | source/blender/blenlib/BLI_fileops_types.h | 10 | ||||
-rw-r--r-- | source/blender/blenlib/BLI_winstuff.h | 5 | ||||
-rw-r--r-- | source/blender/blenlib/intern/storage.c | 47 | ||||
-rw-r--r-- | source/blender/blenlib/intern/winstuff_dir.c | 9 |
5 files changed, 39 insertions, 44 deletions
diff --git a/source/blender/blenlib/BLI_fileops.h b/source/blender/blenlib/BLI_fileops.h index c032b606900..2d1e1d84882 100644 --- a/source/blender/blenlib/BLI_fileops.h +++ b/source/blender/blenlib/BLI_fileops.h @@ -60,17 +60,23 @@ int BLI_delete(const char *path, bool dir, bool recursive); int BLI_move(const char *path, const char *to); int BLI_create_symlink(const char *path, const char *to); +/* keep in sync with the definition of struct direntry in BLI_fileops_types.h */ #ifdef WIN32 -# ifndef __MINGW64__ +# if (defined(_MSC_VER) && (_MSC_VER >= 1500)) || defined(__MINGW64__) typedef struct _stat64 BLI_stat_t; +# elif defined(__MINGW32__) +typedef struct _stati64 BLI_stat_t; # else -typedef struct stat BLI_stat_t; -#endif +typedef struct _stat BLI_stat_t; +# endif #else typedef struct stat BLI_stat_t; #endif int BLI_stat(const char *path, BLI_stat_t *buffer); +#ifdef WIN32 +int BLI_wstat(const wchar_t *path, BLI_stat_t *buffer); +#endif /* Directories */ diff --git a/source/blender/blenlib/BLI_fileops_types.h b/source/blender/blenlib/BLI_fileops_types.h index a7372c01e52..53c9fa16b70 100644 --- a/source/blender/blenlib/BLI_fileops_types.h +++ b/source/blender/blenlib/BLI_fileops_types.h @@ -45,12 +45,16 @@ struct direntry { mode_t type; char *relname; char *path; -#if (defined(WIN32) || defined(WIN64)) && !defined(__MINGW32__) && (_MSC_VER >= 1500) +#ifdef WIN32 /* keep in sync with the definition of BLI_stat_t in BLI_fileops.h */ +# if (defined(_MSC_VER) && (_MSC_VER >= 1500)) || defined(__MINGW64__) struct _stat64 s; -#elif defined(__MINGW32__) +# elif defined(__MINGW32__) struct _stati64 s; +# else + struct _stat s; +# endif #else - struct stat s; + struct stat s; #endif unsigned int flags; char size[16]; diff --git a/source/blender/blenlib/BLI_winstuff.h b/source/blender/blenlib/BLI_winstuff.h index f615e5a9300..f40359ec3dc 100644 --- a/source/blender/blenlib/BLI_winstuff.h +++ b/source/blender/blenlib/BLI_winstuff.h @@ -125,10 +125,6 @@ typedef long ssize_t; # endif #endif - -#ifdef FREE_WINDOWS -#include <dirent.h> -#else struct dirent { int d_ino; int d_off; @@ -151,7 +147,6 @@ typedef struct _DIR { DIR *opendir(const char *path); struct dirent *readdir(DIR *dp); int closedir(DIR *dp); -#endif void RegisterBlendExtension(void); void get_default_root(char *root); diff --git a/source/blender/blenlib/intern/storage.c b/source/blender/blenlib/intern/storage.c index a5de1072372..453b0cc939f 100644 --- a/source/blender/blenlib/intern/storage.c +++ b/source/blender/blenlib/intern/storage.c @@ -255,22 +255,7 @@ static void bli_builddir(struct BuildDirCtx *dir_ctx, const char *dirname) file->relname = dlink->name; file->path = BLI_strdupcat(dirname, dlink->name); BLI_join_dirfile(fullname, sizeof(fullname), dirname, dlink->name); -// use 64 bit file size, only needed for WIN32 and WIN64. -// Excluding other than current MSVC compiler until able to test -#ifdef WIN32 - { - wchar_t *name_16 = alloc_utf16_from_8(fullname, 0); -#if defined(_MSC_VER) && (_MSC_VER >= 1500) - _wstat64(name_16, &file->s); -#elif defined(__MINGW32__) - _stati64(fullname, &file->s); -#endif - free(name_16); - } - -#else - stat(fullname, &file->s); -#endif + BLI_stat(fullname, &file->s); file->type = file->s.st_mode; file->flags = 0; dir_ctx->nrfiles++; @@ -473,11 +458,7 @@ size_t BLI_file_size(const char *path) int BLI_exists(const char *name) { #if defined(WIN32) -#ifndef __MINGW32__ - struct _stat64 st; -#else - struct _stati64 st; -#endif + BLI_stat_t st; wchar_t *tmp_16 = alloc_utf16_from_8(name, 1); int len, res; unsigned int old_error_mode; @@ -506,11 +487,7 @@ int BLI_exists(const char *name) * when looking for a file on an empty CD/DVD drive */ old_error_mode = SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX); -#ifndef __MINGW32__ - res = _wstat64(tmp_16, &st); -#else - res = _wstati64(tmp_16, &st); -#endif + res = BLI_wstat(tmp_16, &st); SetErrorMode(old_error_mode); @@ -530,16 +507,22 @@ int BLI_stat(const char *path, BLI_stat_t *buffer) int r; UTF16_ENCODE(path); - /* workaround error in MinGW64 headers, normally, a wstat should work */ -#ifndef __MINGW64__ - r = _wstat64(path_16, buffer); -#else - r = _wstati64(path_16, buffer); -#endif + r = BLI_wstat(path_16, buffer); UTF16_UN_ENCODE(path); return r; } + +int BLI_wstat(const wchar_t *path, BLI_stat_t *buffer) +{ +#if (defined(_MSC_VER) && (_MSC_VER >= 1500)) || defined(__MINGW64__) + return _wstat64(path, buffer); +#elif defined(__MINGW32__) + return _wstati64(path, buffer); +#else + return _wstat(path, buffer); +#endif +} #else int BLI_stat(const char *path, struct stat *buffer) { diff --git a/source/blender/blenlib/intern/winstuff_dir.c b/source/blender/blenlib/intern/winstuff_dir.c index 90250de1683..3d669a869f9 100644 --- a/source/blender/blenlib/intern/winstuff_dir.c +++ b/source/blender/blenlib/intern/winstuff_dir.c @@ -28,7 +28,7 @@ * (opendir, readdir, closedir) */ -#if defined(WIN32) && !defined(FREE_WINDOWS) +#ifdef WIN32 /* standalone for inclusion in binaries other then blender */ # ifdef USE_STANDALONE @@ -44,6 +44,13 @@ #include "BLI_utildefines.h" #include "utfconv.h" +/* Note: MinGW (FREE_WINDOWS) has opendir() and _wopendir(), and only the +* latter accepts a path name of wchar_t type. Rather than messing up with +* extra #ifdef's here and there, Blender's own implementations of opendir() +* and related functions are used to properly support paths with non-ASCII +* characters. (kjym3) +*/ + DIR *opendir(const char *path) { wchar_t *path_16 = alloc_utf16_from_8(path, 0); |