# HG changeset patch # User Jens Alfke # Date 1211055288 25200 # Node ID 823e7e74088e97b80eec74a19adacf0817309d64 # Parent 5588347dfcbdb19f021cf6d9e8a0affcae104f2c * Assert macros now put the failure code in a separate segment. * Added $string utility. diff -r 5588347dfcbd -r 823e7e74088e CollectionUtils.h --- a/CollectionUtils.h Wed May 07 16:47:44 2008 -0700 +++ b/CollectionUtils.h Sat May 17 13:14:48 2008 -0700 @@ -32,6 +32,8 @@ BOOL $equal(id obj1, id obj2); // Like -isEqual: but works even if either/both are nil +NSString* $string( const char *utf8Str ); + #define $sprintf(FORMAT, ARGS... ) [NSString stringWithFormat: (FORMAT), ARGS] #define $cast(CLASSNAME,OBJ) ((CLASSNAME*)(_cast([CLASSNAME class],(OBJ)))) diff -r 5588347dfcbd -r 823e7e74088e CollectionUtils.m --- a/CollectionUtils.m Wed May 07 16:47:44 2008 -0700 +++ b/CollectionUtils.m Sat May 17 13:14:48 2008 -0700 @@ -171,6 +171,15 @@ } +NSString* $string( const char *utf8Str ) +{ + if( utf8Str ) + return [NSString stringWithCString: utf8Str encoding: NSUTF8StringEncoding]; + else + return nil; +} + + @implementation NSArray (MYUtils) - (BOOL) my_containsObjectIdenticalTo: (id)object diff -r 5588347dfcbd -r 823e7e74088e Test.h --- a/Test.h Wed May 07 16:47:44 2008 -0700 +++ b/Test.h Sat May 17 13:14:48 2008 -0700 @@ -8,6 +8,7 @@ #import #import "CollectionUtils.h" +#import "Logging.h" /** Call this first thing in main() to run tests. @@ -36,7 +37,7 @@ } Test cases are disabled if the DEBUG macro is not defined (i.e. in a release build). */ #if DEBUG -#define TestCase(NAME) void Test_##NAME(void); \ +#define TestCase(NAME) __attribute__ ((section ("__TEXT, Tests"))) void Test_##NAME(void); \ struct TestCaseLink linkToTest##NAME = {&Test_##NAME,#NAME}; \ __attribute__((constructor)) static void registerTestCase##NAME() \ {linkToTest##NAME.next = gAllTestCases; gAllTestCases=&linkToTest##NAME; } \ @@ -54,12 +55,22 @@ /** General-purpose assertions, replacing NSAssert etc.. You can use these outside test cases. */ -#define Assert(COND,MSG...) do{ if( __builtin_expect(!(COND),NO) ) \ - _AssertFailed(self,(const char*)_cmd, __FILE__, __LINE__,\ - #COND,##MSG,NULL); }while(0) -#define CAssert(COND,MSG...) do{ if( __builtin_expect(!(COND),NO) ) \ - _AssertFailed(nil, __PRETTY_FUNCTION__, __FILE__, __LINE__,\ - #COND,##MSG,NULL); }while(0) +#ifdef __cplusplus + #define IN_SEGMENT_NORETURN(SEG) +#else + #define IN_SEGMENT_NORETURN(SEG) auto __attribute__ ((section ("__TEXT, "#SEG))) __attribute__ ((noinline)) __attribute__((noreturn)) void _assertfailure_(void);\ + _assertfailure_();\ + void _assertfailure_(void) +#endif + + +#define Assert(COND,MSG...) do{ if( __builtin_expect(!(COND),NO) ) { \ + IN_SEGMENT_NORETURN(Logging) {_AssertFailed(self,(const char*)_cmd, __FILE__, __LINE__,\ + #COND,##MSG,NULL);} } }while(0) +#define CAssert(COND,MSG...) do{ if( __builtin_expect(!(COND),NO) ) { \ + static const char *_name = __PRETTY_FUNCTION__;\ + IN_SEGMENT_NORETURN(Logging) {_AssertFailed(nil, _name, __FILE__, __LINE__,\ + #COND,##MSG,NULL);} } }while(0) #define AssertEqual(VAL,EXPECTED) do{ id _val = VAL, _expected = EXPECTED;\ Assert(_val==_expected || [_val isEqual: _expected], @"Unexpected value for %s: %@ (expected %@)", #VAL,_val,_expected); \