diff options
| author | Benjamin Herr <ben@0x539.de> | 2014-04-07 18:24:06 +0200 |
|---|---|---|
| committer | Benjamin Herr <ben@0x539.de> | 2014-04-08 01:21:37 +0200 |
| commit | 1700f359bc5d6b8086194e3cc0f3698666dd41a4 (patch) | |
| tree | 1b13a272ce86db854784afb66d615a4f8aa92efd | |
| parent | 4051bd900abbb47557dd8928532eedbc2bca0563 (diff) | |
| download | rust-1700f359bc5d6b8086194e3cc0f3698666dd41a4.tar.gz rust-1700f359bc5d6b8086194e3cc0f3698666dd41a4.zip | |
libglob: only return dirs for globs ending in /
`foo.txt/` should not return `foo.txt` if `foo.txt` is in fact a text file and not a directory.
| -rw-r--r-- | src/libglob/lib.rs | 14 | ||||
| -rw-r--r-- | src/test/run-pass/glob-std.rs | 2 |
2 files changed, 14 insertions, 2 deletions
diff --git a/src/libglob/lib.rs b/src/libglob/lib.rs index 07b7c6604e7..d19924da5be 100644 --- a/src/libglob/lib.rs +++ b/src/libglob/lib.rs @@ -43,6 +43,7 @@ use std::path::is_sep; pub struct Paths { root: Path, dir_patterns: Vec<Pattern>, + require_dir: bool, options: MatchOptions, todo: Vec<(Path,uint)>, } @@ -106,6 +107,7 @@ pub fn glob_with(pattern: &str, options: MatchOptions) -> Paths { return Paths { root: root, dir_patterns: Vec::new(), + require_dir: false, options: options, todo: Vec::new(), }; @@ -118,6 +120,7 @@ pub fn glob_with(pattern: &str, options: MatchOptions) -> Paths { .split_terminator(is_sep) .map(|s| Pattern::new(s)) .collect::<Vec<Pattern>>(); + let require_dir = pattern.chars().next_back().map(is_sep) == Some(true); let mut todo = Vec::new(); if dir_patterns.len() > 0 { @@ -130,6 +133,7 @@ pub fn glob_with(pattern: &str, options: MatchOptions) -> Paths { Paths { root: root, dir_patterns: dir_patterns, + require_dir: require_dir, options: options, todo: todo, } @@ -146,7 +150,10 @@ impl Iterator<Path> for Paths { let (path,idx) = self.todo.pop().unwrap(); // idx -1: was already checked by fill_todo, maybe path was '.' or // '..' that we can't match here because of normalization. - if idx == -1 as uint { return Some(path); } + if idx == -1 as uint { + if self.require_dir && !path.is_dir() { continue; } + return Some(path); + } let ref pattern = *self.dir_patterns.get(idx); if pattern.matches_with(match path.filename_str() { @@ -161,7 +168,10 @@ impl Iterator<Path> for Paths { if idx == self.dir_patterns.len() - 1 { // it is not possible for a pattern to match a directory *AND* its children // so we don't need to check the children - return Some(path); + + if !self.require_dir || path.is_dir() { + return Some(path); + } } else { fill_todo(&mut self.todo, self.dir_patterns.as_slice(), idx + 1, &path, self.options); diff --git a/src/test/run-pass/glob-std.rs b/src/test/run-pass/glob-std.rs index eec6d675295..bd6161dd31a 100644 --- a/src/test/run-pass/glob-std.rs +++ b/src/test/run-pass/glob-std.rs @@ -138,6 +138,8 @@ pub fn main() { assert_eq!(glob_vec("nonexistent/../bbb"), Vec::new()); assert_eq!(glob_vec("aaa/tomato/tomato.txt/.."), Vec::new()); + assert_eq!(glob_vec("aaa/tomato/tomato.txt/"), Vec::new()); + assert_eq!(glob_vec("aa[a]"), vec!(abs_path("aaa"))); assert_eq!(glob_vec("aa[abc]"), vec!(abs_path("aaa"))); assert_eq!(glob_vec("a[bca]a"), vec!(abs_path("aaa"))); |
