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