tst-dynarray.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574
  1. /* Test for dynamic arrays.
  2. Copyright (C) 2017-2019 Free Software Foundation, Inc.
  3. This file is part of the GNU C Library.
  4. The GNU C Library is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU Lesser General Public
  6. License as published by the Free Software Foundation; either
  7. version 2.1 of the License, or (at your option) any later version.
  8. The GNU C Library is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public
  13. License along with the GNU C Library; if not, see
  14. <http://www.gnu.org/licenses/>. */
  15. #include "tst-dynarray-shared.h"
  16. #include <errno.h>
  17. #include <stdint.h>
  18. #define DYNARRAY_STRUCT dynarray_long
  19. #define DYNARRAY_ELEMENT long
  20. #define DYNARRAY_PREFIX dynarray_long_
  21. #define DYNARRAY_ELEMENT_INIT(e) (*(e) = 17)
  22. #include <malloc/dynarray-skeleton.c>
  23. struct long_array
  24. {
  25. long *array;
  26. size_t length;
  27. };
  28. #define DYNARRAY_STRUCT dynarray_long_noscratch
  29. #define DYNARRAY_ELEMENT long
  30. #define DYNARRAY_PREFIX dynarray_long_noscratch_
  31. #define DYNARRAY_ELEMENT_INIT(e) (*(e) = 23)
  32. #define DYNARRAY_FINAL_TYPE struct long_array
  33. #define DYNARRAY_INITIAL_SIZE 0
  34. #include <malloc/dynarray-skeleton.c>
  35. #define DYNARRAY_STRUCT zstr
  36. #define DYNARRAY_ELEMENT char
  37. #define DYNARRAY_PREFIX zstr_
  38. #define DYNARRAY_INITIAL_SIZE 128
  39. #include <malloc/dynarray-skeleton.c>
  40. #include <malloc.h>
  41. #include <mcheck.h>
  42. #include <stdint.h>
  43. #include <support/check.h>
  44. #include <support/support.h>
  45. enum { max_count = 20 };
  46. /* Test dynamic arrays with int elements (no automatic deallocation
  47. for elements). */
  48. static void
  49. test_int (void)
  50. {
  51. /* Empty array. */
  52. {
  53. struct dynarray_int dyn;
  54. dynarray_int_init (&dyn);
  55. CHECK_EMPTY (int, &dyn);
  56. }
  57. /* Empty array with finalization. */
  58. {
  59. struct dynarray_int dyn;
  60. dynarray_int_init (&dyn);
  61. CHECK_INIT_STATE (int, &dyn);
  62. struct int_array result = { (int *) (uintptr_t) -1, -1 };
  63. TEST_VERIFY_EXIT (dynarray_int_finalize (&dyn, &result));
  64. CHECK_INIT_STATE (int, &dyn);
  65. TEST_VERIFY_EXIT (result.array == NULL);
  66. TEST_VERIFY_EXIT (result.length == 0);
  67. }
  68. /* Non-empty array tests.
  69. do_add: Switch between emplace (false) and add (true).
  70. do_finalize: Perform finalize call at the end.
  71. do_clear: Perform clear call at the end.
  72. do_remove_last: Perform remove_last call after adding elements.
  73. count: Number of elements added to the array. */
  74. for (int do_add = 0; do_add < 2; ++do_add)
  75. for (int do_finalize = 0; do_finalize < 2; ++do_finalize)
  76. for (int do_clear = 0; do_clear < 2; ++do_clear)
  77. for (int do_remove_last = 0; do_remove_last < 2; ++do_remove_last)
  78. for (unsigned int count = 0; count < max_count; ++count)
  79. {
  80. if (do_remove_last && count == 0)
  81. continue;
  82. unsigned int base = count * count;
  83. struct dynarray_int dyn;
  84. dynarray_int_init (&dyn);
  85. for (unsigned int i = 0; i < count; ++i)
  86. {
  87. if (do_add)
  88. dynarray_int_add (&dyn, base + i);
  89. else
  90. {
  91. int *place = dynarray_int_emplace (&dyn);
  92. TEST_VERIFY_EXIT (place != NULL);
  93. *place = base + i;
  94. }
  95. TEST_VERIFY_EXIT (!dynarray_int_has_failed (&dyn));
  96. TEST_VERIFY_EXIT (dynarray_int_size (&dyn) == i + 1);
  97. TEST_VERIFY_EXIT (dynarray_int_size (&dyn)
  98. <= dyn.dynarray_header.allocated);
  99. }
  100. TEST_VERIFY_EXIT (dynarray_int_size (&dyn) == count);
  101. TEST_VERIFY_EXIT (count <= dyn.dynarray_header.allocated);
  102. if (count > 0)
  103. {
  104. TEST_VERIFY (dynarray_int_begin (&dyn)
  105. == dynarray_int_at (&dyn, 0));
  106. TEST_VERIFY (dynarray_int_end (&dyn)
  107. == dynarray_int_at (&dyn, count - 1) + 1);
  108. }
  109. unsigned final_count;
  110. bool heap_array = dyn.dynarray_header.array != dyn.scratch;
  111. if (do_remove_last)
  112. {
  113. dynarray_int_remove_last (&dyn);
  114. if (count == 0)
  115. final_count = 0;
  116. else
  117. final_count = count - 1;
  118. }
  119. else
  120. final_count = count;
  121. if (final_count > 0)
  122. {
  123. TEST_VERIFY (dynarray_int_begin (&dyn)
  124. == dynarray_int_at (&dyn, 0));
  125. TEST_VERIFY (dynarray_int_end (&dyn)
  126. == dynarray_int_at (&dyn, final_count - 1) + 1);
  127. }
  128. if (do_clear)
  129. {
  130. dynarray_int_clear (&dyn);
  131. final_count = 0;
  132. }
  133. TEST_VERIFY_EXIT (!dynarray_int_has_failed (&dyn));
  134. TEST_VERIFY_EXIT ((dyn.dynarray_header.array != dyn.scratch)
  135. == heap_array);
  136. TEST_VERIFY_EXIT (dynarray_int_size (&dyn) == final_count);
  137. TEST_VERIFY_EXIT (dyn.dynarray_header.allocated >= final_count);
  138. if (!do_clear)
  139. for (unsigned int i = 0; i < final_count; ++i)
  140. TEST_VERIFY_EXIT (*dynarray_int_at (&dyn, i) == base + i);
  141. if (do_finalize)
  142. {
  143. struct int_array result = { (int *) (uintptr_t) -1, -1 };
  144. TEST_VERIFY_EXIT (dynarray_int_finalize (&dyn, &result));
  145. CHECK_INIT_STATE (int, &dyn);
  146. TEST_VERIFY_EXIT (result.length == final_count);
  147. if (final_count == 0)
  148. TEST_VERIFY_EXIT (result.array == NULL);
  149. else
  150. {
  151. TEST_VERIFY_EXIT (result.array != NULL);
  152. TEST_VERIFY_EXIT (result.array != (int *) (uintptr_t) -1);
  153. TEST_VERIFY_EXIT
  154. (malloc_usable_size (result.array)
  155. >= final_count * sizeof (result.array[0]));
  156. for (unsigned int i = 0; i < final_count; ++i)
  157. TEST_VERIFY_EXIT (result.array[i] == base + i);
  158. free (result.array);
  159. }
  160. }
  161. else /* !do_finalize */
  162. {
  163. dynarray_int_free (&dyn);
  164. CHECK_INIT_STATE (int, &dyn);
  165. }
  166. }
  167. }
  168. /* Test dynamic arrays with char * elements (with automatic
  169. deallocation of the pointed-to strings). */
  170. static void
  171. test_str (void)
  172. {
  173. /* Empty array. */
  174. {
  175. struct dynarray_str dyn;
  176. dynarray_str_init (&dyn);
  177. CHECK_EMPTY (str, &dyn);
  178. }
  179. /* Empty array with finalization. */
  180. {
  181. struct dynarray_str dyn;
  182. dynarray_str_init (&dyn);
  183. TEST_VERIFY_EXIT (!dynarray_str_has_failed (&dyn));
  184. struct str_array result = { (char **) (uintptr_t) -1, -1 };
  185. TEST_VERIFY_EXIT (dynarray_str_finalize (&dyn, &result));
  186. CHECK_INIT_STATE (str, &dyn);
  187. TEST_VERIFY_EXIT (result.array == NULL);
  188. TEST_VERIFY_EXIT (result.length == 0);
  189. }
  190. /* Non-empty array tests.
  191. do_add: Switch between emplace (false) and add (true).
  192. do_finalize: Perform finalize call at the end.
  193. do_clear: Perform clear call at the end.
  194. do_remove_last: Perform remove_last call after adding elements.
  195. count: Number of elements added to the array. */
  196. for (int do_add = 0; do_add < 2; ++do_add)
  197. for (int do_finalize = 0; do_finalize < 2; ++do_finalize)
  198. for (int do_clear = 0; do_clear < 2; ++do_clear)
  199. for (int do_remove_last = 0; do_remove_last < 2; ++do_remove_last)
  200. for (unsigned int count = 0; count < max_count; ++count)
  201. {
  202. if (do_remove_last && count == 0)
  203. continue;
  204. unsigned int base = count * count;
  205. struct dynarray_str dyn;
  206. dynarray_str_init (&dyn);
  207. for (unsigned int i = 0; i < count; ++i)
  208. {
  209. char *item = xasprintf ("%d", base + i);
  210. if (do_add)
  211. dynarray_str_add (&dyn, item);
  212. else
  213. {
  214. char **place = dynarray_str_emplace (&dyn);
  215. TEST_VERIFY_EXIT (place != NULL);
  216. TEST_VERIFY_EXIT (*place == NULL);
  217. *place = item;
  218. }
  219. TEST_VERIFY_EXIT (!dynarray_str_has_failed (&dyn));
  220. TEST_VERIFY_EXIT (dynarray_str_size (&dyn) == i + 1);
  221. TEST_VERIFY_EXIT (dynarray_str_size (&dyn)
  222. <= dyn.dynarray_header.allocated);
  223. }
  224. TEST_VERIFY_EXIT (dynarray_str_size (&dyn) == count);
  225. TEST_VERIFY_EXIT (count <= dyn.dynarray_header.allocated);
  226. if (count > 0)
  227. {
  228. TEST_VERIFY (dynarray_str_begin (&dyn)
  229. == dynarray_str_at (&dyn, 0));
  230. TEST_VERIFY (dynarray_str_end (&dyn)
  231. == dynarray_str_at (&dyn, count - 1) + 1);
  232. }
  233. unsigned final_count;
  234. bool heap_array = dyn.dynarray_header.array != dyn.scratch;
  235. if (do_remove_last)
  236. {
  237. dynarray_str_remove_last (&dyn);
  238. if (count == 0)
  239. final_count = 0;
  240. else
  241. final_count = count - 1;
  242. }
  243. else
  244. final_count = count;
  245. if (final_count > 0)
  246. {
  247. TEST_VERIFY (dynarray_str_begin (&dyn)
  248. == dynarray_str_at (&dyn, 0));
  249. TEST_VERIFY (dynarray_str_end (&dyn)
  250. == dynarray_str_at (&dyn, final_count - 1) + 1);
  251. }
  252. if (do_clear)
  253. {
  254. dynarray_str_clear (&dyn);
  255. final_count = 0;
  256. }
  257. TEST_VERIFY_EXIT (!dynarray_str_has_failed (&dyn));
  258. TEST_VERIFY_EXIT ((dyn.dynarray_header.array != dyn.scratch)
  259. == heap_array);
  260. TEST_VERIFY_EXIT (dynarray_str_size (&dyn) == final_count);
  261. TEST_VERIFY_EXIT (dyn.dynarray_header.allocated >= final_count);
  262. if (!do_clear)
  263. for (unsigned int i = 0; i < count - do_remove_last; ++i)
  264. {
  265. char *expected = xasprintf ("%d", base + i);
  266. const char *actual = *dynarray_str_at (&dyn, i);
  267. TEST_VERIFY_EXIT (strcmp (actual, expected) == 0);
  268. free (expected);
  269. }
  270. if (do_finalize)
  271. {
  272. struct str_array result = { (char **) (uintptr_t) -1, -1 };
  273. TEST_VERIFY_EXIT (dynarray_str_finalize (&dyn, &result));
  274. CHECK_INIT_STATE (str, &dyn);
  275. TEST_VERIFY_EXIT (result.length == final_count);
  276. if (final_count == 0)
  277. TEST_VERIFY_EXIT (result.array == NULL);
  278. else
  279. {
  280. TEST_VERIFY_EXIT (result.array != NULL);
  281. TEST_VERIFY_EXIT (result.array
  282. != (char **) (uintptr_t) -1);
  283. TEST_VERIFY_EXIT (result.length
  284. == count - do_remove_last);
  285. TEST_VERIFY_EXIT
  286. (malloc_usable_size (result.array)
  287. >= final_count * sizeof (result.array[0]));
  288. for (unsigned int i = 0; i < count - do_remove_last; ++i)
  289. {
  290. char *expected = xasprintf ("%d", base + i);
  291. char *actual = result.array[i];
  292. TEST_VERIFY_EXIT (strcmp (actual, expected) == 0);
  293. free (expected);
  294. free (actual);
  295. }
  296. free (result.array);
  297. }
  298. }
  299. else /* !do_finalize */
  300. {
  301. dynarray_str_free (&dyn);
  302. CHECK_INIT_STATE (str, &dyn);
  303. }
  304. }
  305. /* Test resizing. */
  306. {
  307. enum { count = 2131 };
  308. struct dynarray_str dyn;
  309. dynarray_str_init (&dyn);
  310. /* From length 0 to length 1. */
  311. TEST_VERIFY (dynarray_str_resize (&dyn, 1));
  312. TEST_VERIFY (dynarray_str_size (&dyn) == 1);
  313. TEST_VERIFY (*dynarray_str_at (&dyn, 0) == NULL);
  314. *dynarray_str_at (&dyn, 0) = xstrdup ("allocated");
  315. dynarray_str_free (&dyn);
  316. /* From length 0 to length 1 and 2. */
  317. TEST_VERIFY (dynarray_str_resize (&dyn, 1));
  318. TEST_VERIFY (dynarray_str_size (&dyn) == 1);
  319. TEST_VERIFY (*dynarray_str_at (&dyn, 0) == NULL);
  320. *dynarray_str_at (&dyn, 0) = xstrdup ("allocated0");
  321. TEST_VERIFY (dynarray_str_resize (&dyn, 2));
  322. TEST_VERIFY (dynarray_str_size (&dyn) == 2);
  323. TEST_VERIFY (strcmp (*dynarray_str_at (&dyn, 0), "allocated0") == 0);
  324. TEST_VERIFY (*dynarray_str_at (&dyn, 1) == NULL);
  325. *dynarray_str_at (&dyn, 1) = xstrdup ("allocated1");
  326. TEST_VERIFY (dynarray_str_resize (&dyn, count));
  327. TEST_VERIFY (dynarray_str_size (&dyn) == count);
  328. TEST_VERIFY (strcmp (*dynarray_str_at (&dyn, 0), "allocated0") == 0);
  329. TEST_VERIFY (strcmp (*dynarray_str_at (&dyn, 1), "allocated1") == 0);
  330. for (int i = 2; i < count; ++i)
  331. TEST_VERIFY (*dynarray_str_at (&dyn, i) == NULL);
  332. *dynarray_str_at (&dyn, count - 1) = xstrdup ("allocated2");
  333. TEST_VERIFY (dynarray_str_resize (&dyn, 3));
  334. TEST_VERIFY (strcmp (*dynarray_str_at (&dyn, 0), "allocated0") == 0);
  335. TEST_VERIFY (strcmp (*dynarray_str_at (&dyn, 1), "allocated1") == 0);
  336. TEST_VERIFY (*dynarray_str_at (&dyn, 2) == NULL);
  337. dynarray_str_free (&dyn);
  338. }
  339. }
  340. /* Verify that DYNARRAY_ELEMENT_INIT has an effect. */
  341. static void
  342. test_long_init (void)
  343. {
  344. enum { count = 2131 };
  345. {
  346. struct dynarray_long dyn;
  347. dynarray_long_init (&dyn);
  348. for (int i = 0; i < count; ++i)
  349. {
  350. long *place = dynarray_long_emplace (&dyn);
  351. TEST_VERIFY_EXIT (place != NULL);
  352. TEST_VERIFY (*place == 17);
  353. }
  354. TEST_VERIFY (dynarray_long_size (&dyn) == count);
  355. for (int i = 0; i < count; ++i)
  356. TEST_VERIFY (*dynarray_long_at (&dyn, i) == 17);
  357. dynarray_long_free (&dyn);
  358. TEST_VERIFY (dynarray_long_resize (&dyn, 1));
  359. TEST_VERIFY (dynarray_long_size (&dyn) == 1);
  360. TEST_VERIFY (*dynarray_long_at (&dyn, 0) == 17);
  361. *dynarray_long_at (&dyn, 0) = 18;
  362. dynarray_long_free (&dyn);
  363. TEST_VERIFY (dynarray_long_resize (&dyn, 1));
  364. TEST_VERIFY (dynarray_long_size (&dyn) == 1);
  365. TEST_VERIFY (*dynarray_long_at (&dyn, 0) == 17);
  366. TEST_VERIFY (dynarray_long_resize (&dyn, 2));
  367. TEST_VERIFY (dynarray_long_size (&dyn) == 2);
  368. TEST_VERIFY (*dynarray_long_at (&dyn, 0) == 17);
  369. TEST_VERIFY (*dynarray_long_at (&dyn, 1) == 17);
  370. *dynarray_long_at (&dyn, 0) = 18;
  371. TEST_VERIFY (dynarray_long_resize (&dyn, count));
  372. TEST_VERIFY (dynarray_long_size (&dyn) == count);
  373. TEST_VERIFY (*dynarray_long_at (&dyn, 0) == 18);
  374. for (int i = 1; i < count; ++i)
  375. TEST_VERIFY (*dynarray_long_at (&dyn, i) == 17);
  376. dynarray_long_free (&dyn);
  377. }
  378. /* Similar, but without an on-stack scratch region
  379. (DYNARRAY_INITIAL_SIZE is 0). */
  380. {
  381. struct dynarray_long_noscratch dyn;
  382. dynarray_long_noscratch_init (&dyn);
  383. struct long_array result;
  384. TEST_VERIFY_EXIT (dynarray_long_noscratch_finalize (&dyn, &result));
  385. TEST_VERIFY (result.array == NULL);
  386. TEST_VERIFY (result.length == 0);
  387. /* Test with one element. */
  388. {
  389. long *place = dynarray_long_noscratch_emplace (&dyn);
  390. TEST_VERIFY_EXIT (place != NULL);
  391. TEST_VERIFY (*place == 23);
  392. }
  393. TEST_VERIFY (dynarray_long_noscratch_size (&dyn) == 1);
  394. TEST_VERIFY (*dynarray_long_noscratch_at (&dyn, 0) == 23);
  395. TEST_VERIFY_EXIT (dynarray_long_noscratch_finalize (&dyn, &result));
  396. TEST_VERIFY_EXIT (result.array != NULL);
  397. TEST_VERIFY (result.length == 1);
  398. TEST_VERIFY (result.array[0] == 23);
  399. free (result.array);
  400. for (int i = 0; i < count; ++i)
  401. {
  402. long *place = dynarray_long_noscratch_emplace (&dyn);
  403. TEST_VERIFY_EXIT (place != NULL);
  404. TEST_VERIFY (*place == 23);
  405. if (i == 0)
  406. *place = 29;
  407. }
  408. TEST_VERIFY (dynarray_long_noscratch_size (&dyn) == count);
  409. TEST_VERIFY (*dynarray_long_noscratch_at (&dyn, 0) == 29);
  410. for (int i = 1; i < count; ++i)
  411. TEST_VERIFY (*dynarray_long_noscratch_at (&dyn, i) == 23);
  412. TEST_VERIFY_EXIT (dynarray_long_noscratch_finalize (&dyn, &result));
  413. TEST_VERIFY_EXIT (result.array != NULL);
  414. TEST_VERIFY (result.length == count);
  415. TEST_VERIFY (result.array[0] == 29);
  416. for (int i = 1; i < count; ++i)
  417. TEST_VERIFY (result.array[i] == 23);
  418. free (result.array);
  419. TEST_VERIFY (dynarray_long_noscratch_resize (&dyn, 1));
  420. TEST_VERIFY (dynarray_long_noscratch_size (&dyn) == 1);
  421. TEST_VERIFY (*dynarray_long_noscratch_at (&dyn, 0) == 23);
  422. *dynarray_long_noscratch_at (&dyn, 0) = 24;
  423. dynarray_long_noscratch_free (&dyn);
  424. TEST_VERIFY (dynarray_long_noscratch_resize (&dyn, 1));
  425. TEST_VERIFY (dynarray_long_noscratch_size (&dyn) == 1);
  426. TEST_VERIFY (*dynarray_long_noscratch_at (&dyn, 0) == 23);
  427. TEST_VERIFY (dynarray_long_noscratch_resize (&dyn, 2));
  428. TEST_VERIFY (dynarray_long_noscratch_size (&dyn) == 2);
  429. TEST_VERIFY (*dynarray_long_noscratch_at (&dyn, 0) == 23);
  430. TEST_VERIFY (*dynarray_long_noscratch_at (&dyn, 1) == 23);
  431. *dynarray_long_noscratch_at (&dyn, 0) = 24;
  432. TEST_VERIFY (dynarray_long_noscratch_resize (&dyn, count));
  433. TEST_VERIFY (dynarray_long_noscratch_size (&dyn) == count);
  434. TEST_VERIFY (*dynarray_long_noscratch_at (&dyn, 0) == 24);
  435. for (int i = 1; i < count; ++i)
  436. TEST_VERIFY (*dynarray_long_noscratch_at (&dyn, i) == 23);
  437. dynarray_long_noscratch_free (&dyn);
  438. }
  439. }
  440. /* Test overflow in resize. */
  441. static void
  442. test_long_overflow (void)
  443. {
  444. {
  445. struct dynarray_long dyn;
  446. dynarray_long_init (&dyn);
  447. errno = EINVAL;
  448. TEST_VERIFY (!dynarray_long_resize
  449. (&dyn, (SIZE_MAX / sizeof (long)) + 1));
  450. TEST_VERIFY (errno == ENOMEM);
  451. TEST_VERIFY (dynarray_long_has_failed (&dyn));
  452. }
  453. {
  454. struct dynarray_long_noscratch dyn;
  455. dynarray_long_noscratch_init (&dyn);
  456. errno = EINVAL;
  457. TEST_VERIFY (!dynarray_long_noscratch_resize
  458. (&dyn, (SIZE_MAX / sizeof (long)) + 1));
  459. TEST_VERIFY (errno == ENOMEM);
  460. TEST_VERIFY (dynarray_long_noscratch_has_failed (&dyn));
  461. }
  462. }
  463. /* Test NUL-terminated string construction with the add function and
  464. the simple finalize function. */
  465. static void
  466. test_zstr (void)
  467. {
  468. /* Totally empty string (no NUL termination). */
  469. {
  470. struct zstr s;
  471. zstr_init (&s);
  472. char *result = zstr_finalize (&s, NULL);
  473. TEST_VERIFY (result == NULL);
  474. TEST_VERIFY (zstr_size (&s) == 0);
  475. size_t length = 1;
  476. result = zstr_finalize (&s, &length);
  477. TEST_VERIFY (result == NULL);
  478. TEST_VERIFY (length == 0);
  479. TEST_VERIFY (zstr_size (&s) == 0);
  480. }
  481. /* Empty string. */
  482. {
  483. struct zstr s;
  484. zstr_init (&s);
  485. zstr_add (&s, '\0');
  486. char *result = zstr_finalize (&s, NULL);
  487. TEST_VERIFY_EXIT (result != NULL);
  488. TEST_VERIFY (*result == '\0');
  489. TEST_VERIFY (zstr_size (&s) == 0);
  490. free (result);
  491. zstr_add (&s, '\0');
  492. size_t length = 1;
  493. result = zstr_finalize (&s, &length);
  494. TEST_VERIFY_EXIT (result != NULL);
  495. TEST_VERIFY (*result == '\0');
  496. TEST_VERIFY (length == 1);
  497. TEST_VERIFY (zstr_size (&s) == 0);
  498. free (result);
  499. }
  500. /* A few characters. */
  501. {
  502. struct zstr s;
  503. zstr_init (&s);
  504. zstr_add (&s, 'A');
  505. zstr_add (&s, 'b');
  506. zstr_add (&s, 'c');
  507. zstr_add (&s, '\0');
  508. char *result = zstr_finalize (&s, NULL);
  509. TEST_VERIFY_EXIT (result != NULL);
  510. TEST_VERIFY (strcmp (result, "Abc") == 0);
  511. TEST_VERIFY (zstr_size (&s) == 0);
  512. free (result);
  513. zstr_add (&s, 'X');
  514. zstr_add (&s, 'y');
  515. zstr_add (&s, 'z');
  516. zstr_add (&s, '\0');
  517. size_t length = 1;
  518. result = zstr_finalize (&s, &length);
  519. TEST_VERIFY_EXIT (result != NULL);
  520. TEST_VERIFY (strcmp (result, "Xyz") == 0);
  521. TEST_VERIFY (length == 4);
  522. TEST_VERIFY (zstr_size (&s) == 0);
  523. free (result);
  524. }
  525. }
  526. static int
  527. do_test (void)
  528. {
  529. mtrace ();
  530. test_int ();
  531. test_str ();
  532. test_long_init ();
  533. test_long_overflow ();
  534. test_zstr ();
  535. return 0;
  536. }
  537. #include <support/test-driver.c>