diff options
Diffstat (limited to 'vendor')
| -rw-r--r-- | vendor/NSXReturnThrowError/NSXReturnThrowError.h | 103 | ||||
| -rw-r--r-- | vendor/NSXReturnThrowError/NSXReturnThrowError.m | 106 | 
2 files changed, 209 insertions, 0 deletions
| diff --git a/vendor/NSXReturnThrowError/NSXReturnThrowError.h b/vendor/NSXReturnThrowError/NSXReturnThrowError.h new file mode 100644 index 0000000..b8aa11a --- /dev/null +++ b/vendor/NSXReturnThrowError/NSXReturnThrowError.h @@ -0,0 +1,103 @@ +/***************************************************************************//** +	NSXReturnThrowError.h +		Copyright (c) 2007 Jonathan 'Wolf' Rentzsch: <http://rentzsch.com> +		Some rights reserved: <http://opensource.org/licenses/mit-license.php> +	 +	@section Overview + +		NSXReturnThrowError does two things: + +		1. Eases wrapping error codes into NSError objects. + +		2. Enhances NSError by adding origin information to the error instance. +		   Origin information includes the actual line of code that returned +		   the error, as well as the file+line+function/method name. + +		A big NSXReturnThrowError feature is that it deduces the correct NSError +		error domain based on the wrapped code's return type+value. Bonus: it +		does so without requiring ObjC++, relying on \@encode acrobatics +		instead. + +		NSXReturnThrowError was coded against 10.4, but should be compatible +		with 10.3 as well. However that's currently untested. + +	@section Usage + +		NSXReturnThrowError handles both types of error handling: explicit +		returning of NSError objects and raising NSExceptions. + +		Use NSXReturnError() if you're returning NSError objects explicitly: + +		@code +		- (id)demoReturnError:(NSError**)error_ { +			id result = nil; +			NSError *error = nil; +			 +			NSXReturnError(SomeCarbonFunction()); +			if (!error) +				NSXReturnError(someposixfunction()); +			if (!error) +				NSXReturnError(some_mach_function()); +			if (!error) +				NSXReturnError([SomeCocoaClass sharedInstance]); +			 +			if (error_) *error_ = error; +			return result; +		} +		@endcode + +		Use NSXThrowError() if you'd prefer to raise NSException objects: + +		@code +		- (id)demo { +			id result = nil; +			 +			NSXThrowError(SomeCarbonFunction()); +			NSXThrowError(someposixfunction()); +			NSXThrowError(some_mach_function()); +			NSXThrowError([SomeCocoaClass newObject]); +			 +			return result; +		} +		@endcode +		 +		The current structure of the raised NSException object is that it's a +		normal NSException whose name is "NSError". The actual error object is +		hung off the exception's userInfo dictionary with the key of @"error". + +	@mainpage	NSXReturnThrowError +	@todo		Add a compile-time flag for whether to stuff __FILE__+friends +				info into the generated NSError or not. +	 + +	***************************************************************************/ + +#import <Foundation/Foundation.h> + +extern NSString *NSXErrorExceptionName; +extern NSString *NULLPointerErrorDomain; +extern NSString *BOOLErrorDomain; + +void NSXMakeErrorImp(const char *objCType_, intptr_t result_, const char *file_, unsigned line_, const char *function_, const char *code_, NSError **error_); + +#define	NSXMakeError(ERROR, CODE)	\ +	do{	\ +		typeof(CODE) codeResult = (CODE);	\ +		NSXMakeErrorImp(@encode(typeof(CODE)), (intptr_t)codeResult, __FILE__, __LINE__, __PRETTY_FUNCTION__, #CODE, &ERROR);	\ +	}while(0) + +#define	NSXReturnError(CODE)	NSXMakeError(error, CODE) +  +#define NSXRaiseError(ERROR) \ +    [[NSException exceptionWithName:NSXErrorExceptionName	\ +                             reason:[error description]	\ +                           userInfo:[NSDictionary dictionaryWithObject:error forKey:@"error"]] raise]; + +#define NSXThrowError(CODE) \ +	do{	\ +		NSError *error = nil;	\ +		NSXReturnError(CODE);	\ +		if (error) {	\ +			NSXRaiseError(ERROR);	\ +		}	\ +	}while(0) diff --git a/vendor/NSXReturnThrowError/NSXReturnThrowError.m b/vendor/NSXReturnThrowError/NSXReturnThrowError.m new file mode 100644 index 0000000..22f31a5 --- /dev/null +++ b/vendor/NSXReturnThrowError/NSXReturnThrowError.m @@ -0,0 +1,106 @@ +/******************************************************************************* +	NSXReturnThrowError.m +		Copyright (c) 2007 Jonathan 'Wolf' Rentzsch: <http://rentzsch.com> +		Some rights reserved: <http://opensource.org/licenses/mit-license.php> + +	***************************************************************************/ + +#import "NSXReturnThrowError.h" + +NSString *NSXErrorExceptionName = @"NSXError"; +NSString *NULLPointerErrorDomain = @"NULLPointerErrorDomain"; +NSString *BOOLErrorDomain = @"BOOLErrorDomain"; + +typedef	enum { +	NSXErrorCodeType_Unknown, +	NSXErrorCodeType_Cocoa,			//	"@" +	NSXErrorCodeType_PosixOrMach,	//	"i" (-1 == posix+errno, otherwise mach) +	NSXErrorCodeType_Carbon,		//	"s" || "l" +	NSXErrorCodeType_ptr,			//	"r*" || "*" || "^" +	NSXErrorCodeType_BOOL			//	"c" +}	NSXErrorCodeType; + +static NSXErrorCodeType NSXErrorCodeTypeFromObjCType(const char *objCType) { +	switch (objCType[0]) { +		case 's': +		case 'l': +			return NSXErrorCodeType_Carbon; +		case 'i': +			return NSXErrorCodeType_PosixOrMach; +		case '@': +			return NSXErrorCodeType_Cocoa; +		case '^': +		case '*': +			return NSXErrorCodeType_ptr; +		case 'r': +			return '*' == objCType[1] ? NSXErrorCodeType_ptr : NSXErrorCodeType_Unknown; +		case 'c': +			return NSXErrorCodeType_BOOL; +		default: +			return NSXErrorCodeType_Unknown; +	} +} + +void NSXMakeErrorImp(const char *objCType_, intptr_t result_, const char *file_, unsigned line_, const char *function_, const char *code_, NSError **error_) { +	NSString *errorDomain = nil; +	int errorCode = (int)result_; +	 +	switch (NSXErrorCodeTypeFromObjCType(objCType_)) { +		case NSXErrorCodeType_Cocoa: +			//	codeResult's type is an id/NSObject* pointer. 0 == nil == failure. +			if (0 == result_) { +				errorDomain = @"NSCocoaErrorDomain"; // Could use NSCocoaErrorDomain symbol, but that would force us to 10.4. +				errorCode = -1; +			} +			break; +		case NSXErrorCodeType_Carbon: +			//	codeResult's type is OSErr (short) or OSStatus (long). 0 == noErr == success. +			if (0 != result_) { +				errorDomain = NSOSStatusErrorDomain; +			} +			break; +		case NSXErrorCodeType_PosixOrMach: +			//	codeResult's type is int, which is used for both posix error codes and mach_error_t/kern_return_t. +			//	0 means success for both, and we can differentiate posix error codes since they're always -1 (the +			//	actual posix code stored in errno). +			if (0 != result_) { +				if (-1 == result_) { +					//	Posix error code. +					errorDomain = NSPOSIXErrorDomain; +					errorCode = errno; +				} else { +					//	Mach error code. +					errorDomain = NSMachErrorDomain; +				} +			} +			break; +		case NSXErrorCodeType_ptr: +			//	codeResult's type is some sort of non-id/non-NSObject* pointer. 0 == NULL == failure. +			if (0 == result_) { +				errorDomain = NULLPointerErrorDomain; +				errorCode = -1; +			} +			break; +		case NSXErrorCodeType_BOOL: +			//	codeResult's type is a BOOL. 0 == NO == failure. +			if (0 == result_) { +				errorDomain = BOOLErrorDomain; +				errorCode = -1; +			} +			break; +		default: +			NSCAssert1(NO, @"NSXErrorCodeType_Unknown: \"%s\"", objCType_); +			break; +	} + +	if (errorDomain) { +		*error_ = [NSError errorWithDomain:errorDomain +									  code:errorCode +								  userInfo:[NSDictionary dictionaryWithObjectsAndKeys: +									  [NSString stringWithUTF8String:file_],   @"reportingFile", +									  [NSNumber numberWithInt:line_],   @"reportingLine", +									  [NSString stringWithUTF8String:function_], @"reportingMethod", +									  [NSString stringWithUTF8String:code_], @"origin", +									  nil]]; +	} +} | 
