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