Skip to content

Commit 13536f9

Browse files
committed
WIP/SwiftLintCore: port the glob function to Windows
Windows does not support `glob` as a standard C library function as that is not part of the C standard. Attempt to emulate that through the use of `FindFirstFileW` and `FindNextFile` to iterate the matching files given a pattern. This should allow us to start enumerating the files as if we had `glob` available.
1 parent 913fac8 commit 13536f9

File tree

1 file changed

+29
-0
lines changed

1 file changed

+29
-0
lines changed

Source/SwiftLintFramework/Helpers/Glob.swift

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ import func Musl.glob
99
#endif
1010
#endif
1111

12+
#if os(Windows)
13+
import WinSDK
14+
#endif
15+
1216
// Adapted from https://gist.github.com/efirestone/ce01ae109e08772647eb061b3bb387c3
1317

1418
struct Glob {
@@ -20,6 +24,28 @@ struct Glob {
2024

2125
return expandGlobstar(pattern: pattern)
2226
.reduce(into: [String]()) { paths, pattern in
27+
#if os(Windows)
28+
URL(fileURLWithPath: pattern).withUnsafeFileSystemRepresentation {
29+
var ffd: WIN32_FIND_DATAW = WIN32_FIND_DATAW()
30+
31+
let hDirectory: HANDLE = String(cString: $0!).withCString(encodedAs: UTF16.self) {
32+
FindFirstFileW($0, &ffd)
33+
}
34+
if hDirectory == INVALID_HANDLE_VALUE { return }
35+
defer { FindClose(hDirectory) }
36+
37+
repeat {
38+
let path: String = withUnsafePointer(to: &ffd.cFileName) {
39+
$0.withMemoryRebound(to: UInt16.self, capacity: MemoryLayout.size(ofValue: $0) / MemoryLayout<WCHAR>.size) {
40+
String(decodingCString: $0, as: UTF16.self)
41+
}
42+
}
43+
if path != "." && path != ".." {
44+
paths.append(path)
45+
}
46+
} while FindNextFileW(hDirectory, &ffd)
47+
}
48+
#else
2349
var globResult = glob_t()
2450
defer { globfree(&globResult) }
2551

@@ -31,6 +57,7 @@ struct Glob {
3157
if glob(pattern, flags, nil, &globResult) == 0 {
3258
paths.append(contentsOf: populateFiles(globResult: globResult))
3359
}
60+
#endif
3461
}
3562
.unique
3663
.sorted()
@@ -92,6 +119,7 @@ struct Glob {
92119
return isDirectory && isDirectoryBool.boolValue
93120
}
94121

122+
#if !os(Windows)
95123
private static func populateFiles(globResult: glob_t) -> [String] {
96124
#if os(Linux)
97125
let matchCount = globResult.gl_pathc
@@ -102,4 +130,5 @@ struct Glob {
102130
globResult.gl_pathv[index].flatMap { String(validatingUTF8: $0) }
103131
}
104132
}
133+
#endif
105134
}

0 commit comments

Comments
 (0)