@@ -16,7 +16,7 @@ pub(super) static ALTERNATIVE_LOCATIONS: Lazy<Vec<PathBuf>> = Lazy::new(|| {
16
16
pub ( super ) static ALTERNATIVE_LOCATIONS : Lazy < Vec < PathBuf > > = Lazy :: new ( || vec ! [ ] ) ;
17
17
18
18
#[ cfg( windows) ]
19
- fn alternative_windows_locations_from_environment < F > ( var_os_func : F ) -> Vec < PathBuf >
19
+ fn locations_under_program_files < F > ( var_os_func : F ) -> Vec < PathBuf >
20
20
where
21
21
F : Fn ( & str ) -> Option < std:: ffi:: OsString > ,
22
22
{
28
28
let varname_x86 = "ProgramFiles(x86)" ;
29
29
30
30
// Should give a 32-bit program files path on a 32-bit system. We also check this on a 64-bit
31
- // system, even though it *should* equal the process architecture specific variable, so that we
32
- // cover the case of a parent process that passes down an overly sanitized environment that
31
+ // system, even though it *should* equal the process's architecture specific variable, so that
32
+ // we cover the case of a parent process that passes down an overly sanitized environment that
33
33
// lacks the architecture-specific variable. On a 64-bit system, because parent and child
34
34
// processes' architectures can be different, Windows sets the child's ProgramFiles variable
35
35
// from the ProgramW6432 or ProgramFiles(x86) variable applicable to the child's architecture.
@@ -38,10 +38,10 @@ where
38
38
let varname_current = "ProgramFiles" ;
39
39
40
40
// 64-bit relative bin dir. So far, this is always mingw64, not ucrt64, clang64, or clangarm64.
41
- let suffix_64 = Path :: new ( r"Git\bin\ mingw64" ) ;
41
+ let suffix_64 = Path :: new ( r"Git\mingw64\bin " ) ;
42
42
43
43
// 32-bit relative bin dir. So far, this is always mingw32, not clang32.
44
- let suffix_32 = Path :: new ( r"Git\bin\ mingw32" ) ;
44
+ let suffix_32 = Path :: new ( r"Git\mingw32\bin " ) ;
45
45
46
46
// Whichever of the 64-bit or 32-bit relative bin better matches this process's architecture.
47
47
// Unlike the system architecture, the process architecture is always known at compile time.
@@ -189,6 +189,124 @@ mod tests {
189
189
}
190
190
}
191
191
192
+ #[ cfg( windows) ]
193
+ macro_rules! var_os_stub {
194
+ { $( $name: expr => $value: expr) ,* $( , ) ? } => {
195
+ |key| {
196
+ match key {
197
+ $(
198
+ $name => Some ( OsString :: from( $value) ) ,
199
+ ) *
200
+ _ => None ,
201
+ }
202
+ }
203
+ } ;
204
+ }
205
+
206
+ #[ cfg( windows) ]
207
+ macro_rules! locations_from {
208
+ ( $( $name: expr => $value: expr) ,* $( , ) ?) => {
209
+ super :: locations_under_program_files( var_os_stub! {
210
+ $(
211
+ $name => $value,
212
+ ) *
213
+ } )
214
+ }
215
+ }
216
+
217
+ #[ cfg( windows) ]
218
+ macro_rules! pathbuf_vec {
219
+ [ $( $path: expr) ,* $( , ) ?] => {
220
+ vec![ $(
221
+ PathBuf :: from( $path) ,
222
+ ) * ]
223
+ }
224
+ }
225
+
226
+ #[ test]
227
+ #[ cfg( windows) ]
228
+ fn locations_under_program_files_ordinary ( ) {
229
+ assert_eq ! (
230
+ locations_from!(
231
+ "ProgramFiles" => r"C:\Program Files" ,
232
+ ) ,
233
+ if cfg!( target_pointer_width = "64" ) {
234
+ pathbuf_vec![ r"C:\Program Files\Git\mingw64\bin" ]
235
+ } else {
236
+ pathbuf_vec![ r"C:\Program Files\Git\mingw32\bin" ]
237
+ } ,
238
+ ) ;
239
+ assert_eq ! (
240
+ locations_from!(
241
+ "ProgramFiles" => {
242
+ if cfg!( target_pointer_width = "64" ) {
243
+ r"C:\Program Files"
244
+ } else {
245
+ r"C:\Program Files (x86)"
246
+ }
247
+ } ,
248
+ "ProgramFiles(x86)" => r"C:\Program Files (x86)" ,
249
+ "ProgramW6432" => r"C:\Program Files" ,
250
+ ) ,
251
+ pathbuf_vec![
252
+ r"C:\Program Files\Git\mingw64\bin" ,
253
+ r"C:\Program Files (x86)\Git\mingw32\bin" ,
254
+ ] ,
255
+ ) ;
256
+ assert_eq ! ( locations_from!( ) , Vec :: <PathBuf >:: new( ) ) ;
257
+ }
258
+
259
+ #[ test]
260
+ #[ cfg( windows) ]
261
+ fn locations_under_program_files_strange ( ) {
262
+ assert_eq ! (
263
+ locations_from!(
264
+ "ProgramFiles" => r"X:\cur\rent" ,
265
+ "ProgramFiles(x86)" => r"Y:\nar\row" ,
266
+ "ProgramW6432" => r"Z:\wi\de" ,
267
+ ) ,
268
+ pathbuf_vec![
269
+ r"Z:\wi\de\Git\mingw64\bin" ,
270
+ r"Y:\nar\row\Git\mingw32\bin" ,
271
+ if cfg!( target_pointer_width = "64" ) {
272
+ r"X:\cur\rent\Git\mingw64\bin"
273
+ } else {
274
+ r"X:\cur\rent\Git\mingw32\bin"
275
+ } ,
276
+ ] ,
277
+ ) ;
278
+ assert_eq ! (
279
+ locations_from!(
280
+ "ProgramW6432" => r"Z:\wi\de" ,
281
+ ) ,
282
+ pathbuf_vec![ r"Z:\wi\de\Git\mingw64\bin" ] ,
283
+ ) ;
284
+ assert_eq ! (
285
+ locations_from!(
286
+ "ProgramFiles" => r"Z:/wi//de/" ,
287
+ "ProgramFiles(x86)" => r"Y:/\nar\/row" ,
288
+ "ProgramW6432" => r"Z:\wi\.\de" ,
289
+ ) ,
290
+ if cfg!( target_pointer_width = "64" ) {
291
+ pathbuf_vec![ r"Z:\wi\de\Git\mingw64\bin" , r"Y:\nar\row\Git\mingw32\bin" ]
292
+ } else {
293
+ pathbuf_vec![
294
+ r"Z:\wi\de\Git\mingw64\bin" ,
295
+ r"Y:\nar\row\Git\mingw32\bin" ,
296
+ r"Z:\wi\de\Git\mingw32\bin" ,
297
+ ]
298
+ } ,
299
+ ) ;
300
+ assert_eq ! (
301
+ locations_from!(
302
+ "ProgramFiles" => r"foo\bar" ,
303
+ "ProgramFiles(x86)" => r"\\host\share\subdir" ,
304
+ "ProgramW6432" => r"" ,
305
+ ) ,
306
+ pathbuf_vec![ r"\\host\share\subdir\Git\mingw32\bin" ] ,
307
+ ) ;
308
+ }
309
+
192
310
#[ cfg( windows) ]
193
311
use {
194
312
known_folders:: { get_known_folder_path, KnownFolder } ,
0 commit comments