summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS.md8
-rw-r--r--dir.c242
-rw-r--r--test/ruby/test_dir.rb101
3 files changed, 294 insertions, 57 deletions
diff --git a/NEWS.md b/NEWS.md
index 1c0feb6560..a53f4f22a4 100644
--- a/NEWS.md
+++ b/NEWS.md
@@ -14,6 +14,13 @@ sufficient information, see the ChangeLog file or Redmine
## Core classes updates (outstanding ones only)
+* Dir
+
+ * Modified method
+
+ * Dir.glob and Dir.[] now sort the results by default, and
+ accept `sort:` keyword option. [[Feature #8709]]
+
* Hash
* Modified method
@@ -46,6 +53,7 @@ sufficient information, see the ChangeLog file or Redmine
## Miscellaneous changes
+[Feature #8709]: https://bugs.ruby-lang.org/issues/8709
[Feature #8948]: https://bugs.ruby-lang.org/issues/8948
[Feature #16274]: https://bugs.ruby-lang.org/issues/16274
[Feature #16377]: https://bugs.ruby-lang.org/issues/16377
diff --git a/dir.c b/dir.c
index 6734559a0b..d54ba646e4 100644
--- a/dir.c
+++ b/dir.c
@@ -219,6 +219,7 @@ typedef enum {
#else
#define FNM_SHORTNAME 0
#endif
+#define FNM_GLOB_NOSORT 0x40
#define FNM_NOMATCH 1
#define FNM_ERROR 2
@@ -1350,21 +1351,34 @@ sys_enc_warning_in(const char *func, const char *mesg, rb_encoding *enc)
#define sys_warning(val, enc) \
((flags & GLOB_VERBOSE) ? sys_enc_warning_in(RUBY_FUNCTION_NAME_STRING, (val), (enc)) :(void)0)
-static inline void *
-glob_alloc_n(size_t x, size_t y)
+static inline size_t
+glob_alloc_size(size_t x, size_t y)
{
size_t z;
if (rb_mul_size_overflow(x, y, SSIZE_MAX, &z)) {
rb_memerror(); /* or...? */
}
else {
- return malloc(z);
+ return z;
}
}
+static inline void *
+glob_alloc_n(size_t x, size_t y)
+{
+ return malloc(glob_alloc_size(x, y));
+}
+
+static inline void *
+glob_realloc_n(void *p, size_t x, size_t y)
+{
+ return realloc(p, glob_alloc_size(x, y));
+}
+
#define GLOB_ALLOC(type) ((type *)malloc(sizeof(type)))
#define GLOB_ALLOC_N(type, n) ((type *)glob_alloc_n(sizeof(type), n))
#define GLOB_REALLOC(ptr, size) realloc((ptr), (size))
+#define GLOB_REALLOC_N(ptr, n) glob_realloc_n(ptr, sizeof(*(ptr)), n)
#define GLOB_FREE(ptr) free(ptr)
#define GLOB_JUMP_TAG(status) (((status) == -1) ? rb_memerror() : rb_jump_tag(status))
@@ -2016,8 +2030,17 @@ rb_glob_error(const char *path, VALUE a, const void *enc, int error)
return status;
}
+typedef struct rb_dirent {
+ long d_namlen;
+ const char *d_name;
+#ifdef _WIN32
+ const char *d_altname;
+#endif
+ uint8_t d_type;
+} rb_dirent_t;
+
static inline int
-dirent_match(const char *pat, rb_encoding *enc, const char *name, const struct dirent *dp, int flags)
+dirent_match(const char *pat, rb_encoding *enc, const char *name, const rb_dirent_t *dp, int flags)
{
if (fnmatch(pat, enc, name, flags) == 0) return 1;
#ifdef _WIN32
@@ -2042,7 +2065,7 @@ struct push_glob_args {
struct dirent_brace_args {
const char *name;
- const struct dirent *dp;
+ const rb_dirent_t *dp;
int flags;
};
@@ -2105,6 +2128,154 @@ 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);
+static const size_t rb_dirent_name_offset =
+ offsetof(rb_dirent_t, d_type) + sizeof(uint8_t);
+
+static rb_dirent_t *
+dirent_copy(const struct dirent *dp, rb_dirent_t *rdp)
+{
+ if (!dp) return NULL;
+ size_t namlen = NAMLEN(dp);
+ const size_t altlen =
+#ifdef _WIN32
+ dp->d_altlen ? dp->d_altlen + 1 :
+#endif
+ 0;
+ rb_dirent_t *newrdp = rdp;
+ if (!rdp && !(newrdp = malloc(rb_dirent_name_offset + namlen + 1 + altlen)))
+ return NULL;
+ newrdp->d_namlen = namlen;
+ if (!rdp) {
+ char *name = (char *)newrdp + rb_dirent_name_offset;
+ memcpy(name, dp->d_name, namlen);
+ name[namlen] = '\0';
+#ifdef _WIN32
+ newrdp->d_altname = NULL;
+ if (altlen) {
+ char *const altname = name + namlen + 1;
+ memcpy(altname, dp->d_altname, altlen - 1);
+ altname[altlen - 1] = '\0';
+ newrdp->d_altname = altname;
+ }
+#endif
+ newrdp->d_name = name;
+ }
+ else {
+ newrdp->d_name = dp->d_name;
+#ifdef _WIN32
+ newrdp->d_altname = dp->d_altname;
+#endif
+ }
+#ifdef DT_UNKNOWN
+ newrdp->d_type = dp->d_type;
+#else
+ newrdp->d_type = 0;
+#endif
+ return newrdp;
+}
+
+typedef union {
+ struct {
+ DIR *dirp;
+ rb_dirent_t ent;
+ } nosort;
+ struct {
+ size_t count, idx;
+ rb_dirent_t **entries;
+ } sort;
+} ruby_glob_entries_t;
+
+static int
+glob_sort_cmp(const void *a, const void *b, void *e)
+{
+ const rb_dirent_t *ent1 = *(void **)a;
+ const rb_dirent_t *ent2 = *(void **)b;
+ return strcmp(ent1->d_name, ent2->d_name);
+}
+
+static void
+glob_dir_finish(ruby_glob_entries_t *ent, int flags)
+{
+ if (flags & FNM_GLOB_NOSORT) {
+ closedir(ent->nosort.dirp);
+ ent->nosort.dirp = NULL;
+ }
+ else if (ent->sort.entries) {
+ for (size_t i = 0, count = ent->sort.count; i < count;) {
+ GLOB_FREE(ent->sort.entries[i++]);
+ }
+ GLOB_FREE(ent->sort.entries);
+ ent->sort.entries = NULL;
+ ent->sort.count = ent->sort.idx = 0;
+ }
+}
+
+static ruby_glob_entries_t *
+glob_opendir(ruby_glob_entries_t *ent, DIR *dirp, int flags, rb_encoding *enc)
+{
+ MEMZERO(ent, ruby_glob_entries_t, 1);
+ if (flags & FNM_GLOB_NOSORT) {
+ ent->nosort.dirp = dirp;
+ }
+ else {
+ void *newp;
+ struct dirent *dp;
+ size_t count = 0, capacity = 0;
+ ent->sort.count = 0;
+ ent->sort.idx = 0;
+ ent->sort.entries = 0;
+#ifdef _WIN32
+ if ((capacity = dirp->nfiles) > 0) {
+ if (!(newp = GLOB_ALLOC_N(rb_dirent_t, capacity))) {
+ closedir(dirp);
+ return NULL;
+ }
+ ent->sort.entries = newp;
+ }
+#endif
+ while ((dp = READDIR(dirp, enc)) != NULL) {
+ rb_dirent_t *rdp = dirent_copy(dp, NULL);
+ if (!rdp) {
+ nomem:
+ glob_dir_finish(ent, 0);
+ closedir(dirp);
+ return NULL;
+ }
+ if (count >= capacity) {
+ capacity += 256;
+ if (!(newp = GLOB_REALLOC_N(ent->sort.entries, capacity)))
+ goto nomem;
+ ent->sort.entries = newp;
+ }
+ ent->sort.entries[count++] = rdp;
+ ent->sort.count = count;
+ }
+ closedir(dirp);
+ if (count < capacity) {
+ if (!(newp = GLOB_REALLOC_N(ent->sort.entries, count)))
+ goto nomem;
+ ent->sort.entries = newp;
+ }
+ ruby_qsort(ent->sort.entries, ent->sort.count, sizeof(ent->sort.entries[0]),
+ glob_sort_cmp, NULL);
+ }
+ return ent;
+}
+
+static rb_dirent_t *
+glob_getent(ruby_glob_entries_t *ent, int flags, rb_encoding *enc)
+{
+ if (flags & FNM_GLOB_NOSORT) {
+ return dirent_copy(READDIR(ent->nosort.dirp, enc), &ent->nosort.ent);
+ }
+ else if (ent->sort.idx < ent->sort.count) {
+ return ent->sort.entries[ent->sort.idx++];
+ }
+ else {
+ return NULL;
+ }
+}
+
static int
glob_helper(
int fd,
@@ -2217,7 +2388,7 @@ glob_helper(
if (pathtype == path_noent) return 0;
if (magical || recursive) {
- struct dirent *dp;
+ rb_dirent_t *dp;
DIR *dirp;
# if USE_NAME_ON_FS == USE_NAME_ON_FS_BY_FNMATCH
char *plainname = 0;
@@ -2256,7 +2427,18 @@ glob_helper(
if (is_case_sensitive(dirp, path) == 0)
flags |= FNM_CASEFOLD;
# endif
- while ((dp = READDIR(dirp, enc)) != NULL) {
+ ruby_glob_entries_t globent;
+ if (!glob_opendir(&globent, dirp, flags, enc)) {
+ status = 0;
+ if (funcs->error) {
+ status = (*funcs->error)(path, arg, enc, ENOMEM);
+ }
+ else {
+ sys_warning(path, enc);
+ }
+ return status;
+ }
+ while ((dp = glob_getent(&globent, flags, enc)) != NULL) {
char *buf;
rb_pathtype_t new_pathtype = path_unknown;
const char *name;
@@ -2265,7 +2447,7 @@ glob_helper(
IF_NORMALIZE_UTF8PATH(VALUE utf8str = Qnil);
name = dp->d_name;
- namlen = NAMLEN(dp);
+ namlen = dp->d_namlen;
if (recursive && name[0] == '.') {
++dotfile;
if (namlen == 1) {
@@ -2360,7 +2542,7 @@ glob_helper(
if (status) break;
}
- closedir(dirp);
+ glob_dir_finish(&globent, flags);
}
else if (plain) {
struct glob_pattern **copy_beg, **copy_end, **cur2;
@@ -2753,15 +2935,16 @@ dir_globs(long argc, const VALUE *argv, VALUE base, int flags)
}
static void
-dir_glob_options(VALUE opt, VALUE *base, int *flags)
+dir_glob_options(VALUE opt, VALUE *base, int *sort, int *flags)
{
- static ID kw[2];
- VALUE args[2];
+ static ID kw[3];
+ VALUE args[3];
if (!kw[0]) {
kw[0] = rb_intern_const("base");
- kw[1] = rb_intern_const("flags");
+ kw[1] = rb_intern_const("sort");
+ kw[2] = rb_intern_const("flags");
}
- rb_get_kwargs(opt, kw, 0, flags ? 2 : 1, args);
+ rb_get_kwargs(opt, kw, 0, flags ? 3 : 2, args);
if (args[0] == Qundef || NIL_P(args[0])) {
*base = Qnil;
}
@@ -2775,14 +2958,13 @@ dir_glob_options(VALUE opt, VALUE *base, int *flags)
if (!RSTRING_LEN(args[0])) args[0] = Qnil;
*base = args[0];
}
- if (flags && args[1] != Qundef) {
- *flags = NUM2INT(args[1]);
- }
+ if (sort && args[1] == Qfalse) *sort |= FNM_GLOB_NOSORT;
+ if (flags && args[2] != Qundef) *flags = NUM2INT(args[2]);
}
/*
* call-seq:
- * Dir[ string [, string ...] [, base: path] ] -> array
+ * Dir[ string [, string ...] [, base: path] [, sort: true] ] -> array
*
* Equivalent to calling
* <code>Dir.glob([</code><i>string,...</i><code>], 0)</code>.
@@ -2792,18 +2974,19 @@ static VALUE
dir_s_aref(int argc, VALUE *argv, VALUE obj)
{
VALUE opts, base;
+ int sort = 0;
argc = rb_scan_args(argc, argv, "*:", NULL, &opts);
- dir_glob_options(opts, &base, NULL);
+ dir_glob_options(opts, &base, &sort, NULL);
if (argc == 1) {
- return rb_push_glob(argv[0], base, 0);
+ return rb_push_glob(argv[0], base, sort);
}
- return dir_globs(argc, argv, base, 0);
+ return dir_globs(argc, argv, base, sort);
}
/*
* call-seq:
- * Dir.glob( pattern, [flags], [base: path] ) -> array
- * Dir.glob( pattern, [flags], [base: path] ) { |filename| block } -> nil
+ * Dir.glob( pattern, [flags], [base: path] [, sort: true] ) -> array
+ * Dir.glob( pattern, [flags], [base: path] [, sort: true] ) { |filename| block } -> nil
*
* Expands +pattern+, which is a pattern string or an Array of pattern
* strings, and returns an array containing the matching filenames.
@@ -2816,10 +2999,14 @@ dir_s_aref(int argc, VALUE *argv, VALUE obj)
* case, you will need to prepend the base directory name if you want real
* paths.
*
+ * The results which matched single wildcard or character set are sorted in
+ * binary ascending order, unless false is given as the optional +sort+
+ * keyword argument. The order of an Array of pattern strings and braces
+ * are preserved.
+ *
* Note that the pattern is not a regexp, it's closer to a shell glob.
* See File::fnmatch for the meaning of the +flags+ parameter.
- * Case sensitivity depends on your system (File::FNM_CASEFOLD is ignored),
- * as does the order in which the results are returned.
+ * Case sensitivity depends on your system (File::FNM_CASEFOLD is ignored).
*
* <code>*</code>::
* Matches any file. Can be restricted by other values in the glob.
@@ -2892,14 +3079,15 @@ static VALUE
dir_s_glob(int argc, VALUE *argv, VALUE obj)
{
VALUE str, rflags, ary, opts, base;
- int flags;
+ int flags, sort = 0;
argc = rb_scan_args(argc, argv, "11:", &str, &rflags, &opts);
if (argc == 2)
flags = NUM2INT(rflags);
else
flags = 0;
- dir_glob_options(opts, &base, &flags);
+ dir_glob_options(opts, &base, &sort, &flags);
+ flags |= sort;
ary = rb_check_array_type(str);
if (NIL_P(ary)) {
diff --git a/test/ruby/test_dir.rb b/test/ruby/test_dir.rb
index 29d5bc1540..bab23302f7 100644
--- a/test/ruby/test_dir.rb
+++ b/test/ruby/test_dir.rb
@@ -136,15 +136,17 @@ class TestDir < Test::Unit::TestCase
def test_glob
assert_equal((%w(. ..) + ("a".."z").to_a).map{|f| File.join(@root, f) },
- Dir.glob(File.join(@root, "*"), File::FNM_DOTMATCH).sort)
+ Dir.glob(File.join(@root, "*"), File::FNM_DOTMATCH))
assert_equal([@root] + ("a".."z").map {|f| File.join(@root, f) },
- Dir.glob([@root, File.join(@root, "*")]).sort)
+ Dir.glob([@root, File.join(@root, "*")]))
+ assert_equal([@root] + ("a".."z").map {|f| File.join(@root, f) },
+ Dir.glob([@root, File.join(@root, "*")], sort: false).sort)
assert_raise_with_message(ArgumentError, /nul-separated/) do
Dir.glob(@root + "\0\0\0" + File.join(@root, "*"))
end
assert_equal(("a".."z").step(2).map {|f| File.join(File.join(@root, f), "") },
- Dir.glob(File.join(@root, "*/")).sort)
+ Dir.glob(File.join(@root, "*/")))
assert_equal([File.join(@root, '//a')], Dir.glob(@root + '//a'))
FileUtils.touch(File.join(@root, "{}"))
@@ -154,7 +156,7 @@ class TestDir < Test::Unit::TestCase
assert_equal([], Dir.glob(File.join(@root, '[a-\\')))
assert_equal([File.join(@root, "a")], Dir.glob(File.join(@root, 'a\\')))
- assert_equal(("a".."f").map {|f| File.join(@root, f) }, Dir.glob(File.join(@root, '[abc/def]')).sort)
+ assert_equal(("a".."f").map {|f| File.join(@root, f) }, Dir.glob(File.join(@root, '[abc/def]')))
open(File.join(@root, "}}{}"), "wb") {}
open(File.join(@root, "}}a"), "wb") {}
@@ -184,7 +186,7 @@ class TestDir < Test::Unit::TestCase
dirs = ["a/.x", "a/b/.y"]
FileUtils.mkdir_p(dirs)
dirs.map {|dir| open("#{dir}/z", "w") {}}
- assert_equal([], Dir.glob("a/**/z").sort, bug8283)
+ assert_equal([], Dir.glob("a/**/z"), bug8283)
assert_equal(["a/.x/z"], Dir.glob("a/**/.x/z"), bug8283)
assert_equal(["a/.x/z"], Dir.glob("a/.x/**/z"), bug8283)
assert_equal(["a/b/.y/z"], Dir.glob("a/**/.y/z"), bug8283)
@@ -202,6 +204,9 @@ class TestDir < Test::Unit::TestCase
bug15540 = '[ruby-core:91110] [Bug #15540]'
assert_equal(["c/d/a/", "c/d/a/b/", "c/d/a/b/c/", "c/e/a/", "c/e/a/b/", "c/e/a/b/c/"],
Dir.glob('c/{d,e}/a/**/'), bug15540)
+
+ assert_equal(["c/e/a/", "c/e/a/b/", "c/e/a/b/c/", "c/d/a/", "c/d/a/b/", "c/d/a/b/c/"],
+ Dir.glob('c/{e,d}/a/**/'))
end
end
@@ -213,6 +218,17 @@ class TestDir < Test::Unit::TestCase
end
end
+ def test_glob_order
+ Dir.chdir(@root) do
+ assert_equal(["#{@root}/a", "#{@root}/b"], Dir.glob("#{@root}/[ba]"))
+ assert_equal(["#{@root}/b", "#{@root}/a"], Dir.glob(%W"#{@root}/b #{@root}/a"))
+ assert_equal(["#{@root}/b", "#{@root}/a"], Dir.glob("#{@root}/{b,a}"))
+ end
+ assert_equal(["a", "b"], Dir.glob("[ba]", base: @root))
+ assert_equal(["b", "a"], Dir.glob(%W"b a", base: @root))
+ assert_equal(["b", "a"], Dir.glob("{b,a}", base: @root))
+ end
+
if Process.const_defined?(:RLIMIT_NOFILE)
def test_glob_too_may_open_files
assert_separately([], "#{<<-"begin;"}\n#{<<-'end;'}", chdir: @root)
@@ -237,21 +253,38 @@ class TestDir < Test::Unit::TestCase
Dir.mkdir(File.join(@root, "a/dir"))
dirs = @dirs + %w[a/dir/]
dirs.sort!
- assert_equal(files, Dir.glob("*/*.c", base: @root).sort)
- assert_equal(files, Dir.chdir(@root) {Dir.glob("*/*.c", base: ".").sort})
- assert_equal(%w[foo.c], Dir.chdir(@root) {Dir.glob("*.c", base: "a").sort})
- assert_equal(files, Dir.chdir(@root) {Dir.glob("*/*.c", base: "").sort})
- assert_equal(files, Dir.chdir(@root) {Dir.glob("*/*.c", base: nil).sort})
- assert_equal(@dirs, Dir.glob("*/", base: @root).sort)
- assert_equal(@dirs, Dir.chdir(@root) {Dir.glob("*/", base: ".").sort})
- assert_equal(%w[dir/], Dir.chdir(@root) {Dir.glob("*/", base: "a").sort})
- assert_equal(@dirs, Dir.chdir(@root) {Dir.glob("*/", base: "").sort})
- assert_equal(@dirs, Dir.chdir(@root) {Dir.glob("*/", base: nil).sort})
- assert_equal(dirs, Dir.glob("**/*/", base: @root).sort)
- assert_equal(dirs, Dir.chdir(@root) {Dir.glob("**/*/", base: ".").sort})
- assert_equal(%w[dir/], Dir.chdir(@root) {Dir.glob("**/*/", base: "a").sort})
- assert_equal(dirs, Dir.chdir(@root) {Dir.glob("**/*/", base: "").sort})
- assert_equal(dirs, Dir.chdir(@root) {Dir.glob("**/*/", base: nil).sort})
+
+ assert_equal(files, Dir.glob("*/*.c", base: @root))
+ assert_equal(files, Dir.chdir(@root) {Dir.glob("*/*.c", base: ".")})
+ assert_equal(%w[foo.c], Dir.chdir(@root) {Dir.glob("*.c", base: "a")})
+ assert_equal(files, Dir.chdir(@root) {Dir.glob("*/*.c", base: "")})
+ assert_equal(files, Dir.chdir(@root) {Dir.glob("*/*.c", base: nil)})
+ assert_equal(@dirs, Dir.glob("*/", base: @root))
+ assert_equal(@dirs, Dir.chdir(@root) {Dir.glob("*/", base: ".")})
+ assert_equal(%w[dir/], Dir.chdir(@root) {Dir.glob("*/", base: "a")})
+ assert_equal(@dirs, Dir.chdir(@root) {Dir.glob("*/", base: "")})
+ assert_equal(@dirs, Dir.chdir(@root) {Dir.glob("*/", base: nil)})
+ assert_equal(dirs, Dir.glob("**/*/", base: @root))
+ assert_equal(dirs, Dir.chdir(@root) {Dir.glob("**/*/", base: ".")})
+ assert_equal(%w[dir/], Dir.chdir(@root) {Dir.glob("**/*/", base: "a")})
+ assert_equal(dirs, Dir.chdir(@root) {Dir.glob("**/*/", base: "")})
+ assert_equal(dirs, Dir.chdir(@root) {Dir.glob("**/*/", base: nil)})
+
+ assert_equal(files, Dir.glob("*/*.c", base: @root, sort: false).sort)
+ assert_equal(files, Dir.chdir(@root) {Dir.glob("*/*.c", base: ".", sort: false).sort})
+ assert_equal(%w[foo.c], Dir.chdir(@root) {Dir.glob("*.c", base: "a", sort: false).sort})
+ assert_equal(files, Dir.chdir(@root) {Dir.glob("*/*.c", base: "", sort: false).sort})
+ assert_equal(files, Dir.chdir(@root) {Dir.glob("*/*.c", base: nil, sort: false).sort})
+ assert_equal(@dirs, Dir.glob("*/", base: @root))
+ assert_equal(@dirs, Dir.chdir(@root) {Dir.glob("*/", base: ".", sort: false).sort})
+ assert_equal(%w[dir/], Dir.chdir(@root) {Dir.glob("*/", base: "a", sort: false).sort})
+ assert_equal(@dirs, Dir.chdir(@root) {Dir.glob("*/", base: "", sort: false).sort})
+ assert_equal(@dirs, Dir.chdir(@root) {Dir.glob("*/", base: nil, sort: false).sort})
+ assert_equal(dirs, Dir.glob("**/*/", base: @root))
+ assert_equal(dirs, Dir.chdir(@root) {Dir.glob("**/*/", base: ".", sort: false).sort})
+ assert_equal(%w[dir/], Dir.chdir(@root) {Dir.glob("**/*/", base: "a", sort: false).sort})
+ assert_equal(dirs, Dir.chdir(@root) {Dir.glob("**/*/", base: "", sort: false).sort})
+ assert_equal(dirs, Dir.chdir(@root) {Dir.glob("**/*/", base: nil, sort: false).sort})
end
def test_glob_base_dir
@@ -260,12 +293,20 @@ class TestDir < Test::Unit::TestCase
Dir.mkdir(File.join(@root, "a/dir"))
dirs = @dirs + %w[a/dir/]
dirs.sort!
- assert_equal(files, Dir.open(@root) {|d| Dir.glob("*/*.c", base: d)}.sort)
+
+ assert_equal(files, Dir.open(@root) {|d| Dir.glob("*/*.c", base: d)})
assert_equal(%w[foo.c], Dir.chdir(@root) {Dir.open("a") {|d| Dir.glob("*.c", base: d)}})
- assert_equal(@dirs, Dir.open(@root) {|d| Dir.glob("*/", base: d).sort})
- assert_equal(%w[dir/], Dir.chdir(@root) {Dir.open("a") {|d| Dir.glob("*/", base: d).sort}})
- assert_equal(dirs, Dir.open(@root) {|d| Dir.glob("**/*/", base: d).sort})
- assert_equal(%w[dir/], Dir.chdir(@root) {Dir.open("a") {|d| Dir.glob("**/*/", base: d).sort}})
+ assert_equal(@dirs, Dir.open(@root) {|d| Dir.glob("*/", base: d)})
+ assert_equal(%w[dir/], Dir.chdir(@root) {Dir.open("a") {|d| Dir.glob("*/", base: d)}})
+ assert_equal(dirs, Dir.open(@root) {|d| Dir.glob("**/*/", base: d)})
+ assert_equal(%w[dir/], Dir.chdir(@root) {Dir.open("a") {|d| Dir.glob("**/*/", base: d)}})
+
+ assert_equal(files, Dir.open(@root) {|d| Dir.glob("*/*.c", base: d, sort: false).sort})
+ assert_equal(%w[foo.c], Dir.chdir(@root) {Dir.open("a") {|d| Dir.glob("*.c", base: d, sort: false).sort}})
+ assert_equal(@dirs, Dir.open(@root) {|d| Dir.glob("*/", base: d, sort: false).sort})
+ assert_equal(%w[dir/], Dir.chdir(@root) {Dir.open("a") {|d| Dir.glob("*/", base: d, sort: false).sort}})
+ assert_equal(dirs, Dir.open(@root) {|d| Dir.glob("**/*/", base: d, sort: false).sort})
+ assert_equal(%w[dir/], Dir.chdir(@root) {Dir.open("a") {|d| Dir.glob("**/*/", base: d, sort: false).sort}})
end
def assert_entries(entries, children_only = false)
@@ -337,10 +378,10 @@ class TestDir < Test::Unit::TestCase
end
assert_equal([*"a".."z", *"symlink-a".."symlink-z"].each_slice(2).map {|f, _| File.join(@root, f + "/") }.sort,
- Dir.glob(File.join(@root, "*/")).sort)
+ Dir.glob(File.join(@root, "*/")))
assert_equal([@root + "/", *[*"a".."z"].each_slice(2).map {|f, _| File.join(@root, f + "/") }],
- Dir.glob(File.join(@root, "**/")).sort)
+ Dir.glob(File.join(@root, "**/")))
end
def test_glob_metachar
@@ -424,8 +465,8 @@ class TestDir < Test::Unit::TestCase
Dir.mkdir('some-dir')
File.write('some-dir/foo', 'some content')
- assert_equal [ 'dir-symlink', 'some-dir' ], Dir['*'].sort
- assert_equal [ 'dir-symlink', 'some-dir', 'some-dir/foo' ], Dir['**/*'].sort
+ assert_equal [ 'dir-symlink', 'some-dir' ], Dir['*']
+ assert_equal [ 'dir-symlink', 'some-dir', 'some-dir/foo' ], Dir['**/*']
end
end
end
@@ -471,7 +512,7 @@ class TestDir < Test::Unit::TestCase
ensure
fs.clear
end
- list = Dir.glob("*").sort
+ list = Dir.glob("*")
assert_not_empty(list)
assert_equal([*"a".."z"], list)
end;