* Assert macros now put the failure code in a separate segment.
* Added $string utility.
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); \