1 //- Copyright (c) 2010 James Grenning and Contributed to Unity Project
2 /* ==========================================
3 Unity Project - A Test Framework for C
4 Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams
5 [Released under MIT License. Please refer to license.txt for details]
6 ========================================== */
7
8 #include <string.h>
9 #include <stdio.h>
10 #include "unity_fixture.h"
11 #include "unity_internals.h"
12
13 UNITY_FIXTURE_T UnityFixture;
14
15 //If you decide to use the function pointer approach.
16 int (*outputChar)(int) = putchar;
17
18 int verbose = 0;
19
20
announceTestRun(unsigned int runNumber)21 static void announceTestRun(unsigned int runNumber)
22 {
23 UnityPrint("Unity test run ");
24 UnityPrintNumber(runNumber+1);
25 UnityPrint(" of ");
26 UnityPrintNumber(UnityFixture.RepeatCount);
27 UNITY_OUTPUT_CHAR('\n');
28 }
29
UnityMain(int argc,const char * argv[],void (* runAllTests)(void))30 int UnityMain(int argc, const char* argv[], void (*runAllTests)(void))
31 {
32 int result = UnityGetCommandLineOptions(argc, argv);
33 unsigned int r;
34 if (result != 0)
35 return result;
36
37 for (r = 0; r < UnityFixture.RepeatCount; r++)
38 {
39 UnityBegin(argv[0]);
40 announceTestRun(r);
41 runAllTests();
42 UNITY_OUTPUT_CHAR('\n');
43 UnityEnd();
44 }
45
46 return UnityFailureCount();
47 }
48
selected(const char * filter,const char * name)49 static int selected(const char * filter, const char * name)
50 {
51 if (filter == 0)
52 return 1;
53 return strstr(name, filter) ? 1 : 0;
54 }
55
testSelected(const char * test)56 static int testSelected(const char* test)
57 {
58 return selected(UnityFixture.NameFilter, test);
59 }
60
groupSelected(const char * group)61 static int groupSelected(const char* group)
62 {
63 return selected(UnityFixture.GroupFilter, group);
64 }
65
runTestCase(void)66 static void runTestCase(void)
67 {
68
69 }
70
UnityTestRunner(unityfunction * setup,unityfunction * testBody,unityfunction * teardown,const char * printableName,const char * group,const char * name,const char * file,int line)71 void UnityTestRunner(unityfunction* setup,
72 unityfunction* testBody,
73 unityfunction* teardown,
74 const char * printableName,
75 const char * group,
76 const char * name,
77 const char * file, int line)
78 {
79 if (testSelected(name) && groupSelected(group))
80 {
81 Unity.CurrentTestFailed = 0;
82 Unity.TestFile = file;
83 Unity.CurrentTestName = printableName;
84 Unity.CurrentTestLineNumber = line;
85 if (!UnityFixture.Verbose)
86 UNITY_OUTPUT_CHAR('.');
87 else
88 UnityPrint(printableName);
89
90 Unity.NumberOfTests++;
91 UnityMalloc_StartTest();
92 UnityPointer_Init();
93
94 runTestCase();
95 if (TEST_PROTECT())
96 {
97 setup();
98 testBody();
99 }
100 if (TEST_PROTECT())
101 {
102 teardown();
103 }
104 if (TEST_PROTECT())
105 {
106 UnityPointer_UndoAllSets();
107 if (!Unity.CurrentTestFailed)
108 UnityMalloc_EndTest();
109 }
110 UnityConcludeFixtureTest();
111 }
112 }
113
UnityIgnoreTest(const char * printableName)114 void UnityIgnoreTest(const char * printableName)
115 {
116 Unity.NumberOfTests++;
117 Unity.CurrentTestIgnored = 1;
118 if (!UnityFixture.Verbose)
119 UNITY_OUTPUT_CHAR('!');
120 else
121 UnityPrint(printableName);
122 UnityConcludeFixtureTest();
123 }
124
125
126 //-------------------------------------------------
127 //Malloc and free stuff
128 //
129 #define MALLOC_DONT_FAIL -1
130 static int malloc_count;
131 static int malloc_fail_countdown = MALLOC_DONT_FAIL;
132
UnityMalloc_StartTest(void)133 void UnityMalloc_StartTest(void)
134 {
135 malloc_count = 0;
136 malloc_fail_countdown = MALLOC_DONT_FAIL;
137 }
138
UnityMalloc_EndTest(void)139 void UnityMalloc_EndTest(void)
140 {
141 malloc_fail_countdown = MALLOC_DONT_FAIL;
142 if (malloc_count != 0)
143 {
144 TEST_FAIL_MESSAGE("This test leaks!");
145 }
146 }
147
UnityMalloc_MakeMallocFailAfterCount(int countdown)148 void UnityMalloc_MakeMallocFailAfterCount(int countdown)
149 {
150 malloc_fail_countdown = countdown;
151 }
152
153 #ifdef malloc
154 #undef malloc
155 #endif
156
157 #ifdef free
158 #undef free
159 #endif
160
161 #ifdef calloc
162 #undef calloc
163 #endif
164
165 #ifdef realloc
166 #undef realloc
167 #endif
168
169 #include <stdlib.h>
170 #include <string.h>
171
172 typedef struct GuardBytes
173 {
174 size_t size;
175 char guard[sizeof(size_t)];
176 } Guard;
177
178
179 static const char * end = "END";
180
unity_malloc(size_t size)181 void * unity_malloc(size_t size)
182 {
183 char* mem;
184 Guard* guard;
185
186 if (malloc_fail_countdown != MALLOC_DONT_FAIL)
187 {
188 if (malloc_fail_countdown == 0)
189 return 0;
190 malloc_fail_countdown--;
191 }
192
193 malloc_count++;
194
195 guard = (Guard*)malloc(size + sizeof(Guard) + 4);
196 guard->size = size;
197 mem = (char*)&(guard[1]);
198 memcpy(&mem[size], end, strlen(end) + 1);
199
200 return (void*)mem;
201 }
202
isOverrun(void * mem)203 static int isOverrun(void * mem)
204 {
205 Guard* guard = (Guard*)mem;
206 char* memAsChar = (char*)mem;
207 guard--;
208
209 return strcmp(&memAsChar[guard->size], end) != 0;
210 }
211
release_memory(void * mem)212 static void release_memory(void * mem)
213 {
214 Guard* guard = (Guard*)mem;
215 guard--;
216
217 malloc_count--;
218 free(guard);
219 }
220
unity_free(void * mem)221 void unity_free(void * mem)
222 {
223 int overrun = isOverrun(mem);//strcmp(&memAsChar[guard->size], end) != 0;
224 release_memory(mem);
225 if (overrun)
226 {
227 TEST_FAIL_MESSAGE("Buffer overrun detected during free()");
228 }
229 }
230
unity_calloc(size_t num,size_t size)231 void* unity_calloc(size_t num, size_t size)
232 {
233 void* mem = unity_malloc(num * size);
234 memset(mem, 0, num*size);
235 return mem;
236 }
237
unity_realloc(void * oldMem,size_t size)238 void* unity_realloc(void * oldMem, size_t size)
239 {
240 Guard* guard = (Guard*)oldMem;
241 // char* memAsChar = (char*)oldMem;
242 void* newMem;
243
244 if (oldMem == 0)
245 return unity_malloc(size);
246
247 guard--;
248 if (isOverrun(oldMem))
249 {
250 release_memory(oldMem);
251 TEST_FAIL_MESSAGE("Buffer overrun detected during realloc()");
252 }
253
254 if (size == 0)
255 {
256 release_memory(oldMem);
257 return 0;
258 }
259
260 if (guard->size >= size)
261 return oldMem;
262
263 newMem = unity_malloc(size);
264 memcpy(newMem, oldMem, guard->size);
265 unity_free(oldMem);
266 return newMem;
267 }
268
269
270 //--------------------------------------------------------
271 //Automatic pointer restoration functions
272 typedef struct _PointerPair
273 {
274 struct _PointerPair * next;
275 void ** pointer;
276 void * old_value;
277 } PointerPair;
278
279 enum {MAX_POINTERS=50};
280 static PointerPair pointer_store[MAX_POINTERS];
281 static int pointer_index = 0;
282
UnityPointer_Init(void)283 void UnityPointer_Init(void)
284 {
285 pointer_index = 0;
286 }
287
UnityPointer_Set(void ** pointer,void * newValue)288 void UnityPointer_Set(void ** pointer, void * newValue)
289 {
290 if (pointer_index >= MAX_POINTERS)
291 TEST_FAIL_MESSAGE("Too many pointers set");
292
293 pointer_store[pointer_index].pointer = pointer;
294 pointer_store[pointer_index].old_value = *pointer;
295 *pointer = newValue;
296 pointer_index++;
297 }
298
UnityPointer_UndoAllSets(void)299 void UnityPointer_UndoAllSets(void)
300 {
301 while (pointer_index > 0)
302 {
303 pointer_index--;
304 *(pointer_store[pointer_index].pointer) =
305 pointer_store[pointer_index].old_value;
306
307 }
308 }
309
UnityFailureCount(void)310 int UnityFailureCount(void)
311 {
312 return Unity.TestFailures;
313 }
314
UnityGetCommandLineOptions(int argc,const char * argv[])315 int UnityGetCommandLineOptions(int argc, const char* argv[])
316 {
317 int i;
318 UnityFixture.Verbose = 0;
319 UnityFixture.GroupFilter = 0;
320 UnityFixture.NameFilter = 0;
321 UnityFixture.RepeatCount = 1;
322
323 if (argc == 1)
324 return 0;
325
326 for (i = 1; i < argc; )
327 {
328 if (strcmp(argv[i], "-v") == 0)
329 {
330 UnityFixture.Verbose = 1;
331 i++;
332 }
333 else if (strcmp(argv[i], "-g") == 0)
334 {
335 i++;
336 if (i >= argc)
337 return 1;
338 UnityFixture.GroupFilter = argv[i];
339 i++;
340 }
341 else if (strcmp(argv[i], "-n") == 0)
342 {
343 i++;
344 if (i >= argc)
345 return 1;
346 UnityFixture.NameFilter = argv[i];
347 i++;
348 }
349 else if (strcmp(argv[i], "-r") == 0)
350 {
351 UnityFixture.RepeatCount = 2;
352 i++;
353 if (i < argc)
354 {
355 if (*(argv[i]) >= '0' && *(argv[i]) <= '9')
356 {
357 UnityFixture.RepeatCount = atoi(argv[i]);
358 i++;
359 }
360 }
361 } else {
362 // ignore unknown parameter
363 i++;
364 }
365 }
366 return 0;
367 }
368
UnityConcludeFixtureTest(void)369 void UnityConcludeFixtureTest(void)
370 {
371 if (Unity.CurrentTestIgnored)
372 {
373 if (UnityFixture.Verbose)
374 {
375 UNITY_OUTPUT_CHAR('\n');
376 }
377 Unity.TestIgnores++;
378 }
379 else if (!Unity.CurrentTestFailed)
380 {
381 if (UnityFixture.Verbose)
382 {
383 UnityPrint(" PASS");
384 UNITY_OUTPUT_CHAR('\n');
385 }
386 }
387 else if (Unity.CurrentTestFailed)
388 {
389 Unity.TestFailures++;
390 }
391
392 Unity.CurrentTestFailed = 0;
393 Unity.CurrentTestIgnored = 0;
394 }
395