1 /* 2 ****************************************************************** 3 ****************************************************************** 4 ******* ******** 5 ****** (C) 1988-2010 Tecplot, Inc. ******* 6 ******* ******** 7 ****************************************************************** 8 ****************************************************************** 9 */ 10 /* 11 * Provide four levels of assertion control. Assertions provide a mechanism 12 * to enforce a contract between a client and service provider. The assertions 13 * are listed in order of highest to lowest priority. Assertions can be turned 14 * off individually by defining the appropriate name (see preprossessor 15 * definitions below), however, lower priority assertions should be turned 16 * off prior to higher ones. As confidence in the code increases all assertions 17 * can be turned off by defining NO_ASSERTS. 18 * 19 * The assertions defined below have the following meanings: 20 * 21 * INVARIANT - Asserts that a property's state is invariant throughout the 22 * life of the property's scope. Stating invariant properties 23 * of an application provides a deeper understanding of the 24 * application's state. These statements are usually 25 * positioned just ahead of the preconditions and just after 26 * the postconditions. 27 * 28 * REQUIRE - Asserts that a method's preconditions are within their 29 * valid domains. Preconditions are conditions placed upon 30 * any state information relied upon for the call. These 31 * statements should be as close to the top of the method 32 * as possible (except for assertions on invariant properties). 33 * 34 * ENSURE - Asserts that a method's postconditions are within their 35 * valid ranges. Postconditions are conditions placed upon 36 * any state information modified by the call. These 37 * statements should be as close to the bottom of the method 38 * (presumably there is only one exit point) as possible 39 * (except for assertions on invariant properties). 40 * 41 * CHECK - Any other assertion not covered by the above assertions. 42 * These are often added within a method body to specify 43 * something that may not be immediately obvious to the reader 44 * or to validate your assumptions about a call to a 3rd party 45 * method that does not use runtime assertions for its 46 * preconditions or postconditions. Obviously if the 3rd party 47 * method uses assertions then there is no need for the CHECK. 48 * 49 * Additionally a convenience macro is available to place in code that is 50 * pending implementation. 51 * 52 * NOT_IMPLEMENTED - Assertion that always fails during runtime for debug 53 * builds and always fails at compile time for release 54 * builds. 55 */ 56 #if !defined TASSERT_H 57 #define TASSERT_H 58 59 #if defined (MSWIN) 60 # include <assert.h> 61 #endif /* MSWIN */ 62 63 #if !defined TECPLOTKERNEL && !defined STD_ASSERTS 64 #define STD_ASSERTS 65 #endif 66 67 #if !defined (MSWIN) 68 # include <assert.h> 69 # if !defined ASSERT 70 # define ASSERT assert 71 # endif 72 #endif 73 74 #if defined MSWIN 75 /* MFC .NET defines ENSURE, so we undefine it here */ 76 #if defined ENSURE 77 #undef ENSURE 78 #endif /* ENSURE */ 79 #endif /* MSWIN */ 80 81 /* BEGINREMOVEFROMADDON */ 82 #define INVALID_REF ((void *)0x0000FFFF) 83 /* 84 * Chances are low the address 0x11111111 will be used, so we'll risk asserting 85 * against it (see unitialized assignment in newmalloc). 86 */ 87 #define UNINITIALIZED_REF ((void *)0x11111111) 88 #define INVALID_FN_REF ((void *)NULL) 89 /* ENDREMOVEFROMADDON */ 90 91 #ifdef UNIXX 92 /* BEGINREMOVEFROMADDON */ 93 #if defined TECPLOTKERNEL 94 /* CORE SOURCE CODE REMOVED */ 95 # if defined NO_ASSERTS 96 # else 97 # endif 98 #endif /* TECPLOTKERNAL */ 99 /* ENDREMOVEFROMADDON */ 100 101 /* BEGINREMOVEFROMADDON */ 102 #if !defined TECPLOTKERNEL 103 /* For add-ons, there is a problem with VALID_REF, so just test for non-NULL */ 104 /* ENDREMOVEFROMADDON */ 105 # if !defined VALID_REF 106 # define VALID_REF(p) ( (p) != NULL ) 107 # endif 108 # if !defined VALID_FN_REF 109 # define VALID_FN_REF(fp) ( (fp) != NULL ) 110 # endif 111 /* BEGINREMOVEFROMADDON */ 112 #endif /* !defined TECPLOTKERNAL */ 113 /* ENDREMOVEFROMADDON */ 114 115 /* BEGINREMOVEFROMADDON */ 116 /* Widgets are pointers under Motif */ 117 # define VALID_WIDGET(widget) VALID_REF((widget)) 118 /* Menu widgets are pointers too */ 119 # define VALID_MENU_WIDGET(widget) VALID_REF((widget)) 120 /* ENDREMOVEFROMADDON */ 121 #endif /* UNIXX */ 122 123 #ifdef MSWIN 124 /* BEGINREMOVEFROMADDON */ 125 /* Don't use AfxIsValidAddress()! See Bug <7245>. 126 1/4/08, dto. */ 127 /* ENDREMOVEFROMADDON */ 128 129 #if defined NO_ASSERTS 130 /* release build in TecUtil layer uses these for TUASSERT */ 131 # if !defined VALID_REF 132 # define VALID_REF(p) ((p) != NULL) 133 # endif 134 # if !defined VALID_FN_REF 135 # define VALID_FN_REF(pf) ((pf) != NULL) 136 # endif 137 #else 138 # if !defined VALID_REF 139 # define VALID_REF(p) ((p) != NULL && !IsBadReadPtr((const void *)(p), 1)) 140 # endif 141 # if !defined VALID_FN_REF 142 # define VALID_FN_REF(pf) ((pf) != NULL && !IsBadReadPtr((const void *)(pf),(UINT_PTR)sizeof(const void*))) 143 # endif 144 #endif 145 146 /* BEGINREMOVEFROMADDON */ 147 /* Widgets are numbers under Windows, so we decode it with GetWindowFromWidget */ 148 # if defined ENGINE 149 # define VALID_WIDGET(widget) ((widget) != NULL) 150 # else 151 # define VALID_WIDGET(widget) ((widget) != NULL && GetWindowFromWidget((widget))!=NULL) 152 # endif // ENGINE 153 154 /* Menu widgets are numbers too, so we just check against zero */ 155 # define VALID_MENU_WIDGET(widget) ((widget)!=NULL) 156 /* ENDREMOVEFROMADDON */ 157 #endif /* MSWIN */ 158 /* BEGINREMOVEFROMADDON */ 159 /* handles are not pointers to memory, so the only test we can */ 160 /* perform is to check for 0 */ 161 #define VALID_HANDLE(handle) ((handle)!=0) 162 163 #if defined FLEXLM 164 #define VALID_FLEX_JOB_HANDLE(handle) ((handle) != NULL) 165 #define VALID_FLEX_ERROR_CODE(ErrorCode)(ErrorCode <= 0) 166 #endif /* FLEXLM */ 167 168 /* ENDREMOVEFROMADDON */ 169 /* other useful validity checks */ 170 #if !defined VALID_BOOLEAN 171 # define VALID_BOOLEAN(b) ((b) == TRUE || (b) == FALSE) 172 #endif 173 #if !defined VALID_ENUM 174 # define VALID_ENUM(value, type) (0 <= (int)(value) && \ 175 (int)(value) < END_##type) 176 #endif 177 178 /* Test a parameter than can be NULL or a valid pointer */ 179 #if !defined VALID_REF_OR_NULL 180 # define VALID_REF_OR_NULL(ptr) IMPLICATION((ptr) != NULL, VALID_REF(ptr)) 181 #endif 182 #if !defined VALID_FN_REF_OR_NULL 183 # define VALID_FN_REF_OR_NULL(ptr) IMPLICATION((ptr) != NULL, VALID_FN_REF(ptr)) 184 #endif 185 186 /* BEGINREMOVEFROMADDON */ 187 #define VALID_TRANSLATED_STRING(ts) (!(ts).isNull()) 188 189 /** 190 * These macros are a little complicated but it allows one to 191 * write a simple assertion regardless of the zone type or 192 * selected plane: 193 * 194 * REQUIRE(VALID_CELL_INDEX(CZData, CellIndex, Plane))); 195 * 196 * Prior to using the macros a call to SetupXxx, 197 * or at a minimum SetupCZData, must be called to setup 198 * the globals defining the dataset structure. 199 */ 200 #define VALID_FE_CELL_INDEX(CZData, CellIndex) \ 201 (/* CellIndex range test */ \ 202 0 <= (CellIndex) && \ 203 (CellIndex) < (CZData)->NumElements) 204 205 #define VALID_IPLANE_CELL_INDEX(CZData,CellIndex) \ 206 (/* CellIndex range test */ \ 207 (CellIndex) >= 0 && \ 208 IINDEX((CZData),CellIndex) <= MAX((CZData)->NumIPtsM1,1) && \ 209 JINDEX((CZData),CellIndex) < MAX((CZData)->NumJPtsM1,1) && \ 210 KINDEX((CZData),CellIndex) < MAX((CZData)->NumKPtsM1,1)) 211 212 #define VALID_JPLANE_CELL_INDEX(CZData,CellIndex) \ 213 (/* CellIndex range test */ \ 214 (CellIndex) >= 0 && \ 215 IINDEX((CZData),CellIndex) < MAX((CZData)->NumIPtsM1,1) && \ 216 JINDEX((CZData),CellIndex) <= MAX((CZData)->NumJPtsM1,1) && \ 217 KINDEX((CZData),CellIndex) < MAX((CZData)->NumKPtsM1,1)) 218 219 #define VALID_KPLANE_CELL_INDEX(CZData,CellIndex) \ 220 (/* CellIndex range test */ \ 221 (CellIndex) >= 0 && \ 222 IINDEX((CZData),CellIndex) < MAX((CZData)->NumIPtsM1,1) && \ 223 JINDEX((CZData),CellIndex) < MAX((CZData)->NumJPtsM1,1) && \ 224 KINDEX((CZData),CellIndex) <= MAX((CZData)->NumKPtsM1,1)) 225 226 #define VALID_ORDERED_CELL_INDEX(CZData, CellIndex, Plane) \ 227 (/* macro preconditions */ \ 228 ((IJKPlanes_e)(Plane) == IJKPlanes_I || \ 229 (IJKPlanes_e)(Plane) == IJKPlanes_J || \ 230 (IJKPlanes_e)(Plane) == IJKPlanes_K || \ 231 (IJKPlanes_e)(Plane) == IJKPlanes_Volume) && \ 232 \ 233 /* CellIndex range test */ \ 234 (IMPLICATION(((IJKPlanes_e)(Plane) == IJKPlanes_I || \ 235 (IJKPlanes_e)(Plane) == IJKPlanes_Volume), \ 236 VALID_IPLANE_CELL_INDEX((CZData),CellIndex)) && \ 237 IMPLICATION(((IJKPlanes_e)(Plane) == IJKPlanes_J || \ 238 (IJKPlanes_e)(Plane) == IJKPlanes_Volume), \ 239 VALID_JPLANE_CELL_INDEX((CZData),CellIndex)) && \ 240 IMPLICATION(((IJKPlanes_e)(Plane) == IJKPlanes_K || \ 241 (IJKPlanes_e)(Plane) == IJKPlanes_Volume), \ 242 VALID_KPLANE_CELL_INDEX((CZData),CellIndex)))) 243 244 #define VALID_CELL_INDEX(CZData, CellIndex, Plane) \ 245 (((CZData)->NM != NULL || (CZData)->FM != NULL) ? \ 246 VALID_FE_CELL_INDEX((CZData), (CellIndex)) : \ 247 VALID_ORDERED_CELL_INDEX((CZData), (CellIndex), (Plane))) 248 249 #define VALID_DATASET(dataSet,checkNumZones) (((dataSet) != NULL) && \ 250 IMPLICATION((checkNumZones),(dataSet)->NumZones >= 1)) 251 252 253 254 #ifdef MSWIN 255 /* Here is a more specific check in Windows for a valid 256 pointer to an MFC Window object. 257 Note that GetSafeHwnd() works even if pWnd is NULL, because 258 it checks the 'this' pointer first */ 259 # define VALID_WND(pWnd) (::IsWindow((pWnd)->GetSafeHwnd())) 260 261 #else /* !MSWIN */ 262 # define VALID_WND(pWnd) /* Should not be used in Motif */ 263 #endif /* MSWIN */ 264 /* ENDREMOVEFROMADDON */ 265 266 /* Check for a non-zero length string */ 267 #if !defined VALID_NON_ZERO_LEN_STR 268 # if defined MSWIN 269 # if defined NO_ASSERTS 270 # define VALID_NON_ZERO_LEN_STR(str) (VALID_REF(str) && !ISEMPTYSTRING(str)) 271 # else 272 # define VALID_NON_ZERO_LEN_STR(str) \ 273 (VALID_REF(str) && \ 274 !IsBadReadPtr((const void*)(str),(UINT_PTR)(1+strlen((const char*)(str)))) && \ 275 !ISEMPTYSTRING(str)) 276 # endif 277 # else 278 # define VALID_NON_ZERO_LEN_STR(str) (VALID_REF(str) && !ISEMPTYSTRING(str)) 279 # endif 280 #endif 281 282 #if !defined VALID_SET_INDEX 283 # define VALID_SET_INDEX(setIndex) (((SetIndex_t)setIndex)>=(SetIndex_t)1) 284 #endif 285 286 /* Check for valid stdio file handle */ 287 #if !defined VALID_FILE_HANDLE 288 # define VALID_FILE_HANDLE(stream) ((stream) != NULL) 289 #endif 290 291 /* To check colors and pen numbers */ 292 /* BEGINREMOVEFROMADDON */ 293 #define VALID_BASIC_COLOR(BColor) \ 294 (FirstBasicColor<=(BColor) && (BColor)<=LastBasicColor) 295 #define VALID_CONTOUR_COLOR(Color) \ 296 (ContourColorOffset<=(Color) && \ 297 (Color)<ContourColorOffset+GeneralBase.Limits.MaxNumContourLevels+1) 298 #define VALID_PLOTTING_COLOR(Color) \ 299 (VALID_BASIC_COLOR(Color) || VALID_CONTOUR_COLOR(Color)) 300 #define VALID_INTERFACE_SPECIFIC_COLOR(BColor) \ 301 (FirstInterfaceColor<=(BColor) && (BColor)<=LastInterfaceColor) 302 #define VALID_INTERFACE_COLOR(Color) \ 303 (VALID_PLOTTING_COLOR(Color) || VALID_INTERFACE_SPECIFIC_COLOR(Color)) 304 #define VALID_MULTICOLOR_COLOR(Color) \ 305 (((Color) == MultiColor_C) || ((Color) == MultiColor2_C) || \ 306 ((Color) == MultiColor3_C) || ((Color) == MultiColor4_C) || \ 307 ((Color) == MultiColor5_C) || ((Color) == MultiColor6_C) || \ 308 ((Color) == MultiColor7_C) || ((Color) == MultiColor8_C)) 309 #define VALID_RGB_COLOR(Color) \ 310 ((Color) == RGBColor_C) 311 #define VALID_ASSIGNABLE_COLOR(C) \ 312 (VALID_BASIC_COLOR(C) || \ 313 VALID_MULTICOLOR_COLOR(C) || \ 314 VALID_RGB_COLOR(C)) 315 #define VALID_PEN_OFFSET(PenOffset) \ 316 (Black_C<=(PenOffset) && (PenOffset)<=NumPlotterPens) 317 #define VALID_PEN_OFFSET_FOR_OBJECT(PenOffset) \ 318 (FirstObjectPen<=(PenOffset) && (PenOffset)<=LastObjectPen) 319 320 321 /* to check FE cells */ 322 #define VALID_ELEMENT_TYPE(element_type) \ 323 ((element_type) == ZoneType_FETriangle || \ 324 (element_type) == ZoneType_FEQuad || \ 325 (element_type) == ZoneType_FETetra || \ 326 (element_type) == ZoneType_FEBrick || \ 327 (element_type) == ZoneType_FELineSeg) 328 329 330 331 /* 332 * Test validity of zone and variable names. A valid name is one that has a 333 * valid reference, is not padded with spaces and is within the maximum 334 * specified length. 335 */ 336 #define VALID_NAME(Name, MaxLength) \ 337 (VALID_REF(Name) && \ 338 (ISEMPTYSTRING(Name) || \ 339 (!tecplot::isspace((Name)[0]) && !tecplot::isspace((Name)[strlen(Name)-1]))) && \ 340 strlen(Name) <= (MaxLength)) 341 #define VALID_ZONE_NAME(Name) VALID_NAME((Name), MaxChrsZnTitle) 342 #define VALID_VAR_NAME(Name) VALID_NAME((Name), MaxChrsVarName) 343 344 345 /* Special test for lighting effect (don't allow "none" in some cases) */ 346 #define VALID_LIGHTINGEFFECT(L) \ 347 (((L) == LightingEffect_Paneled) || ((L) == LightingEffect_Gouraud)) 348 349 350 /* type definition for assert failure notification function */ 351 typedef void (*TAssertFailureNotifyFunc)( 352 const char *expression, /* text representation of the assertion */ 353 const char *file_name, /* name of the file containing the assertion */ 354 int line); /* line number in the file of the assertion */ 355 356 #if !defined STD_ASSERTS 357 /* external function prototypes */ 358 extern void TAssert( 359 const char *expression, /* text representation of the assertion */ 360 const char *file_name, /* name of the file containing the assertion */ 361 int line); /* line number in the file of the assertion */ 362 363 extern TAssertFailureNotifyFunc InstallTAssertFailureNotify( 364 TAssertFailureNotifyFunc new_function); /* new notification function */ 365 #endif /* !STD_ASSERTS */ 366 /* ENDREMOVEFROMADDON */ 367 368 #if defined NO_ASSERTS 369 /* BEGINREMOVEFROMADDON */ 370 # define TASSERT(EXPR) 371 /* ENDREMOVEFROMADDON */ 372 # if !defined INVARIANT 373 # define INVARIANT(EXPR) 374 # endif 375 # if !defined REQUIRE 376 # define REQUIRE(EXPR) 377 # endif 378 # if !defined ENSURE 379 # define ENSURE(EXPR) 380 # endif 381 # if !defined CHECK 382 # define CHECK(EXPR) 383 # endif 384 # ifdef VERIFY 385 # undef VERIFY 386 # endif 387 # define VERIFY(EXPR) ((void)(EXPR)) 388 389 /* 390 * If a project is compiled with "warnings treated as errors" we need a way to 391 * to remove parameters that are only used for assertions if assertions are 392 * turned off. 393 * 394 * This macro is used in the implementation as follows: 395 * 396 * void someFunction(int const ASSERT_ONLY_PARAM(paramOnlyUsedInAssertions)) 397 * { 398 * ... 399 * } 400 */ 401 # if !defined ASSERT_ONLY_PARAM 402 # define ASSERT_ONLY_PARAM(PARAMETER) 403 # endif 404 405 /* 406 * Only define IGNORENOTIMPLEMENTED if building a "test" release build 407 * that you are fully aware may contain unimplemented features. 408 */ 409 # if !defined NOT_IMPLEMENTED 410 # if defined IGNORENOTIMPLEMENTED 411 # define NOT_IMPLEMENTED() CHECK(FALSE) 412 # else 413 # if defined MSWIN 414 /* 415 * NOT_IMPLEMENTED is defined using a parameter, but should be called with none, 416 * this will then throw a warning and not break the compile. Unix doesn't pick 417 * up this warning, so break the compile under Unix 418 */ 419 # define NOT_IMPLEMENTED(x) TAssert("Not Implemented", __FILE__, __LINE__) 420 # endif 421 # if defined UNIXX 422 # define NOT_IMPLEMENTED() not implemented /* intentionally break the compile */ 423 # endif 424 # endif 425 # endif 426 #elif defined STD_ASSERTS 427 /* BEGINREMOVEFROMADDON */ 428 # define TASSERT(EXPR) assert(EXPR) 429 /* ENDREMOVEFROMADDON */ 430 # if !defined INVARIANT 431 # define INVARIANT(EXPR) assert(EXPR) 432 # endif 433 # if !defined REQUIRE 434 # define REQUIRE(EXPR) assert(EXPR) 435 # endif 436 # if !defined ENSURE 437 # define ENSURE(EXPR) assert(EXPR) 438 # endif 439 # if !defined CHECK 440 # define CHECK(EXPR) assert(EXPR) 441 # endif 442 # ifdef VERIFY 443 # undef VERIFY 444 # endif 445 # ifndef VERIFY 446 # if defined NDEBUG 447 # define VERIFY(EXPR) ((void)(EXPR)) 448 # else 449 # define VERIFY(EXPR) assert(EXPR) 450 # endif 451 # endif /* VERIFY */ 452 # if !defined NOT_IMPLEMENTED 453 # define NOT_IMPLEMENTED() assert(!("Not Implemented")) 454 # endif 455 /* 456 * See note above for this macro. 457 */ 458 # if !defined ASSERT_ONLY_PARAM 459 # define ASSERT_ONLY_PARAM(PARAMETER) PARAMETER 460 # endif 461 #else 462 /* BEGINREMOVEFROMADDON */ 463 #if defined (MSWIN) 464 #if defined CHECKED_BUILD 465 #include <string> 466 #include <vector> 467 #include <algorithm> 468 469 class AssertionLog 470 { 471 public: 472 static void initializeAssertLog(const std::string &fileName); 473 static bool isLoggingAssertions(); 474 static void addAssertion(const std::string &message); 475 private: 476 static void writeOutAssertion(const std::string &message); 477 private: 478 static bool logAssertions; 479 static std::string logFileName; 480 static std::vector<std::string> assertList; 481 }; 482 483 extern void TWinCheckedFailedLine(const char *Expr, 484 const char *FileName, 485 int LineNum); 486 487 #define TASSERT(EXPR)\ 488 do { if (!(EXPR)) { TWinCheckedFailedLine(#EXPR,__FILE__,__LINE__); } } while (0) 489 #else 490 #define TASSERT(EXPR) ASSERT(EXPR) /* MFC assert. 491 Works in both release & debug builds */ 492 #endif /* CHECKED_BUILD */ 493 #else 494 #define TASSERT(EXPR) (void)((EXPR) || (TAssert(#EXPR, __FILE__, __LINE__), 0)) 495 #endif 496 497 # if defined NO_INVARIANTS 498 # define INVARIANT(EXPR) 499 # else 500 # define INVARIANT(EXPR) TASSERT(EXPR) 501 # endif 502 503 # if defined NO_PRECONDITIONS 504 # define REQUIRE(EXPR) 505 # else 506 # define REQUIRE(EXPR) TASSERT(EXPR) 507 # endif 508 509 # if defined NO_POSTCONDITIONS 510 # define ENSURE(EXPR) 511 # else 512 # define ENSURE(EXPR) TASSERT(EXPR) 513 # endif 514 515 # if defined VERIFY 516 # undef VERIFY 517 # endif 518 519 # if defined NO_CHECKS 520 # define CHECK(EXPR) 521 # define VERIFY(EXPR) ((void)(EXPR)) 522 # else 523 # define CHECK(EXPR) TASSERT(EXPR) 524 # if defined NDEBUG 525 # define VERIFY(EXPR) ((void)(EXPR)) 526 # else 527 # define VERIFY(EXPR) TASSERT(EXPR) 528 # endif 529 # endif 530 531 # if defined NICE_NOT_IMPLEMENTED 532 # define NOT_IMPLEMENTED() NiceNotImplemented() 533 # else 534 # define NOT_IMPLEMENTED() TASSERT(!("Not Implemented")) 535 # endif 536 /* 537 * See note above for this macro. 538 */ 539 # define ASSERT_ONLY_PARAM(PARAMETER) PARAMETER 540 /* ENDREMOVEFROMADDON */ 541 #endif 542 /* BEGINREMOVEFROMADDON */ 543 #if !defined STD_ASSERTS 544 extern void TecplotMopupOnAssert(void); 545 #endif /* !STD_ASSERTS */ 546 547 #if defined NICE_NOT_IMPLEMENTED 548 extern void NiceNotImplemented(void); 549 #endif 550 /* ENDREMOVEFROMADDON */ 551 552 /* convenience macros for implication, P -> Q, and equivalence, P <-> Q. */ 553 #if !defined IMPLICATION 554 # define IMPLICATION(P,Q) (!(P) || (Q)) 555 #endif 556 #if !defined EQUIVALENCE 557 # define EQUIVALENCE(P,Q) ((P) == (Q)) 558 #endif 559 560 /* BEGINREMOVEFROMADDON */ 561 #if defined RLM 562 #define VALID_RLM_HANDLE(h) ((h) != NULL) 563 #endif /* RLM */ 564 /* ENDREMOVEFROMADDON */ 565 566 567 #endif /* TASSERT_H */ 568