]> git.saurik.com Git - apple/objc4.git/blobdiff - test/copyIvarList.m
objc4-437.tar.gz
[apple/objc4.git] / test / copyIvarList.m
diff --git a/test/copyIvarList.m b/test/copyIvarList.m
new file mode 100644 (file)
index 0000000..d7535a1
--- /dev/null
@@ -0,0 +1,111 @@
+#include "test.h"
+#include <string.h>
+#include <malloc/malloc.h>
+#include <objc/objc-runtime.h>
+
+@interface SuperIvars { 
+    id isa;
+    int ivar1;
+    int ivar2;
+} @end
+@implementation SuperIvars @end
+
+@interface SubIvars : SuperIvars { 
+    int ivar3;
+    int ivar4;
+} @end
+@implementation SubIvars @end
+
+
+@interface FourIvars {
+    int ivar1;
+    int ivar2;
+    int ivar3;
+    int ivar4;
+} @end
+@implementation FourIvars @end
+
+@interface NoIvars { } @end
+@implementation NoIvars @end
+
+static int isNamed(Ivar iv, const char *name)
+{
+    return (0 == strcmp(name, ivar_getName(iv)));
+}
+
+int main()
+{
+    Ivar *ivars;
+    unsigned int count;
+    Class cls;
+
+    cls = objc_getClass("SubIvars");
+    testassert(cls);
+
+    count = 100;
+    ivars = class_copyIvarList(cls, &count);
+    testassert(ivars);
+    testassert(count == 2);
+    testassert(isNamed(ivars[0], "ivar3"));
+    testassert(isNamed(ivars[1], "ivar4"));
+    // ivars[] should be null-terminated
+    testassert(ivars[2] == NULL);
+    free(ivars);
+
+    cls = objc_getClass("SuperIvars");
+    testassert(cls);
+
+    count = 100;
+    ivars = class_copyIvarList(cls, &count);
+    testassert(ivars);
+    testassert(count == 3);
+    testassert(isNamed(ivars[0], "isa"));
+    testassert(isNamed(ivars[1], "ivar1"));
+    testassert(isNamed(ivars[2], "ivar2"));
+    // ivars[] should be null-terminated
+    testassert(ivars[3] == NULL);
+    free(ivars);
+
+    // Check null-termination - this ivar list block would be 16 bytes
+    // if it weren't for the terminator
+    cls = objc_getClass("FourIvars");
+    testassert(cls);
+
+    count = 100;
+    ivars = class_copyIvarList(cls, &count);
+    testassert(ivars);
+    testassert(count == 4);
+    testassert(malloc_size(ivars) >= 5 * sizeof(Ivar));
+    testassert(ivars[3] != NULL);
+    testassert(ivars[4] == NULL);
+    free(ivars);
+
+    // Check NULL count parameter
+    ivars = class_copyIvarList(cls, NULL);
+    testassert(ivars);
+    testassert(ivars[4] == NULL);
+    testassert(ivars[3] != NULL);
+    free(ivars);
+
+    // Check NULL class parameter
+    count = 100;
+    ivars = class_copyIvarList(NULL, &count);
+    testassert(!ivars);
+    testassert(count == 0);
+    
+    // Check NULL class and count
+    ivars = class_copyIvarList(NULL, NULL);
+    testassert(!ivars);
+
+    // Check class with no ivars
+    cls = objc_getClass("NoIvars");
+    testassert(cls);
+
+    count = 100;
+    ivars = class_copyIvarList(cls, &count);
+    testassert(!ivars);
+    testassert(count == 0);
+
+    succeed(__FILE__);
+    return 0;
+}