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