-
Notifications
You must be signed in to change notification settings - Fork 517
/
Copy pathcopyPropertyList.m
167 lines (141 loc) · 4.16 KB
/
copyPropertyList.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
// TEST_CONFIG
#include "test.h"
#include <string.h>
#include <malloc/malloc.h>
#include <objc/objc-runtime.h>
OBJC_ROOT_CLASS
@interface SuperProps { id isa; int prop1; int prop2; }
@property int prop1;
@property int prop2;
@end
@implementation SuperProps
@synthesize prop1;
@synthesize prop2;
@end
@interface SubProps : SuperProps { int prop3; int prop4; }
@property int prop3;
@property int prop4;
@end
@implementation SubProps
@synthesize prop3;
@synthesize prop4;
@end
OBJC_ROOT_CLASS
@interface FourProps { int prop1; int prop2; int prop3; int prop4; }
@property int prop1;
@property int prop2;
@property int prop3;
@property int prop4;
@end
@implementation FourProps
@synthesize prop1;
@synthesize prop2;
@synthesize prop3;
@synthesize prop4;
@end
OBJC_ROOT_CLASS
@interface NoProps @end
@implementation NoProps @end
OBJC_ROOT_CLASS
@interface ClassProps
@property(readonly,class) int prop1;
@property(readonly,class) int prop2;
@property(readonly) int prop2;
@property(readonly) int prop3;
@end
@implementation ClassProps
+(int)prop1 { return 0; }
+(int)prop2 { return 0; }
-(int)prop2 { return 0; }
-(int)prop3 { return 0; }
@end
static int isNamed(objc_property_t p, const char *name)
{
return (0 == strcmp(name, property_getName(p)));
}
int main()
{
objc_property_t *props;
unsigned int count;
Class cls;
cls = objc_getClass("SubProps");
testassert(cls);
count = 100;
props = class_copyPropertyList(cls, &count);
testassert(props);
testassert(count == 2);
testassert((isNamed(props[0], "prop3") && isNamed(props[1], "prop4")) ||
(isNamed(props[1], "prop3") && isNamed(props[0], "prop4")));
// props[] should be null-terminated
testassert(props[2] == NULL);
free(props);
cls = objc_getClass("SuperProps");
testassert(cls);
count = 100;
props = class_copyPropertyList(cls, &count);
testassert(props);
testassert(count == 2);
testassert((isNamed(props[0], "prop1") && isNamed(props[1], "prop2")) ||
(isNamed(props[1], "prop1") && isNamed(props[0], "prop2")));
// props[] should be null-terminated
testassert(props[2] == NULL);
free(props);
// Check null-termination - this property list block would be 16 bytes
// if it weren't for the terminator
cls = objc_getClass("FourProps");
testassert(cls);
count = 100;
props = class_copyPropertyList(cls, &count);
testassert(props);
testassert(count == 4);
testassert(malloc_size(props) >= 5 * sizeof(objc_property_t));
testassert(props[3] != NULL);
testassert(props[4] == NULL);
free(props);
// Check NULL count parameter
props = class_copyPropertyList(cls, NULL);
testassert(props);
testassert(props[4] == NULL);
testassert(props[3] != NULL);
free(props);
// Check NULL class parameter
count = 100;
props = class_copyPropertyList(NULL, &count);
testassert(!props);
testassert(count == 0);
// Check NULL class and count
props = class_copyPropertyList(NULL, NULL);
testassert(!props);
// Check class with no properties
cls = objc_getClass("NoProps");
testassert(cls);
count = 100;
props = class_copyPropertyList(cls, &count);
testassert(!props);
testassert(count == 0);
// Check class properties
cls = objc_getClass("ClassProps");
testassert(cls);
count = 100;
props = class_copyPropertyList(cls, &count);
testassert(props);
testassert(count == 2);
testassert((isNamed(props[0], "prop2") && isNamed(props[1], "prop3")) ||
(isNamed(props[1], "prop2") && isNamed(props[0], "prop3")));
// props[] should be null-terminated
testassert(props[2] == NULL);
free(props);
cls = object_getClass(objc_getClass("ClassProps"));
testassert(cls);
count = 100;
props = class_copyPropertyList(cls, &count);
testassert(props);
testassert(count == 2);
testassert((isNamed(props[0], "prop1") && isNamed(props[1], "prop2")) ||
(isNamed(props[1], "prop1") && isNamed(props[0], "prop2")));
// props[] should be null-terminated
testassert(props[2] == NULL);
free(props);
succeed(__FILE__);
return 0;
}