7 #include <objc/runtime.h>
14 #define checkattrlist(attrs, attrcount, target) \
18 testassert(attrcount == target); \
19 testassert(malloc_size(attrs) >= \
20 (1+target) * sizeof(objc_property_attribute_t)); \
21 testassert(attrs[target].name == NULL); \
22 testassert(attrs[target].value == NULL); \
25 testassert(attrcount == 0); \
29 #define checkattr(attrs, i, n, v) \
31 char *attrsstart = (char *)attrs; \
32 char *attrsend = (char *)attrs + malloc_size(attrs); \
33 testassert((char*)(attrs+i+1) <= attrsend); \
34 testassert(attrs[i].name >= attrsstart); \
35 testassert(attrs[i].value >= attrsstart); \
36 testassert(attrs[i].name + strlen(attrs[i].name) + 1 <= attrsend); \
37 testassert(attrs[i].value + strlen(attrs[i].value) + 1 <= attrsend); \
38 if (n) testassert(0 == strcmp(attrs[i].name, n)); \
39 else testassert(attrs[i].name == NULL); \
40 if (v) testassert(0 == strcmp(attrs[i].value, v)); \
41 else testassert(attrs[i].value == NULL); \
47 objc_property_attribute_t *attrs;
48 unsigned int attrcount;
50 // STRING TO ATTRIBUTE LIST (property_copyAttributeList)
52 struct objc_property prop;
57 attrs = property_copyAttributeList(NULL, &attrcount);
59 testassert(attrcount == 0);
60 attrs = property_copyAttributeList(NULL, NULL);
66 attrs = property_copyAttributeList(&prop, &attrcount);
67 checkattrlist(attrs, attrcount, 0);
68 attrs = property_copyAttributeList(&prop, NULL);
74 attrs = property_copyAttributeList(&prop, &attrcount);
75 checkattrlist(attrs, attrcount, 0);
76 attrs = property_copyAttributeList(&prop, NULL);
82 attrs = property_copyAttributeList(&prop, &attrcount);
83 checkattrlist(attrs, attrcount, 0);
84 attrs = property_copyAttributeList(&prop, NULL);
87 // long and short names, with and without values
89 prop.attr = "?XX,',\"?!?!\"YY,\"''''\"";
90 attrs = property_copyAttributeList(&prop, &attrcount);
91 checkattrlist(attrs, attrcount, 4);
92 checkattr(attrs, 0, "?", "XX");
93 checkattr(attrs, 1, "'", "");
94 checkattr(attrs, 2, "?!?!", "YY");
95 checkattr(attrs, 3, "''''", "");
98 // all recognized attributes simultaneously, values with quotes
100 prop.attr = "T11,V2222,S333333\",G\"44444444,W,P,D,R,N,C,&";
101 attrs = property_copyAttributeList(&prop, &attrcount);
102 checkattrlist(attrs, attrcount, 11);
103 checkattr(attrs, 0, "T", "11");
104 checkattr(attrs, 1, "V", "2222");
105 checkattr(attrs, 2, "S", "333333\"");
106 checkattr(attrs, 3, "G", "\"44444444");
107 checkattr(attrs, 4, "W", "");
108 checkattr(attrs, 5, "P", "");
109 checkattr(attrs, 6, "D", "");
110 checkattr(attrs, 7, "R", "");
111 checkattr(attrs, 8, "N", "");
112 checkattr(attrs, 9, "C", "");
113 checkattr(attrs,10, "&", "");
118 prop.attr = "W,T11,P,?XX,D,V2222,R,',N,S333333\",C,\"?!?!\"YY,&,G\"44444444,\"''''\"";
119 attrs = property_copyAttributeList(&prop, &attrcount);
120 checkattrlist(attrs, attrcount, 15);
121 checkattr(attrs, 0, "W", "");
122 checkattr(attrs, 1, "T", "11");
123 checkattr(attrs, 2, "P", "");
124 checkattr(attrs, 3, "?", "XX");
125 checkattr(attrs, 4, "D", "");
126 checkattr(attrs, 5, "V", "2222");
127 checkattr(attrs, 6, "R", "");
128 checkattr(attrs, 7, "'", "");
129 checkattr(attrs, 8, "N", "");
130 checkattr(attrs, 9, "S", "333333\"");
131 checkattr(attrs,10, "C", "");
132 checkattr(attrs,11, "?!?!", "YY");
133 checkattr(attrs,12, "&", "");
134 checkattr(attrs,13, "G", "\"44444444");
135 checkattr(attrs,14, "''''", "");
138 // SEARCH ATTRIBUTE LIST (property_copyAttributeValue)
140 // null property, null name, empty name
141 value = property_copyAttributeValue(NULL, NULL);
143 value = property_copyAttributeValue(NULL, "foo");
145 value = property_copyAttributeValue(NULL, "");
147 value = property_copyAttributeValue(&prop, NULL);
149 value = property_copyAttributeValue(&prop, "");
152 // null attributes, empty attributes
154 value = property_copyAttributeValue(&prop, "foo");
157 value = property_copyAttributeValue(&prop, "foo");
160 // long and short names, with and without values
161 prop.attr = "?XX,',\"?!?!\"YY,\"''''\"";
162 value = property_copyAttributeValue(&prop, "missing");
164 value = property_copyAttributeValue(&prop, "X");
166 value = property_copyAttributeValue(&prop, "\"");
168 value = property_copyAttributeValue(&prop, "'''");
170 value = property_copyAttributeValue(&prop, "'''''");
173 value = property_copyAttributeValue(&prop, "?");
174 testassert(0 == strcmp(value, "XX"));
175 testassert(malloc_size(value) >= 1 + strlen(value));
177 value = property_copyAttributeValue(&prop, "'");
178 testassert(0 == strcmp(value, ""));
179 testassert(malloc_size(value) >= 1 + strlen(value));
181 value = property_copyAttributeValue(&prop, "?!?!");
182 testassert(0 == strcmp(value, "YY"));
183 testassert(malloc_size(value) >= 1 + strlen(value));
185 value = property_copyAttributeValue(&prop, "''''");
186 testassert(0 == strcmp(value, ""));
187 testassert(malloc_size(value) >= 1 + strlen(value));
190 // all recognized attributes simultaneously, values with quotes
191 prop.attr = "T11,V2222,S333333\",G\"44444444,W,P,D,R,N,C,&";
192 value = property_copyAttributeValue(&prop, "T");
193 testassert(0 == strcmp(value, "11"));
194 testassert(malloc_size(value) >= 1 + strlen(value));
196 value = property_copyAttributeValue(&prop, "V");
197 testassert(0 == strcmp(value, "2222"));
198 testassert(malloc_size(value) >= 1 + strlen(value));
200 value = property_copyAttributeValue(&prop, "S");
201 testassert(0 == strcmp(value, "333333\""));
202 testassert(malloc_size(value) >= 1 + strlen(value));
204 value = property_copyAttributeValue(&prop, "G");
205 testassert(0 == strcmp(value, "\"44444444"));
206 testassert(malloc_size(value) >= 1 + strlen(value));
208 value = property_copyAttributeValue(&prop, "W");
209 testassert(0 == strcmp(value, ""));
210 testassert(malloc_size(value) >= 1 + strlen(value));
212 value = property_copyAttributeValue(&prop, "P");
213 testassert(0 == strcmp(value, ""));
214 testassert(malloc_size(value) >= 1 + strlen(value));
216 value = property_copyAttributeValue(&prop, "D");
217 testassert(0 == strcmp(value, ""));
218 testassert(malloc_size(value) >= 1 + strlen(value));
220 value = property_copyAttributeValue(&prop, "R");
221 testassert(0 == strcmp(value, ""));
222 testassert(malloc_size(value) >= 1 + strlen(value));
224 value = property_copyAttributeValue(&prop, "N");
225 testassert(0 == strcmp(value, ""));
226 testassert(malloc_size(value) >= 1 + strlen(value));
228 value = property_copyAttributeValue(&prop, "C");
229 testassert(0 == strcmp(value, ""));
230 testassert(malloc_size(value) >= 1 + strlen(value));
232 value = property_copyAttributeValue(&prop, "&");
233 testassert(0 == strcmp(value, ""));
234 testassert(malloc_size(value) >= 1 + strlen(value));
237 // ATTRIBUTE LIST TO STRING (class_addProperty)
240 objc_property_t prop2;
243 ok = class_addProperty([TestRoot class], NULL, (objc_property_attribute_t *)1, 1);
247 ok = class_addProperty([TestRoot class], "test-null-desc", NULL, 0);
249 prop2 = class_getProperty([TestRoot class], "test-null-desc");
251 testassert(0 == strcmp(property_getAttributes(prop2), ""));
254 ok = class_addProperty([TestRoot class], "test-empty-desc", (objc_property_attribute_t*)1, 0);
256 prop2 = class_getProperty([TestRoot class], "test-empty-desc");
258 testassert(0 == strcmp(property_getAttributes(prop2), ""));
260 // long and short names, with and without values
261 objc_property_attribute_t attrs2[] = {
268 ok = class_addProperty([TestRoot class], "test-unrecognized", attrs2, 5);
270 prop2 = class_getProperty([TestRoot class], "test-unrecognized");
272 testassert(0 == strcmp(property_getAttributes(prop2), "?XX,',\"?!?!\"YY,\"''''\""));
274 // all recognized attributes simultaneously, values with quotes
275 objc_property_attribute_t attrs3[] = {
283 { "G", "\"44444444" },
288 ok = class_addProperty([TestRoot class], "test-recognized", attrs3, 11);
290 prop2 = class_getProperty([TestRoot class], "test-recognized");
292 testassert(0 == strcmp(property_getAttributes(prop2),
293 "&,C,N,R,D,P,W,G\"44444444,S333333\",V2222,T11"));
296 objc_property_attribute_t attrs4[] = {
305 { "G", "\"44444444" },
314 ok = class_addProperty([TestRoot class], "test-sink", attrs4, 16);
316 prop2 = class_getProperty([TestRoot class], "test-sink");
318 testassert(0 == strcmp(property_getAttributes(prop2),
319 "&,C,N,R,D,P,W,G\"44444444,S333333\",V2222,T11,"
320 "?XX,',\"?!?!\"YY,\"''''\""));