Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

list_test.c 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407
  1. /*
  2. * Copyright (C) 2011 Michael Brown <mbrown@fensystems.co.uk>.
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License as
  6. * published by the Free Software Foundation; either version 2 of the
  7. * License, or any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful, but
  10. * WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. * General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17. */
  18. FILE_LICENCE ( GPL2_OR_LATER );
  19. /** @file
  20. *
  21. * List function tests
  22. *
  23. */
  24. /* Forcibly enable assertions for list_check() */
  25. #undef NDEBUG
  26. #include <assert.h>
  27. #include <string.h>
  28. #include <stdio.h>
  29. #include <ipxe/list.h>
  30. #include <ipxe/test.h>
  31. /** A list test structure */
  32. struct list_test {
  33. /** List element */
  34. struct list_head list;
  35. /** Label */
  36. char label;
  37. };
  38. /** List test elements */
  39. static struct list_test list_tests[] = {
  40. { .label = '0' },
  41. { .label = '1' },
  42. { .label = '2' },
  43. { .label = '3' },
  44. { .label = '4' },
  45. { .label = '5' },
  46. { .label = '6' },
  47. { .label = '7' },
  48. { .label = '8' },
  49. { .label = '9' },
  50. };
  51. /** Test list */
  52. static LIST_HEAD ( test_list );
  53. /**
  54. * Check list contents are as expected
  55. *
  56. * @v list Test list
  57. * @v expected Expected contents
  58. * @v ok List contents are as expected
  59. */
  60. static int list_check_contents ( struct list_head *list,
  61. const char *expected ) {
  62. struct list_test *entry;
  63. size_t num_entries = 0;
  64. /* Determine size of list */
  65. list_for_each_entry ( entry, list, list )
  66. num_entries++;
  67. {
  68. char found[ num_entries + 1 ];
  69. char found_rev[ num_entries + 1 ];
  70. char *tmp;
  71. /* Build up list content string */
  72. tmp = found;
  73. list_for_each_entry ( entry, list, list )
  74. *(tmp++) = entry->label;
  75. *tmp = '\0';
  76. /* Sanity check reversed list */
  77. tmp = &found_rev[ sizeof ( found_rev ) - 1 ];
  78. *tmp = '\0';
  79. list_for_each_entry_reverse ( entry, list, list )
  80. *(--tmp) = entry->label;
  81. if ( strcmp ( found, found_rev ) != 0 ) {
  82. printf ( "FAILURE: list reversal mismatch (forward "
  83. "\"%s\", reverse \"%s\")\n",
  84. found, found_rev );
  85. return 0;
  86. }
  87. /* Compare against expected content */
  88. if ( strcmp ( found, expected ) == 0 ) {
  89. return 1;
  90. } else {
  91. printf ( "FAILURE: expected \"%s\", got \"%s\"\n",
  92. expected, found );
  93. return 0;
  94. }
  95. }
  96. }
  97. /**
  98. * Report list test result
  99. *
  100. * @v list Test list
  101. * @v expected Expected contents
  102. */
  103. #define list_contents_ok( list, expected ) do { \
  104. ok ( list_check_contents ( (list), (expected) ) ); \
  105. } while ( 0 )
  106. /**
  107. * Perform list self-test
  108. *
  109. */
  110. static void list_test_exec ( void ) {
  111. struct list_head *list = &test_list;
  112. struct list_head target_list;
  113. struct list_head *target = &target_list;
  114. /* Test initialiser and list_empty() */
  115. ok ( list_empty ( list ) );
  116. list_contents_ok ( list, "" );
  117. /* Test list_add(), list_add_tail() and list_del() */
  118. INIT_LIST_HEAD ( list );
  119. list_contents_ok ( list, "" );
  120. list_add ( &list_tests[4].list, list ); /* prepend */
  121. list_contents_ok ( list, "4" );
  122. list_add ( &list_tests[2].list, list ); /* prepend */
  123. list_contents_ok ( list, "24" );
  124. list_add_tail ( &list_tests[7].list, list ); /* append */
  125. list_contents_ok ( list, "247" );
  126. list_add ( &list_tests[1].list, &list_tests[4].list ); /* after */
  127. list_contents_ok ( list, "2417" );
  128. list_add_tail ( &list_tests[8].list, &list_tests[7].list ); /* before */
  129. list_contents_ok ( list, "24187" );
  130. list_del ( &list_tests[4].list ); /* delete middle */
  131. list_contents_ok ( list, "2187" );
  132. list_del ( &list_tests[2].list ); /* delete first */
  133. list_contents_ok ( list, "187" );
  134. list_del ( &list_tests[7].list ); /* delete last */
  135. list_contents_ok ( list, "18" );
  136. list_del ( &list_tests[1].list ); /* delete all */
  137. list_del ( &list_tests[8].list ); /* delete all */
  138. list_contents_ok ( list, "" );
  139. ok ( list_empty ( list ) );
  140. /* Test list_is_singular() */
  141. INIT_LIST_HEAD ( list );
  142. ok ( ! list_is_singular ( list ) );
  143. list_add ( &list_tests[1].list, list );
  144. ok ( list_is_singular ( list ) );
  145. list_add ( &list_tests[3].list, list );
  146. ok ( ! list_is_singular ( list ) );
  147. list_del ( &list_tests[1].list );
  148. ok ( list_is_singular ( list ) );
  149. /* Test list_is_last() */
  150. INIT_LIST_HEAD ( list );
  151. list_add_tail ( &list_tests[6].list, list );
  152. ok ( list_is_last ( &list_tests[6].list, list ) );
  153. list_add_tail ( &list_tests[4].list, list );
  154. ok ( list_is_last ( &list_tests[4].list, list ) );
  155. ok ( ! list_is_last ( &list_tests[6].list, list ) );
  156. /* Test list_cut_position() - empty list */
  157. INIT_LIST_HEAD ( list );
  158. INIT_LIST_HEAD ( target );
  159. list_cut_position ( target, list, list );
  160. list_contents_ok ( list, "" );
  161. list_contents_ok ( target, "" );
  162. /* Test list_cut_position() - singular list, move nothing */
  163. INIT_LIST_HEAD ( list );
  164. INIT_LIST_HEAD ( target );
  165. list_add_tail ( &list_tests[4].list, list );
  166. list_cut_position ( target, list, list );
  167. list_contents_ok ( list, "4" );
  168. list_contents_ok ( target, "" );
  169. /* Test list_cut_position() - singular list, move singular entry */
  170. INIT_LIST_HEAD ( list );
  171. INIT_LIST_HEAD ( target );
  172. list_add_tail ( &list_tests[9].list, list );
  173. list_cut_position ( target, list, &list_tests[9].list );
  174. list_contents_ok ( list, "" );
  175. list_contents_ok ( target, "9" );
  176. /* Test list_cut_position() - multi-entry list, move nothing */
  177. INIT_LIST_HEAD ( list );
  178. list_add_tail ( &list_tests[3].list, list );
  179. list_add_tail ( &list_tests[2].list, list );
  180. list_add_tail ( &list_tests[7].list, list );
  181. INIT_LIST_HEAD ( target );
  182. list_cut_position ( target, list, list );
  183. list_contents_ok ( list, "327" );
  184. list_contents_ok ( target, "" );
  185. /* Test list_cut_position() - multi-entry list, move some */
  186. INIT_LIST_HEAD ( list );
  187. INIT_LIST_HEAD ( target );
  188. list_add_tail ( &list_tests[8].list, list );
  189. list_add_tail ( &list_tests[0].list, list );
  190. list_add_tail ( &list_tests[9].list, list );
  191. list_add_tail ( &list_tests[3].list, list );
  192. list_add_tail ( &list_tests[2].list, list );
  193. list_cut_position ( target, list, &list_tests[0].list );
  194. list_contents_ok ( list, "932" );
  195. list_contents_ok ( target, "80" );
  196. /* Test list_cut_position() - multi-entry list, move everything */
  197. INIT_LIST_HEAD ( list );
  198. INIT_LIST_HEAD ( target );
  199. list_add_tail ( &list_tests[3].list, list );
  200. list_add_tail ( &list_tests[5].list, list );
  201. list_add_tail ( &list_tests[4].list, list );
  202. list_add_tail ( &list_tests[7].list, list );
  203. list_add_tail ( &list_tests[1].list, list );
  204. list_cut_position ( target, list, &list_tests[1].list );
  205. list_contents_ok ( list, "" );
  206. list_contents_ok ( target, "35471" );
  207. /* Test list_splice() - empty list */
  208. INIT_LIST_HEAD ( list );
  209. INIT_LIST_HEAD ( target );
  210. list_splice ( list, target );
  211. list_contents_ok ( list, "" );
  212. list_contents_ok ( target, "" );
  213. /* Test list_splice() - both lists empty */
  214. INIT_LIST_HEAD ( list );
  215. INIT_LIST_HEAD ( target );
  216. list_splice ( list, target );
  217. list_contents_ok ( target, "" );
  218. /* Test list_splice() - source list empty */
  219. INIT_LIST_HEAD ( list );
  220. INIT_LIST_HEAD ( target );
  221. list_add_tail ( &list_tests[1].list, target );
  222. list_add_tail ( &list_tests[3].list, target );
  223. list_splice ( list, &list_tests[1].list );
  224. list_contents_ok ( target, "13" );
  225. /* Test list_splice() - destination list empty */
  226. INIT_LIST_HEAD ( list );
  227. INIT_LIST_HEAD ( target );
  228. list_add_tail ( &list_tests[6].list, list );
  229. list_add_tail ( &list_tests[5].list, list );
  230. list_add_tail ( &list_tests[2].list, list );
  231. list_splice ( list, target );
  232. list_contents_ok ( target, "652" );
  233. /* Test list_splice() - both lists non-empty */
  234. INIT_LIST_HEAD ( list );
  235. INIT_LIST_HEAD ( target );
  236. list_add_tail ( &list_tests[8].list, list );
  237. list_add_tail ( &list_tests[4].list, list );
  238. list_add_tail ( &list_tests[5].list, list );
  239. list_add_tail ( &list_tests[1].list, target );
  240. list_add_tail ( &list_tests[9].list, target );
  241. list_splice ( list, &list_tests[1].list );
  242. list_contents_ok ( target, "18459" );
  243. /* Test list_splice_tail() - both lists empty */
  244. INIT_LIST_HEAD ( list );
  245. INIT_LIST_HEAD ( target );
  246. list_splice_tail ( list, target );
  247. list_contents_ok ( target, "" );
  248. /* Test list_splice_tail() - source list empty */
  249. INIT_LIST_HEAD ( list );
  250. INIT_LIST_HEAD ( target );
  251. list_add_tail ( &list_tests[5].list, target );
  252. list_splice_tail ( list, &list_tests[5].list );
  253. list_contents_ok ( target, "5" );
  254. /* Test list_splice_tail() - destination list empty */
  255. INIT_LIST_HEAD ( list );
  256. INIT_LIST_HEAD ( target );
  257. list_add_tail ( &list_tests[2].list, list );
  258. list_add_tail ( &list_tests[1].list, list );
  259. list_add_tail ( &list_tests[0].list, list );
  260. list_splice_tail ( list, target );
  261. list_contents_ok ( target, "210" );
  262. /* Test list_splice_tail() - both lists non-empty */
  263. INIT_LIST_HEAD ( list );
  264. INIT_LIST_HEAD ( target );
  265. list_add_tail ( &list_tests[9].list, list );
  266. list_add_tail ( &list_tests[5].list, list );
  267. list_add_tail ( &list_tests[7].list, list );
  268. list_add_tail ( &list_tests[2].list, target );
  269. list_add_tail ( &list_tests[4].list, target );
  270. list_splice_tail ( list, &list_tests[2].list );
  271. list_contents_ok ( target, "95724" );
  272. /* Test list_splice_init() */
  273. INIT_LIST_HEAD ( list );
  274. INIT_LIST_HEAD ( target );
  275. list_add_tail ( &list_tests[4].list, list );
  276. list_add_tail ( &list_tests[1].list, target );
  277. list_splice_init ( list, target );
  278. ok ( list_empty ( list ) );
  279. list_contents_ok ( list, "" );
  280. list_contents_ok ( target, "41" );
  281. /* Test list_splice_tail_init() */
  282. INIT_LIST_HEAD ( list );
  283. INIT_LIST_HEAD ( target );
  284. list_add_tail ( &list_tests[3].list, list );
  285. list_add_tail ( &list_tests[2].list, list );
  286. list_add_tail ( &list_tests[5].list, target );
  287. list_splice_tail_init ( list, &list_tests[5].list );
  288. ok ( list_empty ( list ) );
  289. list_contents_ok ( list, "" );
  290. list_contents_ok ( target, "325" );
  291. /* Test list_entry() */
  292. INIT_LIST_HEAD ( &list_tests[3].list ); // for list_check()
  293. ok ( list_entry ( &list_tests[3].list, struct list_test, list )
  294. == &list_tests[3] );
  295. /* Test list_first_entry() */
  296. INIT_LIST_HEAD ( list );
  297. list_add_tail ( &list_tests[9].list, list );
  298. list_add_tail ( &list_tests[5].list, list );
  299. list_add_tail ( &list_tests[6].list, list );
  300. ok ( list_first_entry ( list, struct list_test, list )
  301. == &list_tests[9] );
  302. list_del ( &list_tests[9].list );
  303. ok ( list_first_entry ( list, struct list_test, list )
  304. == &list_tests[5] );
  305. /* Test list_for_each() */
  306. INIT_LIST_HEAD ( list );
  307. list_add_tail ( &list_tests[6].list, list );
  308. list_add_tail ( &list_tests[7].list, list );
  309. list_add_tail ( &list_tests[3].list, list );
  310. {
  311. char *expected = "673";
  312. struct list_head *pos;
  313. struct list_test *entry;
  314. list_for_each ( pos, list ) {
  315. entry = list_entry ( pos, struct list_test, list );
  316. ok ( entry->label == *(expected++) );
  317. }
  318. }
  319. /* list_for_each_entry() and list_for_each_entry_reverse() are
  320. * already tested as part of list_contents_ok()
  321. */
  322. /* Test list_for_each_entry_safe() */
  323. INIT_LIST_HEAD ( list );
  324. list_add_tail ( &list_tests[2].list, list );
  325. list_add_tail ( &list_tests[4].list, list );
  326. list_add_tail ( &list_tests[1].list, list );
  327. {
  328. char *expected = "241";
  329. struct list_test *pos;
  330. struct list_test *tmp;
  331. list_for_each_entry_safe ( pos, tmp, list, list ) {
  332. list_contents_ok ( list, expected );
  333. list_del ( &pos->list );
  334. expected++;
  335. list_contents_ok ( list, expected );
  336. }
  337. }
  338. ok ( list_empty ( list ) );
  339. /* Test list_contains() and list_contains_entry() */
  340. INIT_LIST_HEAD ( list );
  341. INIT_LIST_HEAD ( &list_tests[3].list );
  342. list_add ( &list_tests[8].list, list );
  343. list_add ( &list_tests[5].list, list );
  344. ok ( list_contains ( &list_tests[8].list, list ) );
  345. ok ( list_contains_entry ( &list_tests[8], list, list ) );
  346. ok ( list_contains ( &list_tests[5].list, list ) );
  347. ok ( list_contains_entry ( &list_tests[5], list, list ) );
  348. ok ( ! list_contains ( &list_tests[3].list, list ) );
  349. ok ( ! list_contains_entry ( &list_tests[3], list, list ) );
  350. /* Test list_check_contains_entry() */
  351. INIT_LIST_HEAD ( list );
  352. list_add ( &list_tests[4].list, list );
  353. list_add ( &list_tests[0].list, list );
  354. list_add ( &list_tests[3].list, list );
  355. list_check_contains_entry ( &list_tests[4], list, list );
  356. list_check_contains_entry ( &list_tests[0], list, list );
  357. list_check_contains_entry ( &list_tests[3], list, list );
  358. }
  359. /** List self-test */
  360. struct self_test list_test __self_test = {
  361. .name = "list",
  362. .exec = list_test_exec,
  363. };