minimap2 0.2.25.1 → 0.2.26.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (109) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +9 -0
  3. data/ext/Rakefile +2 -2
  4. data/ext/minimap2/NEWS.md +9 -0
  5. data/ext/minimap2/README.md +2 -2
  6. data/ext/minimap2/cookbook.md +2 -2
  7. data/ext/minimap2/minimap.h +1 -1
  8. data/ext/minimap2/minimap2.1 +1 -1
  9. data/ext/minimap2/misc/paftools.js +1 -1
  10. data/ext/minimap2/python/mappy.pyx +1 -1
  11. data/ext/minimap2/setup.py +22 -32
  12. data/lib/minimap2/version.rb +1 -1
  13. metadata +1 -97
  14. data/ext/minimap2/lib/simde/CONTRIBUTING.md +0 -114
  15. data/ext/minimap2/lib/simde/COPYING +0 -20
  16. data/ext/minimap2/lib/simde/README.md +0 -333
  17. data/ext/minimap2/lib/simde/amalgamate.py +0 -58
  18. data/ext/minimap2/lib/simde/meson.build +0 -33
  19. data/ext/minimap2/lib/simde/netlify.toml +0 -20
  20. data/ext/minimap2/lib/simde/simde/arm/neon/float32x2.h +0 -140
  21. data/ext/minimap2/lib/simde/simde/arm/neon/float32x4.h +0 -137
  22. data/ext/minimap2/lib/simde/simde/arm/neon/float64x1.h +0 -142
  23. data/ext/minimap2/lib/simde/simde/arm/neon/float64x2.h +0 -145
  24. data/ext/minimap2/lib/simde/simde/arm/neon/int16x4.h +0 -140
  25. data/ext/minimap2/lib/simde/simde/arm/neon/int16x8.h +0 -145
  26. data/ext/minimap2/lib/simde/simde/arm/neon/int32x2.h +0 -140
  27. data/ext/minimap2/lib/simde/simde/arm/neon/int32x4.h +0 -143
  28. data/ext/minimap2/lib/simde/simde/arm/neon/int64x1.h +0 -137
  29. data/ext/minimap2/lib/simde/simde/arm/neon/int64x2.h +0 -141
  30. data/ext/minimap2/lib/simde/simde/arm/neon/int8x16.h +0 -147
  31. data/ext/minimap2/lib/simde/simde/arm/neon/int8x8.h +0 -141
  32. data/ext/minimap2/lib/simde/simde/arm/neon/uint16x4.h +0 -134
  33. data/ext/minimap2/lib/simde/simde/arm/neon/uint16x8.h +0 -138
  34. data/ext/minimap2/lib/simde/simde/arm/neon/uint32x2.h +0 -134
  35. data/ext/minimap2/lib/simde/simde/arm/neon/uint32x4.h +0 -137
  36. data/ext/minimap2/lib/simde/simde/arm/neon/uint64x1.h +0 -131
  37. data/ext/minimap2/lib/simde/simde/arm/neon/uint64x2.h +0 -135
  38. data/ext/minimap2/lib/simde/simde/arm/neon/uint8x16.h +0 -141
  39. data/ext/minimap2/lib/simde/simde/arm/neon/uint8x8.h +0 -135
  40. data/ext/minimap2/lib/simde/simde/arm/neon.h +0 -97
  41. data/ext/minimap2/lib/simde/simde/check.h +0 -267
  42. data/ext/minimap2/lib/simde/simde/debug-trap.h +0 -83
  43. data/ext/minimap2/lib/simde/simde/hedley.h +0 -1899
  44. data/ext/minimap2/lib/simde/simde/simde-arch.h +0 -445
  45. data/ext/minimap2/lib/simde/simde/simde-common.h +0 -697
  46. data/ext/minimap2/lib/simde/simde/x86/avx.h +0 -5385
  47. data/ext/minimap2/lib/simde/simde/x86/avx2.h +0 -2402
  48. data/ext/minimap2/lib/simde/simde/x86/avx512bw.h +0 -391
  49. data/ext/minimap2/lib/simde/simde/x86/avx512f.h +0 -3389
  50. data/ext/minimap2/lib/simde/simde/x86/avx512vl.h +0 -112
  51. data/ext/minimap2/lib/simde/simde/x86/fma.h +0 -659
  52. data/ext/minimap2/lib/simde/simde/x86/mmx.h +0 -2210
  53. data/ext/minimap2/lib/simde/simde/x86/sse.h +0 -3696
  54. data/ext/minimap2/lib/simde/simde/x86/sse2.h +0 -5991
  55. data/ext/minimap2/lib/simde/simde/x86/sse3.h +0 -343
  56. data/ext/minimap2/lib/simde/simde/x86/sse4.1.h +0 -1783
  57. data/ext/minimap2/lib/simde/simde/x86/sse4.2.h +0 -105
  58. data/ext/minimap2/lib/simde/simde/x86/ssse3.h +0 -1053
  59. data/ext/minimap2/lib/simde/simde/x86/svml.h +0 -543
  60. data/ext/minimap2/lib/simde/test/CMakeLists.txt +0 -166
  61. data/ext/minimap2/lib/simde/test/arm/meson.build +0 -4
  62. data/ext/minimap2/lib/simde/test/arm/neon/meson.build +0 -23
  63. data/ext/minimap2/lib/simde/test/arm/neon/skel.c +0 -871
  64. data/ext/minimap2/lib/simde/test/arm/neon/test-neon-internal.h +0 -134
  65. data/ext/minimap2/lib/simde/test/arm/neon/test-neon.c +0 -39
  66. data/ext/minimap2/lib/simde/test/arm/neon/test-neon.h +0 -10
  67. data/ext/minimap2/lib/simde/test/arm/neon/vadd.c +0 -1260
  68. data/ext/minimap2/lib/simde/test/arm/neon/vdup_n.c +0 -873
  69. data/ext/minimap2/lib/simde/test/arm/neon/vmul.c +0 -1084
  70. data/ext/minimap2/lib/simde/test/arm/neon/vsub.c +0 -1260
  71. data/ext/minimap2/lib/simde/test/arm/test-arm-internal.h +0 -18
  72. data/ext/minimap2/lib/simde/test/arm/test-arm.c +0 -20
  73. data/ext/minimap2/lib/simde/test/arm/test-arm.h +0 -8
  74. data/ext/minimap2/lib/simde/test/cmake/AddCompilerFlags.cmake +0 -171
  75. data/ext/minimap2/lib/simde/test/cmake/ExtraWarningFlags.cmake +0 -68
  76. data/ext/minimap2/lib/simde/test/meson.build +0 -64
  77. data/ext/minimap2/lib/simde/test/munit/COPYING +0 -21
  78. data/ext/minimap2/lib/simde/test/munit/Makefile +0 -55
  79. data/ext/minimap2/lib/simde/test/munit/README.md +0 -54
  80. data/ext/minimap2/lib/simde/test/munit/example.c +0 -351
  81. data/ext/minimap2/lib/simde/test/munit/meson.build +0 -37
  82. data/ext/minimap2/lib/simde/test/munit/munit.c +0 -2055
  83. data/ext/minimap2/lib/simde/test/munit/munit.h +0 -535
  84. data/ext/minimap2/lib/simde/test/run-tests.c +0 -20
  85. data/ext/minimap2/lib/simde/test/run-tests.h +0 -260
  86. data/ext/minimap2/lib/simde/test/x86/avx.c +0 -13752
  87. data/ext/minimap2/lib/simde/test/x86/avx2.c +0 -9977
  88. data/ext/minimap2/lib/simde/test/x86/avx512bw.c +0 -2664
  89. data/ext/minimap2/lib/simde/test/x86/avx512f.c +0 -10416
  90. data/ext/minimap2/lib/simde/test/x86/avx512vl.c +0 -210
  91. data/ext/minimap2/lib/simde/test/x86/fma.c +0 -2557
  92. data/ext/minimap2/lib/simde/test/x86/meson.build +0 -33
  93. data/ext/minimap2/lib/simde/test/x86/mmx.c +0 -2878
  94. data/ext/minimap2/lib/simde/test/x86/skel.c +0 -2984
  95. data/ext/minimap2/lib/simde/test/x86/sse.c +0 -5121
  96. data/ext/minimap2/lib/simde/test/x86/sse2.c +0 -9860
  97. data/ext/minimap2/lib/simde/test/x86/sse3.c +0 -486
  98. data/ext/minimap2/lib/simde/test/x86/sse4.1.c +0 -3446
  99. data/ext/minimap2/lib/simde/test/x86/sse4.2.c +0 -101
  100. data/ext/minimap2/lib/simde/test/x86/ssse3.c +0 -2084
  101. data/ext/minimap2/lib/simde/test/x86/svml.c +0 -1545
  102. data/ext/minimap2/lib/simde/test/x86/test-avx.h +0 -16
  103. data/ext/minimap2/lib/simde/test/x86/test-avx512.h +0 -25
  104. data/ext/minimap2/lib/simde/test/x86/test-mmx.h +0 -13
  105. data/ext/minimap2/lib/simde/test/x86/test-sse.h +0 -13
  106. data/ext/minimap2/lib/simde/test/x86/test-sse2.h +0 -13
  107. data/ext/minimap2/lib/simde/test/x86/test-x86-internal.h +0 -196
  108. data/ext/minimap2/lib/simde/test/x86/test-x86.c +0 -48
  109. data/ext/minimap2/lib/simde/test/x86/test-x86.h +0 -8
