Upgrade to version 0.3.21
[platform/upstream/openblas.git] / utest / ctest.h
1 /* Copyright 2011-2016 Bas van den Berg
2  *
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15
16 #ifndef CTEST_H
17 #define CTEST_H
18
19 #if defined _WIN32 || defined __CYGWIN__
20 #ifndef WIN32
21 #define WIN32
22 #endif
23 #endif
24
25 #ifndef WIN32
26 #define WEAK __attribute__ ((weak))
27 #else
28 #define WEAK
29 #endif
30
31 #ifndef __MSC_VER
32 #include <inttypes.h> /* intmax_t, uintmax_t, PRI* */
33 #endif
34
35 #include <stddef.h> /* size_t */
36
37 typedef void (*SetupFunc)(void*);
38 typedef void (*TearDownFunc)(void*);
39 typedef void (*RunWithDataFunc)(void*);
40
41 struct ctest {
42     const char* ssname;  // suite name
43     const char* ttname;  // test name
44     void (*run)();
45     int skip;
46
47     void* data;
48     SetupFunc setup;
49     TearDownFunc teardown;
50
51     struct ctest *next;
52
53     unsigned int magic;
54 };
55
56 #define __FNAME(sname, tname) __ctest_##sname##_##tname##_run
57 #define __TNAME(sname, tname) __ctest_##sname##_##tname
58 #define __PNAME(sname, tname) __ctest_##sname##_##tname##_pointer
59
60 #ifdef __APPLE__
61 #define __CTEST_APPLE
62 #endif
63
64 #ifdef __MINGW32__
65 #undef CTEST_SEGFAULT
66 #endif
67
68 #if defined(_WIN32)
69 #if defined(__clang__)
70 #define __CTEST_NO_TIME
71 #undef CTEST_SEGFAULT
72 #elif defined(_MSC_VER)
73 #define __CTEST_MSVC
74 #endif
75 #endif
76
77 //config for MSVC compiler
78 #ifdef __CTEST_MSVC
79
80 #define __CTEST_NO_TIME
81 #define CTEST_NO_COLORS
82
83 #if __MSC_VER >= 1500
84 #include <inttypes.h>
85 #else
86 #include <stdint.h>
87 #define CTEST_NO_INTTYPES
88 #endif
89
90 #ifndef CTEST_ADD_TESTS_MANUALLY
91 #pragma section(".ctest$a")
92 #pragma section(".ctest$u")
93 #pragma section(".ctest$z")
94 #endif
95
96 //clear this flag for msvc
97 #ifdef CTEST_SEGFAULT
98 #undef CTEST_SEGFAULT
99 #endif
100
101 #ifndef __cplusplus
102 #define inline __inline
103 #endif
104 #endif
105
106 #ifdef CTEST_NO_JMP
107 #define __CTEST_NO_JMP
108 #endif
109
110 #define __CTEST_MAGIC (0xdeadbeef)
111
112 #ifdef CTEST_ADD_TESTS_MANUALLY
113 # define __Test_Section
114 #else
115 #ifdef __CTEST_APPLE
116 #define __Test_Section __attribute__ ((used, section ("__DATA, .ctest")))
117 #elif defined (__CTEST_MSVC)
118 #define __Test_Section __declspec( allocate(".ctest$u"))
119 #else
120 #define __Test_Section __attribute__ ((used, section (".ctest")))
121 #endif
122 #endif
123
124 #ifndef __CTEST_MSVC
125 #define __CTEST_STRUCT(sname, tname, _skip, __data, __setup, __teardown) \
126     static struct ctest __TNAME(sname, tname)  = { \
127         .ssname=#sname, \
128         .ttname=#tname, \
129         .run = __FNAME(sname, tname), \
130         .skip = _skip, \
131         .data = __data, \
132         .setup = (SetupFunc)__setup,                                    \
133         .teardown = (TearDownFunc)__teardown,                           \
134         .next =  NULL, \
135         .magic = __CTEST_MAGIC}; \
136     static void * __PNAME(sname, tname)[2] __Test_Section = {(void*)& __TNAME(sname,tname), (void*)__CTEST_MAGIC};
137 #else
138 //for msvc
139 #define __CTEST_STRUCT(sname, tname, _skip, __data, __setup, __teardown) \
140     static struct ctest __TNAME(sname, tname) = { \
141          #sname, \
142          #tname, \
143          __FNAME(sname, tname), \
144          _skip, \
145          __data, \
146          (SetupFunc)__setup, \
147          (TearDownFunc)__teardown, \
148          NULL, \
149          __CTEST_MAGIC}; \
150     __Test_Section static void * __PNAME(sname, tname)[2]= {(void*)& __TNAME(sname,tname), (void *)__CTEST_MAGIC}; 
151 #endif
152
153 #define CTEST_DATA(sname) struct sname##_data
154
155 #define CTEST_SETUP(sname) \
156     void WEAK sname##_setup(struct sname##_data* data)
157
158 #define CTEST_TEARDOWN(sname) \
159     void WEAK sname##_teardown(struct sname##_data* data)
160
161 #define __CTEST_INTERNAL(sname, tname, _skip) \
162     void __FNAME(sname, tname)(); \
163     __CTEST_STRUCT(sname, tname, _skip, NULL, NULL, NULL) \
164     void __FNAME(sname, tname)()
165
166 #ifdef __CTEST_APPLE
167 #define SETUP_FNAME(sname) NULL
168 #define TEARDOWN_FNAME(sname) NULL
169 #else
170 #define SETUP_FNAME(sname) sname##_setup
171 #define TEARDOWN_FNAME(sname) sname##_teardown
172 #endif
173
174 #define __CTEST2_INTERNAL(sname, tname, _skip) \
175     static struct sname##_data  __ctest_##sname##_data; \
176     CTEST_SETUP(sname); \
177     CTEST_TEARDOWN(sname); \
178     void __FNAME(sname, tname)(struct sname##_data* data); \
179     __CTEST_STRUCT(sname, tname, _skip, &__ctest_##sname##_data, SETUP_FNAME(sname), TEARDOWN_FNAME(sname)) \
180     void __FNAME(sname, tname)(struct sname##_data* data)
181
182
183 void CTEST_LOG(const char* fmt, ...);
184 void CTEST_ERR(const char* fmt, ...);  // doesn't return
185
186 #define CTEST(sname, tname) __CTEST_INTERNAL(sname, tname, 0)
187 #define CTEST_SKIP(sname, tname) __CTEST_INTERNAL(sname, tname, 1)
188
189 #define CTEST2(sname, tname) __CTEST2_INTERNAL(sname, tname, 0)
190 #define CTEST2_SKIP(sname, tname) __CTEST2_INTERNAL(sname, tname, 1)
191
192
193 #ifdef CTEST_ADD_TESTS_MANUALLY
194
195 void __ctest_addTest(struct ctest *);
196
197 #define CTEST_ADD(sname, tname) do { \
198     extern struct ctest __TNAME(sname, tname); \
199     __ctest_addTest(&__TNAME(sname, tname)); \
200 } while (0)
201
202 #define CTEST_ADD2(sname, tname) do { \
203     extern struct ctest __TNAME(sname, tname); \
204     __ctest_addTest(&__TNAME(sname, tname)); \
205 } while (0)
206
207 #endif // CTEST_ADD_TESTS_MANUALLY
208
209 void assert_str(const char* exp, const char* real, const char* caller, int line);
210 #define ASSERT_STR(exp, real) assert_str(exp, real, __FILE__, __LINE__)
211
212 void assert_data(const unsigned char* exp, size_t expsize,
213                  const unsigned char* real, size_t realsize,
214                  const char* caller, int line);
215 #define ASSERT_DATA(exp, expsize, real, realsize) \
216     assert_data(exp, expsize, real, realsize, __FILE__, __LINE__)
217
218 void assert_equal(intmax_t exp, intmax_t real, const char* caller, int line);
219 #define ASSERT_EQUAL(exp, real) assert_equal(exp, real, __FILE__, __LINE__)
220
221 void assert_equal_u(uintmax_t exp, uintmax_t real, const char* caller, int line);
222 #define ASSERT_EQUAL_U(exp, real) assert_equal_u(exp, real, __FILE__, __LINE__)
223
224 void assert_not_equal(intmax_t exp, intmax_t real, const char* caller, int line);
225 #define ASSERT_NOT_EQUAL(exp, real) assert_not_equal(exp, real, __FILE__, __LINE__)
226
227 void assert_not_equal_u(uintmax_t exp, uintmax_t real, const char* caller, int line);
228 #define ASSERT_NOT_EQUAL_U(exp, real) assert_not_equal_u(exp, real, __FILE__, __LINE__)
229
230 void assert_interval(intmax_t exp1, intmax_t exp2, intmax_t real, const char* caller, int line);
231 #define ASSERT_INTERVAL(exp1, exp2, real) assert_interval(exp1, exp2, real, __FILE__, __LINE__)
232
233 void assert_null(void* real, const char* caller, int line);
234 #define ASSERT_NULL(real) assert_null((void*)real, __FILE__, __LINE__)
235
236 void assert_not_null(const void* real, const char* caller, int line);
237 #define ASSERT_NOT_NULL(real) assert_not_null(real, __FILE__, __LINE__)
238
239 void assert_true(int real, const char* caller, int line);
240 #define ASSERT_TRUE(real) assert_true(real, __FILE__, __LINE__)
241
242 void assert_false(int real, const char* caller, int line);
243 #define ASSERT_FALSE(real) assert_false(real, __FILE__, __LINE__)
244
245 void assert_fail(const char* caller, int line);
246 #define ASSERT_FAIL() assert_fail(__FILE__, __LINE__)
247
248 /* If longjmp() is not available, integer flag will be used instead of jmp_buf.
249  *
250  * __CTEST_SETJMP() will clear the flag and return zero, and __CTEST_LONGJMP()
251  * will set the flag to its argument. __CTEST_ERROR_CODE() will return that flag.
252  *
253  * If longjmp() is available, jmp_buf will be used as usual and __CTEST_ERROR_CODE()
254  * will always return zero.
255  *
256  * You can check both __CTEST_SETJMP() and __CTEST_ERROR_CODE() return value
257  * to detect error in a portable way.
258  */
259 #ifdef __CTEST_NO_JMP
260 # define __CTEST_JMPBUF                 int
261 # define __CTEST_ERROR_CODE(_var)       (_var)
262 # define __CTEST_SETJMP(_var)           (_var = 0)
263 # define __CTEST_LONGJMP(_var, _err)    (_var = _err)
264 #else // !__CTEST_NO_JMP
265 # define __CTEST_JMPBUF                 jmp_buf
266 # define __CTEST_ERROR_CODE(_var)       (0)
267 # define __CTEST_SETJMP(_var)           setjmp(_var)
268 # define __CTEST_LONGJMP(_var, _err)    longjmp(_var, _err)
269 #endif // __CTEST_NO_JMP
270
271 void assert_dbl_near(double exp, double real, double tol, const char* caller, int line);
272 #define ASSERT_DBL_NEAR(exp, real) assert_dbl_near(exp, real, 1e-4, __FILE__, __LINE__)
273 #define ASSERT_DBL_NEAR_TOL(exp, real, tol) assert_dbl_near(exp, real, tol, __FILE__, __LINE__)
274
275 void assert_dbl_far(double exp, double real, double tol, const char* caller, int line);
276 #define ASSERT_DBL_FAR(exp, real) assert_dbl_far(exp, real, 1e-4, __FILE__, __LINE__)
277 #define ASSERT_DBL_FAR_TOL(exp, real, tol) assert_dbl_far(exp, real, tol, __FILE__, __LINE__)
278
279 #ifdef CTEST_MAIN
280
281 #ifndef __CTEST_NO_JMP
282 #include <setjmp.h>
283 #endif
284
285 #include <stdarg.h>
286 #include <stdio.h>
287 #include <string.h>
288
289 #ifndef __CTEST_NO_TIME
290 #include <sys/time.h>
291 #endif
292 #include <stdint.h>
293
294 #ifdef _WIN32
295 #include <io.h>
296 #else
297 #include <unistd.h>
298 #endif
299
300 #include <stdlib.h>
301
302 #ifdef __CTEST_APPLE
303 #include <dlfcn.h>
304 #endif
305
306 static size_t ctest_errorsize;
307 static char* ctest_errormsg;
308 #define MSG_SIZE 4096
309 static char ctest_errorbuffer[MSG_SIZE];
310 static __CTEST_JMPBUF ctest_err;
311 static int color_output = 1;
312 static const char* suite_name;
313 static const char* test_name;
314
315 typedef int (*filter_func)(struct ctest*);
316
317 #define ANSI_BLACK    "\033[0;30m"
318 #define ANSI_RED      "\033[0;31m"
319 #define ANSI_GREEN    "\033[0;32m"
320 #define ANSI_YELLOW   "\033[0;33m"
321 #define ANSI_BLUE     "\033[0;34m"
322 #define ANSI_MAGENTA  "\033[0;35m"
323 #define ANSI_CYAN     "\033[0;36m"
324 #define ANSI_GREY     "\033[0;37m"
325 #define ANSI_DARKGREY "\033[01;30m"
326 #define ANSI_BRED     "\033[01;31m"
327 #define ANSI_BGREEN   "\033[01;32m"
328 #define ANSI_BYELLOW  "\033[01;33m"
329 #define ANSI_BBLUE    "\033[01;34m"
330 #define ANSI_BMAGENTA "\033[01;35m"
331 #define ANSI_BCYAN    "\033[01;36m"
332 #define ANSI_WHITE    "\033[01;37m"
333 #define ANSI_NORMAL   "\033[0m"
334
335 #ifdef __CTEST_MSVC
336 #ifndef CTEST_ADD_TESTS_MANUALLY
337 __declspec(allocate(".ctest$a")) struct ctest * ctest_win_begin;
338 __declspec(allocate(".ctest$z")) struct ctest * ctest_win_end;
339 #endif
340 #endif
341
342 static CTEST(suite, test) { }
343
344 #define __CTEST_POINTER_NEXT(_test) (struct ctest **)((struct ctest **)(_test) + 2)
345 #define __CTEST_POINTER_PREV(_test) (struct ctest **)((struct ctest **)(_test) - 2)
346
347 /* First element of test list.
348  */
349 static struct ctest * * __ctest_head_p = (struct ctest **)__PNAME(suite, test);
350
351 #ifdef CTEST_ADD_TESTS_MANUALLY
352
353 /* Last element of test list.
354  */
355 static struct ctest *__ctest_tail = &__TNAME(suite, test);
356
357 /* Add test to linked list manually.
358  */
359 void __ctest_addTest(struct ctest *test)
360 {
361     __ctest_tail->next = test;
362     __ctest_tail = test;
363 }
364 #else // !CTEST_ADD_TESTS_MANUALLY
365
366 #ifndef __CTEST_MSVC
367 /* Add all tests to linked list automatically.
368  */
369 static void __ctest_linkTests()
370 {
371     struct ctest ** test;
372     struct ctest ** ctest_begin = (struct ctest **)__PNAME(suite, test);
373     struct ctest ** ctest_end = (struct ctest **)__PNAME(suite, test);
374
375     // find begin and end of section by comparing magics
376     while (1) {
377         struct ctest** t = __CTEST_POINTER_PREV(ctest_begin);
378         if (t[0] == NULL) break;
379         if (t[1] != (struct ctest*)__CTEST_MAGIC) break;
380         ctest_begin = t;
381     }
382     while (1) {
383         struct ctest** t = __CTEST_POINTER_NEXT(ctest_end);
384         if (t[0] == NULL) break;
385         if (t[1] != (struct ctest*)__CTEST_MAGIC) break;
386         ctest_end = t;
387     }
388     ctest_end = __CTEST_POINTER_NEXT(ctest_end); // end after last one
389
390     for (test = ctest_begin; test != ctest_end; test = __CTEST_POINTER_NEXT(test)) {
391         struct ctest ** next_p = __CTEST_POINTER_NEXT(test);
392         struct ctest * next;
393         if (next_p == ctest_end)
394             next = NULL;
395         else
396             next = next_p[0];
397
398         (*test)->next = next;
399     }
400
401     __ctest_head_p = ctest_begin;
402 }
403 #else //for msvc
404 static void __ctest_linkTests()
405 {
406     struct ctest ** ctest_start = __ctest_head_p;
407     struct ctest ** test;
408     struct ctest * cur=ctest_start[0];
409
410     for(test=&ctest_win_begin; test!=&ctest_win_end; test++){
411       //check
412       if(test[1] == (struct ctest*)__CTEST_MAGIC){
413         //skip the start
414         if((test[0]) == ctest_start[0]) continue;
415         
416         cur->next = test[0];
417         cur=cur->next;
418         cur->next=NULL;
419       }
420     }
421 }
422 #endif
423 #endif
424
425 inline static void vprint_errormsg(const char* const fmt, va_list ap) {
426         // (v)snprintf returns the number that would have been written
427     const int ret = vsnprintf(ctest_errormsg, ctest_errorsize, fmt, ap);
428     if (ret < 0) {
429                 ctest_errormsg[0] = 0x00;
430     } else {
431         const size_t size = (size_t) ret;
432         const size_t s = (ctest_errorsize <= size ? size -ctest_errorsize : size);
433         // ctest_errorsize may overflow at this point
434                 ctest_errorsize -= s;
435                 ctest_errormsg += s;
436     }
437 }
438
439 inline static void print_errormsg(const char* const fmt, ...) {
440     va_list argp;
441     va_start(argp, fmt);
442     vprint_errormsg(fmt, argp);
443     va_end(argp);
444 }
445
446 static void msg_start(const char* color, const char* title) {
447     if (color_output) {
448         print_errormsg("%s", color);
449     }
450     print_errormsg("  %s: ", title);
451 }
452
453 static void msg_end() {
454     if (color_output) {
455         print_errormsg(ANSI_NORMAL);
456     }
457     print_errormsg("\n");
458 }
459
460 void CTEST_LOG(const char* fmt, ...)
461 {
462     va_list argp;
463     msg_start(ANSI_BLUE, "LOG");
464
465     va_start(argp, fmt);
466     vprint_errormsg(fmt, argp);
467     va_end(argp);
468
469     msg_end();
470 }
471
472 void CTEST_ERR(const char* fmt, ...)
473 {
474     va_list argp;
475     msg_start(ANSI_YELLOW, "ERR");
476
477     va_start(argp, fmt);
478     vprint_errormsg(fmt, argp);
479     va_end(argp);
480
481     msg_end();
482     __CTEST_LONGJMP(ctest_err, 1);
483 }
484
485 void assert_str(const char* exp, const char*  real, const char* caller, int line) {
486     if ((exp == NULL && real != NULL) ||
487         (exp != NULL && real == NULL) ||
488         (exp && real && strcmp(exp, real) != 0)) {
489         CTEST_ERR("%s:%d  expected '%s', got '%s'", caller, line, exp, real);
490     }
491 }
492
493 void assert_data(const unsigned char* exp, size_t expsize,
494                  const unsigned char* real, size_t realsize,
495                  const char* caller, int line) {
496     size_t i;
497     if (expsize != realsize) {
498 #ifndef CTEST_NO_INTTYPES
499         CTEST_ERR("%s:%d  expected %" PRIuMAX " bytes, got %" PRIuMAX, caller, line, (uintmax_t) expsize, (uintmax_t) realsize);
500 #else
501         CTEST_ERR("%s:%d  expected %u bytes, got %u", caller, line, (uintmax_t) expsize, (uintmax_t) realsize);
502 #endif
503     }
504     for (i=0; i<expsize; i++) {
505         if (exp[i] != real[i]) {
506 #ifndef CTEST_NO_INTTYPES
507             CTEST_ERR("%s:%d expected 0x%02x at offset %" PRIuMAX " got 0x%02x",
508 #else
509             CTEST_ERR("%s:%d expected 0x%02x at offset %u got 0x%02x",
510 #endif
511                 caller, line, exp[i], (uintmax_t) i, real[i]);
512         }
513     }
514 }
515
516 void assert_equal(intmax_t exp, intmax_t real, const char* caller, int line) {
517     if (exp != real) {
518 #ifndef CTEST_NO_INTTYPES
519         CTEST_ERR("%s:%d  expected %" PRIdMAX ", got %" PRIdMAX, caller, line, exp, real);
520 #else
521         CTEST_ERR("%s:%d  expected %d, got %d", caller, line, exp, real);
522 #endif
523     }
524 }
525
526 void assert_equal_u(uintmax_t exp, uintmax_t real, const char* caller, int line) {
527     if (exp != real) {
528 #ifndef CTEST_NO_INTTYPES
529         CTEST_ERR("%s:%d  expected %" PRIuMAX ", got %" PRIuMAX, caller, line, exp, real);
530 #else
531         CTEST_ERR("%s:%d  expected %u, got %u", caller, line, exp, real);
532 #endif
533     }
534 }
535
536 void assert_not_equal(intmax_t exp, intmax_t real, const char* caller, int line) {
537     if ((exp) == (real)) {
538 #ifndef CTEST_NO_INTTYPES
539         CTEST_ERR("%s:%d  should not be %" PRIdMAX, caller, line, real);
540 #else
541         CTEST_ERR("%s:%d  should not be %d", caller, line, real);
542 #endif
543     }
544 }
545
546 void assert_not_equal_u(uintmax_t exp, uintmax_t real, const char* caller, int line) {
547     if ((exp) == (real)) {
548 #ifndef CTEST_NO_INTTYPES
549         CTEST_ERR("%s:%d  should not be %" PRIuMAX, caller, line, real);
550 #else
551         CTEST_ERR("%s:%d  should not be %u", caller, line, real);
552 #endif
553     }
554 }
555
556 void assert_interval(intmax_t exp1, intmax_t exp2, intmax_t real, const char* caller, int line) {
557     if (real < exp1 || real > exp2) {
558 #ifndef CTEST_NO_INTTYPES
559         CTEST_ERR("%s:%d  expected %" PRIdMAX "-%" PRIdMAX ", got %" PRIdMAX, caller, line, exp1, exp2, real);
560 #else
561         CTEST_ERR("%s:%d  expected %d-%d, got %d", caller, line, exp1, exp2, real);
562 #endif
563     }
564 }
565
566 void assert_dbl_near(double exp, double real, double tol, const char* caller, int line) {
567     double diff = exp - real;
568     double absdiff = diff;
569     /* avoid using fabs and linking with a math lib */
570     if(diff < 0) {
571       absdiff *= -1;
572     }
573     if (absdiff > tol) {
574         CTEST_ERR("%s:%d  expected %0.3e, got %0.3e (diff %0.3e, tol %0.3e)", caller, line, exp, real, diff, tol);
575     }
576 }
577
578 void assert_dbl_far(double exp, double real, double tol, const char* caller, int line) {
579     double diff = exp - real;
580     double absdiff = diff;
581     /* avoid using fabs and linking with a math lib */
582     if(diff < 0) {
583       absdiff *= -1;
584     }
585     if (absdiff <= tol) {
586         CTEST_ERR("%s:%d  expected %0.3e, got %0.3e (diff %0.3e, tol %0.3e)", caller, line, exp, real, diff, tol);
587     }
588 }
589
590 void assert_null(void* real, const char* caller, int line) {
591     if ((real) != NULL) {
592         CTEST_ERR("%s:%d  should be NULL", caller, line);
593     }
594 }
595
596 void assert_not_null(const void* real, const char* caller, int line) {
597     if (real == NULL) {
598         CTEST_ERR("%s:%d  should not be NULL", caller, line);
599     }
600 }
601
602 void assert_true(int real, const char* caller, int line) {
603     if ((real) == 0) {
604         CTEST_ERR("%s:%d  should be true", caller, line);
605     }
606 }
607
608 void assert_false(int real, const char* caller, int line) {
609     if ((real) != 0) {
610         CTEST_ERR("%s:%d  should be false", caller, line);
611     }
612 }
613
614 void assert_fail(const char* caller, int line) {
615     CTEST_ERR("%s:%d  shouldn't come here", caller, line);
616 }
617
618
619 static int suite_all(struct ctest* t) {
620     (void) t; // fix unused parameter warning
621     return 1;
622 }
623
624 static int suite_filter(struct ctest* t) {
625     return strncmp(suite_name, t->ssname, strlen(suite_name)) == 0;
626 }
627
628 static int suite_test_filter(struct ctest* t) {
629   int suit_match, test_match;
630   suit_match=(strncmp(suite_name, t->ssname, strlen(suite_name)) == 0);
631   test_match=(strncmp(test_name, t->ttname, strlen(test_name)) == 0);
632   return (suit_match & test_match);
633 }
634
635
636 #ifndef __CTEST_NO_TIME
637 static uint64_t getCurrentTime() {
638     struct timeval now;
639     gettimeofday(&now, NULL);
640     uint64_t now64 = (uint64_t) now.tv_sec;
641     now64 *= 1000000;
642     now64 += ((uint64_t) now.tv_usec);
643     return now64;
644 }
645 #endif
646
647 static void color_print(const char* color, const char* text) {
648     if (color_output)
649         printf("%s%s"ANSI_NORMAL"\n", color, text);
650     else
651         printf("%s\n", text);
652 }
653
654 #ifdef __CTEST_APPLE
655 static void *find_symbol(struct ctest *test, const char *fname)
656 {
657     size_t len = strlen(test->ssname) + 1 + strlen(fname);
658     char *symbol_name = (char *) malloc(len + 1);
659     memset(symbol_name, 0, len + 1);
660     snprintf(symbol_name, len + 1, "%s_%s", test->ssname, fname);
661
662     //fprintf(stderr, ">>>> dlsym: loading %s\n", symbol_name);
663     void *symbol = dlsym(RTLD_DEFAULT, symbol_name);
664     if (!symbol) {
665         //fprintf(stderr, ">>>> ERROR: %s\n", dlerror());
666     }
667     // returns NULL on error
668
669     free(symbol_name);
670     return symbol;
671 }
672 #endif
673
674 #ifdef CTEST_SEGFAULT
675 #include <signal.h>
676 static void sighandler(int signum)
677 {
678     char msg[128];
679     snprintf(msg, sizeof(msg), "[SIGNAL %d: %s]", signum, strsignal(signum));
680     color_print(ANSI_BRED, msg);
681     fflush(stdout);
682
683     /* "Unregister" the signal handler and send the signal back to the process
684      * so it can terminate as expected */
685     signal(signum, SIG_DFL);
686     kill(getpid(), signum);
687 }
688 #endif
689
690 int ctest_main(int argc, const char *argv[])
691 {
692     static int total = 0;
693     static int num_ok = 0;
694     static int num_fail = 0;
695     static int num_skip = 0;
696     static int index = 1;
697     static filter_func filter = suite_all;
698
699     const char* color = (num_fail) ? ANSI_BRED : ANSI_GREEN;
700     char results[80];
701     static struct ctest* test;
702
703 #ifdef CTEST_SEGFAULT
704     signal(SIGSEGV, sighandler);
705 #endif
706
707     if (argc == 2) {
708         suite_name = argv[1];
709         filter = suite_filter;
710     }else if (argc == 3) {
711         suite_name = argv[1];
712         test_name = argv[2];
713         filter = suite_test_filter;
714     }
715
716 #ifdef CTEST_NO_COLORS
717     color_output = 0;
718 #else
719     color_output = isatty(1);
720 #endif
721
722 #ifndef __CTEST_NO_TIME
723     uint64_t t1 = getCurrentTime();
724 #endif
725
726 #ifndef CTEST_ADD_TESTS_MANUALLY
727     __ctest_linkTests();
728 #endif
729
730
731     for (test = *(__ctest_head_p); test != NULL; test=test->next) {
732         if (test == &__ctest_suite_test) continue;
733         if (filter(test)) total++;
734     }
735
736     for (test = *(__ctest_head_p); test != NULL; test=test->next) {
737         if (test == &__ctest_suite_test) continue;
738         if (filter(test)) {
739             ctest_errorbuffer[0] = 0;
740             ctest_errorsize = MSG_SIZE-1;
741             ctest_errormsg = ctest_errorbuffer;
742             printf("TEST %d/%d %s:%s ", index, total, test->ssname, test->ttname);
743             fflush(stdout);
744             if (test->skip) {
745                 color_print(ANSI_BYELLOW, "[SKIPPED]");
746                 num_skip++;
747             } else {
748                 int result = __CTEST_SETJMP(ctest_err);
749                 if (result == 0) {
750 #ifdef __CTEST_APPLE
751                     if (!test->setup) {
752                         test->setup = (SetupFunc) find_symbol(test, "setup");
753                     }
754                     if (!test->teardown) {
755                         test->teardown = (TearDownFunc) find_symbol(test, "teardown");
756                     }
757 #endif
758
759                     if (test->setup) test->setup(test->data);
760                     if (test->data)
761                       ((RunWithDataFunc)test->run)(test->data);
762                     else
763                         test->run();
764                     if (test->teardown) test->teardown(test->data);
765                     // if we got here it's ok
766 #ifdef CTEST_COLOR_OK
767                     color_print(ANSI_BGREEN, "[OK]");
768 #else
769                     printf("[OK]\n");
770 #endif
771                     num_ok++;
772                 } else {
773                     color_print(ANSI_BRED, "[FAIL]");
774                     num_fail++;
775                 }
776                 if (ctest_errorsize != MSG_SIZE-1) printf("%s", ctest_errorbuffer);
777             }
778             index++;
779         }
780     }
781 #ifndef __CTEST_NO_TIME
782     uint64_t t2 = getCurrentTime();
783 #endif
784
785 #ifndef __CTEST_NO_TIME
786     sprintf(results, "RESULTS: %d tests (%d ok, %d failed, %d skipped) ran in %"PRIu64" ms", total, num_ok, num_fail, num_skip, (t2 - t1)/1000);
787 #else
788     sprintf(results, "RESULTS: %d tests (%d ok, %d failed, %d skipped)", total, num_ok, num_fail, num_skip);
789 #endif
790     color_print(color, results);
791     return num_fail;
792 }
793
794 #endif
795
796 #endif
797