1 // See instructions in weak.h
6 // Subclass of superclass that isn't there
7 @interface MyMissingSuper : MissingSuper
10 @implementation MyMissingSuper
11 +(int) method { return 1+[super method]; }
12 +(void) load { state++; }
15 // Subclass of subclass of superclass that isn't there
16 @interface MyMissingSub : MyMissingSuper
19 @implementation MyMissingSub
20 +(int) method { return 1+[super method]; }
21 +(void) load { state++; }
24 // Subclass of real superclass
25 @interface MyNotMissingSuper : NotMissingSuper
28 @implementation MyNotMissingSuper
29 +(int) method { return 1+[super method]; }
30 +(void) load { state++; }
33 // Subclass of subclass of superclass that isn't there
34 @interface MyNotMissingSub : MyNotMissingSuper
37 @implementation MyNotMissingSub
38 +(int) method { return 1+[super method]; }
39 +(void) load { state++; }
42 // Categories on all of the above
43 @interface MissingRoot (MissingRootExtras)
47 @implementation MissingRoot (MissingRootExtras)
48 +(void)load { state++; }
49 +(int) cat_method { return 40; }
52 @interface MissingSuper (MissingSuperExtras)
56 @implementation MissingSuper (MissingSuperExtras)
57 +(void)load { state++; }
58 +(int) cat_method { return 1+[super cat_method]; }
61 @interface MyMissingSuper (MyMissingSuperExtras)
65 @implementation MyMissingSuper (MyMissingSuperExtras)
66 +(void)load { state++; }
67 +(int) cat_method { return 1+[super cat_method]; }
70 @interface MyMissingSub (MyMissingSubExtras)
74 @implementation MyMissingSub (MyMissingSubExtras)
75 +(void)load { state++; }
76 +(int) cat_method { return 1+[super cat_method]; }
80 @interface NotMissingRoot (NotMissingRootExtras)
84 @implementation NotMissingRoot (NotMissingRootExtras)
85 +(void)load { state++; }
86 +(int) cat_method { return 30; }
89 @interface NotMissingSuper (NotMissingSuperExtras)
93 @implementation NotMissingSuper (NotMissingSuperExtras)
94 +(void)load { state++; }
95 +(int) cat_method { return 1+[super cat_method]; }
98 @interface MyNotMissingSuper (MyNotMissingSuperExtras)
102 @implementation MyNotMissingSuper (MyNotMissingSuperExtras)
103 +(void)load { state++; }
104 +(int) cat_method { return 1+[super cat_method]; }
107 @interface MyNotMissingSub (MyNotMissingSubExtras)
111 @implementation MyNotMissingSub (MyNotMissingSubExtras)
112 +(void)load { state++; }
113 +(int) cat_method { return 1+[super cat_method]; }
118 # define TESTIVAR(cond) testassert(cond)
120 # define TESTIVAR(cond) /* rdar */
123 static BOOL classInList(__unsafe_unretained Class classes[], const char *name)
125 for (int i = 0; classes[i] != nil; i++) {
126 if (0 == strcmp(class_getName(classes[i]), name)) return YES;
131 static BOOL classInNameList(const char **names, const char *name)
134 for (cp = names; *cp; cp++) {
135 if (0 == strcmp(*cp, name)) return YES;
140 int main(int argc __unused, char **argv)
143 if (strstr(argv[0], "-not-missing.exe")) {
145 } else if (strstr(argv[0], "-missing.exe")) {
148 fail("executable name must be weak*-missing.exe or weak*-not-missing.exe");
151 // class and category +load methods
152 if (weakMissing) testassert(state == 8);
153 else testassert(state == 16);
157 testassert([NotMissingRoot class]);
158 testassert([NotMissingSuper class]);
159 testassert([MyNotMissingSuper class]);
160 testassert([MyNotMissingSub class]);
162 testassert([MissingRoot class] == nil);
163 testassert([MissingSuper class] == nil);
164 testassert([MyMissingSuper class] == nil);
165 testassert([MyMissingSub class] == nil);
167 testassert([MissingRoot class]);
168 testassert([MissingSuper class]);
169 testassert([MyMissingSuper class]);
170 testassert([MyMissingSub class]);
174 testassert(objc_getClass("NotMissingRoot"));
175 testassert(objc_getClass("NotMissingSuper"));
176 testassert(objc_getClass("MyNotMissingSuper"));
177 testassert(objc_getClass("MyNotMissingSub"));
179 testassert(objc_getClass("MissingRoot") == nil);
180 testassert(objc_getClass("MissingSuper") == nil);
181 testassert(objc_getClass("MyMissingSuper") == nil);
182 testassert(objc_getClass("MyMissingSub") == nil);
184 testassert(objc_getClass("MissingRoot"));
185 testassert(objc_getClass("MissingSuper"));
186 testassert(objc_getClass("MyMissingSuper"));
187 testassert(objc_getClass("MyMissingSub"));
195 classes.c = objc_copyClassList(NULL);
196 testassert(classInList(classes.c, "NotMissingRoot"));
197 testassert(classInList(classes.c, "NotMissingSuper"));
198 testassert(classInList(classes.c, "MyNotMissingSuper"));
199 testassert(classInList(classes.c, "MyNotMissingSub"));
201 testassert(! classInList(classes.c, "MissingRoot"));
202 testassert(! classInList(classes.c, "MissingSuper"));
203 testassert(! classInList(classes.c, "MyMissingSuper"));
204 testassert(! classInList(classes.c, "MyMissingSub"));
206 testassert(classInList(classes.c, "MissingRoot"));
207 testassert(classInList(classes.c, "MissingSuper"));
208 testassert(classInList(classes.c, "MyMissingSuper"));
209 testassert(classInList(classes.c, "MyMissingSub"));
214 const char *image = class_getImageName(objc_getClass("NotMissingRoot"));
216 const char **names = objc_copyClassNamesForImage(image, NULL);
218 testassert(classInNameList(names, "NotMissingRoot"));
219 testassert(classInNameList(names, "NotMissingSuper"));
221 testassert(! classInNameList(names, "MissingRoot"));
222 testassert(! classInNameList(names, "MissingSuper"));
224 testassert(classInNameList(names, "MissingRoot"));
225 testassert(classInNameList(names, "MissingSuper"));
229 image = class_getImageName(objc_getClass("MyNotMissingSub"));
231 names = objc_copyClassNamesForImage(image, NULL);
233 testassert(classInNameList(names, "MyNotMissingSuper"));
234 testassert(classInNameList(names, "MyNotMissingSub"));
236 testassert(! classInNameList(names, "MyMissingSuper"));
237 testassert(! classInNameList(names, "MyMissingSub"));
239 testassert(classInNameList(names, "MyMissingSuper"));
240 testassert(classInNameList(names, "MyMissingSub"));
245 testassert(20 == [NotMissingRoot method]);
246 testassert(21 == [NotMissingSuper method]);
247 testassert(22 == [MyNotMissingSuper method]);
248 testassert(23 == [MyNotMissingSub method]);
250 testassert(0 == [MissingRoot method]);
251 testassert(0 == [MissingSuper method]);
252 testassert(0 == [MyMissingSuper method]);
253 testassert(0 == [MyMissingSub method]);
255 testassert(10 == [MissingRoot method]);
256 testassert(11 == [MissingSuper method]);
257 testassert(12 == [MyMissingSuper method]);
258 testassert(13 == [MyMissingSub method]);
262 testassert(30 == [NotMissingRoot cat_method]);
263 testassert(31 == [NotMissingSuper cat_method]);
264 testassert(32 == [MyNotMissingSuper cat_method]);
265 testassert(33 == [MyNotMissingSub cat_method]);
267 testassert(0 == [MissingRoot cat_method]);
268 testassert(0 == [MissingSuper cat_method]);
269 testassert(0 == [MyMissingSuper cat_method]);
270 testassert(0 == [MyMissingSub cat_method]);
272 testassert(40 == [MissingRoot cat_method]);
273 testassert(41 == [MissingSuper cat_method]);
274 testassert(42 == [MyMissingSuper cat_method]);
275 testassert(43 == [MyMissingSub cat_method]);
278 // allocations and ivars
280 NotMissingSuper *obj2;
282 testassert((obj = [[NotMissingRoot alloc] init]));
284 testassert((obj2 = [[NotMissingSuper alloc] init]));
285 TESTIVAR(obj2->ivar == 200);
287 testassert((obj2 = [[MyNotMissingSuper alloc] init]));
288 TESTIVAR(obj2->ivar == 200);
290 testassert((obj2 = [[MyNotMissingSub alloc] init]));
291 TESTIVAR(obj2->ivar == 200);
294 testassert([[MissingRoot alloc] init] == nil);
295 testassert([[MissingSuper alloc] init] == nil);
296 testassert([[MyMissingSuper alloc] init] == nil);
297 testassert([[MyMissingSub alloc] init] == nil);
299 testassert((obj = [[MissingRoot alloc] init]));
301 testassert((obj3 = [[MissingSuper alloc] init]));
302 TESTIVAR(obj3->ivar == 100);
304 testassert((obj3 = [[MyMissingSuper alloc] init]));
305 TESTIVAR(obj3->ivar == 100);
307 testassert((obj3 = [[MyMissingSub alloc] init]));
308 TESTIVAR(obj3->ivar == 100);
312 *strrchr(argv[0], '.') = 0;
313 succeed(basename(argv[0]));