* Assert macros now put the failure code in a separate segment.
authorJens Alfke <jens@mooseyard.com>
Sat May 17 13:14:48 2008 -0700 (2008-05-17)
changeset 9823e7e74088e
parent 8 5588347dfcbd
child 10 82a37ccf6b8c
* Assert macros now put the failure code in a separate segment.
* Added $string utility.
CollectionUtils.h
CollectionUtils.m
Test.h
     1.1 --- a/CollectionUtils.h	Wed May 07 16:47:44 2008 -0700
     1.2 +++ b/CollectionUtils.h	Sat May 17 13:14:48 2008 -0700
     1.3 @@ -32,6 +32,8 @@
     1.4  
     1.5  BOOL $equal(id obj1, id obj2);      // Like -isEqual: but works even if either/both are nil
     1.6  
     1.7 +NSString* $string( const char *utf8Str );
     1.8 +
     1.9  #define $sprintf(FORMAT, ARGS... )  [NSString stringWithFormat: (FORMAT), ARGS]
    1.10  
    1.11  #define $cast(CLASSNAME,OBJ)        ((CLASSNAME*)(_cast([CLASSNAME class],(OBJ))))
     2.1 --- a/CollectionUtils.m	Wed May 07 16:47:44 2008 -0700
     2.2 +++ b/CollectionUtils.m	Sat May 17 13:14:48 2008 -0700
     2.3 @@ -171,6 +171,15 @@
     2.4  }
     2.5  
     2.6  
     2.7 +NSString* $string( const char *utf8Str )
     2.8 +{
     2.9 +    if( utf8Str )
    2.10 +        return [NSString stringWithCString: utf8Str encoding: NSUTF8StringEncoding];
    2.11 +    else
    2.12 +        return nil;
    2.13 +}
    2.14 +
    2.15 +
    2.16  @implementation NSArray (MYUtils)
    2.17  
    2.18  - (BOOL) my_containsObjectIdenticalTo: (id)object
     3.1 --- a/Test.h	Wed May 07 16:47:44 2008 -0700
     3.2 +++ b/Test.h	Sat May 17 13:14:48 2008 -0700
     3.3 @@ -8,6 +8,7 @@
     3.4  
     3.5  #import <Foundation/Foundation.h>
     3.6  #import "CollectionUtils.h"
     3.7 +#import "Logging.h"
     3.8  
     3.9  
    3.10  /** Call this first thing in main() to run tests.
    3.11 @@ -36,7 +37,7 @@
    3.12          }
    3.13      Test cases are disabled if the DEBUG macro is not defined (i.e. in a release build). */
    3.14  #if DEBUG
    3.15 -#define TestCase(NAME)      void Test_##NAME(void); \
    3.16 +#define TestCase(NAME)      __attribute__ ((section ("__TEXT, Tests"))) void Test_##NAME(void); \
    3.17                              struct TestCaseLink linkToTest##NAME = {&Test_##NAME,#NAME}; \
    3.18                              __attribute__((constructor)) static void registerTestCase##NAME() \
    3.19                                  {linkToTest##NAME.next = gAllTestCases; gAllTestCases=&linkToTest##NAME; } \
    3.20 @@ -54,12 +55,22 @@
    3.21  
    3.22  /** General-purpose assertions, replacing NSAssert etc.. You can use these outside test cases. */
    3.23  
    3.24 -#define Assert(COND,MSG...)    do{ if( __builtin_expect(!(COND),NO) ) \
    3.25 -                                    _AssertFailed(self,(const char*)_cmd, __FILE__, __LINE__,\
    3.26 -                                                  #COND,##MSG,NULL); }while(0)
    3.27 -#define CAssert(COND,MSG...)    do{ if( __builtin_expect(!(COND),NO) ) \
    3.28 -                                    _AssertFailed(nil, __PRETTY_FUNCTION__, __FILE__, __LINE__,\
    3.29 -                                                  #COND,##MSG,NULL); }while(0)
    3.30 +#ifdef __cplusplus
    3.31 +    #define IN_SEGMENT_NORETURN(SEG)
    3.32 +#else
    3.33 +    #define IN_SEGMENT_NORETURN(SEG) auto __attribute__ ((section ("__TEXT, "#SEG))) __attribute__ ((noinline)) __attribute__((noreturn)) void _assertfailure_(void);\
    3.34 +                            _assertfailure_();\
    3.35 +                            void _assertfailure_(void)
    3.36 +#endif
    3.37 +
    3.38 +
    3.39 +#define Assert(COND,MSG...)    do{ if( __builtin_expect(!(COND),NO) ) { \
    3.40 +                                    IN_SEGMENT_NORETURN(Logging) {_AssertFailed(self,(const char*)_cmd, __FILE__, __LINE__,\
    3.41 +                                                        #COND,##MSG,NULL);} } }while(0)
    3.42 +#define CAssert(COND,MSG...)    do{ if( __builtin_expect(!(COND),NO) ) { \
    3.43 +                                    static const char *_name = __PRETTY_FUNCTION__;\
    3.44 +                                    IN_SEGMENT_NORETURN(Logging) {_AssertFailed(nil, _name, __FILE__, __LINE__,\
    3.45 +                                                        #COND,##MSG,NULL);} } }while(0)
    3.46  
    3.47  #define AssertEqual(VAL,EXPECTED)   do{ id _val = VAL, _expected = EXPECTED;\
    3.48                                          Assert(_val==_expected || [_val isEqual: _expected], @"Unexpected value for %s: %@ (expected %@)", #VAL,_val,_expected); \