@@ -44,9 +44,9 @@ public enum ExitCondition: Sendable {
4444 /// | Linux | [`<stdlib.h>`](https://sourceware.org/glibc/manual/latest/html_node/Exit-Status.html), `<sysexits.h>` |
4545 /// | Windows | [`<stdlib.h>`](https://learn.microsoft.com/en-us/cpp/c-runtime-library/exit-success-exit-failure) |
4646 ///
47- /// On POSIX-like systems including macOS and Linux, only the low unsigned 8
48- /// bits (0–255) of the exit code are reliably preserved and reported to
49- /// a parent process .
47+ /// On macOS and Windows, the full exit code reported by the process is
48+ /// yielded to the parent process. Linux and other POSIX-like systems may only
49+ /// reliably report the low unsigned 8 bits (0–255) of the exit code .
5050 case exitCode( _ exitCode: CInt )
5151
5252 /// The process terminated with the given signal.
@@ -62,43 +62,171 @@ public enum ExitCondition: Sendable {
6262 /// | macOS | [`<signal.h>`](https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man3/signal.3.html) |
6363 /// | Linux | [`<signal.h>`](https://sourceware.org/glibc/manual/latest/html_node/Standard-Signals.html) |
6464 /// | Windows | [`<signal.h>`](https://learn.microsoft.com/en-us/cpp/c-runtime-library/signal-constants) |
65+ ///
66+ /// On Windows, by default, the C runtime will terminate a process with exit
67+ /// code `-3` if a raised signal is not handled, exactly as if `exit(-3)` were
68+ /// called. As a result, this case is unavailable on that platform. Developers
69+ /// should use ``failure`` instead when testing signal handling on Windows.
6570#if os(Windows)
6671 @available ( * , unavailable, message: " On Windows, use .failure instead. " )
6772#endif
6873 case signal( _ signal: CInt )
6974}
7075
71- // MARK: -
76+ // MARK: - Equatable
7277
7378#if SWT_NO_EXIT_TESTS
7479@available ( * , unavailable, message: " Exit tests are not available on this platform. " )
7580#endif
7681extension ExitCondition {
77- /// Check whether this instance matches another .
82+ /// Check whether or not two values of this type are equal .
7883 ///
7984 /// - Parameters:
80- /// - other: The other instance to compare against.
85+ /// - lhs: One value to compare.
86+ /// - rhs: Another value to compare.
8187 ///
82- /// - Returns: Whether or not this instance is equal to, or at least covers,
83- /// the other instance.
84- func matches( _ other: ExitCondition ) -> Bool {
85- return switch ( self , other) {
86- case ( . failure, . failure) :
87- true
88+ /// - Returns: Whether or not `lhs` and `rhs` are equal.
89+ ///
90+ /// Two instances of this type can be compared; if either instance is equal to
91+ /// ``failure``, it will compare equal to any instance except ``success``. To
92+ /// check if two instances are exactly equal, use the ``===(_:_:)`` operator:
93+ ///
94+ /// ```swift
95+ /// let lhs: ExitCondition = .failure
96+ /// let rhs: ExitCondition = .signal(SIGINT)
97+ /// print(lhs == rhs) // prints "true"
98+ /// print(lhs === rhs) // prints "false"
99+ /// ```
100+ ///
101+ /// This special behavior means that the ``==(_:_:)`` operator is not
102+ /// transitive, and does not satisfy the requirements of
103+ /// [`Equatable`](https://developer.apple.com/documentation/swift/equatable)
104+ /// or [`Hashable`](https://developer.apple.com/documentation/swift/hashable).
105+ ///
106+ /// For any values `a` and `b`, `a == b` implies that `a != b` is `false`.
107+ public static func == ( lhs: Self , rhs: Self ) -> Bool {
108+ #if SWT_NO_EXIT_TESTS
109+ fatalError ( " Unsupported " )
110+ #else
111+ return switch ( lhs, rhs) {
88112 case let ( . failure, . exitCode( exitCode) ) , let ( . exitCode( exitCode) , . failure) :
89113 exitCode != EXIT_SUCCESS
114+ #if !os(Windows)
115+ case ( . failure, . signal) , ( . signal, . failure) :
116+ // All terminating signals are considered failures.
117+ true
118+ #endif
119+ default :
120+ lhs === rhs
121+ }
122+ #endif
123+ }
124+
125+ /// Check whether or not two values of this type are _not_ equal.
126+ ///
127+ /// - Parameters:
128+ /// - lhs: One value to compare.
129+ /// - rhs: Another value to compare.
130+ ///
131+ /// - Returns: Whether or not `lhs` and `rhs` are _not_ equal.
132+ ///
133+ /// Two instances of this type can be compared; if either instance is equal to
134+ /// ``failure``, it will compare equal to any instance except ``success``. To
135+ /// check if two instances are not exactly equal, use the ``!==(_:_:)``
136+ /// operator:
137+ ///
138+ /// ```swift
139+ /// let lhs: ExitCondition = .failure
140+ /// let rhs: ExitCondition = .signal(SIGINT)
141+ /// print(lhs != rhs) // prints "false"
142+ /// print(lhs !== rhs) // prints "true"
143+ /// ```
144+ ///
145+ /// This special behavior means that the ``!=(_:_:)`` operator is not
146+ /// transitive, and does not satisfy the requirements of
147+ /// [`Equatable`](https://developer.apple.com/documentation/swift/equatable)
148+ /// or [`Hashable`](https://developer.apple.com/documentation/swift/hashable).
149+ ///
150+ /// For any values `a` and `b`, `a == b` implies that `a != b` is `false`.
151+ public static func != ( lhs: Self , rhs: Self ) -> Bool {
152+ #if SWT_NO_EXIT_TESTS
153+ fatalError ( " Unsupported " )
154+ #else
155+ !( lhs == rhs)
156+ #endif
157+ }
158+
159+ /// Check whether or not two values of this type are identical.
160+ ///
161+ /// - Parameters:
162+ /// - lhs: One value to compare.
163+ /// - rhs: Another value to compare.
164+ ///
165+ /// - Returns: Whether or not `lhs` and `rhs` are identical.
166+ ///
167+ /// Two instances of this type can be compared; if either instance is equal to
168+ /// ``failure``, it will compare equal to any instance except ``success``. To
169+ /// check if two instances are exactly equal, use the ``===(_:_:)`` operator:
170+ ///
171+ /// ```swift
172+ /// let lhs: ExitCondition = .failure
173+ /// let rhs: ExitCondition = .signal(SIGINT)
174+ /// print(lhs == rhs) // prints "true"
175+ /// print(lhs === rhs) // prints "false"
176+ /// ```
177+ ///
178+ /// This special behavior means that the ``==(_:_:)`` operator is not
179+ /// transitive, and does not satisfy the requirements of
180+ /// [`Equatable`](https://developer.apple.com/documentation/swift/equatable)
181+ /// or [`Hashable`](https://developer.apple.com/documentation/swift/hashable).
182+ ///
183+ /// For any values `a` and `b`, `a === b` implies that `a !== b` is `false`.
184+ public static func === ( lhs: Self , rhs: Self ) -> Bool {
185+ return switch ( lhs, rhs) {
186+ case ( . failure, . failure) :
187+ true
90188 case let ( . exitCode( lhs) , . exitCode( rhs) ) :
91189 lhs == rhs
92190#if !os(Windows)
93191 case let ( . signal( lhs) , . signal( rhs) ) :
94192 lhs == rhs
95- case ( . signal, . failure) , ( . failure, . signal) :
96- // All terminating signals are considered failures.
97- true
98- case ( . signal, . exitCode) , ( . exitCode, . signal) :
99- // Signals do not match exit codes.
100- false
101193#endif
194+ default :
195+ false
102196 }
103197 }
198+
199+ /// Check whether or not two values of this type are _not_ identical.
200+ ///
201+ /// - Parameters:
202+ /// - lhs: One value to compare.
203+ /// - rhs: Another value to compare.
204+ ///
205+ /// - Returns: Whether or not `lhs` and `rhs` are _not_ identical.
206+ ///
207+ /// Two instances of this type can be compared; if either instance is equal to
208+ /// ``failure``, it will compare equal to any instance except ``success``. To
209+ /// check if two instances are not exactly equal, use the ``!==(_:_:)``
210+ /// operator:
211+ ///
212+ /// ```swift
213+ /// let lhs: ExitCondition = .failure
214+ /// let rhs: ExitCondition = .signal(SIGINT)
215+ /// print(lhs != rhs) // prints "false"
216+ /// print(lhs !== rhs) // prints "true"
217+ /// ```
218+ ///
219+ /// This special behavior means that the ``!=(_:_:)`` operator is not
220+ /// transitive, and does not satisfy the requirements of
221+ /// [`Equatable`](https://developer.apple.com/documentation/swift/equatable)
222+ /// or [`Hashable`](https://developer.apple.com/documentation/swift/hashable).
223+ ///
224+ /// For any values `a` and `b`, `a === b` implies that `a !== b` is `false`.
225+ public static func !== ( lhs: Self , rhs: Self ) -> Bool {
226+ #if SWT_NO_EXIT_TESTS
227+ fatalError ( " Unsupported " )
228+ #else
229+ !( lhs === rhs)
230+ #endif
231+ }
104232}
0 commit comments