Branch data Line data Source code
1 : : #include "mocks.h"
2 : : #include <stdarg.h>
3 : : #include <setjmp.h>
4 : : #include <cmocka.h>
5 : : #include <errno.h>
6 : : #include <stdio.h>
7 : : #include <string.h>
8 : :
9 : : static bool mock_fread_enabled = false;
10 : : static size_t mock_fread_calls = 0;
11 : : static const char *mock_fread_target_suffix = NULL;
12 : : static FILE *mock_fread_target_stream = NULL;
13 : : static bool mock_fread_error_seen = false;
14 : : static int mock_fread_errno = EIO;
15 : :
16 : 12 : static bool mock_path_matches_suffix(const char *path,const char *suffix)
17 : : {
18 : 12 : size_t path_len = 0;
19 : 12 : size_t suffix_len = 0;
20 : :
21 [ + - - + ]: 12 : if(path == NULL || suffix == NULL)
22 : : {
23 : 0 : return false;
24 : : }
25 : :
26 [ - + ]: 12 : if(strcmp(path,suffix) == 0)
27 : : {
28 : 0 : return true;
29 : : }
30 : :
31 : 12 : path_len = strlen(path);
32 : 12 : suffix_len = strlen(suffix);
33 : :
34 [ - + ]: 12 : if(path_len < suffix_len + 1U)
35 : : {
36 : 0 : return false;
37 : : }
38 : :
39 [ + + ]: 12 : if(path[path_len - suffix_len - 1U] != '/')
40 : : {
41 : 8 : return false;
42 : : }
43 : :
44 : 4 : return strcmp(path + (path_len - suffix_len),suffix) == 0;
45 : : }
46 : :
47 : 1 : void mocks_fread_set_target_suffix(const char *suffix)
48 : : {
49 : 1 : mock_fread_target_suffix = suffix;
50 : 1 : }
51 : :
52 : 2 : void mocks_fread_enable(bool enabled)
53 : : {
54 : 2 : mock_fread_enabled = enabled;
55 : 2 : }
56 : :
57 : 2 : void mocks_fread_reset(void)
58 : : {
59 : 2 : mock_fread_enabled = false;
60 : 2 : mock_fread_calls = 0;
61 : 2 : mock_fread_target_suffix = NULL;
62 : 2 : mock_fread_target_stream = NULL;
63 : 2 : mock_fread_error_seen = false;
64 : 2 : mock_fread_errno = EIO;
65 : 2 : }
66 : :
67 : 1 : size_t mocks_fread_call_count(void)
68 : : {
69 : 1 : return mock_fread_calls;
70 : : }
71 : :
72 : 1 : void mocks_fread_set_errno(int err)
73 : : {
74 : 1 : mock_fread_errno = err;
75 : 1 : }
76 : :
77 : : FILE *__real_fopen(const char *path,const char *mode);
78 : :
79 : 1639 : FILE *__wrap_fopen(const char *path,const char *mode)
80 : : {
81 : 1639 : FILE *stream = __real_fopen(path,mode);
82 : :
83 [ + + + + ]: 1639 : if(stream != NULL && mock_fread_target_suffix != NULL)
84 : : {
85 [ + + ]: 12 : if(mock_path_matches_suffix(path,mock_fread_target_suffix))
86 : : {
87 : 1 : mock_fread_target_stream = stream;
88 : : }
89 : : }
90 : :
91 : 1639 : return stream;
92 : : }
93 : :
94 : : size_t __real_fread(void *ptr,size_t size,size_t nmemb,FILE *stream);
95 : :
96 : 2045 : size_t __wrap_fread(void *ptr,size_t size,size_t nmemb,FILE *stream)
97 : : {
98 [ + + ]: 2045 : if(mock_fread_enabled
99 [ + - ]: 23 : && stream != NULL
100 [ + + ]: 23 : && stream == mock_fread_target_stream
101 [ + - ]: 1 : && mock_fread_calls == 0)
102 : : {
103 : 1 : mock_fread_calls++;
104 : 1 : mock_fread_error_seen = true;
105 : 1 : errno = mock_fread_errno;
106 : 1 : return 0;
107 : : }
108 : :
109 : 2044 : return __real_fread(ptr,size,nmemb,stream);
110 : : }
111 : :
112 : : int __real_ferror(FILE *stream);
113 : :
114 : 813 : int __wrap_ferror(FILE *stream)
115 : : {
116 [ + - + + : 813 : if(stream != NULL && stream == mock_fread_target_stream && mock_fread_error_seen)
+ - ]
117 : : {
118 : : /*
119 : : * Clear the target once the error is observed to avoid matching a
120 : : * recycled FILE* address for unrelated files (seen in coverage builds).
121 : : */
122 : 1 : mock_fread_target_stream = NULL;
123 : 1 : mock_fread_error_seen = false;
124 : 1 : return 1;
125 : : }
126 : :
127 : 812 : return __real_ferror(stream);
128 : : }
|