qsorttst.c 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367
  1. /*++
  2. Copyright (c) 2013 Minoca Corp.
  3. This file is licensed under the terms of the GNU General Public License
  4. version 3. Alternative licensing terms are available. Contact
  5. info@minocacorp.com for details. See the LICENSE file at the root of this
  6. project for complete licensing information.
  7. Module Name:
  8. qsorttst.c
  9. Abstract:
  10. This module tests the qsort function a bit.
  11. Author:
  12. Evan Green 11-Jul-2013
  13. Environment:
  14. Test
  15. --*/
  16. //
  17. // ------------------------------------------------------------------- Includes
  18. //
  19. //
  20. // Define this so it doesn't get defined to an import.
  21. //
  22. #define LIBC_API
  23. #include <minoca/lib/types.h>
  24. #include <stdio.h>
  25. #include <stdlib.h>
  26. //
  27. // ---------------------------------------------------------------- Definitions
  28. //
  29. #define TEST_QUICKSORT_ARRAY_COUNT 1000
  30. //
  31. // ------------------------------------------------------ Data Type Definitions
  32. //
  33. //
  34. // ----------------------------------------------- Internal Function Prototypes
  35. //
  36. ULONG
  37. TestQuickSortCase (
  38. ULONG TestIndex,
  39. PULONG Array,
  40. ULONG ArrayCount,
  41. BOOL ExactSet
  42. );
  43. int
  44. TestQuickSortCompare (
  45. const void *Left,
  46. const void *Right
  47. );
  48. //
  49. // -------------------------------------------------------------------- Globals
  50. //
  51. ULONG TestQuickSortArray[TEST_QUICKSORT_ARRAY_COUNT];
  52. //
  53. // ------------------------------------------------------------------ Functions
  54. //
  55. ULONG
  56. TestQuickSort (
  57. VOID
  58. )
  59. /*++
  60. Routine Description:
  61. This routine implements the entry point for the quicksort test.
  62. Arguments:
  63. None.
  64. Return Value:
  65. Returns the count of test failures.
  66. --*/
  67. {
  68. PULONG Array;
  69. ULONG Case;
  70. ULONG Failures;
  71. ULONG Index;
  72. Array = TestQuickSortArray;
  73. Case = 0;
  74. Failures = 0;
  75. //
  76. // Try something small and simple.
  77. //
  78. Array[0] = 0;
  79. Array[1] = 1;
  80. Array[2] = 2;
  81. Array[3] = 4;
  82. Array[4] = 3;
  83. Failures += TestQuickSortCase(Case, Array, 5, TRUE);
  84. Case += 1;
  85. //
  86. // Try something else small and exactly out of order.
  87. //
  88. for (Index = 0; Index < 6; Index += 1) {
  89. Array[Index] = 6 - Index - 1;
  90. }
  91. Failures += TestQuickSortCase(Case, Array, 6, TRUE);
  92. Case += 1;
  93. //
  94. // Try something small that's all the same.
  95. //
  96. for (Index = 0; Index < 6; Index += 1) {
  97. Array[Index] = 0;
  98. }
  99. Failures += TestQuickSortCase(Case, Array, 6, FALSE);
  100. Case += 1;
  101. //
  102. // Try something small with lots of duplicates.
  103. //
  104. for (Index = 0; Index < 12; Index += 1) {
  105. Array[Index] = (12 - Index - 1) / 4;
  106. }
  107. Failures += TestQuickSortCase(Case, Array, 6, FALSE);
  108. Case += 1;
  109. //
  110. // Put everything exactly out of order.
  111. //
  112. for (Index = 0; Index < TEST_QUICKSORT_ARRAY_COUNT; Index += 1) {
  113. Array[Index] = TEST_QUICKSORT_ARRAY_COUNT - Index - 1;
  114. }
  115. Failures += TestQuickSortCase(Case,
  116. Array,
  117. TEST_QUICKSORT_ARRAY_COUNT,
  118. TRUE);
  119. Case += 1;
  120. //
  121. // Put everything in order.
  122. //
  123. for (Index = 0; Index < TEST_QUICKSORT_ARRAY_COUNT; Index += 1) {
  124. Array[Index] = Index;
  125. }
  126. Failures += TestQuickSortCase(Case,
  127. Array,
  128. TEST_QUICKSORT_ARRAY_COUNT,
  129. TRUE);
  130. Case += 1;
  131. //
  132. // Fill it with random numbers that are very likely to repeat.
  133. //
  134. for (Index = 0; Index < TEST_QUICKSORT_ARRAY_COUNT; Index += 1) {
  135. Array[Index] = rand() % (TEST_QUICKSORT_ARRAY_COUNT / 4);
  136. }
  137. Failures += TestQuickSortCase(Case,
  138. Array,
  139. TEST_QUICKSORT_ARRAY_COUNT,
  140. FALSE);
  141. Case += 1;
  142. //
  143. // Fill it with random numbers that are likely to repeat a few times.
  144. //
  145. for (Index = 0; Index < TEST_QUICKSORT_ARRAY_COUNT; Index += 1) {
  146. Array[Index] = rand() % TEST_QUICKSORT_ARRAY_COUNT;
  147. }
  148. Failures += TestQuickSortCase(Case,
  149. Array,
  150. TEST_QUICKSORT_ARRAY_COUNT,
  151. FALSE);
  152. Case += 1;
  153. //
  154. // Fill it with random numbers that probably won't repeat.
  155. //
  156. for (Index = 0; Index < TEST_QUICKSORT_ARRAY_COUNT; Index += 1) {
  157. Array[Index] = rand();
  158. }
  159. Failures += TestQuickSortCase(Case,
  160. Array,
  161. TEST_QUICKSORT_ARRAY_COUNT,
  162. FALSE);
  163. Case += 1;
  164. return Failures;
  165. }
  166. //
  167. // --------------------------------------------------------- Internal Functions
  168. //
  169. ULONG
  170. TestQuickSortCase (
  171. ULONG TestIndex,
  172. PULONG Array,
  173. ULONG ArrayCount,
  174. BOOL ExactSet
  175. )
  176. /*++
  177. Routine Description:
  178. This routine runs quicksort on the given array and validates the results.
  179. Arguments:
  180. TestIndex - Supplies the test case number for error printing.
  181. Array - Supplies a pointer to the array of integers.
  182. ArrayCount - Supplies the size of the array in elements.
  183. ExactSet - Supplies a boolean if the array contains exactly the integers
  184. 0 through count - 1.
  185. Return Value:
  186. Returns the number of failures (zero or one).
  187. --*/
  188. {
  189. ULONG Index;
  190. BOOL PrintedYet;
  191. ULONG WrongCount;
  192. PrintedYet = FALSE;
  193. WrongCount = 0;
  194. qsort(Array, ArrayCount, sizeof(ULONG), TestQuickSortCompare);
  195. for (Index = 0; Index < ArrayCount; Index += 1) {
  196. if (ExactSet != FALSE) {
  197. if (Array[Index] != Index) {
  198. if (PrintedYet == FALSE) {
  199. printf("Error: Test case %d failed.\n", TestIndex);
  200. PrintedYet = TRUE;
  201. }
  202. printf("Error: Index %4d had %4d in it.\n",
  203. Index,
  204. Array[Index]);
  205. WrongCount += 1;
  206. }
  207. } else {
  208. if ((Index != 0) && (Array[Index] < Array[Index - 1])) {
  209. if (PrintedYet == FALSE) {
  210. printf("Error: Test case %d failed.\n", TestIndex);
  211. PrintedYet = TRUE;
  212. }
  213. printf("Error: Index %4d had %4d in it, but previous value "
  214. "was %d.\n",
  215. Index,
  216. Array[Index],
  217. Array[Index - 1]);
  218. WrongCount += 1;
  219. }
  220. }
  221. }
  222. if (WrongCount != 0) {
  223. printf("%d values out of order.\n", WrongCount);
  224. return 1;
  225. }
  226. return 0;
  227. }
  228. int
  229. TestQuickSortCompare (
  230. const void *Left,
  231. const void *Right
  232. )
  233. /*++
  234. Routine Description:
  235. This routine compares two test array elements. It is used by the quicksort
  236. function.
  237. Arguments:
  238. Left - Supplies a pointer into the array of the left side of the comparison.
  239. Right - Supplies a pointer into the array of the right side of the
  240. comparison.
  241. Return Value:
  242. <0 if the left is less than the right.
  243. 0 if the two elements are equal.
  244. >0 if the left element is greater than the right.
  245. --*/
  246. {
  247. ULONG LeftNumber;
  248. ULONG RightNumber;
  249. LeftNumber = *((PULONG)Left);
  250. RightNumber = *((PULONG)Right);
  251. if (LeftNumber < RightNumber) {
  252. return -1;
  253. }
  254. if (LeftNumber > RightNumber) {
  255. return 1;
  256. }
  257. return 0;
  258. }