ptrarray.c 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349
  1. #include <stdio.h>
  2. #include <glib.h>
  3. #include "test.h"
  4. /* Redefine the private structure only to verify proper allocations */
  5. typedef struct _GPtrArrayPriv {
  6. gpointer *pdata;
  7. guint len;
  8. guint size;
  9. } GPtrArrayPriv;
  10. /* Don't add more than 32 items to this please */
  11. static const char *items [] = {
  12. "Apples", "Oranges", "Plumbs", "Goats", "Snorps", "Grapes",
  13. "Tickle", "Place", "Coffee", "Cookies", "Cake", "Cheese",
  14. "Tseng", "Holiday", "Avenue", "Smashing", "Water", "Toilet",
  15. NULL
  16. };
  17. static GPtrArray *ptrarray_alloc_and_fill(guint *item_count)
  18. {
  19. GPtrArray *array = g_ptr_array_new();
  20. gint i;
  21. for(i = 0; items[i] != NULL; i++) {
  22. g_ptr_array_add(array, (gpointer)items[i]);
  23. }
  24. if(item_count != NULL) {
  25. *item_count = i;
  26. }
  27. return array;
  28. }
  29. static guint guess_size(guint length)
  30. {
  31. guint size = 1;
  32. while(size < length) {
  33. size <<= 1;
  34. }
  35. return size;
  36. }
  37. RESULT ptrarray_alloc()
  38. {
  39. GPtrArrayPriv *array;
  40. guint i;
  41. array = (GPtrArrayPriv *)ptrarray_alloc_and_fill(&i);
  42. if(array->size != guess_size(array->len)) {
  43. return FAILED("Size should be %d, but it is %d",
  44. guess_size(array->len), array->size);
  45. }
  46. if(array->len != i) {
  47. return FAILED("Expected %d node(s) in the array", i);
  48. }
  49. g_ptr_array_free((GPtrArray *)array, TRUE);
  50. return OK;
  51. }
  52. RESULT ptrarray_for_iterate()
  53. {
  54. GPtrArray *array = ptrarray_alloc_and_fill(NULL);
  55. guint i;
  56. for(i = 0; i < array->len; i++) {
  57. char *item = (char *)g_ptr_array_index(array, i);
  58. if(item != items[i]) {
  59. return FAILED(
  60. "Expected item at %d to be %s, but it was %s",
  61. i, items[i], item);
  62. }
  63. }
  64. g_ptr_array_free(array, TRUE);
  65. return OK;
  66. }
  67. static gint foreach_iterate_index = 0;
  68. static char *foreach_iterate_error = NULL;
  69. void foreach_callback(gpointer data, gpointer user_data)
  70. {
  71. char *item = (char *)data;
  72. const char *item_cmp = items[foreach_iterate_index++];
  73. if(foreach_iterate_error != NULL) {
  74. return;
  75. }
  76. if(item != item_cmp) {
  77. foreach_iterate_error = FAILED(
  78. "Expected item at %d to be %s, but it was %s",
  79. foreach_iterate_index - 1, item_cmp, item);
  80. }
  81. }
  82. RESULT ptrarray_foreach_iterate()
  83. {
  84. GPtrArray *array = ptrarray_alloc_and_fill(NULL);
  85. foreach_iterate_index = 0;
  86. foreach_iterate_error = NULL;
  87. g_ptr_array_foreach(array, foreach_callback, array);
  88. g_ptr_array_free(array, TRUE);
  89. return foreach_iterate_error;
  90. }
  91. RESULT ptrarray_set_size()
  92. {
  93. GPtrArray *array = g_ptr_array_new();
  94. guint i, grow_length = 50;
  95. g_ptr_array_add(array, (gpointer)items[0]);
  96. g_ptr_array_add(array, (gpointer)items[1]);
  97. g_ptr_array_set_size(array, grow_length);
  98. if(array->len != grow_length) {
  99. return FAILED("Array length should be 50, it is %d", array->len);
  100. } else if(array->pdata[0] != items[0]) {
  101. return FAILED("Item 0 was overwritten, should be %s", items[0]);
  102. } else if(array->pdata[1] != items[1]) {
  103. return FAILED("Item 1 was overwritten, should be %s", items[1]);
  104. }
  105. for(i = 2; i < array->len; i++) {
  106. if(array->pdata[i] != NULL) {
  107. return FAILED("Item %d is not NULL, it is %p", i, array->pdata[i]);
  108. }
  109. }
  110. g_ptr_array_free(array, TRUE);
  111. return OK;
  112. }
  113. RESULT ptrarray_remove_index()
  114. {
  115. GPtrArray *array;
  116. guint i;
  117. array = ptrarray_alloc_and_fill(&i);
  118. g_ptr_array_remove_index(array, 0);
  119. if(array->pdata[0] != items[1]) {
  120. return FAILED("First item is not %s, it is %s", items[1],
  121. array->pdata[0]);
  122. }
  123. g_ptr_array_remove_index(array, array->len - 1);
  124. if(array->pdata[array->len - 1] != items[array->len]) {
  125. return FAILED("Last item is not %s, it is %s",
  126. items[array->len - 2], array->pdata[array->len - 1]);
  127. }
  128. g_ptr_array_free(array, TRUE);
  129. return OK;
  130. }
  131. RESULT ptrarray_remove_index_fast()
  132. {
  133. GPtrArray *array;
  134. guint i;
  135. array = ptrarray_alloc_and_fill(&i);
  136. g_ptr_array_remove_index_fast(array, 0);
  137. if(array->pdata[0] != items[array->len]) {
  138. return FAILED("First item is not %s, it is %s", items[array->len],
  139. array->pdata[0]);
  140. }
  141. g_ptr_array_remove_index_fast(array, array->len - 1);
  142. if(array->pdata[array->len - 1] != items[array->len - 1]) {
  143. return FAILED("Last item is not %s, it is %s",
  144. items[array->len - 1], array->pdata[array->len - 1]);
  145. }
  146. g_ptr_array_free(array, TRUE);
  147. return OK;
  148. }
  149. RESULT ptrarray_remove()
  150. {
  151. GPtrArray *array;
  152. guint i;
  153. array = ptrarray_alloc_and_fill(&i);
  154. g_ptr_array_remove(array, (gpointer)items[7]);
  155. if(!g_ptr_array_remove(array, (gpointer)items[4])) {
  156. return FAILED("Item %s not removed", items[4]);
  157. }
  158. if(g_ptr_array_remove(array, (gpointer)items[4])) {
  159. return FAILED("Item %s still in array after removal", items[4]);
  160. }
  161. if(array->pdata[array->len - 1] != items[array->len + 1]) {
  162. return FAILED("Last item in GPtrArray not correct");
  163. }
  164. g_ptr_array_free(array, TRUE);
  165. return OK;
  166. }
  167. static gint ptrarray_sort_compare(gconstpointer a, gconstpointer b)
  168. {
  169. gchar *stra = *(gchar **) a;
  170. gchar *strb = *(gchar **) b;
  171. return strcmp(stra, strb);
  172. }
  173. RESULT ptrarray_sort()
  174. {
  175. GPtrArray *array = g_ptr_array_new();
  176. guint i;
  177. gchar *letters [] = { "A", "B", "C", "D", "E" };
  178. g_ptr_array_add(array, letters[0]);
  179. g_ptr_array_add(array, letters[1]);
  180. g_ptr_array_add(array, letters[2]);
  181. g_ptr_array_add(array, letters[3]);
  182. g_ptr_array_add(array, letters[4]);
  183. g_ptr_array_sort(array, ptrarray_sort_compare);
  184. for(i = 0; i < array->len; i++) {
  185. if(array->pdata[i] != letters[i]) {
  186. return FAILED("Array out of order, expected %s got %s at position %d",
  187. letters [i], (gchar *) array->pdata [i], i);
  188. }
  189. }
  190. g_ptr_array_free(array, TRUE);
  191. return OK;
  192. }
  193. static gint ptrarray_sort_compare_with_data (gconstpointer a, gconstpointer b, gpointer user_data)
  194. {
  195. gchar *stra = *(gchar **) a;
  196. gchar *strb = *(gchar **) b;
  197. if (strcmp (user_data, "this is the data for qsort") != 0)
  198. fprintf (stderr, "oops at compare with_data\n");
  199. return strcmp(stra, strb);
  200. }
  201. RESULT ptrarray_sort_with_data ()
  202. {
  203. GPtrArray *array = g_ptr_array_new();
  204. guint i;
  205. gchar *letters [] = { "A", "B", "C", "D", "E" };
  206. g_ptr_array_add(array, letters[4]);
  207. g_ptr_array_add(array, letters[1]);
  208. g_ptr_array_add(array, letters[2]);
  209. g_ptr_array_add(array, letters[0]);
  210. g_ptr_array_add(array, letters[3]);
  211. g_ptr_array_sort_with_data(array, ptrarray_sort_compare_with_data, "this is the data for qsort");
  212. for(i = 0; i < array->len; i++) {
  213. if(array->pdata[i] != letters[i]) {
  214. return FAILED("Array out of order, expected %s got %s at position %d",
  215. letters [i], (gchar *) array->pdata [i], i);
  216. }
  217. }
  218. g_ptr_array_free(array, TRUE);
  219. return OK;
  220. }
  221. RESULT ptrarray_remove_fast()
  222. {
  223. GPtrArray *array = g_ptr_array_new();
  224. gchar *letters [] = { "A", "B", "C", "D", "E" };
  225. if (g_ptr_array_remove_fast (array, NULL))
  226. return FAILED ("Removing NULL succeeded");
  227. g_ptr_array_add(array, letters[0]);
  228. if (!g_ptr_array_remove_fast (array, letters[0]) || array->len != 0)
  229. return FAILED ("Removing last element failed");
  230. g_ptr_array_add(array, letters[0]);
  231. g_ptr_array_add(array, letters[1]);
  232. g_ptr_array_add(array, letters[2]);
  233. g_ptr_array_add(array, letters[3]);
  234. g_ptr_array_add(array, letters[4]);
  235. if (!g_ptr_array_remove_fast (array, letters[0]) || array->len != 4)
  236. return FAILED ("Removing first element failed");
  237. if (array->pdata [0] != letters [4])
  238. return FAILED ("First element wasn't replaced with last upon removal");
  239. if (g_ptr_array_remove_fast (array, letters[0]))
  240. return FAILED ("Succedeed removing a non-existing element");
  241. if (!g_ptr_array_remove_fast (array, letters[3]) || array->len != 3)
  242. return FAILED ("Failed removing \"D\"");
  243. if (!g_ptr_array_remove_fast (array, letters[1]) || array->len != 2)
  244. return FAILED ("Failed removing \"B\"");
  245. if (array->pdata [0] != letters [4] || array->pdata [1] != letters [2])
  246. return FAILED ("Last two elements are wrong");
  247. g_ptr_array_free(array, TRUE);
  248. return OK;
  249. }
  250. static Test ptrarray_tests [] = {
  251. {"alloc", ptrarray_alloc},
  252. {"for_iterate", ptrarray_for_iterate},
  253. {"foreach_iterate", ptrarray_foreach_iterate},
  254. {"set_size", ptrarray_set_size},
  255. {"remove_index", ptrarray_remove_index},
  256. {"remove_index_fast", ptrarray_remove_index_fast},
  257. {"remove", ptrarray_remove},
  258. {"sort", ptrarray_sort},
  259. {"remove_fast", ptrarray_remove_fast},
  260. {"sort_with_data", ptrarray_sort_with_data},
  261. {NULL, NULL}
  262. };
  263. DEFINE_TEST_GROUP_INIT(ptrarray_tests_init, ptrarray_tests)