[Bf-blender-cvs] [77f3577] master: D605: Fixes for proper handling of wchar_t paths in MinGW.

Tamito Kajiyama noreply at git.blender.org
Mon Jun 23 03:07:40 CEST 2014


Commit: 77f357728f708dd7a19a62110f34fa9afa5e9213
Author: Tamito Kajiyama
Date:   Mon Jun 23 10:07:06 2014 +0900
https://developer.blender.org/rB77f357728f708dd7a19a62110f34fa9afa5e9213

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

===================================================================

M	source/blender/blenlib/BLI_fileops.h
M	source/blender/blenlib/BLI_fileops_types.h
M	source/blender/blenlib/BLI_winstuff.h
M	source/blender/blenlib/intern/storage.c
M	source/blender/blenlib/intern/winstuff_dir.c

===================================================================

diff --git a/source/blender/blenlib/BLI_fileops.h b/source/blender/blenlib/BLI_fileops.h
index c032b60..2d1e1d8 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 a7372c0..53c9fa1 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 f615e5a..f40359e 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 a5de107..453b0cc 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 90250de..3d669a8 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);




More information about the Bf-blender-cvs mailing list