Bug 575870 - Enable the firefox button on xp themed, classic, and aero basic. r=dao...
[mozilla-central.git] / xpcom / glue / nsDebug.h
blob3eeddb669d9009a970292b506b91be0330040663
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
13 * License.
15 * The Original Code is mozilla.org code.
17 * The Initial Developer of the Original Code is
18 * Netscape Communications Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 1998
20 * the Initial Developer. All Rights Reserved.
22 * Contributor(s):
24 * Alternatively, the contents of this file may be used under the terms of
25 * either of the GNU General Public License Version 2 or later (the "GPL"),
26 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
36 * ***** END LICENSE BLOCK ***** */
38 #ifndef nsDebug_h___
39 #define nsDebug_h___
41 #ifndef nscore_h___
42 #include "nscore.h"
43 #endif
45 #ifndef nsError_h__
46 #include "nsError.h"
47 #endif
49 #include "nsXPCOM.h"
51 #ifdef DEBUG
52 #define NS_DEBUG
53 #include "prprf.h"
54 #endif
56 #ifdef DEBUG
58 /**
59 * Abort the execution of the program if the expression evaluates to
60 * false.
62 * There is no status value returned from the macro.
64 * Note that the non-debug version of this macro does <b>not</b>
65 * evaluate the expression argument. Hence side effect statements
66 * as arguments to the macro will yield improper execution in a
67 * non-debug build. For example:
69 * NS_ABORT_IF_FALSE(0 == foo++, "yikes foo should be zero");
71 * Note also that the non-debug version of this macro does <b>not</b>
72 * evaluate the message argument.
74 #define NS_ABORT_IF_FALSE(_expr, _msg) \
75 PR_BEGIN_MACRO \
76 if (!(_expr)) { \
77 NS_DebugBreak(NS_DEBUG_ABORT, _msg, #_expr, __FILE__, __LINE__); \
78 } \
79 PR_END_MACRO
81 /**
82 * Warn if a given condition is false.
84 * Program execution continues past the usage of this macro.
86 * Note also that the non-debug version of this macro does <b>not</b>
87 * evaluate the message argument.
89 #define NS_WARN_IF_FALSE(_expr,_msg) \
90 PR_BEGIN_MACRO \
91 if (!(_expr)) { \
92 NS_DebugBreak(NS_DEBUG_WARNING, _msg, #_expr, __FILE__, __LINE__); \
93 } \
94 PR_END_MACRO
96 /**
97 * Test a precondition for truth. If the expression is not true then
98 * trigger a program failure.
100 #define NS_PRECONDITION(expr, str) \
101 PR_BEGIN_MACRO \
102 if (!(expr)) { \
103 NS_DebugBreak(NS_DEBUG_ASSERTION, str, #expr, __FILE__, __LINE__); \
105 PR_END_MACRO
108 * Test an assertion for truth. If the expression is not true then
109 * trigger a program failure.
111 #define NS_ASSERTION(expr, str) \
112 PR_BEGIN_MACRO \
113 if (!(expr)) { \
114 NS_DebugBreak(NS_DEBUG_ASSERTION, str, #expr, __FILE__, __LINE__); \
116 PR_END_MACRO
119 * Test a post-condition for truth. If the expression is not true then
120 * trigger a program failure.
122 #define NS_POSTCONDITION(expr, str) \
123 PR_BEGIN_MACRO \
124 if (!(expr)) { \
125 NS_DebugBreak(NS_DEBUG_ASSERTION, str, #expr, __FILE__, __LINE__); \
127 PR_END_MACRO
130 * This macros triggers a program failure if executed. It indicates that
131 * an attempt was made to execute some unimplemented functionality.
133 #define NS_NOTYETIMPLEMENTED(str) \
134 NS_DebugBreak(NS_DEBUG_ASSERTION, str, "NotYetImplemented", __FILE__, __LINE__)
137 * This macros triggers a program failure if executed. It indicates that
138 * an attempt was made to execute some unimplemented functionality.
140 #define NS_NOTREACHED(str) \
141 NS_DebugBreak(NS_DEBUG_ASSERTION, str, "Not Reached", __FILE__, __LINE__)
144 * Log an error message.
146 #define NS_ERROR(str) \
147 NS_DebugBreak(NS_DEBUG_ASSERTION, str, "Error", __FILE__, __LINE__)
150 * Log a warning message.
152 #define NS_WARNING(str) \
153 NS_DebugBreak(NS_DEBUG_WARNING, str, nsnull, __FILE__, __LINE__)
156 * Trigger an abort
158 #define NS_ABORT() \
159 NS_DebugBreak(NS_DEBUG_ABORT, nsnull, nsnull, __FILE__, __LINE__)
162 * Cause a break
164 #define NS_BREAK() \
165 NS_DebugBreak(NS_DEBUG_BREAK, nsnull, nsnull, __FILE__, __LINE__)
167 #else /* NS_DEBUG */
170 * The non-debug version of these macros do not evaluate the
171 * expression or the message arguments to the macro.
173 #define NS_ABORT_IF_FALSE(_expr, _msg) PR_BEGIN_MACRO /* nothing */ PR_END_MACRO
174 #define NS_WARN_IF_FALSE(_expr, _msg) PR_BEGIN_MACRO /* nothing */ PR_END_MACRO
175 #define NS_PRECONDITION(expr, str) PR_BEGIN_MACRO /* nothing */ PR_END_MACRO
176 #define NS_ASSERTION(expr, str) PR_BEGIN_MACRO /* nothing */ PR_END_MACRO
177 #define NS_POSTCONDITION(expr, str) PR_BEGIN_MACRO /* nothing */ PR_END_MACRO
178 #define NS_NOTYETIMPLEMENTED(str) PR_BEGIN_MACRO /* nothing */ PR_END_MACRO
179 #define NS_NOTREACHED(str) PR_BEGIN_MACRO /* nothing */ PR_END_MACRO
180 #define NS_ERROR(str) PR_BEGIN_MACRO /* nothing */ PR_END_MACRO
181 #define NS_WARNING(str) PR_BEGIN_MACRO /* nothing */ PR_END_MACRO
182 #define NS_ABORT() PR_BEGIN_MACRO /* nothing */ PR_END_MACRO
183 #define NS_BREAK() PR_BEGIN_MACRO /* nothing */ PR_END_MACRO
185 #endif /* ! NS_DEBUG */
187 /******************************************************************************
188 ** Macros for static assertions. These are used by the sixgill tool.
189 ** When the tool is not running these macros are no-ops.
190 ******************************************************************************/
192 #ifdef XGILL_PLUGIN
194 #define STATIC_PRECONDITION(COND) __attribute__((precondition(#COND)))
195 #define STATIC_PRECONDITION_ASSUME(COND) __attribute__((precondition_assume(#COND)))
196 #define STATIC_POSTCONDITION(COND) __attribute__((postcondition(#COND)))
197 #define STATIC_POSTCONDITION_ASSUME(COND) __attribute__((postcondition_assume(#COND)))
198 #define STATIC_INVARIANT(COND) __attribute__((invariant(#COND)))
199 #define STATIC_INVARIANT_ASSUME(COND) __attribute__((invariant_assume(#COND)))
201 /* Used to make identifiers for assert/assume annotations in a function. */
202 #define STATIC_PASTE2(X,Y) X ## Y
203 #define STATIC_PASTE1(X,Y) STATIC_PASTE2(X,Y)
205 #define STATIC_ASSERT(COND) \
206 PR_BEGIN_MACRO \
207 __attribute__((assert(#COND), unused)) \
208 int STATIC_PASTE1(static_assert_, __COUNTER__); \
209 PR_END_MACRO
211 #define STATIC_ASSUME(COND) \
212 PR_BEGIN_MACRO \
213 __attribute__((assume(#COND), unused)) \
214 int STATIC_PASTE1(static_assume_, __COUNTER__); \
215 PR_END_MACRO
217 #define STATIC_ASSERT_RUNTIME(COND) \
218 PR_BEGIN_MACRO \
219 __attribute__((assert_runtime(#COND), unused)) \
220 int STATIC_PASTE1(static_assert_runtime_, __COUNTER__); \
221 PR_END_MACRO
223 /* Redefine runtime assertion macros to perform static assertions, for both
224 * debug and release builds. Don't include the original runtime assertions;
225 * this ensures the tool will consider cases where the assertion fails. */
227 #undef NS_PRECONDITION
228 #undef NS_ASSERTION
229 #undef NS_POSTCONDITION
231 #define NS_PRECONDITION(expr, str) STATIC_ASSERT_RUNTIME(expr)
232 #define NS_ASSERTION(expr, str) STATIC_ASSERT_RUNTIME(expr)
233 #define NS_POSTCONDITION(expr, str) STATIC_ASSERT_RUNTIME(expr)
235 #else /* XGILL_PLUGIN */
237 #define STATIC_PRECONDITION(COND) /* nothing */
238 #define STATIC_PRECONDITION_ASSUME(COND) /* nothing */
239 #define STATIC_POSTCONDITION(COND) /* nothing */
240 #define STATIC_POSTCONDITION_ASSUME(COND) /* nothing */
241 #define STATIC_INVARIANT(COND) /* nothing */
242 #define STATIC_INVARIANT_ASSUME(COND) /* nothing */
244 #define STATIC_ASSERT(COND) PR_BEGIN_MACRO /* nothing */ PR_END_MACRO
245 #define STATIC_ASSUME(COND) PR_BEGIN_MACRO /* nothing */ PR_END_MACRO
246 #define STATIC_ASSERT_RUNTIME(COND) PR_BEGIN_MACRO /* nothing */ PR_END_MACRO
248 #endif /* XGILL_PLUGIN */
250 /******************************************************************************
251 ** Macros for terminating execution when an unrecoverable condition is
252 ** reached. These need to be compiled regardless of the NS_DEBUG flag.
253 ******************************************************************************/
256 * Terminate execution <i>immediately</i>, and if possible on the current
257 * platform, in such a way that execution can't be continued by other
258 * code (e.g., by intercepting a signal).
260 #define NS_RUNTIMEABORT(msg) \
261 NS_DebugBreak(NS_DEBUG_ABORT, msg, nsnull, __FILE__, __LINE__)
264 /* Macros for checking the trueness of an expression passed in within an
265 * interface implementation. These need to be compiled regardless of the */
266 /* NS_DEBUG flag
267 ******************************************************************************/
269 #define NS_ENSURE_TRUE(x, ret) \
270 PR_BEGIN_MACRO \
271 if (NS_UNLIKELY(!(x))) { \
272 NS_WARNING("NS_ENSURE_TRUE(" #x ") failed"); \
273 return ret; \
275 PR_END_MACRO
277 #define NS_ENSURE_FALSE(x, ret) \
278 NS_ENSURE_TRUE(!(x), ret)
280 /******************************************************************************
281 ** Macros for checking results
282 ******************************************************************************/
284 #if defined(DEBUG) && !defined(XPCOM_GLUE_AVOID_NSPR)
286 #define NS_ENSURE_SUCCESS_BODY(res, ret) \
287 char *msg = PR_smprintf("NS_ENSURE_SUCCESS(%s, %s) failed with " \
288 "result 0x%X", #res, #ret, __rv); \
289 NS_WARNING(msg); \
290 PR_smprintf_free(msg);
292 #else
294 #define NS_ENSURE_SUCCESS_BODY(res, ret) \
295 NS_WARNING("NS_ENSURE_SUCCESS(" #res ", " #ret ") failed");
297 #endif
299 #define NS_ENSURE_SUCCESS(res, ret) \
300 PR_BEGIN_MACRO \
301 nsresult __rv = res; /* Don't evaluate |res| more than once */ \
302 if (NS_FAILED(__rv)) { \
303 NS_ENSURE_SUCCESS_BODY(res, ret) \
304 return ret; \
306 PR_END_MACRO
308 /******************************************************************************
309 ** Macros for checking state and arguments upon entering interface boundaries
310 ******************************************************************************/
312 #define NS_ENSURE_ARG(arg) \
313 NS_ENSURE_TRUE(arg, NS_ERROR_INVALID_ARG)
315 #define NS_ENSURE_ARG_POINTER(arg) \
316 NS_ENSURE_TRUE(arg, NS_ERROR_INVALID_POINTER)
318 #define NS_ENSURE_ARG_MIN(arg, min) \
319 NS_ENSURE_TRUE((arg) >= min, NS_ERROR_INVALID_ARG)
321 #define NS_ENSURE_ARG_MAX(arg, max) \
322 NS_ENSURE_TRUE((arg) <= max, NS_ERROR_INVALID_ARG)
324 #define NS_ENSURE_ARG_RANGE(arg, min, max) \
325 NS_ENSURE_TRUE(((arg) >= min) && ((arg) <= max), NS_ERROR_INVALID_ARG)
327 #define NS_ENSURE_STATE(state) \
328 NS_ENSURE_TRUE(state, NS_ERROR_UNEXPECTED)
330 #define NS_ENSURE_NO_AGGREGATION(outer) \
331 NS_ENSURE_FALSE(outer, NS_ERROR_NO_AGGREGATION)
333 #define NS_ENSURE_PROPER_AGGREGATION(outer, iid) \
334 NS_ENSURE_FALSE(outer && !iid.Equals(NS_GET_IID(nsISupports)), NS_ERROR_INVALID_ARG)
336 /*****************************************************************************/
338 #ifdef XPCOM_GLUE
339 #define NS_CheckThreadSafe
340 #else
341 #define NS_CheckThreadSafe(owningThread, msg) \
342 NS_ASSERTION(owningThread == PR_GetCurrentThread(), msg)
343 #endif
345 /* When compiling the XPCOM Glue on Windows, we pretend that it's going to
346 * be linked with a static CRT (-MT) even when it's not. This means that we
347 * cannot link to data exports from the CRT, only function exports. So,
348 * instead of referencing "stderr" directly, use fdopen.
350 PR_BEGIN_EXTERN_C
352 NS_COM_GLUE void
353 printf_stderr(const char *fmt, ...);
355 PR_END_EXTERN_C
357 #endif /* nsDebug_h___ */