1130812Smarcel//- Copyright (c) 2010 James Grenning and Contributed to Unity Project 2130812Smarcel/* ========================================== 3130812Smarcel Unity Project - A Test Framework for C 4130812Smarcel Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams 5130812Smarcel [Released under MIT License. Please refer to license.txt for details] 6130812Smarcel========================================== */ 7130812Smarcel 8130812Smarcel#include <string.h> 9130812Smarcel#include <stdio.h> 10130812Smarcel#include "unity_fixture.h" 11130812Smarcel#include "unity_internals.h" 12130812Smarcel 13130812SmarcelUNITY_FIXTURE_T UnityFixture; 14130812Smarcel 15130812Smarcel//If you decide to use the function pointer approach. 16130812Smarcelint (*outputChar)(int) = putchar; 17130812Smarcel 18130812Smarcelint verbose = 0; 19130812Smarcel 20130812Smarcel 21130812Smarcelstatic void announceTestRun(unsigned int runNumber) 22130812Smarcel{ 23130812Smarcel UnityPrint("Unity test run "); 24130812Smarcel UnityPrintNumber(runNumber+1); 25130812Smarcel UnityPrint(" of "); 26130812Smarcel UnityPrintNumber(UnityFixture.RepeatCount); 27130812Smarcel UNITY_OUTPUT_CHAR('\n'); 28130812Smarcel} 29130812Smarcel 30130812Smarcelint UnityMain(int argc, const char* argv[], void (*runAllTests)(void)) 31130812Smarcel{ 32130812Smarcel int result = UnityGetCommandLineOptions(argc, argv); 33130812Smarcel unsigned int r; 34130812Smarcel if (result != 0) 35130812Smarcel return result; 36130812Smarcel 37130812Smarcel for (r = 0; r < UnityFixture.RepeatCount; r++) 38130812Smarcel { 39130812Smarcel UnityBegin(argv[0]); 40130812Smarcel announceTestRun(r); 41130812Smarcel runAllTests(); 42130812Smarcel UNITY_OUTPUT_CHAR('\n'); 43130812Smarcel UnityEnd(); 44130812Smarcel } 45130812Smarcel 46130812Smarcel return UnityFailureCount(); 47130812Smarcel} 48130812Smarcel 49130812Smarcelstatic int selected(const char * filter, const char * name) 50130812Smarcel{ 51130812Smarcel if (filter == 0) 52130812Smarcel return 1; 53130812Smarcel return strstr(name, filter) ? 1 : 0; 54130812Smarcel} 55130812Smarcel 56130812Smarcelstatic int testSelected(const char* test) 57130812Smarcel{ 58130812Smarcel return selected(UnityFixture.NameFilter, test); 59130812Smarcel} 60130812Smarcel 61130812Smarcelstatic int groupSelected(const char* group) 62130812Smarcel{ 63130812Smarcel return selected(UnityFixture.GroupFilter, group); 64130812Smarcel} 65130812Smarcel 66130812Smarcelstatic void runTestCase(void) 67130812Smarcel{ 68130812Smarcel 69130812Smarcel} 70130812Smarcel 71130812Smarcelvoid UnityTestRunner(unityfunction* setup, 72130812Smarcel unityfunction* testBody, 73130812Smarcel unityfunction* teardown, 74130812Smarcel const char * printableName, 75130812Smarcel const char * group, 76130812Smarcel const char * name, 77130812Smarcel const char * file, int line) 78130812Smarcel{ 79130812Smarcel if (testSelected(name) && groupSelected(group)) 80130812Smarcel { 81130812Smarcel Unity.CurrentTestFailed = 0; 82130812Smarcel Unity.TestFile = file; 83130812Smarcel Unity.CurrentTestName = printableName; 84130812Smarcel Unity.CurrentTestLineNumber = line; 85130812Smarcel if (!UnityFixture.Verbose) 86130812Smarcel UNITY_OUTPUT_CHAR('.'); 87130812Smarcel else 88130812Smarcel UnityPrint(printableName); 89130812Smarcel 90130812Smarcel Unity.NumberOfTests++; 91130812Smarcel UnityMalloc_StartTest(); 92130812Smarcel UnityPointer_Init(); 93130812Smarcel 94130812Smarcel runTestCase(); 95130812Smarcel if (TEST_PROTECT()) 96130812Smarcel { 97130812Smarcel setup(); 98130812Smarcel testBody(); 99130812Smarcel } 100130812Smarcel if (TEST_PROTECT()) 101130812Smarcel { 102130812Smarcel teardown(); 103130812Smarcel } 104130812Smarcel if (TEST_PROTECT()) 105130812Smarcel { 106130812Smarcel UnityPointer_UndoAllSets(); 107130812Smarcel if (!Unity.CurrentTestFailed) 108130812Smarcel UnityMalloc_EndTest(); 109130812Smarcel } 110130812Smarcel UnityConcludeFixtureTest(); 111130812Smarcel } 112130812Smarcel} 113130812Smarcel 114130812Smarcelvoid UnityIgnoreTest(const char * printableName) 115130812Smarcel{ 116130812Smarcel Unity.NumberOfTests++; 117130812Smarcel Unity.CurrentTestIgnored = 1; 118130812Smarcel if (!UnityFixture.Verbose) 119130812Smarcel UNITY_OUTPUT_CHAR('!'); 120130812Smarcel else 121130812Smarcel UnityPrint(printableName); 122130812Smarcel UnityConcludeFixtureTest(); 123130812Smarcel} 124130812Smarcel 125130812Smarcel 126130812Smarcel//------------------------------------------------- 127130812Smarcel//Malloc and free stuff 128130812Smarcel// 129130812Smarcel#define MALLOC_DONT_FAIL -1 130130812Smarcelstatic int malloc_count; 131130812Smarcelstatic int malloc_fail_countdown = MALLOC_DONT_FAIL; 132130812Smarcel 133130812Smarcelvoid UnityMalloc_StartTest(void) 134130812Smarcel{ 135130812Smarcel malloc_count = 0; 136130812Smarcel malloc_fail_countdown = MALLOC_DONT_FAIL; 137130812Smarcel} 138130812Smarcel 139130812Smarcelvoid UnityMalloc_EndTest(void) 140130812Smarcel{ 141130812Smarcel malloc_fail_countdown = MALLOC_DONT_FAIL; 142130812Smarcel if (malloc_count != 0) 143130812Smarcel { 144130812Smarcel TEST_FAIL_MESSAGE("This test leaks!"); 145130812Smarcel } 146130812Smarcel} 147130812Smarcel 148130812Smarcelvoid UnityMalloc_MakeMallocFailAfterCount(int countdown) 149130812Smarcel{ 150130812Smarcel malloc_fail_countdown = countdown; 151130812Smarcel} 152130812Smarcel 153130812Smarcel#ifdef malloc 154130812Smarcel#undef malloc 155130812Smarcel#endif 156130812Smarcel 157130812Smarcel#ifdef free 158130812Smarcel#undef free 159130812Smarcel#endif 160130812Smarcel 161130812Smarcel#ifdef calloc 162130812Smarcel#undef calloc 163130812Smarcel#endif 164130812Smarcel 165130812Smarcel#ifdef realloc 166130812Smarcel#undef realloc 167130812Smarcel#endif 168130812Smarcel 169130812Smarcel#include <stdlib.h> 170130812Smarcel#include <string.h> 171130812Smarcel 172130812Smarceltypedef struct GuardBytes 173130812Smarcel{ 174130812Smarcel size_t size; 175130812Smarcel char guard[sizeof(size_t)]; 176130812Smarcel} Guard; 177130812Smarcel 178130812Smarcel 179static const char * end = "END"; 180 181void * 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 203static 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 212static void release_memory(void * mem) 213{ 214 Guard* guard = (Guard*)mem; 215 guard--; 216 217 malloc_count--; 218 free(guard); 219} 220 221void 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 231void* 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 238void* 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 272typedef struct _PointerPair 273{ 274 struct _PointerPair * next; 275 void ** pointer; 276 void * old_value; 277} PointerPair; 278 279enum {MAX_POINTERS=50}; 280static PointerPair pointer_store[MAX_POINTERS]; 281static int pointer_index = 0; 282 283void UnityPointer_Init(void) 284{ 285 pointer_index = 0; 286} 287 288void 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 299void 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 310int UnityFailureCount(void) 311{ 312 return Unity.TestFailures; 313} 314 315int 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 369void 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