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

ruby-changes:32728

From: nobu <ko1@a...>
Date: Tue, 4 Feb 2014 17:20:11 +0900 (JST)
Subject: [ruby-changes:32728] nobu:r44807 (trunk): dir.c: glob cases on case-insensitive system

nobu	2014-02-04 17:20:05 +0900 (Tue, 04 Feb 2014)

  New Revision: 44807

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

  Log:
    dir.c: glob cases on case-insensitive system
    
    * dir.c (glob_helper): return the filename with actual cases on
      the filesystem if it is case-insensitive.  [ruby-core:42469]
      [Feature #5994]

  Modified files:
    trunk/ChangeLog
    trunk/dir.c
    trunk/lib/mkmf.rb
    trunk/test/ruby/test_dir.rb
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 44806)
+++ ChangeLog	(revision 44807)
@@ -1,3 +1,9 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Tue Feb  4 17:20:03 2014  Nobuyoshi Nakada  <nobu@r...>
+
+	* dir.c (glob_helper): return the filename with actual cases on
+	  the filesystem if it is case-insensitive.  [ruby-core:42469]
+	  [Feature #5994]
+
 Tue Feb  4 16:16:58 2014  Koichi Sasada  <ko1@a...>
 
 	* string.c: use STR_SHARED instead of ELTS_SHARED.
Index: lib/mkmf.rb
===================================================================
--- lib/mkmf.rb	(revision 44806)
+++ lib/mkmf.rb	(revision 44807)
@@ -71,7 +71,7 @@ module MakeMakefile https://github.com/ruby/ruby/blob/trunk/lib/mkmf.rb#L71
   # Extensions for files complied with a C++ compiler
 
   CXX_EXT = %w[cc mm cxx cpp]
-  if File::FNM_SYSCASE.zero?
+  unless File.exist?(File.join(*File.split(__FILE__).tap {|d, b| b.swapcase}))
     CXX_EXT.concat(%w[C])
   end
 
Index: dir.c
===================================================================
--- dir.c	(revision 44806)
+++ dir.c	(revision 44807)
@@ -1210,10 +1210,10 @@ glob_make_pattern(const char *p, const c https://github.com/ruby/ruby/blob/trunk/dir.c#L1210
 	}
 	else {
 	    const char *m = find_dirsep(p, e, flags, enc);
-	    const int magic = FNM_SYSCASE || HAVE_HFS || has_magic(p, m, flags, enc);
+	    const int magic = has_magic(p, m, flags, enc);
 	    char *buf;
 
-	    if (!magic && !recursive && *m) {
+	    if (!(FNM_SYSCASE || HAVE_HFS || magic) && !recursive && *m) {
 		const char *m2;
 		while (!has_magic(m+1, m2 = find_dirsep(m+1, e, flags, enc), flags, enc) &&
 		       *m2) {
@@ -1397,14 +1397,29 @@ glob_helper( https://github.com/ruby/ruby/blob/trunk/dir.c#L1397
 
     if (exist == NO || isdir == NO) return 0;
 
-    if (magical || recursive) {
+    if (magical || recursive || ((FNM_SYSCASE || HAVE_HFS) && plain)) {
 	struct dirent *dp;
 	DIR *dirp;
 	IF_HAVE_HFS(int hfs_p);
 	dirp = do_opendir(*path ? path : ".", flags, enc);
-	if (dirp == NULL) return 0;
+	if (dirp == NULL) {
+# if FNM_SYSCASE || HAVE_HFS
+	    if (!(magical || recursive) && (errno == EACCES)) {
+		/* no read permission, fallback */
+		goto literally;
+	    }
+# endif
+	    return 0;
+	}
 	IF_HAVE_HFS(hfs_p = is_hfs(dirp));
 
+# if HAVE_HFS
+	if (!(hfs_p || magical || recursive)) {
+	    closedir(dirp);
+	    goto literally;
+	}
+	flags |= FNM_CASEFOLD;
+# endif
 	while ((dp = READDIR(dirp, enc)) != NULL) {
 	    char *buf;
 	    enum answer new_isdir = UNKNOWN;
@@ -1486,6 +1501,9 @@ glob_helper( https://github.com/ruby/ruby/blob/trunk/dir.c#L1501
     else if (plain) {
 	struct glob_pattern **copy_beg, **copy_end, **cur2;
 
+# if FNM_SYSCASE || HAVE_HFS
+      literally:
+# endif
 	copy_beg = copy_end = GLOB_ALLOC_N(struct glob_pattern *, end - beg);
 	if (!copy_beg) return -1;
 	for (cur = beg; cur < end; ++cur)
Index: test/ruby/test_dir.rb
===================================================================
--- test/ruby/test_dir.rb	(revision 44806)
+++ test/ruby/test_dir.rb	(revision 44807)
@@ -228,6 +228,27 @@ class TestDir < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_dir.rb#L228
     assert_empty(Dir.glob(File.join(@root, "<")), bug8597)
   end
 
+  def test_glob_cases
+    feature5994 = "[ruby-core:42469] [Feature #5994]"
+    feature5994 << "\nDir.glob should return the filename with actual cases on the filesystem"
+    Dir.chdir(File.join(@root, "a")) do
+      open("FileWithCases", "w") {}
+      return unless File.exist?("filewithcases")
+      assert_equal(%w"FileWithCases", Dir.glob("filewithcases"), feature5994)
+    end
+    Dir.chdir(File.join(@root, "c")) do
+      open("FileWithCases", "w") {}
+      mode = File.stat(".").mode
+      begin
+        File.chmod(mode & ~0444, ".")
+        return if mode == File.stat(".").mode
+        assert_equal(%w"filewithcases", Dir.glob("filewithcases"), feature5994)
+      ensure
+        File.chmod(mode, ".")
+      end
+    end
+  end
+
   def test_home
     env_home = ENV["HOME"]
     env_logdir = ENV["LOGDIR"]

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

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