The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
acutest.h
Go to the documentation of this file.
1 /*
2  * Acutest -- Another C/C++ Unit Test facility
3  * <https://github.com/mity/acutest>
4  *
5  * Copyright 2013-2020 Martin Mitas
6  * Copyright 2019 Garrett D'Amore
7  *
8  * Permission is hereby granted, free of charge, to any person obtaining a
9  * copy of this software and associated documentation files (the "Software"),
10  * to deal in the Software without restriction, including without limitation
11  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12  * and/or sell copies of the Software, and to permit persons to whom the
13  * Software is furnished to do so, subject to the following conditions:
14  *
15  * The above copyright notice and this permission notice shall be included in
16  * all copies or substantial portions of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
24  * IN THE SOFTWARE.
25  */
26 
27 #ifndef ACUTEST_H
28 #define ACUTEST_H
29 
30 
31 /************************
32  *** Public interface ***
33  ************************/
34 
35 /* By default, "acutest.h" provides the main program entry point (function
36  * main()). However, if the test suite is composed of multiple source files
37  * which include "acutest.h", then this causes a problem of multiple main()
38  * definitions. To avoid this problem, #define macro TEST_NO_MAIN in all
39  * compilation units but one.
40  */
41 
42 /* Macro to specify list of unit tests in the suite.
43  * The unit test implementation MUST provide list of unit tests it implements
44  * with this macro:
45  *
46  * TEST_LIST = {
47  * { "test1_name", test1_func_ptr },
48  * { "test2_name", test2_func_ptr },
49  * ...
50  * { NULL, NULL } // zeroed record marking the end of the list
51  * };
52  *
53  * The list specifies names of each test (must be unique) and pointer to
54  * a function implementing it. The function does not take any arguments
55  * and has no return values, i.e. every test function has to be compatible
56  * with this prototype:
57  *
58  * void test_func(void);
59  *
60  * Note the list has to be ended with a zeroed record.
61  */
62 #define TEST_LIST const struct acutest_test_ acutest_list_[]
63 
64 
65 /* Macros for testing whether an unit test succeeds or fails. These macros
66  * can be used arbitrarily in functions implementing the unit tests.
67  *
68  * If any condition fails throughout execution of a test, the test fails.
69  *
70  * TEST_CHECK takes only one argument (the condition), TEST_CHECK_ allows
71  * also to specify an error message to print out if the condition fails.
72  * (It expects printf-like format string and its parameters). The macros
73  * return non-zero (condition passes) or 0 (condition fails).
74  *
75  * That can be useful when more conditions should be checked only if some
76  * preceding condition passes, as illustrated in this code snippet:
77  *
78  * SomeStruct* ptr = allocate_some_struct();
79  * if(TEST_CHECK(ptr != NULL)) {
80  * TEST_CHECK(ptr->member1 < 100);
81  * TEST_CHECK(ptr->member2 > 200);
82  * }
83  */
84 #define TEST_CHECK_(cond,...) acutest_check_((cond), __FILE__, __LINE__, __VA_ARGS__)
85 #define TEST_CHECK(cond) acutest_check_((cond), __FILE__, __LINE__, "%s", #cond)
86 
87 
88 /* These macros are the same as TEST_CHECK_ and TEST_CHECK except that if the
89  * condition fails, the currently executed unit test is immediately aborted.
90  *
91  * That is done either by calling abort() if the unit test is executed as a
92  * child process; or via longjmp() if the unit test is executed within the
93  * main Acutest process.
94  *
95  * As a side effect of such abortion, your unit tests may cause memory leaks,
96  * unflushed file descriptors, and other phenomena caused by the abortion.
97  *
98  * Therefore you should not use these as a general replacement for TEST_CHECK.
99  * Use it with some caution, especially if your test causes some other side
100  * effects to the outside world (e.g. communicating with some server, inserting
101  * into a database etc.).
102  */
103 #define TEST_ASSERT_(cond,...) \
104  do { \
105  if(!acutest_check_((cond), __FILE__, __LINE__, __VA_ARGS__)) \
106  acutest_abort_(); \
107  } while(0)
108 #define TEST_ASSERT(cond) \
109  do { \
110  if(!acutest_check_((cond), __FILE__, __LINE__, "%s", #cond)) \
111  acutest_abort_(); \
112  } while(0)
113 
114 
115 #ifdef __cplusplus
116 /* Macros to verify that the code (the 1st argument) throws exception of given
117  * type (the 2nd argument). (Note these macros are only available in C++.)
118  *
119  * TEST_EXCEPTION_ is like TEST_EXCEPTION but accepts custom printf-like
120  * message.
121  *
122  * For example:
123  *
124  * TEST_EXCEPTION(function_that_throw(), ExpectedExceptionType);
125  *
126  * If the function_that_throw() throws ExpectedExceptionType, the check passes.
127  * If the function throws anything incompatible with ExpectedExceptionType
128  * (or if it does not thrown an exception at all), the check fails.
129  */
130 #define TEST_EXCEPTION(code, exctype) \
131  do { \
132  bool exc_ok_ = false; \
133  const char *msg_ = NULL; \
134  try { \
135  code; \
136  msg_ = "No exception thrown."; \
137  } catch(exctype const&) { \
138  exc_ok_= true; \
139  } catch(...) { \
140  msg_ = "Unexpected exception thrown."; \
141  } \
142  acutest_check_(exc_ok_, __FILE__, __LINE__, #code " throws " #exctype);\
143  if(msg_ != NULL) \
144  acutest_message_(false, "%s", msg_); \
145  } while(0)
146 #define TEST_EXCEPTION_(code, exctype, ...) \
147  do { \
148  bool exc_ok_ = false; \
149  const char *msg_ = NULL; \
150  try { \
151  code; \
152  msg_ = "No exception thrown."; \
153  } catch(exctype const&) { \
154  exc_ok_= true; \
155  } catch(...) { \
156  msg_ = "Unexpected exception thrown."; \
157  } \
158  acutest_check_(exc_ok_, __FILE__, __LINE__, __VA_ARGS__); \
159  if(msg_ != NULL) \
160  acutest_message_(false, "%s", msg_); \
161  } while(0)
162 #endif /* #ifdef __cplusplus */
163 
164 
165 /* Sometimes it is useful to split execution of more complex unit tests to some
166  * smaller parts and associate those parts with some names.
167  *
168  * This is especially handy if the given unit test is implemented as a loop
169  * over some vector of multiple testing inputs. Using these macros allow to use
170  * sort of subtitle for each iteration of the loop (e.g. outputting the input
171  * itself or a name associated to it), so that if any TEST_CHECK condition
172  * fails in the loop, it can be easily seen which iteration triggers the
173  * failure, without the need to manually output the iteration-specific data in
174  * every single TEST_CHECK inside the loop body.
175  *
176  * TEST_CASE allows to specify only single string as the name of the case,
177  * TEST_CASE_ provides all the power of printf-like string formatting.
178  *
179  * Note that the test cases cannot be nested. Starting a new test case ends
180  * implicitly the previous one. To end the test case explicitly (e.g. to end
181  * the last test case after exiting the loop), you may use TEST_CASE(NULL).
182  */
183 #define TEST_CASE_(...) acutest_case_(__VA_ARGS__)
184 #define TEST_CASE(name) acutest_case_("%s", name)
185 
186 
187 /* Maximal output per TEST_CASE call. Longer messages are cut.
188  * You may define another limit prior including "acutest.h"
189  */
190 #ifndef TEST_CASE_MAXSIZE
191  #define TEST_CASE_MAXSIZE 64
192 #endif
193 
194 /* printf-like macro for outputting an extra information about a failure.
195  *
196  * Intended use is to output some computed output versus the expected value,
197  * e.g. like this:
198  *
199  * if(!TEST_CHECK(produced == expected)) {
200  * TEST_MSG("Expected: %d", expected);
201  * TEST_MSG("Produced: %d", produced);
202  * }
203  *
204  * Note the message is only written down if the most recent use of any checking
205  * macro (like e.g. TEST_CHECK or TEST_EXCEPTION) in the current test failed.
206  * This means the above is equivalent to just this:
207  *
208  * TEST_CHECK(produced == expected);
209  * TEST_MSG("Expected: %d", expected);
210  * TEST_MSG("Produced: %d", produced);
211  *
212  * The macro can deal with multi-line output fairly well. It also automatically
213  * adds a final new-line if there is none present.
214  */
215 #define TEST_MSG(...) TEST_MSG_FAIL(__VA_ARGS__)
216 #define TEST_MSG_FAIL(...) acutest_message_(false, __VA_ARGS__)
217 
218 
219 /* Alternative version of TEST_MSG which outputs regardless of the
220  * failure status of the current test.
221  */
222 #define TEST_MSG_ALWAYS(...) acutest_message_(true, __VA_ARGS__)
223 
224 /* Maximal output per TEST_MSG call. Longer messages are cut.
225  * You may define another limit prior including "acutest.h"
226  */
227 #ifndef TEST_MSG_MAXSIZE
228  #define TEST_MSG_MAXSIZE 1024
229 #endif
230 
231 
232 /* Macro for dumping a block of memory.
233  *
234  * Its intended use is very similar to what TEST_MSG is for, but instead of
235  * generating any printf-like message, this is for dumping raw block of a
236  * memory in a hexadecimal form:
237  *
238  * TEST_CHECK(size_produced == size_expected &&
239  * memcmp(addr_produced, addr_expected, size_produced) == 0);
240  * TEST_DUMP("Expected:", addr_expected, size_expected);
241  * TEST_DUMP("Produced:", addr_produced, size_produced);
242  */
243 #define TEST_DUMP(title, addr, size) TEST_DUMP_FAIL(title, addr, size)
244 #define TEST_DUMP_FAIL(title, addr, size) acutest_dump_(false, title, addr, size);
245 
246 /* Alternative version of TEST_DUMP which outputs regardless of the
247  * failure status of the current test
248  */
249 #define TEST_DUMP_ALWAYS(title, addr, size) acutest_dump_(true, title, addr, size);
250 
251 /* Maximal output per TEST_DUMP call (in bytes to dump). Longer blocks are cut.
252  * You may define another limit prior including "acutest.h"
253  */
254 #ifndef TEST_DUMP_MAXSIZE
255  #define TEST_DUMP_MAXSIZE 1024
256 #endif
257 
258 /* Maximal size of log entries passed between child test processes and parent
259  * process. This allows for a memory block dump with a title up to TEST_MSG_MAXSIZE
260  * in length, plus ": " separator and NULL terminator. Longer messages cause an error.
261  */
262 #define TEST_LOG_MAXSIZE ((TEST_DUMP_MAXSIZE * 3) + TEST_MSG_MAXSIZE + 3)
263 
264 /* Common test initialisation/clean-up
265  *
266  * In some test suites, it may be needed to perform some sort of the same
267  * initialization and/or clean-up in all the tests.
268  *
269  * Such test suites may use macros TEST_INIT and/or TEST_FINI prior including
270  * this header. The expansion of the macro is then used as a body of helper
271  * function called just before executing every single (TEST_INIT) or just after
272  * it ends (TEST_FINI).
273  *
274  * Examples of various ways how to use the macro TEST_INIT:
275  *
276  * #define TEST_INIT my_init_func();
277  * #define TEST_INIT my_init_func() // Works even without the semicolon
278  * #define TEST_INIT setlocale(LC_ALL, NULL);
279  * #define TEST_INIT { setlocale(LC_ALL, NULL); my_init_func(); }
280  *
281  * TEST_FINI is to be used in the same way.
282  */
283 
284 
285 /**********************
286  *** Implementation ***
287  **********************/
288 
289 /* The unit test files should not rely on anything below. */
290 
291 #include <ctype.h>
292 #include <stdarg.h>
293 #include <stdio.h>
294 #include <stdlib.h>
295 #include <string.h>
296 #include <setjmp.h>
297 #include <stdbool.h>
298 
299 #if defined(unix) || defined(__unix__) || defined(__unix) || defined(__APPLE__)
300  #define ACUTEST_UNIX_ 1
301  #include <errno.h>
302  #include <libgen.h>
303  #include <unistd.h>
304  #include <sys/types.h>
305  #include <sys/wait.h>
306  #include <signal.h>
307  #include <time.h>
308 
309  #if defined CLOCK_PROCESS_CPUTIME_ID && defined CLOCK_MONOTONIC
310  #define ACUTEST_HAS_POSIX_TIMER_ 1
311  #endif
312 #endif
313 
314 #if defined(_gnu_linux_) || defined(__linux__)
315  #define ACUTEST_LINUX_ 1
316  #include <fcntl.h>
317  #include <sys/stat.h>
318 #endif
319 
320 #if defined(_WIN32) || defined(__WIN32__) || defined(__WINDOWS__)
321  #define ACUTEST_WIN_ 1
322  #include <windows.h>
323  #include <io.h>
324 #endif
325 
326 #ifdef __cplusplus
327  #include <exception>
328 #endif
329 
330 #ifdef __has_include
331  #if __has_include(<valgrind.h>)
332  #include <valgrind.h>
333  #endif
334 #endif
335 
336 /* Enable the use of the non-standard keyword __attribute__ to silence warnings under some compilers */
337 #if defined(__GNUC__) || defined(__clang__)
338  #define ACUTEST_ATTRIBUTE_(attr) __attribute__((attr))
339 #else
340  #define ACUTEST_ATTRIBUTE_(attr)
341 #endif
342 
343 /* Note our global private identifiers end with '_' to mitigate risk of clash
344  * with the unit tests implementation. */
345 
346 #ifdef __cplusplus
347  extern "C" {
348 #endif
349 
350 #ifdef _MSC_VER
351  /* In the multi-platform code like ours, we cannot use the non-standard
352  * "safe" functions from Microsoft C lib like e.g. sprintf_s() instead of
353  * standard sprintf(). Hence, lets disable the warning C4996. */
354  #pragma warning(push)
355  #pragma warning(disable: 4996)
356 #endif
357 
358 
360  const char* name;
361  void (*func)(void);
362 };
363 
365 
367  char* msg;
369 };
370 
372  unsigned char flags;
373  double duration;
376 };
377 
378 enum {
382 };
383 
384 extern const struct acutest_test_ acutest_list_[];
385 
386 int acutest_check_(int cond, const char* file, int line, const char* fmt, ...);
387 void acutest_case_(const char* fmt, ...);
388 void acutest_log_(const char* fmt, ...);
389 void acutest_message_(bool always, const char* fmt, ...);
390 void acutest_dump_(bool always, const char* title, const void* addr, size_t size);
391 void acutest_abort_(void) ACUTEST_ATTRIBUTE_(noreturn);
392 
393 
394 #ifndef TEST_NO_MAIN
395 
396 static char* acutest_argv0_ = NULL;
397 static size_t acutest_list_size_ = 0;
399 static size_t acutest_count_ = 0;
400 static int acutest_no_exec_ = -1;
401 static int acutest_no_summary_ = 0;
402 static int acutest_tap_ = 0;
403 static int acutest_skip_mode_ = 0;
404 static int acutest_worker_ = 0;
405 static int acutest_worker_index_ = 0;
406 static int acutest_cond_failed_ = 0;
407 static int acutest_was_aborted_ = 0;
408 static FILE *acutest_xml_output_ = NULL;
409 
411 static int acutest_stat_run_units_ = 0;
412 
413 static const struct acutest_test_* acutest_current_test_ = NULL;
414 static int acutest_current_index_ = 0;
418 static int acutest_verbose_level_ = 2;
419 static int acutest_test_failures_ = 0;
420 static int acutest_colorize_ = 0;
421 static int acutest_timer_ = 0;
422 
424 static jmp_buf acutest_abort_jmp_buf_;
425 
426 #if defined ACUTEST_WIN_
427 HANDLE hChildWrite = NULL;
428 #endif
429 
430 static void
432 {
433  size_t i;
435  acutest_data_log_* next;
436 
437  for (i = 0; i < acutest_count_; i++) {
439  while (log_entry) {
440  next = log_entry->next;
441 #if defined ACUTEST_WIN_
442  if (hChildWrite) {
443  if (!WriteFile(hChildWrite, log_entry->msg, (strlen(log_entry->msg) + 1) * sizeof(char), NULL, NULL))
444  fprintf(stderr, "Upable to write to pipe");
445  }
446 #endif
447  free(log_entry->msg);
448  free(log_entry);
449  log_entry = next;
450  }
451  }
452  free((void*) acutest_test_data_);
453 }
454 
455 static void ACUTEST_ATTRIBUTE_(noreturn)
456 acutest_exit_(int exit_code)
457 {
459  exit(exit_code);
460 }
461 
462 #if defined ACUTEST_WIN_
463  typedef LARGE_INTEGER acutest_timer_type_;
464  static LARGE_INTEGER acutest_timer_freq_;
467 
468  static void
469  acutest_timer_init_(void)
470  {
471  QueryPerformanceFrequency(&acutest_timer_freq_);
472  }
473 
474  static void
475  acutest_timer_get_time_(LARGE_INTEGER* ts)
476  {
477  QueryPerformanceCounter(ts);
478  }
479 
480  static double
481  acutest_timer_diff_(LARGE_INTEGER start, LARGE_INTEGER end)
482  {
483  double duration = (double)(end.QuadPart - start.QuadPart);
484  duration /= (double)acutest_timer_freq_.QuadPart;
485  return duration;
486  }
487 
488  static void
490  {
492  }
493 #elif defined ACUTEST_HAS_POSIX_TIMER_
494  static clockid_t acutest_timer_id_;
495  typedef struct timespec acutest_timer_type_;
498 
499  static void
500  acutest_timer_init_(void)
501  {
502  if(acutest_timer_ == 1)
503  acutest_timer_id_ = CLOCK_MONOTONIC;
504  else if(acutest_timer_ == 2)
505  acutest_timer_id_ = CLOCK_PROCESS_CPUTIME_ID;
506  }
507 
508  static void
509  acutest_timer_get_time_(struct timespec* ts)
510  {
511  clock_gettime(acutest_timer_id_, ts);
512  }
513 
514  static double
515  acutest_timer_diff_(struct timespec start, struct timespec end)
516  {
517  double endns;
518  double startns;
519 
520  endns = end.tv_sec;
521  endns *= 1e9;
522  endns += end.tv_nsec;
523 
524  startns = start.tv_sec;
525  startns *= 1e9;
526  startns += start.tv_nsec;
527 
528  return ((endns - startns)/ 1e9);
529  }
530 
531  static void
533  {
534  printf("%.6lf secs",
536  }
537 #else
538  typedef int acutest_timer_type_;
541 
542  void
544  {}
545 
546  static void
548  {
549  (void) ts;
550  }
551 
552  static double
553  acutest_timer_diff_(int start, int end)
554  {
555  (void) start;
556  (void) end;
557  return 0.0;
558  }
559 
560  static void
562  {}
563 #endif
564 
565 #define ACUTEST_COLOR_DEFAULT_ 0
566 #define ACUTEST_COLOR_GREEN_ 1
567 #define ACUTEST_COLOR_RED_ 2
568 #define ACUTEST_COLOR_DEFAULT_INTENSIVE_ 3
569 #define ACUTEST_COLOR_GREEN_INTENSIVE_ 4
570 #define ACUTEST_COLOR_RED_INTENSIVE_ 5
571 
572 static int ACUTEST_ATTRIBUTE_(format (printf, 2, 3))
573 acutest_colored_printf_(int color, const char* fmt, ...)
574 {
575  va_list args;
576  char buffer[256];
577  int n;
578 
582  buffer[sizeof(buffer)-1] = '\0';
583 
585  return printf("%s", buffer);
586  }
587 
588 #if defined ACUTEST_UNIX_
589  {
590  const char* col_str;
591  switch(color) {
592  case ACUTEST_COLOR_GREEN_: col_str = "\033[0;32m"; break;
593  case ACUTEST_COLOR_RED_: col_str = "\033[0;31m"; break;
594  case ACUTEST_COLOR_GREEN_INTENSIVE_: col_str = "\033[1;32m"; break;
595  case ACUTEST_COLOR_RED_INTENSIVE_: col_str = "\033[1;31m"; break;
596  case ACUTEST_COLOR_DEFAULT_INTENSIVE_: col_str = "\033[1m"; break;
597  default: col_str = "\033[0m"; break;
598  }
599  printf("%s", col_str);
600  n = printf("%s", buffer);
601  printf("\033[0m");
602  return n;
603  }
604 #elif defined ACUTEST_WIN_
605  {
606  HANDLE h;
607  CONSOLE_SCREEN_BUFFER_INFO info;
608  WORD attr;
609 
610  h = GetStdHandle(STD_OUTPUT_HANDLE);
611  GetConsoleScreenBufferInfo(h, &info);
612 
613  switch(color) {
614  case ACUTEST_COLOR_GREEN_: attr = FOREGROUND_GREEN; break;
615  case ACUTEST_COLOR_RED_: attr = FOREGROUND_RED; break;
616  case ACUTEST_COLOR_GREEN_INTENSIVE_: attr = FOREGROUND_GREEN | FOREGROUND_INTENSITY; break;
617  case ACUTEST_COLOR_RED_INTENSIVE_: attr = FOREGROUND_RED | FOREGROUND_INTENSITY; break;
618  case ACUTEST_COLOR_DEFAULT_INTENSIVE_: attr = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY; break;
619  default: attr = 0; break;
620  }
621  if(attr != 0)
622  SetConsoleTextAttribute(h, attr);
623  n = printf("%s", buffer);
624  SetConsoleTextAttribute(h, info.wAttributes);
625  return n;
626  }
627 #else
628  n = printf("%s", buffer);
629  return n;
630 #endif
631 }
632 
633 static void
635 {
636  if(!acutest_tap_) {
637  if(acutest_verbose_level_ >= 3) {
638  acutest_colored_printf_(ACUTEST_COLOR_DEFAULT_INTENSIVE_, "Test %s:\n", test->name);
640  } else if(acutest_verbose_level_ >= 1) {
641  int n;
642  char spaces[48];
643 
644  n = acutest_colored_printf_(ACUTEST_COLOR_DEFAULT_INTENSIVE_, "Test %s... ", test->name);
645  memset(spaces, ' ', sizeof(spaces));
646  if(n < (int) sizeof(spaces))
647  printf("%.*s", (int) sizeof(spaces) - n, spaces);
648  } else {
650  }
651  }
652 }
653 
654 static void
656 {
657  if(acutest_tap_) {
658  const char* str = (result == 0) ? "ok" : "not ok";
659 
660  printf("%s %d - %s\n", str, acutest_current_index_ + 1, acutest_current_test_->name);
661 
662  if(result == 0 && acutest_timer_) {
663  printf("# Duration: ");
665  printf("\n");
666  }
667  } else {
668  int color = (result == 0) ? ACUTEST_COLOR_GREEN_INTENSIVE_ : ACUTEST_COLOR_RED_INTENSIVE_;
669  const char* str = (result == 0) ? "OK" : "FAILED";
670  printf("[ ");
671  acutest_colored_printf_(color, "%s", str);
672  printf(" ]");
673 
674  if(result == 0 && acutest_timer_) {
675  printf(" ");
677  }
678 
679  printf("\n");
680  }
681 }
682 
683 static void
685 {
686  static const char spaces[] = " ";
687  int n = level * 2;
688 
689  if(acutest_tap_ && n > 0) {
690  n--;
691  printf("#");
692  }
693 
694  while(n > 16) {
695  printf("%s", spaces);
696  n -= 16;
697  }
698  printf("%.*s", n, spaces);
699 }
700 
701 int ACUTEST_ATTRIBUTE_(format (printf, 4, 5))
702 acutest_check_(int cond, const char* file, int line, const char* fmt, ...)
703 {
704  const char *result_str;
707 
708  if(cond) {
709  result_str = "ok";
711  verbose_level = 3;
712  } else {
715 
716  result_str = "failed";
718  verbose_level = 2;
721  }
722 
724  va_list args;
725 
728  acutest_colored_printf_(ACUTEST_COLOR_DEFAULT_INTENSIVE_, "Case %s:\n", acutest_case_name_);
731  }
732 
734  if(file != NULL) {
735 #ifdef ACUTEST_WIN_
736  const char* lastsep1 = strrchr(file, '\\');
737  const char* lastsep2 = strrchr(file, '/');
738  if(lastsep1 == NULL)
739  lastsep1 = file-1;
740  if(lastsep2 == NULL)
741  lastsep2 = file-1;
742  file = (lastsep1 > lastsep2 ? lastsep1 : lastsep2) + 1;
743 #else
744  const char* lastsep = strrchr(file, '/');
745  if(lastsep != NULL)
746  file = lastsep+1;
747 #endif
748  printf("%s:%d: Check ", file, line);
749  }
750 
751  va_start(args, fmt);
752  vprintf(fmt, args);
753  va_end(args);
754 
755  printf("... ");
756  acutest_colored_printf_(result_color, "%s", result_str);
757  printf("\n");
759  }
760 
761  acutest_cond_failed_ = (cond == 0);
763 }
764 
765 void ACUTEST_ATTRIBUTE_(format (printf, 1, 2))
766 acutest_log_(const char* fmt, ...)
767 {
768  char buffer[TEST_LOG_MAXSIZE];
770  va_list args;
771 
772  log_entry = (acutest_data_log_*)calloc(1, sizeof(acutest_data_log_));
773  if (log_entry == NULL) {
774  fprintf(stderr, "Out of memory.\n");
775  acutest_exit_(2);
776  }
777 
778  /* This is the first log entry for the current test, set the head */
781 
782  /* There is something already at the tail of the list - append our new entry */
785 
786  /* Set the tail of the list ready for the next append */
788 
789  va_start(args, fmt);
791  va_end(args);
792  buffer[TEST_LOG_MAXSIZE - 1] = '\0';
793 
794  log_entry->msg = (char *)calloc(strlen(buffer) + 1, sizeof(char));
795  if (log_entry->msg == NULL) {
796  fprintf(stderr, "Out of memory.\n");
797  acutest_exit_(2);
798 
799  }
801 }
802 
803 void ACUTEST_ATTRIBUTE_(format (printf, 1, 2))
804 acutest_case_(const char* fmt, ...)
805 {
806  va_list args;
807 
808  if(acutest_verbose_level_ < 2)
809  return;
810 
813  acutest_case_name_[0] = '\0';
814  }
815 
816  if(fmt == NULL)
817  return;
818 
819  va_start(args, fmt);
821  va_end(args);
822  acutest_case_name_[sizeof(acutest_case_name_) - 1] = '\0';
823 
824  if(acutest_verbose_level_ >= 3) {
826  acutest_colored_printf_(ACUTEST_COLOR_DEFAULT_INTENSIVE_, "Case %s:\n", acutest_case_name_);
829  }
830 }
831 
832 void ACUTEST_ATTRIBUTE_(format (printf, 2, 3))
833 acutest_message_(bool always, const char* fmt, ...)
834 {
835  char buffer[TEST_MSG_MAXSIZE];
836  char* line_beg;
837  char* line_end;
838  va_list args;
839 
840  if(acutest_verbose_level_ < 2)
841  return;
842 
843  /* We allow extra message only when something is already wrong in the
844  * current test or always is true. */
845  if((acutest_current_test_ == NULL || !acutest_cond_failed_) && !always)
846  return;
847 
848  va_start(args, fmt);
850  va_end(args);
851  buffer[TEST_MSG_MAXSIZE-1] = '\0';
852 
853  acutest_log_("%s", buffer); /* Add the message to the log */
854 
855  line_beg = buffer;
856  while(1) {
857  line_end = strchr(line_beg, '\n');
858  if(line_end == NULL)
859  break;
861  printf("%.*s\n", (int)(line_end - line_beg), line_beg);
862  line_beg = line_end + 1;
863  }
864  if(line_beg[0] != '\0') {
866  printf("%s\n", line_beg);
867  }
868 }
869 
870 void
871 acutest_dump_(bool always, const char* title, const void* addr, size_t size)
872 {
873  static const size_t BYTES_PER_LINE = 16;
874  size_t line_beg;
875  size_t truncate = 0;
876  size_t buflen = (size * 3) + strlen(title) + 2;
877  char* buffer;
878  char* p;
879  char* end;
880 
881  if(acutest_verbose_level_ < 2)
882  return;
883 
884  /* We allow extra message only when something is already wrong in the
885  * current test or always is true. */
886  if((acutest_current_test_ == NULL || !acutest_cond_failed_) && !always)
887  return;
888 
889  if(size > TEST_DUMP_MAXSIZE) {
890  truncate = size - TEST_DUMP_MAXSIZE;
891  size = TEST_DUMP_MAXSIZE;
892  }
893 
894  /* Allocate space for log copy of dump */
895  buffer = (char *)calloc(buflen, sizeof(char));
896  end = buffer + buflen;
897 
899  printf((title[strlen(title)-1] == ':') ? "%s\n" : "%s:\n", title);
900 
901  strcpy(buffer, title);
902  p = buffer + strlen(title);
903  if (title[strlen(title) - 1] != ':') {
904  *p = ':';
905  p++;
906  }
907 
908  for(line_beg = 0; line_beg < size; line_beg += BYTES_PER_LINE) {
909  size_t line_end = line_beg + BYTES_PER_LINE;
910  size_t off;
911 
913  printf("%08lx: ", (unsigned long)line_beg);
914  for(off = line_beg; off < line_end; off++) {
915  if(off < size) {
916  printf(" %02x", ((const unsigned char*)addr)[off]);
917  snprintf(p, end - p, " %02x", ((const unsigned char*)addr)[off]);
918  p += 3;
919  } else
920  printf(" ");
921  }
922 
923  printf(" ");
924  for(off = line_beg; off < line_end; off++) {
925  unsigned char byte = ((const unsigned char*)addr)[off];
926  if(off < size)
927  printf("%c", (iscntrl(byte) ? '.' : byte));
928  else
929  break;
930  }
931 
932  printf("\n");
933  }
934 
935  if(truncate > 0) {
937  printf(" ... (and more %u bytes)\n", (unsigned) truncate);
938  }
939 
940  acutest_log_("%s", buffer);
941  free(buffer);
942 }
943 
944 /* This is called just before each test */
945 static void
946 acutest_init_(const char *test_name)
947 {
948 #ifdef TEST_INIT
949  TEST_INIT
950  ; /* Allow for a single unterminated function call */
951 #endif
952 
953  /* Suppress any warnings about unused variable. */
954  (void) test_name;
955 }
956 
957 /* This is called after each test */
958 static void
959 acutest_fini_(const char *test_name)
960 {
961 #ifdef TEST_FINI
962  TEST_FINI
963  ; /* Allow for a single unterminated function call */
964 #endif
965 
966  /* Suppress any warnings about unused variable. */
967  (void) test_name;
968 }
969 
970 void
972 {
974  longjmp(acutest_abort_jmp_buf_, 1);
975  } else {
976  if(acutest_current_test_ != NULL)
978  abort();
979  }
980 }
981 
982 static void
984 {
985  const struct acutest_test_* test;
986 
987  printf("Unit tests:\n");
988  for(test = &acutest_list_[0]; test->func != NULL; test++)
989  printf(" %s\n", test->name);
990 }
991 
992 static void
994 {
996  return;
997 
999  acutest_count_++;
1000 }
1001 
1002 static void
1004 {
1006 }
1007 
1008 static void
1009 acutest_set_duration_(int i, double duration)
1010 {
1011  acutest_test_data_[i].duration = duration;
1012 }
1013 
1014 static int
1015 acutest_name_contains_word_(const char* name, const char* pattern)
1016 {
1017  static const char word_delim[] = " \t-_/.,:;";
1018  const char* substr;
1019  size_t pattern_len;
1020 
1021  pattern_len = strlen(pattern);
1022 
1023  substr = strstr(name, pattern);
1024  while(substr != NULL) {
1025  int starts_on_word_boundary = (substr == name || strchr(word_delim, substr[-1]) != NULL);
1026  int ends_on_word_boundary = (substr[pattern_len] == '\0' || strchr(word_delim, substr[pattern_len]) != NULL);
1027 
1028  if(starts_on_word_boundary && ends_on_word_boundary)
1029  return 1;
1030 
1031  substr = strstr(substr+1, pattern);
1032  }
1033 
1034  return 0;
1035 }
1036 
1037 static int
1038 acutest_lookup_(const char* pattern)
1039 {
1040  int i;
1041  int n = 0;
1042 
1043  /* Try exact match. */
1044  for(i = 0; i < (int) acutest_list_size_; i++) {
1045  if(strcmp(acutest_list_[i].name, pattern) == 0) {
1046  acutest_remember_(i);
1047  n++;
1048  break;
1049  }
1050  }
1051  if(n > 0)
1052  return n;
1053 
1054  /* Try word match. */
1055  for(i = 0; i < (int) acutest_list_size_; i++) {
1057  acutest_remember_(i);
1058  n++;
1059  }
1060  }
1061  if(n > 0)
1062  return n;
1063 
1064  /* Try relaxed match. */
1065  for(i = 0; i < (int) acutest_list_size_; i++) {
1066  if(strstr(acutest_list_[i].name, pattern) != NULL) {
1067  acutest_remember_(i);
1068  n++;
1069  }
1070  }
1071 
1072  return n;
1073 }
1074 
1075 
1076 /* Called if anything goes bad in Acutest, or if the unit test ends in other
1077  * way then by normal returning from its function (e.g. exception or some
1078  * abnormal child process termination). */
1079 static void ACUTEST_ATTRIBUTE_(format (printf, 1, 2))
1080 acutest_error_(const char* fmt, ...)
1081 {
1082  if(acutest_verbose_level_ == 0)
1083  return;
1084 
1085  if(acutest_verbose_level_ >= 2) {
1086  va_list args;
1087 
1089  if(acutest_verbose_level_ >= 3)
1090  acutest_colored_printf_(ACUTEST_COLOR_RED_INTENSIVE_, "ERROR: ");
1091  va_start(args, fmt);
1092  vprintf(fmt, args);
1093  va_end(args);
1094  printf("\n");
1095  }
1096 
1097  if(acutest_verbose_level_ >= 3) {
1098  printf("\n");
1099  }
1100 }
1101 
1102 /* Call directly the given test unit function. */
1103 static int
1104 acutest_do_run_(const struct acutest_test_* test, int index)
1105 {
1106  int status = -1;
1107 
1109  acutest_current_test_ = test;
1110  acutest_current_index_ = index;
1114 
1115 #ifdef __cplusplus
1116  try {
1117 #endif
1118  acutest_init_(test->name);
1120 
1121  /* This is good to do in case the test unit crashes. */
1122  fflush(stdout);
1123  fflush(stderr);
1124 
1125  if(!acutest_worker_) {
1127  if(setjmp(acutest_abort_jmp_buf_) != 0) {
1129  goto aborted;
1130  }
1131  }
1132 
1134  test->func();
1135 aborted:
1138 
1139  if(acutest_verbose_level_ >= 3) {
1141  if(acutest_test_failures_ == 0) {
1142  acutest_colored_printf_(ACUTEST_COLOR_GREEN_INTENSIVE_, "SUCCESS: ");
1143  printf("All conditions have passed.\n");
1144 
1145  if(acutest_timer_) {
1147  printf("Duration: ");
1149  printf("\n");
1150  }
1151  } else {
1152  acutest_colored_printf_(ACUTEST_COLOR_RED_INTENSIVE_, "FAILED: ");
1153  if(!acutest_was_aborted_) {
1154  printf("%d condition%s %s failed.\n",
1156  (acutest_test_failures_ == 1) ? "" : "s",
1157  (acutest_test_failures_ == 1) ? "has" : "have");
1158  } else {
1159  printf("Aborted.\n");
1160  }
1161  }
1162  printf("\n");
1163  } else if(acutest_verbose_level_ >= 1 && acutest_test_failures_ == 0) {
1165  }
1166 
1167  status = (acutest_test_failures_ == 0) ? 0 : -1;
1168 
1169 #ifdef __cplusplus
1170  } catch(std::exception& e) {
1171  const char* what = e.what();
1172  acutest_check_(0, NULL, 0, "Threw std::exception");
1173  if(what != NULL)
1174  acutest_message_(false, "std::exception::what(): %s", what);
1175 
1176  if(acutest_verbose_level_ >= 3) {
1178  acutest_colored_printf_(ACUTEST_COLOR_RED_INTENSIVE_, "FAILED: ");
1179  printf("C++ exception.\n\n");
1180  }
1181  } catch(...) {
1182  acutest_check_(0, NULL, 0, "Threw an exception");
1183 
1184  if(acutest_verbose_level_ >= 3) {
1186  acutest_colored_printf_(ACUTEST_COLOR_RED_INTENSIVE_, "FAILED: ");
1187  printf("C++ exception.\n\n");
1188  }
1189  }
1190 #endif
1191 
1192  acutest_fini_(test->name);
1193  acutest_case_(NULL);
1194  acutest_current_test_ = NULL;
1195 
1196  return status;
1197 }
1198 
1199 /* Trigger the unit test. If possible (and not suppressed) it starts a child
1200  * process who calls acutest_do_run_(), otherwise it calls acutest_do_run_()
1201  * directly. */
1202 static void
1203 acutest_run_(const struct acutest_test_* test, int index, int master_index)
1204 {
1205  int failed = 1;
1206  acutest_timer_type_ start, end;
1207 
1208  acutest_current_test_ = test;
1210  acutest_timer_get_time_(&start);
1211 
1212  if(!acutest_no_exec_) {
1213 
1214 #if defined(ACUTEST_UNIX_)
1215 
1216  pid_t pid;
1217  int exit_code;
1218  int fd[2];
1219  char msg[TEST_LOG_MAXSIZE];
1220  char *p;
1221  size_t count;
1222 
1223  /* Make sure the child starts with empty I/O buffers. */
1224  fflush(stdout);
1225  fflush(stderr);
1226 
1227  if (pipe(fd) == -1) {
1228  fprintf(stderr, "Unable to create pipe.\n");
1229  acutest_exit_(2);
1230  }
1231 
1232  pid = fork();
1233  if(pid == (pid_t)-1) {
1234  acutest_error_("Cannot fork. %s [%d]", strerror(errno), errno);
1235  failed = 1;
1236  } else if(pid == 0) {
1237  /* Child: Do the test. */
1239  close(fd[0]); /* Child only uses the write pipe, close the read one */
1240  acutest_worker_ = 1;
1241  failed = (acutest_do_run_(test, index) != 0);
1242 
1243  /* Write any log messages to the pipe.
1244  * Send each log entry as a null terminated string */
1246  while (log_entry) {
1247  if (write(fd[1], log_entry->msg, (strlen(log_entry->msg) + 1) * sizeof(char)) == -1) {
1248  fprintf(stderr, "Unable to write to pipe\n");
1249  acutest_exit_(2);
1250  }
1252  }
1253  close(fd[1]);
1254  acutest_exit_(failed ? 1 : 0);
1255  } else {
1256  close(fd[1]); /* Parent only uses the read pipe, close the write one */
1257  /* Parent: Wait until child terminates and analyze its exit code. */
1258  waitpid(pid, &exit_code, 0);
1259  if(WIFEXITED(exit_code)) {
1260  switch(WEXITSTATUS(exit_code)) {
1261  case 0: failed = 0; break; /* test has passed. */
1262  case 1: /* noop */ break; /* "normal" failure. */
1263  default: acutest_error_("Unexpected exit code [%d]", WEXITSTATUS(exit_code));
1264  }
1265  } else if(WIFSIGNALED(exit_code)) {
1266  char tmp[32];
1267  const char* signame;
1268  switch(WTERMSIG(exit_code)) {
1269  case SIGINT: signame = "SIGINT"; break;
1270  case SIGHUP: signame = "SIGHUP"; break;
1271  case SIGQUIT: signame = "SIGQUIT"; break;
1272  case SIGABRT: signame = "SIGABRT"; break;
1273  case SIGKILL: signame = "SIGKILL"; break;
1274  case SIGSEGV: signame = "SIGSEGV"; break;
1275  case SIGILL: signame = "SIGILL"; break;
1276  case SIGTERM: signame = "SIGTERM"; break;
1277  default: snprintf(tmp, sizeof(tmp), "signal %d", WTERMSIG(exit_code)); signame = tmp; break;
1278  }
1279  acutest_error_("Test interrupted by %s.", signame);
1280  } else {
1281  acutest_error_("Test ended in an unexpected way [%d].", exit_code);
1282  }
1283 
1284  /* Read log messages from the child, one character at a time to
1285  * find the NULLs, then re-create the log entries in the parent */
1286  p = msg;
1287  count = 0;
1288  acutest_current_index_ = index; /* acutest_log_() needs this set to know which entry to populate */
1289  while (read(fd[0], p, sizeof(char))) {
1290  if (*p == '\0') { /* Found a NULL terminator */
1291  acutest_log_("%s", msg); /* Create parent log entry */
1292  p = msg; /* reset pointer */
1293  count = 0;
1294  } else {
1295  p++;
1296  count++;
1297  }
1298  if (count >= TEST_LOG_MAXSIZE) {
1299  fprintf(stderr, "Log message from child too large");
1300  acutest_exit_(2);
1301  }
1302  }
1303  close(fd[0]);
1304  }
1305 
1306 #elif defined(ACUTEST_WIN_)
1307 
1308  char buffer[512] = {0};
1309  STARTUPINFOA startupInfo;
1310  PROCESS_INFORMATION processInfo;
1311  DWORD exitCode;
1312  HANDLE hRead = NULL;
1313  HANDLE hWrite = NULL;
1314  SECURITY_ATTRIBUTES lpPipeAttribute;
1315  lpPipeAttribute.nLength = sizeof(lpPipeAttribute);
1316  lpPipeAttribute.lpSecurityDescriptor = NULL;
1317  lpPipeAttribute.bInheritHandle = TRUE;
1318  char* p;
1319  char msg[TEST_LOG_MAXSIZE];
1320  size_t count;
1321 
1322  /* Create pipe for receiving log entries */
1323  if (!CreatePipe(&hRead, &hWrite, &lpPipeAttribute, 0)) {
1324  fprintf(stderr, "Error creating pipe\n");
1325  acutest_exit_(2);
1326  }
1327 
1328  /* Windows has no fork(). So we propagate all info into the child
1329  * through a command line arguments. */
1330  _snprintf(buffer, sizeof(buffer)-1,
1331  "%s --worker=%d %s --no-exec --no-summary %s --verbose=%d --color=%s --pipe=%I64d -- \"%s\"",
1332  acutest_argv0_, index, acutest_timer_ ? "--time" : "",
1333  acutest_tap_ ? "--tap" : "", acutest_verbose_level_,
1334  acutest_colorize_ ? "always" : "never", (ULONG64)(ULONG_PTR)hWrite,
1335  test->name);
1336  memset(&startupInfo, 0, sizeof(startupInfo));
1337  startupInfo.cb = sizeof(STARTUPINFO);
1338  if(CreateProcessA(NULL, buffer, NULL, NULL, TRUE, 0, NULL, NULL, &startupInfo, &processInfo)) {
1339  WaitForSingleObject(processInfo.hProcess, INFINITE);
1340  GetExitCodeProcess(processInfo.hProcess, &exitCode);
1341  CloseHandle(processInfo.hThread);
1342  CloseHandle(processInfo.hProcess);
1343 
1344  /* Read log messages from the child, one character at a time to
1345  * find the NULLs, then re-create the log entries in the parent */
1346  p = msg;
1347  count = 0;
1348  acutest_current_index_ = index; /* acutest_log_() needs this set to know which entry to populate */
1349  while (ReadFile(hRead, p, sizeof(char), NULL, NULL)) {
1350  if (*p == '\0') { /* Found a NULL terminator */
1351  acutest_log_("%s", msg); /* Create parent log entry */
1352  p = msg; /* reset pointer */
1353  count = 0;
1354  }
1355  else {
1356  p++;
1357  count++;
1358  }
1359  if (count >= TEST_MSG_MAXSIZE) {
1360  fprintf(stderr, "Log message from child too large");
1361  acutest_exit_(2);
1362  }
1363  }
1364 
1365  CloseHandle(hRead);
1366  CloseHandle(hWrite);
1367  failed = (exitCode != 0);
1368  if(exitCode > 1) {
1369  switch(exitCode) {
1370  case 3: acutest_error_("Aborted."); break;
1371  case 0xC0000005: acutest_error_("Access violation."); break;
1372  default: acutest_error_("Test ended in an unexpected way [%lu].", exitCode); break;
1373  }
1374  }
1375  } else {
1376  acutest_error_("Cannot create unit test subprocess [%ld].", GetLastError());
1377  failed = 1;
1378  }
1379 
1380 #else
1381 
1382  /* A platform where we don't know how to run child process. */
1383  failed = (acutest_do_run_(test, index) != 0);
1384 
1385 #endif
1386 
1387  } else {
1388  /* Child processes suppressed through --no-exec. */
1389  failed = (acutest_do_run_(test, index) != 0);
1390  }
1392 
1393  acutest_current_test_ = NULL;
1394 
1396  if(failed)
1398 
1399  acutest_set_success_(master_index, !failed);
1400  acutest_set_duration_(master_index, acutest_timer_diff_(start, end));
1401 }
1402 
1403 #if defined(ACUTEST_WIN_)
1404 /* Callback for SEH events. */
1405 static LONG CALLBACK
1406 acutest_seh_exception_filter_(EXCEPTION_POINTERS *ptrs)
1407 {
1408  acutest_check_(0, NULL, 0, "Unhandled SEH exception");
1409  acutest_message_(false, "Exception code: 0x%08lx", ptrs->ExceptionRecord->ExceptionCode);
1410  acutest_message_(false, "Exception address: 0x%p", ptrs->ExceptionRecord->ExceptionAddress);
1411 
1412  fflush(stdout);
1413  fflush(stderr);
1414 
1415  return EXCEPTION_EXECUTE_HANDLER;
1416 }
1417 #endif
1418 
1419 
1420 #define ACUTEST_CMDLINE_OPTFLAG_OPTIONALARG_ 0x0001
1421 #define ACUTEST_CMDLINE_OPTFLAG_REQUIREDARG_ 0x0002
1422 
1423 #define ACUTEST_CMDLINE_OPTID_NONE_ 0
1424 #define ACUTEST_CMDLINE_OPTID_UNKNOWN_ (-0x7fffffff + 0)
1425 #define ACUTEST_CMDLINE_OPTID_MISSINGARG_ (-0x7fffffff + 1)
1426 #define ACUTEST_CMDLINE_OPTID_BOGUSARG_ (-0x7fffffff + 2)
1427 
1430  const char* longname;
1431  int id;
1432  unsigned flags;
1434 
1435 static int
1437  const char* arggroup,
1438  int (*callback)(int /*optval*/, const char* /*arg*/))
1439 {
1440  const ACUTEST_CMDLINE_OPTION_* opt;
1441  int i;
1442  int ret = 0;
1443 
1444  for(i = 0; arggroup[i] != '\0'; i++) {
1445  for(opt = options; opt->id != 0; opt++) {
1446  if(arggroup[i] == opt->shortname)
1447  break;
1448  }
1449 
1450  if(opt->id != 0 && !(opt->flags & ACUTEST_CMDLINE_OPTFLAG_REQUIREDARG_)) {
1451  ret = callback(opt->id, NULL);
1452  } else {
1453  /* Unknown option. */
1454  char badoptname[3];
1455  badoptname[0] = '-';
1456  badoptname[1] = arggroup[i];
1457  badoptname[2] = '\0';
1459  badoptname);
1460  }
1461 
1462  if(ret != 0)
1463  break;
1464  }
1465 
1466  return ret;
1467 }
1468 
1469 #define ACUTEST_CMDLINE_AUXBUF_SIZE_ 32
1470 
1471 static int
1472 acutest_cmdline_read_(const ACUTEST_CMDLINE_OPTION_* options, int argc, char** argv,
1473  int (*callback)(int /*optval*/, const char* /*arg*/))
1474 {
1475 
1476  const ACUTEST_CMDLINE_OPTION_* opt;
1477  char auxbuf[ACUTEST_CMDLINE_AUXBUF_SIZE_+1];
1478  int after_doubledash = 0;
1479  int i = 1;
1480  int ret = 0;
1481 
1482  auxbuf[ACUTEST_CMDLINE_AUXBUF_SIZE_] = '\0';
1483 
1484  while(i < argc) {
1485  if(after_doubledash || strcmp(argv[i], "-") == 0) {
1486  /* Non-option argument. */
1487  ret = callback(ACUTEST_CMDLINE_OPTID_NONE_, argv[i]);
1488  } else if(strcmp(argv[i], "--") == 0) {
1489  /* End of options. All the remaining members are non-option arguments. */
1490  after_doubledash = 1;
1491  } else if(argv[i][0] != '-') {
1492  /* Non-option argument. */
1493  ret = callback(ACUTEST_CMDLINE_OPTID_NONE_, argv[i]);
1494  } else {
1495  for(opt = options; opt->id != 0; opt++) {
1496  if(opt->longname != NULL && strncmp(argv[i], "--", 2) == 0) {
1497  size_t len = strlen(opt->longname);
1498  if(strncmp(argv[i]+2, opt->longname, len) == 0) {
1499  /* Regular long option. */
1500  if(argv[i][2+len] == '\0') {
1501  /* with no argument provided. */
1503  ret = callback(opt->id, NULL);
1504  else
1505  ret = callback(ACUTEST_CMDLINE_OPTID_MISSINGARG_, argv[i]);
1506  break;
1507  } else if(argv[i][2+len] == '=') {
1508  /* with an argument provided. */
1510  ret = callback(opt->id, argv[i]+2+len+1);
1511  } else {
1512  snprintf(auxbuf, sizeof(auxbuf), "--%s", opt->longname);
1513  ret = callback(ACUTEST_CMDLINE_OPTID_BOGUSARG_, auxbuf);
1514  }
1515  break;
1516  } else {
1517  continue;
1518  }
1519  }
1520  } else if(opt->shortname != '\0' && argv[i][0] == '-') {
1521  if(argv[i][1] == opt->shortname) {
1522  /* Regular short option. */
1524  if(argv[i][2] != '\0')
1525  ret = callback(opt->id, argv[i]+2);
1526  else if(i+1 < argc)
1527  ret = callback(opt->id, argv[++i]);
1528  else
1529  ret = callback(ACUTEST_CMDLINE_OPTID_MISSINGARG_, argv[i]);
1530  break;
1531  } else {
1532  ret = callback(opt->id, NULL);
1533 
1534  /* There might be more (argument-less) short options
1535  * grouped together. */
1536  if(ret == 0 && argv[i][2] != '\0')
1537  ret = acutest_cmdline_handle_short_opt_group_(options, argv[i]+2, callback);
1538  break;
1539  }
1540  }
1541  }
1542  }
1543 
1544  if(opt->id == 0) { /* still not handled? */
1545  if(argv[i][0] != '-') {
1546  /* Non-option argument. */
1547  ret = callback(ACUTEST_CMDLINE_OPTID_NONE_, argv[i]);
1548  } else {
1549  /* Unknown option. */
1550  char* badoptname = argv[i];
1551 
1552  if(strncmp(badoptname, "--", 2) == 0) {
1553  /* Strip any argument from the long option. */
1554  char* assignment = strchr(badoptname, '=');
1555  if(assignment != NULL) {
1556  size_t len = assignment - badoptname;
1559  strncpy(auxbuf, badoptname, len);
1560  auxbuf[len] = '\0';
1561  badoptname = auxbuf;
1562  }
1563  }
1564 
1565  ret = callback(ACUTEST_CMDLINE_OPTID_UNKNOWN_, badoptname);
1566  }
1567  }
1568  }
1569 
1570  if(ret != 0)
1571  return ret;
1572  i++;
1573  }
1574 
1575  return ret;
1576 }
1577 
1578 static void
1580 {
1581  printf("Usage: %s [options] [test...]\n", acutest_argv0_);
1582  printf("\n");
1583  printf("Run the specified unit tests; or if the option '--skip' is used, run all\n");
1584  printf("tests in the suite but those listed. By default, if no tests are specified\n");
1585  printf("on the command line, all unit tests in the suite are run.\n");
1586  printf("\n");
1587  printf("Options:\n");
1588  printf(" -s, --skip Execute all unit tests but the listed ones\n");
1589  printf(" --exec[=WHEN] If supported, execute unit tests as child processes\n");
1590  printf(" (WHEN is one of 'auto', 'always', 'never')\n");
1591  printf(" -E, --no-exec Same as --exec=never\n");
1592 #if defined ACUTEST_WIN_
1593  printf(" -t, --time Measure test duration\n");
1594 #elif defined ACUTEST_HAS_POSIX_TIMER_
1595  printf(" -t, --time Measure test duration (real time)\n");
1596  printf(" --time=TIMER Measure test duration, using given timer\n");
1597  printf(" (TIMER is one of 'real', 'cpu')\n");
1598 #endif
1599  printf(" --no-summary Suppress printing of test results summary\n");
1600  printf(" --tap Produce TAP-compliant output\n");
1601  printf(" (See https://testanything.org/)\n");
1602  printf(" -x, --xml-output=FILE Enable XUnit output to the given file\n");
1603  printf(" -l, --list List unit tests in the suite and exit\n");
1604  printf(" -v, --verbose Make output more verbose\n");
1605  printf(" --verbose=LEVEL Set verbose level to LEVEL:\n");
1606  printf(" 0 ... Be silent\n");
1607  printf(" 1 ... Output one line per test (and summary)\n");
1608  printf(" 2 ... As 1 and failed conditions (this is default)\n");
1609  printf(" 3 ... As 1 and all conditions (and extended summary)\n");
1610  printf(" -q, --quiet Same as --verbose=0\n");
1611  printf(" --color[=WHEN] Enable colorized output\n");
1612  printf(" (WHEN is one of 'auto', 'always', 'never')\n");
1613  printf(" --no-color Same as --color=never\n");
1614  printf(" -h, --help Display this help and exit\n");
1615 
1616  if(acutest_list_size_ < 16) {
1617  printf("\n");
1619  }
1620 }
1621 
1623  { 's', "skip", 's', 0 },
1624  { 0, "exec", 'e', ACUTEST_CMDLINE_OPTFLAG_OPTIONALARG_ },
1625  { 'E', "no-exec", 'E', 0 },
1626 #if defined ACUTEST_WIN_
1627  { 't', "time", 't', 0 },
1628  { 0, "timer", 't', 0 }, /* kept for compatibility */
1629  { 0, "pipe", 'p', ACUTEST_CMDLINE_OPTFLAG_REQUIREDARG_}, /* internal */
1630 #elif defined ACUTEST_HAS_POSIX_TIMER_
1631  { 't', "time", 't', ACUTEST_CMDLINE_OPTFLAG_OPTIONALARG_ },
1632  { 0, "timer", 't', ACUTEST_CMDLINE_OPTFLAG_OPTIONALARG_ }, /* kept for compatibility */
1633 #endif
1634  { 0, "no-summary", 'S', 0 },
1635  { 0, "tap", 'T', 0 },
1636  { 'l', "list", 'l', 0 },
1637  { 'v', "verbose", 'v', ACUTEST_CMDLINE_OPTFLAG_OPTIONALARG_ },
1638  { 'q', "quiet", 'q', 0 },
1639  { 0, "color", 'c', ACUTEST_CMDLINE_OPTFLAG_OPTIONALARG_ },
1640  { 0, "no-color", 'C', 0 },
1641  { 'h', "help", 'h', 0 },
1642  { 0, "worker", 'w', ACUTEST_CMDLINE_OPTFLAG_REQUIREDARG_ }, /* internal */
1643  { 'x', "xml-output", 'x', ACUTEST_CMDLINE_OPTFLAG_REQUIREDARG_ },
1644  { 0, NULL, 0, 0 }
1645 };
1646 
1647 static int
1648 acutest_cmdline_callback_(int id, const char* arg)
1649 {
1650  switch(id) {
1651  case 's':
1652  acutest_skip_mode_ = 1;
1653  break;
1654 
1655  case 'e':
1656  if(arg == NULL || strcmp(arg, "always") == 0) {
1657  acutest_no_exec_ = 0;
1658  } else if(strcmp(arg, "never") == 0) {
1659  acutest_no_exec_ = 1;
1660  } else if(strcmp(arg, "auto") == 0) {
1661  /*noop*/
1662  } else {
1663  fprintf(stderr, "%s: Unrecognized argument '%s' for option --exec.\n", acutest_argv0_, arg);
1664  fprintf(stderr, "Try '%s --help' for more information.\n", acutest_argv0_);
1665  acutest_exit_(2);
1666  }
1667  break;
1668 
1669  case 'E':
1670  acutest_no_exec_ = 1;
1671  break;
1672 
1673  case 't':
1674 #if defined ACUTEST_WIN_ || defined ACUTEST_HAS_POSIX_TIMER_
1675  if(arg == NULL || strcmp(arg, "real") == 0) {
1676  acutest_timer_ = 1;
1677  #ifndef ACUTEST_WIN_
1678  } else if(strcmp(arg, "cpu") == 0) {
1679  acutest_timer_ = 2;
1680  #endif
1681  } else {
1682  fprintf(stderr, "%s: Unrecognized argument '%s' for option --time.\n", acutest_argv0_, arg);
1683  fprintf(stderr, "Try '%s --help' for more information.\n", acutest_argv0_);
1684  acutest_exit_(2);
1685  }
1686 #endif
1687  break;
1688 
1689  case 'S':
1690  acutest_no_summary_ = 1;
1691  break;
1692 
1693  case 'T':
1694  acutest_tap_ = 1;
1695  break;
1696 
1697  case 'l':
1699  acutest_exit_(0);
1700  break;
1701 
1702  case 'v':
1703  acutest_verbose_level_ = (arg != NULL ? atoi(arg) : acutest_verbose_level_+1);
1704  break;
1705 
1706 #if defined ACUTEST_WIN_
1707  case 'p':
1708  hChildWrite = (HANDLE)(ULONG_PTR)_atoi64(arg);
1709  break;
1710 #endif
1711  case 'q':
1713  break;
1714 
1715  case 'c':
1716  if(arg == NULL || strcmp(arg, "always") == 0) {
1717  acutest_colorize_ = 1;
1718  } else if(strcmp(arg, "never") == 0) {
1719  acutest_colorize_ = 0;
1720  } else if(strcmp(arg, "auto") == 0) {
1721  /*noop*/
1722  } else {
1723  fprintf(stderr, "%s: Unrecognized argument '%s' for option --color.\n", acutest_argv0_, arg);
1724  fprintf(stderr, "Try '%s --help' for more information.\n", acutest_argv0_);
1725  acutest_exit_(2);
1726  }
1727  break;
1728 
1729  case 'C':
1730  acutest_colorize_ = 0;
1731  break;
1732 
1733  case 'h':
1734  acutest_help_();
1735  acutest_exit_(0);
1736  break;
1737 
1738  case 'w':
1739  acutest_worker_ = 1;
1740  acutest_worker_index_ = atoi(arg);
1741  break;
1742  case 'x':
1743  acutest_xml_output_ = fopen(arg, "w");
1744  if (!acutest_xml_output_) {
1745  fprintf(stderr, "Unable to open '%s': %s\n", arg, strerror(errno));
1746  acutest_exit_(2);
1747  }
1748  break;
1749 
1750  case 0:
1751  if(acutest_lookup_(arg) == 0) {
1752  fprintf(stderr, "%s: Unrecognized unit test '%s'\n", acutest_argv0_, arg);
1753  fprintf(stderr, "Try '%s --list' for list of unit tests.\n", acutest_argv0_);
1754  acutest_exit_(2);
1755  }
1756  break;
1757 
1759  fprintf(stderr, "Unrecognized command line option '%s'.\n", arg);
1760  fprintf(stderr, "Try '%s --help' for more information.\n", acutest_argv0_);
1761  acutest_exit_(2);
1762  break;
1763 
1765  fprintf(stderr, "The command line option '%s' requires an argument.\n", arg);
1766  fprintf(stderr, "Try '%s --help' for more information.\n", acutest_argv0_);
1767  acutest_exit_(2);
1768  break;
1769 
1771  fprintf(stderr, "The command line option '%s' does not expect an argument.\n", arg);
1772  fprintf(stderr, "Try '%s --help' for more information.\n", acutest_argv0_);
1773  acutest_exit_(2);
1774  break;
1775  }
1776 
1777  return 0;
1778 }
1779 
1780 
1781 #ifdef ACUTEST_LINUX_
1782 static int
1783 acutest_is_tracer_present_(void)
1784 {
1785  /* Must be large enough so the line 'TracerPid: ${PID}' can fit in. */
1786  static const int OVERLAP = 32;
1787 
1788  char buf[256+OVERLAP+1];
1789  int tracer_present = 0;
1790  int fd;
1791  size_t n_read = 0;
1792 
1793  fd = open("/proc/self/status", O_RDONLY);
1794  if(fd == -1)
1795  return 0;
1796 
1797  while(1) {
1798  static const char pattern[] = "TracerPid:";
1799  const char* field;
1800 
1801  while(n_read < sizeof(buf) - 1) {
1802  ssize_t n;
1803 
1804  n = read(fd, buf + n_read, sizeof(buf) - 1 - n_read);
1805  if(n <= 0)
1806  break;
1807  n_read += n;
1808  }
1809  buf[n_read] = '\0';
1810 
1811  field = strstr(buf, pattern);
1812  if(field != NULL && field < buf + sizeof(buf) - OVERLAP) {
1813  pid_t tracer_pid = (pid_t) atoi(field + sizeof(pattern) - 1);
1814  tracer_present = (tracer_pid != 0);
1815  break;
1816  }
1817 
1818  if(n_read == sizeof(buf)-1) {
1819  memmove(buf, buf + sizeof(buf)-1 - OVERLAP, OVERLAP);
1820  n_read = OVERLAP;
1821  } else {
1822  break;
1823  }
1824  }
1825 
1826  close(fd);
1827  return tracer_present;
1828 }
1829 #endif
1830 
1831 int
1832 main(int argc, char** argv)
1833 {
1834  int i;
1835  int index;
1836 
1837  acutest_argv0_ = argv[0];
1838 
1839 #if defined ACUTEST_UNIX_
1840  acutest_colorize_ = isatty(STDOUT_FILENO);
1841 #elif defined ACUTEST_WIN_
1842  #if defined _BORLANDC_
1843  acutest_colorize_ = isatty(_fileno(stdout));
1844  #else
1845  acutest_colorize_ = _isatty(_fileno(stdout));
1846  #endif
1847 #else
1848  acutest_colorize_ = 0;
1849 #endif
1850 
1851  /* Count all test units */
1852  acutest_list_size_ = 0;
1853  for(i = 0; acutest_list_[i].func != NULL; i++)
1855 
1857  if(acutest_test_data_ == NULL) {
1858  fprintf(stderr, "Out of memory.\n");
1859  acutest_exit_(2);
1860  }
1861 
1862  /* Parse options */
1864 
1865  /* Initialize the proper timer. */
1867 
1868 #if defined(ACUTEST_WIN_)
1869  SetUnhandledExceptionFilter(acutest_seh_exception_filter_);
1870 #ifdef _MSC_VER
1871  _set_abort_behavior(0, _WRITE_ABORT_MSG);
1872 #endif
1873 #endif
1874 
1875  /* By default, we want to run all tests. */
1876  if(acutest_count_ == 0) {
1877  for(i = 0; acutest_list_[i].func != NULL; i++)
1878  acutest_remember_(i);
1879  }
1880 
1881  /* Guess whether we want to run unit tests as child processes. */
1882  if(acutest_no_exec_ < 0) {
1883  acutest_no_exec_ = 0;
1884 
1885  if(acutest_count_ <= 1) {
1886  acutest_no_exec_ = 1;
1887  } else {
1888 #ifdef ACUTEST_WIN_
1889  if(IsDebuggerPresent())
1890  acutest_no_exec_ = 1;
1891 #endif
1892 #ifdef ACUTEST_LINUX_
1893  if(acutest_is_tracer_present_())
1894  acutest_no_exec_ = 1;
1895 #endif
1896 #ifdef RUNNING_ON_VALGRIND
1897  /* RUNNING_ON_VALGRIND is provided by optionally included <valgrind.h> */
1899  acutest_no_exec_ = 1;
1900 #endif
1901  }
1902  }
1903 
1904  if(acutest_tap_) {
1905  /* TAP requires we know test result ("ok", "not ok") before we output
1906  * anything about the test, and this gets problematic for larger verbose
1907  * levels. */
1908  if(acutest_verbose_level_ > 2)
1910 
1911  /* TAP harness should provide some summary. */
1912  acutest_no_summary_ = 1;
1913 
1914  if(!acutest_worker_)
1915  printf("1..%d\n", (int) acutest_count_);
1916  }
1917 
1918  index = acutest_worker_index_;
1919  for(i = 0; acutest_list_[i].func != NULL; i++) {
1920  int run = (acutest_test_data_[i].flags & ACUTEST_FLAG_RUN_);
1921  if (acutest_skip_mode_) /* Run all tests except those listed. */
1922  run = !run;
1923  if(run)
1924  acutest_run_(&acutest_list_[i], index++, i);
1925  }
1926 
1927  /* Write a summary */
1929  if(acutest_verbose_level_ >= 3) {
1930  acutest_colored_printf_(ACUTEST_COLOR_DEFAULT_INTENSIVE_, "Summary:\n");
1931 
1932  printf(" Count of all unit tests: %4d\n", (int) acutest_list_size_);
1933  printf(" Count of run unit tests: %4d\n", acutest_stat_run_units_);
1934  printf(" Count of failed unit tests: %4d\n", acutest_stat_failed_units_);
1935  printf(" Count of skipped unit tests: %4d\n", (int) acutest_list_size_ - acutest_stat_run_units_);
1936  }
1937 
1938  if(acutest_stat_failed_units_ == 0) {
1939  acutest_colored_printf_(ACUTEST_COLOR_GREEN_INTENSIVE_, "SUCCESS:");
1940  printf(" All unit tests have passed.\n");
1941  } else {
1942  acutest_colored_printf_(ACUTEST_COLOR_RED_INTENSIVE_, "FAILED:");
1943  printf(" %d of %d unit tests %s failed.\n",
1945  (acutest_stat_failed_units_ == 1) ? "has" : "have");
1946  }
1947 
1948  if(acutest_verbose_level_ >= 3)
1949  printf("\n");
1950  }
1951 
1952  if (acutest_xml_output_) {
1953 #if defined ACUTEST_UNIX_
1954  char *suite_name = basename(argv[0]);
1955 #elif defined ACUTEST_WIN_
1956  char suite_name[_MAX_FNAME];
1957  _splitpath(argv[0], NULL, NULL, suite_name, NULL);
1958 #else
1959  const char *suite_name = argv[0];
1960 #endif
1962  fprintf(acutest_xml_output_, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
1963  fprintf(acutest_xml_output_, "<testsuite name=\"%s\" tests=\"%d\" errors=\"%d\" failures=\"%d\" skip=\"%d\">\n",
1966  for(i = 0; acutest_list_[i].func != NULL; i++) {
1967  struct acutest_test_data_ *details = &acutest_test_data_[i];
1968  fprintf(acutest_xml_output_, " <testcase name=\"%s\" time=\"%.2f\">\n", acutest_list_[i].name, details->duration);
1969  if (details->flags & ACUTEST_FLAG_FAILURE_)
1970  fprintf(acutest_xml_output_, " <failure />\n");
1971  if (!(details->flags & ACUTEST_FLAG_FAILURE_) && !(details->flags & ACUTEST_FLAG_SUCCESS_))
1972  fprintf(acutest_xml_output_, " <skipped />\n");
1973  log_entry = details->log_head;
1974  while (log_entry) {
1975  fprintf(acutest_xml_output_, " <system-out>%s</system-out>\n", log_entry->msg);
1977  }
1978  fprintf(acutest_xml_output_, " </testcase>\n");
1979  }
1980  fprintf(acutest_xml_output_, "</testsuite>\n");
1981  fclose(acutest_xml_output_);
1982  }
1983 
1984  acutest_cleanup_();
1985 
1986  return (acutest_stat_failed_units_ == 0) ? 0 : 1;
1987 }
1988 
1989 
1990 #endif /* #ifndef TEST_NO_MAIN */
1991 
1992 #ifdef _MSC_VER
1993  #pragma warning(pop)
1994 #endif
1995 
1996 #ifdef __cplusplus
1997  } /* extern "C" */
1998 #endif
1999 
2000 #endif /* #ifndef ACUTEST_H */
#define ACUTEST_CMDLINE_OPTID_NONE_
Definition: acutest.h:1423
acutest_data_log_ * next
Definition: acutest.h:368
#define ACUTEST_ATTRIBUTE_(attr)
Definition: acutest.h:340
vsnprintf(buffer, sizeof(buffer), fmt, args)
static void acutest_init_(const char *test_name)
Definition: acutest.h:946
struct acutest_test_CMDLINE_OPTION_ ACUTEST_CMDLINE_OPTION_
static int acutest_test_failures_
Definition: acutest.h:419
#define ACUTEST_COLOR_DEFAULT_INTENSIVE_
Definition: acutest.h:568
static const ACUTEST_CMDLINE_OPTION_ acutest_cmdline_options_[]
Definition: acutest.h:1622
static int const char char buffer[256]
Definition: acutest.h:574
static void acutest_line_indent_(int level)
Definition: acutest.h:684
#define ACUTEST_COLOR_GREEN_INTENSIVE_
Definition: acutest.h:569
static int acutest_name_contains_word_(const char *name, const char *pattern)
Definition: acutest.h:1015
static int acutest_test_already_logged_
Definition: acutest.h:416
static int acutest_no_exec_
Definition: acutest.h:400
#define TEST_MSG_MAXSIZE
Definition: acutest.h:228
static FILE * acutest_xml_output_
Definition: acutest.h:408
int acutest_check_(int cond, const char *file, int line, const char *fmt,...)
int const char * file
Definition: acutest.h:702
static int acutest_worker_
Definition: acutest.h:404
static int acutest_stat_run_units_
Definition: acutest.h:411
static int acutest_colorize_
Definition: acutest.h:420
static char acutest_case_name_[TEST_CASE_MAXSIZE]
Definition: acutest.h:415
int acutest_timer_type_
Definition: acutest.h:538
static void acutest_cleanup_(void)
Definition: acutest.h:431
va_end(args)
unsigned char flags
Definition: acutest.h:372
int main(int argc, char **argv)
Definition: acutest.h:1832
static int acutest_cond_failed_
Definition: acutest.h:406
int verbose_level
Definition: acutest.h:706
static void acutest_timer_print_diff_(void)
Definition: acutest.h:561
#define ACUTEST_COLOR_GREEN_
Definition: acutest.h:566
static int acutest_case_already_logged_
Definition: acutest.h:417
void acutest_dump_(bool always, const char *title, const void *addr, size_t size)
Definition: acutest.h:871
int n
Definition: acutest.h:577
static const struct acutest_test_ * acutest_current_test_
Definition: acutest.h:413
#define TEST_CASE_MAXSIZE
Definition: acutest.h:191
static void acutest_set_duration_(int i, double duration)
Definition: acutest.h:1009
static void acutest_help_(void)
Definition: acutest.h:1579
static int acutest_timer_
Definition: acutest.h:421
static void acutest_finish_test_line_(int result)
Definition: acutest.h:655
#define ACUTEST_CMDLINE_OPTID_MISSINGARG_
Definition: acutest.h:1425
acutest_test_data_[acutest_current_index_] log_tail
Definition: acutest.h:787
static void acutest_fini_(const char *test_name)
Definition: acutest.h:959
void acutest_message_(bool always, const char *fmt,...)
@ ACUTEST_FLAG_SUCCESS_
Definition: acutest.h:380
@ ACUTEST_FLAG_RUN_
Definition: acutest.h:379
@ ACUTEST_FLAG_FAILURE_
Definition: acutest.h:381
static void acutest_timer_get_time_(int *ts)
Definition: acutest.h:547
#define ACUTEST_CMDLINE_OPTID_UNKNOWN_
Definition: acutest.h:1424
#define ACUTEST_CMDLINE_OPTID_BOGUSARG_
Definition: acutest.h:1426
static void acutest_list_names_(void)
Definition: acutest.h:983
static int acutest_cmdline_read_(const ACUTEST_CMDLINE_OPTION_ *options, int argc, char **argv, int(*callback)(int, const char *))
Definition: acutest.h:1472
static void acutest_run_(const struct acutest_test_ *test, int index, int master_index)
Definition: acutest.h:1203
static void acutest_set_success_(int i, int success)
Definition: acutest.h:1003
static int acutest_verbose_level_
Definition: acutest.h:418
const struct acutest_test_ acutest_list_[]
static int acutest_skip_mode_
Definition: acutest.h:403
static int acutest_cmdline_handle_short_opt_group_(const ACUTEST_CMDLINE_OPTION_ *options, const char *arggroup, int(*callback)(int, const char *))
Definition: acutest.h:1436
void acutest_timer_init_(void)
Definition: acutest.h:543
#define ACUTEST_CMDLINE_AUXBUF_SIZE_
Definition: acutest.h:1469
static int acutest_abort_has_jmp_buf_
Definition: acutest.h:423
acutest_data_log_ * log_tail
Definition: acutest.h:375
acutest_data_log_ * log_head
Definition: acutest.h:374
strcpy(log_entry->msg, buffer)
static void acutest_begin_test_line_(const struct acutest_test_ *test)
Definition: acutest.h:634
static void acutest_remember_(int i)
Definition: acutest.h:993
log_entry msg
Definition: acutest.h:794
static int acutest_lookup_(const char *pattern)
Definition: acutest.h:1038
void const char char * line_beg
Definition: acutest.h:834
char * line_end
Definition: acutest.h:837
va_list args
Definition: acutest.h:770
int const char int const char int result_color
Definition: acutest.h:703
static int acutest_do_run_(const struct acutest_test_ *test, int index)
Definition: acutest.h:1104
static double acutest_timer_diff_(int start, int end)
Definition: acutest.h:553
static int acutest_was_aborted_
Definition: acutest.h:407
void acutest_abort_(void) ACUTEST_ATTRIBUTE_(noreturn)
Definition: acutest.h:971
#define ACUTEST_CMDLINE_OPTFLAG_REQUIREDARG_
Definition: acutest.h:1421
static int const char * fmt
Definition: acutest.h:573
static int acutest_worker_index_
Definition: acutest.h:405
static int acutest_cmdline_callback_(int id, const char *arg)
Definition: acutest.h:1648
static size_t acutest_count_
Definition: acutest.h:399
void acutest_log_(const char *fmt,...)
#define TEST_LOG_MAXSIZE
Definition: acutest.h:262
static jmp_buf acutest_abort_jmp_buf_
Definition: acutest.h:424
#define ACUTEST_COLOR_RED_INTENSIVE_
Definition: acutest.h:570
static int acutest_stat_failed_units_
Definition: acutest.h:410
result_str
Definition: acutest.h:716
int const char int line
Definition: acutest.h:702
static int acutest_tap_
Definition: acutest.h:402
#define ACUTEST_COLOR_RED_
Definition: acutest.h:567
#define TEST_DUMP_MAXSIZE
Definition: acutest.h:255
static acutest_timer_type_ acutest_timer_start_
Definition: acutest.h:539
va_start(args, fmt)
static int acutest_current_index_
Definition: acutest.h:414
static int acutest_no_summary_
Definition: acutest.h:401
static char * acutest_argv0_
Definition: acutest.h:396
static acutest_timer_type_ acutest_timer_end_
Definition: acutest.h:540
#define ACUTEST_CMDLINE_OPTFLAG_OPTIONALARG_
Definition: acutest.h:1420
void acutest_case_(const char *fmt,...)
void acutest_data_log_ * log_entry
Definition: acutest.h:767
static size_t acutest_list_size_
Definition: acutest.h:397
static char const * spaces
Definition: dependency.c:364
#define RUNNING_ON_VALGRIND
Definition: dl.c:40
free(array)
waitpid(reap->pid_ev->pid, &status, 0)
long int ssize_t
Definition: merged_model.c:24
#define TEST_INIT
#define TEST_FINI
#define WIFEXITED(stat_val)
Definition: radiusd.c:72
#define WEXITSTATUS(stat_val)
Definition: radiusd.c:69
static char const * name
Signals that can be sent to a request.
PUBLIC int snprintf(char *string, size_t length, char *format, va_alist)
Definition: snprintf.c:689
return count
Definition: module.c:175
const char * name
Definition: acutest.h:360
void(* func)(void)
Definition: acutest.h:361
Simple time functions.
goto success
Definition: tmpl_eval.c:1450
close(uq->fd)
int format(printf, 5, 0))