1
/* ***** BEGIN LICENSE BLOCK *****
2
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
4
* The contents of this file are subject to the Mozilla Public License Version
5
* 1.1 (the "License"); you may not use this file except in compliance with
6
* the License. You may obtain a copy of the License at
7
* http://www.mozilla.org/MPL/
9
* Software distributed under the License is distributed on an "AS IS" basis,
10
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11
* for the specific language governing rights and limitations under the
14
* The Original Code is the Netscape Portable Runtime (NSPR).
16
* The Initial Developer of the Original Code is
17
* Netscape Communications Corporation.
18
* Portions created by the Initial Developer are Copyright (C) 1998-2000
19
* the Initial Developer. All Rights Reserved.
23
* Alternatively, the contents of this file may be used under the terms of
24
* either the GNU General Public License Version 2 or later (the "GPL"), or
25
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
26
* in which case the provisions of the GPL or the LGPL are applicable instead
27
* of those above. If you wish to allow use of your version of this file only
28
* under the terms of either the GPL or the LGPL, and not to allow others to
29
* use your version of this file under the terms of the MPL, indicate your
30
* decision by deleting the provisions above and replace them with the notice
31
* and other provisions required by the GPL or the LGPL. If you do not delete
32
* the provisions above, a recipient may use your version of this file under
33
* the terms of any one of the MPL, the GPL or the LGPL.
35
* ***** END LICENSE BLOCK ***** */
37
/*********************************************************************
43
A collection of routines and macros to handle assertions and
47
Copyright � Apple Computer, Inc. 1989-1991
69
Nov 12 95 BKJ Moved to MetroWerks environment & the NSPR
72
To keep code size down, use these routines and macros with the C
73
compiler option -b2 or -b3. This will eliminate duplicate strings
76
*********************************************************************/
78
#ifndef __MACERRORHANDLING__
79
#define __MACERRORHANDLING__
81
/*********************************************************************
85
*********************************************************************/
90
/*********************************************************************
94
*********************************************************************/
97
These defines are used to control the amount of information
98
displayed when an assertion fails. DEBUGOFF and WARN will run
99
silently. MIN will simply break into the debugger. ON will break
100
and display the assertion that failed and the exception (for
101
require statements). FULL will also display the source file name
102
and line number. SYM does a SysBreak and is usefull when using a
103
symbolic debugger like SourceBug or SADE. They should be set into
104
DEBUGLEVEL. The default LEVEL is OFF.
115
#define DEBUGLEVEL DEBUGOFF
119
resumeLabel is used to control the insertion of labels for use with
120
the resume macro. If you do not use the resume macro and you wish
121
to have multible exceptions per label then you can add the
122
following define to you source code.
125
#define resumeLabel(exception) // Multiple exceptions per label
126
// #define resumeLabel(exception) resume_ ## exception: // Single exception per label
130
traceon and debugon are used to test for options
133
#define traceon ((DEBUGLEVEL > DEBUGWARN) && defined(TRACEON))
134
#define debugon (DEBUGLEVEL > DEBUGWARN)
137
Add some macros for DEBUGMIN and DEBUGSYM to keep the size down.
140
#define __DEBUGSMALL ((DEBUGLEVEL == DEBUGMIN) || \
141
(DEBUGLEVEL == DEBUGSYM))
143
#if DEBUGLEVEL == DEBUGMIN
144
#define __DebuggerBreak Debugger()
145
#elif DEBUGLEVEL == DEBUGSYM
146
#define __DebuggerBreak SysBreak()
151
/*********************************************************************
157
If debugging is on then check will test assertion and if it fails
158
break into the debugger. Otherwise check does nothing.
160
*********************************************************************/
164
#define check(assertion) \
167
else __DebuggerBreak; \
170
#elif DEBUGLEVEL == DEBUGON
172
#define check(assertion) \
176
dprintf(notrace, "Assertion \"%s\" Failed", #assertion); \
180
#elif DEBUGLEVEL == DEBUGFULL
182
#define check(assertion) \
186
dprintf(notrace, "Assertion \"%s\" Failed\n" \
189
#assertion, __FILE__, __LINE__); \
195
#define check(assertion)
200
/*********************************************************************
206
If debugging is on then ncheck will test !assertion and if it fails
207
break into the debugger. Otherwise ncheck does nothing.
209
*********************************************************************/
213
#define ncheck(assertion) \
215
if (assertion) __DebuggerBreak; \
218
#elif DEBUGLEVEL == DEBUGON
220
#define ncheck(assertion) \
222
void* __privateAssertion = (void*)(assertion); \
224
if (__privateAssertion) { \
225
dprintf(notrace, "Assertion \"!(%s [= %#08X])\" Failed", \
226
#assertion, __privateAssertion); \
230
#elif DEBUGLEVEL == DEBUGFULL
232
#define ncheck(assertion) \
234
void* __privateAssertion = (void*)(assertion); \
236
if (__privateAssertion) { \
237
dprintf(notrace, "Assertion \"!(%s [= %#08X])\" Failed\n" \
240
#assertion, __privateAssertion, __FILE__, __LINE__); \
246
#define ncheck(assertion)
251
/*********************************************************************
254
check_action(assertion, action)
257
If debugging is on then check_action will test assertion and if it
258
fails break into the debugger then execute action. Otherwise
259
check_action does nothing.
261
*********************************************************************/
265
#define check_action(assertion, action) \
273
#elif DEBUGLEVEL == DEBUGON
275
#define check_action(assertion, action) \
279
dprintf(notrace, "Assertion \"%s\" Failed", #assertion); \
284
#elif DEBUGLEVEL == DEBUGFULL
286
#define check_action(assertion, action) \
290
dprintf(notrace, "Assertion \"%s\" Failed\n" \
293
#assertion, __FILE__, __LINE__); \
300
#define check_action(assertion, action)
305
/**************************************************************************************
308
ncheck_action(assertion, action)
311
If debugging is on then ncheck_action will test !assertion and if
312
it fails break into the debugger then execute action. Otherwise
313
ncheck_action does nothing.
315
*********************************************************************/
319
#define ncheck_action(assertion, action) \
327
#elif DEBUGLEVEL == DEBUGON
329
#define ncheck_action(assertion, action) \
331
void* __privateAssertion = (void*)(assertion); \
333
if (__privateAssertion) { \
334
dprintf(notrace, "Assertion \"!(%s [= %#08X])\" Failed", \
335
#assertion, __privateAssertion); \
340
#elif DEBUGLEVEL == DEBUGFULL
342
#define ncheck_action(assertion, action) \
344
void* __privateAssertion = (void*)(assertion); \
346
if (__privateAssertion) { \
347
dprintf(notrace, "Assertion \"!(%s [= %#08X])\" Failed\n" \
350
#assertion, __privateAssertion, __FILE__, __LINE__); \
357
#define ncheck_action(assertion, action)
362
/*********************************************************************
365
require(assertion, exception)
368
require will test assertion and if it fails:
369
break into the debugger if debugging is on.
372
*********************************************************************/
376
#define require(assertion, exception) \
382
resumeLabel(exception); \
386
#elif DEBUGLEVEL == DEBUGON
388
#define require(assertion, exception) \
392
dprintf(notrace, "Assertion \"%s\" Failed\n" \
393
"Exception \"%s\" Raised", \
394
#assertion, #exception); \
396
resumeLabel(exception); \
400
#elif DEBUGLEVEL == DEBUGFULL
402
#define require(assertion, exception) \
406
dprintf(notrace, "Assertion \"%s\" Failed\n" \
407
"Exception \"%s\" Raised\n" \
410
#assertion, #exception, __FILE__, __LINE__); \
412
resumeLabel(exception); \
418
#define require(assertion, exception) \
423
resumeLabel(exception); \
430
/*********************************************************************
433
nrequire(assertion, exception)
436
nrequire will test !assertion and if it fails:
437
break into the debugger if debugging is on.
440
*********************************************************************/
444
#define nrequire(assertion, exception) \
449
resumeLabel(exception); \
453
#elif DEBUGLEVEL == DEBUGON
455
#define nrequire(assertion, exception) \
457
void* __privateAssertion = (void*)(assertion); \
459
if (__privateAssertion) { \
460
dprintf(notrace, "Assertion \"!(%s [= %#08X])\" Failed\n" \
461
"Exception \"%s\" Raised", \
462
#assertion, __privateAssertion, #exception); \
464
resumeLabel(exception); \
468
#elif DEBUGLEVEL == DEBUGFULL
470
#define nrequire(assertion, exception) \
472
void* __privateAssertion = (void*)(assertion); \
474
if (__privateAssertion) { \
475
dprintf(notrace, "Assertion \"!(%s [= %#08X])\" Failed\n" \
476
"Exception \"%s\" Raised\n" \
479
#assertion, __privateAssertion, #exception, __FILE__, \
482
resumeLabel(exception); \
488
#define nrequire(assertion, exception) \
492
resumeLabel(exception); \
499
/*********************************************************************
502
require_action(assertion, exception, action)
505
require_action will test assertion and if it fails:
506
break into the debugger if debugging is on.
510
*********************************************************************/
514
#define require_action(assertion, exception, action) \
521
resumeLabel(exception); \
525
#elif DEBUGLEVEL == DEBUGON
527
#define require_action(assertion, exception, action) \
531
dprintf(notrace, "Assertion \"%s\" Failed\n" \
532
"Exception \"%s\" Raised", \
533
#assertion, #exception); \
536
resumeLabel(exception); \
540
#elif DEBUGLEVEL == DEBUGFULL
542
#define require_action(assertion, exception, action) \
546
dprintf(notrace, "Assertion \"%s\" Failed\n" \
547
"Exception \"%s\" Raised\n" \
550
#assertion, #exception, __FILE__, __LINE__); \
553
resumeLabel(exception); \
559
#define require_action(assertion, exception, action) \
565
resumeLabel(exception); \
572
/*********************************************************************
575
nrequire_action(assertion, exception, action)
578
nrequire_action will test !assertion and if it fails:
579
break into the debugger if debugging is on.
583
*********************************************************************/
587
#define nrequire_action(assertion, exception, action) \
593
resumeLabel(exception); \
597
#elif DEBUGLEVEL == DEBUGON
599
#define nrequire_action(assertion, exception, action) \
601
void* __privateAssertion = (void*)(assertion); \
603
if (__privateAssertion) { \
604
dprintf(notrace, "Assertion \"!(%s [= %#08X])\" Failed\n" \
605
"Exception \"%s\" Raised", \
606
#assertion, __privateAssertion, #exception); \
609
resumeLabel(exception); \
613
#elif DEBUGLEVEL == DEBUGFULL
615
#define nrequire_action(assertion, exception, action) \
617
void* __privateAssertion = (void*)(assertion); \
619
if (__privateAssertion) { \
620
dprintf(notrace, "Assertion \"!(%s [= %#08X])\" Failed\n" \
621
"Exception \"%s\" Raised\n" \
624
#assertion, __privateAssertion, #exception, __FILE__, \
628
resumeLabel(exception); \
634
#define nrequire_action(assertion, exception, action) \
639
resumeLabel(exception); \
646
/*********************************************************************
652
resume will resume execution after the n/require/_action statement
653
specified by exception. Resume lables must be on (the default) in
654
order to use resume. If an action form of require was used then the
655
action will not be re-executed.
657
*********************************************************************/
660
#define resume(exception) \
662
goto resume_ ## exception; \
667
/********************************************************************/