TestDriver.cxx.in 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. #include <ctype.h> /* NOLINT */
  2. #include <stdio.h> /* NOLINT */
  3. #include <stdlib.h> /* NOLINT */
  4. #include <string.h> /* NOLINT */
  5. #include <time.h> /* NOLINT */
  6. #if defined(_MSC_VER)
  7. #pragma warning(disable : 4996) /* deprecation */
  8. #endif
  9. @CMAKE_TESTDRIVER_EXTRA_INCLUDES@
  10. /* Forward declare test functions. */
  11. @CMAKE_FORWARD_DECLARE_TESTS@
  12. #ifdef __cplusplus
  13. # define CM_CAST(TYPE, EXPR) static_cast<TYPE>(EXPR)
  14. # if __cplusplus >= 201103L
  15. # define CM_NULL nullptr
  16. # else
  17. # define CM_NULL NULL
  18. # endif
  19. #else
  20. # define CM_CAST(TYPE, EXPR) (TYPE)(EXPR)
  21. # define CM_NULL NULL
  22. #endif
  23. /* Create map. */
  24. typedef int (*MainFuncPointer)(int, char* []); /* NOLINT */
  25. typedef struct /* NOLINT */
  26. {
  27. const char* name;
  28. MainFuncPointer func;
  29. } functionMapEntry;
  30. static functionMapEntry cmakeGeneratedFunctionMapEntries[] = {
  31. @CMAKE_FUNCTION_TABLE_ENTRIES@
  32. { CM_NULL, CM_NULL } /* NOLINT */
  33. };
  34. static const int NumTests = CM_CAST(int,
  35. sizeof(cmakeGeneratedFunctionMapEntries) / sizeof(functionMapEntry)) - 1;
  36. /* Allocate and create a lowercased copy of string
  37. (note that it has to be free'd manually) */
  38. static char* lowercase(const char* string)
  39. {
  40. char *new_string;
  41. char *p;
  42. size_t stringSize;
  43. stringSize = CM_CAST(size_t, strlen(string) + 1);
  44. new_string = CM_CAST(char*, malloc(sizeof(char) * stringSize));
  45. if (new_string == CM_NULL) { /* NOLINT */
  46. return CM_NULL; /* NOLINT */
  47. }
  48. strcpy(new_string, string); /* NOLINT */
  49. for (p = new_string; *p != 0; ++p) {
  50. *p = CM_CAST(char, tolower(*p));
  51. }
  52. return new_string;
  53. }
  54. static int isTestSkipped(const char *name, int n_skipped_tests, char *skipped_tests[]) {
  55. int i;
  56. for (i = 0; i < n_skipped_tests; i++) {
  57. if (strcmp(name, skipped_tests[i]) == 0) {
  58. return 1;
  59. }
  60. }
  61. return 0;
  62. }
  63. int main(int ac, char* av[])
  64. {
  65. int i;
  66. int testNum = 0;
  67. int partial_match;
  68. int run_all;
  69. char *arg;
  70. int testToRun = -1;
  71. @CMAKE_TESTDRIVER_ARGVC_FUNCTION@
  72. /* If no test name was given */
  73. /* process command line with user function. */
  74. if (ac < 2) {
  75. /* Ask for a test. */
  76. printf("Available tests:\n");
  77. for (i = 0; i < NumTests; ++i) {
  78. printf("%3d. %s\n", i, cmakeGeneratedFunctionMapEntries[i].name);
  79. }
  80. printf("To run a test, enter the test number: ");
  81. fflush(stdout);
  82. if (scanf("%d", &testNum) != 1) {
  83. printf("Couldn't parse that input as a number\n");
  84. return -1;
  85. }
  86. if (testNum >= NumTests) {
  87. printf("%3d is an invalid test number.\n", testNum);
  88. return -1;
  89. }
  90. testToRun = testNum;
  91. ac--;
  92. av++;
  93. }
  94. partial_match = 0;
  95. run_all = 0;
  96. arg = CM_NULL; /* NOLINT */
  97. /* If partial match or running all tests are requested. */
  98. if (testToRun == -1 && ac > 1) {
  99. partial_match = (strcmp(av[1], "-R") == 0) ? 1 : 0;
  100. run_all = (strcmp(av[1], "-A") == 0) ? 1 : 0;
  101. }
  102. if (partial_match != 0 && ac < 3) {
  103. printf("-R needs an additional parameter.\n");
  104. return -1;
  105. }
  106. if (run_all == 1) {
  107. clock_t t;
  108. int status = 0;
  109. const char* status_message = CM_NULL;
  110. printf("TAP version 13\n");
  111. printf("1..%d\n", NumTests);
  112. for (i = 0; i < NumTests; ++i) {
  113. const char *name = cmakeGeneratedFunctionMapEntries[i].name;
  114. if (ac > 2) {
  115. if (isTestSkipped(name, ac - 2, av + 2) == 1) {
  116. printf("ok %d %s # SKIP\n", i + 1, name);
  117. continue;
  118. }
  119. }
  120. t = clock();
  121. status = (*cmakeGeneratedFunctionMapEntries[i].func)(ac, av);
  122. t = clock() - t;
  123. status_message = (status == -1) ? "not ok" : "ok";
  124. {
  125. double time_taken = CM_CAST(double, t) / CLOCKS_PER_SEC;
  126. printf("%s %d %s # %f\n", status_message, i + 1, name, time_taken);
  127. }
  128. }
  129. printf("All tests finished.\n");
  130. return 0;
  131. }
  132. if (testToRun == -1) {
  133. arg = lowercase(av[1 + partial_match]);
  134. }
  135. for (i = 0; i < NumTests && testToRun == -1; ++i) {
  136. char *test_name = lowercase(cmakeGeneratedFunctionMapEntries[i].name);
  137. if (partial_match != 0 && strstr(test_name, arg) != CM_NULL) { /* NOLINT */
  138. testToRun = i;
  139. ac -= 2;
  140. av += 2;
  141. } else if (partial_match == 0 && strcmp(test_name, arg) == 0) {
  142. testToRun = i;
  143. ac--;
  144. av++;
  145. }
  146. free(test_name);
  147. }
  148. free(arg);
  149. if (testToRun != -1) {
  150. int result;
  151. @CMAKE_TESTDRIVER_BEFORE_TESTMAIN@
  152. if (testToRun < 0 || testToRun >= NumTests) {
  153. printf("testToRun was modified by TestDriver code to an invalid value: "
  154. "%3d.\n",
  155. testNum);
  156. return -1;
  157. }
  158. result = (*cmakeGeneratedFunctionMapEntries[testToRun].func)(ac, av);
  159. @CMAKE_TESTDRIVER_AFTER_TESTMAIN@
  160. return result;
  161. }
  162. /* Nothing was run, display the test names. */
  163. printf("Available tests:\n");
  164. for (i = 0; i < NumTests; ++i) {
  165. printf("%3d. %s\n", i, cmakeGeneratedFunctionMapEntries[i].name);
  166. }
  167. printf("Failed: %s is an invalid test name.\n", av[1]);
  168. return -1;
  169. }