ruby-changes:48364
From: naruse <ko1@a...>
Date: Fri, 27 Oct 2017 17:40:46 +0900 (JST)
Subject: [ruby-changes:48364] naruse:r60478 (trunk): Revert "Dir.glob with FNM_EXTGLOB is optimized [Feature #13873]"
naruse 2017-10-27 17:40:40 +0900 (Fri, 27 Oct 2017) New Revision: 60478 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=60478 Log: Revert "Dir.glob with FNM_EXTGLOB is optimized [Feature #13873]" This reverts commit r60341,r60342,r60344,r60345. Breaking compabitility of the order of result breaks many tests. To avoid such effort to fix tests, the order should be kept. Modified files: trunk/NEWS trunk/dir.c trunk/spec/ruby/core/dir/shared/glob.rb trunk/test/ruby/test_dir.rb trunk/test/ruby/test_fnmatch.rb Index: dir.c =================================================================== --- dir.c (revision 60477) +++ dir.c (revision 60478) @@ -287,8 +287,6 @@ bracket( https://github.com/ruby/ruby/blob/trunk/dir.c#L287 #define UNESCAPE(p) (escape && *(p) == '\\' ? (p) + 1 : (p)) #define ISEND(p) (!*(p) || (pathname && *(p) == '/')) #define RETURN(val) return *pcur = p, *scur = s, (val); -#define FNMATCH_ALLOC_N(type, n) ((type *)malloc(sizeof(type) * (n))) -#define FNMATCH_FREE(ptr) free(ptr) static int fnmatch_helper( @@ -312,11 +310,8 @@ fnmatch_helper( https://github.com/ruby/ruby/blob/trunk/dir.c#L310 int r; - if (period && *s == '.') { /* leading period */ - int c = *UNESCAPE(p); - if (c != '.' && (!(flags & FNM_EXTGLOB) || c != '{')) RETURN(FNM_NOMATCH); - } - + if (period && *s == '.' && *UNESCAPE(p) != '.') /* leading period */ + RETURN(FNM_NOMATCH); while (1) { switch (*p) { @@ -350,57 +345,6 @@ fnmatch_helper( https://github.com/ruby/ruby/blob/trunk/dir.c#L345 } goto failed; } - - case '{': - if (flags & FNM_EXTGLOB) { - size_t len = pend - p; - char *buf = FNMATCH_ALLOC_N(char, len); - const char *rbrace = NULL; - while (p < pend) { - const char *t = ++p; - int nest = 0; - while (p < pend && !(*p == ',' && nest == 0)) { - if (*p == '{') nest++; - if (*p == '}') { - if (nest == 0) { - if (!rbrace) rbrace = p; - goto rest; - } - nest--; - } - if (*p == '\\' && escape) { - if (++p >= pend) break; - } - Inc(p, pend, enc); - } - if (!rbrace) { - rbrace = p; - while (rbrace < pend && !(*rbrace == '}' && nest == 0)) { - if (*rbrace == '{') nest++; - if (*rbrace == '}') nest--; - if (*rbrace == '\\' && escape) { - if (++p >= pend) break; - } - Inc(rbrace, pend, enc); - } - } - rest: - memcpy(buf, t, p-t); - buf[p-t]=0; - strlcpy(buf+(p-t), rbrace+1, len-(p-t)); - { - const char *pp = buf, *ss = s; - r = fnmatch_helper((const char **)&pp, &ss, flags|FNM_DOTMATCH, enc); - } - if (r == 0) { - p = buf; - FNMATCH_FREE(buf); - RETURN(0); - } - if (p >= rbrace) break; - } - FNMATCH_FREE(buf); - } } /* ordinary */ @@ -1481,12 +1425,6 @@ has_magic(const char *p, const char *pen https://github.com/ruby/ruby/blob/trunk/dir.c#L1425 case '[': return MAGICAL; - case '{': - if (flags & FNM_EXTGLOB) { - return MAGICAL; - } - break; - case '\\': if (escape && p++ >= pend) continue; @@ -2333,13 +2271,6 @@ push_pattern(const char *path, VALUE ary https://github.com/ruby/ruby/blob/trunk/dir.c#L2271 rb_ary_push(ary, name); } -struct push_glob_args { - struct glob_args glob; - int flags; - int fd; -}; -static int push_caller(const char *path, VALUE val, void *enc); - static int ruby_brace_expand(const char *str, int flags, ruby_glob_func *func, VALUE arg, rb_encoding *enc, VALUE var) @@ -2348,7 +2279,7 @@ ruby_brace_expand(const char *str, int f https://github.com/ruby/ruby/blob/trunk/dir.c#L2279 const char *p = str; const char *pend = p + strlen(p); const char *s = p; - const char *lbrace = NULL, *rbrace = NULL; + const char *lbrace = 0, *rbrace = 0; int nest = 0, status = 0; while (*p) { @@ -2367,18 +2298,9 @@ ruby_brace_expand(const char *str, int f https://github.com/ruby/ruby/blob/trunk/dir.c#L2298 if (lbrace && rbrace) { size_t len = strlen(s) + 1; - char *buf; + char *buf = GLOB_ALLOC_N(char, len); long shift; - if (func == push_caller && !strchr(lbrace, '/')) { - /* Now it reaches file basename entry. */ - /* Handle braces in glob_helper */ - struct push_glob_args *a = (struct push_glob_args *)arg; - a->flags |= FNM_EXTGLOB; - return glob_call_func(func, s, arg, enc); - } - - buf = GLOB_ALLOC_N(char, len); if (!buf) return -1; memcpy(buf, s, lbrace-s); shift = (lbrace-s); @@ -2442,6 +2364,12 @@ ruby_brace_glob(const char *str, int fla https://github.com/ruby/ruby/blob/trunk/dir.c#L2364 return ruby_brace_glob_with_enc(str, flags, func, arg, rb_ascii8bit_encoding()); } +struct push_glob_args { + struct glob_args glob; + int flags; + int fd; +}; + static int push_caller(const char *path, VALUE val, void *enc) { Index: NEWS =================================================================== --- NEWS (revision 60477) +++ NEWS (revision 60478) @@ -31,8 +31,6 @@ with all sufficient information, see the https://github.com/ruby/ruby/blob/trunk/NEWS#L31 * Dir.glob provides new optional keyword argument, :base. [Feature #13056] - * Dir.glob with FNM_EXTGLOB is optimized [Feature #13873] - The order of resulted array is changed in some cases. * Dir.children [Feature #11302] * Dir.each_child [Feature #11302] Index: test/ruby/test_dir.rb =================================================================== --- test/ruby/test_dir.rb (revision 60477) +++ test/ruby/test_dir.rb (revision 60478) @@ -144,8 +144,8 @@ class TestDir < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_dir.rb#L144 assert_equal([File.join(@root, '//a')], Dir.glob(@root + '//a')) FileUtils.touch(File.join(@root, "{}")) - assert_equal(%w(a {}).map{|f| File.join(@root, f) }, - Dir.glob(File.join(@root, '{\{\},a}')).sort) + assert_equal(%w({} a).map{|f| File.join(@root, f) }, + Dir.glob(File.join(@root, '{\{\},a}'))) assert_equal([], Dir.glob(File.join(@root, '['))) assert_equal([], Dir.glob(File.join(@root, '[a-\\'))) @@ -154,8 +154,8 @@ class TestDir < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_dir.rb#L154 open(File.join(@root, "}}{}"), "wb") {} open(File.join(@root, "}}a"), "wb") {} - assert_equal(%w(}}{} }}a).map {|f| File.join(@root, f)}.sort, Dir.glob(File.join(@root, '}}{\{\},a}')).sort) - assert_equal(%w(}}{} }}a b c).map {|f| File.join(@root, f)}.sort, Dir.glob(File.join(@root, '{\}\}{\{\},a},b,c}')).sort) + assert_equal(%w(}}{} }}a).map {|f| File.join(@root, f)}, Dir.glob(File.join(@root, '}}{\{\},a}'))) + assert_equal(%w(}}{} }}a b c).map {|f| File.join(@root, f)}, Dir.glob(File.join(@root, '{\}\}{\{\},a},b,c}'))) end def test_glob_recursive Index: test/ruby/test_fnmatch.rb =================================================================== --- test/ruby/test_fnmatch.rb (revision 60477) +++ test/ruby/test_fnmatch.rb (revision 60478) @@ -108,10 +108,6 @@ class TestFnmatch < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_fnmatch.rb#L108 feature5422 = '[ruby-core:40037]' assert_file.for(feature5422).not_fnmatch?( "{.g,t}*", ".gem") assert_file.for(feature5422).fnmatch?("{.g,t}*", ".gem", File::FNM_EXTGLOB) - - assert_file.fnmatch?("{,.}*", ".gem", File::FNM_EXTGLOB) - assert_file.not_fnmatch?("{}*", ".gem", File::FNM_EXTGLOB) - assert_file.not_fnmatch?("{.}*", ".gem") end def test_unmatched_encoding Index: spec/ruby/core/dir/shared/glob.rb =================================================================== --- spec/ruby/core/dir/shared/glob.rb (revision 60477) +++ spec/ruby/core/dir/shared/glob.rb (revision 60478) @@ -221,12 +221,12 @@ describe :dir_glob, shared: true do https://github.com/ruby/ruby/blob/trunk/spec/ruby/core/dir/shared/glob.rb#L221 it "respects the order of {} expressions, expanding left most first" do files = Dir.send(@method, "brace/a{.js,.html}{.erb,.rjs}") - files.sort.should == %w!brace/a.html.erb brace/a.js.rjs! + files.should == %w!brace/a.js.rjs brace/a.html.erb! end it "respects the optional nested {} expressions" do files = Dir.send(@method, "brace/a{.{js,html},}{.{erb,rjs},}") - files.sort.should == %w!brace/a brace/a.erb brace/a.html.erb brace/a.js brace/a.js.rjs! + files.should == %w!brace/a.js.rjs brace/a.js brace/a.html.erb brace/a.erb brace/a! end it "matches special characters by escaping with a backslash with '\\<character>'" do -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/