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 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 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 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 56 static int testSelected(const char* test) 57 { 58 return selected(UnityFixture.NameFilter, test); 59 } 60 61 static int groupSelected(const char* group) 62 { 63 return selected(UnityFixture.GroupFilter, group); 64 } 65 66 static void runTestCase(void) 67 { 68 69 } 70 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 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 133 void UnityMalloc_StartTest(void) 134 { 135 malloc_count = 0; 136 malloc_fail_countdown = MALLOC_DONT_FAIL; 137 } 138 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 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 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 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 212 static void release_memory(void * mem) 213 { 214 Guard* guard = (Guard*)mem; 215 guard--; 216 217 malloc_count--; 218 free(guard); 219 } 220 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 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 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 283 void UnityPointer_Init(void) 284 { 285 pointer_index = 0; 286 } 287 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 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 310 int UnityFailureCount(void) 311 { 312 return Unity.TestFailures; 313 } 314 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 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