ruby-changes:25406
From: nobu <ko1@a...>
Date: Sun, 4 Nov 2012 10:19:43 +0900 (JST)
Subject: [ruby-changes:25406] nobu:r37463 (trunk): dir.c: FNM_EXTGLOB
nobu 2012-11-04 10:19:11 +0900 (Sun, 04 Nov 2012) New Revision: 37463 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=37463 Log: dir.c: FNM_EXTGLOB * dir.c (file_s_fnmatch): match with expanding braces if FNM_EXTGLOB is set. [ruby-core:40037] [Feature #5422] Modified files: trunk/ChangeLog trunk/NEWS trunk/dir.c trunk/test/ruby/envutil.rb trunk/test/ruby/test_fnmatch.rb Index: ChangeLog =================================================================== --- ChangeLog (revision 37462) +++ ChangeLog (revision 37463) @@ -1,3 +1,8 @@ +Sun Nov 4 10:19:03 2012 Nobuyoshi Nakada <nobu@r...> + + * dir.c (file_s_fnmatch): match with expanding braces if FNM_EXTGLOB + is set. [ruby-core:40037] [Feature #5422] + Sat Nov 3 23:38:15 2012 Tadayoshi Funaba <tadf@d...> * complex.c: modified doc. Index: dir.c =================================================================== --- dir.c (revision 37462) +++ dir.c (revision 37463) @@ -85,6 +85,7 @@ #define FNM_PATHNAME 0x02 #define FNM_DOTMATCH 0x04 #define FNM_CASEFOLD 0x08 +#define FNM_EXTGLOB 0x10 #if CASEFOLD_FILESYSTEM #define FNM_SYSCASE FNM_CASEFOLD #else @@ -1912,6 +1913,15 @@ return rb_ensure(rb_Array, dir, dir_close, dir); } +static int +fnmatch_brace(const char *pattern, VALUE val, void *enc) +{ + struct brace_args *arg = (struct brace_args *)val; + VALUE path = arg->value; + + return (fnmatch(pattern, enc, RSTRING_PTR(path), arg->flags) == 0); +} + /* * call-seq: * File.fnmatch( pattern, path, [flags] ) -> (true or false) @@ -2008,10 +2018,22 @@ StringValue(pattern); FilePathStringValue(path); - if (fnmatch(RSTRING_PTR(pattern), rb_enc_get(pattern), RSTRING_PTR(path), - flags) == 0) - return Qtrue; + if (flags & FNM_EXTGLOB) { + struct brace_args args; + args.value = path; + args.flags = flags; + if (ruby_brace_expand(RSTRING_PTR(pattern), flags, fnmatch_brace, + (VALUE)&args, rb_enc_get(pattern)) > 0) + return Qtrue; + } + else { + if (fnmatch(RSTRING_PTR(pattern), rb_enc_get(pattern), RSTRING_PTR(path), + flags) == 0) + return Qtrue; + } + RB_GC_GUARD(pattern); + return Qfalse; } @@ -2111,5 +2133,6 @@ rb_file_const("FNM_PATHNAME", INT2FIX(FNM_PATHNAME)); rb_file_const("FNM_DOTMATCH", INT2FIX(FNM_DOTMATCH)); rb_file_const("FNM_CASEFOLD", INT2FIX(FNM_CASEFOLD)); + rb_file_const("FNM_EXTGLOB", INT2FIX(FNM_EXTGLOB)); rb_file_const("FNM_SYSCASE", INT2FIX(FNM_SYSCASE)); } Index: NEWS =================================================================== --- NEWS (revision 37462) +++ NEWS (revision 37463) @@ -31,6 +31,11 @@ * aliased method: * ENV.to_h is a new alias for ENV.to_hash + * File: + * extended method: + * File.fnmatch? now expands braces in the pattern if + File::FNM_EXTGLOB option is given. + * Hash * added method: * added Hash#to_h as explicit conversion method, like Array#to_a. Index: test/ruby/test_fnmatch.rb =================================================================== --- test/ruby/test_fnmatch.rb (revision 37462) +++ test/ruby/test_fnmatch.rb (revision 37463) @@ -1,4 +1,5 @@ require 'test/unit' +require_relative 'envutil' class TestFnmatch < Test::Unit::TestCase @@ -103,4 +104,9 @@ assert(File.fnmatch('**/foo', 'c:/root/foo', File::FNM_PATHNAME)) end + def test_extglob + feature5422 = '[ruby-core:40037]' + assert_file.for(feature5422).not_fnmatch?( "{.g,t}*", ".gem") + assert_file.for(feature5422).fnmatch?("{.g,t}*", ".gem", File::FNM_EXTGLOB) + end end Index: test/ruby/envutil.rb =================================================================== --- test/ruby/envutil.rb (revision 37462) +++ test/ruby/envutil.rb (revision 37463) @@ -229,7 +229,7 @@ AssertFile end - class << (AssertFile = Object.new) + class << (AssertFile = Struct.new(:message).new) include Assertions def assert_file_predicate(predicate, *args) if /\Anot_/ =~ predicate @@ -241,9 +241,14 @@ mesg = "Expected file " << args.shift.inspect mesg << mu_pp(args) unless args.empty? mesg << "#{neg} to be #{predicate}" + mesg << " #{message}" if message assert(result, mesg) end alias method_missing assert_file_predicate + + def for(message) + clone.tap {|a| a.message = message} + end end end end -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/