1 /* 2 File: CADebugMacros.h 3 Abstract: Part of CoreAudio Utility Classes 4 Version: 1.0.3 5 6 Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple 7 Inc. ("Apple") in consideration of your agreement to the following 8 terms, and your use, installation, modification or redistribution of 9 this Apple software constitutes acceptance of these terms. If you do 10 not agree with these terms, please do not use, install, modify or 11 redistribute this Apple software. 12 13 In consideration of your agreement to abide by the following terms, and 14 subject to these terms, Apple grants you a personal, non-exclusive 15 license, under Apple's copyrights in this original Apple software (the 16 "Apple Software"), to use, reproduce, modify and redistribute the Apple 17 Software, with or without modifications, in source and/or binary forms; 18 provided that if you redistribute the Apple Software in its entirety and 19 without modifications, you must retain this notice and the following 20 text and disclaimers in all such redistributions of the Apple Software. 21 Neither the name, trademarks, service marks or logos of Apple Inc. may 22 be used to endorse or promote products derived from the Apple Software 23 without specific prior written permission from Apple. Except as 24 expressly stated in this notice, no other rights or licenses, express or 25 implied, are granted by Apple herein, including but not limited to any 26 patent rights that may be infringed by your derivative works or by other 27 works in which the Apple Software may be incorporated. 28 29 The Apple Software is provided by Apple on an "AS IS" basis. APPLE 30 MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION 31 THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS 32 FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND 33 OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. 34 35 IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL 36 OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 37 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 38 INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, 39 MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED 40 AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), 41 STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE 42 POSSIBILITY OF SUCH DAMAGE. 43 44 Copyright (C) 2013 Apple Inc. All Rights Reserved. 45 46 */ 47 #if !defined(__CADebugMacros_h__) 48 #define __CADebugMacros_h__ 49 50 //============================================================================= 51 // Includes 52 //============================================================================= 53 54 #if !defined(__COREAUDIO_USE_FLAT_INCLUDES__) 55 #include <CoreAudio/CoreAudioTypes.h> 56 #else 57 #include "CoreAudioTypes.h" 58 #endif 59 60 //============================================================================= 61 // CADebugMacros 62 //============================================================================= 63 64 //#define CoreAudio_StopOnFailure 1 65 //#define CoreAudio_TimeStampMessages 1 66 //#define CoreAudio_ThreadStampMessages 1 67 //#define CoreAudio_FlushDebugMessages 1 68 69 #if TARGET_RT_BIG_ENDIAN 70 #define CA4CCToCString(the4CC) { ((char*)&the4CC)[0], ((char*)&the4CC)[1], ((char*)&the4CC)[2], ((char*)&the4CC)[3], 0 } 71 #define CACopy4CCToCString(theCString, the4CC) { theCString[0] = ((char*)&the4CC)[0]; theCString[1] = ((char*)&the4CC)[1]; theCString[2] = ((char*)&the4CC)[2]; theCString[3] = ((char*)&the4CC)[3]; theCString[4] = 0; } 72 #else 73 #define CA4CCToCString(the4CC) { ((char*)&the4CC)[3], ((char*)&the4CC)[2], ((char*)&the4CC)[1], ((char*)&the4CC)[0], 0 } 74 #define CACopy4CCToCString(theCString, the4CC) { theCString[0] = ((char*)&the4CC)[3]; theCString[1] = ((char*)&the4CC)[2]; theCString[2] = ((char*)&the4CC)[1]; theCString[3] = ((char*)&the4CC)[0]; theCString[4] = 0; } 75 #endif 76 77 // This is a macro that does a sizeof and casts the result to a UInt32. This is useful for all the 78 // places where -wshorten64-32 catches assigning a sizeof expression to a UInt32. 79 // For want of a better place to park this, we'll park it here. 80 #define SizeOf32(X) ((UInt32)sizeof(X)) 81 82 // This is a macro that does a offsetof and casts the result to a UInt32. This is useful for all the 83 // places where -wshorten64-32 catches assigning an offsetof expression to a UInt32. 84 // For want of a better place to park this, we'll park it here. 85 #define OffsetOf32(X, Y) ((UInt32)offsetof(X, Y)) 86 87 // This macro casts the expression to a UInt32. It is called out specially to allow us to track casts 88 // that have been added purely to avert -wshorten64-32 warnings on 64 bit platforms. 89 // For want of a better place to park this, we'll park it here. 90 #define ToUInt32(X) ((UInt32)(X)) 91 92 #pragma mark Basic Definitions 93 94 #if DEBUG || CoreAudio_Debug 95 // can be used to break into debugger immediately, also see CADebugger 96 #define BusError() { long* p=NULL; *p=0; } 97 98 // basic debugging print routines 99 #if TARGET_OS_MAC && !TARGET_API_MAC_CARBON 100 extern void DebugStr(const unsigned char* debuggerMsg); 101 #define DebugMessage(msg) DebugStr("\p"msg) 102 #define DebugMessageN1(msg, N1) 103 #define DebugMessageN2(msg, N1, N2) 104 #define DebugMessageN3(msg, N1, N2, N3) 105 #else 106 #include "CADebugPrintf.h" 107 108 #if (CoreAudio_FlushDebugMessages && !CoreAudio_UseSysLog) || defined(CoreAudio_UseSideFile) 109 #define FlushRtn ,fflush(DebugPrintfFile) 110 #else 111 #define FlushRtn 112 #endif 113 114 #if CoreAudio_ThreadStampMessages 115 #include <pthread.h> 116 #include "CAHostTimeBase.h" 117 #if TARGET_RT_64_BIT 118 #define DebugPrintfThreadIDFormat "%16p" 119 #else 120 #define DebugPrintfThreadIDFormat "%8p" 121 #endif 122 #define DebugMsg(inFormat, ...) DebugPrintf("%17qd: " DebugPrintfThreadIDFormat " " inFormat, CAHostTimeBase::GetCurrentTimeInNanos(), pthread_self(), ## __VA_ARGS__) FlushRtn 123 #elif CoreAudio_TimeStampMessages 124 #include "CAHostTimeBase.h" 125 #define DebugMsg(inFormat, ...) DebugPrintf("%17qd: " inFormat, CAHostTimeBase::GetCurrentTimeInNanos(), ## __VA_ARGS__) FlushRtn 126 #else 127 #define DebugMsg(inFormat, ...) DebugPrintf(inFormat, ## __VA_ARGS__) FlushRtn 128 #endif 129 #endif 130 void DebugPrint(const char *fmt, ...); // can be used like printf 131 #ifndef DEBUGPRINT 132 #define DEBUGPRINT(msg) DebugPrint msg // have to double-parenthesize arglist (see Debugging.h) 133 #endif 134 #if VERBOSE 135 #define vprint(msg) DEBUGPRINT(msg) 136 #else 137 #define vprint(msg) 138 #endif 139 140 // Original macro keeps its function of turning on and off use of CADebuggerStop() for both asserts and throws. 141 // For backwards compat, it overrides any setting of the two sub-macros. 142 #if CoreAudio_StopOnFailure 143 #include "CADebugger.h" 144 #undef CoreAudio_StopOnAssert 145 #define CoreAudio_StopOnAssert 1 146 #undef CoreAudio_StopOnThrow 147 #define CoreAudio_StopOnThrow 1 148 #define STOP CADebuggerStop() 149 #else 150 #define STOP 151 #endif 152 153 #if CoreAudio_StopOnAssert 154 #if !CoreAudio_StopOnFailure 155 #include "CADebugger.h" 156 #define STOP 157 #endif 158 #define __ASSERT_STOP CADebuggerStop() 159 #else 160 #define __ASSERT_STOP 161 #endif 162 163 #if CoreAudio_StopOnThrow 164 #if !CoreAudio_StopOnFailure 165 #include "CADebugger.h" 166 #define STOP 167 #endif 168 #define __THROW_STOP CADebuggerStop() 169 #else 170 #define __THROW_STOP 171 #endif 172 173 #else 174 #define DebugMsg(inFormat, ...) 175 #ifndef DEBUGPRINT 176 #define DEBUGPRINT(msg) 177 #endif 178 #define vprint(msg) 179 #define STOP 180 #define __ASSERT_STOP 181 #define __THROW_STOP 182 #endif 183 184 // Old-style numbered DebugMessage calls are implemented in terms of DebugMsg() now 185 #define DebugMessage(msg) DebugMsg(msg) 186 #define DebugMessageN1(msg, N1) DebugMsg(msg, N1) 187 #define DebugMessageN2(msg, N1, N2) DebugMsg(msg, N1, N2) 188 #define DebugMessageN3(msg, N1, N2, N3) DebugMsg(msg, N1, N2, N3) 189 #define DebugMessageN4(msg, N1, N2, N3, N4) DebugMsg(msg, N1, N2, N3, N4) 190 #define DebugMessageN5(msg, N1, N2, N3, N4, N5) DebugMsg(msg, N1, N2, N3, N4, N5) 191 #define DebugMessageN6(msg, N1, N2, N3, N4, N5, N6) DebugMsg(msg, N1, N2, N3, N4, N5, N6) 192 #define DebugMessageN7(msg, N1, N2, N3, N4, N5, N6, N7) DebugMsg(msg, N1, N2, N3, N4, N5, N6, N7) 193 #define DebugMessageN8(msg, N1, N2, N3, N4, N5, N6, N7, N8) DebugMsg(msg, N1, N2, N3, N4, N5, N6, N7, N8) 194 #define DebugMessageN9(msg, N1, N2, N3, N4, N5, N6, N7, N8, N9) DebugMsg(msg, N1, N2, N3, N4, N5, N6, N7, N8, N9) 195 196 void LogError(const char *fmt, ...); // writes to syslog (and stderr if debugging) 197 void LogWarning(const char *fmt, ...); // writes to syslog (and stderr if debugging) 198 199 #define NO_ACTION (void)0 200 201 #if DEBUG || CoreAudio_Debug 202 203 #pragma mark Debug Macros 204 205 #define Assert(inCondition, inMessage) \ 206 if(!(inCondition)) \ 207 { \ 208 DebugMessage(inMessage); \ 209 __ASSERT_STOP; \ 210 } 211 212 #define AssertFileLine(inCondition, inMessage) \ 213 if(!(inCondition)) \ 214 { \ 215 DebugMessageN3("%s, line %d: %s", __FILE__, __LINE__, inMessage); \ 216 __ASSERT_STOP; \ 217 } 218 219 #define AssertNoError(inError, inMessage) \ 220 { \ 221 SInt32 __Err = (inError); \ 222 if(__Err != 0) \ 223 { \ 224 char __4CC[5] = CA4CCToCString(__Err); \ 225 DebugMessageN2(inMessage ", Error: %d (%s)", (int)__Err, __4CC); \ 226 __ASSERT_STOP; \ 227 } \ 228 } 229 230 #define AssertNoKernelError(inError, inMessage) \ 231 { \ 232 unsigned int __Err = (unsigned int)(inError); \ 233 if(__Err != 0) \ 234 { \ 235 DebugMessageN1(inMessage ", Error: 0x%X", __Err); \ 236 __ASSERT_STOP; \ 237 } \ 238 } 239 240 #define AssertNotNULL(inPtr, inMessage) \ 241 { \ 242 if((inPtr) == NULL) \ 243 { \ 244 DebugMessage(inMessage); \ 245 __ASSERT_STOP; \ 246 } \ 247 } 248 249 #define FailIf(inCondition, inHandler, inMessage) \ 250 if(inCondition) \ 251 { \ 252 DebugMessage(inMessage); \ 253 STOP; \ 254 goto inHandler; \ 255 } 256 257 #define FailWithAction(inCondition, inAction, inHandler, inMessage) \ 258 if(inCondition) \ 259 { \ 260 DebugMessage(inMessage); \ 261 STOP; \ 262 { inAction; } \ 263 goto inHandler; \ 264 } 265 266 #define FailIfNULL(inPointer, inAction, inHandler, inMessage) \ 267 if((inPointer) == NULL) \ 268 { \ 269 DebugMessage(inMessage); \ 270 STOP; \ 271 { inAction; } \ 272 goto inHandler; \ 273 } 274 275 #define FailIfKernelError(inKernelError, inAction, inHandler, inMessage) \ 276 { \ 277 unsigned int __Err = (inKernelError); \ 278 if(__Err != 0) \ 279 { \ 280 DebugMessageN1(inMessage ", Error: 0x%X", __Err); \ 281 STOP; \ 282 { inAction; } \ 283 goto inHandler; \ 284 } \ 285 } 286 287 #define FailIfError(inError, inAction, inHandler, inMessage) \ 288 { \ 289 SInt32 __Err = (inError); \ 290 if(__Err != 0) \ 291 { \ 292 char __4CC[5] = CA4CCToCString(__Err); \ 293 DebugMessageN2(inMessage ", Error: %ld (%s)", (long int)__Err, __4CC); \ 294 STOP; \ 295 { inAction; } \ 296 goto inHandler; \ 297 } \ 298 } 299 300 #define FailIfNoMessage(inCondition, inHandler, inMessage) \ 301 if(inCondition) \ 302 { \ 303 STOP; \ 304 goto inHandler; \ 305 } 306 307 #define FailWithActionNoMessage(inCondition, inAction, inHandler, inMessage) \ 308 if(inCondition) \ 309 { \ 310 STOP; \ 311 { inAction; } \ 312 goto inHandler; \ 313 } 314 315 #define FailIfNULLNoMessage(inPointer, inAction, inHandler, inMessage) \ 316 if((inPointer) == NULL) \ 317 { \ 318 STOP; \ 319 { inAction; } \ 320 goto inHandler; \ 321 } 322 323 #define FailIfKernelErrorNoMessage(inKernelError, inAction, inHandler, inMessage) \ 324 { \ 325 unsigned int __Err = (inKernelError); \ 326 if(__Err != 0) \ 327 { \ 328 STOP; \ 329 { inAction; } \ 330 goto inHandler; \ 331 } \ 332 } 333 334 #define FailIfErrorNoMessage(inError, inAction, inHandler, inMessage) \ 335 { \ 336 SInt32 __Err = (inError); \ 337 if(__Err != 0) \ 338 { \ 339 STOP; \ 340 { inAction; } \ 341 goto inHandler; \ 342 } \ 343 } 344 345 #if defined(__cplusplus) 346 347 #define Throw(inException) __THROW_STOP; throw (inException) 348 349 #define ThrowIf(inCondition, inException, inMessage) \ 350 if(inCondition) \ 351 { \ 352 DebugMessage(inMessage); \ 353 Throw(inException); \ 354 } 355 356 #define ThrowIfNULL(inPointer, inException, inMessage) \ 357 if((inPointer) == NULL) \ 358 { \ 359 DebugMessage(inMessage); \ 360 Throw(inException); \ 361 } 362 363 #define ThrowIfKernelError(inKernelError, inException, inMessage) \ 364 { \ 365 unsigned int __Err = (inKernelError); \ 366 if(__Err != 0) \ 367 { \ 368 DebugMessageN1(inMessage ", Error: 0x%X", __Err); \ 369 Throw(inException); \ 370 } \ 371 } 372 373 #define ThrowIfError(inError, inException, inMessage) \ 374 { \ 375 SInt32 __Err = (inError); \ 376 if(__Err != 0) \ 377 { \ 378 char __4CC[5] = CA4CCToCString(__Err); \ 379 DebugMessageN2(inMessage ", Error: %d (%s)", (int)__Err, __4CC); \ 380 Throw(inException); \ 381 } \ 382 } 383 384 #if TARGET_OS_WIN32 385 #define ThrowIfWinError(inError, inException, inMessage) \ 386 { \ 387 HRESULT __Err = (inError); \ 388 if(FAILED(__Err)) \ 389 { \ 390 DebugMessageN2(inMessage ", Code: %d, Facility: 0x%X", HRESULT_CODE(__Err), HRESULT_FACILITY(__Err)); \ 391 Throw(inException); \ 392 } \ 393 } 394 #endif 395 396 #define SubclassResponsibility(inMethodName, inException) \ 397 { \ 398 DebugMessage(inMethodName": Subclasses must implement this method"); \ 399 Throw(inException); \ 400 } 401 402 #endif // defined(__cplusplus) 403 404 #else 405 406 #pragma mark Release Macros 407 408 #define Assert(inCondition, inMessage) \ 409 if(!(inCondition)) \ 410 { \ 411 __ASSERT_STOP; \ 412 } 413 414 #define AssertFileLine(inCondition, inMessage) Assert(inCondition, inMessage) 415 416 #define AssertNoError(inError, inMessage) \ 417 { \ 418 SInt32 __Err = (inError); \ 419 if(__Err != 0) \ 420 { \ 421 __ASSERT_STOP; \ 422 } \ 423 } 424 425 #define AssertNoKernelError(inError, inMessage) \ 426 { \ 427 unsigned int __Err = (unsigned int)(inError); \ 428 if(__Err != 0) \ 429 { \ 430 __ASSERT_STOP; \ 431 } \ 432 } 433 434 #define AssertNotNULL(inPtr, inMessage) \ 435 { \ 436 if((inPtr) == NULL) \ 437 { \ 438 __ASSERT_STOP; \ 439 } \ 440 } 441 442 #define FailIf(inCondition, inHandler, inMessage) \ 443 if(inCondition) \ 444 { \ 445 STOP; \ 446 goto inHandler; \ 447 } 448 449 #define FailWithAction(inCondition, inAction, inHandler, inMessage) \ 450 if(inCondition) \ 451 { \ 452 STOP; \ 453 { inAction; } \ 454 goto inHandler; \ 455 } 456 457 #define FailIfNULL(inPointer, inAction, inHandler, inMessage) \ 458 if((inPointer) == NULL) \ 459 { \ 460 STOP; \ 461 { inAction; } \ 462 goto inHandler; \ 463 } 464 465 #define FailIfKernelError(inKernelError, inAction, inHandler, inMessage) \ 466 if((inKernelError) != 0) \ 467 { \ 468 STOP; \ 469 { inAction; } \ 470 goto inHandler; \ 471 } 472 473 #define FailIfError(inError, inAction, inHandler, inMessage) \ 474 if((inError) != 0) \ 475 { \ 476 STOP; \ 477 { inAction; } \ 478 goto inHandler; \ 479 } 480 481 #define FailIfNoMessage(inCondition, inHandler, inMessage) \ 482 if(inCondition) \ 483 { \ 484 STOP; \ 485 goto inHandler; \ 486 } 487 488 #define FailWithActionNoMessage(inCondition, inAction, inHandler, inMessage) \ 489 if(inCondition) \ 490 { \ 491 STOP; \ 492 { inAction; } \ 493 goto inHandler; \ 494 } 495 496 #define FailIfNULLNoMessage(inPointer, inAction, inHandler, inMessage) \ 497 if((inPointer) == NULL) \ 498 { \ 499 STOP; \ 500 { inAction; } \ 501 goto inHandler; \ 502 } 503 504 #define FailIfKernelErrorNoMessage(inKernelError, inAction, inHandler, inMessage) \ 505 { \ 506 unsigned int __Err = (inKernelError); \ 507 if(__Err != 0) \ 508 { \ 509 STOP; \ 510 { inAction; } \ 511 goto inHandler; \ 512 } \ 513 } 514 515 #define FailIfErrorNoMessage(inError, inAction, inHandler, inMessage) \ 516 { \ 517 SInt32 __Err = (inError); \ 518 if(__Err != 0) \ 519 { \ 520 STOP; \ 521 { inAction; } \ 522 goto inHandler; \ 523 } \ 524 } 525 526 #if defined(__cplusplus) 527 528 #define Throw(inException) __THROW_STOP; throw (inException) 529 530 #define ThrowIf(inCondition, inException, inMessage) \ 531 if(inCondition) \ 532 { \ 533 Throw(inException); \ 534 } 535 536 #define ThrowIfNULL(inPointer, inException, inMessage) \ 537 if((inPointer) == NULL) \ 538 { \ 539 Throw(inException); \ 540 } 541 542 #define ThrowIfKernelError(inKernelError, inException, inMessage) \ 543 { \ 544 unsigned int __Err = (inKernelError); \ 545 if(__Err != 0) \ 546 { \ 547 Throw(inException); \ 548 } \ 549 } 550 551 #define ThrowIfError(inError, inException, inMessage) \ 552 { \ 553 SInt32 __Err = (inError); \ 554 if(__Err != 0) \ 555 { \ 556 Throw(inException); \ 557 } \ 558 } 559 560 #if TARGET_OS_WIN32 561 #define ThrowIfWinError(inError, inException, inMessage) \ 562 { \ 563 HRESULT __Err = (inError); \ 564 if(FAILED(__Err)) \ 565 { \ 566 Throw(inException); \ 567 } \ 568 } 569 #endif 570 571 #define SubclassResponsibility(inMethodName, inException) \ 572 { \ 573 Throw(inException); \ 574 } 575 576 #endif // defined(__cplusplus) 577 578 #endif // DEBUG || CoreAudio_Debug 579 580 #endif 581