Skip to content

Commit 60e25e3

Browse files
committed
Moved Dir.glob to dir.rb
1 parent 310054b commit 60e25e3

File tree

2 files changed

+120
-119
lines changed

2 files changed

+120
-119
lines changed

dir.c

+27-119
Original file line numberDiff line numberDiff line change
@@ -2898,6 +2898,28 @@ dir_globs(long argc, const VALUE *argv, VALUE base, int flags)
28982898
return ary;
28992899
}
29002900

2901+
static VALUE
2902+
dir_glob_option_base(VALUE base)
2903+
{
2904+
if (base == Qundef || NIL_P(base)) {
2905+
return Qnil;
2906+
}
2907+
#if USE_OPENDIR_AT
2908+
if (rb_typeddata_is_kind_of(base, &dir_data_type)) {
2909+
return base;
2910+
}
2911+
#endif
2912+
FilePathValue(base);
2913+
if (!RSTRING_LEN(base)) return Qnil;
2914+
return base;
2915+
}
2916+
2917+
static int
2918+
dir_glob_option_sort(VALUE sort)
2919+
{
2920+
return (sort ? 0 : FNM_GLOB_NOSORT);
2921+
}
2922+
29012923
static void
29022924
dir_glob_options(VALUE opt, VALUE *base, int *sort, int *flags)
29032925
{
@@ -2909,19 +2931,7 @@ dir_glob_options(VALUE opt, VALUE *base, int *sort, int *flags)
29092931
kw[2] = rb_intern_const("flags");
29102932
}
29112933
rb_get_kwargs(opt, kw, 0, flags ? 3 : 2, args);
2912-
if (args[0] == Qundef || NIL_P(args[0])) {
2913-
*base = Qnil;
2914-
}
2915-
#if USE_OPENDIR_AT
2916-
else if (rb_typeddata_is_kind_of(args[0], &dir_data_type)) {
2917-
*base = args[0];
2918-
}
2919-
#endif
2920-
else {
2921-
FilePathValue(args[0]);
2922-
if (!RSTRING_LEN(args[0])) args[0] = Qnil;
2923-
*base = args[0];
2924-
}
2934+
*base = dir_glob_option_base(args[0]);
29252935
if (sort && args[1] == Qfalse) *sort |= FNM_GLOB_NOSORT;
29262936
if (flags && args[2] != Qundef) *flags = NUM2INT(args[2]);
29272937
}
@@ -2947,113 +2957,12 @@ dir_s_aref(int argc, VALUE *argv, VALUE obj)
29472957
return dir_globs(argc, argv, base, sort);
29482958
}
29492959

