1
- // Copyright 2014 The Rust Project Developers. See the COPYRIGHT
1
+ // Copyright 2013 The Rust Project Developers. See the COPYRIGHT
2
2
// file at the top-level directory of this distribution and at
3
3
// http://rust-lang.org/COPYRIGHT.
4
4
//
@@ -43,7 +43,6 @@ use std::path::is_sep;
43
43
pub struct Paths {
44
44
root : Path ,
45
45
dir_patterns : Vec < Pattern > ,
46
- require_dir : bool ,
47
46
options : MatchOptions ,
48
47
todo : Vec < ( Path , uint ) > ,
49
48
}
@@ -52,7 +51,7 @@ pub struct Paths {
52
51
/// Return an iterator that produces all the Paths that match the given pattern,
53
52
/// which may be absolute or relative to the current working directory.
54
53
///
55
- /// This method uses the default match options and is equivalent to calling
54
+ /// is method uses the default match options and is equivalent to calling
56
55
/// `glob_with(pattern, MatchOptions::new())`. Use `glob_with` directly if you
57
56
/// want to use non-default match options.
58
57
///
@@ -107,7 +106,6 @@ pub fn glob_with(pattern: &str, options: MatchOptions) -> Paths {
107
106
return Paths {
108
107
root : root,
109
108
dir_patterns : Vec :: new ( ) ,
110
- require_dir : false ,
111
109
options : options,
112
110
todo : Vec :: new ( ) ,
113
111
} ;
@@ -119,21 +117,13 @@ pub fn glob_with(pattern: &str, options: MatchOptions) -> Paths {
119
117
let dir_patterns = pattern. slice_from ( cmp:: min ( root_len, pattern. len ( ) ) )
120
118
. split_terminator ( is_sep)
121
119
. map ( |s| Pattern :: new ( s) )
122
- . collect :: < Vec < Pattern > > ( ) ;
123
- let require_dir = pattern. chars ( ) . next_back ( ) . map ( is_sep) == Some ( true ) ;
120
+ . collect ( ) ;
124
121
125
- let mut todo = Vec :: new ( ) ;
126
- if dir_patterns. len ( ) > 0 {
127
- // Shouldn't happen, but we're using -1 as a special index.
128
- assert ! ( dir_patterns. len( ) < -1 as uint) ;
129
-
130
- fill_todo ( & mut todo, dir_patterns. as_slice ( ) , 0 , & root, options) ;
131
- }
122
+ let todo = list_dir_sorted ( & root) . move_iter ( ) . map ( |x|( x, 0 u) ) . collect ( ) ;
132
123
133
124
Paths {
134
125
root : root,
135
126
dir_patterns : dir_patterns,
136
- require_dir : require_dir,
137
127
options : options,
138
128
todo : todo,
139
129
}
@@ -148,12 +138,6 @@ impl Iterator<Path> for Paths {
148
138
}
149
139
150
140
let ( path, idx) = self . todo . pop ( ) . unwrap ( ) ;
151
- // idx -1: was already checked by fill_todo, maybe path was '.' or
152
- // '..' that we can't match here because of normalization.
153
- if idx == -1 as uint {
154
- if self . require_dir && !path. is_dir ( ) { continue ; }
155
- return Some ( path) ;
156
- }
157
141
let ref pattern = * self . dir_patterns . get ( idx) ;
158
142
159
143
if pattern. matches_with ( match path. filename_str ( ) {
@@ -168,27 +152,23 @@ impl Iterator<Path> for Paths {
168
152
if idx == self . dir_patterns . len ( ) - 1 {
169
153
// it is not possible for a pattern to match a directory *AND* its children
170
154
// so we don't need to check the children
171
-
172
- if !self . require_dir || path. is_dir ( ) {
173
- return Some ( path) ;
174
- }
155
+ return Some ( path) ;
175
156
} else {
176
- fill_todo ( & mut self . todo , self . dir_patterns . as_slice ( ) ,
177
- idx + 1 , & path, self . options ) ;
157
+ self . todo . extend ( list_dir_sorted ( & path) . move_iter ( ) . map ( |x|( x, idx+1 ) ) ) ;
178
158
}
179
159
}
180
160
}
181
161
}
182
162
183
163
}
184
164
185
- fn list_dir_sorted ( path : & Path ) -> Option < Vec < Path > > {
165
+ fn list_dir_sorted ( path : & Path ) -> Vec < Path > {
186
166
match fs:: readdir ( path) {
187
167
Ok ( mut children) => {
188
168
children. sort_by ( |p1, p2| p2. filename ( ) . cmp ( & p1. filename ( ) ) ) ;
189
- Some ( children. move_iter ( ) . collect ( ) )
169
+ children. move_iter ( ) . collect ( )
190
170
}
191
- Err ( ..) => None
171
+ Err ( ..) => Vec :: new ( )
192
172
}
193
173
}
194
174
@@ -455,72 +435,6 @@ impl Pattern {
455
435
456
436
}
457
437
458
- // Fills `todo` with paths under `path` to be matched by `patterns[idx]`,
459
- // special-casing patterns to match `.` and `..`, and avoiding `readdir()`
460
- // calls when there are no metacharacters in the pattern.
461
- fn fill_todo ( todo : & mut Vec < ( Path , uint ) > , patterns : & [ Pattern ] , idx : uint , path : & Path ,
462
- options : MatchOptions ) {
463
- // convert a pattern that's just many Char(_) to a string
464
- fn pattern_as_str ( pattern : & Pattern ) -> Option < ~str > {
465
- let mut s = ~"";
466
- for token in pattern. tokens . iter ( ) {
467
- match * token {
468
- Char ( c) => s. push_char ( c) ,
469
- _ => return None
470
- }
471
- }
472
- return Some ( s) ;
473
- }
474
-
475
- let add = |todo : & mut Vec < _ > , next_path : Path | {
476
- if idx + 1 == patterns. len ( ) {
477
- // We know it's good, so don't make the iterator match this path
478
- // against the pattern again. In particular, it can't match
479
- // . or .. globs since these never show up as path components.
480
- todo. push ( ( next_path, -1 as uint ) ) ;
481
- } else {
482
- fill_todo ( todo, patterns, idx + 1 , & next_path, options) ;
483
- }
484
- } ;
485
-
486
- let pattern = & patterns[ idx] ;
487
-
488
- match pattern_as_str ( pattern) {
489
- Some ( s) => {
490
- // This pattern component doesn't have any metacharacters, so we
491
- // don't need to read the current directory to know where to
492
- // continue. So instead of passing control back to the iterator,
493
- // we can just check for that one entry and potentially recurse
494
- // right away.
495
- let special = "." == s || ".." == s;
496
- let next_path = path. join ( s) ;
497
- if ( special && path. is_dir ( ) ) || ( !special && next_path. exists ( ) ) {
498
- add ( todo, next_path) ;
499
- }
500
- } ,
501
- None => {
502
- match list_dir_sorted ( path) {
503
- Some ( entries) => {
504
- todo. extend ( entries. move_iter ( ) . map ( |x|( x, idx) ) ) ;
505
-
506
- // Matching the special directory entries . and .. that refer to
507
- // the current and parent directory respectively requires that
508
- // the pattern has a leading dot, even if the `MatchOptions` field
509
- // `require_literal_leading_dot` is not set.
510
- if pattern. tokens . len ( ) > 0 && pattern. tokens . get ( 0 ) == & Char ( '.' ) {
511
- for & special in [ "." , ".." ] . iter ( ) {
512
- if pattern. matches_with ( special, options) {
513
- add ( todo, path. join ( special) ) ;
514
- }
515
- }
516
- }
517
- }
518
- None => { }
519
- }
520
- }
521
- }
522
- }
523
-
524
438
fn parse_char_specifiers ( s : & [ char ] ) -> Vec < CharSpecifier > {
525
439
let mut cs = Vec :: new ( ) ;
526
440
let mut i = 0 ;
@@ -653,7 +567,7 @@ mod test {
653
567
fn test_absolute_pattern ( ) {
654
568
// assume that the filesystem is not empty!
655
569
assert ! ( glob( "/*" ) . next( ) . is_some( ) ) ;
656
- assert ! ( glob( "//" ) . next( ) . is_some ( ) ) ;
570
+ assert ! ( glob( "//" ) . next( ) . is_none ( ) ) ;
657
571
658
572
// check windows absolute paths with host/device components
659
573
let root_with_device = os:: getcwd ( ) . root_path ( ) . unwrap ( ) . join ( "*" ) ;
0 commit comments