1// TEST_CONFIG 2 3#include "test.h" 4#include <string.h> 5#include <malloc/malloc.h> 6#include <objc/objc-runtime.h> 7 8OBJC_ROOT_CLASS 9@interface SuperIvars { 10 id isa; 11 int ivar1; 12 int ivar2; 13} @end 14@implementation SuperIvars @end 15 16@interface SubIvars : SuperIvars { 17 int ivar3; 18 int ivar4; 19} @end 20@implementation SubIvars @end 21 22OBJC_ROOT_CLASS 23@interface FourIvars { 24 int ivar1; 25 int ivar2; 26 int ivar3; 27 int ivar4; 28} @end 29@implementation FourIvars @end 30 31OBJC_ROOT_CLASS 32@interface NoIvars { } @end 33@implementation NoIvars @end 34 35static int isNamed(Ivar iv, const char *name) 36{ 37 return (0 == strcmp(name, ivar_getName(iv))); 38} 39 40int main() 41{ 42 Ivar *ivars; 43 unsigned int count; 44 Class cls; 45 46 cls = objc_getClass("SubIvars"); 47 testassert(cls); 48 49 count = 100; 50 ivars = class_copyIvarList(cls, &count); 51 testassert(ivars); 52 testassert(count == 2); 53 testassert(isNamed(ivars[0], "ivar3")); 54 testassert(isNamed(ivars[1], "ivar4")); 55 // ivars[] should be null-terminated 56 testassert(ivars[2] == NULL); 57 free(ivars); 58 59 cls = objc_getClass("SuperIvars"); 60 testassert(cls); 61 62 count = 100; 63 ivars = class_copyIvarList(cls, &count); 64 testassert(ivars); 65 testassert(count == 3); 66 testassert(isNamed(ivars[0], "isa")); 67 testassert(isNamed(ivars[1], "ivar1")); 68 testassert(isNamed(ivars[2], "ivar2")); 69 // ivars[] should be null-terminated 70 testassert(ivars[3] == NULL); 71 free(ivars); 72 73 // Check null-termination - this ivar list block would be 16 bytes 74 // if it weren't for the terminator 75 cls = objc_getClass("FourIvars"); 76 testassert(cls); 77 78 count = 100; 79 ivars = class_copyIvarList(cls, &count); 80 testassert(ivars); 81 testassert(count == 4); 82 testassert(malloc_size(ivars) >= 5 * sizeof(Ivar)); 83 testassert(ivars[3] != NULL); 84 testassert(ivars[4] == NULL); 85 free(ivars); 86 87 // Check NULL count parameter 88 ivars = class_copyIvarList(cls, NULL); 89 testassert(ivars); 90 testassert(ivars[4] == NULL); 91 testassert(ivars[3] != NULL); 92 free(ivars); 93 94 // Check NULL class parameter 95 count = 100; 96 ivars = class_copyIvarList(NULL, &count); 97 testassert(!ivars); 98 testassert(count == 0); 99 100 // Check NULL class and count 101 ivars = class_copyIvarList(NULL, NULL); 102 testassert(!ivars); 103 104 // Check class with no ivars 105 cls = objc_getClass("NoIvars"); 106 testassert(cls); 107 108 count = 100; 109 ivars = class_copyIvarList(cls, &count); 110 testassert(!ivars); 111 testassert(count == 0); 112 113 succeed(__FILE__); 114 return 0; 115} 116