7
7
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
8
8
//
9
9
10
- #if os(macOS) || os(iOS )
10
+ #if canImport(Darwin )
11
11
import Darwin
12
- #elseif os(Linux) || CYGWIN
12
+ #endif
13
+
14
+ #if canImport(Glibc)
13
15
import Glibc
14
16
#endif
15
17
@@ -128,23 +130,22 @@ open class FileManager : NSObject {
128
130
129
131
init ? ( _ domainMask: SearchPathDomainMask ) {
130
132
if domainMask == . systemDomainMask {
131
- self = . system
133
+ self = . system; return
132
134
}
133
135
if domainMask == . localDomainMask {
134
- self = . local
136
+ self = . local; return
135
137
}
136
138
if domainMask == . networkDomainMask {
137
- self = . network
139
+ self = . network; return
138
140
}
139
141
if domainMask == . userDomainMask {
140
- self = . user
142
+ self = . user; return
141
143
}
142
144
143
145
return nil
144
146
}
145
147
}
146
148
147
- #if os(macOS) || os(iOS) || os(tvOS) || os(watchOS)
148
149
private func darwinPathURLs( for domain: _SearchPathDomain , system: String ? , local: String ? , network: String ? , userHomeSubpath: String ? ) -> [ URL ] {
149
150
switch domain {
150
151
case . system:
@@ -174,35 +175,140 @@ open class FileManager : NSObject {
174
175
return [ URL ( fileURLWithPath: all, isDirectory: true , relativeTo: URL ( fileURLWithPath: NSHomeDirectory ( ) , isDirectory: true ) ) ]
175
176
}
176
177
}
177
- #endif
178
178
179
179
#if os(Windows) // Non-Apple OSes that do not implement FHS/XDG are not currently supported.
180
180
@available ( * , unavailable, message: " Not implemented for this OS " )
181
181
open func urls( for directory: SearchPathDirectory , in domainMask: SearchPathDomainMask ) -> [ URL ] {
182
182
NSUnimplemented ( )
183
183
}
184
184
#else
185
-
186
185
/* -URLsForDirectory:inDomains: is analogous to NSSearchPathForDirectoriesInDomains(), but returns an array of NSURL instances for use with URL-taking APIs. This API is suitable when you need to search for a file or files which may live in one of a variety of locations in the domains specified.
187
186
*/
188
187
open func urls( for directory: SearchPathDirectory , in domainMask: SearchPathDomainMask ) -> [ URL ] {
189
-
190
188
guard let domain = _SearchPathDomain ( domainMask) else {
191
189
fatalError ( " Values other than .systemDomainMask, .localDomainMask, .userDomainMask, .networkDomainMask are unsupported " )
192
190
}
193
191
194
192
// We are going to return appropriate paths on Darwin, but [] on platforms that do not have comparable locations.
195
193
// For example, on FHS/XDG systems, applications are not installed in a single path.
196
-
197
- #if os(macOS) || os(iOS) || os(tvOS) || os(watchOS)
198
- // For Darwin:
194
+
195
+ let useDarwinPaths : Bool
196
+ if let envVar = ProcessInfo . processInfo. environment [ " _NSFileManagerUseXDGPathsForDirectoryDomains " ] {
197
+ useDarwinPaths = !NSString( string: envVar) . boolValue
198
+ } else {
199
+ #if canImport(Darwin)
200
+ useDarwinPaths = true
201
+ #else
202
+ useDarwinPaths = false
203
+ #endif
204
+ }
205
+
206
+ if useDarwinPaths {
207
+ return darwinURLs ( for: directory, in: domain)
208
+ } else {
209
+ return xdgURLs ( for: directory, in: domain)
210
+ }
211
+ }
212
+ #endif
213
+
214
+ private func xdgURLs( for directory: SearchPathDirectory , in domain: _SearchPathDomain ) -> [ URL ] {
215
+ // FHS/XDG-compliant OSes:
216
+ switch directory {
217
+ case . autosavedInformationDirectory:
218
+ let runtimePath = _SwiftValue. fetch ( nonOptional: _CFXDGCreateDataHomePath ( ) ) as! String
219
+ return [ URL ( fileURLWithPath: " Autosave Information " , isDirectory: true , relativeTo: URL ( fileURLWithPath: runtimePath, isDirectory: true ) ) ]
220
+
221
+ case . desktopDirectory:
222
+ guard domain == . user else { return [ ] }
223
+ return [ _XDGUserDirectory. desktop. url ]
224
+
225
+ case . documentDirectory:
226
+ guard domain == . user else { return [ ] }
227
+ return [ _XDGUserDirectory. documents. url ]
228
+
229
+ case . cachesDirectory:
230
+ guard domain == . user else { return [ ] }
231
+ let path = _SwiftValue. fetch ( nonOptional: _CFXDGCreateCacheDirectoryPath ( ) ) as! String
232
+ return [ URL ( fileURLWithPath: path, isDirectory: true ) ]
233
+
234
+ case . applicationSupportDirectory:
235
+ guard domain == . user else { return [ ] }
236
+ let path = _SwiftValue. fetch ( nonOptional: _CFXDGCreateDataHomePath ( ) ) as! String
237
+ return [ URL ( fileURLWithPath: path, isDirectory: true ) ]
238
+
239
+ case . downloadsDirectory:
240
+ guard domain == . user else { return [ ] }
241
+ return [ _XDGUserDirectory. download. url ]
242
+
243
+ case . userDirectory:
244
+ guard domain == . local else { return [ ] }
245
+ return [ URL ( fileURLWithPath: " /home " , isDirectory: true ) ]
246
+
247
+ case . moviesDirectory:
248
+ return [ _XDGUserDirectory. videos. url ]
249
+
250
+ case . musicDirectory:
251
+ guard domain == . user else { return [ ] }
252
+ return [ _XDGUserDirectory. music. url ]
253
+
254
+ case . picturesDirectory:
255
+ guard domain == . user else { return [ ] }
256
+ return [ _XDGUserDirectory. pictures. url ]
257
+
258
+ case . sharedPublicDirectory:
259
+ guard domain == . user else { return [ ] }
260
+ return [ _XDGUserDirectory. publicShare. url ]
261
+
262
+ case . trashDirectory:
263
+ let userTrashURL = URL ( fileURLWithPath: " .Trash " , isDirectory: true , relativeTo: URL ( fileURLWithPath: NSHomeDirectory ( ) , isDirectory: true ) )
264
+ if domain == . user || domain == . local {
265
+ return [ userTrashURL ]
266
+ } else {
267
+ return [ ]
268
+ }
269
+
270
+ // None of these are supported outside of Darwin:
271
+ case . applicationDirectory:
272
+ fallthrough
273
+ case . demoApplicationDirectory:
274
+ fallthrough
275
+ case . developerApplicationDirectory:
276
+ fallthrough
277
+ case . adminApplicationDirectory:
278
+ fallthrough
279
+ case . libraryDirectory:
280
+ fallthrough
281
+ case . developerDirectory:
282
+ fallthrough
283
+ case . documentationDirectory:
284
+ fallthrough
285
+ case . coreServiceDirectory:
286
+ fallthrough
287
+ case . inputMethodsDirectory:
288
+ fallthrough
289
+ case . preferencePanesDirectory:
290
+ fallthrough
291
+ case . applicationScriptsDirectory:
292
+ fallthrough
293
+ case . allApplicationsDirectory:
294
+ fallthrough
295
+ case . allLibrariesDirectory:
296
+ fallthrough
297
+ case . printerDescriptionDirectory:
298
+ fallthrough
299
+ case . itemReplacementDirectory:
300
+ return [ ]
301
+ }
302
+ }
303
+
304
+ private func darwinURLs( for directory: SearchPathDirectory , in domain: _SearchPathDomain ) -> [ URL ] {
199
305
switch directory {
200
306
case . applicationDirectory:
201
307
return darwinPathURLs ( for: domain, all: " Applications " , useLocalDirectoryForSystem: true )
202
-
308
+
203
309
case . demoApplicationDirectory:
204
310
return darwinPathURLs ( for: domain, all: " Demos " , useLocalDirectoryForSystem: true )
205
-
311
+
206
312
case . developerApplicationDirectory:
207
313
return darwinPathURLs ( for: domain, all: " Developer/Applications " , useLocalDirectoryForSystem: true )
208
314
@@ -229,7 +335,7 @@ open class FileManager : NSObject {
229
335
230
336
case . preferencePanesDirectory:
231
337
return darwinPathURLs ( for: domain, system: " /System/Library/PreferencePanes " , local: " /Library/PreferencePanes " , network: nil , userHomeSubpath: " Library/PreferencePanes " )
232
-
338
+
233
339
case . applicationScriptsDirectory:
234
340
// Only the ObjC Foundation can know where this is.
235
341
return [ ]
@@ -251,27 +357,27 @@ open class FileManager : NSObject {
251
357
case . printerDescriptionDirectory:
252
358
guard domain == . system else { return [ ] }
253
359
return [ URL ( fileURLWithPath: " /System/Library/Printers/PPD " , isDirectory: true ) ]
254
-
360
+
255
361
case . desktopDirectory:
256
362
guard domain == . user else { return [ ] }
257
363
return [ URL ( fileURLWithPath: " Desktop " , isDirectory: true , relativeTo: URL ( fileURLWithPath: NSHomeDirectory ( ) , isDirectory: true ) ) ]
258
364
259
365
case . documentDirectory:
260
366
guard domain == . user else { return [ ] }
261
367
return [ URL ( fileURLWithPath: " Documents " , isDirectory: true , relativeTo: URL ( fileURLWithPath: NSHomeDirectory ( ) , isDirectory: true ) ) ]
262
-
368
+
263
369
case . cachesDirectory:
264
370
guard domain == . user else { return [ ] }
265
371
return [ URL ( fileURLWithPath: " Library/Caches " , isDirectory: true , relativeTo: URL ( fileURLWithPath: NSHomeDirectory ( ) , isDirectory: true ) ) ]
266
-
372
+
267
373
case . applicationSupportDirectory:
268
374
guard domain == . user else { return [ ] }
269
375
return [ URL ( fileURLWithPath: " Library/Application Support " , isDirectory: true , relativeTo: URL ( fileURLWithPath: NSHomeDirectory ( ) , isDirectory: true ) ) ]
270
-
376
+
271
377
case . downloadsDirectory:
272
378
guard domain == . user else { return [ ] }
273
379
return [ URL ( fileURLWithPath: " Downloads " , isDirectory: true , relativeTo: URL ( fileURLWithPath: NSHomeDirectory ( ) , isDirectory: true ) ) ]
274
-
380
+
275
381
case . userDirectory:
276
382
return darwinPathURLs ( for: domain, system: nil , local: " /Users " , network: " /Network/Users " , userHomeSubpath: nil )
277
383
@@ -282,15 +388,15 @@ open class FileManager : NSObject {
282
388
case . musicDirectory:
283
389
guard domain == . user else { return [ ] }
284
390
return [ URL ( fileURLWithPath: " Music " , isDirectory: true , relativeTo: URL ( fileURLWithPath: NSHomeDirectory ( ) , isDirectory: true ) ) ]
285
-
391
+
286
392
case . picturesDirectory:
287
393
guard domain == . user else { return [ ] }
288
394
return [ URL ( fileURLWithPath: " Pictures " , isDirectory: true , relativeTo: URL ( fileURLWithPath: NSHomeDirectory ( ) , isDirectory: true ) ) ]
289
-
395
+
290
396
case . sharedPublicDirectory:
291
397
guard domain == . user else { return [ ] }
292
398
return [ URL ( fileURLWithPath: " Public " , isDirectory: true , relativeTo: URL ( fileURLWithPath: NSHomeDirectory ( ) , isDirectory: true ) ) ]
293
-
399
+
294
400
case . trashDirectory:
295
401
let userTrashURL = URL ( fileURLWithPath: " .Trash " , isDirectory: true , relativeTo: URL ( fileURLWithPath: NSHomeDirectory ( ) , isDirectory: true ) )
296
402
if domain == . user || domain == . local {
@@ -303,99 +409,8 @@ open class FileManager : NSObject {
303
409
// This directory is only returned by url(for:in:appropriateFor:create:)
304
410
return [ ]
305
411
}
306
- #elseif !os(Windows)
307
- // FHS/XDG-compliant OSes:
308
- switch directory {
309
- case . autosavedInformationDirectory:
310
- let runtimePath = _SwiftValue. fetch ( nonOptional: _CFXDGCreateDataHomePath ( ) ) as! String
311
- return [ URL ( fileURLWithPath: " Autosave Information " , isDirectory: true , relativeTo: URL ( fileURLWithPath: runtimePath, isDirectory: true ) ) ]
312
-
313
- case . desktopDirectory:
314
- guard domain == . user else { return [ ] }
315
- return [ _XDGUserDirectory. desktop. url ]
316
-
317
- case . documentDirectory:
318
- guard domain == . user else { return [ ] }
319
- return [ _XDGUserDirectory. documents. url ]
320
-
321
- case . cachesDirectory:
322
- guard domain == . user else { return [ ] }
323
- let path = _SwiftValue. fetch ( nonOptional: _CFXDGCreateCacheDirectoryPath ( ) ) as! String
324
- return [ URL ( fileURLWithPath: path, isDirectory: true ) ]
325
-
326
- case . applicationSupportDirectory:
327
- guard domain == . user else { return [ ] }
328
- let path = _SwiftValue. fetch ( nonOptional: _CFXDGCreateDataHomePath ( ) ) as! String
329
- return [ URL ( fileURLWithPath: path, isDirectory: true ) ]
330
-
331
- case . downloadsDirectory:
332
- guard domain == . user else { return [ ] }
333
- return [ _XDGUserDirectory. download. url ]
334
-
335
- case . userDirectory:
336
- guard domain == . local else { return [ ] }
337
- return [ URL ( fileURLWithPath: " /home " , isDirectory: true ) ]
338
-
339
- case . moviesDirectory:
340
- return [ _XDGUserDirectory. videos. url ]
341
-
342
- case . musicDirectory:
343
- guard domain == . user else { return [ ] }
344
- return [ _XDGUserDirectory. music. url ]
345
-
346
- case . picturesDirectory:
347
- guard domain == . user else { return [ ] }
348
- return [ _XDGUserDirectory. pictures. url ]
349
-
350
- case . sharedPublicDirectory:
351
- guard domain == . user else { return [ ] }
352
- return [ _XDGUserDirectory. publicShare. url ]
353
-
354
- case . trashDirectory:
355
- let userTrashURL = URL ( fileURLWithPath: " .Trash " , isDirectory: true , relativeTo: URL ( fileURLWithPath: NSHomeDirectory ( ) , isDirectory: true ) )
356
- if domain == . user || domain == . local {
357
- return [ userTrashURL ]
358
- } else {
359
- return [ ]
360
- }
361
-
362
- // None of these are supported outside of Darwin:
363
- case . applicationDirectory:
364
- fallthrough
365
- case . demoApplicationDirectory:
366
- fallthrough
367
- case . developerApplicationDirectory:
368
- fallthrough
369
- case . adminApplicationDirectory:
370
- fallthrough
371
- case . libraryDirectory:
372
- fallthrough
373
- case . developerDirectory:
374
- fallthrough
375
- case . documentationDirectory:
376
- fallthrough
377
- case . coreServiceDirectory:
378
- fallthrough
379
- case . inputMethodsDirectory:
380
- fallthrough
381
- case . preferencePanesDirectory:
382
- fallthrough
383
- case . applicationScriptsDirectory:
384
- fallthrough
385
- case . allApplicationsDirectory:
386
- fallthrough
387
- case . allLibrariesDirectory:
388
- fallthrough
389
- case . printerDescriptionDirectory:
390
- fallthrough
391
- case . itemReplacementDirectory:
392
- return [ ]
393
- }
394
- #endif
395
-
396
412
}
397
- #endif
398
-
413
+
399
414
private enum URLForDirectoryError : Error {
400
415
case directoryUnknown
401
416
}
0 commit comments