Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cartfile.private
Original file line number Diff line number Diff line change
@@ -1 +1 @@
github "mattgallagher/CwlPreconditionTesting" "1e62a726d54c743f4585233f08fcaac7307319b5"
github "mattgallagher/CwlPreconditionTesting" == 1.2.0
3 changes: 1 addition & 2 deletions Cartfile.resolved
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
github "mattgallagher/CwlCatchException" "b14c111e9b33cd142bd4bc75c482cfd5c3490923"
github "mattgallagher/CwlPreconditionTesting" "1e62a726d54c743f4585233f08fcaac7307319b5"
github "mattgallagher/CwlPreconditionTesting" "1.2.0"
9 changes: 0 additions & 9 deletions Carthage/Checkouts/CwlCatchException/Package.swift

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
ISC License

Copyright © 2017 Matt Gallagher ( http://cocoawithlove.com ). All rights reserved.

Permission to use, copy, modify, and/or distribute this software for any
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// swift-tools-version:4.2
import PackageDescription

let package = Package(
name: "CwlCatchException",
products: [
.library(name: "CwlCatchException", type: .dynamic, targets: ["CwlCatchException"]),
],
targets: [
.target(name: "CwlCatchException", dependencies: [.target(name: "CwlCatchExceptionSupport")]),
.target(name: "CwlCatchExceptionSupport"),
.testTarget(name: "CwlCatchExceptionTests", dependencies: [.target(name: "CwlCatchException")])
]
)
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# CwlCatchException
A simple Swift wrapper around an Objective-C `@try`/`@catch` statement that selectively catches Objective-C exceptions by `NSException` subtype, rethrowing if any caught exception is not the expected subtype.

Look at [CwlCatchExceptionTests.swift](https://github.com/mattgallagher/CwlCatchException/blob/master/CwlCatchExceptionTests/CwlCatchExceptionTests.swift?ts=4) for syntax.
Look at [CwlCatchExceptionTests.swift](https://github.com/mattgallagher/CwlCatchException/blob/master/Tests/CwlCatchExceptionTests/CwlCatchExceptionTests.swift) for syntax.

## Adding to your project

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// CwlAssertionTesting
//
// Created by Matt Gallagher on 2016/01/10.
// Copyright © 2016 Matt Gallagher ( http://cocoawithlove.com ). All rights reserved.
// Copyright © 2016 Matt Gallagher ( https://www.cocoawithlove.com ). All rights reserved.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
Expand All @@ -24,12 +24,12 @@ import Foundation
import CwlCatchExceptionSupport
#endif

private func catchReturnTypeConverter<T: NSException>(_ type: T.Type, block: () -> Void) -> T? {
private func catchReturnTypeConverter<T: NSException>(_ type: T.Type, block: @escaping () -> Void) -> T? {
return catchExceptionOfKind(type, block) as? T
}

extension NSException {
public static func catchException(in block: () -> Void) -> Self? {
public static func catchException(in block: @escaping () -> Void) -> Self? {
return catchReturnTypeConverter(self, block: block)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// CwlAssertionTesting
//
// Created by Matt Gallagher on 2016/01/10.
// Copyright © 2016 Matt Gallagher ( http://cocoawithlove.com ). All rights reserved.
// Copyright © 2016 Matt Gallagher ( https://www.cocoawithlove.com ). All rights reserved.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
Expand All @@ -20,10 +20,10 @@

#import "CwlCatchException.h"

#if !SWIFT_PACKAGE && NON_SWIFT_PACKAGE
#if !SWIFT_PACKAGE
__attribute__((visibility("hidden")))
#endif
NSException* catchExceptionOfKind(Class __nonnull type, __attribute__((noescape)) void (^ __nonnull inBlock)(void)) {
NSException* __nullable catchExceptionOfKind(Class __nonnull type, void (^ __nonnull inBlock)(void)) {
@try {
inBlock();
} @catch (NSException *exception) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// CwlCatchException
//
// Created by Matt Gallagher on 2016/01/10.
// Copyright © 2016 Matt Gallagher ( http://cocoawithlove.com ). All rights reserved.
// Copyright © 2016 Matt Gallagher ( https://www.cocoawithlove.com ). All rights reserved.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
Expand All @@ -26,7 +26,7 @@ FOUNDATION_EXPORT double CwlCatchExceptionVersionNumber;
//! Project version string for CwlCatchException.
FOUNDATION_EXPORT const unsigned char CwlCatchExceptionVersionString[];

#if !SWIFT_PACKAGE && NON_SWIFT_PACKAGE
#if !SWIFT_PACKAGE
__attribute__((visibility("hidden")))
#endif
NSException* __nullable catchExceptionOfKind(Class __nonnull type, __attribute__((noescape)) void (^ __nonnull inBlock)(void));
NSException* __nullable catchExceptionOfKind(Class __nonnull type, void (^ __nonnull inBlock)(void));
29 changes: 19 additions & 10 deletions Carthage/Checkouts/CwlPreconditionTesting/Package.swift
Original file line number Diff line number Diff line change
@@ -1,19 +1,28 @@
// swift-tools-version:4.0
import PackageDescription

let package = Package(
name: "CwlPreconditionTesting",
targets: [
Target(name: "CwlPreconditionTesting", dependencies: [
"CwlMachBadInstructionHandler"
]),
Target(name: "CwlMachBadInstructionHandler")
products: [
.library(name: "CwlPreconditionTesting", type: .dynamic, targets: ["CwlPreconditionTesting", "CwlMachBadInstructionHandler"])
],
dependencies: [
.Package(url: "https://github.com/mattgallagher/CwlCatchException.git", Version(1, 0, 2, prereleaseIdentifiers: ["beta", "3"])),
.package(url: "https://github.com/mattgallagher/CwlCatchException.git", from: "1.2.0")
],
exclude: [
"Sources/CwlPreconditionTesting/Mach/CwlPreconditionTesting.h",
"Sources/CwlPreconditionTesting/Posix/CwlPreconditionTesting.h",
"Sources/CwlPreconditionTesting/CwlCatchBadInstructionPosix.swift",
targets: [
.target(
name: "CwlPreconditionTesting",
dependencies: [
.target(name: "CwlMachBadInstructionHandler"),
.product(name: "CwlCatchException")
],
exclude: [
"./Mach/CwlPreconditionTesting.h",
"./Posix/CwlPreconditionTesting.h",
"./CwlCatchBadInstructionPosix.swift"
]
),
.target(name: "CwlMachBadInstructionHandler"),
.testTarget(name: "CwlPreconditionTestingTests", dependencies: ["CwlPreconditionTesting"])
]
)
24 changes: 5 additions & 19 deletions Carthage/Checkouts/CwlPreconditionTesting/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,31 +18,17 @@ Minimum requirements are iOS 8 (simulator-only) or macOS 10.9. The project inclu

1. In a subdirectory of your project's directory, run `git clone https://github.com/mattgallagher/CwlPreconditionTesting.git`
2. Drag the "CwlPreconditionTesting.xcodeproj" file from the Finder into your own project's file tree in Xcode
3. Add the "CwlPreconditionTesting.framework" from the "Products" folder of the CwlPreconditionTesting project's file tree to the "Copy Files (Frameworks)" build phases of any target that you want to include this module.
4. Drag the "CwlCatchException.framework" from the "Dependencies" group (within the CwlPreconditionTesting project's file tree) onto the same "Copy Files (Frameworks)" build phase (this item may be red but that shouldn't be a problem).

That third step is a little tricky if you're unfamiliar with Xcode but it involves:

a. click on your project in the file tree
b. click on the target to whih you want to add this module
c. select the "Build Phases" tab
d. if you don't already have a "Copy File" build phase with a "Destination: Frameworks", add one using the "+" button in the top left of the tab
e. click the "+" within the "Copy File (Frameworks)" phase and from the list that appears, select the "CwlPreconditionTesting.framework" (if there are multiple frameworks with the same name, look for the one that appears *above* the corresponding macOS or iOS CwlPreconditionTesting testing target).

When building using this approach, the "FetchDependencies" target will use the Swift Package Manager to download the "CwlCatchException" project from github. The download is stored in the "Build intermediates" directory for your project. Normally, you can ignore its existence but if you get any errors from the "FetchDependencies" target, you might need to clean the build folder (Hold "Option" key while selecting "Product" &rarr; "Clean Build Folder..." from the Xcode menubar).

You can use the "Package.swift" to manage the behavior of the Swift Package Manager or if you want to download dependencies manually (instead of using this behind-the-scenes use of the Swift package manager), you should delete the "FetchDependencies" target and replace the "CwlCatchException" targets with alternatives that build the dependencies in accordance with your manual download.
3. Add the "CwlPreconditionTesting.framework" from the "Products" folder of the CwlPreconditionTesting project's file tree to the "Copy Files (Frameworks)" build phases of any targets that you want to include this module.
4. Drag the "CwlCatchException.framework" from the "Dependencies" group (within the CwlPreconditionTesting project's file tree) onto the same "Copy Files (Frameworks)" build phase

### Swift Package Manager

Add the following to the `dependencies` array in your "Package.swift" file:

.Package(url: "https://github.com/mattgallagher/CwlPreconditionTesting.git", majorVersion: 1),

Or, if you're using the `swift-tools-version:4.0` package manager, add the following to the `dependencies` array in your "Package.swift" file:
Assuming you're using the `swift-tools-version:4.0` package manager, add the following to the `dependencies` array in your "Package.swift" file:

.package(url: "https://github.com/mattgallagher/CwlPreconditionTesting.git", majorVersion: 1)

> NOTE: even though this git repository includes its dependencies in the Dependencies folder, building via the Swift Package manager fetches and builds these dependencies independently.

### CocoaPods

Add the following lines to your target in your "Podfile":
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// CwlPreconditionTesting
//
// Created by Matt Gallagher on 2016/01/10.
// Copyright © 2016 Matt Gallagher ( http://cocoawithlove.com ). All rights reserved.
// Copyright © 2016 Matt Gallagher ( https://www.cocoawithlove.com ). All rights reserved.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
Expand All @@ -18,33 +18,36 @@
// IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
//

#if defined(__x86_64__)
#ifdef __APPLE__
#import "TargetConditionals.h"
#if TARGET_OS_OSX || TARGET_OS_IOS

#import "mach_excServer.h"
#import "CwlMachBadInstructionHandler.h"
@protocol BadInstructionReply <NSObject>
+(NSNumber *)receiveReply:(NSValue *)value;
@end
/// A basic function that receives callbacks from mach_exc_server and relays them to the Swift implemented BadInstructionException.catch_mach_exception_raise_state.
kern_return_t catch_mach_exception_raise_state(mach_port_t exception_port, exception_type_t exception, const mach_exception_data_t code, mach_msg_type_number_t codeCnt, int *flavor, const thread_state_t old_state, mach_msg_type_number_t old_stateCnt, thread_state_t new_state, mach_msg_type_number_t *new_stateCnt) {
bad_instruction_exception_reply_t reply = { exception_port, exception, code, codeCnt, flavor, old_state, old_stateCnt, new_state, new_stateCnt };
Class badInstructionClass = NSClassFromString(@"BadInstructionException");
NSValue *value = [NSValue valueWithBytes: &reply objCType: @encode(bad_instruction_exception_reply_t)];
return [[badInstructionClass performSelector: @selector(receiveReply:) withObject: value] intValue];
}
// The mach port should be configured so that this function is never used.
kern_return_t catch_mach_exception_raise(mach_port_t exception_port, mach_port_t thread, mach_port_t task, exception_type_t exception, mach_exception_data_t code, mach_msg_type_number_t codeCnt) {
assert(false);
return KERN_FAILURE;
}
// The mach port should be configured so that this function is never used.
kern_return_t catch_mach_exception_raise_state_identity(mach_port_t exception_port, mach_port_t thread, mach_port_t task, exception_type_t exception, mach_exception_data_t code, mach_msg_type_number_t codeCnt, int *flavor, thread_state_t old_state, mach_msg_type_number_t old_stateCnt, thread_state_t new_state, mach_msg_type_number_t *new_stateCnt) {
assert(false);
return KERN_FAILURE;
}
#import "mach_excServer.h"
#import "CwlMachBadInstructionHandler.h"

@protocol BadInstructionReply <NSObject>
+(NSNumber *)receiveReply:(NSValue *)value;
@end

/// A basic function that receives callbacks from mach_exc_server and relays them to the Swift implemented BadInstructionException.catch_mach_exception_raise_state.
kern_return_t catch_mach_exception_raise_state(mach_port_t exception_port, exception_type_t exception, const mach_exception_data_t code, mach_msg_type_number_t codeCnt, int *flavor, const thread_state_t old_state, mach_msg_type_number_t old_stateCnt, thread_state_t new_state, mach_msg_type_number_t *new_stateCnt) {
bad_instruction_exception_reply_t reply = { exception_port, exception, code, codeCnt, flavor, old_state, old_stateCnt, new_state, new_stateCnt };
Class badInstructionClass = NSClassFromString(@"BadInstructionException");
NSValue *value = [NSValue valueWithBytes: &reply objCType: @encode(bad_instruction_exception_reply_t)];
return [[badInstructionClass performSelector: @selector(receiveReply:) withObject: value] intValue];
}

// The mach port should be configured so that this function is never used.
kern_return_t catch_mach_exception_raise(mach_port_t exception_port, mach_port_t thread, mach_port_t task, exception_type_t exception, mach_exception_data_t code, mach_msg_type_number_t codeCnt) {
assert(false);
return KERN_FAILURE;
}

// The mach port should be configured so that this function is never used.
kern_return_t catch_mach_exception_raise_state_identity(mach_port_t exception_port, mach_port_t thread, mach_port_t task, exception_type_t exception, mach_exception_data_t code, mach_msg_type_number_t codeCnt, int *flavor, thread_state_t old_state, mach_msg_type_number_t old_stateCnt, thread_state_t new_state, mach_msg_type_number_t *new_stateCnt) {
assert(false);
return KERN_FAILURE;
}

#endif
#endif /* TARGET_OS_OSX || TARGET_OS_IOS */
#endif /* __APPLE__ */
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// CwlPreconditionTesting
//
// Created by Matt Gallagher on 2016/01/10.
// Copyright © 2016 Matt Gallagher ( http://cocoawithlove.com ). All rights reserved.
// Copyright © 2016 Matt Gallagher ( https://www.cocoawithlove.com ). All rights reserved.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
Expand All @@ -19,8 +19,14 @@
//

#import <Foundation/Foundation.h>

#if TARGET_OS_OSX || TARGET_OS_IOS

#import <mach/mach.h>

extern bool _swift_disableExclusivityChecking;
extern bool _swift_reportFatalErrorsToDebugger;

NS_ASSUME_NONNULL_BEGIN

extern boolean_t mach_exc_server(mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP);
Expand Down Expand Up @@ -68,3 +74,5 @@ typedef struct
} bad_instruction_exception_reply_t;

NS_ASSUME_NONNULL_END

#endif
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,12 @@
* OPTIONS:
*/

#if defined(__x86_64__)

/* Module mach_exc */

#define __MIG_check__Request__mach_exc_subsystem__ 1

#include "mach_excServer.h"
#import "mach_excServer.h"
#if TARGET_OS_OSX || TARGET_OS_IOS

#ifndef mig_internal
#define mig_internal static __inline__
Expand Down Expand Up @@ -534,4 +533,4 @@ mig_external mig_routine_t mach_exc_server_routine
return catch_mach_exc_subsystem.routine[msgh_id].stub_routine;
}

#endif
#endif /* TARGET_OS_OSX || TARGET_OS_IOS */
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
#ifdef __APPLE__
#import "TargetConditionals.h"
#if TARGET_OS_OSX || TARGET_OS_IOS

#ifndef _mach_exc_server_
#define _mach_exc_server_

/* Module mach_exc */

#include <string.h>

#include <mach/ndr.h>
#include <mach/boolean.h>
#include <mach/kern_return.h>
Expand Down Expand Up @@ -319,3 +324,6 @@ __AfterMigServerHeader
#endif /* __AfterMigServerHeader */

#endif /* _mach_exc_server_ */

#endif /* TARGET_OS_OSX || TARGET_OS_IOS */
#endif /* __APPLE__ */
Loading