Line data Source code
1 : /*
2 : * Copyright 2008 Google Inc.
3 : * Copyright 2014-2018 Andreas Schneider <asn@cryptomilk.org>
4 : * Copyright 2015 Jakub Hrozek <jakub.hrozek@posteo.se>
5 : *
6 : * Licensed under the Apache License, Version 2.0 (the "License");
7 : * you may not use this file except in compliance with the License.
8 : * You may obtain a copy of the License at
9 : *
10 : * http://www.apache.org/licenses/LICENSE-2.0
11 : *
12 : * Unless required by applicable law or agreed to in writing, software
13 : * distributed under the License is distributed on an "AS IS" BASIS,
14 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 : * See the License for the specific language governing permissions and
16 : * limitations under the License.
17 : */
18 : #ifdef HAVE_CONFIG_H
19 : #include "config.h"
20 : #endif
21 :
22 : #ifdef HAVE_MALLOC_H
23 : #include <malloc.h>
24 : #endif
25 :
26 : #ifdef HAVE_INTTYPES_H
27 : #include <inttypes.h>
28 : #endif
29 :
30 : #ifdef HAVE_SIGNAL_H
31 : #include <signal.h>
32 : #endif
33 :
34 : #ifdef HAVE_STRINGS_H
35 : #include <strings.h>
36 : #endif
37 :
38 : #include <stdint.h>
39 : #include <setjmp.h>
40 : #include <stdarg.h>
41 : #include <stddef.h>
42 : #include <stdio.h>
43 : #include <stdlib.h>
44 : #include <string.h>
45 : #include <stdbool.h>
46 : #include <time.h>
47 : #include <float.h>
48 :
49 : /*
50 : * This allows to add a platform specific header file. Some embedded platforms
51 : * sometimes miss certain types and definitions.
52 : *
53 : * Example:
54 : *
55 : * typedef unsigned long int uintptr_t
56 : * #define _UINTPTR_T 1
57 : * #define _UINTPTR_T_DEFINED 1
58 : */
59 : #ifdef CMOCKA_PLATFORM_INCLUDE
60 : # include "cmocka_platform.h"
61 : #endif /* CMOCKA_PLATFORM_INCLUDE */
62 :
63 : #include <cmocka.h>
64 : #include <cmocka_private.h>
65 :
66 : /* Size of guard bytes around dynamically allocated blocks. */
67 : #define MALLOC_GUARD_SIZE 16
68 : /* Pattern used to initialize guard blocks. */
69 : #define MALLOC_GUARD_PATTERN 0xEF
70 : /* Pattern used to initialize memory allocated with test_malloc(). */
71 : #define MALLOC_ALLOC_PATTERN 0xBA
72 : #define MALLOC_FREE_PATTERN 0xCD
73 : /* Alignment of allocated blocks. NOTE: This must be base2. */
74 : #ifndef MALLOC_ALIGNMENT
75 : #define MALLOC_ALIGNMENT sizeof(size_t)
76 : #endif
77 :
78 : /* Printf formatting for source code locations. */
79 : #define SOURCE_LOCATION_FORMAT "%s:%u"
80 :
81 : #if defined(HAVE_GCC_THREAD_LOCAL_STORAGE)
82 : # define CMOCKA_THREAD __thread
83 : #elif defined(HAVE_MSVC_THREAD_LOCAL_STORAGE)
84 : # define CMOCKA_THREAD __declspec(thread)
85 : #else
86 : # define CMOCKA_THREAD
87 : #endif
88 :
89 : #ifdef HAVE_CLOCK_REALTIME
90 : #define CMOCKA_CLOCK_GETTIME(clock_id, ts) clock_gettime((clock_id), (ts))
91 : #else
92 : #define CMOCKA_CLOCK_GETTIME(clock_id, ts)
93 : #endif
94 :
95 : #ifndef MAX
96 : #define MAX(a,b) ((a) < (b) ? (b) : (a))
97 : #endif
98 :
99 : /**
100 : * POSIX has sigsetjmp/siglongjmp, while Windows only has setjmp/longjmp.
101 : */
102 : #ifdef HAVE_SIGLONGJMP
103 : # define cm_jmp_buf sigjmp_buf
104 : # define cm_setjmp(env) sigsetjmp(env, 1)
105 : # define cm_longjmp(env, val) siglongjmp(env, val)
106 : #else
107 : # define cm_jmp_buf jmp_buf
108 : # define cm_setjmp(env) setjmp(env)
109 : # define cm_longjmp(env, val) longjmp(env, val)
110 : #endif
111 :
112 :
113 : /*
114 : * Declare and initialize a LargestIntegralType variable name
115 : * with value the conversion of ptr.
116 : */
117 : #define declare_initialize_value_pointer_pointer(name, ptr) \
118 : LargestIntegralType name ; \
119 : name = (LargestIntegralType) (uintptr_t) ptr
120 :
121 : /* Cast a LargestIntegralType to pointer_type. */
122 : #define cast_largest_integral_type_to_pointer( \
123 : pointer_type, largest_integral_type) \
124 : ((pointer_type)(uintptr_t)(largest_integral_type))
125 :
126 : /* Doubly linked list node. */
127 : typedef struct ListNode {
128 : const void *value;
129 : int refcount;
130 : struct ListNode *next;
131 : struct ListNode *prev;
132 : } ListNode;
133 :
134 : /* Debug information for malloc(). */
135 : struct MallocBlockInfoData {
136 : void* block; /* Address of the block returned by malloc(). */
137 : size_t allocated_size; /* Total size of the allocated block. */
138 : size_t size; /* Request block size. */
139 : SourceLocation location; /* Where the block was allocated. */
140 : ListNode node; /* Node within list of all allocated blocks. */
141 : };
142 :
143 : typedef union {
144 : struct MallocBlockInfoData *data;
145 : char *ptr;
146 : } MallocBlockInfo;
147 :
148 : /* State of each test. */
149 : typedef struct TestState {
150 : const ListNode *check_point; /* Check point of the test if there's a */
151 : /* setup function. */
152 : void *state; /* State associated with the test. */
153 : } TestState;
154 :
155 : /* Determines whether two values are the same. */
156 : typedef int (*EqualityFunction)(const void *left, const void *right);
157 :
158 : /* Value of a symbol and the place it was declared. */
159 : typedef struct SymbolValue {
160 : SourceLocation location;
161 : LargestIntegralType value;
162 : } SymbolValue;
163 :
164 : /*
165 : * Contains a list of values for a symbol.
166 : * NOTE: Each structure referenced by symbol_values_list_head must have a
167 : * SourceLocation as its' first member.
168 : */
169 : typedef struct SymbolMapValue {
170 : const char *symbol_name;
171 : ListNode symbol_values_list_head;
172 : } SymbolMapValue;
173 :
174 : /* Where a particular ordering was located and its symbol name */
175 : typedef struct FuncOrderingValue {
176 : SourceLocation location;
177 : const char * function;
178 : } FuncOrderingValue;
179 :
180 : /* Used by list_free() to deallocate values referenced by list nodes. */
181 : typedef void (*CleanupListValue)(const void *value, void *cleanup_value_data);
182 :
183 : /* Structure used to check the range of integer types.a */
184 : typedef struct CheckIntegerRange {
185 : CheckParameterEvent event;
186 : LargestIntegralType minimum;
187 : LargestIntegralType maximum;
188 : } CheckIntegerRange;
189 :
190 : /* Structure used to check whether an integer value is in a set. */
191 : typedef struct CheckIntegerSet {
192 : CheckParameterEvent event;
193 : const LargestIntegralType *set;
194 : size_t size_of_set;
195 : } CheckIntegerSet;
196 :
197 : /* Used to check whether a parameter matches the area of memory referenced by
198 : * this structure. */
199 : typedef struct CheckMemoryData {
200 : CheckParameterEvent event;
201 : const void *memory;
202 : size_t size;
203 : } CheckMemoryData;
204 :
205 : static ListNode* list_initialize(ListNode * const node);
206 : static ListNode* list_add(ListNode * const head, ListNode *new_node);
207 : static ListNode* list_add_value(ListNode * const head, const void *value,
208 : const int count);
209 : static ListNode* list_remove(
210 : ListNode * const node, const CleanupListValue cleanup_value,
211 : void * const cleanup_value_data);
212 : static void list_remove_free(
213 : ListNode * const node, const CleanupListValue cleanup_value,
214 : void * const cleanup_value_data);
215 : static int list_empty(const ListNode * const head);
216 : static int list_find(
217 : ListNode * const head, const void *value,
218 : const EqualityFunction equal_func, ListNode **output);
219 : static int list_first(ListNode * const head, ListNode **output);
220 : static ListNode* list_free(
221 : ListNode * const head, const CleanupListValue cleanup_value,
222 : void * const cleanup_value_data);
223 :
224 : static void add_symbol_value(
225 : ListNode * const symbol_map_head, const char * const symbol_names[],
226 : const size_t number_of_symbol_names, const void* value, const int count);
227 : static int get_symbol_value(
228 : ListNode * const symbol_map_head, const char * const symbol_names[],
229 : const size_t number_of_symbol_names, void **output);
230 : static void free_value(const void *value, void *cleanup_value_data);
231 : static void free_symbol_map_value(
232 : const void *value, void *cleanup_value_data);
233 : static void remove_always_return_values(ListNode * const map_head,
234 : const size_t number_of_symbol_names);
235 :
236 : static size_t check_for_leftover_values_list(const ListNode * head,
237 : const char * const error_message);
238 :
239 : static size_t check_for_leftover_values(
240 : const ListNode * const map_head, const char * const error_message,
241 : const size_t number_of_symbol_names);
242 :
243 : static void remove_always_return_values_from_list(ListNode * const map_head);
244 :
245 : /*
246 : * This must be called at the beginning of a test to initialize some data
247 : * structures.
248 : */
249 : static void initialize_testing(const char *test_name);
250 :
251 : /* This must be called at the end of a test to free() allocated structures. */
252 : static void teardown_testing(const char *test_name);
253 :
254 : static enum cm_message_output cm_get_output(void);
255 :
256 : static int cm_error_message_enabled = 1;
257 : static CMOCKA_THREAD char *cm_error_message;
258 :
259 : /*
260 : * Keeps track of the calling context returned by setenv() so that the fail()
261 : * method can jump out of a test.
262 : */
263 : static CMOCKA_THREAD cm_jmp_buf global_run_test_env;
264 : static CMOCKA_THREAD int global_running_test = 0;
265 :
266 : /* Keeps track of the calling context returned by setenv() so that */
267 : /* mock_assert() can optionally jump back to expect_assert_failure(). */
268 : jmp_buf global_expect_assert_env;
269 : int global_expecting_assert = 0;
270 : const char *global_last_failed_assert = NULL;
271 : static int global_skip_test;
272 :
273 : /* Keeps a map of the values that functions will have to return to provide */
274 : /* mocked interfaces. */
275 : static CMOCKA_THREAD ListNode global_function_result_map_head;
276 : /* Location of the last mock value returned was declared. */
277 : static CMOCKA_THREAD SourceLocation global_last_mock_value_location;
278 :
279 : /* Keeps a map of the values that functions expect as parameters to their
280 : * mocked interfaces. */
281 : static CMOCKA_THREAD ListNode global_function_parameter_map_head;
282 : /* Location of last parameter value checked was declared. */
283 : static CMOCKA_THREAD SourceLocation global_last_parameter_location;
284 :
285 : /* List (acting as FIFO) of call ordering. */
286 : static CMOCKA_THREAD ListNode global_call_ordering_head;
287 : /* Location of last call ordering that was declared. */
288 : static CMOCKA_THREAD SourceLocation global_last_call_ordering_location;
289 :
290 : /* List of all currently allocated blocks. */
291 : static CMOCKA_THREAD ListNode global_allocated_blocks;
292 :
293 : static enum cm_message_output global_msg_output = CM_OUTPUT_STDOUT;
294 :
295 : static const char *global_test_filter_pattern;
296 :
297 : static const char *global_skip_filter_pattern;
298 :
299 : #ifndef _WIN32
300 : /* Signals caught by exception_handler(). */
301 : static const int exception_signals[] = {
302 : SIGFPE,
303 : SIGILL,
304 : SIGSEGV,
305 : #ifdef SIGBUS
306 : SIGBUS,
307 : #endif
308 : #ifdef SIGSYS
309 : SIGSYS,
310 : #endif
311 : };
312 :
313 : /* Default signal functions that should be restored after a test is complete. */
314 : typedef void (*SignalFunction)(int signal);
315 : static SignalFunction default_signal_functions[
316 : ARRAY_SIZE(exception_signals)];
317 :
318 : #else /* _WIN32 */
319 :
320 : /* The default exception filter. */
321 : static LPTOP_LEVEL_EXCEPTION_FILTER previous_exception_filter;
322 :
323 : /* Fatal exceptions. */
324 : typedef struct ExceptionCodeInfo {
325 : DWORD code;
326 : const char* description;
327 : } ExceptionCodeInfo;
328 :
329 : #define EXCEPTION_CODE_INFO(exception_code) {exception_code, #exception_code}
330 :
331 : static const ExceptionCodeInfo exception_codes[] = {
332 : EXCEPTION_CODE_INFO(EXCEPTION_ACCESS_VIOLATION),
333 : EXCEPTION_CODE_INFO(EXCEPTION_ARRAY_BOUNDS_EXCEEDED),
334 : EXCEPTION_CODE_INFO(EXCEPTION_DATATYPE_MISALIGNMENT),
335 : EXCEPTION_CODE_INFO(EXCEPTION_FLT_DENORMAL_OPERAND),
336 : EXCEPTION_CODE_INFO(EXCEPTION_FLT_DIVIDE_BY_ZERO),
337 : EXCEPTION_CODE_INFO(EXCEPTION_FLT_INEXACT_RESULT),
338 : EXCEPTION_CODE_INFO(EXCEPTION_FLT_INVALID_OPERATION),
339 : EXCEPTION_CODE_INFO(EXCEPTION_FLT_OVERFLOW),
340 : EXCEPTION_CODE_INFO(EXCEPTION_FLT_STACK_CHECK),
341 : EXCEPTION_CODE_INFO(EXCEPTION_FLT_UNDERFLOW),
342 : EXCEPTION_CODE_INFO(EXCEPTION_GUARD_PAGE),
343 : EXCEPTION_CODE_INFO(EXCEPTION_ILLEGAL_INSTRUCTION),
344 : EXCEPTION_CODE_INFO(EXCEPTION_INT_DIVIDE_BY_ZERO),
345 : EXCEPTION_CODE_INFO(EXCEPTION_INT_OVERFLOW),
346 : EXCEPTION_CODE_INFO(EXCEPTION_INVALID_DISPOSITION),
347 : EXCEPTION_CODE_INFO(EXCEPTION_INVALID_HANDLE),
348 : EXCEPTION_CODE_INFO(EXCEPTION_IN_PAGE_ERROR),
349 : EXCEPTION_CODE_INFO(EXCEPTION_NONCONTINUABLE_EXCEPTION),
350 : EXCEPTION_CODE_INFO(EXCEPTION_PRIV_INSTRUCTION),
351 : EXCEPTION_CODE_INFO(EXCEPTION_STACK_OVERFLOW),
352 : };
353 : #endif /* !_WIN32 */
354 :
355 : enum CMUnitTestStatus {
356 : CM_TEST_NOT_STARTED,
357 : CM_TEST_PASSED,
358 : CM_TEST_FAILED,
359 : CM_TEST_ERROR,
360 : CM_TEST_SKIPPED,
361 : };
362 :
363 : struct CMUnitTestState {
364 : const ListNode *check_point; /* Check point of the test if there's a setup function. */
365 : const struct CMUnitTest *test; /* Point to array element in the tests we get passed */
366 : void *state; /* State associated with the test */
367 : const char *error_message; /* The error messages by the test */
368 : enum CMUnitTestStatus status; /* PASSED, FAILED, ABORT ... */
369 : double runtime; /* Time calculations */
370 : };
371 :
372 : /* Exit the currently executing test. */
373 0 : static void exit_test(const int quit_application)
374 : {
375 0 : const char *env = getenv("CMOCKA_TEST_ABORT");
376 0 : int abort_test = 0;
377 :
378 0 : if (env != NULL && strlen(env) == 1) {
379 0 : abort_test = (env[0] == '1');
380 : }
381 :
382 0 : if (global_skip_test == 0 &&
383 : abort_test == 1) {
384 0 : print_error("%s", cm_error_message);
385 0 : abort();
386 0 : } else if (global_running_test) {
387 0 : cm_longjmp(global_run_test_env, 1);
388 0 : } else if (quit_application) {
389 0 : exit(-1);
390 : }
391 0 : }
392 :
393 0 : void _skip(const char * const file, const int line)
394 : {
395 0 : cm_print_error(SOURCE_LOCATION_FORMAT ": Skipped!\n", file, line);
396 0 : global_skip_test = 1;
397 0 : exit_test(1);
398 :
399 : /* Unreachable */
400 0 : exit(-1);
401 : }
402 :
403 : /* Initialize a SourceLocation structure. */
404 8136 : static void initialize_source_location(SourceLocation * const location) {
405 8136 : assert_non_null(location);
406 8136 : location->file = NULL;
407 8136 : location->line = 0;
408 8136 : }
409 :
410 :
411 : /* Determine whether a source location is currently set. */
412 0 : static int source_location_is_set(const SourceLocation * const location) {
413 0 : assert_non_null(location);
414 0 : return location->file && location->line;
415 : }
416 :
417 :
418 : /* Set a source location. */
419 0 : static void set_source_location(
420 : SourceLocation * const location, const char * const file,
421 : const int line) {
422 0 : assert_non_null(location);
423 0 : location->file = file;
424 0 : location->line = line;
425 0 : }
426 :
427 :
428 0 : static int c_strreplace(char *src,
429 : size_t src_len,
430 : const char *pattern,
431 : const char *repl,
432 : int *str_replaced)
433 : {
434 0 : char *p = NULL;
435 :
436 0 : p = strstr(src, pattern);
437 0 : if (p == NULL) {
438 0 : return -1;
439 : }
440 :
441 : do {
442 0 : size_t of = p - src;
443 0 : size_t l = strlen(src);
444 0 : size_t pl = strlen(pattern);
445 0 : size_t rl = strlen(repl);
446 :
447 : /* overflow check */
448 0 : if (src_len <= l + MAX(pl, rl) + 1) {
449 0 : return -1;
450 : }
451 :
452 0 : if (rl != pl) {
453 0 : memmove(src + of + rl, src + of + pl, l - of - pl + 1);
454 : }
455 :
456 0 : memcpy(src + of, repl, rl);
457 :
458 0 : if (str_replaced != NULL) {
459 0 : *str_replaced = 1;
460 : }
461 0 : p = strstr(src, pattern);
462 0 : } while (p != NULL);
463 :
464 0 : return 0;
465 : }
466 :
467 0 : static int c_strmatch(const char *str, const char *pattern)
468 : {
469 : int ok;
470 :
471 0 : if (str == NULL || pattern == NULL) {
472 0 : return 0;
473 : }
474 :
475 : for (;;) {
476 : /* Check if pattern is done */
477 0 : if (*pattern == '\0') {
478 : /* If string is at the end, we're good */
479 0 : if (*str == '\0') {
480 0 : return 1;
481 : }
482 :
483 0 : return 0;
484 : }
485 :
486 0 : if (*pattern == '*') {
487 : /* Move on */
488 0 : pattern++;
489 :
490 : /* If we are at the end, everything is fine */
491 0 : if (*pattern == '\0') {
492 0 : return 1;
493 : }
494 :
495 : /* Try to match each position */
496 0 : for (; *str != '\0'; str++) {
497 0 : ok = c_strmatch(str, pattern);
498 0 : if (ok) {
499 0 : return 1;
500 : }
501 : }
502 :
503 : /* No match */
504 0 : return 0;
505 : }
506 :
507 : /* If we are at the end, leave */
508 0 : if (*str == '\0') {
509 0 : return 0;
510 : }
511 :
512 : /* Check if we have a single wildcard or matching char */
513 0 : if (*pattern != '?' && *str != *pattern) {
514 0 : return 0;
515 : }
516 :
517 : /* Move string and pattern */
518 0 : str++;
519 0 : pattern++;
520 : }
521 :
522 : return 0;
523 : }
524 :
525 : /* Create function results and expected parameter lists. */
526 1356 : void initialize_testing(const char *test_name) {
527 : (void)test_name;
528 1356 : list_initialize(&global_function_result_map_head);
529 1356 : initialize_source_location(&global_last_mock_value_location);
530 1356 : list_initialize(&global_function_parameter_map_head);
531 1356 : initialize_source_location(&global_last_parameter_location);
532 1356 : list_initialize(&global_call_ordering_head);
533 1356 : initialize_source_location(&global_last_parameter_location);
534 1356 : }
535 :
536 :
537 1356 : static void fail_if_leftover_values(const char *test_name) {
538 1356 : int error_occurred = 0;
539 : (void)test_name;
540 1356 : remove_always_return_values(&global_function_result_map_head, 1);
541 1356 : if (check_for_leftover_values(
542 : &global_function_result_map_head,
543 : "%s() has remaining non-returned values.\n", 1)) {
544 0 : error_occurred = 1;
545 : }
546 :
547 1356 : remove_always_return_values(&global_function_parameter_map_head, 2);
548 1356 : if (check_for_leftover_values(
549 : &global_function_parameter_map_head,
550 : "'%s' parameter still has values that haven't been checked.\n",
551 : 2)) {
552 0 : error_occurred = 1;
553 : }
554 :
555 1356 : remove_always_return_values_from_list(&global_call_ordering_head);
556 1356 : if (check_for_leftover_values_list(&global_call_ordering_head,
557 : "%s function was expected to be called but was not.\n")) {
558 0 : error_occurred = 1;
559 : }
560 1356 : if (error_occurred) {
561 0 : exit_test(1);
562 : }
563 1356 : }
564 :
565 :
566 1356 : static void teardown_testing(const char *test_name) {
567 : (void)test_name;
568 1356 : list_free(&global_function_result_map_head, free_symbol_map_value,
569 : (void*)0);
570 1356 : initialize_source_location(&global_last_mock_value_location);
571 1356 : list_free(&global_function_parameter_map_head, free_symbol_map_value,
572 : (void*)1);
573 1356 : initialize_source_location(&global_last_parameter_location);
574 1356 : list_free(&global_call_ordering_head, free_value,
575 : (void*)0);
576 1356 : initialize_source_location(&global_last_call_ordering_location);
577 1356 : }
578 :
579 : /* Initialize a list node. */
580 4073 : static ListNode* list_initialize(ListNode * const node) {
581 4073 : node->value = NULL;
582 4073 : node->next = node;
583 4073 : node->prev = node;
584 4073 : node->refcount = 1;
585 4073 : return node;
586 : }
587 :
588 :
589 : /*
590 : * Adds a value at the tail of a given list.
591 : * The node referencing the value is allocated from the heap.
592 : */
593 0 : static ListNode* list_add_value(ListNode * const head, const void *value,
594 : const int refcount) {
595 0 : ListNode * const new_node = (ListNode*)malloc(sizeof(ListNode));
596 0 : assert_non_null(head);
597 0 : assert_non_null(value);
598 0 : new_node->value = value;
599 0 : new_node->refcount = refcount;
600 0 : return list_add(head, new_node);
601 : }
602 :
603 :
604 : /* Add new_node to the end of the list. */
605 0 : static ListNode* list_add(ListNode * const head, ListNode *new_node) {
606 0 : assert_non_null(head);
607 0 : assert_non_null(new_node);
608 0 : new_node->next = head;
609 0 : new_node->prev = head->prev;
610 0 : head->prev->next = new_node;
611 0 : head->prev = new_node;
612 0 : return new_node;
613 : }
614 :
615 :
616 : /* Remove a node from a list. */
617 0 : static ListNode* list_remove(
618 : ListNode * const node, const CleanupListValue cleanup_value,
619 : void * const cleanup_value_data) {
620 0 : assert_non_null(node);
621 0 : node->prev->next = node->next;
622 0 : node->next->prev = node->prev;
623 0 : if (cleanup_value) {
624 0 : cleanup_value(node->value, cleanup_value_data);
625 : }
626 0 : return node;
627 : }
628 :
629 :
630 : /* Remove a list node from a list and free the node. */
631 0 : static void list_remove_free(
632 : ListNode * const node, const CleanupListValue cleanup_value,
633 : void * const cleanup_value_data) {
634 0 : assert_non_null(node);
635 0 : free(list_remove(node, cleanup_value, cleanup_value_data));
636 0 : }
637 :
638 :
639 : /*
640 : * Frees memory kept by a linked list The cleanup_value function is called for
641 : * every "value" field of nodes in the list, except for the head. In addition
642 : * to each list value, cleanup_value_data is passed to each call to
643 : * cleanup_value. The head of the list is not deallocated.
644 : */
645 4068 : static ListNode* list_free(
646 : ListNode * const head, const CleanupListValue cleanup_value,
647 : void * const cleanup_value_data) {
648 4068 : assert_non_null(head);
649 4068 : while (!list_empty(head)) {
650 0 : list_remove_free(head->next, cleanup_value, cleanup_value_data);
651 : }
652 4068 : return head;
653 : }
654 :
655 :
656 : /* Determine whether a list is empty. */
657 5424 : static int list_empty(const ListNode * const head) {
658 5424 : assert_non_null(head);
659 5424 : return head->next == head;
660 : }
661 :
662 :
663 : /*
664 : * Find a value in the list using the equal_func to compare each node with the
665 : * value.
666 : */
667 0 : static int list_find(ListNode * const head, const void *value,
668 : const EqualityFunction equal_func, ListNode **output) {
669 : ListNode *current;
670 0 : assert_non_null(head);
671 0 : for (current = head->next; current != head; current = current->next) {
672 0 : if (equal_func(current->value, value)) {
673 0 : *output = current;
674 0 : return 1;
675 : }
676 : }
677 0 : return 0;
678 : }
679 :
680 : /* Returns the first node of a list */
681 0 : static int list_first(ListNode * const head, ListNode **output) {
682 0 : ListNode *target_node = NULL;
683 0 : assert_non_null(head);
684 0 : if (list_empty(head)) {
685 0 : return 0;
686 : }
687 0 : target_node = head->next;
688 0 : *output = target_node;
689 0 : return 1;
690 : }
691 :
692 :
693 : /* Deallocate a value referenced by a list. */
694 0 : static void free_value(const void *value, void *cleanup_value_data) {
695 : (void)cleanup_value_data;
696 0 : assert_non_null(value);
697 0 : free((void*)value);
698 0 : }
699 :
700 :
701 : /* Releases memory associated to a symbol_map_value. */
702 0 : static void free_symbol_map_value(const void *value,
703 : void *cleanup_value_data) {
704 0 : SymbolMapValue * const map_value = (SymbolMapValue*)value;
705 0 : const LargestIntegralType children = cast_ptr_to_largest_integral_type(cleanup_value_data);
706 0 : assert_non_null(value);
707 0 : if (children == 0) {
708 0 : list_free(&map_value->symbol_values_list_head,
709 : free_value,
710 : NULL);
711 : } else {
712 0 : list_free(&map_value->symbol_values_list_head,
713 : free_symbol_map_value,
714 0 : (void *)((uintptr_t)children - 1));
715 : }
716 :
717 0 : free(map_value);
718 0 : }
719 :
720 :
721 : /*
722 : * Determine whether a symbol name referenced by a symbol_map_value matches the
723 : * specified function name.
724 : */
725 0 : static int symbol_names_match(const void *map_value, const void *symbol) {
726 0 : return !strcmp(((SymbolMapValue*)map_value)->symbol_name,
727 : (const char*)symbol);
728 : }
729 :
730 : /*
731 : * Adds a value to the queue of values associated with the given hierarchy of
732 : * symbols. It's assumed value is allocated from the heap.
733 : */
734 0 : static void add_symbol_value(ListNode * const symbol_map_head,
735 : const char * const symbol_names[],
736 : const size_t number_of_symbol_names,
737 : const void* value, const int refcount) {
738 : const char* symbol_name;
739 : ListNode *target_node;
740 : SymbolMapValue *target_map_value;
741 0 : assert_non_null(symbol_map_head);
742 0 : assert_non_null(symbol_names);
743 0 : assert_true(number_of_symbol_names);
744 0 : symbol_name = symbol_names[0];
745 :
746 0 : if (!list_find(symbol_map_head, symbol_name, symbol_names_match,
747 : &target_node)) {
748 : SymbolMapValue * const new_symbol_map_value =
749 0 : (SymbolMapValue*)malloc(sizeof(*new_symbol_map_value));
750 0 : new_symbol_map_value->symbol_name = symbol_name;
751 0 : list_initialize(&new_symbol_map_value->symbol_values_list_head);
752 0 : target_node = list_add_value(symbol_map_head, new_symbol_map_value,
753 : 1);
754 : }
755 :
756 0 : target_map_value = (SymbolMapValue*)target_node->value;
757 0 : if (number_of_symbol_names == 1) {
758 0 : list_add_value(&target_map_value->symbol_values_list_head,
759 : value, refcount);
760 : } else {
761 0 : add_symbol_value(&target_map_value->symbol_values_list_head,
762 : &symbol_names[1], number_of_symbol_names - 1, value,
763 : refcount);
764 : }
765 0 : }
766 :
767 :
768 : /*
769 : * Gets the next value associated with the given hierarchy of symbols.
770 : * The value is returned as an output parameter with the function returning the
771 : * node's old refcount value if a value is found, 0 otherwise. This means that
772 : * a return value of 1 indicates the node was just removed from the list.
773 : */
774 0 : static int get_symbol_value(
775 : ListNode * const head, const char * const symbol_names[],
776 : const size_t number_of_symbol_names, void **output) {
777 0 : const char* symbol_name = NULL;
778 0 : ListNode *target_node = NULL;
779 0 : assert_non_null(head);
780 0 : assert_non_null(symbol_names);
781 0 : assert_true(number_of_symbol_names);
782 0 : assert_non_null(output);
783 0 : symbol_name = symbol_names[0];
784 :
785 0 : if (list_find(head, symbol_name, symbol_names_match, &target_node)) {
786 0 : SymbolMapValue *map_value = NULL;
787 0 : ListNode *child_list = NULL;
788 0 : int return_value = 0;
789 0 : assert_non_null(target_node);
790 0 : assert_non_null(target_node->value);
791 :
792 0 : map_value = (SymbolMapValue*)target_node->value;
793 0 : child_list = &map_value->symbol_values_list_head;
794 :
795 0 : if (number_of_symbol_names == 1) {
796 0 : ListNode *value_node = NULL;
797 0 : return_value = list_first(child_list, &value_node);
798 0 : assert_true(return_value);
799 : /* Add a check to silence clang analyzer */
800 0 : if (return_value == 0) {
801 0 : goto out;
802 : }
803 0 : *output = (void*) value_node->value;
804 0 : return_value = value_node->refcount;
805 0 : if (value_node->refcount - 1 == 0) {
806 0 : list_remove_free(value_node, NULL, NULL);
807 0 : } else if (value_node->refcount > WILL_RETURN_ONCE) {
808 0 : --value_node->refcount;
809 : }
810 : } else {
811 0 : return_value = get_symbol_value(
812 : child_list, &symbol_names[1], number_of_symbol_names - 1,
813 : output);
814 : }
815 0 : if (list_empty(child_list)) {
816 0 : list_remove_free(target_node, free_symbol_map_value, (void*)0);
817 : }
818 0 : return return_value;
819 : }
820 0 : out:
821 0 : cm_print_error("No entries for symbol %s.\n", symbol_name);
822 0 : return 0;
823 : }
824 :
825 : /**
826 : * Taverse a list of nodes and remove first symbol value in list that has a
827 : * refcount < -1 (i.e. should always be returned and has been returned at
828 : * least once).
829 : */
830 :
831 1356 : static void remove_always_return_values_from_list(ListNode * const map_head)
832 : {
833 1356 : ListNode * current = NULL;
834 1356 : ListNode * next = NULL;
835 1356 : assert_non_null(map_head);
836 :
837 1356 : for (current = map_head->next, next = current->next;
838 1356 : current != map_head;
839 0 : current = next, next = current->next) {
840 0 : if (current->refcount < -1) {
841 0 : list_remove_free(current, free_value, NULL);
842 : }
843 : }
844 1356 : }
845 :
846 : /*
847 : * Traverse down a tree of symbol values and remove the first symbol value
848 : * in each branch that has a refcount < -1 (i.e should always be returned
849 : * and has been returned at least once).
850 : */
851 2712 : static void remove_always_return_values(ListNode * const map_head,
852 : const size_t number_of_symbol_names) {
853 : ListNode *current;
854 2712 : assert_non_null(map_head);
855 2712 : assert_true(number_of_symbol_names);
856 2712 : current = map_head->next;
857 2712 : while (current != map_head) {
858 0 : SymbolMapValue * const value = (SymbolMapValue*)current->value;
859 0 : ListNode * const next = current->next;
860 : ListNode *child_list;
861 0 : assert_non_null(value);
862 0 : child_list = &value->symbol_values_list_head;
863 :
864 0 : if (!list_empty(child_list)) {
865 0 : if (number_of_symbol_names == 1) {
866 0 : ListNode * const child_node = child_list->next;
867 : /* If this item has been returned more than once, free it. */
868 0 : if (child_node->refcount < -1) {
869 0 : list_remove_free(child_node, free_value, NULL);
870 : }
871 : } else {
872 0 : remove_always_return_values(child_list,
873 : number_of_symbol_names - 1);
874 : }
875 : }
876 :
877 0 : if (list_empty(child_list)) {
878 0 : list_remove_free(current, free_value, NULL);
879 : }
880 0 : current = next;
881 : }
882 2712 : }
883 :
884 1356 : static size_t check_for_leftover_values_list(const ListNode * head,
885 : const char * const error_message)
886 : {
887 : ListNode *child_node;
888 1356 : size_t leftover_count = 0;
889 1356 : if (!list_empty(head))
890 : {
891 0 : for (child_node = head->next; child_node != head;
892 0 : child_node = child_node->next, ++leftover_count) {
893 0 : const FuncOrderingValue *const o =
894 : (const FuncOrderingValue*) child_node->value;
895 0 : cm_print_error("%s: %s", error_message, o->function);
896 0 : cm_print_error(SOURCE_LOCATION_FORMAT
897 : ": note: remaining item was declared here\n",
898 0 : o->location.file, o->location.line);
899 : }
900 : }
901 1356 : return leftover_count;
902 : }
903 :
904 : /*
905 : * Checks if there are any leftover values set up by the test that were never
906 : * retrieved through execution, and fail the test if that is the case.
907 : */
908 2712 : static size_t check_for_leftover_values(
909 : const ListNode * const map_head, const char * const error_message,
910 : const size_t number_of_symbol_names) {
911 : const ListNode *current;
912 2712 : size_t symbols_with_leftover_values = 0;
913 2712 : assert_non_null(map_head);
914 2712 : assert_true(number_of_symbol_names);
915 :
916 2712 : for (current = map_head->next; current != map_head;
917 0 : current = current->next) {
918 0 : const SymbolMapValue * const value =
919 : (SymbolMapValue*)current->value;
920 : const ListNode *child_list;
921 0 : assert_non_null(value);
922 0 : child_list = &value->symbol_values_list_head;
923 :
924 0 : if (!list_empty(child_list)) {
925 0 : if (number_of_symbol_names == 1) {
926 : const ListNode *child_node;
927 0 : cm_print_error("%s: %s", error_message, value->symbol_name);
928 :
929 0 : for (child_node = child_list->next; child_node != child_list;
930 0 : child_node = child_node->next) {
931 0 : const SourceLocation * const location =
932 : (const SourceLocation*)child_node->value;
933 0 : cm_print_error(SOURCE_LOCATION_FORMAT
934 : ": note: remaining item was declared here\n",
935 0 : location->file, location->line);
936 : }
937 : } else {
938 0 : cm_print_error("%s: ", value->symbol_name);
939 0 : check_for_leftover_values(child_list, error_message,
940 : number_of_symbol_names - 1);
941 : }
942 0 : symbols_with_leftover_values ++;
943 : }
944 : }
945 2712 : return symbols_with_leftover_values;
946 : }
947 :
948 :
949 : /* Get the next return value for the specified mock function. */
950 0 : LargestIntegralType _mock(const char * const function, const char* const file,
951 : const int line) {
952 : void *result;
953 0 : const int rc = get_symbol_value(&global_function_result_map_head,
954 : &function, 1, &result);
955 0 : if (rc) {
956 0 : SymbolValue * const symbol = (SymbolValue*)result;
957 0 : const LargestIntegralType value = symbol->value;
958 0 : global_last_mock_value_location = symbol->location;
959 0 : if (rc == 1) {
960 0 : free(symbol);
961 : }
962 0 : return value;
963 : } else {
964 0 : cm_print_error(SOURCE_LOCATION_FORMAT ": error: Could not get value "
965 : "to mock function %s\n", file, line, function);
966 0 : if (source_location_is_set(&global_last_mock_value_location)) {
967 0 : cm_print_error(SOURCE_LOCATION_FORMAT
968 : ": note: Previously returned mock value was declared here\n",
969 : global_last_mock_value_location.file,
970 : global_last_mock_value_location.line);
971 : } else {
972 0 : cm_print_error("There were no previously returned mock values for "
973 : "this test.\n");
974 : }
975 0 : exit_test(1);
976 : }
977 0 : return 0;
978 : }
979 :
980 : /* Ensure that function is being called in proper order */
981 0 : void _function_called(const char *const function,
982 : const char *const file,
983 : const int line)
984 : {
985 0 : ListNode *first_value_node = NULL;
986 0 : ListNode *value_node = NULL;
987 : int rc;
988 :
989 0 : rc = list_first(&global_call_ordering_head, &value_node);
990 0 : first_value_node = value_node;
991 0 : if (rc) {
992 : FuncOrderingValue *expected_call;
993 : int cmp;
994 :
995 0 : expected_call = (FuncOrderingValue *)value_node->value;
996 :
997 0 : cmp = strcmp(expected_call->function, function);
998 0 : if (value_node->refcount < -1) {
999 : /*
1000 : * Search through value nodes until either function is found or
1001 : * encounter a non-zero refcount greater than -2
1002 : */
1003 0 : if (cmp != 0) {
1004 0 : value_node = value_node->next;
1005 0 : expected_call = (FuncOrderingValue *)value_node->value;
1006 :
1007 0 : cmp = strcmp(expected_call->function, function);
1008 0 : while (value_node->refcount < -1 &&
1009 0 : cmp != 0 &&
1010 0 : value_node != first_value_node->prev) {
1011 0 : value_node = value_node->next;
1012 0 : if (value_node == NULL) {
1013 0 : break;
1014 : }
1015 0 : expected_call = (FuncOrderingValue *)value_node->value;
1016 0 : if (expected_call == NULL) {
1017 0 : continue;
1018 : }
1019 0 : cmp = strcmp(expected_call->function, function);
1020 : }
1021 :
1022 0 : if (expected_call == NULL || value_node == first_value_node->prev) {
1023 0 : cm_print_error(SOURCE_LOCATION_FORMAT
1024 : ": error: No expected mock calls matching "
1025 : "called() invocation in %s",
1026 : file, line,
1027 : function);
1028 0 : exit_test(1);
1029 : }
1030 : }
1031 : }
1032 :
1033 0 : if (cmp == 0) {
1034 0 : if (value_node->refcount > -2 && --value_node->refcount == 0) {
1035 0 : list_remove_free(value_node, free_value, NULL);
1036 : }
1037 : } else {
1038 0 : cm_print_error(SOURCE_LOCATION_FORMAT
1039 : ": error: Expected call to %s but received called() "
1040 : "in %s\n",
1041 : file, line,
1042 : expected_call->function,
1043 : function);
1044 0 : exit_test(1);
1045 : }
1046 : } else {
1047 0 : cm_print_error(SOURCE_LOCATION_FORMAT
1048 : ": error: No mock calls expected but called() was "
1049 : "invoked in %s\n",
1050 : file, line,
1051 : function);
1052 0 : exit_test(1);
1053 : }
1054 0 : }
1055 :
1056 : /* Add a return value for the specified mock function name. */
1057 0 : void _will_return(const char * const function_name, const char * const file,
1058 : const int line, const LargestIntegralType value,
1059 : const int count) {
1060 : SymbolValue * const return_value =
1061 0 : (SymbolValue*)malloc(sizeof(*return_value));
1062 0 : assert_true(count != 0);
1063 0 : return_value->value = value;
1064 0 : set_source_location(&return_value->location, file, line);
1065 0 : add_symbol_value(&global_function_result_map_head, &function_name, 1,
1066 : return_value, count);
1067 0 : }
1068 :
1069 :
1070 : /*
1071 : * Add a custom parameter checking function. If the event parameter is NULL
1072 : * the event structure is allocated internally by this function. If event
1073 : * parameter is provided it must be allocated on the heap and doesn't need to
1074 : * be deallocated by the caller.
1075 : */
1076 0 : void _expect_check(
1077 : const char* const function, const char* const parameter,
1078 : const char* const file, const int line,
1079 : const CheckParameterValue check_function,
1080 : const LargestIntegralType check_data,
1081 : CheckParameterEvent * const event, const int count) {
1082 0 : CheckParameterEvent * const check =
1083 0 : event ? event : (CheckParameterEvent*)malloc(sizeof(*check));
1084 0 : const char* symbols[] = {function, parameter};
1085 0 : check->parameter_name = parameter;
1086 0 : check->check_value = check_function;
1087 0 : check->check_value_data = check_data;
1088 0 : set_source_location(&check->location, file, line);
1089 0 : add_symbol_value(&global_function_parameter_map_head, symbols, 2, check,
1090 : count);
1091 0 : }
1092 :
1093 : /*
1094 : * Add an call expectations that a particular function is called correctly.
1095 : * This is used for code under test that makes calls to several functions
1096 : * in depended upon components (mocks).
1097 : */
1098 :
1099 0 : void _expect_function_call(
1100 : const char * const function_name,
1101 : const char * const file,
1102 : const int line,
1103 : const int count)
1104 : {
1105 : FuncOrderingValue *ordering;
1106 :
1107 0 : assert_non_null(function_name);
1108 0 : assert_non_null(file);
1109 0 : assert_true(count != 0);
1110 :
1111 0 : ordering = (FuncOrderingValue *)malloc(sizeof(*ordering));
1112 :
1113 0 : set_source_location(&ordering->location, file, line);
1114 0 : ordering->function = function_name;
1115 :
1116 0 : list_add_value(&global_call_ordering_head, ordering, count);
1117 0 : }
1118 :
1119 : /* Returns 1 if the specified float values are equal, else returns 0. */
1120 0 : static int float_compare(const float left,
1121 : const float right,
1122 : const float epsilon) {
1123 : float absLeft;
1124 : float absRight;
1125 : float largest;
1126 : float relDiff;
1127 :
1128 0 : float diff = left - right;
1129 0 : diff = (diff >= 0.f) ? diff : -diff;
1130 :
1131 : // Check if the numbers are really close -- needed
1132 : // when comparing numbers near zero.
1133 0 : if (diff <= epsilon) {
1134 0 : return 1;
1135 : }
1136 :
1137 0 : absLeft = (left >= 0.f) ? left : -left;
1138 0 : absRight = (right >= 0.f) ? right : -right;
1139 :
1140 0 : largest = (absRight > absLeft) ? absRight : absLeft;
1141 0 : relDiff = largest * FLT_EPSILON;
1142 :
1143 0 : if (diff > relDiff) {
1144 0 : return 0;
1145 : }
1146 0 : return 1;
1147 : }
1148 :
1149 : /* Returns 1 if the specified float values are equal. If the values are not equal
1150 : * an error is displayed and 0 is returned. */
1151 0 : static int float_values_equal_display_error(const float left,
1152 : const float right,
1153 : const float epsilon) {
1154 0 : const int equal = float_compare(left, right, epsilon);
1155 0 : if (!equal) {
1156 0 : cm_print_error(FloatPrintfFormat " != "
1157 : FloatPrintfFormat "\n", left, right);
1158 : }
1159 0 : return equal;
1160 : }
1161 :
1162 : /* Returns 1 if the specified float values are different. If the values are equal
1163 : * an error is displayed and 0 is returned. */
1164 0 : static int float_values_not_equal_display_error(const float left,
1165 : const float right,
1166 : const float epsilon) {
1167 0 : const int not_equal = (float_compare(left, right, epsilon) == 0);
1168 0 : if (!not_equal) {
1169 0 : cm_print_error(FloatPrintfFormat " == "
1170 : FloatPrintfFormat "\n", left, right);
1171 : }
1172 0 : return not_equal;
1173 : }
1174 :
1175 : /* Returns 1 if the specified double values are equal, else returns 0. */
1176 0 : static int double_compare(const double left,
1177 : const double right,
1178 : const double epsilon) {
1179 : double absLeft;
1180 : double absRight;
1181 : double largest;
1182 : double relDiff;
1183 :
1184 0 : double diff = left - right;
1185 0 : diff = (diff >= 0.f) ? diff : -diff;
1186 :
1187 : /*
1188 : * Check if the numbers are really close -- needed
1189 : * when comparing numbers near zero.
1190 : */
1191 0 : if (diff <= epsilon) {
1192 0 : return 1;
1193 : }
1194 :
1195 0 : absLeft = (left >= 0.f) ? left : -left;
1196 0 : absRight = (right >= 0.f) ? right : -right;
1197 :
1198 0 : largest = (absRight > absLeft) ? absRight : absLeft;
1199 0 : relDiff = largest * FLT_EPSILON;
1200 :
1201 0 : if (diff > relDiff) {
1202 0 : return 0;
1203 : }
1204 :
1205 0 : return 1;
1206 : }
1207 :
1208 : /*
1209 : * Returns 1 if the specified double values are equal. If the values are not
1210 : * equal an error is displayed and 0 is returned.
1211 : */
1212 0 : static int double_values_equal_display_error(const double left,
1213 : const double right,
1214 : const double epsilon) {
1215 0 : const int equal = double_compare(left, right, epsilon);
1216 :
1217 0 : if (!equal) {
1218 0 : cm_print_error(DoublePrintfFormat " != "
1219 : DoublePrintfFormat "\n", left, right);
1220 : }
1221 :
1222 0 : return equal;
1223 : }
1224 :
1225 : /*
1226 : * Returns 1 if the specified double values are different. If the values are
1227 : * equal an error is displayed and 0 is returned.
1228 : */
1229 0 : static int double_values_not_equal_display_error(const double left,
1230 : const double right,
1231 : const double epsilon) {
1232 0 : const int not_equal = (double_compare(left, right, epsilon) == 0);
1233 :
1234 0 : if (!not_equal) {
1235 0 : cm_print_error(DoublePrintfFormat " == "
1236 : DoublePrintfFormat "\n", left, right);
1237 : }
1238 :
1239 0 : return not_equal;
1240 : }
1241 :
1242 : /* Returns 1 if the specified values are equal. If the values are not equal
1243 : * an error is displayed and 0 is returned. */
1244 25600 : static int values_equal_display_error(const LargestIntegralType left,
1245 : const LargestIntegralType right) {
1246 25600 : const int equal = left == right;
1247 25600 : if (!equal) {
1248 0 : cm_print_error(LargestIntegralTypePrintfFormat " != "
1249 : LargestIntegralTypePrintfFormat "\n", left, right);
1250 : }
1251 25600 : return equal;
1252 : }
1253 :
1254 : /*
1255 : * Returns 1 if the specified values are not equal. If the values are equal
1256 : * an error is displayed and 0 is returned. */
1257 67 : static int values_not_equal_display_error(const LargestIntegralType left,
1258 : const LargestIntegralType right) {
1259 67 : const int not_equal = left != right;
1260 67 : if (!not_equal) {
1261 0 : cm_print_error(LargestIntegralTypePrintfFormat " == "
1262 : LargestIntegralTypePrintfFormat "\n", left, right);
1263 : }
1264 67 : return not_equal;
1265 : }
1266 :
1267 :
1268 : /*
1269 : * Determine whether value is contained within check_integer_set.
1270 : * If invert is 0 and the value is in the set 1 is returned, otherwise 0 is
1271 : * returned and an error is displayed. If invert is 1 and the value is not
1272 : * in the set 1 is returned, otherwise 0 is returned and an error is
1273 : * displayed.
1274 : */
1275 0 : static int value_in_set_display_error(
1276 : const LargestIntegralType value,
1277 : const CheckIntegerSet * const check_integer_set, const int invert) {
1278 0 : int succeeded = invert;
1279 0 : assert_non_null(check_integer_set);
1280 : {
1281 0 : const LargestIntegralType * const set = check_integer_set->set;
1282 0 : const size_t size_of_set = check_integer_set->size_of_set;
1283 : size_t i;
1284 0 : for (i = 0; i < size_of_set; i++) {
1285 0 : if (set[i] == value) {
1286 : /* If invert = 0 and item is found, succeeded = 1. */
1287 : /* If invert = 1 and item is found, succeeded = 0. */
1288 0 : succeeded = !succeeded;
1289 0 : break;
1290 : }
1291 : }
1292 0 : if (succeeded) {
1293 0 : return 1;
1294 : }
1295 0 : cm_print_error(LargestIntegralTypePrintfFormatDecimal
1296 : " is %sin the set (",
1297 : value, invert ? "" : "not ");
1298 0 : for (i = 0; i < size_of_set; i++) {
1299 0 : cm_print_error(LargestIntegralTypePrintfFormat ", ", set[i]);
1300 : }
1301 0 : cm_print_error(")\n");
1302 : }
1303 0 : return 0;
1304 : }
1305 :
1306 :
1307 : /*
1308 : * Determine whether a value is within the specified range. If the value is
1309 : * within the specified range 1 is returned. If the value isn't within the
1310 : * specified range an error is displayed and 0 is returned.
1311 : */
1312 0 : static int integer_in_range_display_error(
1313 : const LargestIntegralType value, const LargestIntegralType range_min,
1314 : const LargestIntegralType range_max) {
1315 0 : if (value >= range_min && value <= range_max) {
1316 0 : return 1;
1317 : }
1318 0 : cm_print_error(LargestIntegralTypePrintfFormatDecimal
1319 : " is not within the range "
1320 : LargestIntegralTypePrintfFormatDecimal "-"
1321 : LargestIntegralTypePrintfFormatDecimal "\n",
1322 : value, range_min, range_max);
1323 0 : return 0;
1324 : }
1325 :
1326 :
1327 : /*
1328 : * Determine whether a value is within the specified range. If the value
1329 : * is not within the range 1 is returned. If the value is within the
1330 : * specified range an error is displayed and zero is returned.
1331 : */
1332 0 : static int integer_not_in_range_display_error(
1333 : const LargestIntegralType value, const LargestIntegralType range_min,
1334 : const LargestIntegralType range_max) {
1335 0 : if (value < range_min || value > range_max) {
1336 0 : return 1;
1337 : }
1338 0 : cm_print_error(LargestIntegralTypePrintfFormatDecimal
1339 : " is within the range "
1340 : LargestIntegralTypePrintfFormatDecimal "-"
1341 : LargestIntegralTypePrintfFormatDecimal "\n",
1342 : value, range_min, range_max);
1343 0 : return 0;
1344 : }
1345 :
1346 :
1347 : /*
1348 : * Determine whether the specified strings are equal. If the strings are equal
1349 : * 1 is returned. If they're not equal an error is displayed and 0 is
1350 : * returned.
1351 : */
1352 9 : static int string_equal_display_error(
1353 : const char * const left, const char * const right) {
1354 9 : if (strcmp(left, right) == 0) {
1355 9 : return 1;
1356 : }
1357 0 : cm_print_error("\"%s\" != \"%s\"\n", left, right);
1358 0 : return 0;
1359 : }
1360 :
1361 :
1362 : /*
1363 : * Determine whether the specified strings are equal. If the strings are not
1364 : * equal 1 is returned. If they're not equal an error is displayed and 0 is
1365 : * returned
1366 : */
1367 0 : static int string_not_equal_display_error(
1368 : const char * const left, const char * const right) {
1369 0 : if (strcmp(left, right) != 0) {
1370 0 : return 1;
1371 : }
1372 0 : cm_print_error("\"%s\" == \"%s\"\n", left, right);
1373 0 : return 0;
1374 : }
1375 :
1376 :
1377 : /*
1378 : * Determine whether the specified areas of memory are equal. If they're equal
1379 : * 1 is returned otherwise an error is displayed and 0 is returned.
1380 : */
1381 393 : static int memory_equal_display_error(const char* const a, const char* const b,
1382 : const size_t size) {
1383 393 : size_t differences = 0;
1384 : size_t i;
1385 32403 : for (i = 0; i < size; i++) {
1386 32010 : const char l = a[i];
1387 32010 : const char r = b[i];
1388 32010 : if (l != r) {
1389 0 : if (differences < 16) {
1390 0 : cm_print_error("difference at offset %" PRIdS " 0x%02x 0x%02x\n",
1391 : i, l, r);
1392 : }
1393 0 : differences ++;
1394 : }
1395 : }
1396 393 : if (differences > 0) {
1397 0 : if (differences >= 16) {
1398 0 : cm_print_error("...\n");
1399 : }
1400 0 : cm_print_error("%"PRIdS " bytes of %p and %p differ\n",
1401 : differences, (void *)a, (void *)b);
1402 0 : return 0;
1403 : }
1404 393 : return 1;
1405 : }
1406 :
1407 :
1408 : /*
1409 : * Determine whether the specified areas of memory are not equal. If they're
1410 : * not equal 1 is returned otherwise an error is displayed and 0 is
1411 : * returned.
1412 : */
1413 6 : static int memory_not_equal_display_error(
1414 : const char* const a, const char* const b, const size_t size) {
1415 6 : size_t same = 0;
1416 : size_t i;
1417 2919 : for (i = 0; i < size; i++) {
1418 2913 : const char l = a[i];
1419 2913 : const char r = b[i];
1420 2913 : if (l == r) {
1421 30 : same ++;
1422 : }
1423 : }
1424 6 : if (same == size) {
1425 0 : cm_print_error("%"PRIdS "bytes of %p and %p the same\n",
1426 : same, (void *)a, (void *)b);
1427 0 : return 0;
1428 : }
1429 6 : return 1;
1430 : }
1431 :
1432 :
1433 : /* CheckParameterValue callback to check whether a value is within a set. */
1434 0 : static int check_in_set(const LargestIntegralType value,
1435 : const LargestIntegralType check_value_data) {
1436 0 : return value_in_set_display_error(value,
1437 : cast_largest_integral_type_to_pointer(CheckIntegerSet*,
1438 : check_value_data), 0);
1439 : }
1440 :
1441 :
1442 : /* CheckParameterValue callback to check whether a value isn't within a set. */
1443 0 : static int check_not_in_set(const LargestIntegralType value,
1444 : const LargestIntegralType check_value_data) {
1445 0 : return value_in_set_display_error(value,
1446 : cast_largest_integral_type_to_pointer(CheckIntegerSet*,
1447 : check_value_data), 1);
1448 : }
1449 :
1450 :
1451 : /* Create the callback data for check_in_set() or check_not_in_set() and
1452 : * register a check event. */
1453 0 : static void expect_set(
1454 : const char* const function, const char* const parameter,
1455 : const char* const file, const int line,
1456 : const LargestIntegralType values[], const size_t number_of_values,
1457 : const CheckParameterValue check_function, const int count) {
1458 : CheckIntegerSet * const check_integer_set =
1459 0 : (CheckIntegerSet*)malloc(sizeof(*check_integer_set) +
1460 : (sizeof(values[0]) * number_of_values));
1461 0 : LargestIntegralType * const set = (LargestIntegralType*)(
1462 : check_integer_set + 1);
1463 0 : declare_initialize_value_pointer_pointer(check_data, check_integer_set);
1464 0 : assert_non_null(values);
1465 0 : assert_true(number_of_values);
1466 0 : memcpy(set, values, number_of_values * sizeof(values[0]));
1467 0 : check_integer_set->set = set;
1468 0 : check_integer_set->size_of_set = number_of_values;
1469 0 : _expect_check(
1470 : function, parameter, file, line, check_function,
1471 : check_data, &check_integer_set->event, count);
1472 0 : }
1473 :
1474 :
1475 : /* Add an event to check whether a value is in a set. */
1476 0 : void _expect_in_set(
1477 : const char* const function, const char* const parameter,
1478 : const char* const file, const int line,
1479 : const LargestIntegralType values[], const size_t number_of_values,
1480 : const int count) {
1481 0 : expect_set(function, parameter, file, line, values, number_of_values,
1482 : check_in_set, count);
1483 0 : }
1484 :
1485 :
1486 : /* Add an event to check whether a value isn't in a set. */
1487 0 : void _expect_not_in_set(
1488 : const char* const function, const char* const parameter,
1489 : const char* const file, const int line,
1490 : const LargestIntegralType values[], const size_t number_of_values,
1491 : const int count) {
1492 0 : expect_set(function, parameter, file, line, values, number_of_values,
1493 : check_not_in_set, count);
1494 0 : }
1495 :
1496 :
1497 : /* CheckParameterValue callback to check whether a value is within a range. */
1498 0 : static int check_in_range(const LargestIntegralType value,
1499 : const LargestIntegralType check_value_data) {
1500 0 : CheckIntegerRange * const check_integer_range =
1501 : cast_largest_integral_type_to_pointer(CheckIntegerRange*,
1502 : check_value_data);
1503 0 : assert_non_null(check_integer_range);
1504 0 : return integer_in_range_display_error(value, check_integer_range->minimum,
1505 : check_integer_range->maximum);
1506 : }
1507 :
1508 :
1509 : /* CheckParameterValue callback to check whether a value is not within a range. */
1510 0 : static int check_not_in_range(const LargestIntegralType value,
1511 : const LargestIntegralType check_value_data) {
1512 0 : CheckIntegerRange * const check_integer_range =
1513 : cast_largest_integral_type_to_pointer(CheckIntegerRange*,
1514 : check_value_data);
1515 0 : assert_non_null(check_integer_range);
1516 0 : return integer_not_in_range_display_error(
1517 : value, check_integer_range->minimum, check_integer_range->maximum);
1518 : }
1519 :
1520 :
1521 : /* Create the callback data for check_in_range() or check_not_in_range() and
1522 : * register a check event. */
1523 0 : static void expect_range(
1524 : const char* const function, const char* const parameter,
1525 : const char* const file, const int line,
1526 : const LargestIntegralType minimum, const LargestIntegralType maximum,
1527 : const CheckParameterValue check_function, const int count) {
1528 : CheckIntegerRange * const check_integer_range =
1529 0 : (CheckIntegerRange*)malloc(sizeof(*check_integer_range));
1530 0 : declare_initialize_value_pointer_pointer(check_data, check_integer_range);
1531 0 : check_integer_range->minimum = minimum;
1532 0 : check_integer_range->maximum = maximum;
1533 0 : _expect_check(function, parameter, file, line, check_function,
1534 : check_data, &check_integer_range->event, count);
1535 0 : }
1536 :
1537 :
1538 : /* Add an event to determine whether a parameter is within a range. */
1539 0 : void _expect_in_range(
1540 : const char* const function, const char* const parameter,
1541 : const char* const file, const int line,
1542 : const LargestIntegralType minimum, const LargestIntegralType maximum,
1543 : const int count) {
1544 0 : expect_range(function, parameter, file, line, minimum, maximum,
1545 : check_in_range, count);
1546 0 : }
1547 :
1548 :
1549 : /* Add an event to determine whether a parameter is not within a range. */
1550 0 : void _expect_not_in_range(
1551 : const char* const function, const char* const parameter,
1552 : const char* const file, const int line,
1553 : const LargestIntegralType minimum, const LargestIntegralType maximum,
1554 : const int count) {
1555 0 : expect_range(function, parameter, file, line, minimum, maximum,
1556 : check_not_in_range, count);
1557 0 : }
1558 :
1559 :
1560 : /* CheckParameterValue callback to check whether a value is equal to an
1561 : * expected value. */
1562 0 : static int check_value(const LargestIntegralType value,
1563 : const LargestIntegralType check_value_data) {
1564 0 : return values_equal_display_error(value, check_value_data);
1565 : }
1566 :
1567 :
1568 : /* Add an event to check a parameter equals an expected value. */
1569 0 : void _expect_value(
1570 : const char* const function, const char* const parameter,
1571 : const char* const file, const int line,
1572 : const LargestIntegralType value, const int count) {
1573 0 : _expect_check(function, parameter, file, line, check_value, value, NULL,
1574 : count);
1575 0 : }
1576 :
1577 :
1578 : /* CheckParameterValue callback to check whether a value is not equal to an
1579 : * expected value. */
1580 0 : static int check_not_value(const LargestIntegralType value,
1581 : const LargestIntegralType check_value_data) {
1582 0 : return values_not_equal_display_error(value, check_value_data);
1583 : }
1584 :
1585 :
1586 : /* Add an event to check a parameter is not equal to an expected value. */
1587 0 : void _expect_not_value(
1588 : const char* const function, const char* const parameter,
1589 : const char* const file, const int line,
1590 : const LargestIntegralType value, const int count) {
1591 0 : _expect_check(function, parameter, file, line, check_not_value, value,
1592 : NULL, count);
1593 0 : }
1594 :
1595 :
1596 : /* CheckParameterValue callback to check whether a parameter equals a string. */
1597 0 : static int check_string(const LargestIntegralType value,
1598 : const LargestIntegralType check_value_data) {
1599 0 : return string_equal_display_error(
1600 : cast_largest_integral_type_to_pointer(char*, value),
1601 : cast_largest_integral_type_to_pointer(char*, check_value_data));
1602 : }
1603 :
1604 :
1605 : /* Add an event to check whether a parameter is equal to a string. */
1606 0 : void _expect_string(
1607 : const char* const function, const char* const parameter,
1608 : const char* const file, const int line, const char* string,
1609 : const int count) {
1610 0 : declare_initialize_value_pointer_pointer(string_pointer,
1611 : discard_const(string));
1612 0 : _expect_check(function, parameter, file, line, check_string,
1613 : string_pointer, NULL, count);
1614 0 : }
1615 :
1616 :
1617 : /* CheckParameterValue callback to check whether a parameter is not equals to
1618 : * a string. */
1619 0 : static int check_not_string(const LargestIntegralType value,
1620 : const LargestIntegralType check_value_data) {
1621 0 : return string_not_equal_display_error(
1622 : cast_largest_integral_type_to_pointer(char*, value),
1623 : cast_largest_integral_type_to_pointer(char*, check_value_data));
1624 : }
1625 :
1626 :
1627 : /* Add an event to check whether a parameter is not equal to a string. */
1628 0 : void _expect_not_string(
1629 : const char* const function, const char* const parameter,
1630 : const char* const file, const int line, const char* string,
1631 : const int count) {
1632 0 : declare_initialize_value_pointer_pointer(string_pointer,
1633 : discard_const(string));
1634 0 : _expect_check(function, parameter, file, line, check_not_string,
1635 : string_pointer, NULL, count);
1636 0 : }
1637 :
1638 : /* CheckParameterValue callback to check whether a parameter equals an area of
1639 : * memory. */
1640 0 : static int check_memory(const LargestIntegralType value,
1641 : const LargestIntegralType check_value_data) {
1642 0 : CheckMemoryData * const check = cast_largest_integral_type_to_pointer(
1643 : CheckMemoryData*, check_value_data);
1644 0 : assert_non_null(check);
1645 0 : return memory_equal_display_error(
1646 : cast_largest_integral_type_to_pointer(const char*, value),
1647 0 : (const char*)check->memory, check->size);
1648 : }
1649 :
1650 :
1651 : /* Create the callback data for check_memory() or check_not_memory() and
1652 : * register a check event. */
1653 0 : static void expect_memory_setup(
1654 : const char* const function, const char* const parameter,
1655 : const char* const file, const int line,
1656 : const void * const memory, const size_t size,
1657 : const CheckParameterValue check_function, const int count) {
1658 : CheckMemoryData * const check_data =
1659 0 : (CheckMemoryData*)malloc(sizeof(*check_data) + size);
1660 0 : void * const mem = (void*)(check_data + 1);
1661 0 : declare_initialize_value_pointer_pointer(check_data_pointer, check_data);
1662 0 : assert_non_null(memory);
1663 0 : assert_true(size);
1664 0 : memcpy(mem, memory, size);
1665 0 : check_data->memory = mem;
1666 0 : check_data->size = size;
1667 0 : _expect_check(function, parameter, file, line, check_function,
1668 : check_data_pointer, &check_data->event, count);
1669 0 : }
1670 :
1671 :
1672 : /* Add an event to check whether a parameter matches an area of memory. */
1673 0 : void _expect_memory(
1674 : const char* const function, const char* const parameter,
1675 : const char* const file, const int line, const void* const memory,
1676 : const size_t size, const int count) {
1677 0 : expect_memory_setup(function, parameter, file, line, memory, size,
1678 : check_memory, count);
1679 0 : }
1680 :
1681 :
1682 : /* CheckParameterValue callback to check whether a parameter is not equal to
1683 : * an area of memory. */
1684 0 : static int check_not_memory(const LargestIntegralType value,
1685 : const LargestIntegralType check_value_data) {
1686 0 : CheckMemoryData * const check = cast_largest_integral_type_to_pointer(
1687 : CheckMemoryData*, check_value_data);
1688 0 : assert_non_null(check);
1689 0 : return memory_not_equal_display_error(
1690 : cast_largest_integral_type_to_pointer(const char*, value),
1691 0 : (const char*)check->memory,
1692 : check->size);
1693 : }
1694 :
1695 :
1696 : /* Add an event to check whether a parameter doesn't match an area of memory. */
1697 0 : void _expect_not_memory(
1698 : const char* const function, const char* const parameter,
1699 : const char* const file, const int line, const void* const memory,
1700 : const size_t size, const int count) {
1701 0 : expect_memory_setup(function, parameter, file, line, memory, size,
1702 : check_not_memory, count);
1703 0 : }
1704 :
1705 :
1706 : /* CheckParameterValue callback that always returns 1. */
1707 0 : static int check_any(const LargestIntegralType value,
1708 : const LargestIntegralType check_value_data) {
1709 : (void)value;
1710 : (void)check_value_data;
1711 0 : return 1;
1712 : }
1713 :
1714 :
1715 : /* Add an event to allow any value for a parameter. */
1716 0 : void _expect_any(
1717 : const char* const function, const char* const parameter,
1718 : const char* const file, const int line, const int count) {
1719 0 : _expect_check(function, parameter, file, line, check_any, 0, NULL,
1720 : count);
1721 0 : }
1722 :
1723 :
1724 0 : void _check_expected(
1725 : const char * const function_name, const char * const parameter_name,
1726 : const char* file, const int line, const LargestIntegralType value) {
1727 0 : void *result = NULL;
1728 0 : const char* symbols[] = {function_name, parameter_name};
1729 0 : const int rc = get_symbol_value(&global_function_parameter_map_head,
1730 : symbols, 2, &result);
1731 0 : if (rc) {
1732 0 : CheckParameterEvent * const check = (CheckParameterEvent*)result;
1733 : int check_succeeded;
1734 0 : global_last_parameter_location = check->location;
1735 0 : check_succeeded = check->check_value(value, check->check_value_data);
1736 0 : if (rc == 1) {
1737 0 : free(check);
1738 : }
1739 0 : if (!check_succeeded) {
1740 0 : cm_print_error(SOURCE_LOCATION_FORMAT
1741 : ": error: Check of parameter %s, function %s failed\n"
1742 : SOURCE_LOCATION_FORMAT
1743 : ": note: Expected parameter declared here\n",
1744 : file, line,
1745 : parameter_name, function_name,
1746 : global_last_parameter_location.file,
1747 : global_last_parameter_location.line);
1748 0 : _fail(file, line);
1749 : }
1750 : } else {
1751 0 : cm_print_error(SOURCE_LOCATION_FORMAT ": error: Could not get value "
1752 : "to check parameter %s of function %s\n", file, line,
1753 : parameter_name, function_name);
1754 0 : if (source_location_is_set(&global_last_parameter_location)) {
1755 0 : cm_print_error(SOURCE_LOCATION_FORMAT
1756 : ": note: Previously declared parameter value was declared here\n",
1757 : global_last_parameter_location.file,
1758 : global_last_parameter_location.line);
1759 : } else {
1760 0 : cm_print_error("There were no previously declared parameter values "
1761 : "for this test.\n");
1762 : }
1763 0 : exit_test(1);
1764 : }
1765 0 : }
1766 :
1767 :
1768 : /* Replacement for assert. */
1769 0 : void mock_assert(const int result, const char* const expression,
1770 : const char* const file, const int line) {
1771 0 : if (!result) {
1772 0 : if (global_expecting_assert) {
1773 0 : global_last_failed_assert = expression;
1774 0 : longjmp(global_expect_assert_env, result);
1775 : } else {
1776 0 : cm_print_error("ASSERT: %s\n", expression);
1777 0 : _fail(file, line);
1778 : }
1779 : }
1780 0 : }
1781 :
1782 :
1783 32841 : void _assert_true(const LargestIntegralType result,
1784 : const char * const expression,
1785 : const char * const file, const int line) {
1786 32841 : if (!result) {
1787 0 : cm_print_error("%s\n", expression);
1788 0 : _fail(file, line);
1789 : }
1790 32841 : }
1791 :
1792 0 : void _assert_return_code(const LargestIntegralType result,
1793 : size_t rlen,
1794 : const LargestIntegralType error,
1795 : const char * const expression,
1796 : const char * const file,
1797 : const int line)
1798 : {
1799 : LargestIntegralType valmax;
1800 :
1801 :
1802 0 : switch (rlen) {
1803 0 : case 1:
1804 0 : valmax = 255;
1805 0 : break;
1806 0 : case 2:
1807 0 : valmax = 32767;
1808 0 : break;
1809 0 : case 4:
1810 0 : valmax = 2147483647;
1811 0 : break;
1812 0 : case 8:
1813 : default:
1814 0 : if (rlen > sizeof(valmax)) {
1815 0 : valmax = 2147483647;
1816 : } else {
1817 0 : valmax = 9223372036854775807L;
1818 : }
1819 0 : break;
1820 : }
1821 :
1822 0 : if (result > valmax - 1) {
1823 0 : if (error > 0) {
1824 0 : cm_print_error("%s < 0, errno("
1825 : LargestIntegralTypePrintfFormatDecimal "): %s\n",
1826 : expression, error, strerror((int)error));
1827 : } else {
1828 0 : cm_print_error("%s < 0\n", expression);
1829 : }
1830 0 : _fail(file, line);
1831 : }
1832 0 : }
1833 :
1834 0 : void _assert_float_equal(const float a,
1835 : const float b,
1836 : const float epsilon,
1837 : const char * const file,
1838 : const int line) {
1839 0 : if (!float_values_equal_display_error(a, b, epsilon)) {
1840 0 : _fail(file, line);
1841 : }
1842 0 : }
1843 :
1844 0 : void _assert_float_not_equal(const float a,
1845 : const float b,
1846 : const float epsilon,
1847 : const char * const file,
1848 : const int line) {
1849 0 : if (!float_values_not_equal_display_error(a, b, epsilon)) {
1850 0 : _fail(file, line);
1851 : }
1852 0 : }
1853 :
1854 0 : void _assert_double_equal(const double a,
1855 : const double b,
1856 : const double epsilon,
1857 : const char * const file,
1858 : const int line) {
1859 0 : if (!double_values_equal_display_error(a, b, epsilon)) {
1860 0 : _fail(file, line);
1861 : }
1862 0 : }
1863 :
1864 0 : void _assert_double_not_equal(const double a,
1865 : const double b,
1866 : const double epsilon,
1867 : const char * const file,
1868 : const int line) {
1869 0 : if (!double_values_not_equal_display_error(a, b, epsilon)) {
1870 0 : _fail(file, line);
1871 : }
1872 0 : }
1873 :
1874 25600 : void _assert_int_equal(
1875 : const LargestIntegralType a, const LargestIntegralType b,
1876 : const char * const file, const int line) {
1877 25600 : if (!values_equal_display_error(a, b)) {
1878 0 : _fail(file, line);
1879 : }
1880 25600 : }
1881 :
1882 :
1883 67 : void _assert_int_not_equal(
1884 : const LargestIntegralType a, const LargestIntegralType b,
1885 : const char * const file, const int line) {
1886 67 : if (!values_not_equal_display_error(a, b)) {
1887 0 : _fail(file, line);
1888 : }
1889 67 : }
1890 :
1891 :
1892 9 : void _assert_string_equal(const char * const a, const char * const b,
1893 : const char * const file, const int line) {
1894 9 : if (!string_equal_display_error(a, b)) {
1895 0 : _fail(file, line);
1896 : }
1897 9 : }
1898 :
1899 :
1900 0 : void _assert_string_not_equal(const char * const a, const char * const b,
1901 : const char *file, const int line) {
1902 0 : if (!string_not_equal_display_error(a, b)) {
1903 0 : _fail(file, line);
1904 : }
1905 0 : }
1906 :
1907 :
1908 393 : void _assert_memory_equal(const void * const a, const void * const b,
1909 : const size_t size, const char* const file,
1910 : const int line) {
1911 393 : if (!memory_equal_display_error((const char*)a, (const char*)b, size)) {
1912 0 : _fail(file, line);
1913 : }
1914 393 : }
1915 :
1916 :
1917 6 : void _assert_memory_not_equal(const void * const a, const void * const b,
1918 : const size_t size, const char* const file,
1919 : const int line) {
1920 6 : if (!memory_not_equal_display_error((const char*)a, (const char*)b,
1921 : size)) {
1922 0 : _fail(file, line);
1923 : }
1924 6 : }
1925 :
1926 :
1927 0 : void _assert_in_range(
1928 : const LargestIntegralType value, const LargestIntegralType minimum,
1929 : const LargestIntegralType maximum, const char* const file,
1930 : const int line) {
1931 0 : if (!integer_in_range_display_error(value, minimum, maximum)) {
1932 0 : _fail(file, line);
1933 : }
1934 0 : }
1935 :
1936 0 : void _assert_not_in_range(
1937 : const LargestIntegralType value, const LargestIntegralType minimum,
1938 : const LargestIntegralType maximum, const char* const file,
1939 : const int line) {
1940 0 : if (!integer_not_in_range_display_error(value, minimum, maximum)) {
1941 0 : _fail(file, line);
1942 : }
1943 0 : }
1944 :
1945 0 : void _assert_in_set(const LargestIntegralType value,
1946 : const LargestIntegralType values[],
1947 : const size_t number_of_values, const char* const file,
1948 : const int line) {
1949 : CheckIntegerSet check_integer_set;
1950 0 : check_integer_set.set = values;
1951 0 : check_integer_set.size_of_set = number_of_values;
1952 0 : if (!value_in_set_display_error(value, &check_integer_set, 0)) {
1953 0 : _fail(file, line);
1954 : }
1955 0 : }
1956 :
1957 0 : void _assert_not_in_set(const LargestIntegralType value,
1958 : const LargestIntegralType values[],
1959 : const size_t number_of_values, const char* const file,
1960 : const int line) {
1961 : CheckIntegerSet check_integer_set;
1962 0 : check_integer_set.set = values;
1963 0 : check_integer_set.size_of_set = number_of_values;
1964 0 : if (!value_in_set_display_error(value, &check_integer_set, 1)) {
1965 0 : _fail(file, line);
1966 : }
1967 0 : }
1968 :
1969 :
1970 : /* Get the list of allocated blocks. */
1971 2611 : static ListNode* get_allocated_blocks_list(void) {
1972 : /* If it initialized, initialize the list of allocated blocks. */
1973 2611 : if (!global_allocated_blocks.value) {
1974 5 : list_initialize(&global_allocated_blocks);
1975 5 : global_allocated_blocks.value = (void*)1;
1976 : }
1977 2611 : return &global_allocated_blocks;
1978 : }
1979 :
1980 88 : static void *libc_calloc(size_t nmemb, size_t size)
1981 : {
1982 : #undef calloc
1983 88 : return calloc(nmemb, size);
1984 : #define calloc test_calloc
1985 : }
1986 :
1987 1255 : static void libc_free(void *ptr)
1988 : {
1989 : #undef free
1990 1255 : free(ptr);
1991 : #define free test_free
1992 1255 : }
1993 :
1994 0 : static void *libc_realloc(void *ptr, size_t size)
1995 : {
1996 : #undef realloc
1997 0 : return realloc(ptr, size);
1998 : #define realloc test_realloc
1999 : }
2000 :
2001 : static void vcm_print_error(const char* const format,
2002 : va_list args) CMOCKA_PRINTF_ATTRIBUTE(1, 0);
2003 :
2004 : /* It's important to use the libc malloc and free here otherwise
2005 : * the automatic free of leaked blocks can reap the error messages
2006 : */
2007 0 : static void vcm_print_error(const char* const format, va_list args)
2008 : {
2009 : char buffer[1024];
2010 0 : size_t msg_len = 0;
2011 : va_list ap;
2012 : int len;
2013 0 : va_copy(ap, args);
2014 :
2015 0 : len = vsnprintf(buffer, sizeof(buffer), format, args);
2016 0 : if (len < 0) {
2017 : /* TODO */
2018 0 : goto end;
2019 : }
2020 :
2021 0 : if (cm_error_message == NULL) {
2022 : /* CREATE MESSAGE */
2023 :
2024 0 : cm_error_message = libc_calloc(1, len + 1);
2025 0 : if (cm_error_message == NULL) {
2026 : /* TODO */
2027 0 : goto end;
2028 : }
2029 : } else {
2030 : /* APPEND MESSAGE */
2031 : char *tmp;
2032 :
2033 0 : msg_len = strlen(cm_error_message);
2034 0 : tmp = libc_realloc(cm_error_message, msg_len + len + 1);
2035 0 : if (tmp == NULL) {
2036 0 : goto end;
2037 : }
2038 0 : cm_error_message = tmp;
2039 : }
2040 :
2041 0 : if (((size_t)len) < sizeof(buffer)) {
2042 : /* Use len + 1 to also copy '\0' */
2043 0 : memcpy(cm_error_message + msg_len, buffer, len + 1);
2044 : } else {
2045 0 : vsnprintf(cm_error_message + msg_len, len, format, ap);
2046 : }
2047 0 : end:
2048 0 : va_end(ap);
2049 :
2050 0 : }
2051 :
2052 1167 : static void vcm_free_error(char *err_msg)
2053 : {
2054 1167 : libc_free(err_msg);
2055 1167 : }
2056 :
2057 : /* Use the real malloc in this function. */
2058 : #undef malloc
2059 0 : void* _test_malloc(const size_t size, const char* file, const int line) {
2060 0 : char *ptr = NULL;
2061 : MallocBlockInfo block_info;
2062 0 : ListNode * const block_list = get_allocated_blocks_list();
2063 : size_t allocate_size;
2064 0 : char *block = NULL;
2065 :
2066 0 : allocate_size = size + (MALLOC_GUARD_SIZE * 2) +
2067 : sizeof(struct MallocBlockInfoData) + MALLOC_ALIGNMENT;
2068 0 : assert_true(allocate_size > size);
2069 :
2070 0 : block = (char *)malloc(allocate_size);
2071 0 : assert_non_null(block);
2072 :
2073 : /* Calculate the returned address. */
2074 0 : ptr = (char*)(((size_t)block + MALLOC_GUARD_SIZE +
2075 0 : sizeof(struct MallocBlockInfoData) +
2076 0 : MALLOC_ALIGNMENT) & ~(MALLOC_ALIGNMENT - 1));
2077 :
2078 : /* Initialize the guard blocks. */
2079 0 : memset(ptr - MALLOC_GUARD_SIZE, MALLOC_GUARD_PATTERN, MALLOC_GUARD_SIZE);
2080 0 : memset(ptr + size, MALLOC_GUARD_PATTERN, MALLOC_GUARD_SIZE);
2081 0 : memset(ptr, MALLOC_ALLOC_PATTERN, size);
2082 :
2083 0 : block_info.ptr = ptr - (MALLOC_GUARD_SIZE +
2084 : sizeof(struct MallocBlockInfoData));
2085 0 : set_source_location(&block_info.data->location, file, line);
2086 0 : block_info.data->allocated_size = allocate_size;
2087 0 : block_info.data->size = size;
2088 0 : block_info.data->block = block;
2089 0 : block_info.data->node.value = block_info.ptr;
2090 0 : list_add(block_list, &block_info.data->node);
2091 0 : return ptr;
2092 : }
2093 : #define malloc test_malloc
2094 :
2095 :
2096 0 : void* _test_calloc(const size_t number_of_elements, const size_t size,
2097 : const char* file, const int line) {
2098 0 : void* const ptr = _test_malloc(number_of_elements * size, file, line);
2099 0 : if (ptr) {
2100 0 : memset(ptr, 0, number_of_elements * size);
2101 : }
2102 0 : return ptr;
2103 : }
2104 : #define calloc test_calloc
2105 :
2106 :
2107 : /* Use the real free in this function. */
2108 : #undef free
2109 0 : void _test_free(void* const ptr, const char* file, const int line) {
2110 : unsigned int i;
2111 0 : char *block = discard_const_p(char, ptr);
2112 : MallocBlockInfo block_info;
2113 :
2114 0 : if (ptr == NULL) {
2115 0 : return;
2116 : }
2117 :
2118 0 : _assert_true(cast_ptr_to_largest_integral_type(ptr), "ptr", file, line);
2119 0 : block_info.ptr = block - (MALLOC_GUARD_SIZE +
2120 : sizeof(struct MallocBlockInfoData));
2121 : /* Check the guard blocks. */
2122 : {
2123 0 : char *guards[2] = {block - MALLOC_GUARD_SIZE,
2124 0 : block + block_info.data->size};
2125 0 : for (i = 0; i < ARRAY_SIZE(guards); i++) {
2126 : unsigned int j;
2127 0 : char * const guard = guards[i];
2128 0 : for (j = 0; j < MALLOC_GUARD_SIZE; j++) {
2129 0 : const char diff = guard[j] - MALLOC_GUARD_PATTERN;
2130 0 : if (diff) {
2131 0 : cm_print_error(SOURCE_LOCATION_FORMAT
2132 : ": error: Guard block of %p size=%lu is corrupt\n"
2133 : SOURCE_LOCATION_FORMAT ": note: allocated here at %p\n",
2134 : file,
2135 : line,
2136 : ptr,
2137 0 : (unsigned long)block_info.data->size,
2138 0 : block_info.data->location.file,
2139 0 : block_info.data->location.line,
2140 0 : (void *)&guard[j]);
2141 0 : _fail(file, line);
2142 : }
2143 : }
2144 : }
2145 : }
2146 0 : list_remove(&block_info.data->node, NULL, NULL);
2147 :
2148 0 : block = discard_const_p(char, block_info.data->block);
2149 0 : memset(block, MALLOC_FREE_PATTERN, block_info.data->allocated_size);
2150 0 : free(block);
2151 : }
2152 : #define free test_free
2153 :
2154 : #undef realloc
2155 0 : void *_test_realloc(void *ptr,
2156 : const size_t size,
2157 : const char *file,
2158 : const int line)
2159 : {
2160 : MallocBlockInfo block_info;
2161 0 : char *block = ptr;
2162 0 : size_t block_size = size;
2163 : void *new_block;
2164 :
2165 0 : if (ptr == NULL) {
2166 0 : return _test_malloc(size, file, line);
2167 : }
2168 :
2169 0 : if (size == 0) {
2170 0 : _test_free(ptr, file, line);
2171 0 : return NULL;
2172 : }
2173 :
2174 0 : block_info.ptr = block - (MALLOC_GUARD_SIZE +
2175 : sizeof(struct MallocBlockInfoData));
2176 :
2177 0 : new_block = _test_malloc(size, file, line);
2178 0 : if (new_block == NULL) {
2179 0 : return NULL;
2180 : }
2181 :
2182 0 : if (block_info.data->size < size) {
2183 0 : block_size = block_info.data->size;
2184 : }
2185 :
2186 0 : memcpy(new_block, ptr, block_size);
2187 :
2188 : /* Free previous memory */
2189 0 : _test_free(ptr, file, line);
2190 :
2191 0 : return new_block;
2192 : }
2193 : #define realloc test_realloc
2194 :
2195 : /* Crudely checkpoint the current heap state. */
2196 1268 : static const ListNode* check_point_allocated_blocks(void) {
2197 1268 : return get_allocated_blocks_list()->prev;
2198 : }
2199 :
2200 :
2201 : /* Display the blocks allocated after the specified check point. This
2202 : * function returns the number of blocks displayed. */
2203 1343 : static size_t display_allocated_blocks(const ListNode * const check_point) {
2204 1343 : const ListNode * const head = get_allocated_blocks_list();
2205 : const ListNode *node;
2206 1343 : size_t allocated_blocks = 0;
2207 1343 : assert_non_null(check_point);
2208 1343 : assert_non_null(check_point->next);
2209 :
2210 1343 : for (node = check_point->next; node != head; node = node->next) {
2211 0 : const MallocBlockInfo block_info = {
2212 0 : .ptr = discard_const(node->value),
2213 : };
2214 0 : assert_non_null(block_info.ptr);
2215 :
2216 0 : if (allocated_blocks == 0) {
2217 0 : cm_print_error("Blocks allocated...\n");
2218 : }
2219 0 : cm_print_error(SOURCE_LOCATION_FORMAT ": note: block %p allocated here\n",
2220 0 : block_info.data->location.file,
2221 0 : block_info.data->location.line,
2222 0 : block_info.data->block);
2223 0 : allocated_blocks++;
2224 : }
2225 1343 : return allocated_blocks;
2226 : }
2227 :
2228 :
2229 : /* Free all blocks allocated after the specified check point. */
2230 0 : static void free_allocated_blocks(const ListNode * const check_point) {
2231 0 : const ListNode * const head = get_allocated_blocks_list();
2232 : const ListNode *node;
2233 0 : assert_non_null(check_point);
2234 :
2235 0 : node = check_point->next;
2236 0 : assert_non_null(node);
2237 :
2238 0 : while (node != head) {
2239 0 : const MallocBlockInfo block_info = {
2240 0 : .ptr = discard_const(node->value),
2241 : };
2242 0 : node = node->next;
2243 0 : free(discard_const_p(char, block_info.data) +
2244 : sizeof(struct MallocBlockInfoData) +
2245 : MALLOC_GUARD_SIZE);
2246 : }
2247 0 : }
2248 :
2249 :
2250 : /* Fail if any any blocks are allocated after the specified check point. */
2251 1343 : static void fail_if_blocks_allocated(const ListNode * const check_point,
2252 : const char * const test_name) {
2253 1343 : const size_t allocated_blocks = display_allocated_blocks(check_point);
2254 1343 : if (allocated_blocks > 0) {
2255 0 : free_allocated_blocks(check_point);
2256 0 : cm_print_error("ERROR: %s leaked %zu block(s)\n", test_name,
2257 : allocated_blocks);
2258 0 : exit_test(1);
2259 : }
2260 1343 : }
2261 :
2262 :
2263 0 : void _fail(const char * const file, const int line) {
2264 0 : enum cm_message_output output = cm_get_output();
2265 :
2266 0 : switch(output) {
2267 0 : case CM_OUTPUT_STDOUT:
2268 0 : cm_print_error("[ LINE ] --- " SOURCE_LOCATION_FORMAT ": error: Failure!", file, line);
2269 0 : break;
2270 0 : default:
2271 0 : cm_print_error(SOURCE_LOCATION_FORMAT ": error: Failure!", file, line);
2272 0 : break;
2273 : }
2274 0 : exit_test(1);
2275 :
2276 : /* Unreachable */
2277 0 : exit(-1);
2278 : }
2279 :
2280 :
2281 : #ifndef _WIN32
2282 0 : CMOCKA_NORETURN static void exception_handler(int sig) {
2283 0 : const char *sig_strerror = "";
2284 :
2285 : #ifdef HAVE_STRSIGNAL
2286 : sig_strerror = strsignal(sig);
2287 : #endif
2288 :
2289 0 : cm_print_error("Test failed with exception: %s(%d)",
2290 : sig_strerror, sig);
2291 0 : exit_test(1);
2292 :
2293 : /* Unreachable */
2294 0 : exit(-1);
2295 : }
2296 :
2297 : #else /* _WIN32 */
2298 :
2299 : static LONG WINAPI exception_filter(EXCEPTION_POINTERS *exception_pointers) {
2300 : EXCEPTION_RECORD * const exception_record =
2301 : exception_pointers->ExceptionRecord;
2302 : const DWORD code = exception_record->ExceptionCode;
2303 : unsigned int i;
2304 : for (i = 0; i < ARRAY_SIZE(exception_codes); i++) {
2305 : const ExceptionCodeInfo * const code_info = &exception_codes[i];
2306 : if (code == code_info->code) {
2307 : static int shown_debug_message = 0;
2308 : fflush(stdout);
2309 : cm_print_error("%s occurred at %p.\n", code_info->description,
2310 : exception_record->ExceptionAddress);
2311 : if (!shown_debug_message) {
2312 : cm_print_error(
2313 : "\n"
2314 : "To debug in Visual Studio...\n"
2315 : "1. Select menu item File->Open Project\n"
2316 : "2. Change 'Files of type' to 'Executable Files'\n"
2317 : "3. Open this executable.\n"
2318 : "4. Select menu item Debug->Start\n"
2319 : "\n"
2320 : "Alternatively, set the environment variable \n"
2321 : "UNIT_TESTING_DEBUG to 1 and rebuild this executable, \n"
2322 : "then click 'Debug' in the popup dialog box.\n"
2323 : "\n");
2324 : shown_debug_message = 1;
2325 : }
2326 : exit_test(0);
2327 : return EXCEPTION_EXECUTE_HANDLER;
2328 : }
2329 : }
2330 : return EXCEPTION_CONTINUE_SEARCH;
2331 : }
2332 : #endif /* !_WIN32 */
2333 :
2334 0 : void cm_print_error(const char * const format, ...)
2335 : {
2336 : va_list args;
2337 0 : va_start(args, format);
2338 0 : if (cm_error_message_enabled) {
2339 0 : vcm_print_error(format, args);
2340 : } else {
2341 0 : vprint_error(format, args);
2342 : }
2343 0 : va_end(args);
2344 0 : }
2345 :
2346 : /* Standard output and error print methods. */
2347 2510 : void vprint_message(const char* const format, va_list args)
2348 : {
2349 : char buffer[4096];
2350 :
2351 2510 : vsnprintf(buffer, sizeof(buffer), format, args);
2352 2510 : printf("%s", buffer);
2353 2510 : fflush(stdout);
2354 : #ifdef _WIN32
2355 : OutputDebugString(buffer);
2356 : #endif /* _WIN32 */
2357 2510 : }
2358 :
2359 :
2360 88 : void vprint_error(const char* const format, va_list args)
2361 : {
2362 : char buffer[4096];
2363 :
2364 88 : vsnprintf(buffer, sizeof(buffer), format, args);
2365 88 : fprintf(stderr, "%s", buffer);
2366 88 : fflush(stderr);
2367 : #ifdef _WIN32
2368 : OutputDebugString(buffer);
2369 : #endif /* _WIN32 */
2370 88 : }
2371 :
2372 :
2373 2510 : void print_message(const char* const format, ...) {
2374 : va_list args;
2375 2510 : va_start(args, format);
2376 2510 : vprint_message(format, args);
2377 2510 : va_end(args);
2378 2510 : }
2379 :
2380 :
2381 88 : void print_error(const char* const format, ...) {
2382 : va_list args;
2383 88 : va_start(args, format);
2384 88 : vprint_error(format, args);
2385 88 : va_end(args);
2386 88 : }
2387 :
2388 : /* New formatter */
2389 2510 : static enum cm_message_output cm_get_output(void)
2390 : {
2391 2510 : enum cm_message_output output = global_msg_output;
2392 : char *env;
2393 :
2394 2510 : env = getenv("CMOCKA_MESSAGE_OUTPUT");
2395 2510 : if (env != NULL) {
2396 0 : if (strcasecmp(env, "STDOUT") == 0) {
2397 0 : output = CM_OUTPUT_STDOUT;
2398 0 : } else if (strcasecmp(env, "SUBUNIT") == 0) {
2399 0 : output = CM_OUTPUT_SUBUNIT;
2400 0 : } else if (strcasecmp(env, "TAP") == 0) {
2401 0 : output = CM_OUTPUT_TAP;
2402 0 : } else if (strcasecmp(env, "XML") == 0) {
2403 0 : output = CM_OUTPUT_XML;
2404 : }
2405 : }
2406 :
2407 2510 : return output;
2408 : }
2409 :
2410 : enum cm_printf_type {
2411 : PRINTF_TEST_START,
2412 : PRINTF_TEST_SUCCESS,
2413 : PRINTF_TEST_FAILURE,
2414 : PRINTF_TEST_ERROR,
2415 : PRINTF_TEST_SKIPPED,
2416 : };
2417 :
2418 : static int xml_printed;
2419 : static int file_append;
2420 :
2421 0 : static void cmprintf_group_finish_xml(const char *group_name,
2422 : size_t total_executed,
2423 : size_t total_failed,
2424 : size_t total_errors,
2425 : size_t total_skipped,
2426 : double total_runtime,
2427 : struct CMUnitTestState *cm_tests)
2428 : {
2429 0 : FILE *fp = stdout;
2430 0 : int file_opened = 0;
2431 0 : int multiple_files = 0;
2432 : char *env;
2433 : size_t i;
2434 :
2435 0 : env = getenv("CMOCKA_XML_FILE");
2436 0 : if (env != NULL) {
2437 : char buf[1024];
2438 : int rc;
2439 :
2440 0 : snprintf(buf, sizeof(buf), "%s", env);
2441 :
2442 0 : rc = c_strreplace(buf, sizeof(buf), "%g", group_name, &multiple_files);
2443 0 : if (rc < 0) {
2444 0 : snprintf(buf, sizeof(buf), "%s", env);
2445 : }
2446 :
2447 0 : fp = fopen(buf, "r");
2448 0 : if (fp == NULL) {
2449 0 : fp = fopen(buf, "w");
2450 0 : if (fp != NULL) {
2451 0 : file_append = 1;
2452 0 : file_opened = 1;
2453 : } else {
2454 0 : fp = stderr;
2455 : }
2456 : } else {
2457 0 : fclose(fp);
2458 0 : if (file_append) {
2459 0 : fp = fopen(buf, "a");
2460 0 : if (fp != NULL) {
2461 0 : file_opened = 1;
2462 0 : xml_printed = 1;
2463 : } else {
2464 0 : fp = stderr;
2465 : }
2466 : } else {
2467 0 : fp = stderr;
2468 : }
2469 : }
2470 : }
2471 :
2472 0 : if (!xml_printed || (file_opened && !file_append)) {
2473 0 : fprintf(fp, "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");
2474 0 : if (!file_opened) {
2475 0 : xml_printed = 1;
2476 : }
2477 : }
2478 :
2479 0 : fprintf(fp, "<testsuites>\n");
2480 0 : fprintf(fp, " <testsuite name=\"%s\" time=\"%.3f\" "
2481 : "tests=\"%u\" failures=\"%u\" errors=\"%u\" skipped=\"%u\" >\n",
2482 : group_name,
2483 : total_runtime, /* seconds */
2484 : (unsigned)total_executed,
2485 : (unsigned)total_failed,
2486 : (unsigned)total_errors,
2487 : (unsigned)total_skipped);
2488 :
2489 0 : for (i = 0; i < total_executed; i++) {
2490 0 : struct CMUnitTestState *cmtest = &cm_tests[i];
2491 :
2492 0 : fprintf(fp, " <testcase name=\"%s\" time=\"%.3f\" >\n",
2493 0 : cmtest->test->name, cmtest->runtime);
2494 :
2495 0 : switch (cmtest->status) {
2496 0 : case CM_TEST_ERROR:
2497 : case CM_TEST_FAILED:
2498 0 : if (cmtest->error_message != NULL) {
2499 0 : fprintf(fp, " <failure><![CDATA[%s]]></failure>\n",
2500 : cmtest->error_message);
2501 : } else {
2502 0 : fprintf(fp, " <failure message=\"Unknown error\" />\n");
2503 : }
2504 0 : break;
2505 0 : case CM_TEST_SKIPPED:
2506 0 : fprintf(fp, " <skipped/>\n");
2507 0 : break;
2508 :
2509 0 : case CM_TEST_PASSED:
2510 : case CM_TEST_NOT_STARTED:
2511 0 : break;
2512 : }
2513 :
2514 0 : fprintf(fp, " </testcase>\n");
2515 : }
2516 :
2517 0 : fprintf(fp, " </testsuite>\n");
2518 0 : fprintf(fp, "</testsuites>\n");
2519 :
2520 0 : if (file_opened) {
2521 0 : fclose(fp);
2522 : }
2523 0 : }
2524 :
2525 88 : static void cmprintf_group_start_standard(const char *group_name,
2526 : const size_t num_tests)
2527 : {
2528 88 : print_message("[==========] %s: Running %zu test(s).\n",
2529 : group_name,
2530 : num_tests);
2531 88 : }
2532 :
2533 88 : static void cmprintf_group_finish_standard(const char *group_name,
2534 : size_t total_executed,
2535 : size_t total_passed,
2536 : size_t total_failed,
2537 : size_t total_errors,
2538 : size_t total_skipped,
2539 : struct CMUnitTestState *cm_tests)
2540 : {
2541 : size_t i;
2542 :
2543 88 : print_message("[==========] %s: %zu test(s) run.\n",
2544 : group_name,
2545 : total_executed);
2546 88 : print_error("[ PASSED ] %u test(s).\n",
2547 : (unsigned)(total_passed));
2548 :
2549 88 : if (total_skipped) {
2550 0 : print_error("[ SKIPPED ] %s: %zu test(s), listed below:\n",
2551 : group_name,
2552 : total_skipped);
2553 0 : for (i = 0; i < total_executed; i++) {
2554 0 : struct CMUnitTestState *cmtest = &cm_tests[i];
2555 :
2556 0 : if (cmtest->status == CM_TEST_SKIPPED) {
2557 0 : print_error("[ SKIPPED ] %s\n", cmtest->test->name);
2558 : }
2559 : }
2560 0 : print_error("\n %zu SKIPPED TEST(S)\n", total_skipped);
2561 : }
2562 :
2563 88 : if (total_failed) {
2564 0 : print_error("[ FAILED ] %s: %zu test(s), listed below:\n",
2565 : group_name,
2566 : total_failed);
2567 0 : for (i = 0; i < total_executed; i++) {
2568 0 : struct CMUnitTestState *cmtest = &cm_tests[i];
2569 :
2570 0 : if (cmtest->status == CM_TEST_FAILED) {
2571 0 : print_error("[ FAILED ] %s\n", cmtest->test->name);
2572 : }
2573 : }
2574 0 : print_error("\n %zu FAILED TEST(S)\n",
2575 : (total_failed + total_errors));
2576 : }
2577 88 : }
2578 :
2579 2334 : static void cmprintf_standard(enum cm_printf_type type,
2580 : const char *test_name,
2581 : const char *error_message)
2582 : {
2583 2334 : switch (type) {
2584 1167 : case PRINTF_TEST_START:
2585 1167 : print_message("[ RUN ] %s\n", test_name);
2586 1167 : break;
2587 1167 : case PRINTF_TEST_SUCCESS:
2588 1167 : print_message("[ OK ] %s\n", test_name);
2589 1167 : break;
2590 0 : case PRINTF_TEST_FAILURE:
2591 0 : if (error_message != NULL) {
2592 0 : print_error("[ ERROR ] --- %s\n", error_message);
2593 : }
2594 0 : print_message("[ FAILED ] %s\n", test_name);
2595 0 : break;
2596 0 : case PRINTF_TEST_SKIPPED:
2597 0 : print_message("[ SKIPPED ] %s\n", test_name);
2598 0 : break;
2599 0 : case PRINTF_TEST_ERROR:
2600 0 : if (error_message != NULL) {
2601 0 : print_error("%s\n", error_message);
2602 : }
2603 0 : print_error("[ ERROR ] %s\n", test_name);
2604 0 : break;
2605 : }
2606 2334 : }
2607 :
2608 0 : static void cmprintf_group_start_tap(const size_t num_tests)
2609 : {
2610 : static bool version_printed = false;
2611 0 : if (!version_printed) {
2612 0 : print_message("TAP version 13\n");
2613 0 : version_printed = true;
2614 : }
2615 :
2616 0 : print_message("1..%u\n", (unsigned)num_tests);
2617 0 : }
2618 :
2619 0 : static void cmprintf_group_finish_tap(const char *group_name,
2620 : size_t total_executed,
2621 : size_t total_passed,
2622 : size_t total_skipped)
2623 : {
2624 0 : const char *status = "not ok";
2625 0 : if (total_passed + total_skipped == total_executed) {
2626 0 : status = "ok";
2627 : }
2628 0 : print_message("# %s - %s\n", status, group_name);
2629 0 : }
2630 :
2631 0 : static void cmprintf_tap(enum cm_printf_type type,
2632 : size_t test_number,
2633 : const char *test_name,
2634 : const char *error_message)
2635 : {
2636 0 : switch (type) {
2637 0 : case PRINTF_TEST_START:
2638 0 : break;
2639 0 : case PRINTF_TEST_SUCCESS:
2640 0 : print_message("ok %u - %s\n", (unsigned)test_number, test_name);
2641 0 : break;
2642 0 : case PRINTF_TEST_FAILURE:
2643 0 : print_message("not ok %u - %s\n", (unsigned)test_number, test_name);
2644 0 : if (error_message != NULL) {
2645 : char *msg;
2646 : char *p;
2647 :
2648 0 : msg = strdup(error_message);
2649 0 : if (msg == NULL) {
2650 0 : return;
2651 : }
2652 0 : p = msg;
2653 :
2654 0 : while (p[0] != '\0') {
2655 0 : char *q = p;
2656 :
2657 0 : p = strchr(q, '\n');
2658 0 : if (p != NULL) {
2659 0 : p[0] = '\0';
2660 : }
2661 :
2662 0 : print_message("# %s\n", q);
2663 :
2664 0 : if (p == NULL) {
2665 0 : break;
2666 : }
2667 0 : p++;
2668 : }
2669 0 : libc_free(msg);
2670 : }
2671 0 : break;
2672 0 : case PRINTF_TEST_SKIPPED:
2673 0 : print_message("ok %u # SKIP %s\n", (unsigned)test_number, test_name);
2674 0 : break;
2675 0 : case PRINTF_TEST_ERROR:
2676 0 : print_message("not ok %u - %s %s\n",
2677 : (unsigned)test_number, test_name, error_message);
2678 0 : break;
2679 : }
2680 : }
2681 :
2682 0 : static void cmprintf_subunit(enum cm_printf_type type,
2683 : const char *test_name,
2684 : const char *error_message)
2685 : {
2686 0 : switch (type) {
2687 0 : case PRINTF_TEST_START:
2688 0 : print_message("test: %s\n", test_name);
2689 0 : break;
2690 0 : case PRINTF_TEST_SUCCESS:
2691 0 : print_message("success: %s\n", test_name);
2692 0 : break;
2693 0 : case PRINTF_TEST_FAILURE:
2694 0 : print_message("failure: %s", test_name);
2695 0 : if (error_message != NULL) {
2696 0 : print_message(" [\n%s\n]\n", error_message);
2697 : }
2698 0 : break;
2699 0 : case PRINTF_TEST_SKIPPED:
2700 0 : print_message("skip: %s\n", test_name);
2701 0 : break;
2702 0 : case PRINTF_TEST_ERROR:
2703 0 : print_message("error: %s [ %s ]\n", test_name, error_message);
2704 0 : break;
2705 : }
2706 0 : }
2707 :
2708 88 : static void cmprintf_group_start(const char *group_name,
2709 : const size_t num_tests)
2710 : {
2711 : enum cm_message_output output;
2712 :
2713 88 : output = cm_get_output();
2714 :
2715 88 : switch (output) {
2716 88 : case CM_OUTPUT_STDOUT:
2717 88 : cmprintf_group_start_standard(group_name, num_tests);
2718 88 : break;
2719 0 : case CM_OUTPUT_SUBUNIT:
2720 0 : break;
2721 0 : case CM_OUTPUT_TAP:
2722 0 : cmprintf_group_start_tap(num_tests);
2723 0 : break;
2724 0 : case CM_OUTPUT_XML:
2725 0 : break;
2726 : }
2727 88 : }
2728 :
2729 88 : static void cmprintf_group_finish(const char *group_name,
2730 : size_t total_executed,
2731 : size_t total_passed,
2732 : size_t total_failed,
2733 : size_t total_errors,
2734 : size_t total_skipped,
2735 : double total_runtime,
2736 : struct CMUnitTestState *cm_tests)
2737 : {
2738 : enum cm_message_output output;
2739 :
2740 88 : output = cm_get_output();
2741 :
2742 88 : switch (output) {
2743 88 : case CM_OUTPUT_STDOUT:
2744 88 : cmprintf_group_finish_standard(group_name,
2745 : total_executed,
2746 : total_passed,
2747 : total_failed,
2748 : total_errors,
2749 : total_skipped,
2750 : cm_tests);
2751 88 : break;
2752 0 : case CM_OUTPUT_SUBUNIT:
2753 0 : break;
2754 0 : case CM_OUTPUT_TAP:
2755 0 : cmprintf_group_finish_tap(group_name,
2756 : total_executed,
2757 : total_passed,
2758 : total_skipped);
2759 0 : break;
2760 0 : case CM_OUTPUT_XML:
2761 0 : cmprintf_group_finish_xml(group_name,
2762 : total_executed,
2763 : total_failed,
2764 : total_errors,
2765 : total_skipped,
2766 : total_runtime,
2767 : cm_tests);
2768 0 : break;
2769 : }
2770 88 : }
2771 :
2772 2334 : static void cmprintf(enum cm_printf_type type,
2773 : size_t test_number,
2774 : const char *test_name,
2775 : const char *error_message)
2776 : {
2777 : enum cm_message_output output;
2778 :
2779 2334 : output = cm_get_output();
2780 :
2781 2334 : switch (output) {
2782 2334 : case CM_OUTPUT_STDOUT:
2783 2334 : cmprintf_standard(type, test_name, error_message);
2784 2334 : break;
2785 0 : case CM_OUTPUT_SUBUNIT:
2786 0 : cmprintf_subunit(type, test_name, error_message);
2787 0 : break;
2788 0 : case CM_OUTPUT_TAP:
2789 0 : cmprintf_tap(type, test_number, test_name, error_message);
2790 0 : break;
2791 0 : case CM_OUTPUT_XML:
2792 0 : break;
2793 : }
2794 2334 : }
2795 :
2796 0 : void cmocka_set_message_output(enum cm_message_output output)
2797 : {
2798 0 : global_msg_output = output;
2799 0 : }
2800 :
2801 0 : void cmocka_set_test_filter(const char *pattern)
2802 : {
2803 0 : global_test_filter_pattern = pattern;
2804 0 : }
2805 :
2806 0 : void cmocka_set_skip_filter(const char *pattern)
2807 : {
2808 0 : global_skip_filter_pattern = pattern;
2809 0 : }
2810 :
2811 : /****************************************************************************
2812 : * TIME CALCULATIONS
2813 : ****************************************************************************/
2814 :
2815 : #ifdef HAVE_STRUCT_TIMESPEC
2816 : static struct timespec cm_tspecdiff(struct timespec time1,
2817 : struct timespec time0)
2818 : {
2819 : struct timespec ret;
2820 : int xsec = 0;
2821 : int sign = 1;
2822 :
2823 : if (time0.tv_nsec > time1.tv_nsec) {
2824 : xsec = (int) ((time0.tv_nsec - time1.tv_nsec) / (1E9 + 1));
2825 : time0.tv_nsec -= (long int) (1E9 * xsec);
2826 : time0.tv_sec += xsec;
2827 : }
2828 :
2829 : if ((time1.tv_nsec - time0.tv_nsec) > 1E9) {
2830 : xsec = (int) ((time1.tv_nsec - time0.tv_nsec) / 1E9);
2831 : time0.tv_nsec += (long int) (1E9 * xsec);
2832 : time0.tv_sec -= xsec;
2833 : }
2834 :
2835 : ret.tv_sec = time1.tv_sec - time0.tv_sec;
2836 : ret.tv_nsec = time1.tv_nsec - time0.tv_nsec;
2837 :
2838 : if (time1.tv_sec < time0.tv_sec) {
2839 : sign = -1;
2840 : }
2841 :
2842 : ret.tv_sec = ret.tv_sec * sign;
2843 :
2844 : return ret;
2845 : }
2846 :
2847 : static double cm_secdiff(struct timespec clock1, struct timespec clock0)
2848 : {
2849 : double ret;
2850 : struct timespec diff;
2851 :
2852 : diff = cm_tspecdiff(clock1, clock0);
2853 :
2854 : ret = (double) diff.tv_sec;
2855 : ret += (double) diff.tv_nsec / (double) 1E9;
2856 :
2857 : return ret;
2858 : }
2859 : #endif /* HAVE_STRUCT_TIMESPEC */
2860 :
2861 : /****************************************************************************
2862 : * CMOCKA TEST RUNNER
2863 : ****************************************************************************/
2864 1356 : static int cmocka_run_one_test_or_fixture(const char *function_name,
2865 : CMUnitTestFunction test_func,
2866 : CMFixtureFunction setup_func,
2867 : CMFixtureFunction teardown_func,
2868 : void ** const volatile state,
2869 : const void *const heap_check_point)
2870 : {
2871 1356 : const ListNode * const volatile check_point = (const ListNode*)
2872 : (heap_check_point != NULL ?
2873 1167 : heap_check_point : check_point_allocated_blocks());
2874 1356 : int handle_exceptions = 1;
2875 1356 : void *current_state = NULL;
2876 1356 : int rc = 0;
2877 :
2878 : /* FIXME check only one test or fixture is set */
2879 :
2880 : /* Detect if we should handle exceptions */
2881 : #ifdef _WIN32
2882 : handle_exceptions = !IsDebuggerPresent();
2883 : #endif /* _WIN32 */
2884 : #ifdef UNIT_TESTING_DEBUG
2885 : handle_exceptions = 0;
2886 : #endif /* UNIT_TESTING_DEBUG */
2887 :
2888 :
2889 1356 : if (handle_exceptions) {
2890 : #ifndef _WIN32
2891 : unsigned int i;
2892 8136 : for (i = 0; i < ARRAY_SIZE(exception_signals); i++) {
2893 6780 : default_signal_functions[i] = signal(
2894 6780 : exception_signals[i], exception_handler);
2895 : }
2896 : #else /* _WIN32 */
2897 : previous_exception_filter = SetUnhandledExceptionFilter(
2898 : exception_filter);
2899 : #endif /* !_WIN32 */
2900 : }
2901 :
2902 : /* Init the test structure */
2903 1356 : initialize_testing(function_name);
2904 :
2905 1356 : global_running_test = 1;
2906 :
2907 1356 : if (cm_setjmp(global_run_test_env) == 0) {
2908 1356 : if (test_func != NULL) {
2909 1167 : test_func(state != NULL ? state : ¤t_state);
2910 :
2911 1167 : fail_if_blocks_allocated(check_point, function_name);
2912 1167 : rc = 0;
2913 189 : } else if (setup_func != NULL) {
2914 101 : rc = setup_func(state != NULL ? state : ¤t_state);
2915 :
2916 : /*
2917 : * For setup we can ignore any allocated blocks. We just need to
2918 : * ensure they're deallocated on tear down.
2919 : */
2920 88 : } else if (teardown_func != NULL) {
2921 88 : rc = teardown_func(state != NULL ? state : ¤t_state);
2922 :
2923 88 : fail_if_blocks_allocated(check_point, function_name);
2924 : } else {
2925 : /* ERROR */
2926 : }
2927 1356 : fail_if_leftover_values(function_name);
2928 1356 : global_running_test = 0;
2929 : } else {
2930 : /* TEST FAILED */
2931 0 : global_running_test = 0;
2932 0 : rc = -1;
2933 : }
2934 1356 : teardown_testing(function_name);
2935 :
2936 1356 : if (handle_exceptions) {
2937 : #ifndef _WIN32
2938 : unsigned int i;
2939 8136 : for (i = 0; i < ARRAY_SIZE(exception_signals); i++) {
2940 6780 : signal(exception_signals[i], default_signal_functions[i]);
2941 : }
2942 : #else /* _WIN32 */
2943 : if (previous_exception_filter) {
2944 : SetUnhandledExceptionFilter(previous_exception_filter);
2945 : previous_exception_filter = NULL;
2946 : }
2947 : #endif /* !_WIN32 */
2948 : }
2949 :
2950 1356 : return rc;
2951 : }
2952 :
2953 176 : static int cmocka_run_group_fixture(const char *function_name,
2954 : CMFixtureFunction setup_func,
2955 : CMFixtureFunction teardown_func,
2956 : void **state,
2957 : const void *const heap_check_point)
2958 : {
2959 : int rc;
2960 :
2961 176 : if (setup_func != NULL) {
2962 88 : rc = cmocka_run_one_test_or_fixture(function_name,
2963 : NULL,
2964 : setup_func,
2965 : NULL,
2966 : state,
2967 : heap_check_point);
2968 : } else {
2969 88 : rc = cmocka_run_one_test_or_fixture(function_name,
2970 : NULL,
2971 : NULL,
2972 : teardown_func,
2973 : state,
2974 : heap_check_point);
2975 : }
2976 :
2977 176 : return rc;
2978 : }
2979 :
2980 1167 : static int cmocka_run_one_tests(struct CMUnitTestState *test_state)
2981 : {
2982 : #ifdef HAVE_STRUCT_TIMESPEC
2983 : struct timespec start = {
2984 : .tv_sec = 0,
2985 : .tv_nsec = 0,
2986 : };
2987 : struct timespec finish = {
2988 : .tv_sec = 0,
2989 : .tv_nsec = 0,
2990 : };
2991 : #endif
2992 1167 : int rc = 0;
2993 :
2994 : /* Run setup */
2995 1167 : if (test_state->test->setup_func != NULL) {
2996 : /* Setup the memory check point, it will be evaluated on teardown */
2997 13 : test_state->check_point = check_point_allocated_blocks();
2998 :
2999 13 : rc = cmocka_run_one_test_or_fixture(test_state->test->name,
3000 : NULL,
3001 13 : test_state->test->setup_func,
3002 : NULL,
3003 : &test_state->state,
3004 13 : test_state->check_point);
3005 13 : if (rc != 0) {
3006 0 : test_state->status = CM_TEST_ERROR;
3007 0 : cm_print_error("Test setup failed");
3008 : }
3009 : }
3010 :
3011 : /* Run test */
3012 : #ifdef HAVE_STRUCT_TIMESPEC
3013 : CMOCKA_CLOCK_GETTIME(CLOCK_REALTIME, &start);
3014 : #endif
3015 :
3016 1167 : if (rc == 0) {
3017 1167 : rc = cmocka_run_one_test_or_fixture(test_state->test->name,
3018 1167 : test_state->test->test_func,
3019 : NULL,
3020 : NULL,
3021 : &test_state->state,
3022 : NULL);
3023 1167 : if (rc == 0) {
3024 1167 : test_state->status = CM_TEST_PASSED;
3025 : } else {
3026 0 : if (global_skip_test) {
3027 0 : test_state->status = CM_TEST_SKIPPED;
3028 0 : global_skip_test = 0; /* Do not skip the next test */
3029 : } else {
3030 0 : test_state->status = CM_TEST_FAILED;
3031 : }
3032 : }
3033 1167 : rc = 0;
3034 : }
3035 :
3036 1167 : test_state->runtime = 0.0;
3037 :
3038 : #ifdef HAVE_STRUCT_TIMESPEC
3039 : CMOCKA_CLOCK_GETTIME(CLOCK_REALTIME, &finish);
3040 : test_state->runtime = cm_secdiff(finish, start);
3041 : #endif
3042 :
3043 : /* Run teardown */
3044 1167 : if (rc == 0 && test_state->test->teardown_func != NULL) {
3045 0 : rc = cmocka_run_one_test_or_fixture(test_state->test->name,
3046 : NULL,
3047 : NULL,
3048 0 : test_state->test->teardown_func,
3049 : &test_state->state,
3050 0 : test_state->check_point);
3051 0 : if (rc != 0) {
3052 0 : test_state->status = CM_TEST_ERROR;
3053 0 : cm_print_error("Test teardown failed");
3054 : }
3055 : }
3056 :
3057 1167 : test_state->error_message = cm_error_message;
3058 1167 : cm_error_message = NULL;
3059 :
3060 1167 : return rc;
3061 : }
3062 :
3063 88 : int _cmocka_run_group_tests(const char *group_name,
3064 : const struct CMUnitTest * const tests,
3065 : const size_t num_tests,
3066 : CMFixtureFunction group_setup,
3067 : CMFixtureFunction group_teardown)
3068 : {
3069 : struct CMUnitTestState *cm_tests;
3070 88 : const ListNode *group_check_point = check_point_allocated_blocks();
3071 88 : void *group_state = NULL;
3072 88 : size_t total_tests = 0;
3073 88 : size_t total_failed = 0;
3074 88 : size_t total_passed = 0;
3075 88 : size_t total_executed = 0;
3076 88 : size_t total_errors = 0;
3077 88 : size_t total_skipped = 0;
3078 88 : double total_runtime = 0;
3079 : size_t i;
3080 : int rc;
3081 :
3082 : /* Make sure LargestIntegralType is at least the size of a pointer. */
3083 88 : assert_true(sizeof(LargestIntegralType) >= sizeof(void*));
3084 :
3085 88 : cm_tests = libc_calloc(1, sizeof(struct CMUnitTestState) * num_tests);
3086 88 : if (cm_tests == NULL) {
3087 0 : return -1;
3088 : }
3089 :
3090 : /* Setup cmocka test array */
3091 1255 : for (i = 0; i < num_tests; i++) {
3092 1167 : if (tests[i].name != NULL &&
3093 1167 : (tests[i].test_func != NULL
3094 0 : || tests[i].setup_func != NULL
3095 0 : || tests[i].teardown_func != NULL)) {
3096 1167 : if (global_test_filter_pattern != NULL) {
3097 : int match;
3098 :
3099 0 : match = c_strmatch(tests[i].name, global_test_filter_pattern);
3100 0 : if (!match) {
3101 0 : continue;
3102 : }
3103 : }
3104 1167 : if (global_skip_filter_pattern != NULL) {
3105 : int match;
3106 :
3107 0 : match = c_strmatch(tests[i].name, global_skip_filter_pattern);
3108 0 : if (match) {
3109 0 : continue;
3110 : }
3111 : }
3112 1167 : cm_tests[total_tests] = (struct CMUnitTestState) {
3113 1167 : .test = &tests[i],
3114 : .status = CM_TEST_NOT_STARTED,
3115 : .state = NULL,
3116 : };
3117 1167 : total_tests++;
3118 : }
3119 : }
3120 :
3121 88 : cmprintf_group_start(group_name, total_tests);
3122 :
3123 88 : rc = 0;
3124 :
3125 : /* Run group setup */
3126 88 : if (group_setup != NULL) {
3127 88 : rc = cmocka_run_group_fixture("cmocka_group_setup",
3128 : group_setup,
3129 : NULL,
3130 : &group_state,
3131 : group_check_point);
3132 : }
3133 :
3134 88 : if (rc == 0) {
3135 : /* Execute tests */
3136 1255 : for (i = 0; i < total_tests; i++) {
3137 1167 : struct CMUnitTestState *cmtest = &cm_tests[i];
3138 1167 : size_t test_number = i + 1;
3139 :
3140 1167 : cmprintf(PRINTF_TEST_START, test_number, cmtest->test->name, NULL);
3141 :
3142 1167 : if (group_state != NULL) {
3143 1154 : cmtest->state = group_state;
3144 13 : } else if (cmtest->test->initial_state != NULL) {
3145 0 : cmtest->state = cmtest->test->initial_state;
3146 : }
3147 :
3148 1167 : rc = cmocka_run_one_tests(cmtest);
3149 1167 : total_executed++;
3150 1167 : total_runtime += cmtest->runtime;
3151 1167 : if (rc == 0) {
3152 1167 : switch (cmtest->status) {
3153 1167 : case CM_TEST_PASSED:
3154 1167 : cmprintf(PRINTF_TEST_SUCCESS,
3155 : test_number,
3156 1167 : cmtest->test->name,
3157 : cmtest->error_message);
3158 1167 : total_passed++;
3159 1167 : break;
3160 0 : case CM_TEST_SKIPPED:
3161 0 : cmprintf(PRINTF_TEST_SKIPPED,
3162 : test_number,
3163 0 : cmtest->test->name,
3164 : cmtest->error_message);
3165 0 : total_skipped++;
3166 0 : break;
3167 0 : case CM_TEST_FAILED:
3168 0 : cmprintf(PRINTF_TEST_FAILURE,
3169 : test_number,
3170 0 : cmtest->test->name,
3171 : cmtest->error_message);
3172 0 : total_failed++;
3173 0 : break;
3174 0 : default:
3175 0 : cmprintf(PRINTF_TEST_ERROR,
3176 : test_number,
3177 0 : cmtest->test->name,
3178 : "Internal cmocka error");
3179 0 : total_errors++;
3180 0 : break;
3181 : }
3182 : } else {
3183 0 : char err_msg[2048] = {0};
3184 :
3185 0 : snprintf(err_msg, sizeof(err_msg),
3186 : "Could not run test: %s",
3187 : cmtest->error_message);
3188 :
3189 0 : cmprintf(PRINTF_TEST_ERROR,
3190 : test_number,
3191 0 : cmtest->test->name,
3192 : err_msg);
3193 0 : total_errors++;
3194 : }
3195 : }
3196 : } else {
3197 0 : if (cm_error_message != NULL) {
3198 0 : print_error("[ ERROR ] --- %s\n", cm_error_message);
3199 0 : vcm_free_error(cm_error_message);
3200 0 : cm_error_message = NULL;
3201 : }
3202 0 : cmprintf(PRINTF_TEST_ERROR, 0,
3203 : group_name, "[ FAILED ] GROUP SETUP");
3204 0 : total_errors++;
3205 : }
3206 :
3207 : /* Run group teardown */
3208 88 : if (group_teardown != NULL) {
3209 88 : rc = cmocka_run_group_fixture("cmocka_group_teardown",
3210 : NULL,
3211 : group_teardown,
3212 : &group_state,
3213 : group_check_point);
3214 88 : if (rc != 0) {
3215 0 : if (cm_error_message != NULL) {
3216 0 : print_error("[ ERROR ] --- %s\n", cm_error_message);
3217 0 : vcm_free_error(cm_error_message);
3218 0 : cm_error_message = NULL;
3219 : }
3220 0 : cmprintf(PRINTF_TEST_ERROR, 0,
3221 : group_name, "[ FAILED ] GROUP TEARDOWN");
3222 : }
3223 : }
3224 :
3225 88 : cmprintf_group_finish(group_name,
3226 : total_executed,
3227 : total_passed,
3228 : total_failed,
3229 : total_errors,
3230 : total_skipped,
3231 : total_runtime,
3232 : cm_tests);
3233 :
3234 1255 : for (i = 0; i < total_tests; i++) {
3235 1167 : vcm_free_error(discard_const_p(char, cm_tests[i].error_message));
3236 : }
3237 88 : libc_free(cm_tests);
3238 88 : fail_if_blocks_allocated(group_check_point, "cmocka_group_tests");
3239 :
3240 88 : return (int)(total_failed + total_errors);
3241 : }
3242 :
3243 : /****************************************************************************
3244 : * DEPRECATED TEST RUNNER
3245 : ****************************************************************************/
3246 :
3247 0 : int _run_test(
3248 : const char * const function_name, const UnitTestFunction Function,
3249 : void ** const volatile state, const UnitTestFunctionType function_type,
3250 : const void* const heap_check_point) {
3251 0 : const ListNode * const volatile check_point = (const ListNode*)
3252 : (heap_check_point ?
3253 0 : heap_check_point : check_point_allocated_blocks());
3254 0 : void *current_state = NULL;
3255 0 : volatile int rc = 1;
3256 0 : int handle_exceptions = 1;
3257 : #ifdef _WIN32
3258 : handle_exceptions = !IsDebuggerPresent();
3259 : #endif /* _WIN32 */
3260 : #ifdef UNIT_TESTING_DEBUG
3261 : handle_exceptions = 0;
3262 : #endif /* UNIT_TESTING_DEBUG */
3263 :
3264 0 : cm_error_message_enabled = 0;
3265 :
3266 0 : if (handle_exceptions) {
3267 : #ifndef _WIN32
3268 : unsigned int i;
3269 0 : for (i = 0; i < ARRAY_SIZE(exception_signals); i++) {
3270 0 : default_signal_functions[i] = signal(
3271 0 : exception_signals[i], exception_handler);
3272 : }
3273 : #else /* _WIN32 */
3274 : previous_exception_filter = SetUnhandledExceptionFilter(
3275 : exception_filter);
3276 : #endif /* !_WIN32 */
3277 : }
3278 :
3279 0 : if (function_type == UNIT_TEST_FUNCTION_TYPE_TEST) {
3280 0 : print_message("[ RUN ] %s\n", function_name);
3281 : }
3282 0 : initialize_testing(function_name);
3283 0 : global_running_test = 1;
3284 0 : if (cm_setjmp(global_run_test_env) == 0) {
3285 0 : Function(state ? state : ¤t_state);
3286 0 : fail_if_leftover_values(function_name);
3287 :
3288 : /* If this is a setup function then ignore any allocated blocks
3289 : * only ensure they're deallocated on tear down. */
3290 0 : if (function_type != UNIT_TEST_FUNCTION_TYPE_SETUP) {
3291 0 : fail_if_blocks_allocated(check_point, function_name);
3292 : }
3293 :
3294 0 : global_running_test = 0;
3295 :
3296 0 : if (function_type == UNIT_TEST_FUNCTION_TYPE_TEST) {
3297 0 : print_message("[ OK ] %s\n", function_name);
3298 : }
3299 0 : rc = 0;
3300 : } else {
3301 0 : global_running_test = 0;
3302 0 : print_message("[ FAILED ] %s\n", function_name);
3303 : }
3304 0 : teardown_testing(function_name);
3305 :
3306 0 : if (handle_exceptions) {
3307 : #ifndef _WIN32
3308 : unsigned int i;
3309 0 : for (i = 0; i < ARRAY_SIZE(exception_signals); i++) {
3310 0 : signal(exception_signals[i], default_signal_functions[i]);
3311 : }
3312 : #else /* _WIN32 */
3313 : if (previous_exception_filter) {
3314 : SetUnhandledExceptionFilter(previous_exception_filter);
3315 : previous_exception_filter = NULL;
3316 : }
3317 : #endif /* !_WIN32 */
3318 : }
3319 :
3320 0 : return rc;
3321 : }
3322 :
3323 :
3324 0 : int _run_tests(const UnitTest * const tests, const size_t number_of_tests) {
3325 : /* Whether to execute the next test. */
3326 0 : int run_next_test = 1;
3327 : /* Whether the previous test failed. */
3328 0 : int previous_test_failed = 0;
3329 : /* Whether the previous setup failed. */
3330 0 : int previous_setup_failed = 0;
3331 : /* Check point of the heap state. */
3332 0 : const ListNode * const check_point = check_point_allocated_blocks();
3333 : /* Current test being executed. */
3334 0 : size_t current_test = 0;
3335 : /* Number of tests executed. */
3336 0 : size_t tests_executed = 0;
3337 : /* Number of failed tests. */
3338 0 : size_t total_failed = 0;
3339 : /* Number of setup functions. */
3340 0 : size_t setups = 0;
3341 : /* Number of teardown functions. */
3342 0 : size_t teardowns = 0;
3343 : size_t i;
3344 : /*
3345 : * A stack of test states. A state is pushed on the stack
3346 : * when a test setup occurs and popped on tear down.
3347 : */
3348 : TestState* test_states =
3349 0 : (TestState*)malloc(number_of_tests * sizeof(*test_states));
3350 : /* The number of test states which should be 0 at the end */
3351 0 : long number_of_test_states = 0;
3352 : /* Names of the tests that failed. */
3353 0 : const char** failed_names = (const char**)malloc(number_of_tests *
3354 : sizeof(*failed_names));
3355 0 : void **current_state = NULL;
3356 :
3357 : /* Count setup and teardown functions */
3358 0 : for (i = 0; i < number_of_tests; i++) {
3359 0 : const UnitTest * const test = &tests[i];
3360 :
3361 0 : if (test->function_type == UNIT_TEST_FUNCTION_TYPE_SETUP) {
3362 0 : setups++;
3363 : }
3364 :
3365 0 : if (test->function_type == UNIT_TEST_FUNCTION_TYPE_TEARDOWN) {
3366 0 : teardowns++;
3367 : }
3368 : }
3369 :
3370 0 : print_message("[==========] Running %"PRIdS " test(s).\n",
3371 0 : number_of_tests - setups - teardowns);
3372 :
3373 : /* Make sure LargestIntegralType is at least the size of a pointer. */
3374 0 : assert_true(sizeof(LargestIntegralType) >= sizeof(void*));
3375 :
3376 0 : while (current_test < number_of_tests) {
3377 0 : const ListNode *test_check_point = NULL;
3378 : TestState *current_TestState;
3379 0 : const UnitTest * const test = &tests[current_test++];
3380 0 : if (!test->function) {
3381 0 : continue;
3382 : }
3383 :
3384 0 : switch (test->function_type) {
3385 0 : case UNIT_TEST_FUNCTION_TYPE_TEST:
3386 0 : if (! previous_setup_failed) {
3387 0 : run_next_test = 1;
3388 : }
3389 0 : break;
3390 0 : case UNIT_TEST_FUNCTION_TYPE_SETUP: {
3391 : /* Checkpoint the heap before the setup. */
3392 0 : current_TestState = &test_states[number_of_test_states++];
3393 0 : current_TestState->check_point = check_point_allocated_blocks();
3394 0 : test_check_point = current_TestState->check_point;
3395 0 : current_state = ¤t_TestState->state;
3396 0 : *current_state = NULL;
3397 0 : run_next_test = 1;
3398 0 : break;
3399 : }
3400 0 : case UNIT_TEST_FUNCTION_TYPE_TEARDOWN:
3401 : /* Check the heap based on the last setup checkpoint. */
3402 0 : assert_true(number_of_test_states);
3403 0 : current_TestState = &test_states[--number_of_test_states];
3404 0 : test_check_point = current_TestState->check_point;
3405 0 : current_state = ¤t_TestState->state;
3406 0 : break;
3407 0 : default:
3408 0 : print_error("Invalid unit test function type %d\n",
3409 0 : test->function_type);
3410 0 : exit_test(1);
3411 0 : break;
3412 : }
3413 :
3414 0 : if (run_next_test) {
3415 0 : int failed = _run_test(test->name, test->function, current_state,
3416 0 : test->function_type, test_check_point);
3417 0 : if (failed) {
3418 0 : failed_names[total_failed] = test->name;
3419 : }
3420 :
3421 0 : switch (test->function_type) {
3422 0 : case UNIT_TEST_FUNCTION_TYPE_TEST:
3423 0 : previous_test_failed = failed;
3424 0 : total_failed += failed;
3425 0 : tests_executed ++;
3426 0 : break;
3427 :
3428 0 : case UNIT_TEST_FUNCTION_TYPE_SETUP:
3429 0 : if (failed) {
3430 0 : total_failed ++;
3431 0 : tests_executed ++;
3432 : /* Skip forward until the next test or setup function. */
3433 0 : run_next_test = 0;
3434 0 : previous_setup_failed = 1;
3435 : }
3436 0 : previous_test_failed = 0;
3437 0 : break;
3438 :
3439 0 : case UNIT_TEST_FUNCTION_TYPE_TEARDOWN:
3440 : /* If this test failed. */
3441 0 : if (failed && !previous_test_failed) {
3442 0 : total_failed ++;
3443 : }
3444 0 : break;
3445 0 : default:
3446 : #ifndef _HPUX
3447 0 : assert_null("BUG: shouldn't be here!");
3448 : #endif
3449 0 : break;
3450 : }
3451 : }
3452 : }
3453 :
3454 0 : print_message("[==========] %"PRIdS " test(s) run.\n", tests_executed);
3455 0 : print_error("[ PASSED ] %"PRIdS " test(s).\n", tests_executed - total_failed);
3456 :
3457 0 : if (total_failed > 0) {
3458 0 : print_error("[ FAILED ] %"PRIdS " test(s), listed below:\n", total_failed);
3459 0 : for (i = 0; i < total_failed; i++) {
3460 0 : print_error("[ FAILED ] %s\n", failed_names[i]);
3461 : }
3462 : } else {
3463 0 : print_error("\n %"PRIdS " FAILED TEST(S)\n", total_failed);
3464 : }
3465 :
3466 0 : if (number_of_test_states != 0) {
3467 0 : print_error("[ ERROR ] Mismatched number of setup %"PRIdS " and "
3468 : "teardown %"PRIdS " functions\n", setups, teardowns);
3469 0 : total_failed = (size_t)-1;
3470 : }
3471 :
3472 0 : free(test_states);
3473 0 : free((void*)failed_names);
3474 :
3475 0 : fail_if_blocks_allocated(check_point, "run_tests");
3476 0 : return (int)total_failed;
3477 : }
3478 :
3479 0 : int _run_group_tests(const UnitTest * const tests, const size_t number_of_tests)
3480 : {
3481 0 : UnitTestFunction setup = NULL;
3482 0 : const char *setup_name = NULL;
3483 0 : size_t num_setups = 0;
3484 0 : UnitTestFunction teardown = NULL;
3485 0 : const char *teardown_name = NULL;
3486 0 : size_t num_teardowns = 0;
3487 0 : size_t current_test = 0;
3488 : size_t i;
3489 :
3490 : /* Number of tests executed. */
3491 0 : size_t tests_executed = 0;
3492 : /* Number of failed tests. */
3493 0 : size_t total_failed = 0;
3494 : /* Check point of the heap state. */
3495 0 : const ListNode * const check_point = check_point_allocated_blocks();
3496 0 : const char **failed_names = NULL;
3497 0 : void **current_state = NULL;
3498 0 : TestState group_state = {
3499 : .check_point = NULL,
3500 : };
3501 :
3502 0 : if (number_of_tests == 0) {
3503 0 : return -1;
3504 : }
3505 :
3506 0 : failed_names = (const char **)malloc(number_of_tests *
3507 : sizeof(*failed_names));
3508 0 : if (failed_names == NULL) {
3509 0 : return -2;
3510 : }
3511 :
3512 : /* Find setup and teardown function */
3513 0 : for (i = 0; i < number_of_tests; i++) {
3514 0 : const UnitTest * const test = &tests[i];
3515 :
3516 0 : if (test->function_type == UNIT_TEST_FUNCTION_TYPE_GROUP_SETUP) {
3517 0 : if (setup == NULL) {
3518 0 : setup = test->function;
3519 0 : setup_name = test->name;
3520 0 : num_setups = 1;
3521 : } else {
3522 0 : print_error("[ ERROR ] More than one group setup function detected\n");
3523 0 : exit_test(1);
3524 : }
3525 : }
3526 :
3527 0 : if (test->function_type == UNIT_TEST_FUNCTION_TYPE_GROUP_TEARDOWN) {
3528 0 : if (teardown == NULL) {
3529 0 : teardown = test->function;
3530 0 : teardown_name = test->name;
3531 0 : num_teardowns = 1;
3532 : } else {
3533 0 : print_error("[ ERROR ] More than one group teardown function detected\n");
3534 0 : exit_test(1);
3535 : }
3536 : }
3537 : }
3538 :
3539 0 : print_message("[==========] Running %"PRIdS " test(s).\n",
3540 0 : number_of_tests - num_setups - num_teardowns);
3541 :
3542 0 : if (setup != NULL) {
3543 : int failed;
3544 :
3545 0 : group_state.check_point = check_point_allocated_blocks();
3546 0 : current_state = &group_state.state;
3547 0 : *current_state = NULL;
3548 0 : failed = _run_test(setup_name,
3549 : setup,
3550 : current_state,
3551 : UNIT_TEST_FUNCTION_TYPE_SETUP,
3552 0 : group_state.check_point);
3553 0 : if (failed) {
3554 0 : failed_names[total_failed] = setup_name;
3555 : }
3556 :
3557 0 : total_failed += failed;
3558 0 : tests_executed++;
3559 : }
3560 :
3561 0 : while (current_test < number_of_tests) {
3562 0 : int run_test = 0;
3563 0 : const UnitTest * const test = &tests[current_test++];
3564 0 : if (test->function == NULL) {
3565 0 : continue;
3566 : }
3567 :
3568 0 : switch (test->function_type) {
3569 0 : case UNIT_TEST_FUNCTION_TYPE_TEST:
3570 0 : run_test = 1;
3571 0 : break;
3572 0 : case UNIT_TEST_FUNCTION_TYPE_SETUP:
3573 : case UNIT_TEST_FUNCTION_TYPE_TEARDOWN:
3574 : case UNIT_TEST_FUNCTION_TYPE_GROUP_SETUP:
3575 : case UNIT_TEST_FUNCTION_TYPE_GROUP_TEARDOWN:
3576 0 : break;
3577 0 : default:
3578 0 : print_error("Invalid unit test function type %d\n",
3579 0 : test->function_type);
3580 0 : break;
3581 : }
3582 :
3583 0 : if (run_test) {
3584 : int failed;
3585 :
3586 0 : failed = _run_test(test->name,
3587 0 : test->function,
3588 : current_state,
3589 0 : test->function_type,
3590 : NULL);
3591 0 : if (failed) {
3592 0 : failed_names[total_failed] = test->name;
3593 : }
3594 :
3595 0 : total_failed += failed;
3596 0 : tests_executed++;
3597 : }
3598 : }
3599 :
3600 0 : if (teardown != NULL) {
3601 : int failed;
3602 :
3603 0 : failed = _run_test(teardown_name,
3604 : teardown,
3605 : current_state,
3606 : UNIT_TEST_FUNCTION_TYPE_GROUP_TEARDOWN,
3607 0 : group_state.check_point);
3608 0 : if (failed) {
3609 0 : failed_names[total_failed] = teardown_name;
3610 : }
3611 :
3612 0 : total_failed += failed;
3613 0 : tests_executed++;
3614 : }
3615 :
3616 0 : print_message("[==========] %"PRIdS " test(s) run.\n", tests_executed);
3617 0 : print_error("[ PASSED ] %"PRIdS " test(s).\n", tests_executed - total_failed);
3618 :
3619 0 : if (total_failed) {
3620 0 : print_error("[ FAILED ] %"PRIdS " test(s), listed below:\n", total_failed);
3621 0 : for (i = 0; i < total_failed; i++) {
3622 0 : print_error("[ FAILED ] %s\n", failed_names[i]);
3623 : }
3624 : } else {
3625 0 : print_error("\n %"PRIdS " FAILED TEST(S)\n", total_failed);
3626 : }
3627 :
3628 0 : free((void*)failed_names);
3629 0 : fail_if_blocks_allocated(check_point, "run_group_tests");
3630 :
3631 0 : return (int)total_failed;
3632 : }
|