# HG changeset patch # User snej@snej-mbp.mtv.corp.google.com # Date 1239128005 25200 # Node ID a910102a1c9d2f89104afa4eb33490a971c832b3 # Parent a9da6c5d3f7ce1f8489bafae7db4e55163f6c3f4 * Added MYReturnError. * Better iPhone support in ExceptionUtils. * Make sure "All Tests Passed/Failed" message is always logged. diff -r a9da6c5d3f7c -r a910102a1c9d ExceptionUtils.m --- a/ExceptionUtils.m Sat Apr 04 20:53:53 2009 -0700 +++ b/ExceptionUtils.m Tue Apr 07 11:13:25 2009 -0700 @@ -43,7 +43,7 @@ } -@implementation NSException (MooseyardUtil) +@implementation NSException (MYUtilities) - (NSArray*) my_callStackReturnAddresses @@ -70,10 +70,12 @@ - (NSString*) my_callStack { - NSArray *addresses = [self my_callStackReturnAddressesSkipping: 2 limit: 15]; + NSArray *addresses = [self my_callStackReturnAddressesSkipping: 1 limit: 15]; if (!addresses) return nil; + FILE *file = NULL; +#if !TARGET_OS_IPHONE // We pipe the hex return addresses through the 'atos' tool to get symbolic names: // Adapted from : NSMutableString *cmd = [NSMutableString stringWithFormat: @"/usr/bin/atos -p %d", getpid()]; @@ -81,32 +83,41 @@ foreach(addr,addresses) { [cmd appendFormat: @" %p", [addr pointerValue]]; } - FILE *file = popen( [cmd UTF8String], "r" ); - if( ! file ) - return nil; - - NSMutableData *output = [NSMutableData data]; - char buffer[512]; - size_t length; - while ((length = fread( buffer, 1, sizeof( buffer ), file ) )) - [output appendBytes: buffer length: length]; - pclose( file ); - NSString *outStr = [[[NSString alloc] initWithData: output encoding: NSUTF8StringEncoding] autorelease]; + file = popen( [cmd UTF8String], "r" ); +#endif NSMutableString *result = [NSMutableString string]; - NSString *line; - foreach( line, [outStr componentsSeparatedByString: @"\n"] ) { - // Skip frames that are part of the exception/assertion handling itself: - if( [line hasPrefix: @"-[NSAssertionHandler"] || [line hasPrefix: @"+[NSException"] - || [line hasPrefix: @"-[NSException"] || [line hasPrefix: @"_AssertFailed"] ) - continue; - if( result.length ) - [result appendString: @"\n"]; - [result appendString: @"\t"]; - [result appendString: line]; - // Don't show the "__start" frame below "main": - if( [line hasPrefix: @"main "] ) - break; + if( file ) { + NSMutableData *output = [NSMutableData data]; + char buffer[512]; + size_t length; + while ((length = fread( buffer, 1, sizeof( buffer ), file ) )) + [output appendBytes: buffer length: length]; + pclose( file ); + NSString *outStr = [[[NSString alloc] initWithData: output encoding: NSUTF8StringEncoding] autorelease]; + + NSString *line; + foreach( line, [outStr componentsSeparatedByString: @"\n"] ) { + // Skip frames that are part of the exception/assertion handling itself: + if( [line hasPrefix: @"-[NSAssertionHandler"] || [line hasPrefix: @"+[NSException"] + || [line hasPrefix: @"-[NSException"] || [line hasPrefix: @"_AssertFailed"] + || [line hasPrefix: @"objc_"] ) + continue; + if( result.length ) + [result appendString: @"\n"]; + [result appendString: @"\t"]; + [result appendString: line]; + // Don't show the "__start" frame below "main": + if( [line hasPrefix: @"main "] ) + break; + } + } else { + NSValue *addr; + foreach(addr,addresses) { + if( result.length ) + [result appendString: @" <- "]; + [result appendFormat: @"%p", [addr pointerValue]]; + } } return result; } diff -r a9da6c5d3f7c -r a910102a1c9d MYErrorUtils.h --- a/MYErrorUtils.h Sat Apr 04 20:53:53 2009 -0700 +++ b/MYErrorUtils.h Tue Apr 07 11:13:25 2009 -0700 @@ -24,6 +24,13 @@ NSError *MYError( int errorCode, NSString *domain, NSString *messageFormat, ... ) __attribute__ ((format (__NSString__, 3, 4))); +/** A variant of MYError, useful for returning from a method. + If errorCode is nonzero, constructs an NSError and stores it into *outError, + then returns NO. Otherwise returns YES. */ +BOOL MYReturnError( NSError **outError, + int errorCode, NSString *domain, NSString *messageFormat, ... ) + __attribute__ ((format (__NSString__, 4, 5))); + /** Convenience function for creating NSErrors. Stores an NSError into *error, and returns NO. Domain will be MYErrorDomain, code will be kMYErrorMisc. diff -r a9da6c5d3f7c -r a910102a1c9d MYErrorUtils.m --- a/MYErrorUtils.m Sat Apr 04 20:53:53 2009 -0700 +++ b/MYErrorUtils.m Tue Apr 07 11:13:25 2009 -0700 @@ -10,6 +10,7 @@ #import "Test.h" #import "CollectionUtils.h" #import +#import NSString* const MYErrorDomain = @"MYErrorDomain"; @@ -39,6 +40,22 @@ } +BOOL MYReturnError( NSError **outError, + int errorCode, NSString *domain, NSString *messageFormat, ... ) +{ + if (errorCode) { + if (outError) { + va_list args; + va_start(args,messageFormat); + *outError = MYMakeErrorV(errorCode, domain, messageFormat, args); + va_end(args); + } + return NO; + } else + return YES; +} + + BOOL MYMiscError( NSError **error, NSString *message, ... ) { if (error) { @@ -106,7 +123,7 @@ result = nil; } } -#if !TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR +#if !TARGET_OS_IPHONE || defined(__SEC_TYPES__) else if ($equal(domain,NSOSStatusErrorDomain)) { // If it's an OSStatus, check whether CarbonCore knows its name: const char *name = NULL; diff -r a9da6c5d3f7c -r a910102a1c9d Test.m --- a/Test.m Sat Apr 04 20:53:53 2009 -0700 +++ b/Test.m Tue Apr 07 11:13:25 2009 -0700 @@ -107,9 +107,9 @@ } if( sPassed>0 || sFailed>0 || stopAfterTests ) { if( sFailed==0 ) - Log(@"√√√√√√ ALL %i TESTS PASSED √√√√√√", sPassed); + AlwaysLog(@"√√√√√√ ALL %i TESTS PASSED √√√√√√", sPassed); else { - Log(@"****** %i TESTS FAILED, %i PASSED ******", sFailed,sPassed); + Warn(@"****** %i TESTS FAILED, %i PASSED ******", sFailed,sPassed); exit(1); } if( stopAfterTests ) {