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

ruby-changes:30787

From: ktsj <ko1@a...>
Date: Sat, 7 Sep 2013 13:34:33 +0900 (JST)
Subject: [ruby-changes:30787] ktsj:r42866 (trunk): * lib/find.rb (Find.find): respect the encodings of arguments.

ktsj	2013-09-07 13:34:27 +0900 (Sat, 07 Sep 2013)

  New Revision: 42866

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

  Log:
    * lib/find.rb (Find.find): respect the encodings of arguments.
      [ruby-dev:47530] [Feature #8657]
    
    * test/test_find.rb: add tests.

  Modified files:
    trunk/ChangeLog
    trunk/lib/find.rb
    trunk/test/test_find.rb
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 42865)
+++ ChangeLog	(revision 42866)
@@ -1,3 +1,10 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Sat Sep  7 13:29:22 2013  Kazuki Tsujimoto  <kazuki@c...>
+
+	* lib/find.rb (Find.find): respect the encodings of arguments.
+	  [ruby-dev:47530] [Feature #8657]
+
+	* test/test_find.rb: add tests.
+
 Sat Sep  7 10:40:32 2013  Tanaka Akira  <akr@f...>
 
 	* ext/socket/mkconstants.rb (TCP_FASTOPEN): Defined for TCP fast open.
Index: lib/find.rb
===================================================================
--- lib/find.rb	(revision 42865)
+++ lib/find.rb	(revision 42866)
@@ -37,30 +37,36 @@ module Find https://github.com/ruby/ruby/blob/trunk/lib/find.rb#L37
   def find(*paths) # :yield: path
     block_given? or return enum_for(__method__, *paths)
 
-    paths.collect!{|d| raise Errno::ENOENT unless File.exist?(d); d.dup}
-    while file = paths.shift
-      catch(:prune) do
-        yield file.dup.taint
-        begin
-          s = File.lstat(file)
-        rescue Errno::ENOENT, Errno::EACCES, Errno::ENOTDIR, Errno::ELOOP, Errno::ENAMETOOLONG
-          next
-        end
-        if s.directory? then
+    fs_encoding = Encoding.find("filesystem")
+
+    paths.collect!{|d| raise Errno::ENOENT unless File.exist?(d); d.dup}.each do |path|
+      enc = path.encoding == Encoding::US_ASCII ? fs_encoding : path.encoding
+      ps = [path]
+      while file = ps.shift
+        catch(:prune) do
+          yield file.dup.taint
           begin
-            fs = Dir.entries(file)
+            s = File.lstat(file)
           rescue Errno::ENOENT, Errno::EACCES, Errno::ENOTDIR, Errno::ELOOP, Errno::ENAMETOOLONG
             next
           end
-          fs.sort!
-          fs.reverse_each {|f|
-            next if f == "." or f == ".."
-            f = File.join(file, f)
-            paths.unshift f.untaint
-          }
+          if s.directory? then
+            begin
+              fs = Dir.entries(file, encoding: enc)
+            rescue Errno::ENOENT, Errno::EACCES, Errno::ENOTDIR, Errno::ELOOP, Errno::ENAMETOOLONG
+              next
+            end
+            fs.sort!
+            fs.reverse_each {|f|
+              next if f == "." or f == ".."
+              f = File.join(file, f)
+              ps.unshift f.untaint
+            }
+          end
         end
       end
     end
+    nil
   end
 
   #
Index: test/test_find.rb
===================================================================
--- test/test_find.rb	(revision 42865)
+++ test/test_find.rb	(revision 42866)
@@ -210,6 +210,40 @@ class TestFind < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/test_find.rb#L210
     }
   end
 
+  def test_encoding_ascii
+    Dir.mktmpdir {|d|
+      File.open("#{d}/a", "w"){}
+      Dir.mkdir("#{d}/b")
+      a = []
+      Find.find(d.encode(Encoding::US_ASCII)) {|f| a << f }
+      a.each do |i|
+        assert(Encoding.compatible?(d.encode(Encoding.find('filesystem')), i))
+      end
+    }
+  end
+
+  def test_encoding_non_ascii
+    Dir.mktmpdir {|d|
+      File.open("#{d}/a", "w"){}
+      Dir.mkdir("#{d}/b")
+      euc_jp = Encoding::EUC_JP
+      win_31j = Encoding::Windows_31J
+      utf_8 = Encoding::UTF_8
+      a = []
+      Find.find(d.encode(euc_jp), d.encode(win_31j), d.encode(utf_8)) {|f| a << [f, f.encoding] }
+      assert_equal([[d, euc_jp], ["#{d}/a", euc_jp], ["#{d}/b", euc_jp],
+                    [d, win_31j], ["#{d}/a", win_31j], ["#{d}/b", win_31j],
+                    [d, utf_8], ["#{d}/a", utf_8], ["#{d}/b", utf_8]],
+                   a)
+      if /mswin|mingw/ =~ RUBY_PLATFORM
+        a = []
+        Dir.mkdir("#{d}/\u{2660}")
+        Find.find("#{d}".encode(utf_8)) {|f| a << [f, f.encoding] }
+        assert_equal([[d, utf_8], ["#{d}/a", utf_8], ["#{d}/b", utf_8], ["#{d}/\u{2660}", utf_8]], a)
+      end
+    }
+  end
+
   class TestInclude < Test::Unit::TestCase
     include Find
 

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

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