2950-
/*
2951-
* call-seq:
2952-
* Dir.glob( pattern, [flags], [base: path] [, sort: true] ) -> array
2953-
* Dir.glob( pattern, [flags], [base: path] [, sort: true] ) { |filename| block } -> nil
2954-
*
2955-
* Expands +pattern+, which is a pattern string or an Array of pattern
2956-
* strings, and returns an array containing the matching filenames.
2957-
* If a block is given, calls the block once for each matching filename,
2958-
* passing the filename as a parameter to the block.
2959-
*
2960-
* The optional +base+ keyword argument specifies the base directory for
2961-
* interpreting relative pathnames instead of the current working directory.
2962-
* As the results are not prefixed with the base directory name in this
2963-
* case, you will need to prepend the base directory name if you want real
2964-
* paths.
2965-
*
2966-
* The results which matched single wildcard or character set are sorted in
2967-
* binary ascending order, unless false is given as the optional +sort+
2968-
* keyword argument. The order of an Array of pattern strings and braces
2969-
* are preserved.
2970-
*
2971-
* Note that the pattern is not a regexp, it's closer to a shell glob.
2972-
* See File::fnmatch for the meaning of the +flags+ parameter.
2973-
* Case sensitivity depends on your system (File::FNM_CASEFOLD is ignored).
2974-
*
2975-
* <code>*</code>::
2976-
* Matches any file. Can be restricted by other values in the glob.
2977-
* Equivalent to <code>/ .* /mx</code> in regexp.
2978-
*
2979-
* <code>*</code>:: Matches all files
2980-
* <code>c*</code>:: Matches all files beginning with <code>c</code>
2981-
* <code>*c</code>:: Matches all files ending with <code>c</code>
2982-
* <code>\*c\*</code>:: Match all files that have <code>c</code> in them
2983-
* (including at the beginning or end).
2984-
*
2985-
* Note, this will not match Unix-like hidden files (dotfiles). In order
2986-
* to include those in the match results, you must use the
2987-
* File::FNM_DOTMATCH flag or something like <code>"{*,.*}"</code>.
2988-
*
2989-
* <code>**</code>::
2990-
* Matches directories recursively.
2991-
*
2992-
* <code>?</code>::
2993-
* Matches any one character. Equivalent to <code>/.{1}/</code> in regexp.
2994-
*
2995-
* <code>[set]</code>::
2996-
* Matches any one character in +set+. Behaves exactly like character sets
2997-
* in Regexp, including set negation (<code>[^a-z]</code>).
2998-
*
2999-
* <code>{p,q}</code>::
3000-
* Matches either literal <code>p</code> or literal <code>q</code>.
3001-
* Equivalent to pattern alternation in regexp.
3002-
*
3003-
* Matching literals may be more than one character in length. More than
3004-
* two literals may be specified.
3005-
*
3006-
* <code> \\ </code>::
3007-
* Escapes the next metacharacter.
3008-
*
3009-
* Note that this means you cannot use backslash on windows as part of a
3010-
* glob, i.e. <code>Dir["c:\\foo*"]</code> will not work, use
3011-
* <code>Dir["c:/foo*"]</code> instead.
3012-
*
3013-
* Examples:
3014-
*
3015-
* Dir["config.?"] #=> ["config.h"]
3016-
* Dir.glob("config.?") #=> ["config.h"]
3017-
* Dir.glob("*.[a-z][a-z]") #=> ["main.rb"]
3018-
* Dir.glob("*.[^r]*") #=> ["config.h"]
3019-
* Dir.glob("*.{rb,h}") #=> ["main.rb", "config.h"]
3020-
* Dir.glob("*") #=> ["config.h", "main.rb"]
3021-
* Dir.glob("*", File::FNM_DOTMATCH) #=> [".", "..", "config.h", "main.rb"]
3022-
* Dir.glob(["*.rb", "*.h"]) #=> ["main.rb", "config.h"]
3023-
*
3024-
* rbfiles = File.join("**", "*.rb")
3025-
* Dir.glob(rbfiles) #=> ["main.rb",
3026-
* # "lib/song.rb",
3027-
* # "lib/song/karaoke.rb"]
3028-
*
3029-
* Dir.glob(rbfiles, base: "lib") #=> ["song.rb",
3030-
* # "song/karaoke.rb"]
3031-
*
3032-
* libdirs = File.join("**", "lib")
3033-
* Dir.glob(libdirs) #=> ["lib"]
3034-
*
3035-
* librbfiles = File.join("**", "lib", "**", "*.rb")
3036-
* Dir.glob(librbfiles) #=> ["lib/song.rb",
3037-
* # "lib/song/karaoke.rb"]
3038-
*
3039-
* librbfiles = File.join("**", "lib", "*.rb")
3040-
* Dir.glob(librbfiles) #=> ["lib/song.rb"]
3041-
*/
30422960
static VALUE
3043-
dir_s_glob(int argc, VALUE *argv, VALUE obj)
2961+
dir_s_glob(rb_execution_context_t *ec, VALUE obj, VALUE str, VALUE rflags, VALUE base, VALUE sort)
30442962
{
3045-
VALUE str, rflags, ary, opts, base;
3046-
int flags, sort = 0;
3047-
3048-
argc = rb_scan_args(argc, argv, "11:", &str, &rflags, &opts);
3049-
if (argc == 2)
3050-
flags = NUM2INT(rflags);
3051-
else
3052-
flags = 0;
3053-
dir_glob_options(opts, &base, &sort, &flags);
3054-
flags |= sort;
3055-
3056-
ary = rb_check_array_type(str);
2963+
VALUE ary = rb_check_array_type(str);
2964+
const int flags = NUM2INT(rflags) | dir_glob_option_sort(sort);
2965+
base = dir_glob_option_base(base);
30572966
if (NIL_P(ary)) {
30582967
ary = rb_push_glob(str, base, flags);
30592968
}
@@ -3591,7 +3500,6 @@ Init_Dir(void)
35913500
rb_define_singleton_method(rb_cDir,"unlink", dir_s_rmdir, 1);
35923501
rb_define_singleton_method(rb_cDir,"home", dir_s_home, -1);
35933502

3594-
rb_define_singleton_method(rb_cDir,"glob", dir_s_glob, -1);
35953503
rb_define_singleton_method(rb_cDir,"[]", dir_s_aref, -1);
35963504
rb_define_singleton_method(rb_cDir,"exist?", rb_file_directory_p, 1);
35973505
rb_define_singleton_method(rb_cDir,"exists?", rb_dir_exists_p, 1);

dir.rb

+93
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,97 @@ def self.open(name, encoding: nil, &block)
3434
def initialize(name, encoding: nil)
3535
__builtin_dir_initialize(name, encoding)
3636
end
37+
38+
# Dir.glob( pattern, [flags], [base: path] [, sort: true] ) -> array
39+
# Dir.glob( pattern, [flags], [base: path] [, sort: true] ) { |filename| block } -> nil
40+
#
41+
# Expands +pattern+, which is a pattern string or an Array of pattern
42+
# strings, and returns an array containing the matching filenames.
43+
# If a block is given, calls the block once for each matching filename,
44+
# passing the filename as a parameter to the block.
45+
#
46+
# The optional +base+ keyword argument specifies the base directory for
47+
# interpreting relative pathnames instead of the current working directory.
48+
# As the results are not prefixed with the base directory name in this
49+
# case, you will need to prepend the base directory name if you want real
50+
# paths.
51+
#
52+
# The results which matched single wildcard or character set are sorted in
53+
# binary ascending order, unless false is given as the optional +sort+
54+
# keyword argument. The order of an Array of pattern strings and braces
55+
# are preserved.
56+
#
57+
# Note that the pattern is not a regexp, it's closer to a shell glob.
58+
# See File::fnmatch for the meaning of the +flags+ parameter.
59+
# Case sensitivity depends on your system (File::FNM_CASEFOLD is ignored).
60+
#
61+
# <code>*</code>::
62+
# Matches any file. Can be restricted by other values in the glob.
63+
# Equivalent to <code>/ .* /mx</code> in regexp.
64+
#
65+
# <code>*</code>:: Matches all files
66+
# <code>c*</code>:: Matches all files beginning with <code>c</code>
67+
# <code>*c</code>:: Matches all files ending with <code>c</code>
68+
# <code>\*c\*</code>:: Match all files that have <code>c</code> in them
69+
# (including at the beginning or end).
70+
#
71+
# Note, this will not match Unix-like hidden files (dotfiles). In order
72+
# to include those in the match results, you must use the
73+
# File::FNM_DOTMATCH flag or something like <code>"{*,.*}"</code>.
74+
#
75+
# <code>**</code>::
76+
# Matches directories recursively.
77+
#
78+
# <code>?</code>::
79+
# Matches any one character. Equivalent to <code>/.{1}/</code> in regexp.
80+
#
81+
# <code>[set]</code>::
82+
# Matches any one character in +set+. Behaves exactly like character sets
83+
# in Regexp, including set negation (<code>[^a-z]</code>).
84+
#
85+
# <code>{p,q}</code>::
86+
# Matches either literal <code>p</code> or literal <code>q</code>.
87+
# Equivalent to pattern alternation in regexp.
88+
#
89+
# Matching literals may be more than one character in length. More than
90+
# two literals may be specified.
91+
#
92+
# <code> \\ </code>::
93+
# Escapes the next metacharacter.
94+
#
95+
# Note that this means you cannot use backslash on windows as part of a
96+
# glob, i.e. <code>Dir["c:\\foo*"]</code> will not work, use
97+
# <code>Dir["c:/foo*"]</code> instead.
98+
#
99+
# Examples:
100+
#
101+
# Dir["config.?"] #=> ["config.h"]
102+
# Dir.glob("config.?") #=> ["config.h"]
103+
# Dir.glob("*.[a-z][a-z]") #=> ["main.rb"]
104+
# Dir.glob("*.[^r]*") #=> ["config.h"]
105+
# Dir.glob("*.{rb,h}") #=> ["main.rb", "config.h"]
106+
# Dir.glob("*") #=> ["config.h", "main.rb"]
107+
# Dir.glob("*", File::FNM_DOTMATCH) #=> [".", "..", "config.h", "main.rb"]
108+
# Dir.glob(["*.rb", "*.h"]) #=> ["main.rb", "config.h"]
109+
#
110+
# rbfiles = File.join("**", "*.rb")
111+
# Dir.glob(rbfiles) #=> ["main.rb",
112+
# # "lib/song.rb",
113+
# # "lib/song/karaoke.rb"]
114+
#
115+
# Dir.glob(rbfiles, base: "lib") #=> ["song.rb",
116+
# # "song/karaoke.rb"]
117+
#
118+
# libdirs = File.join("**", "lib")
119+
# Dir.glob(libdirs) #=> ["lib"]
120+
#
121+
# librbfiles = File.join("**", "lib", "**", "*.rb")
122+
# Dir.glob(librbfiles) #=> ["lib/song.rb",
123+
# # "lib/song/karaoke.rb"]
124+
#
125+
# librbfiles = File.join("**", "lib", "*.rb")
126+
# Dir.glob(librbfiles) #=> ["lib/song.rb"]
127+
def self.glob(pattern, _flags = 0, flags: _flags, base: nil, sort: true)
128+
__builtin_dir_s_glob(pattern, flags, base, sort)
129+
end
37130
end

0 commit comments

Comments
 (0)