[前][次][番号順一覧][スレッド一覧]

ruby-changes:19332

From: usa <ko1@a...>
Date: Thu, 28 Apr 2011 16:22:27 +0900 (JST)
Subject: [ruby-changes:19332] Ruby:r31372 (trunk): * win32/{win32.c,dir.h} (rb_w32_uopendir): new API to pass UTF-8 path.

usa	2011-04-28 16:22:18 +0900 (Thu, 28 Apr 2011)

  New Revision: 31372

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=31372

  Log:
    * win32/{win32.c,dir.h} (rb_w32_uopendir): new API to pass UTF-8 path.
    
    * win32/win32.c (opendir_internal, rb_w32_opendir): extract and merge
      common part of rb_w32_opendir() and rb_w32_uopendir().
    
    * dir.c (do_opendir, glob_helper): encoding.
    
    * dir.c (dir_initialize, do_opendir): convert path to UTF-8 and call
      rb_w32_uopendir() instead of rb_w32_opendir() on Windows.
      fixes #4491, reported by Joey Zhou.

  Modified files:
    trunk/ChangeLog
    trunk/dir.c
    trunk/win32/dir.h
    trunk/win32/win32.c

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 31371)
+++ ChangeLog	(revision 31372)
@@ -1,3 +1,16 @@
+Thu Apr 28 16:15:49 2011  NAKAMURA Usaku  <usa@r...>
+
+	* win32/{win32.c,dir.h} (rb_w32_uopendir): new API to pass UTF-8 path.
+
+	* win32/win32.c (opendir_internal, rb_w32_opendir): extract and merge
+	  common part of rb_w32_opendir() and rb_w32_uopendir().
+
+	* dir.c (do_opendir, glob_helper): encoding.
+
+	* dir.c (dir_initialize, do_opendir): convert path to UTF-8 and call
+	  rb_w32_uopendir() instead of rb_w32_opendir() on Windows.
+	  fixes #4491, reported by Joey Zhou.
+
 Thu Apr 28 15:32:53 2011  NAKAMURA Usaku  <usa@r...>
 
 	* test/dl/test_base.rb (DL::LIBC_SO): its always msvc*.dll on
Index: dir.c
===================================================================
--- dir.c	(revision 31371)
+++ dir.c	(revision 31372)
@@ -75,6 +75,8 @@
 #define mkdir(p, m) rb_w32_umkdir((p), (m))
 #undef rmdir
 #define rmdir(p) rb_w32_urmdir(p)
+#undef opendir
+#define opendir(p) rb_w32_uopendir(p)
 #endif
 
 #define FNM_NOESCAPE	0x01
@@ -402,6 +404,7 @@
     }
 
     GlobPathValue(dirname, FALSE);
+    dirname = rb_str_encode_ospath(dirname);
 
     TypedData_Get_Struct(dir, struct dir_data, &dir_data_type, dp);
     if (dp->dir) closedir(dp->dir);
@@ -1033,9 +1036,20 @@
 }
 
 static DIR *
