]> git.saurik.com Git - apple/objc4.git/blob - test/addProtocol.m
objc4-551.1.tar.gz
[apple/objc4.git] / test / addProtocol.m
1 /*
2 TEST_RUN_OUTPUT
3 objc\[\d+\]: protocol_addProtocol: added protocol 'EmptyProto' is still under construction!
4 objc\[\d+\]: objc_registerProtocol: protocol 'Proto1' was already registered!
5 objc\[\d+\]: protocol_addProtocol: modified protocol 'Proto1' is not under construction!
6 objc\[\d+\]: protocol_addMethodDescription: protocol 'Proto1' is not under construction!
7 objc\[\d+\]: objc_registerProtocol: protocol 'SuperProto' was already registered!
8 objc\[\d+\]: protocol_addProtocol: modified protocol 'SuperProto' is not under construction!
9 objc\[\d+\]: protocol_addMethodDescription: protocol 'SuperProto' is not under construction!
10 OK: addProtocol.m
11 END
12 */
13
14 #include "test.h"
15
16 #include <objc/runtime.h>
17
18 @protocol SuperProto @end
19 @protocol SuperProto2 @end
20 @protocol UnrelatedProto @end
21
22 int main()
23 {
24 Protocol *proto, *proto2;
25 Protocol * __unsafe_unretained *protolist;
26 struct objc_method_description *desclist;
27 objc_property_t *proplist;
28 unsigned int count;
29
30 // make sure binary contains hard copies of these protocols
31 proto = @protocol(SuperProto);
32 proto = @protocol(SuperProto2);
33
34 // Adding a protocol
35
36 char *name = strdup("Proto1");
37 proto = objc_allocateProtocol(name);
38 testassert(proto);
39 testassert(!objc_getProtocol(name));
40
41 protocol_addProtocol(proto, @protocol(SuperProto));
42 protocol_addProtocol(proto, @protocol(SuperProto2));
43 // no inheritance cycles
44 proto2 = objc_allocateProtocol("EmptyProto");
45 protocol_addProtocol(proto, proto2); // fails
46 objc_registerProtocol(proto2);
47 protocol_addProtocol(proto, proto2); // succeeds
48
49 char *types = strdup("@:");
50 protocol_addMethodDescription(proto, @selector(ReqInst0), types, YES, YES);
51 protocol_addMethodDescription(proto, @selector(ReqInst1), types, YES, YES);
52 protocol_addMethodDescription(proto, @selector(ReqInst2), types, YES, YES);
53 protocol_addMethodDescription(proto, @selector(ReqInst3), types, YES, YES);
54
55 protocol_addMethodDescription(proto, @selector(ReqClas0), types, YES, NO);
56 protocol_addMethodDescription(proto, @selector(ReqClas1), types, YES, NO);
57 protocol_addMethodDescription(proto, @selector(ReqClas2), types, YES, NO);
58 protocol_addMethodDescription(proto, @selector(ReqClas3), types, YES, NO);
59
60 protocol_addMethodDescription(proto, @selector(OptInst0), types, NO, YES);
61 protocol_addMethodDescription(proto, @selector(OptInst1), types, NO, YES);
62 protocol_addMethodDescription(proto, @selector(OptInst2), types, NO, YES);
63 protocol_addMethodDescription(proto, @selector(OptInst3), types, NO, YES);
64
65 protocol_addMethodDescription(proto, @selector(OptClas0), types, NO, NO);
66 protocol_addMethodDescription(proto, @selector(OptClas1), types, NO, NO);
67 protocol_addMethodDescription(proto, @selector(OptClas2), types, NO, NO);
68 protocol_addMethodDescription(proto, @selector(OptClas3), types, NO, NO);
69
70 char *name0 = strdup("ReqInst0");
71 char *name1 = strdup("ReqInst1");
72 char *name2 = strdup("ReqInst2");
73 char *name3 = strdup("ReqInst3");
74 char *attrname = strdup("T");
75 char *attrvalue = strdup("i");
76 objc_property_attribute_t attrs[] = {{attrname, attrvalue}};
77 int attrcount = sizeof(attrs) / sizeof(attrs[0]);
78 protocol_addProperty(proto, name0, attrs, attrcount, YES, YES);
79 protocol_addProperty(proto, name1, attrs, attrcount, YES, YES);
80 protocol_addProperty(proto, name2, attrs, attrcount, YES, YES);
81 protocol_addProperty(proto, name3, attrs, attrcount, YES, YES);
82
83 objc_registerProtocol(proto);
84 testassert(0 == strcmp(protocol_getName(proto), "Proto1"));
85
86 // Use of added protocols
87
88 testassert(proto == objc_getProtocol("Proto1"));
89 strcpy(name, "XXXXXX"); // name is copied
90 testassert(0 == strcmp(protocol_getName(proto), "Proto1"));
91
92 protolist = protocol_copyProtocolList(proto, &count);
93 testassert(protolist);
94 testassert(count == 3);
95 // note this order is not required
96 testassert(protolist[0] == @protocol(SuperProto) &&
97 protolist[1] == @protocol(SuperProto2) &&
98 protolist[2] == proto2);
99 free(protolist);
100
101 testassert(protocol_conformsToProtocol(proto, proto2));
102 testassert(protocol_conformsToProtocol(proto, @protocol(SuperProto)));
103 testassert(!protocol_conformsToProtocol(proto, @protocol(UnrelatedProto)));
104
105 strcpy(types, "XX"); // types is copied
106 desclist = protocol_copyMethodDescriptionList(proto, YES, YES, &count);
107 testassert(desclist && count == 4);
108 testprintf("%p %p\n", desclist[0].name, @selector(ReqInst0));
109 // testassert(desclist[0].name == @selector(ReqInst0));
110 testassert(0 == strcmp(desclist[0].types, "@:"));
111 free(desclist);
112 desclist = protocol_copyMethodDescriptionList(proto, YES, NO, &count);
113 testassert(desclist && count == 4);
114 testassert(desclist[1].name == @selector(ReqClas1));
115 testassert(0 == strcmp(desclist[1].types, "@:"));
116 free(desclist);
117 desclist = protocol_copyMethodDescriptionList(proto, NO, YES, &count);
118 testassert(desclist && count == 4);
119 testassert(desclist[2].name == @selector(OptInst2));
120 testassert(0 == strcmp(desclist[2].types, "@:"));
121 free(desclist);
122 desclist = protocol_copyMethodDescriptionList(proto, NO, NO, &count);
123 testassert(desclist && count == 4);
124 testassert(desclist[3].name == @selector(OptClas3));
125 testassert(0 == strcmp(desclist[3].types, "@:"));
126 free(desclist);
127
128 strcpy(name0, "XXXXXXXX"); // name is copied
129 strcpy(name1, "XXXXXXXX"); // name is copied
130 strcpy(name2, "XXXXXXXX"); // name is copied
131 strcpy(name3, "XXXXXXXX"); // name is copied
132 strcpy(attrname, "X"); // description is copied
133 strcpy(attrvalue, "X"); // description is copied
134 memset(attrs, 'X', sizeof(attrs)); // description is copied
135 proplist = protocol_copyPropertyList(proto, &count);
136 testassert(proplist);
137 testassert(count == 4);
138 // note this order is not required
139 testassert(0 == strcmp(property_getName(proplist[0]), "ReqInst0"));
140 testassert(0 == strcmp(property_getName(proplist[1]), "ReqInst1"));
141 testassert(0 == strcmp(property_getName(proplist[2]), "ReqInst2"));
142 testassert(0 == strcmp(property_getName(proplist[3]), "ReqInst3"));
143 testassert(0 == strcmp(property_getAttributes(proplist[0]), "Ti"));
144 testassert(0 == strcmp(property_getAttributes(proplist[1]), "Ti"));
145 testassert(0 == strcmp(property_getAttributes(proplist[2]), "Ti"));
146 testassert(0 == strcmp(property_getAttributes(proplist[3]), "Ti"));
147 free(proplist);
148
149
150 testassert(proto2 == objc_getProtocol("EmptyProto"));
151 testassert(0 == strcmp(protocol_getName(proto2), "EmptyProto"));
152
153 protolist = protocol_copyProtocolList(proto2, &count);
154 testassert(!protolist);
155 testassert(count == 0);
156
157 testassert(!protocol_conformsToProtocol(proto2, proto));
158 testassert(!protocol_conformsToProtocol(proto2,@protocol(SuperProto)));
159 testassert(!protocol_conformsToProtocol(proto2,@protocol(UnrelatedProto)));
160
161 desclist = protocol_copyMethodDescriptionList(proto2, YES, YES, &count);
162 testassert(!desclist && count == 0);
163 desclist = protocol_copyMethodDescriptionList(proto2, YES, NO, &count);
164 testassert(!desclist && count == 0);
165 desclist = protocol_copyMethodDescriptionList(proto2, NO, YES, &count);
166 testassert(!desclist && count == 0);
167 desclist = protocol_copyMethodDescriptionList(proto2, NO, NO, &count);
168 testassert(!desclist && count == 0);
169
170 // Immutability of existing protocols
171
172 objc_registerProtocol(proto);
173 protocol_addProtocol(proto, @protocol(SuperProto2));
174 protocol_addMethodDescription(proto, @selector(foo), "", YES, YES);
175
176 objc_registerProtocol(@protocol(SuperProto));
177 protocol_addProtocol(@protocol(SuperProto), @protocol(SuperProto2));
178 protocol_addMethodDescription(@protocol(SuperProto), @selector(foo), "", YES, YES);
179
180 // No duplicates
181
182 proto = objc_allocateProtocol("SuperProto");
183 testassert(!proto);
184 proto = objc_allocateProtocol("Proto1");
185 testassert(!proto);
186
187 // NULL protocols ignored
188
189 protocol_addProtocol((Protocol *)objc_unretainedObject((void*)1), NULL);
190 protocol_addProtocol(NULL, (Protocol *)objc_unretainedObject((void*)1));
191 protocol_addProtocol(NULL, NULL);
192 protocol_addMethodDescription(NULL, @selector(foo), "", YES, YES);
193
194 succeed(__FILE__);
195 }