@@ -13,13 +13,15 @@ use std::option;
13
13
use std:: os;
14
14
use std:: hashmap:: HashSet ;
15
15
16
+ pub enum FileMatch { FileMatches , FileDoesntMatch }
17
+
16
18
// A module for searching for libraries
17
19
// FIXME (#2658): I'm not happy how this module turned out. Should
18
20
// probably just be folded into cstore.
19
21
20
22
/// Functions with type `pick` take a parent directory as well as
21
23
/// a file found in that directory.
22
- pub type pick < ' self , T > = & ' self fn ( path : & Path ) -> Option < T > ;
24
+ pub type pick < ' self > = & ' self fn ( path : & Path ) -> FileMatch ;
23
25
24
26
pub fn pick_file ( file : Path , path : & Path ) -> Option < Path > {
25
27
if path. file_path ( ) == file {
@@ -31,7 +33,7 @@ pub fn pick_file(file: Path, path: &Path) -> Option<Path> {
31
33
32
34
pub trait FileSearch {
33
35
fn sysroot ( & self ) -> @Path ;
34
- fn for_each_lib_search_path ( & self , f : & fn ( & Path ) -> bool ) -> bool ;
36
+ fn for_each_lib_search_path ( & self , f : & fn ( & Path ) -> FileMatch ) ;
35
37
fn get_target_lib_path ( & self ) -> Path ;
36
38
fn get_target_lib_file_path ( & self , file : & Path ) -> Path ;
37
39
}
@@ -47,34 +49,51 @@ pub fn mk_filesearch(maybe_sysroot: &Option<@Path>,
47
49
}
48
50
impl FileSearch for FileSearchImpl {
49
51
fn sysroot ( & self ) -> @Path { self . sysroot }
50
- fn for_each_lib_search_path ( & self , f : & fn ( & Path ) -> bool ) -> bool {
52
+ fn for_each_lib_search_path ( & self , f : & fn ( & Path ) -> FileMatch ) {
51
53
let mut visited_dirs = HashSet :: new ( ) ;
54
+ let mut found = false ;
52
55
53
56
debug ! ( "filesearch: searching additional lib search paths [%?]" ,
54
57
self . addl_lib_search_paths. len( ) ) ;
55
58
for path in self . addl_lib_search_paths . iter ( ) {
56
- f ( path) ;
59
+ match f ( path) {
60
+ FileMatches => found = true ,
61
+ FileDoesntMatch => ( )
62
+ }
57
63
visited_dirs. insert ( path. to_str ( ) ) ;
58
64
}
59
65
60
66
debug ! ( "filesearch: searching target lib path" ) ;
61
67
let tlib_path = make_target_lib_path ( self . sysroot ,
62
68
self . target_triple ) ;
63
69
if !visited_dirs. contains ( & tlib_path. to_str ( ) ) {
64
- if !f ( & tlib_path) {
65
- return false ;
70
+ match f ( & tlib_path) {
71
+ FileMatches => found = true ,
72
+ FileDoesntMatch => ( )
66
73
}
67
74
}
68
75
visited_dirs. insert ( tlib_path. to_str ( ) ) ;
69
76
// Try RUST_PATH
70
- let rustpath = rust_path ( ) ;
71
- for path in rustpath. iter ( ) {
77
+ if !found {
78
+ let rustpath = rust_path ( ) ;
79
+ for path in rustpath. iter ( ) {
80
+ debug ! ( "is %s in visited_dirs? %?" ,
81
+ path. push( "lib" ) . to_str( ) ,
82
+ visited_dirs. contains( & path. push( "lib" ) . to_str( ) ) ) ;
83
+
72
84
if !visited_dirs. contains ( & path. push ( "lib" ) . to_str ( ) ) {
73
- f ( & path. push ( "lib" ) ) ;
74
85
visited_dirs. insert ( path. push ( "lib" ) . to_str ( ) ) ;
86
+ // Don't keep searching the RUST_PATH if one match turns up --
87
+ // if we did, we'd get a "multiple matching crates" error
88
+ match f ( & path. push ( "lib" ) ) {
89
+ FileMatches => {
90
+ break ;
91
+ }
92
+ FileDoesntMatch => ( )
93
+ }
75
94
}
95
+ }
76
96
}
77
- true
78
97
}
79
98
fn get_target_lib_path ( & self ) -> Path {
80
99
make_target_lib_path ( self . sysroot , self . target_triple )
@@ -93,28 +112,26 @@ pub fn mk_filesearch(maybe_sysroot: &Option<@Path>,
93
112
} as @FileSearch
94
113
}
95
114
96
- pub fn search < T > ( filesearch : @FileSearch , pick : pick < T > ) -> Option < T > {
97
- let mut rslt = None ;
115
+ pub fn search ( filesearch : @FileSearch , pick : pick ) {
98
116
do filesearch. for_each_lib_search_path ( ) |lib_search_path| {
99
117
debug ! ( "searching %s" , lib_search_path. to_str( ) ) ;
100
118
let r = os:: list_dir_path ( lib_search_path) ;
119
+ let mut rslt = FileDoesntMatch ;
101
120
for path in r. iter ( ) {
102
121
debug ! ( "testing %s" , path. to_str( ) ) ;
103
122
let maybe_picked = pick ( path) ;
104
123
match maybe_picked {
105
- Some ( _ ) => {
124
+ FileMatches => {
106
125
debug ! ( "picked %s" , path. to_str( ) ) ;
107
- rslt = maybe_picked;
108
- break ;
126
+ rslt = FileMatches ;
109
127
}
110
- None => {
128
+ FileDoesntMatch => {
111
129
debug ! ( "rejected %s" , path. to_str( ) ) ;
112
130
}
113
131
}
114
132
}
115
- rslt. is_none ( )
133
+ rslt
116
134
} ;
117
- return rslt;
118
135
}
119
136
120
137
pub fn relative_target_lib_path ( target_triple : & str ) -> Path {
0 commit comments