1// TEST_CONFIG
2
3#include "test.h"
4#include "testroot.i"
5#include <objc/runtime.h>
6
7static int state;
8
9#define ONE 1
10#define TWO 2
11#define LENGTH 3
12#define COUNT 4
13
14@interface Super : TestRoot @end
15@implementation Super
16+(void) one { state = ONE; }
17+(void) two { state = TWO; }
18+(void) length { state = LENGTH; }
19+(void) count { state = COUNT; }
20@end
21
22#define checkExchange(s1, v1, s2, v2)                                   \
23    do {                                                                \
24        Method m1, m2;                                                  \
25                                                                        \
26        testprintf("Check unexchanged version\n");                      \
27        state = 0;                                                      \
28        [Super s1];                                                     \
29        testassert(state == v1);                                        \
30        state = 0;                                                      \
31        [Super s2];                                                     \
32        testassert(state == v2);                                        \
33                                                                        \
34        testprintf("Exchange\n");                                       \
35        m1 = class_getClassMethod([Super class], @selector(s1));        \
36        m2 = class_getClassMethod([Super class], @selector(s2));        \
37        testassert(m1);                                                 \
38        testassert(m2);                                                 \
39        method_exchangeImplementations(m1, m2);                         \
40                                                                        \
41        testprintf("Check exchanged version\n");                        \
42        state = 0;                                                      \
43        [Super s1];                                                     \
44        testassert(state == v2);                                        \
45        state = 0;                                                      \
46        [Super s2];                                                     \
47        testassert(state == v1);                                        \
48                                                                        \
49        testprintf("NULL should do nothing\n");                         \
50        method_exchangeImplementations(m1, NULL);                       \
51        method_exchangeImplementations(NULL, m2);                       \
52        method_exchangeImplementations(NULL, NULL);                     \
53                                                                        \
54        testprintf("Make sure NULL did nothing\n");                     \
55        state = 0;                                                      \
56        [Super s1];                                                     \
57        testassert(state == v2);                                        \
58        state = 0;                                                      \
59        [Super s2];                                                     \
60        testassert(state == v1);                                        \
61                                                                        \
62        testprintf("Put them back\n");                                  \
63        method_exchangeImplementations(m1, m2);                         \
64                                                                        \
65        testprintf("Check restored version\n");                         \
66        state = 0;                                                      \
67        [Super s1];                                                     \
68        testassert(state == v1);                                        \
69        state = 0;                                                      \
70        [Super s2];                                                     \
71        testassert(state == v2);                                        \
72    } while (0) 
73
74int main()
75{
76    // Check ordinary selectors
77    checkExchange(one, ONE, two, TWO);
78
79    // Check vtable selectors
80    checkExchange(length, LENGTH, count, COUNT);
81
82    // Check ordinary<->vtable and vtable<->ordinary
83    checkExchange(count, COUNT, one, ONE);
84    checkExchange(two, TWO, length, LENGTH);
85
86    succeed(__FILE__);
87}
88