propertyDesc.m 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334
  1. /*
  2. TEST_BUILD_OUTPUT
  3. .*propertyDesc.m:\d+:\d+: warning: null passed to a callee that requires a non-null argument \[-Wnonnull\]
  4. .*propertyDesc.m:\d+:\d+: warning: null passed to a callee that requires a non-null argument \[-Wnonnull\]
  5. .*propertyDesc.m:\d+:\d+: warning: null passed to a callee that requires a non-null argument \[-Wnonnull\]
  6. .*propertyDesc.m:\d+:\d+: warning: null passed to a callee that requires a non-null argument \[-Wnonnull\]
  7. .*propertyDesc.m:\d+:\d+: warning: null passed to a callee that requires a non-null argument \[-Wnonnull\]
  8. .*propertyDesc.m:\d+:\d+: warning: null passed to a callee that requires a non-null argument \[-Wnonnull\]
  9. .*propertyDesc.m:\d+:\d+: warning: null passed to a callee that requires a non-null argument \[-Wnonnull\]
  10. .*propertyDesc.m:\d+:\d+: warning: null passed to a callee that requires a non-null argument \[-Wnonnull\]
  11. END
  12. */
  13. #include "test.h"
  14. #include "testroot.i"
  15. #include <stdint.h>
  16. #include <string.h>
  17. #include <objc/runtime.h>
  18. struct objc_property {
  19. const char *name;
  20. const char *attr;
  21. };
  22. #define checkattrlist(attrs, attrcount, target) \
  23. do { \
  24. if (target > 0) { \
  25. testassert(attrs); \
  26. testassert(attrcount == target); \
  27. testassert(malloc_size(attrs) >= \
  28. (1+target) * sizeof(objc_property_attribute_t)); \
  29. testassert(attrs[target].name == NULL); \
  30. testassert(attrs[target].value == NULL); \
  31. } else { \
  32. testassert(!attrs); \
  33. testassert(attrcount == 0); \
  34. } \
  35. } while (0)
  36. #define checkattr(attrs, i, n, v) \
  37. do { \
  38. char *attrsstart = (char *)attrs; \
  39. char *attrsend = (char *)attrs + malloc_size(attrs); \
  40. testassert((char*)(attrs+i+1) <= attrsend); \
  41. testassert(attrs[i].name >= attrsstart); \
  42. testassert(attrs[i].value >= attrsstart); \
  43. testassert(attrs[i].name + strlen(attrs[i].name) + 1 <= attrsend); \
  44. testassert(attrs[i].value + strlen(attrs[i].value) + 1 <= attrsend); \
  45. if (n) testassert(0 == strcmp(attrs[i].name, n)); \
  46. else testassert(attrs[i].name == NULL); \
  47. if (v) testassert(0 == strcmp(attrs[i].value, v)); \
  48. else testassert(attrs[i].value == NULL); \
  49. } while (0)
  50. int main()
  51. {
  52. char *value;
  53. objc_property_attribute_t *attrs;
  54. unsigned int attrcount;
  55. // STRING TO ATTRIBUTE LIST (property_copyAttributeList)
  56. struct objc_property prop;
  57. prop.name = "test";
  58. // null property
  59. attrcount = 42;
  60. attrs = property_copyAttributeList(NULL, &attrcount);
  61. testassert(!attrs);
  62. testassert(attrcount == 0);
  63. attrs = property_copyAttributeList(NULL, NULL);
  64. testassert(!attrs);
  65. // null attributes
  66. attrcount = 42;
  67. prop.attr = NULL;
  68. attrs = property_copyAttributeList(&prop, &attrcount);
  69. checkattrlist(attrs, attrcount, 0);
  70. attrs = property_copyAttributeList(&prop, NULL);
  71. testassert(!attrs);
  72. // empty attributes
  73. attrcount = 42;
  74. prop.attr = "";
  75. attrs = property_copyAttributeList(&prop, &attrcount);
  76. checkattrlist(attrs, attrcount, 0);
  77. attrs = property_copyAttributeList(&prop, NULL);
  78. testassert(!attrs);
  79. // commas only
  80. attrcount = 42;
  81. prop.attr = ",,,";
  82. attrs = property_copyAttributeList(&prop, &attrcount);
  83. checkattrlist(attrs, attrcount, 0);
  84. attrs = property_copyAttributeList(&prop, NULL);
  85. testassert(!attrs);
  86. // long and short names, with and without values
  87. attrcount = 42;
  88. prop.attr = "?XX,',\"?!?!\"YY,\"''''\"";
  89. attrs = property_copyAttributeList(&prop, &attrcount);
  90. checkattrlist(attrs, attrcount, 4);
  91. checkattr(attrs, 0, "?", "XX");
  92. checkattr(attrs, 1, "'", "");
  93. checkattr(attrs, 2, "?!?!", "YY");
  94. checkattr(attrs, 3, "''''", "");
  95. free(attrs);
  96. // all recognized attributes simultaneously, values with quotes
  97. attrcount = 42;
  98. prop.attr = "T11,V2222,S333333\",G\"44444444,W,P,D,R,N,C,&";
  99. attrs = property_copyAttributeList(&prop, &attrcount);
  100. checkattrlist(attrs, attrcount, 11);
  101. checkattr(attrs, 0, "T", "11");
  102. checkattr(attrs, 1, "V", "2222");
  103. checkattr(attrs, 2, "S", "333333\"");
  104. checkattr(attrs, 3, "G", "\"44444444");
  105. checkattr(attrs, 4, "W", "");
  106. checkattr(attrs, 5, "P", "");
  107. checkattr(attrs, 6, "D", "");
  108. checkattr(attrs, 7, "R", "");
  109. checkattr(attrs, 8, "N", "");
  110. checkattr(attrs, 9, "C", "");
  111. checkattr(attrs,10, "&", "");
  112. free(attrs);
  113. // kitchen sink
  114. attrcount = 42;
  115. prop.attr = "W,T11,P,?XX,D,V2222,R,',N,S333333\",C,\"?!?!\"YY,&,G\"44444444,\"''''\"";
  116. attrs = property_copyAttributeList(&prop, &attrcount);
  117. checkattrlist(attrs, attrcount, 15);
  118. checkattr(attrs, 0, "W", "");
  119. checkattr(attrs, 1, "T", "11");
  120. checkattr(attrs, 2, "P", "");
  121. checkattr(attrs, 3, "?", "XX");
  122. checkattr(attrs, 4, "D", "");
  123. checkattr(attrs, 5, "V", "2222");
  124. checkattr(attrs, 6, "R", "");
  125. checkattr(attrs, 7, "'", "");
  126. checkattr(attrs, 8, "N", "");
  127. checkattr(attrs, 9, "S", "333333\"");
  128. checkattr(attrs,10, "C", "");
  129. checkattr(attrs,11, "?!?!", "YY");
  130. checkattr(attrs,12, "&", "");
  131. checkattr(attrs,13, "G", "\"44444444");
  132. checkattr(attrs,14, "''''", "");
  133. free(attrs);
  134. // SEARCH ATTRIBUTE LIST (property_copyAttributeValue)
  135. // null property, null name, empty name
  136. value = property_copyAttributeValue(NULL, NULL);
  137. testassert(!value);
  138. value = property_copyAttributeValue(NULL, "foo");
  139. testassert(!value);
  140. value = property_copyAttributeValue(NULL, "");
  141. testassert(!value);
  142. value = property_copyAttributeValue(&prop, NULL);
  143. testassert(!value);
  144. value = property_copyAttributeValue(&prop, "");
  145. testassert(!value);
  146. // null attributes, empty attributes
  147. prop.attr = NULL;
  148. value = property_copyAttributeValue(&prop, "foo");
  149. testassert(!value);
  150. prop.attr = "";
  151. value = property_copyAttributeValue(&prop, "foo");
  152. testassert(!value);
  153. // long and short names, with and without values
  154. prop.attr = "?XX,',\"?!?!\"YY,\"''''\"";
  155. value = property_copyAttributeValue(&prop, "missing");
  156. testassert(!value);
  157. value = property_copyAttributeValue(&prop, "X");
  158. testassert(!value);
  159. value = property_copyAttributeValue(&prop, "\"");
  160. testassert(!value);
  161. value = property_copyAttributeValue(&prop, "'''");
  162. testassert(!value);
  163. value = property_copyAttributeValue(&prop, "'''''");
  164. testassert(!value);
  165. value = property_copyAttributeValue(&prop, "?");
  166. testassert(0 == strcmp(value, "XX"));
  167. testassert(malloc_size(value) >= 1 + strlen(value));
  168. free(value);
  169. value = property_copyAttributeValue(&prop, "'");
  170. testassert(0 == strcmp(value, ""));
  171. testassert(malloc_size(value) >= 1 + strlen(value));
  172. free(value);
  173. value = property_copyAttributeValue(&prop, "?!?!");
  174. testassert(0 == strcmp(value, "YY"));
  175. testassert(malloc_size(value) >= 1 + strlen(value));
  176. free(value);
  177. value = property_copyAttributeValue(&prop, "''''");
  178. testassert(0 == strcmp(value, ""));
  179. testassert(malloc_size(value) >= 1 + strlen(value));
  180. free(value);
  181. // all recognized attributes simultaneously, values with quotes
  182. prop.attr = "T11,V2222,S333333\",G\"44444444,W,P,D,R,N,C,&";
  183. value = property_copyAttributeValue(&prop, "T");
  184. testassert(0 == strcmp(value, "11"));
  185. testassert(malloc_size(value) >= 1 + strlen(value));
  186. free(value);
  187. value = property_copyAttributeValue(&prop, "V");
  188. testassert(0 == strcmp(value, "2222"));
  189. testassert(malloc_size(value) >= 1 + strlen(value));
  190. free(value);
  191. value = property_copyAttributeValue(&prop, "S");
  192. testassert(0 == strcmp(value, "333333\""));
  193. testassert(malloc_size(value) >= 1 + strlen(value));
  194. free(value);
  195. value = property_copyAttributeValue(&prop, "G");
  196. testassert(0 == strcmp(value, "\"44444444"));
  197. testassert(malloc_size(value) >= 1 + strlen(value));
  198. free(value);
  199. value = property_copyAttributeValue(&prop, "W");
  200. testassert(0 == strcmp(value, ""));
  201. testassert(malloc_size(value) >= 1 + strlen(value));
  202. free(value);
  203. value = property_copyAttributeValue(&prop, "P");
  204. testassert(0 == strcmp(value, ""));
  205. testassert(malloc_size(value) >= 1 + strlen(value));
  206. free(value);
  207. value = property_copyAttributeValue(&prop, "D");
  208. testassert(0 == strcmp(value, ""));
  209. testassert(malloc_size(value) >= 1 + strlen(value));
  210. free(value);
  211. value = property_copyAttributeValue(&prop, "R");
  212. testassert(0 == strcmp(value, ""));
  213. testassert(malloc_size(value) >= 1 + strlen(value));
  214. free(value);
  215. value = property_copyAttributeValue(&prop, "N");
  216. testassert(0 == strcmp(value, ""));
  217. testassert(malloc_size(value) >= 1 + strlen(value));
  218. free(value);
  219. value = property_copyAttributeValue(&prop, "C");
  220. testassert(0 == strcmp(value, ""));
  221. testassert(malloc_size(value) >= 1 + strlen(value));
  222. free(value);
  223. value = property_copyAttributeValue(&prop, "&");
  224. testassert(0 == strcmp(value, ""));
  225. testassert(malloc_size(value) >= 1 + strlen(value));
  226. free(value);
  227. // ATTRIBUTE LIST TO STRING (class_addProperty)
  228. BOOL ok;
  229. objc_property_t prop2;
  230. // null name
  231. ok = class_addProperty([TestRoot class], NULL, (objc_property_attribute_t *)1, 1);
  232. testassert(!ok);
  233. // null description
  234. ok = class_addProperty([TestRoot class], "test-null-desc", NULL, 0);
  235. testassert(ok);
  236. prop2 = class_getProperty([TestRoot class], "test-null-desc");
  237. testassert(prop2);
  238. testassert(0 == strcmp(property_getAttributes(prop2), ""));
  239. // empty description
  240. ok = class_addProperty([TestRoot class], "test-empty-desc", (objc_property_attribute_t*)1, 0);
  241. testassert(ok);
  242. prop2 = class_getProperty([TestRoot class], "test-empty-desc");
  243. testassert(prop2);
  244. testassert(0 == strcmp(property_getAttributes(prop2), ""));
  245. // long and short names, with and without values
  246. objc_property_attribute_t attrs2[] = {
  247. { "!", NULL },
  248. { "?", "XX" },
  249. { "'", "" },
  250. { "?!?!", "YY" },
  251. { "''''", "" }
  252. };
  253. ok = class_addProperty([TestRoot class], "test-unrecognized", attrs2, 5);
  254. testassert(ok);
  255. prop2 = class_getProperty([TestRoot class], "test-unrecognized");
  256. testassert(prop2);
  257. testassert(0 == strcmp(property_getAttributes(prop2), "?XX,',\"?!?!\"YY,\"''''\""));
  258. // all recognized attributes simultaneously, values with quotes
  259. objc_property_attribute_t attrs3[] = {
  260. { "&", "" },
  261. { "C", "" },
  262. { "N", "" },
  263. { "R", "" },
  264. { "D", "" },
  265. { "P", "" },
  266. { "W", "" },
  267. { "G", "\"44444444" },
  268. { "S", "333333\"" },
  269. { "V", "2222" },
  270. { "T", "11" },
  271. };
  272. ok = class_addProperty([TestRoot class], "test-recognized", attrs3, 11);
  273. testassert(ok);
  274. prop2 = class_getProperty([TestRoot class], "test-recognized");
  275. testassert(prop2);
  276. testassert(0 == strcmp(property_getAttributes(prop2),
  277. "&,C,N,R,D,P,W,G\"44444444,S333333\",V2222,T11"));
  278. // kitchen sink
  279. objc_property_attribute_t attrs4[] = {
  280. { "&", "" },
  281. { "C", "" },
  282. { "N", "" },
  283. { "R", "" },
  284. { "D", "" },
  285. { "P", "" },
  286. { "W", "" },
  287. { "!", NULL },
  288. { "G", "\"44444444" },
  289. { "S", "333333\"" },
  290. { "V", "2222" },
  291. { "T", "11" },
  292. { "?", "XX" },
  293. { "'", "" },
  294. { "?!?!", "YY" },
  295. { "''''", "" }
  296. };
  297. ok = class_addProperty([TestRoot class], "test-sink", attrs4, 16);
  298. testassert(ok);
  299. prop2 = class_getProperty([TestRoot class], "test-sink");
  300. testassert(prop2);
  301. testassert(0 == strcmp(property_getAttributes(prop2),
  302. "&,C,N,R,D,P,W,G\"44444444,S333333\",V2222,T11,"
  303. "?XX,',\"?!?!\"YY,\"''''\""));
  304. succeed(__FILE__);
  305. }