Commits

Anonymous committed a910102

* Added MYReturnError.
* Better iPhone support in ExceptionUtils.
* Make sure "All Tests Passed/Failed" message is always logged.

  • Participants
  • Parent commits a9da6c5

Comments (0)

Files changed (4)

File ExceptionUtils.m

 }
 
 
-@implementation NSException (MooseyardUtil)
+@implementation NSException (MYUtilities)
 
 
 - (NSArray*) my_callStackReturnAddresses
 
 - (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 <http://paste.lisp.org/display/47196>:
     NSMutableString *cmd = [NSMutableString stringWithFormat: @"/usr/bin/atos -p %d", getpid()];
     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;
 }

File MYErrorUtils.h

 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.

File MYErrorUtils.m

 #import "Test.h"
 #import "CollectionUtils.h"
 #import <Foundation/Foundation.h>
+#import <Security/SecBase.h>
 
 
 NSString* const MYErrorDomain = @"MYErrorDomain";
 }
 
 
+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) {
                 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;
     }
     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 ) {