copyIvarList.m 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. // TEST_CONFIG
  2. #include "test.h"
  3. #include <string.h>
  4. #include <malloc/malloc.h>
  5. #include <objc/objc-runtime.h>
  6. OBJC_ROOT_CLASS
  7. @interface SuperIvars {
  8. id isa;
  9. int ivar1;
  10. int ivar2;
  11. } @end
  12. @implementation SuperIvars @end
  13. @interface SubIvars : SuperIvars {
  14. int ivar3;
  15. int ivar4;
  16. } @end
  17. @implementation SubIvars @end
  18. OBJC_ROOT_CLASS
  19. @interface FourIvars {
  20. int ivar1;
  21. int ivar2;
  22. int ivar3;
  23. int ivar4;
  24. } @end
  25. @implementation FourIvars @end
  26. OBJC_ROOT_CLASS
  27. @interface NoIvars { } @end
  28. @implementation NoIvars @end
  29. static int isNamed(Ivar iv, const char *name)
  30. {
  31. return (0 == strcmp(name, ivar_getName(iv)));
  32. }
  33. int main()
  34. {
  35. Ivar *ivars;
  36. unsigned int count;
  37. Class cls;
  38. cls = objc_getClass("SubIvars");
  39. testassert(cls);
  40. count = 100;
  41. ivars = class_copyIvarList(cls, &count);
  42. testassert(ivars);
  43. testassert(count == 2);
  44. testassert(isNamed(ivars[0], "ivar3"));
  45. testassert(isNamed(ivars[1], "ivar4"));
  46. // ivars[] should be null-terminated
  47. testassert(ivars[2] == NULL);
  48. free(ivars);
  49. cls = objc_getClass("SuperIvars");
  50. testassert(cls);
  51. count = 100;
  52. ivars = class_copyIvarList(cls, &count);
  53. testassert(ivars);
  54. testassert(count == 3);
  55. testassert(isNamed(ivars[0], "isa"));
  56. testassert(isNamed(ivars[1], "ivar1"));
  57. testassert(isNamed(ivars[2], "ivar2"));
  58. // ivars[] should be null-terminated
  59. testassert(ivars[3] == NULL);
  60. free(ivars);
  61. // Check null-termination - this ivar list block would be 16 bytes
  62. // if it weren't for the terminator
  63. cls = objc_getClass("FourIvars");
  64. testassert(cls);
  65. count = 100;
  66. ivars = class_copyIvarList(cls, &count);
  67. testassert(ivars);
  68. testassert(count == 4);
  69. testassert(malloc_size(ivars) >= 5 * sizeof(Ivar));
  70. testassert(ivars[3] != NULL);
  71. testassert(ivars[4] == NULL);
  72. free(ivars);
  73. // Check NULL count parameter
  74. ivars = class_copyIvarList(cls, NULL);
  75. testassert(ivars);
  76. testassert(ivars[4] == NULL);
  77. testassert(ivars[3] != NULL);
  78. free(ivars);
  79. // Check NULL class parameter
  80. count = 100;
  81. ivars = class_copyIvarList(NULL, &count);
  82. testassert(!ivars);
  83. testassert(count == 0);
  84. // Check NULL class and count
  85. ivars = class_copyIvarList(NULL, NULL);
  86. testassert(!ivars);
  87. // Check class with no ivars
  88. cls = objc_getClass("NoIvars");
  89. testassert(cls);
  90. count = 100;
  91. ivars = class_copyIvarList(cls, &count);
  92. testassert(!ivars);
  93. testassert(count == 0);
  94. succeed(__FILE__);
  95. return 0;
  96. }