@@ -1,2055 +0,0 @@
1
- /* Copyright (c) 2013-2018 Evan Nemerson <evan@nemerson.com>
2
- *
3
- * Permission is hereby granted, free of charge, to any person
4
- * obtaining a copy of this software and associated documentation
5
- * files (the "Software"), to deal in the Software without
6
- * restriction, including without limitation the rights to use, copy,
7
- * modify, merge, publish, distribute, sublicense, and/or sell copies
8
- * of the Software, and to permit persons to whom the Software is
9
- * furnished to do so, subject to the following conditions:
10
- *
11
- * The above copyright notice and this permission notice shall be
12
- * included in all copies or substantial portions of the Software.
13
- *
14
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
18
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
19
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- * SOFTWARE.
22
- */
23
-
24
- /*** Configuration ***/
25
-
26
- /* This is just where the output from the test goes. It's really just
27
- * meant to let you choose stdout or stderr, but if anyone really want
28
- * to direct it to a file let me know, it would be fairly easy to
29
- * support. */
30
- #if !defined(MUNIT_OUTPUT_FILE)
31
- # define MUNIT_OUTPUT_FILE stdout
32
- #endif
33
-
34
- /* This is a bit more useful; it tells µnit how to format the seconds in
35
- * timed tests. If your tests run for longer you might want to reduce
36
- * it, and if your computer is really fast and your tests are tiny you
37
- * can increase it. */
38
- #if !defined(MUNIT_TEST_TIME_FORMAT)
39
- # define MUNIT_TEST_TIME_FORMAT "0.8f"
40
- #endif
41
-
42
- /* If you have long test names you might want to consider bumping
43
- * this. The result information takes 43 characters. */
44
- #if !defined(MUNIT_TEST_NAME_LEN)
45
- # define MUNIT_TEST_NAME_LEN 37
46
- #endif
47
-
48
- /* If you don't like the timing information, you can disable it by
49
- * defining MUNIT_DISABLE_TIMING. */
50
- #if !defined(MUNIT_DISABLE_TIMING)
51
- # define MUNIT_ENABLE_TIMING
52
- #endif
53
-
54
- /*** End configuration ***/
55
-
56
- #if defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE < 200809L)
57
- # undef _POSIX_C_SOURCE
58
- #endif
59
- #if !defined(_POSIX_C_SOURCE)
60
- # define _POSIX_C_SOURCE 200809L
61
- #endif
62
-
63
- /* Solaris freaks out if you try to use a POSIX or SUS standard without
64
- * the "right" C standard. */
65
- #if defined(_XOPEN_SOURCE)
66
- # undef _XOPEN_SOURCE
67
- #endif
68
-
69
- #if defined(__STDC_VERSION__)
70
- # if __STDC_VERSION__ >= 201112L
71
- # define _XOPEN_SOURCE 700
72
- # elif __STDC_VERSION__ >= 199901L
73
- # define _XOPEN_SOURCE 600
74
- # endif
75
- #endif
76
-
77
- /* Because, according to Microsoft, POSIX is deprecated. You've got
78
- * to appreciate the chutzpah. */
79
- #if defined(_MSC_VER) && !defined(_CRT_NONSTDC_NO_DEPRECATE)
80
- # define _CRT_NONSTDC_NO_DEPRECATE
81
- #endif
82
-
83
- #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
84
- # include <stdbool.h>
85
- #elif defined(_WIN32)
86
- /* https://msdn.microsoft.com/en-us/library/tf4dy80a.aspx */
87
- #endif
88
-
89
- #include <limits.h>
90
- #include <time.h>
91
- #include <errno.h>
92
- #include <string.h>
93
- #include <stdlib.h>
94
- #include <stdio.h>
95
- #include <stdarg.h>
96
- #include <setjmp.h>
97
-
98
- #if !defined(MUNIT_NO_NL_LANGINFO) && !defined(_WIN32)
99
- #define MUNIT_NL_LANGINFO
100
- #include <locale.h>
101
- #include <langinfo.h>
102
- #include <strings.h>
103
- #endif
104
-
105
- #if !defined(_WIN32)
106
- # include <unistd.h>
107
- # include <sys/types.h>
108
- # include <sys/wait.h>
109
- #else
110
- # include <windows.h>
111
- # include <io.h>
112
- # include <fcntl.h>
113
- # if !defined(STDERR_FILENO)
114
- # define STDERR_FILENO _fileno(stderr)
115
- # endif
116
- #endif
117
-
118
- #include "munit.h"
119
-
120
- #define MUNIT_STRINGIFY(x) #x
121
- #define MUNIT_XSTRINGIFY(x) MUNIT_STRINGIFY(x)
122
-
123
- #if defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__SUNPRO_CC) || defined(__IBMCPP__)
124
- # define MUNIT_THREAD_LOCAL __thread
125
- #elif (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201102L)) || defined(_Thread_local)
126
- # define MUNIT_THREAD_LOCAL _Thread_local
127
- #elif defined(_WIN32)
128
- # define MUNIT_THREAD_LOCAL __declspec(thread)
129
- #endif
130
-
131
- /* MSVC 12.0 will emit a warning at /W4 for code like 'do { ... }
132
- * while (0)', or 'do { ... } while (1)'. I'm pretty sure nobody
133
- * at Microsoft compiles with /W4. */
134
- #if defined(_MSC_VER) && (_MSC_VER <= 1800)
135
- #pragma warning(disable: 4127)
136
- #endif
137
-
138
- #if defined(_WIN32) || defined(__EMSCRIPTEN__)
139
- # define MUNIT_NO_FORK
140
- #endif
141
-
142
- #if defined(__EMSCRIPTEN__)
143
- # define MUNIT_NO_BUFFER
144
- #endif
145
-
146
- /*** Logging ***/
147
-
148
- static MunitLogLevel munit_log_level_visible = MUNIT_LOG_INFO;
149
- static MunitLogLevel munit_log_level_fatal = MUNIT_LOG_ERROR;
150
-
151
- #if defined(MUNIT_THREAD_LOCAL)
152
- static MUNIT_THREAD_LOCAL munit_bool munit_error_jmp_buf_valid = 0;
153
- static MUNIT_THREAD_LOCAL jmp_buf munit_error_jmp_buf;
154
- #endif
155
-
156
- /* At certain warning levels, mingw will trigger warnings about
157
- * suggesting the format attribute, which we've explicity *not* set
158
- * because it will then choke on our attempts to use the MS-specific
159
- * I64 modifier for size_t (which we have to use since MSVC doesn't
160
- * support the C99 z modifier). */
161
-
162
- #if defined(__MINGW32__) || defined(__MINGW64__)
163
- # pragma GCC diagnostic push
164
- # pragma GCC diagnostic ignored "-Wsuggest-attribute=format"
165
- #endif
166
-
167
- MUNIT_PRINTF(5,0)
168
- static void
169
- munit_logf_exv(MunitLogLevel level, FILE* fp, const char* filename, int line, const char* format, va_list ap) {
170
- if (level < munit_log_level_visible)
171
- return;
172
-
173
- switch (level) {
174
- case MUNIT_LOG_DEBUG:
175
- fputs("Debug", fp);
176
- break;
177
- case MUNIT_LOG_INFO:
178
- fputs("Info", fp);
179
- break;
180
- case MUNIT_LOG_WARNING:
181
- fputs("Warning", fp);
182
- break;
183
- case MUNIT_LOG_ERROR:
184
- fputs("Error", fp);
185
- break;
186
- default:
187
- munit_logf_ex(MUNIT_LOG_ERROR, filename, line, "Invalid log level (%d)", level);
188
- return;
189
- }
190
-
191
- fputs(": ", fp);
192
- if (filename != NULL)
193
- fprintf(fp, "%s:%d: ", filename, line);
194
- vfprintf(fp, format, ap);
195
- fputc('\n', fp);
196
- }
197
-
198
- MUNIT_PRINTF(3,4)
199
- static void
200
- munit_logf_internal(MunitLogLevel level, FILE* fp, const char* format, ...) {
201
- va_list ap;
202
-
203
- va_start(ap, format);
204
- munit_logf_exv(level, fp, NULL, 0, format, ap);
205
- va_end(ap);
206
- }
207
-
208
- static void
209
- munit_log_internal(MunitLogLevel level, FILE* fp, const char* message) {
210
- munit_logf_internal(level, fp, "%s", message);
211
- }
212
-
213
- void
214
- munit_logf_ex(MunitLogLevel level, const char* filename, int line, const char* format, ...) {
215
- va_list ap;
216
-
217
- va_start(ap, format);
218
- munit_logf_exv(level, stderr, filename, line, format, ap);
219
- va_end(ap);
220
-
221
- if (level >= munit_log_level_fatal) {
222
- #if defined(MUNIT_THREAD_LOCAL)
223
- if (munit_error_jmp_buf_valid)
224
- longjmp(munit_error_jmp_buf, 1);
225
- #endif
226
- abort();
227
- }
228
- }
229
-
230
- void
231
- munit_errorf_ex(const char* filename, int line, const char* format, ...) {
232
- va_list ap;
233
-
234
- va_start(ap, format);
235
- munit_logf_exv(MUNIT_LOG_ERROR, stderr, filename, line, format, ap);
236
- va_end(ap);
237
-
238
- #if defined(MUNIT_THREAD_LOCAL)
239
- if (munit_error_jmp_buf_valid)
240
- longjmp(munit_error_jmp_buf, 1);
241
- #endif
242
- abort();
243
- }
244
-
245
- #if defined(__MINGW32__) || defined(__MINGW64__)
246
- #pragma GCC diagnostic pop
247
- #endif
248
-
249
- #if !defined(MUNIT_STRERROR_LEN)
250
- # define MUNIT_STRERROR_LEN 80
251
- #endif
252
-
253
- static void
254
- munit_log_errno(MunitLogLevel level, FILE* fp, const char* msg) {
255
- #if defined(MUNIT_NO_STRERROR_R) || (defined(__MINGW32__) && !defined(MINGW_HAS_SECURE_API))
256
- munit_logf_internal(level, fp, "%s: %s (%d)", msg, strerror(errno), errno);
257
- #else
258
- char munit_error_str[MUNIT_STRERROR_LEN];
259
- munit_error_str[0] = '\0';
260
-
261
- #if !defined(_WIN32)
262
- strerror_r(errno, munit_error_str, MUNIT_STRERROR_LEN);
263
- #else
264
- strerror_s(munit_error_str, MUNIT_STRERROR_LEN, errno);
265
- #endif
266
-
267
- munit_logf_internal(level, fp, "%s: %s (%d)", msg, munit_error_str, errno);
268
- #endif
269
- }
270
-
271
- /*** Memory allocation ***/
272
-
273
- void*
274
- munit_malloc_ex(const char* filename, int line, size_t size) {
275
- void* ptr;
276
-
277
- if (size == 0)
278
- return NULL;
279
-
280
- ptr = calloc(1, size);
281
- if (MUNIT_UNLIKELY(ptr == NULL)) {
282
- munit_logf_ex(MUNIT_LOG_ERROR, filename, line, "Failed to allocate %" MUNIT_SIZE_MODIFIER "u bytes.", size);
283
- }
284
-
285
- return ptr;
286
- }
287
-
288
- /*** Timer code ***/
289
-
290
- #if defined(MUNIT_ENABLE_TIMING)
291
-
292
- #define psnip_uint64_t munit_uint64_t
293
- #define psnip_uint32_t munit_uint32_t
294
-
295
- /* Code copied from portable-snippets
296
- * <https://github.com/nemequ/portable-snippets/>. If you need to
297
- * change something, please do it there so we can keep the code in
298
- * sync. */
299
-
300
- /* Clocks (v1)
301
- * Portable Snippets - https://gitub.com/nemequ/portable-snippets
302
- * Created by Evan Nemerson <evan@nemerson.com>
303
- *
304
- * To the extent possible under law, the authors have waived all
305
- * copyright and related or neighboring rights to this code. For
306
- * details, see the Creative Commons Zero 1.0 Universal license at
307
- * https://creativecommons.org/publicdomain/zero/1.0/
308
- */
309
-
310
- #if !defined(PSNIP_CLOCK_H)
311
- #define PSNIP_CLOCK_H
312
-
313
- #if !defined(psnip_uint64_t)
314
- # include "../exact-int/exact-int.h"
315
- #endif
316
-
317
- #if !defined(PSNIP_CLOCK_STATIC_INLINE)
318
- # if defined(__GNUC__)
319
- # define PSNIP_CLOCK__COMPILER_ATTRIBUTES __attribute__((__unused__))
320
- # else
321
- # define PSNIP_CLOCK__COMPILER_ATTRIBUTES
322
- # endif
323
-
324
- # define PSNIP_CLOCK__FUNCTION PSNIP_CLOCK__COMPILER_ATTRIBUTES static
325
- #endif
326
-
327
- enum PsnipClockType {
328
- /* This clock provides the current time, in units since 1970-01-01
329
- * 00:00:00 UTC not including leap seconds. In other words, UNIX
330
- * time. Keep in mind that this clock doesn't account for leap
331
- * seconds, and can go backwards (think NTP adjustments). */
332
- PSNIP_CLOCK_TYPE_WALL = 1,
333
- /* The CPU time is a clock which increases only when the current
334
- * process is active (i.e., it doesn't increment while blocking on
335
- * I/O). */
336
- PSNIP_CLOCK_TYPE_CPU = 2,
337
- /* Monotonic time is always running (unlike CPU time), but it only
338
- ever moves forward unless you reboot the system. Things like NTP
339
- adjustments have no effect on this clock. */
340
- PSNIP_CLOCK_TYPE_MONOTONIC = 3
341
- };
342
-
343
- struct PsnipClockTimespec {
344
- psnip_uint64_t seconds;
345
- psnip_uint64_t nanoseconds;
346
- };
347
-
348
- /* Methods we support: */
349
-
350
- #define PSNIP_CLOCK_METHOD_CLOCK_GETTIME 1
351
- #define PSNIP_CLOCK_METHOD_TIME 2
352
- #define PSNIP_CLOCK_METHOD_GETTIMEOFDAY 3
353
- #define PSNIP_CLOCK_METHOD_QUERYPERFORMANCECOUNTER 4
354
- #define PSNIP_CLOCK_METHOD_MACH_ABSOLUTE_TIME 5
355
- #define PSNIP_CLOCK_METHOD_CLOCK 6
356
- #define PSNIP_CLOCK_METHOD_GETPROCESSTIMES 7
357
- #define PSNIP_CLOCK_METHOD_GETRUSAGE 8
358
- #define PSNIP_CLOCK_METHOD_GETSYSTEMTIMEPRECISEASFILETIME 9
359
- #define PSNIP_CLOCK_METHOD_GETTICKCOUNT64 10
360
-
361
- #include <assert.h>
362
-
363
- #if defined(HEDLEY_UNREACHABLE)
364
- # define PSNIP_CLOCK_UNREACHABLE() HEDLEY_UNREACHABLE()
365
- #else
366
- # define PSNIP_CLOCK_UNREACHABLE() assert(0)
367
- #endif
368
-
369
- /* Choose an implementation */
370
-
371
- /* #undef PSNIP_CLOCK_WALL_METHOD */
372
- /* #undef PSNIP_CLOCK_CPU_METHOD */
373
- /* #undef PSNIP_CLOCK_MONOTONIC_METHOD */
374
-
375
- /* We want to be able to detect the libc implementation, so we include
376
- <limits.h> (<features.h> isn't available everywhere). */
377
-
378
- #if defined(__unix__) || defined(__unix) || defined(__linux__)
379
- # include <limits.h>
380
- # include <unistd.h>
381
- #endif
382
-
383
- #if defined(_POSIX_TIMERS) && (_POSIX_TIMERS > 0)
384
- /* These are known to work without librt. If you know of others
385
- * please let us know so we can add them. */
386
- # if \
387
- (defined(__GLIBC__) && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 17))) || \
388
- (defined(__FreeBSD__))
389
- # define PSNIP_CLOCK_HAVE_CLOCK_GETTIME
390
- # elif !defined(PSNIP_CLOCK_NO_LIBRT)
391
- # define PSNIP_CLOCK_HAVE_CLOCK_GETTIME
392
- # endif
393
- #endif
394
-
395
- #if defined(_WIN32)
396
- # if !defined(PSNIP_CLOCK_CPU_METHOD)
397
- # define PSNIP_CLOCK_CPU_METHOD PSNIP_CLOCK_METHOD_GETPROCESSTIMES
398
- # endif
399
- # if !defined(PSNIP_CLOCK_MONOTONIC_METHOD)
400
- # define PSNIP_CLOCK_MONOTONIC_METHOD PSNIP_CLOCK_METHOD_QUERYPERFORMANCECOUNTER
401
- # endif
402
- #endif
403
-
404
- #if defined(__MACH__) && !defined(__gnu_hurd__)
405
- # if !defined(PSNIP_CLOCK_MONOTONIC_METHOD)
406
- # define PSNIP_CLOCK_MONOTONIC_METHOD PSNIP_CLOCK_METHOD_MACH_ABSOLUTE_TIME
407
- # endif
408
- #endif
409
-
410
- #if defined(PSNIP_CLOCK_HAVE_CLOCK_GETTIME)
411
- # include <time.h>
412
- # if !defined(PSNIP_CLOCK_WALL_METHOD)
413
- # if defined(CLOCK_REALTIME_PRECISE)
414
- # define PSNIP_CLOCK_WALL_METHOD PSNIP_CLOCK_METHOD_CLOCK_GETTIME
415
- # define PSNIP_CLOCK_CLOCK_GETTIME_WALL CLOCK_REALTIME_PRECISE
416
- # elif !defined(__sun)
417
- # define PSNIP_CLOCK_WALL_METHOD PSNIP_CLOCK_METHOD_CLOCK_GETTIME
418
- # define PSNIP_CLOCK_CLOCK_GETTIME_WALL CLOCK_REALTIME
419
- # endif
420
- # endif
421
- # if !defined(PSNIP_CLOCK_CPU_METHOD)
422
- # if defined(_POSIX_CPUTIME) || defined(CLOCK_PROCESS_CPUTIME_ID)
423
- # define PSNIP_CLOCK_CPU_METHOD PSNIP_CLOCK_METHOD_CLOCK_GETTIME
424
- # define PSNIP_CLOCK_CLOCK_GETTIME_CPU CLOCK_PROCESS_CPUTIME_ID
425
- # elif defined(CLOCK_VIRTUAL)
426
- # define PSNIP_CLOCK_CPU_METHOD PSNIP_CLOCK_METHOD_CLOCK_GETTIME
427
- # define PSNIP_CLOCK_CLOCK_GETTIME_CPU CLOCK_VIRTUAL
428
- # endif
429
- # endif
430
- # if !defined(PSNIP_CLOCK_MONOTONIC_METHOD)
431
- # if defined(CLOCK_MONOTONIC_RAW)
432
- # define PSNIP_CLOCK_MONOTONIC_METHOD PSNIP_CLOCK_METHOD_CLOCK_GETTIME
433
- # define PSNIP_CLOCK_CLOCK_GETTIME_MONOTONIC CLOCK_MONOTONIC
434
- # elif defined(CLOCK_MONOTONIC_PRECISE)
435
- # define PSNIP_CLOCK_MONOTONIC_METHOD PSNIP_CLOCK_METHOD_CLOCK_GETTIME
436
- # define PSNIP_CLOCK_CLOCK_GETTIME_MONOTONIC CLOCK_MONOTONIC_PRECISE
437
- # elif defined(_POSIX_MONOTONIC_CLOCK) || defined(CLOCK_MONOTONIC)
438
- # define PSNIP_CLOCK_MONOTONIC_METHOD PSNIP_CLOCK_METHOD_CLOCK_GETTIME
439
- # define PSNIP_CLOCK_CLOCK_GETTIME_MONOTONIC CLOCK_MONOTONIC
440
- # endif
441
- # endif
442
- #endif
443
-
444
- #if defined(_POSIX_VERSION) && (_POSIX_VERSION >= 200112L)
445
- # if !defined(PSNIP_CLOCK_WALL_METHOD)
446
- # define PSNIP_CLOCK_WALL_METHOD PSNIP_CLOCK_METHOD_GETTIMEOFDAY
447
- # endif
448
- #endif
449
-
450
- #if !defined(PSNIP_CLOCK_WALL_METHOD)
451
- # define PSNIP_CLOCK_WALL_METHOD PSNIP_CLOCK_METHOD_TIME
452
- #endif
453
-
454
- #if !defined(PSNIP_CLOCK_CPU_METHOD)
455
- # define PSNIP_CLOCK_CPU_METHOD PSNIP_CLOCK_METHOD_CLOCK
456
- #endif
457
-
458
- /* Primarily here for testing. */
459
- #if !defined(PSNIP_CLOCK_MONOTONIC_METHOD) && defined(PSNIP_CLOCK_REQUIRE_MONOTONIC)
460
- # error No monotonic clock found.
461
- #endif
462
-
463
- /* Implementations */
464
-
465
- #if \
466
- (defined(PSNIP_CLOCK_CPU_METHOD) && (PSNIP_CLOCK_CPU_METHOD == PSNIP_CLOCK_METHOD_CLOCK_GETTIME)) || \
467
- (defined(PSNIP_CLOCK_WALL_METHOD) && (PSNIP_CLOCK_WALL_METHOD == PSNIP_CLOCK_METHOD_CLOCK_GETTIME)) || \
468
- (defined(PSNIP_CLOCK_MONOTONIC_METHOD) && (PSNIP_CLOCK_MONOTONIC_METHOD == PSNIP_CLOCK_METHOD_CLOCK_GETTIME)) || \
469
- (defined(PSNIP_CLOCK_CPU_METHOD) && (PSNIP_CLOCK_CPU_METHOD == PSNIP_CLOCK_METHOD_CLOCK)) || \
470
- (defined(PSNIP_CLOCK_WALL_METHOD) && (PSNIP_CLOCK_WALL_METHOD == PSNIP_CLOCK_METHOD_CLOCK)) || \
471
- (defined(PSNIP_CLOCK_MONOTONIC_METHOD) && (PSNIP_CLOCK_MONOTONIC_METHOD == PSNIP_CLOCK_METHOD_CLOCK)) || \
472
- (defined(PSNIP_CLOCK_CPU_METHOD) && (PSNIP_CLOCK_CPU_METHOD == PSNIP_CLOCK_METHOD_TIME)) || \
473
- (defined(PSNIP_CLOCK_WALL_METHOD) && (PSNIP_CLOCK_WALL_METHOD == PSNIP_CLOCK_METHOD_TIME)) || \
474
- (defined(PSNIP_CLOCK_MONOTONIC_METHOD) && (PSNIP_CLOCK_MONOTONIC_METHOD == PSNIP_CLOCK_METHOD_TIME))
475
- # include <time.h>
476
- #endif
477
-
478
- #if \
479
- (defined(PSNIP_CLOCK_CPU_METHOD) && (PSNIP_CLOCK_CPU_METHOD == PSNIP_CLOCK_METHOD_GETTIMEOFDAY)) || \
480
- (defined(PSNIP_CLOCK_WALL_METHOD) && (PSNIP_CLOCK_WALL_METHOD == PSNIP_CLOCK_METHOD_GETTIMEOFDAY)) || \
481
- (defined(PSNIP_CLOCK_MONOTONIC_METHOD) && (PSNIP_CLOCK_MONOTONIC_METHOD == PSNIP_CLOCK_METHOD_GETTIMEOFDAY))
482
- # include <sys/time.h>
483
- #endif
484
-
485
- #if \
486
- (defined(PSNIP_CLOCK_CPU_METHOD) && (PSNIP_CLOCK_CPU_METHOD == PSNIP_CLOCK_METHOD_GETPROCESSTIMES)) || \
487
- (defined(PSNIP_CLOCK_WALL_METHOD) && (PSNIP_CLOCK_WALL_METHOD == PSNIP_CLOCK_METHOD_GETPROCESSTIMES)) || \
488
- (defined(PSNIP_CLOCK_MONOTONIC_METHOD) && (PSNIP_CLOCK_MONOTONIC_METHOD == PSNIP_CLOCK_METHOD_GETPROCESSTIMES)) || \
489
- (defined(PSNIP_CLOCK_CPU_METHOD) && (PSNIP_CLOCK_CPU_METHOD == PSNIP_CLOCK_METHOD_GETTICKCOUNT64)) || \
490
- (defined(PSNIP_CLOCK_WALL_METHOD) && (PSNIP_CLOCK_WALL_METHOD == PSNIP_CLOCK_METHOD_GETTICKCOUNT64)) || \
491
- (defined(PSNIP_CLOCK_MONOTONIC_METHOD) && (PSNIP_CLOCK_MONOTONIC_METHOD == PSNIP_CLOCK_METHOD_GETTICKCOUNT64))
492
- # include <windows.h>
493
- #endif
494
-
495
- #if \
496
- (defined(PSNIP_CLOCK_CPU_METHOD) && (PSNIP_CLOCK_CPU_METHOD == PSNIP_CLOCK_METHOD_GETRUSAGE)) || \
497
- (defined(PSNIP_CLOCK_WALL_METHOD) && (PSNIP_CLOCK_WALL_METHOD == PSNIP_CLOCK_METHOD_GETRUSAGE)) || \
498
- (defined(PSNIP_CLOCK_MONOTONIC_METHOD) && (PSNIP_CLOCK_MONOTONIC_METHOD == PSNIP_CLOCK_METHOD_GETRUSAGE))
499
- # include <sys/time.h>
500
- # include <sys/resource.h>
501
- #endif
502
-
503
- #if \
504
- (defined(PSNIP_CLOCK_CPU_METHOD) && (PSNIP_CLOCK_CPU_METHOD == PSNIP_CLOCK_METHOD_MACH_ABSOLUTE_TIME)) || \
505
- (defined(PSNIP_CLOCK_WALL_METHOD) && (PSNIP_CLOCK_WALL_METHOD == PSNIP_CLOCK_METHOD_MACH_ABSOLUTE_TIME)) || \
506
- (defined(PSNIP_CLOCK_MONOTONIC_METHOD) && (PSNIP_CLOCK_MONOTONIC_METHOD == PSNIP_CLOCK_METHOD_MACH_ABSOLUTE_TIME))
507
- # include <CoreServices/CoreServices.h>
508
- # include <mach/mach.h>
509
- # include <mach/mach_time.h>
510
- #endif
511
-
512
- /*** Implementations ***/
513
-
514
- #define PSNIP_CLOCK_NSEC_PER_SEC ((psnip_uint32_t) (1000000000ULL))
515
-
516
- #if \
517
- (defined(PSNIP_CLOCK_CPU_METHOD) && (PSNIP_CLOCK_CPU_METHOD == PSNIP_CLOCK_METHOD_CLOCK_GETTIME)) || \
518
- (defined(PSNIP_CLOCK_WALL_METHOD) && (PSNIP_CLOCK_WALL_METHOD == PSNIP_CLOCK_METHOD_CLOCK_GETTIME)) || \
519
- (defined(PSNIP_CLOCK_MONOTONIC_METHOD) && (PSNIP_CLOCK_MONOTONIC_METHOD == PSNIP_CLOCK_METHOD_CLOCK_GETTIME))
520
- PSNIP_CLOCK__FUNCTION psnip_uint32_t
521
- psnip_clock__clock_getres (clockid_t clk_id) {
522
- struct timespec res;
523
- int r;
524
-
525
- r = clock_getres(clk_id, &res);
526
- if (r != 0)
527
- return 0;
528
-
529
- return (psnip_uint32_t) (PSNIP_CLOCK_NSEC_PER_SEC / res.tv_nsec);
530
- }
531
-
532
- PSNIP_CLOCK__FUNCTION int
533
- psnip_clock__clock_gettime (clockid_t clk_id, struct PsnipClockTimespec* res) {
534
- struct timespec ts;
535
-
536
- if (clock_gettime(clk_id, &ts) != 0)
537
- return -10;
538
-
539
- res->seconds = (psnip_uint64_t) (ts.tv_sec);
540
- res->nanoseconds = (psnip_uint64_t) (ts.tv_nsec);
541
-
542
- return 0;
543
- }
544
- #endif
545
-
546
- PSNIP_CLOCK__FUNCTION psnip_uint32_t
547
- psnip_clock_wall_get_precision (void) {
548
- #if !defined(PSNIP_CLOCK_WALL_METHOD)
549
- return 0;
550
- #elif defined(PSNIP_CLOCK_WALL_METHOD) && PSNIP_CLOCK_WALL_METHOD == PSNIP_CLOCK_METHOD_CLOCK_GETTIME
551
- return psnip_clock__clock_getres(PSNIP_CLOCK_CLOCK_GETTIME_WALL);
552
- #elif defined(PSNIP_CLOCK_WALL_METHOD) && PSNIP_CLOCK_WALL_METHOD == PSNIP_CLOCK_METHOD_GETTIMEOFDAY
553
- return 1000000;
554
- #elif defined(PSNIP_CLOCK_WALL_METHOD) && PSNIP_CLOCK_WALL_METHOD == PSNIP_CLOCK_METHOD_TIME
555
- return 1;
556
- #else
557
- return 0;
558
- #endif
559
- }
560
-
561
- PSNIP_CLOCK__FUNCTION int
562
- psnip_clock_wall_get_time (struct PsnipClockTimespec* res) {
563
- (void) res;
564
-
565
- #if !defined(PSNIP_CLOCK_WALL_METHOD)
566
- return -2;
567
- #elif defined(PSNIP_CLOCK_WALL_METHOD) && PSNIP_CLOCK_WALL_METHOD == PSNIP_CLOCK_METHOD_CLOCK_GETTIME
568
- return psnip_clock__clock_gettime(PSNIP_CLOCK_CLOCK_GETTIME_WALL, res);
569
- #elif defined(PSNIP_CLOCK_WALL_METHOD) && PSNIP_CLOCK_WALL_METHOD == PSNIP_CLOCK_METHOD_TIME
570
- res->seconds = time(NULL);
571
- res->nanoseconds = 0;
572
- #elif defined(PSNIP_CLOCK_WALL_METHOD) && PSNIP_CLOCK_WALL_METHOD == PSNIP_CLOCK_METHOD_GETTIMEOFDAY
573
- struct timeval tv;
574
-
575
- if (gettimeofday(&tv, NULL) != 0)
576
- return -6;
577
-
578
- res->seconds = tv.tv_sec;
579
- res->nanoseconds = tv.tv_usec * 1000;
580
- #else
581
- return -2;
582
- #endif
583
-
584
- return 0;
585
- }
586
-
587
- PSNIP_CLOCK__FUNCTION psnip_uint32_t
588
- psnip_clock_cpu_get_precision (void) {
589
- #if !defined(PSNIP_CLOCK_CPU_METHOD)
590
- return 0;
591
- #elif defined(PSNIP_CLOCK_CPU_METHOD) && PSNIP_CLOCK_CPU_METHOD == PSNIP_CLOCK_METHOD_CLOCK_GETTIME
592
- return psnip_clock__clock_getres(PSNIP_CLOCK_CLOCK_GETTIME_CPU);
593
- #elif defined(PSNIP_CLOCK_CPU_METHOD) && PSNIP_CLOCK_CPU_METHOD == PSNIP_CLOCK_METHOD_CLOCK
594
- return CLOCKS_PER_SEC;
595
- #elif defined(PSNIP_CLOCK_CPU_METHOD) && PSNIP_CLOCK_CPU_METHOD == PSNIP_CLOCK_METHOD_GETPROCESSTIMES
596
- return PSNIP_CLOCK_NSEC_PER_SEC / 100;
597
- #else
598
- return 0;
599
- #endif
600
- }
601
-
602
- PSNIP_CLOCK__FUNCTION int
603
- psnip_clock_cpu_get_time (struct PsnipClockTimespec* res) {
604
- #if !defined(PSNIP_CLOCK_CPU_METHOD)
605
- (void) res;
606
- return -2;
607
- #elif defined(PSNIP_CLOCK_CPU_METHOD) && PSNIP_CLOCK_CPU_METHOD == PSNIP_CLOCK_METHOD_CLOCK_GETTIME
608
- return psnip_clock__clock_gettime(PSNIP_CLOCK_CLOCK_GETTIME_CPU, res);
609
- #elif defined(PSNIP_CLOCK_CPU_METHOD) && PSNIP_CLOCK_CPU_METHOD == PSNIP_CLOCK_METHOD_CLOCK
610
- clock_t t = clock();
611
- if (t == ((clock_t) -1))
612
- return -5;
613
- res->seconds = t / CLOCKS_PER_SEC;
614
- res->nanoseconds = (t % CLOCKS_PER_SEC) * (PSNIP_CLOCK_NSEC_PER_SEC / CLOCKS_PER_SEC);
615
- #elif defined(PSNIP_CLOCK_CPU_METHOD) && PSNIP_CLOCK_CPU_METHOD == PSNIP_CLOCK_METHOD_GETPROCESSTIMES
616
- FILETIME CreationTime, ExitTime, KernelTime, UserTime;
617
- LARGE_INTEGER date, adjust;
618
-
619
- if (!GetProcessTimes(GetCurrentProcess(), &CreationTime, &ExitTime, &KernelTime, &UserTime))
620
- return -7;
621
-
622
- /* http://www.frenk.com/2009/12/convert-filetime-to-unix-timestamp/ */
623
- date.HighPart = UserTime.dwHighDateTime;
624
- date.LowPart = UserTime.dwLowDateTime;
625
- adjust.QuadPart = 11644473600000 * 10000;
626
- date.QuadPart -= adjust.QuadPart;
627
-
628
- res->seconds = date.QuadPart / 10000000;
629
- res->nanoseconds = (date.QuadPart % 10000000) * (PSNIP_CLOCK_NSEC_PER_SEC / 100);
630
- #elif PSNIP_CLOCK_CPU_METHOD == PSNIP_CLOCK_METHOD_GETRUSAGE
631
- struct rusage usage;
632
- if (getrusage(RUSAGE_SELF, &usage) != 0)
633
- return -8;
634
-
635
- res->seconds = usage.ru_utime.tv_sec;
636
- res->nanoseconds = tv.tv_usec * 1000;
637
- #else
638
- (void) res;
639
- return -2;
640
- #endif
641
-
642
- return 0;
643
- }
644
-
645
- PSNIP_CLOCK__FUNCTION psnip_uint32_t
646
- psnip_clock_monotonic_get_precision (void) {
647
- #if !defined(PSNIP_CLOCK_MONOTONIC_METHOD)
648
- return 0;
649
- #elif defined(PSNIP_CLOCK_MONOTONIC_METHOD) && PSNIP_CLOCK_MONOTONIC_METHOD == PSNIP_CLOCK_METHOD_CLOCK_GETTIME
650
- return psnip_clock__clock_getres(PSNIP_CLOCK_CLOCK_GETTIME_MONOTONIC);
651
- #elif defined(PSNIP_CLOCK_MONOTONIC_METHOD) && PSNIP_CLOCK_MONOTONIC_METHOD == PSNIP_CLOCK_METHOD_MACH_ABSOLUTE_TIME
652
- static mach_timebase_info_data_t tbi = { 0, };
653
- if (tbi.denom == 0)
654
- mach_timebase_info(&tbi);
655
- return (psnip_uint32_t) (tbi.numer / tbi.denom);
656
- #elif defined(PSNIP_CLOCK_MONOTONIC_METHOD) && PSNIP_CLOCK_MONOTONIC_METHOD == PSNIP_CLOCK_METHOD_GETTICKCOUNT64
657
- return 1000;
658
- #elif defined(PSNIP_CLOCK_MONOTONIC_METHOD) && PSNIP_CLOCK_MONOTONIC_METHOD == PSNIP_CLOCK_METHOD_QUERYPERFORMANCECOUNTER
659
- LARGE_INTEGER Frequency;
660
- QueryPerformanceFrequency(&Frequency);
661
- return (psnip_uint32_t) ((Frequency.QuadPart > PSNIP_CLOCK_NSEC_PER_SEC) ? PSNIP_CLOCK_NSEC_PER_SEC : Frequency.QuadPart);
662
- #else
663
- return 0;
664
- #endif
665
- }
666
-
667
- PSNIP_CLOCK__FUNCTION int
668
- psnip_clock_monotonic_get_time (struct PsnipClockTimespec* res) {
669
- #if !defined(PSNIP_CLOCK_MONOTONIC_METHOD)
670
- (void) res;
671
- return -2;
672
- #elif defined(PSNIP_CLOCK_MONOTONIC_METHOD) && PSNIP_CLOCK_MONOTONIC_METHOD == PSNIP_CLOCK_METHOD_CLOCK_GETTIME
673
- return psnip_clock__clock_gettime(PSNIP_CLOCK_CLOCK_GETTIME_MONOTONIC, res);
674
- #elif defined(PSNIP_CLOCK_MONOTONIC_METHOD) && PSNIP_CLOCK_MONOTONIC_METHOD == PSNIP_CLOCK_METHOD_MACH_ABSOLUTE_TIME
675
- psnip_uint64_t nsec = mach_absolute_time();
676
- static mach_timebase_info_data_t tbi = { 0, };
677
- if (tbi.denom == 0)
678
- mach_timebase_info(&tbi);
679
- nsec *= ((psnip_uint64_t) tbi.numer) / ((psnip_uint64_t) tbi.denom);
680
- res->seconds = nsec / PSNIP_CLOCK_NSEC_PER_SEC;
681
- res->nanoseconds = nsec % PSNIP_CLOCK_NSEC_PER_SEC;
682
- #elif defined(PSNIP_CLOCK_MONOTONIC_METHOD) && PSNIP_CLOCK_MONOTONIC_METHOD == PSNIP_CLOCK_METHOD_QUERYPERFORMANCECOUNTER
683
- LARGE_INTEGER t, f;
684
- if (QueryPerformanceCounter(&t) == 0)
685
- return -12;
686
-
687
- QueryPerformanceFrequency(&f);
688
- res->seconds = t.QuadPart / f.QuadPart;
689
- res->nanoseconds = t.QuadPart % f.QuadPart;
690
- if (f.QuadPart > PSNIP_CLOCK_NSEC_PER_SEC)
691
- res->nanoseconds /= f.QuadPart / PSNIP_CLOCK_NSEC_PER_SEC;
692
- else
693
- res->nanoseconds *= PSNIP_CLOCK_NSEC_PER_SEC / f.QuadPart;
694
- #elif defined(PSNIP_CLOCK_MONOTONIC_METHOD) && PSNIP_CLOCK_MONOTONIC_METHOD == PSNIP_CLOCK_METHOD_GETTICKCOUNT64
695
- const ULONGLONG msec = GetTickCount64();
696
- res->seconds = msec / 1000;
697
- res->nanoseconds = sec % 1000;
698
- #else
699
- return -2;
700
- #endif
701
-
702
- return 0;
703
- }
704
-
705
- /* Returns the number of ticks per second for the specified clock.
706
- * For example, a clock with millisecond precision would return 1000,
707
- * and a clock with 1 second (such as the time() function) would
708
- * return 1.
709
- *
710
- * If the requested clock isn't available, it will return 0.
711
- * Hopefully this will be rare, but if it happens to you please let us
712
- * know so we can work on finding a way to support your system.
713
- *
714
- * Note that different clocks on the same system often have a
715
- * different precisions.
716
- */
717
- PSNIP_CLOCK__FUNCTION psnip_uint32_t
718
- psnip_clock_get_precision (enum PsnipClockType clock_type) {
719
- switch (clock_type) {
720
- case PSNIP_CLOCK_TYPE_MONOTONIC:
721
- return psnip_clock_monotonic_get_precision ();
722
- case PSNIP_CLOCK_TYPE_CPU:
723
- return psnip_clock_cpu_get_precision ();
724
- case PSNIP_CLOCK_TYPE_WALL:
725
- return psnip_clock_wall_get_precision ();
726
- }
727
-
728
- PSNIP_CLOCK_UNREACHABLE();
729
- return 0;
730
- }
731
-
732
- /* Set the provided timespec to the requested time. Returns 0 on
733
- * success, or a negative value on failure. */
734
- PSNIP_CLOCK__FUNCTION int
735
- psnip_clock_get_time (enum PsnipClockType clock_type, struct PsnipClockTimespec* res) {
736
- assert(res != NULL);
737
-
738
- switch (clock_type) {
739
- case PSNIP_CLOCK_TYPE_MONOTONIC:
740
- return psnip_clock_monotonic_get_time (res);
741
- case PSNIP_CLOCK_TYPE_CPU:
742
- return psnip_clock_cpu_get_time (res);
743
- case PSNIP_CLOCK_TYPE_WALL:
744
- return psnip_clock_wall_get_time (res);
745
- }
746
-
747
- return -1;
748
- }
749
-
750
- #endif /* !defined(PSNIP_CLOCK_H) */
751
-
752
- static psnip_uint64_t
753
- munit_clock_get_elapsed(struct PsnipClockTimespec* start, struct PsnipClockTimespec* end) {
754
- psnip_uint64_t r = (end->seconds - start->seconds) * PSNIP_CLOCK_NSEC_PER_SEC;
755
- if (end->nanoseconds < start->nanoseconds) {
756
- r -= (start->nanoseconds - end->nanoseconds);
757
- } else {
758
- r += (end->nanoseconds - start->nanoseconds);
759
- }
760
- return r;
761
- }
762
-
763
- #else
764
- # include <time.h>
765
- #endif /* defined(MUNIT_ENABLE_TIMING) */
766
-
767
- /*** PRNG stuff ***/
768
-
769
- /* This is (unless I screwed up, which is entirely possible) the
770
- * version of PCG with 32-bit state. It was chosen because it has a
771
- * small enough state that we should reliably be able to use CAS
772
- * instead of requiring a lock for thread-safety.
773
- *
774
- * If I did screw up, I probably will not bother changing it unless
775
- * there is a significant bias. It's really not important this be
776
- * particularly strong, as long as it is fairly random it's much more
777
- * important that it be reproducible, so bug reports have a better
778
- * chance of being reproducible. */
779
-
780
- #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) && !defined(__STDC_NO_ATOMICS__) && !defined(__EMSCRIPTEN__) && (!defined(__GNUC_MINOR__) || (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ > 8))
781
- # define HAVE_STDATOMIC
782
- #elif defined(__clang__)
783
- # if __has_extension(c_atomic)
784
- # define HAVE_CLANG_ATOMICS
785
- # endif
786
- #endif
787
-
788
- /* Workaround for http://llvm.org/bugs/show_bug.cgi?id=26911 */
789
- #if defined(__clang__) && defined(_WIN32)
790
- # undef HAVE_STDATOMIC
791
- # if defined(__c2__)
792
- # undef HAVE_CLANG_ATOMICS
793
- # endif
794
- #endif
795
-
796
- #if defined(_OPENMP)
797
- # define ATOMIC_UINT32_T uint32_t
798
- # define ATOMIC_UINT32_INIT(x) (x)
799
- #elif defined(HAVE_STDATOMIC)
800
- # include <stdatomic.h>
801
- # define ATOMIC_UINT32_T _Atomic uint32_t
802
- # define ATOMIC_UINT32_INIT(x) ATOMIC_VAR_INIT(x)
803
- #elif defined(HAVE_CLANG_ATOMICS)
804
- # define ATOMIC_UINT32_T _Atomic uint32_t
805
- # define ATOMIC_UINT32_INIT(x) (x)
806
- #elif defined(_WIN32)
807
- # define ATOMIC_UINT32_T volatile LONG
808
- # define ATOMIC_UINT32_INIT(x) (x)
809
- #else
810
- # define ATOMIC_UINT32_T volatile uint32_t
811
- # define ATOMIC_UINT32_INIT(x) (x)
812
- #endif
813
-
814
- static ATOMIC_UINT32_T munit_rand_state = ATOMIC_UINT32_INIT(42);
815
-
816
- #if defined(_OPENMP)
817
- static inline void
818
- munit_atomic_store(ATOMIC_UINT32_T* dest, ATOMIC_UINT32_T value) {
819
- #pragma omp critical (munit_atomics)
820
- *dest = value;
821
- }
822
-
823
- static inline uint32_t
824
- munit_atomic_load(ATOMIC_UINT32_T* src) {
825
- int ret;
826
- #pragma omp critical (munit_atomics)
827
- ret = *src;
828
- return ret;
829
- }
830
-
831
- static inline uint32_t
832
- munit_atomic_cas(ATOMIC_UINT32_T* dest, ATOMIC_UINT32_T* expected, ATOMIC_UINT32_T desired) {
833
- munit_bool ret;
834
-
835
- #pragma omp critical (munit_atomics)
836
- {
837
- if (*dest == *expected) {
838
- *dest = desired;
839
- ret = 1;
840
- } else {
841
- ret = 0;
842
- }
843
- }
844
-
845
- return ret;
846
- }
847
- #elif defined(HAVE_STDATOMIC)
848
- # define munit_atomic_store(dest, value) atomic_store(dest, value)
849
- # define munit_atomic_load(src) atomic_load(src)
850
- # define munit_atomic_cas(dest, expected, value) atomic_compare_exchange_weak(dest, expected, value)
851
- #elif defined(HAVE_CLANG_ATOMICS)
852
- # define munit_atomic_store(dest, value) __c11_atomic_store(dest, value, __ATOMIC_SEQ_CST)
853
- # define munit_atomic_load(src) __c11_atomic_load(src, __ATOMIC_SEQ_CST)
854
- # define munit_atomic_cas(dest, expected, value) __c11_atomic_compare_exchange_weak(dest, expected, value, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)
855
- #elif defined(__GNUC__) && (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)
856
- # define munit_atomic_store(dest, value) __atomic_store_n(dest, value, __ATOMIC_SEQ_CST)
857
- # define munit_atomic_load(src) __atomic_load_n(src, __ATOMIC_SEQ_CST)
858
- # define munit_atomic_cas(dest, expected, value) __atomic_compare_exchange_n(dest, expected, value, 1, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)
859
- #elif defined(__GNUC__) && (__GNUC__ >= 4)
860
- # define munit_atomic_store(dest,value) do { *(dest) = (value); } while (0)
861
- # define munit_atomic_load(src) (*(src))
862
- # define munit_atomic_cas(dest, expected, value) __sync_bool_compare_and_swap(dest, *expected, value)
863
- #elif defined(_WIN32) /* Untested */
864
- # define munit_atomic_store(dest,value) do { *(dest) = (value); } while (0)
865
- # define munit_atomic_load(src) (*(src))
866
- # define munit_atomic_cas(dest, expected, value) InterlockedCompareExchange((dest), (value), *(expected))
867
- #else
868
- # warning No atomic implementation, PRNG will not be thread-safe
869
- # define munit_atomic_store(dest, value) do { *(dest) = (value); } while (0)
870
- # define munit_atomic_load(src) (*(src))
871
- static inline munit_bool
872
- munit_atomic_cas(ATOMIC_UINT32_T* dest, ATOMIC_UINT32_T* expected, ATOMIC_UINT32_T desired) {
873
- if (*dest == *expected) {
874
- *dest = desired;
875
- return 1;
876
- } else {
877
- return 0;
878
- }
879
- }
880
- #endif
881
-
882
- #define MUNIT_PRNG_MULTIPLIER (747796405U)
883
- #define MUNIT_PRNG_INCREMENT (1729U)
884
-
885
- static munit_uint32_t
886
- munit_rand_next_state(munit_uint32_t state) {
887
- return state * MUNIT_PRNG_MULTIPLIER + MUNIT_PRNG_INCREMENT;
888
- }
889
-
890
- static munit_uint32_t
891
- munit_rand_from_state(munit_uint32_t state) {
892
- munit_uint32_t res = ((state >> ((state >> 28) + 4)) ^ state) * (277803737U);
893
- res ^= res >> 22;
894
- return res;
895
- }
896
-
897
- void
898
- munit_rand_seed(munit_uint32_t seed) {
899
- munit_uint32_t state = munit_rand_next_state(seed + MUNIT_PRNG_INCREMENT);
900
- munit_atomic_store(&munit_rand_state, state);
901
- }
902
-
903
- static munit_uint32_t
904
- munit_rand_generate_seed(void) {
905
- munit_uint32_t seed, state;
906
- #if defined(MUNIT_ENABLE_TIMING)
907
- struct PsnipClockTimespec wc = { 0, };
908
-
909
- psnip_clock_get_time(PSNIP_CLOCK_TYPE_WALL, &wc);
910
- seed = (munit_uint32_t) wc.nanoseconds;
911
- #else
912
- seed = (munit_uint32_t) time(NULL);
913
- #endif
914
-
915
- state = munit_rand_next_state(seed + MUNIT_PRNG_INCREMENT);
916
- return munit_rand_from_state(state);
917
- }
918
-
919
- static munit_uint32_t
920
- munit_rand_state_uint32(munit_uint32_t* state) {
921
- const munit_uint32_t old = *state;
922
- *state = munit_rand_next_state(old);
923
- return munit_rand_from_state(old);
924
- }
925
-
926
- munit_uint32_t
927
- munit_rand_uint32(void) {
928
- munit_uint32_t old, state;
929
-
930
- do {
931
- old = munit_atomic_load(&munit_rand_state);
932
- state = munit_rand_next_state(old);
933
- } while (!munit_atomic_cas(&munit_rand_state, &old, state));
934
-
935
- return munit_rand_from_state(old);
936
- }
937
-
938
- static void
939
- munit_rand_state_memory(munit_uint32_t* state, size_t size, munit_uint8_t data[MUNIT_ARRAY_PARAM(size)]) {
940
- size_t members_remaining = size / sizeof(munit_uint32_t);
941
- size_t bytes_remaining = size % sizeof(munit_uint32_t);
942
- munit_uint8_t* b = data;
943
- munit_uint32_t rv;
944
- while (members_remaining-- > 0) {
945
- rv = munit_rand_state_uint32(state);
946
- memcpy(b, &rv, sizeof(munit_uint32_t));
947
- b += sizeof(munit_uint32_t);
948
- }
949
- if (bytes_remaining != 0) {
950
- rv = munit_rand_state_uint32(state);
951
- memcpy(b, &rv, bytes_remaining);
952
- }
953
- }
954
-
955
- void
956
- munit_rand_memory(size_t size, munit_uint8_t data[MUNIT_ARRAY_PARAM(size)]) {
957
- munit_uint32_t old, state;
958
-
959
- do {
960
- state = old = munit_atomic_load(&munit_rand_state);
961
- munit_rand_state_memory(&state, size, data);
962
- } while (!munit_atomic_cas(&munit_rand_state, &old, state));
963
- }
964
-
965
- static munit_uint32_t
966
- munit_rand_state_at_most(munit_uint32_t* state, munit_uint32_t salt, munit_uint32_t max) {
967
- /* We want (UINT32_MAX + 1) % max, which in unsigned arithmetic is the same
968
- * as (UINT32_MAX + 1 - max) % max = -max % max. We compute -max using not
969
- * to avoid compiler warnings.
970
- */
971
- const munit_uint32_t min = (~max + 1U) % max;
972
- munit_uint32_t x;
973
-
974
- if (max == (~((munit_uint32_t) 0U)))
975
- return munit_rand_state_uint32(state) ^ salt;
976
-
977
- max++;
978
-
979
- do {
980
- x = munit_rand_state_uint32(state) ^ salt;
981
- } while (x < min);
982
-
983
- return x % max;
984
- }
985
-
986
- static munit_uint32_t
987
- munit_rand_at_most(munit_uint32_t salt, munit_uint32_t max) {
988
- munit_uint32_t old, state;
989
- munit_uint32_t retval;
990
-
991
- do {
992
- state = old = munit_atomic_load(&munit_rand_state);
993
- retval = munit_rand_state_at_most(&state, salt, max);
994
- } while (!munit_atomic_cas(&munit_rand_state, &old, state));
995
-
996
- return retval;
997
- }
998
-
999
- int
1000
- munit_rand_int_range(int min, int max) {
1001
- munit_uint64_t range = (munit_uint64_t) max - (munit_uint64_t) min;
1002
-
1003
- if (min > max)
1004
- return munit_rand_int_range(max, min);
1005
-
1006
- if (range > (~((munit_uint32_t) 0U)))
1007
- range = (~((munit_uint32_t) 0U));
1008
-
1009
- return min + munit_rand_at_most(0, (munit_uint32_t) range);
1010
- }
1011
-
1012
- double
1013
- munit_rand_double(void) {
1014
- munit_uint32_t old, state;
1015
- double retval = 0.0;
1016
-
1017
- do {
1018
- state = old = munit_atomic_load(&munit_rand_state);
1019
-
1020
- /* See http://mumble.net/~campbell/tmp/random_real.c for how to do
1021
- * this right. Patches welcome if you feel that this is too
1022
- * biased. */
1023
- retval = munit_rand_state_uint32(&state) / ((~((munit_uint32_t) 0U)) + 1.0);
1024
- } while (!munit_atomic_cas(&munit_rand_state, &old, state));
1025
-
1026
- return retval;
1027
- }
1028
-
1029
- /*** Test suite handling ***/
1030
-
1031
- typedef struct {
1032
- unsigned int successful;
1033
- unsigned int skipped;
1034
- unsigned int failed;
1035
- unsigned int errored;
1036
- #if defined(MUNIT_ENABLE_TIMING)
1037
- munit_uint64_t cpu_clock;
1038
- munit_uint64_t wall_clock;
1039
- #endif
1040
- } MunitReport;
1041
-
1042
- typedef struct {
1043
- const char* prefix;
1044
- const MunitSuite* suite;
1045
- const char** tests;
1046
- munit_uint32_t seed;
1047
- unsigned int iterations;
1048
- MunitParameter* parameters;
1049
- munit_bool single_parameter_mode;
1050
- void* user_data;
1051
- MunitReport report;
1052
- munit_bool colorize;
1053
- munit_bool fork;
1054
- munit_bool show_stderr;
1055
- munit_bool fatal_failures;
1056
- } MunitTestRunner;
1057
-
1058
- const char*
1059
- munit_parameters_get(const MunitParameter params[], const char* key) {
1060
- const MunitParameter* param;
1061
-
1062
- for (param = params ; param != NULL && param->name != NULL ; param++)
1063
- if (strcmp(param->name, key) == 0)
1064
- return param->value;
1065
- return NULL;
1066
- }
1067
-
1068
- #if defined(MUNIT_ENABLE_TIMING)
1069
- static void
1070
- munit_print_time(FILE* fp, munit_uint64_t nanoseconds) {
1071
- fprintf(fp, "%" MUNIT_TEST_TIME_FORMAT, ((double) nanoseconds) / ((double) PSNIP_CLOCK_NSEC_PER_SEC));
1072
- }
1073
- #endif
1074
-
1075
- /* Add a paramter to an array of parameters. */
1076
- static MunitResult
1077
- munit_parameters_add(size_t* params_size, MunitParameter* params[MUNIT_ARRAY_PARAM(*params_size)], char* name, char* value) {
1078
- *params = realloc(*params, sizeof(MunitParameter) * (*params_size + 2));
1079
- if (*params == NULL)
1080
- return MUNIT_ERROR;
1081
-
1082
- (*params)[*params_size].name = name;
1083
- (*params)[*params_size].value = value;
1084
- (*params_size)++;
1085
- (*params)[*params_size].name = NULL;
1086
- (*params)[*params_size].value = NULL;
1087
-
1088
- return MUNIT_OK;
1089
- }
1090
-
1091
- /* Concatenate two strings, but just return one of the components
1092
- * unaltered if the other is NULL or "". */
1093
- static char*
1094
- munit_maybe_concat(size_t* len, char* prefix, char* suffix) {
1095
- char* res;
1096
- size_t res_l;
1097
- const size_t prefix_l = prefix != NULL ? strlen(prefix) : 0;
1098
- const size_t suffix_l = suffix != NULL ? strlen(suffix) : 0;
1099
- if (prefix_l == 0 && suffix_l == 0) {
1100
- res = NULL;
1101
- res_l = 0;
1102
- } else if (prefix_l == 0 && suffix_l != 0) {
1103
- res = suffix;
1104
- res_l = suffix_l;
1105
- } else if (prefix_l != 0 && suffix_l == 0) {
1106
- res = prefix;
1107
- res_l = prefix_l;
1108
- } else {
1109
- res_l = prefix_l + suffix_l;
1110
- res = malloc(res_l + 1);
1111
- memcpy(res, prefix, prefix_l);
1112
- memcpy(res + prefix_l, suffix, suffix_l);
1113
- res[res_l] = 0;
1114
- }
1115
-
1116
- if (len != NULL)
1117
- *len = res_l;
1118
-
1119
- return res;
1120
- }
1121
-
1122
- /* Possbily free a string returned by munit_maybe_concat. */
1123
- static void
1124
- munit_maybe_free_concat(char* s, const char* prefix, const char* suffix) {
1125
- if (prefix != s && suffix != s)
1126
- free(s);
1127
- }
1128
-
1129
- /* Cheap string hash function, just used to salt the PRNG. */
1130
- static munit_uint32_t
1131
- munit_str_hash(const char* name) {
1132
- const char *p;
1133
- munit_uint32_t h = 5381U;
1134
-
1135
- for (p = name; *p != '\0'; p++)
1136
- h = (h << 5) + h + *p;
1137
-
1138
- return h;
1139
- }
1140
-
1141
- static void
1142
- munit_splice(int from, int to) {
1143
- munit_uint8_t buf[1024];
1144
- #if !defined(_WIN32)
1145
- ssize_t len;
1146
- ssize_t bytes_written;
1147
- ssize_t write_res;
1148
- #else
1149
- int len;
1150
- int bytes_written;
1151
- int write_res;
1152
- #endif
1153
- do {
1154
- len = read(from, buf, sizeof(buf));
1155
- if (len > 0) {
1156
- bytes_written = 0;
1157
- do {
1158
- write_res = write(to, buf + bytes_written, len - bytes_written);
1159
- if (write_res < 0)
1160
- break;
1161
- bytes_written += write_res;
1162
- } while (bytes_written < len);
1163
- }
1164
- else
1165
- break;
1166
- } while (1);
1167
- }
1168
-
1169
- /* This is the part that should be handled in the child process */
1170
- static MunitResult
1171
- munit_test_runner_exec(MunitTestRunner* runner, const MunitTest* test, const MunitParameter params[], MunitReport* report) {
1172
- unsigned int iterations = runner->iterations;
1173
- MunitResult result = MUNIT_FAIL;
1174
- #if defined(MUNIT_ENABLE_TIMING)
1175
- struct PsnipClockTimespec wall_clock_begin = { 0, }, wall_clock_end = { 0, };
1176
- struct PsnipClockTimespec cpu_clock_begin = { 0, }, cpu_clock_end = { 0, };
1177
- #endif
1178
- unsigned int i = 0;
1179
-
1180
- if ((test->options & MUNIT_TEST_OPTION_SINGLE_ITERATION) == MUNIT_TEST_OPTION_SINGLE_ITERATION)
1181
- iterations = 1;
1182
- else if (iterations == 0)
1183
- iterations = runner->suite->iterations;
1184
-
1185
- munit_rand_seed(runner->seed);
1186
-
1187
- do {
1188
- void* data = (test->setup == NULL) ? runner->user_data : test->setup(params, runner->user_data);
1189
-
1190
- #if defined(MUNIT_ENABLE_TIMING)
1191
- psnip_clock_get_time(PSNIP_CLOCK_TYPE_WALL, &wall_clock_begin);
1192
- psnip_clock_get_time(PSNIP_CLOCK_TYPE_CPU, &cpu_clock_begin);
1193
- #endif
1194
-
1195
- result = test->test(params, data);
1196
-
1197
- #if defined(MUNIT_ENABLE_TIMING)
1198
- psnip_clock_get_time(PSNIP_CLOCK_TYPE_WALL, &wall_clock_end);
1199
- psnip_clock_get_time(PSNIP_CLOCK_TYPE_CPU, &cpu_clock_end);
1200
- #endif
1201
-
1202
- if (test->tear_down != NULL)
1203
- test->tear_down(data);
1204
-
1205
- if (MUNIT_LIKELY(result == MUNIT_OK)) {
1206
- report->successful++;
1207
- #if defined(MUNIT_ENABLE_TIMING)
1208
- report->wall_clock += munit_clock_get_elapsed(&wall_clock_begin, &wall_clock_end);
1209
- report->cpu_clock += munit_clock_get_elapsed(&cpu_clock_begin, &cpu_clock_end);
1210
- #endif
1211
- } else {
1212
- switch ((int) result) {
1213
- case MUNIT_SKIP:
1214
- report->skipped++;
1215
- break;
1216
- case MUNIT_FAIL:
1217
- report->failed++;
1218
- break;
1219
- case MUNIT_ERROR:
1220
- report->errored++;
1221
- break;
1222
- default:
1223
- break;
1224
- }
1225
- break;
1226
- }
1227
- } while (++i < iterations);
1228
-
1229
- return result;
1230
- }
1231
-
1232
- #if defined(MUNIT_EMOTICON)
1233
- # define MUNIT_RESULT_STRING_OK ":)"
1234
- # define MUNIT_RESULT_STRING_SKIP ":|"
1235
- # define MUNIT_RESULT_STRING_FAIL ":("
1236
- # define MUNIT_RESULT_STRING_ERROR ":o"
1237
- # define MUNIT_RESULT_STRING_TODO ":/"
1238
- #else
1239
- # define MUNIT_RESULT_STRING_OK "OK "
1240
- # define MUNIT_RESULT_STRING_SKIP "SKIP "
1241
- # define MUNIT_RESULT_STRING_FAIL "FAIL "
1242
- # define MUNIT_RESULT_STRING_ERROR "ERROR"
1243
- # define MUNIT_RESULT_STRING_TODO "TODO "
1244
- #endif
1245
-
1246
- static void
1247
- munit_test_runner_print_color(const MunitTestRunner* runner, const char* string, char color) {
1248
- if (runner->colorize)
1249
- fprintf(MUNIT_OUTPUT_FILE, "\x1b[3%cm%s\x1b[39m", color, string);
1250
- else
1251
- fputs(string, MUNIT_OUTPUT_FILE);
1252
- }
1253
-
1254
- #if !defined(MUNIT_NO_BUFFER)
1255
- static int
1256
- munit_replace_stderr(FILE* stderr_buf) {
1257
- if (stderr_buf != NULL) {
1258
- const int orig_stderr = dup(STDERR_FILENO);
1259
-
1260
- int errfd = fileno(stderr_buf);
1261
- if (MUNIT_UNLIKELY(errfd == -1)) {
1262
- exit(EXIT_FAILURE);
1263
- }
1264
-
1265
- dup2(errfd, STDERR_FILENO);
1266
-
1267
- return orig_stderr;
1268
- }
1269
-
1270
- return -1;
1271
- }
1272
-
1273
- static void
1274
- munit_restore_stderr(int orig_stderr) {
1275
- if (orig_stderr != -1) {
1276
- dup2(orig_stderr, STDERR_FILENO);
1277
- close(orig_stderr);
1278
- }
1279
- }
1280
- #endif /* !defined(MUNIT_NO_BUFFER) */
1281
-
1282
- /* Run a test with the specified parameters. */
1283
- static void
1284
- munit_test_runner_run_test_with_params(MunitTestRunner* runner, const MunitTest* test, const MunitParameter params[]) {
1285
- MunitResult result = MUNIT_OK;
1286
- MunitReport report = {
1287
- 0, 0, 0, 0,
1288
- #if defined(MUNIT_ENABLE_TIMING)
1289
- 0, 0
1290
- #endif
1291
- };
1292
- unsigned int output_l;
1293
- munit_bool first;
1294
- const MunitParameter* param;
1295
- FILE* stderr_buf;
1296
- #if !defined(MUNIT_NO_FORK)
1297
- int pipefd[2];
1298
- pid_t fork_pid;
1299
- int orig_stderr;
1300
- ssize_t bytes_written = 0;
1301
- ssize_t write_res;
1302
- ssize_t bytes_read = 0;
1303
- ssize_t read_res;
1304
- int status = 0;
1305
- pid_t changed_pid;
1306
- #endif
1307
-
1308
- if (params != NULL) {
1309
- output_l = 2;
1310
- fputs(" ", MUNIT_OUTPUT_FILE);
1311
- first = 1;
1312
- for (param = params ; param != NULL && param->name != NULL ; param++) {
1313
- if (!first) {
1314
- fputs(", ", MUNIT_OUTPUT_FILE);
1315
- output_l += 2;
1316
- } else {
1317
- first = 0;
1318
- }
1319
-
1320
- output_l += fprintf(MUNIT_OUTPUT_FILE, "%s=%s", param->name, param->value);
1321
- }
1322
- while (output_l++ < MUNIT_TEST_NAME_LEN) {
1323
- fputc(' ', MUNIT_OUTPUT_FILE);
1324
- }
1325
- }
1326
-
1327
- fflush(MUNIT_OUTPUT_FILE);
1328
-
1329
- stderr_buf = NULL;
1330
- #if !defined(_WIN32) || defined(__MINGW32__)
1331
- stderr_buf = tmpfile();
1332
- #else
1333
- tmpfile_s(&stderr_buf);
1334
- #endif
1335
- if (stderr_buf == NULL) {
1336
- munit_log_errno(MUNIT_LOG_ERROR, stderr, "unable to create buffer for stderr");
1337
- result = MUNIT_ERROR;
1338
- goto print_result;
1339
- }
1340
-
1341
- #if !defined(MUNIT_NO_FORK)
1342
- if (runner->fork) {
1343
- pipefd[0] = -1;
1344
- pipefd[1] = -1;
1345
- if (pipe(pipefd) != 0) {
1346
- munit_log_errno(MUNIT_LOG_ERROR, stderr, "unable to create pipe");
1347
- result = MUNIT_ERROR;
1348
- goto print_result;
1349
- }
1350
-
1351
- fork_pid = fork();
1352
- if (fork_pid == 0) {
1353
- close(pipefd[0]);
1354
-
1355
- orig_stderr = munit_replace_stderr(stderr_buf);
1356
- munit_test_runner_exec(runner, test, params, &report);
1357
-
1358
- /* Note that we don't restore stderr. This is so we can buffer
1359
- * things written to stderr later on (such as by
1360
- * asan/tsan/ubsan, valgrind, etc.) */
1361
- close(orig_stderr);
1362
-
1363
- do {
1364
- write_res = write(pipefd[1], ((munit_uint8_t*) (&report)) + bytes_written, sizeof(report) - bytes_written);
1365
- if (write_res < 0) {
1366
- if (stderr_buf != NULL) {
1367
- munit_log_errno(MUNIT_LOG_ERROR, stderr, "unable to write to pipe");
1368
- }
1369
- exit(EXIT_FAILURE);
1370
- }
1371
- bytes_written += write_res;
1372
- } while ((size_t) bytes_written < sizeof(report));
1373
-
1374
- if (stderr_buf != NULL)
1375
- fclose(stderr_buf);
1376
- close(pipefd[1]);
1377
-
1378
- exit(EXIT_SUCCESS);
1379
- } else if (fork_pid == -1) {
1380
- close(pipefd[0]);
1381
- close(pipefd[1]);
1382
- if (stderr_buf != NULL) {
1383
- munit_log_errno(MUNIT_LOG_ERROR, stderr, "unable to fork");
1384
- }
1385
- report.errored++;
1386
- result = MUNIT_ERROR;
1387
- } else {
1388
- close(pipefd[1]);
1389
- do {
1390
- read_res = read(pipefd[0], ((munit_uint8_t*) (&report)) + bytes_read, sizeof(report) - bytes_read);
1391
- if (read_res < 1)
1392
- break;
1393
- bytes_read += read_res;
1394
- } while (bytes_read < (ssize_t) sizeof(report));
1395
-
1396
- changed_pid = waitpid(fork_pid, &status, 0);
1397
-
1398
- if (MUNIT_LIKELY(changed_pid == fork_pid) && MUNIT_LIKELY(WIFEXITED(status))) {
1399
- if (bytes_read != sizeof(report)) {
1400
- munit_logf_internal(MUNIT_LOG_ERROR, stderr_buf, "child exited unexpectedly with status %d", WEXITSTATUS(status));
1401
- report.errored++;
1402
- } else if (WEXITSTATUS(status) != EXIT_SUCCESS) {
1403
- munit_logf_internal(MUNIT_LOG_ERROR, stderr_buf, "child exited with status %d", WEXITSTATUS(status));
1404
- report.errored++;
1405
- }
1406
- } else {
1407
- if (WIFSIGNALED(status)) {
1408
- #if defined(_XOPEN_VERSION) && (_XOPEN_VERSION >= 700)
1409
- munit_logf_internal(MUNIT_LOG_ERROR, stderr_buf, "child killed by signal %d (%s)", WTERMSIG(status), strsignal(WTERMSIG(status)));
1410
- #else
1411
- munit_logf_internal(MUNIT_LOG_ERROR, stderr_buf, "child killed by signal %d", WTERMSIG(status));
1412
- #endif
1413
- } else if (WIFSTOPPED(status)) {
1414
- munit_logf_internal(MUNIT_LOG_ERROR, stderr_buf, "child stopped by signal %d", WSTOPSIG(status));
1415
- }
1416
- report.errored++;
1417
- }
1418
-
1419
- close(pipefd[0]);
1420
- waitpid(fork_pid, NULL, 0);
1421
- }
1422
- } else
1423
- #endif
1424
- {
1425
- #if !defined(MUNIT_NO_BUFFER)
1426
- const volatile int orig_stderr = munit_replace_stderr(stderr_buf);
1427
- #endif
1428
-
1429
- #if defined(MUNIT_THREAD_LOCAL)
1430
- if (MUNIT_UNLIKELY(setjmp(munit_error_jmp_buf) != 0)) {
1431
- result = MUNIT_FAIL;
1432
- report.failed++;
1433
- } else {
1434
- munit_error_jmp_buf_valid = 1;
1435
- result = munit_test_runner_exec(runner, test, params, &report);
1436
- }
1437
- #else
1438
- result = munit_test_runner_exec(runner, test, params, &report);
1439
- #endif
1440
-
1441
- #if !defined(MUNIT_NO_BUFFER)
1442
- munit_restore_stderr(orig_stderr);
1443
- #endif
1444
-
1445
- /* Here just so that the label is used on Windows and we don't get
1446
- * a warning */
1447
- goto print_result;
1448
- }
1449
-
1450
- print_result:
1451
-
1452
- fputs("[ ", MUNIT_OUTPUT_FILE);
1453
- if ((test->options & MUNIT_TEST_OPTION_TODO) == MUNIT_TEST_OPTION_TODO) {
1454
- if (report.failed != 0 || report.errored != 0 || report.skipped != 0) {
1455
- munit_test_runner_print_color(runner, MUNIT_RESULT_STRING_TODO, '3');
1456
- result = MUNIT_OK;
1457
- } else {
1458
- munit_test_runner_print_color(runner, MUNIT_RESULT_STRING_ERROR, '1');
1459
- if (MUNIT_LIKELY(stderr_buf != NULL))
1460
- munit_log_internal(MUNIT_LOG_ERROR, stderr_buf, "Test marked TODO, but was successful.");
1461
- runner->report.failed++;
1462
- result = MUNIT_ERROR;
1463
- }
1464
- } else if (report.failed > 0) {
1465
- munit_test_runner_print_color(runner, MUNIT_RESULT_STRING_FAIL, '1');
1466
- runner->report.failed++;
1467
- result = MUNIT_FAIL;
1468
- } else if (report.errored > 0) {
1469
- munit_test_runner_print_color(runner, MUNIT_RESULT_STRING_ERROR, '1');
1470
- runner->report.errored++;
1471
- result = MUNIT_ERROR;
1472
- } else if (report.skipped > 0) {
1473
- munit_test_runner_print_color(runner, MUNIT_RESULT_STRING_SKIP, '3');
1474
- runner->report.skipped++;
1475
- result = MUNIT_SKIP;
1476
- } else if (report.successful > 1) {
1477
- munit_test_runner_print_color(runner, MUNIT_RESULT_STRING_OK, '2');
1478
- #if defined(MUNIT_ENABLE_TIMING)
1479
- fputs(" ] [ ", MUNIT_OUTPUT_FILE);
1480
- munit_print_time(MUNIT_OUTPUT_FILE, report.wall_clock / report.successful);
1481
- fputs(" / ", MUNIT_OUTPUT_FILE);
1482
- munit_print_time(MUNIT_OUTPUT_FILE, report.cpu_clock / report.successful);
1483
- fprintf(MUNIT_OUTPUT_FILE, " CPU ]\n %-" MUNIT_XSTRINGIFY(MUNIT_TEST_NAME_LEN) "s Total: [ ", "");
1484
- munit_print_time(MUNIT_OUTPUT_FILE, report.wall_clock);
1485
- fputs(" / ", MUNIT_OUTPUT_FILE);
1486
- munit_print_time(MUNIT_OUTPUT_FILE, report.cpu_clock);
1487
- fputs(" CPU", MUNIT_OUTPUT_FILE);
1488
- #endif
1489
- runner->report.successful++;
1490
- result = MUNIT_OK;
1491
- } else if (report.successful > 0) {
1492
- munit_test_runner_print_color(runner, MUNIT_RESULT_STRING_OK, '2');
1493
- #if defined(MUNIT_ENABLE_TIMING)
1494
- fputs(" ] [ ", MUNIT_OUTPUT_FILE);
1495
- munit_print_time(MUNIT_OUTPUT_FILE, report.wall_clock);
1496
- fputs(" / ", MUNIT_OUTPUT_FILE);
1497
- munit_print_time(MUNIT_OUTPUT_FILE, report.cpu_clock);
1498
- fputs(" CPU", MUNIT_OUTPUT_FILE);
1499
- #endif
1500
- runner->report.successful++;
1501
- result = MUNIT_OK;
1502
- }
1503
- fputs(" ]\n", MUNIT_OUTPUT_FILE);
1504
-
1505
- if (stderr_buf != NULL) {
1506
- if (result == MUNIT_FAIL || result == MUNIT_ERROR || runner->show_stderr) {
1507
- fflush(MUNIT_OUTPUT_FILE);
1508
-
1509
- rewind(stderr_buf);
1510
- munit_splice(fileno(stderr_buf), STDERR_FILENO);
1511
-
1512
- fflush(stderr);
1513
- }
1514
-
1515
- fclose(stderr_buf);
1516
- }
1517
- }
1518
-
1519
- static void
1520
- munit_test_runner_run_test_wild(MunitTestRunner* runner,
1521
- const MunitTest* test,
1522
- const char* test_name,
1523
- MunitParameter* params,
1524
- MunitParameter* p) {
1525
- const MunitParameterEnum* pe;
1526
- char** values;
1527
- MunitParameter* next;
1528
-
1529
- for (pe = test->parameters ; pe != NULL && pe->name != NULL ; pe++) {
1530
- if (p->name == pe->name)
1531
- break;
1532
- }
1533
-
1534
- if (pe == NULL)
1535
- return;
1536
-
1537
- for (values = pe->values ; *values != NULL ; values++) {
1538
- next = p + 1;
1539
- p->value = *values;
1540
- if (next->name == NULL) {
1541
- munit_test_runner_run_test_with_params(runner, test, params);
1542
- } else {
1543
- munit_test_runner_run_test_wild(runner, test, test_name, params, next);
1544
- }
1545
- if (runner->fatal_failures && (runner->report.failed != 0 || runner->report.errored != 0))
1546
- break;
1547
- }
1548
- }
1549
-
1550
- /* Run a single test, with every combination of parameters
1551
- * requested. */
1552
- static void
1553
- munit_test_runner_run_test(MunitTestRunner* runner,
1554
- const MunitTest* test,
1555
- const char* prefix) {
1556
- char* test_name = munit_maybe_concat(NULL, (char*) prefix, (char*) test->name);
1557
- /* The array of parameters to pass to
1558
- * munit_test_runner_run_test_with_params */
1559
- MunitParameter* params = NULL;
1560
- size_t params_l = 0;
1561
- /* Wildcard parameters are parameters which have possible values
1562
- * specified in the test, but no specific value was passed to the
1563
- * CLI. That means we want to run the test once for every
1564
- * possible combination of parameter values or, if --single was
1565
- * passed to the CLI, a single time with a random set of
1566
- * parameters. */
1567
- MunitParameter* wild_params = NULL;
1568
- size_t wild_params_l = 0;
1569
- const MunitParameterEnum* pe;
1570
- const MunitParameter* cli_p;
1571
- munit_bool filled;
1572
- unsigned int possible;
1573
- char** vals;
1574
- size_t first_wild;
1575
- const MunitParameter* wp;
1576
- int pidx;
1577
-
1578
- munit_rand_seed(runner->seed);
1579
-
1580
- fprintf(MUNIT_OUTPUT_FILE, "%-" MUNIT_XSTRINGIFY(MUNIT_TEST_NAME_LEN) "s", test_name);
1581
-
1582
- if (test->parameters == NULL) {
1583
- /* No parameters. Simple, nice. */
1584
- munit_test_runner_run_test_with_params(runner, test, NULL);
1585
- } else {
1586
- fputc('\n', MUNIT_OUTPUT_FILE);
1587
-
1588
- for (pe = test->parameters ; pe != NULL && pe->name != NULL ; pe++) {
1589
- /* Did we received a value for this parameter from the CLI? */
1590
- filled = 0;
1591
- for (cli_p = runner->parameters ; cli_p != NULL && cli_p->name != NULL ; cli_p++) {
1592
- if (strcmp(cli_p->name, pe->name) == 0) {
1593
- if (MUNIT_UNLIKELY(munit_parameters_add(&params_l, &params, pe->name, cli_p->value) != MUNIT_OK))
1594
- goto cleanup;
1595
- filled = 1;
1596
- break;
1597
- }
1598
- }
1599
- if (filled)
1600
- continue;
1601
-
1602
- /* Nothing from CLI, is the enum NULL/empty? We're not a
1603
- * fuzzer… */
1604
- if (pe->values == NULL || pe->values[0] == NULL)
1605
- continue;
1606
-
1607
- /* If --single was passed to the CLI, choose a value from the
1608
- * list of possibilities randomly. */
1609
- if (runner->single_parameter_mode) {
1610
- possible = 0;
1611
- for (vals = pe->values ; *vals != NULL ; vals++)
1612
- possible++;
1613
- /* We want the tests to be reproducible, even if you're only
1614
- * running a single test, but we don't want every test with
1615
- * the same number of parameters to choose the same parameter
1616
- * number, so use the test name as a primitive salt. */
1617
- pidx = munit_rand_at_most(munit_str_hash(test_name), possible - 1);
1618
- if (MUNIT_UNLIKELY(munit_parameters_add(&params_l, &params, pe->name, pe->values[pidx]) != MUNIT_OK))
1619
- goto cleanup;
1620
- } else {
1621
- /* We want to try every permutation. Put in a placeholder
1622
- * entry, we'll iterate through them later. */
1623
- if (MUNIT_UNLIKELY(munit_parameters_add(&wild_params_l, &wild_params, pe->name, NULL) != MUNIT_OK))
1624
- goto cleanup;
1625
- }
1626
- }
1627
-
1628
- if (wild_params_l != 0) {
1629
- first_wild = params_l;
1630
- for (wp = wild_params ; wp != NULL && wp->name != NULL ; wp++) {
1631
- for (pe = test->parameters ; pe != NULL && pe->name != NULL && pe->values != NULL ; pe++) {
1632
- if (strcmp(wp->name, pe->name) == 0) {
1633
- if (MUNIT_UNLIKELY(munit_parameters_add(&params_l, &params, pe->name, pe->values[0]) != MUNIT_OK))
1634
- goto cleanup;
1635
- }
1636
- }
1637
- }
1638
-
1639
- munit_test_runner_run_test_wild(runner, test, test_name, params, params + first_wild);
1640
- } else {
1641
- munit_test_runner_run_test_with_params(runner, test, params);
1642
- }
1643
-
1644
- cleanup:
1645
- free(params);
1646
- free(wild_params);
1647
- }
1648
-
1649
- munit_maybe_free_concat(test_name, prefix, test->name);
1650
- }
1651
-
1652
- /* Recurse through the suite and run all the tests. If a list of
1653
- * tests to run was provied on the command line, run only those
1654
- * tests. */
1655
- static void
1656
- munit_test_runner_run_suite(MunitTestRunner* runner,
1657
- const MunitSuite* suite,
1658
- const char* prefix) {
1659
- size_t pre_l;
1660
- char* pre = munit_maybe_concat(&pre_l, (char*) prefix, (char*) suite->prefix);
1661
- const MunitTest* test;
1662
- const char** test_name;
1663
- const MunitSuite* child_suite;
1664
-
1665
- /* Run the tests. */
1666
- for (test = suite->tests ; test != NULL && test->test != NULL ; test++) {
1667
- if (runner->tests != NULL) { /* Specific tests were requested on the CLI */
1668
- for (test_name = runner->tests ; test_name != NULL && *test_name != NULL ; test_name++) {
1669
- if ((pre_l == 0 || strncmp(pre, *test_name, pre_l) == 0) &&
1670
- strncmp(test->name, *test_name + pre_l, strlen(*test_name + pre_l)) == 0) {
1671
- munit_test_runner_run_test(runner, test, pre);
1672
- if (runner->fatal_failures && (runner->report.failed != 0 || runner->report.errored != 0))
1673
- goto cleanup;
1674
- }
1675
- }
1676
- } else { /* Run all tests */
1677
- munit_test_runner_run_test(runner, test, pre);
1678
- }
1679
- }
1680
-
1681
- if (runner->fatal_failures && (runner->report.failed != 0 || runner->report.errored != 0))
1682
- goto cleanup;
1683
-
1684
- /* Run any child suites. */
1685
- for (child_suite = suite->suites ; child_suite != NULL && child_suite->prefix != NULL ; child_suite++) {
1686
- munit_test_runner_run_suite(runner, child_suite, pre);
1687
- }
1688
-
1689
- cleanup:
1690
-
1691
- munit_maybe_free_concat(pre, prefix, suite->prefix);
1692
- }
1693
-
1694
- static void
1695
- munit_test_runner_run(MunitTestRunner* runner) {
1696
- munit_test_runner_run_suite(runner, runner->suite, NULL);
1697
- }
1698
-
1699
- static void
1700
- munit_print_help(int argc, char* const argv[MUNIT_ARRAY_PARAM(argc + 1)], void* user_data, const MunitArgument arguments[]) {
1701
- const MunitArgument* arg;
1702
- (void) argc;
1703
-
1704
- printf("USAGE: %s [OPTIONS...] [TEST...]\n\n", argv[0]);
1705
- puts(" --seed SEED\n"
1706
- " Value used to seed the PRNG. Must be a 32-bit integer in decimal\n"
1707
- " notation with no separators (commas, decimals, spaces, etc.), or\n"
1708
- " hexidecimal prefixed by \"0x\".\n"
1709
- " --iterations N\n"
1710
- " Run each test N times. 0 means the default number.\n"
1711
- " --param name value\n"
1712
- " A parameter key/value pair which will be passed to any test with\n"
1713
- " takes a parameter of that name. If not provided, the test will be\n"
1714
- " run once for each possible parameter value.\n"
1715
- " --list Write a list of all available tests.\n"
1716
- " --list-params\n"
1717
- " Write a list of all available tests and their possible parameters.\n"
1718
- " --single Run each parameterized test in a single configuration instead of\n"
1719
- " every possible combination\n"
1720
- " --log-visible debug|info|warning|error\n"
1721
- " --log-fatal debug|info|warning|error\n"
1722
- " Set the level at which messages of different severities are visible,\n"
1723
- " or cause the test to terminate.\n"
1724
- #if !defined(MUNIT_NO_FORK)
1725
- " --no-fork Do not execute tests in a child process. If this option is supplied\n"
1726
- " and a test crashes (including by failing an assertion), no further\n"
1727
- " tests will be performed.\n"
1728
- #endif
1729
- " --fatal-failures\n"
1730
- " Stop executing tests as soon as a failure is found.\n"
1731
- " --show-stderr\n"
1732
- " Show data written to stderr by the tests, even if the test succeeds.\n"
1733
- " --color auto|always|never\n"
1734
- " Colorize (or don't) the output.\n"
1735
- /* 12345678901234567890123456789012345678901234567890123456789012345678901234567890 */
1736
- " --help Print this help message and exit.\n");
1737
- #if defined(MUNIT_NL_LANGINFO)
1738
- setlocale(LC_ALL, "");
1739
- fputs((strcasecmp("UTF-8", nl_langinfo(CODESET)) == 0) ? "µnit" : "munit", stdout);
1740
- #else
1741
- puts("munit");
1742
- #endif
1743
- printf(" %d.%d.%d\n"
1744
- "Full documentation at: https://nemequ.github.io/munit/\n",
1745
- (MUNIT_CURRENT_VERSION >> 16) & 0xff,
1746
- (MUNIT_CURRENT_VERSION >> 8) & 0xff,
1747
- (MUNIT_CURRENT_VERSION >> 0) & 0xff);
1748
- for (arg = arguments ; arg != NULL && arg->name != NULL ; arg++)
1749
- arg->write_help(arg, user_data);
1750
- }
1751
-
1752
- static const MunitArgument*
1753
- munit_arguments_find(const MunitArgument arguments[], const char* name) {
1754
- const MunitArgument* arg;
1755
-
1756
- for (arg = arguments ; arg != NULL && arg->name != NULL ; arg++)
1757
- if (strcmp(arg->name, name) == 0)
1758
- return arg;
1759
-
1760
- return NULL;
1761
- }
1762
-
1763
- static void
1764
- munit_suite_list_tests(const MunitSuite* suite, munit_bool show_params, const char* prefix) {
1765
- size_t pre_l;
1766
- char* pre = munit_maybe_concat(&pre_l, (char*) prefix, (char*) suite->prefix);
1767
- const MunitTest* test;
1768
- const MunitParameterEnum* params;
1769
- munit_bool first;
1770
- char** val;
1771
- const MunitSuite* child_suite;
1772
-
1773
- for (test = suite->tests ;
1774
- test != NULL && test->name != NULL ;
1775
- test++) {
1776
- if (pre != NULL)
1777
- fputs(pre, stdout);
1778
- puts(test->name);
1779
-
1780
- if (show_params) {
1781
- for (params = test->parameters ;
1782
- params != NULL && params->name != NULL ;
1783
- params++) {
1784
- fprintf(stdout, " - %s: ", params->name);
1785
- if (params->values == NULL) {
1786
- puts("Any");
1787
- } else {
1788
- first = 1;
1789
- for (val = params->values ;
1790
- *val != NULL ;
1791
- val++ ) {
1792
- if(!first) {
1793
- fputs(", ", stdout);
1794
- } else {
1795
- first = 0;
1796
- }
1797
- fputs(*val, stdout);
1798
- }
1799
- putc('\n', stdout);
1800
- }
1801
- }
1802
- }
1803
- }
1804
-
1805
- for (child_suite = suite->suites ; child_suite != NULL && child_suite->prefix != NULL ; child_suite++) {
1806
- munit_suite_list_tests(child_suite, show_params, pre);
1807
- }
1808
-
1809
- munit_maybe_free_concat(pre, prefix, suite->prefix);
1810
- }
1811
-
1812
- static munit_bool
1813
- munit_stream_supports_ansi(FILE *stream) {
1814
- #if !defined(_WIN32)
1815
- return isatty(fileno(stream));
1816
- #else
1817
-
1818
- #if !defined(__MINGW32__)
1819
- size_t ansicon_size = 0;
1820
- #endif
1821
-
1822
- if (isatty(fileno(stream))) {
1823
- #if !defined(__MINGW32__)
1824
- getenv_s(&ansicon_size, NULL, 0, "ANSICON");
1825
- return ansicon_size != 0;
1826
- #else
1827
- return getenv("ANSICON") != NULL;
1828
- #endif
1829
- }
1830
- return 0;
1831
- #endif
1832
- }
1833
-
1834
- int
1835
- munit_suite_main_custom(const MunitSuite* suite, void* user_data,
1836
- int argc, char* const argv[MUNIT_ARRAY_PARAM(argc + 1)],
1837
- const MunitArgument arguments[]) {
1838
- int result = EXIT_FAILURE;
1839
- MunitTestRunner runner;
1840
- size_t parameters_size = 0;
1841
- size_t tests_size = 0;
1842
- int arg;
1843
-
1844
- char* envptr;
1845
- unsigned long ts;
1846
- char* endptr;
1847
- unsigned long long iterations;
1848
- MunitLogLevel level;
1849
- const MunitArgument* argument;
1850
- const char** runner_tests;
1851
- unsigned int tests_run;
1852
- unsigned int tests_total;
1853
-
1854
- runner.prefix = NULL;
1855
- runner.suite = NULL;
1856
- runner.tests = NULL;
1857
- runner.seed = 0;
1858
- runner.iterations = 0;
1859
- runner.parameters = NULL;
1860
- runner.single_parameter_mode = 0;
1861
- runner.user_data = NULL;
1862
-
1863
- runner.report.successful = 0;
1864
- runner.report.skipped = 0;
1865
- runner.report.failed = 0;
1866
- runner.report.errored = 0;
1867
- #if defined(MUNIT_ENABLE_TIMING)
1868
- runner.report.cpu_clock = 0;
1869
- runner.report.wall_clock = 0;
1870
- #endif
1871
-
1872
- runner.colorize = 0;
1873
- #if !defined(_WIN32)
1874
- runner.fork = 1;
1875
- #else
1876
- runner.fork = 0;
1877
- #endif
1878
- runner.show_stderr = 0;
1879
- runner.fatal_failures = 0;
1880
- runner.suite = suite;
1881
- runner.user_data = user_data;
1882
- runner.seed = munit_rand_generate_seed();
1883
- runner.colorize = munit_stream_supports_ansi(MUNIT_OUTPUT_FILE);
1884
-
1885
- for (arg = 1 ; arg < argc ; arg++) {
1886
- if (strncmp("--", argv[arg], 2) == 0) {
1887
- if (strcmp("seed", argv[arg] + 2) == 0) {
1888
- if (arg + 1 >= argc) {
1889
- munit_logf_internal(MUNIT_LOG_ERROR, stderr, "%s requires an argument", argv[arg]);
1890
- goto cleanup;
1891
- }
1892
-
1893
- envptr = argv[arg + 1];
1894
- ts = strtoul(argv[arg + 1], &envptr, 0);
1895
- if (*envptr != '\0' || ts > (~((munit_uint32_t) 0U))) {
1896
- munit_logf_internal(MUNIT_LOG_ERROR, stderr, "invalid value ('%s') passed to %s", argv[arg + 1], argv[arg]);
1897
- goto cleanup;
1898
- }
1899
- runner.seed = (munit_uint32_t) ts;
1900
-
1901
- arg++;
1902
- } else if (strcmp("iterations", argv[arg] + 2) == 0) {
1903
- if (arg + 1 >= argc) {
1904
- munit_logf_internal(MUNIT_LOG_ERROR, stderr, "%s requires an argument", argv[arg]);
1905
- goto cleanup;
1906
- }
1907
-
1908
- endptr = argv[arg + 1];
1909
- iterations = strtoul(argv[arg + 1], &endptr, 0);
1910
- if (*endptr != '\0' || iterations > UINT_MAX) {
1911
- munit_logf_internal(MUNIT_LOG_ERROR, stderr, "invalid value ('%s') passed to %s", argv[arg + 1], argv[arg]);
1912
- goto cleanup;
1913
- }
1914
-
1915
- runner.iterations = (unsigned int) iterations;
1916
-
1917
- arg++;
1918
- } else if (strcmp("param", argv[arg] + 2) == 0) {
1919
- if (arg + 2 >= argc) {
1920
- munit_logf_internal(MUNIT_LOG_ERROR, stderr, "%s requires two arguments", argv[arg]);
1921
- goto cleanup;
1922
- }
1923
-
1924
- runner.parameters = realloc(runner.parameters, sizeof(MunitParameter) * (parameters_size + 2));
1925
- if (runner.parameters == NULL) {
1926
- munit_log_internal(MUNIT_LOG_ERROR, stderr, "failed to allocate memory");
1927
- goto cleanup;
1928
- }
1929
- runner.parameters[parameters_size].name = (char*) argv[arg + 1];
1930
- runner.parameters[parameters_size].value = (char*) argv[arg + 2];
1931
- parameters_size++;
1932
- runner.parameters[parameters_size].name = NULL;
1933
- runner.parameters[parameters_size].value = NULL;
1934
- arg += 2;
1935
- } else if (strcmp("color", argv[arg] + 2) == 0) {
1936
- if (arg + 1 >= argc) {
1937
- munit_logf_internal(MUNIT_LOG_ERROR, stderr, "%s requires an argument", argv[arg]);
1938
- goto cleanup;
1939
- }
1940
-
1941
- if (strcmp(argv[arg + 1], "always") == 0)
1942
- runner.colorize = 1;
1943
- else if (strcmp(argv[arg + 1], "never") == 0)
1944
- runner.colorize = 0;
1945
- else if (strcmp(argv[arg + 1], "auto") == 0)
1946
- runner.colorize = munit_stream_supports_ansi(MUNIT_OUTPUT_FILE);
1947
- else {
1948
- munit_logf_internal(MUNIT_LOG_ERROR, stderr, "invalid value ('%s') passed to %s", argv[arg + 1], argv[arg]);
1949
- goto cleanup;
1950
- }
1951
-
1952
- arg++;
1953
- } else if (strcmp("help", argv[arg] + 2) == 0) {
1954
- munit_print_help(argc, argv, user_data, arguments);
1955
- result = EXIT_SUCCESS;
1956
- goto cleanup;
1957
- } else if (strcmp("single", argv[arg] + 2) == 0) {
1958
- runner.single_parameter_mode = 1;
1959
- } else if (strcmp("show-stderr", argv[arg] + 2) == 0) {
1960
- runner.show_stderr = 1;
1961
- #if !defined(_WIN32)
1962
- } else if (strcmp("no-fork", argv[arg] + 2) == 0) {
1963
- runner.fork = 0;
1964
- #endif
1965
- } else if (strcmp("fatal-failures", argv[arg] + 2) == 0) {
1966
- runner.fatal_failures = 1;
1967
- } else if (strcmp("log-visible", argv[arg] + 2) == 0 ||
1968
- strcmp("log-fatal", argv[arg] + 2) == 0) {
1969
- if (arg + 1 >= argc) {
1970
- munit_logf_internal(MUNIT_LOG_ERROR, stderr, "%s requires an argument", argv[arg]);
1971
- goto cleanup;
1972
- }
1973
-
1974
- if (strcmp(argv[arg + 1], "debug") == 0)
1975
- level = MUNIT_LOG_DEBUG;
1976
- else if (strcmp(argv[arg + 1], "info") == 0)
1977
- level = MUNIT_LOG_INFO;
1978
- else if (strcmp(argv[arg + 1], "warning") == 0)
1979
- level = MUNIT_LOG_WARNING;
1980
- else if (strcmp(argv[arg + 1], "error") == 0)
1981
- level = MUNIT_LOG_ERROR;
1982
- else {
1983
- munit_logf_internal(MUNIT_LOG_ERROR, stderr, "invalid value ('%s') passed to %s", argv[arg + 1], argv[arg]);
1984
- goto cleanup;
1985
- }
1986
-
1987
- if (strcmp("log-visible", argv[arg] + 2) == 0)
1988
- munit_log_level_visible = level;
1989
- else
1990
- munit_log_level_fatal = level;
1991
-
1992
- arg++;
1993
- } else if (strcmp("list", argv[arg] + 2) == 0) {
1994
- munit_suite_list_tests(suite, 0, NULL);
1995
- result = EXIT_SUCCESS;
1996
- goto cleanup;
1997
- } else if (strcmp("list-params", argv[arg] + 2) == 0) {
1998
- munit_suite_list_tests(suite, 1, NULL);
1999
- result = EXIT_SUCCESS;
2000
- goto cleanup;
2001
- } else {
2002
- argument = munit_arguments_find(arguments, argv[arg] + 2);
2003
- if (argument == NULL) {
2004
- munit_logf_internal(MUNIT_LOG_ERROR, stderr, "unknown argument ('%s')", argv[arg]);
2005
- goto cleanup;
2006
- }
2007
-
2008
- if (!argument->parse_argument(suite, user_data, &arg, argc, argv))
2009
- goto cleanup;
2010
- }
2011
- } else {
2012
- runner_tests = realloc((void*) runner.tests, sizeof(char*) * (tests_size + 2));
2013
- if (runner_tests == NULL) {
2014
- munit_log_internal(MUNIT_LOG_ERROR, stderr, "failed to allocate memory");
2015
- goto cleanup;
2016
- }
2017
- runner.tests = runner_tests;
2018
- runner.tests[tests_size++] = argv[arg];
2019
- runner.tests[tests_size] = NULL;
2020
- }
2021
- }
2022
-
2023
- fflush(stderr);
2024
- fprintf(MUNIT_OUTPUT_FILE, "Running test suite with seed 0x%08" PRIx32 "...\n", runner.seed);
2025
-
2026
- munit_test_runner_run(&runner);
2027
-
2028
- tests_run = runner.report.successful + runner.report.failed + runner.report.errored;
2029
- tests_total = tests_run + runner.report.skipped;
2030
- if (tests_run == 0) {
2031
- fprintf(stderr, "No tests run, %d (100%%) skipped.\n", runner.report.skipped);
2032
- } else {
2033
- fprintf(MUNIT_OUTPUT_FILE, "%d of %d (%0.0f%%) tests successful, %d (%0.0f%%) test skipped.\n",
2034
- runner.report.successful, tests_run,
2035
- (((double) runner.report.successful) / ((double) tests_run)) * 100.0,
2036
- runner.report.skipped,
2037
- (((double) runner.report.skipped) / ((double) tests_total)) * 100.0);
2038
- }
2039
-
2040
- if (runner.report.failed == 0 && runner.report.errored == 0) {
2041
- result = EXIT_SUCCESS;
2042
- }
2043
-
2044
- cleanup:
2045
- free(runner.parameters);
2046
- free((void*) runner.tests);
2047
-
2048
- return result;
2049
- }
2050
-
2051
- int
2052
- munit_suite_main(const MunitSuite* suite, void* user_data,
2053
- int argc, char* const argv[MUNIT_ARRAY_PARAM(argc + 1)]) {
2054
- return munit_suite_main_custom(suite, user_data, argc, argv, NULL);
2055
- }