* Added MYReturnError.
authorsnej@snej-mbp.mtv.corp.google.com
Tue Apr 07 11:13:25 2009 -0700 (2009-04-07)
changeset 23a910102a1c9d
parent 22 a9da6c5d3f7c
child 24 629c7605ab2a
* Added MYReturnError.
* Better iPhone support in ExceptionUtils.
* Make sure "All Tests Passed/Failed" message is always logged.
ExceptionUtils.m
MYErrorUtils.h
MYErrorUtils.m
Test.m
     1.1 --- a/ExceptionUtils.m	Sat Apr 04 20:53:53 2009 -0700
     1.2 +++ b/ExceptionUtils.m	Tue Apr 07 11:13:25 2009 -0700
     1.3 @@ -43,7 +43,7 @@
     1.4  }
     1.5  
     1.6  
     1.7 -@implementation NSException (MooseyardUtil)
     1.8 +@implementation NSException (MYUtilities)
     1.9  
    1.10  
    1.11  - (NSArray*) my_callStackReturnAddresses
    1.12 @@ -70,10 +70,12 @@
    1.13  
    1.14  - (NSString*) my_callStack
    1.15  {
    1.16 -    NSArray *addresses = [self my_callStackReturnAddressesSkipping: 2 limit: 15];
    1.17 +    NSArray *addresses = [self my_callStackReturnAddressesSkipping: 1 limit: 15];
    1.18      if (!addresses)
    1.19          return nil;
    1.20      
    1.21 +    FILE *file = NULL;
    1.22 +#if !TARGET_OS_IPHONE
    1.23      // We pipe the hex return addresses through the 'atos' tool to get symbolic names:
    1.24      // Adapted from <http://paste.lisp.org/display/47196>:
    1.25      NSMutableString *cmd = [NSMutableString stringWithFormat: @"/usr/bin/atos -p %d", getpid()];
    1.26 @@ -81,32 +83,41 @@
    1.27      foreach(addr,addresses) {
    1.28          [cmd appendFormat: @" %p", [addr pointerValue]];
    1.29      }
    1.30 -    FILE *file = popen( [cmd UTF8String], "r" );
    1.31 -    if( ! file )
    1.32 -        return nil;
    1.33 -    
    1.34 -    NSMutableData *output = [NSMutableData data];
    1.35 -    char buffer[512];
    1.36 -    size_t length;
    1.37 -    while ((length = fread( buffer, 1, sizeof( buffer ), file ) ))
    1.38 -        [output appendBytes: buffer length: length];
    1.39 -    pclose( file );
    1.40 -    NSString *outStr = [[[NSString alloc] initWithData: output encoding: NSUTF8StringEncoding] autorelease];
    1.41 +    file = popen( [cmd UTF8String], "r" );
    1.42 +#endif
    1.43      
    1.44      NSMutableString *result = [NSMutableString string];
    1.45 -    NSString *line;
    1.46 -    foreach( line, [outStr componentsSeparatedByString: @"\n"] ) {
    1.47 -        // Skip  frames that are part of the exception/assertion handling itself:
    1.48 -        if( [line hasPrefix: @"-[NSAssertionHandler"] || [line hasPrefix: @"+[NSException"] 
    1.49 -                || [line hasPrefix: @"-[NSException"] || [line hasPrefix: @"_AssertFailed"] )
    1.50 -            continue;
    1.51 -        if( result.length )
    1.52 -            [result appendString: @"\n"];
    1.53 -        [result appendString: @"\t"];
    1.54 -        [result appendString: line];
    1.55 -        // Don't show the "__start" frame below "main":
    1.56 -        if( [line hasPrefix: @"main "] )
    1.57 -            break;
    1.58 +    if( file ) {
    1.59 +        NSMutableData *output = [NSMutableData data];
    1.60 +        char buffer[512];
    1.61 +        size_t length;
    1.62 +        while ((length = fread( buffer, 1, sizeof( buffer ), file ) ))
    1.63 +            [output appendBytes: buffer length: length];
    1.64 +        pclose( file );
    1.65 +        NSString *outStr = [[[NSString alloc] initWithData: output encoding: NSUTF8StringEncoding] autorelease];
    1.66 +        
    1.67 +        NSString *line;
    1.68 +        foreach( line, [outStr componentsSeparatedByString: @"\n"] ) {
    1.69 +            // Skip  frames that are part of the exception/assertion handling itself:
    1.70 +            if( [line hasPrefix: @"-[NSAssertionHandler"] || [line hasPrefix: @"+[NSException"] 
    1.71 +                    || [line hasPrefix: @"-[NSException"] || [line hasPrefix: @"_AssertFailed"]
    1.72 +                    || [line hasPrefix: @"objc_"] )
    1.73 +                continue;
    1.74 +            if( result.length )
    1.75 +                [result appendString: @"\n"];
    1.76 +            [result appendString: @"\t"];
    1.77 +            [result appendString: line];
    1.78 +            // Don't show the "__start" frame below "main":
    1.79 +            if( [line hasPrefix: @"main "] )
    1.80 +                break;
    1.81 +        }
    1.82 +    } else {
    1.83 +        NSValue *addr;
    1.84 +        foreach(addr,addresses) {
    1.85 +            if( result.length )
    1.86 +                [result appendString: @" <- "];
    1.87 +            [result appendFormat: @"%p", [addr pointerValue]];
    1.88 +        }
    1.89      }
    1.90      return result;
    1.91  }
     2.1 --- a/MYErrorUtils.h	Sat Apr 04 20:53:53 2009 -0700
     2.2 +++ b/MYErrorUtils.h	Tue Apr 07 11:13:25 2009 -0700
     2.3 @@ -24,6 +24,13 @@
     2.4  NSError *MYError( int errorCode, NSString *domain, NSString *messageFormat, ... ) 
     2.5                                  __attribute__ ((format (__NSString__, 3, 4)));
     2.6  
     2.7 +/** A variant of MYError, useful for returning from a method.
     2.8 +    If errorCode is nonzero, constructs an NSError and stores it into *outError,
     2.9 +    then returns NO. Otherwise returns YES. */
    2.10 +BOOL MYReturnError( NSError **outError,
    2.11 +                    int errorCode, NSString *domain, NSString *messageFormat, ... ) 
    2.12 +                                __attribute__ ((format (__NSString__, 4, 5)));
    2.13 +
    2.14  /** Convenience function for creating NSErrors.
    2.15      Stores an NSError into *error, and returns NO.
    2.16      Domain will be MYErrorDomain, code will be kMYErrorMisc.
     3.1 --- a/MYErrorUtils.m	Sat Apr 04 20:53:53 2009 -0700
     3.2 +++ b/MYErrorUtils.m	Tue Apr 07 11:13:25 2009 -0700
     3.3 @@ -10,6 +10,7 @@
     3.4  #import "Test.h"
     3.5  #import "CollectionUtils.h"
     3.6  #import <Foundation/Foundation.h>
     3.7 +#import <Security/SecBase.h>
     3.8  
     3.9  
    3.10  NSString* const MYErrorDomain = @"MYErrorDomain";
    3.11 @@ -39,6 +40,22 @@
    3.12  }
    3.13  
    3.14  
    3.15 +BOOL MYReturnError( NSError **outError,
    3.16 +                    int errorCode, NSString *domain, NSString *messageFormat, ... ) 
    3.17 +{
    3.18 +    if (errorCode) {
    3.19 +        if (outError) {
    3.20 +            va_list args;
    3.21 +            va_start(args,messageFormat);
    3.22 +            *outError = MYMakeErrorV(errorCode, domain, messageFormat, args);
    3.23 +            va_end(args);
    3.24 +        }
    3.25 +        return NO;
    3.26 +    } else
    3.27 +        return YES;
    3.28 +}
    3.29 +
    3.30 +
    3.31  BOOL MYMiscError( NSError **error, NSString *message, ... )
    3.32  {
    3.33      if (error) {
    3.34 @@ -106,7 +123,7 @@
    3.35                  result = nil;
    3.36          }
    3.37      } 
    3.38 -#if !TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
    3.39 +#if !TARGET_OS_IPHONE || defined(__SEC_TYPES__)
    3.40      else if ($equal(domain,NSOSStatusErrorDomain)) {
    3.41          // If it's an OSStatus, check whether CarbonCore knows its name:
    3.42          const char *name = NULL;
     4.1 --- a/Test.m	Sat Apr 04 20:53:53 2009 -0700
     4.2 +++ b/Test.m	Tue Apr 07 11:13:25 2009 -0700
     4.3 @@ -107,9 +107,9 @@
     4.4      }
     4.5      if( sPassed>0 || sFailed>0 || stopAfterTests ) {
     4.6          if( sFailed==0 )
     4.7 -            Log(@"√√√√√√ ALL %i TESTS PASSED √√√√√√", sPassed);
     4.8 +            AlwaysLog(@"√√√√√√ ALL %i TESTS PASSED √√√√√√", sPassed);
     4.9          else {
    4.10 -            Log(@"****** %i TESTS FAILED, %i PASSED ******", sFailed,sPassed);
    4.11 +            Warn(@"****** %i TESTS FAILED, %i PASSED ******", sFailed,sPassed);
    4.12              exit(1);
    4.13          }
    4.14          if( stopAfterTests ) {