minimap2 0.2.25.1 → 0.2.26.0

Sign up to get free protection for your applications and to get access to all the features.
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
- }