-do_opendir(const char *path, int flags)
+do_opendir(const char *path, int flags, rb_encoding *enc)
 {
-    DIR *dirp = opendir(path);
+    DIR *dirp;
+#ifdef _WIN32
+    volatile VALUE tmp;
+    if (enc != rb_usascii_encoding() &&
+	enc != rb_ascii8bit_encoding() &&
+	enc != rb_utf8_encoding()) {
+	tmp = rb_enc_str_new(path, strlen(path), enc);
+	tmp = rb_str_encode_ospath(tmp);
+	path = RSTRING_PTR(tmp);
+    }
+#endif
+    dirp = opendir(path);
     if (dirp == NULL && !to_be_ignored(errno))
 	sys_warning(path);
 
@@ -1354,7 +1368,7 @@
 	struct dirent *dp;
 	DIR *dirp;
 	IF_HAVE_READDIR_R(DEFINE_STRUCT_DIRENT entry);
-	dirp = do_opendir(*path ? path : ".", flags);
+	dirp = do_opendir(*path ? path : ".", flags, enc);
 	if (dirp == NULL) return 0;
 
 	while (READDIR(dirp, enc, &STRUCT_DIRENT(entry), dp)) {
Index: win32/win32.c
===================================================================
--- win32/win32.c	(revision 31371)
+++ win32/win32.c	(revision 31372)
@@ -1690,14 +1690,30 @@
 }
 
 static DIR *
-opendir_internal(HANDLE fh, WIN32_FIND_DATAW *fd)
+opendir_internal(WCHAR *wpath, const char *filename)
 {
+    struct stati64 sbuf;
+    WIN32_FIND_DATAW fd;
+    HANDLE fh;
     DIR *p;
     long len;
     long idx;
     WCHAR *tmpW;
     char *tmp;
 
+    //
+    // check to see if we've got a directory
+    //
+    if (wstati64(wpath, &sbuf) < 0) {
+	return NULL;
+    }
+    if (!(sbuf.st_mode & S_IFDIR) &&
+	(!ISALPHA(filename[0]) || filename[1] != ':' || filename[2] != '\0' ||
+	 ((1 << ((filename[0] & 0x5f) - 'A')) & GetLogicalDrives()) == 0)) {
+	errno = ENOTDIR;
+	return NULL;
+    }
+    fh = open_dir_handle(wpath, &fd);
     if (fh == INVALID_HANDLE_VALUE) {
 	return NULL;
     }
@@ -1718,7 +1734,7 @@
     // of the previous string found.
     //
     do {
-	len = lstrlenW(fd->cFileName) + 1;
+	len = lstrlenW(fd.cFileName) + 1;
 
 	//
 	// bump the string table size by enough for the
@@ -1734,7 +1750,7 @@
 	}
 
 	p->start = tmpW;
-	memcpy(&p->start[idx], fd->cFileName, len * sizeof(WCHAR));
+	memcpy(&p->start[idx], fd.cFileName, len * sizeof(WCHAR));
 
 	if (p->nfiles % DIRENT_PER_CHAR == 0) {
 	    tmp = realloc(p->bits, p->nfiles / DIRENT_PER_CHAR + 1);
@@ -1743,14 +1759,14 @@
 	    p->bits = tmp;
 	    p->bits[p->nfiles / DIRENT_PER_CHAR] = 0;
 	}
-	if (fd->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+	if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
 	    SetBit(p->bits, BitOfIsDir(p->nfiles));
-	if (fd->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
+	if (fd.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
 	    SetBit(p->bits, BitOfIsRep(p->nfiles));
 
 	p->nfiles++;
 	idx += len;
-    } while (FindNextFileW(fh, fd));
+    } while (FindNextFileW(fh, &fd));
     FindClose(fh);
     p->size = idx;
     p->curr = p->start;
@@ -1789,31 +1805,25 @@
 DIR *
 rb_w32_opendir(const char *filename)
 {
-    struct stati64 sbuf;
-    WIN32_FIND_DATAW fd;
-    HANDLE fh;
-    WCHAR *wpath;
-
-    if (!(wpath = filecp_to_wstr(filename, NULL)))
+    DIR *ret;
+    WCHAR *wpath = filecp_to_wstr(filename, NULL);
+    if (!wpath)
 	return NULL;
+    ret = opendir_internal(wpath, filename);
+    free(wpath);
+    return ret;
+}
 
-    //
-    // check to see if we've got a directory
-    //
-    if (wstati64(wpath, &sbuf) < 0) {
-	free(wpath);
+DIR *
+rb_w32_uopendir(const char *filename)
+{
+    DIR *ret;
+    WCHAR *wpath = utf8_to_wstr(filename, NULL);
+    if (!wpath)
 	return NULL;
-    }
-    if (!(sbuf.st_mode & S_IFDIR) &&
-	(!ISALPHA(filename[0]) || filename[1] != ':' || filename[2] != '\0' ||
-	 ((1 << ((filename[0] & 0x5f) - 'A')) & GetLogicalDrives()) == 0)) {
-	free(wpath);
-	errno = ENOTDIR;
-	return NULL;
-    }
-    fh = open_dir_handle(wpath, &fd);
+    ret = opendir_internal(wpath, filename);
     free(wpath);
-    return opendir_internal(fh, &fd);
+    return ret;
 }
 
 //
Index: win32/dir.h
===================================================================
--- win32/dir.h	(revision 31371)
+++ win32/dir.h	(revision 31372)
@@ -28,6 +28,7 @@
 
 
 DIR*           rb_w32_opendir(const char*);
+DIR*           rb_w32_uopendir(const char*);
 struct direct* rb_w32_readdir(DIR *);
 struct direct* rb_w32_readdir_with_enc(DIR *, rb_encoding *);
 long           rb_w32_telldir(DIR *);

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]