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
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.
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 ***** */
59 * Abort the execution of the program if the expression evaluates to
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) \
77 NS_DebugBreak(NS_DEBUG_ABORT, _msg, #_expr, __FILE__, __LINE__); \
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) \
92 NS_DebugBreak(NS_DEBUG_WARNING, _msg, #_expr, __FILE__, __LINE__); \
97 * Test a precondition for truth. If the expression is not true then
98 * trigger a program failure.
100 #define NS_PRECONDITION(expr, str) \
103 NS_DebugBreak(NS_DEBUG_ASSERTION, str, #expr, __FILE__, __LINE__); \
108 * Test an assertion for truth. If the expression is not true then
109 * trigger a program failure.
111 #define NS_ASSERTION(expr, str) \
114 NS_DebugBreak(NS_DEBUG_ASSERTION, str, #expr, __FILE__, __LINE__); \
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) \
125 NS_DebugBreak(NS_DEBUG_ASSERTION, str, #expr, __FILE__, __LINE__); \
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__)
159 NS_DebugBreak(NS_DEBUG_ABORT, nsnull, nsnull, __FILE__, __LINE__)
165 NS_DebugBreak(NS_DEBUG_BREAK, nsnull, nsnull, __FILE__, __LINE__)
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 /* Avoid name collision if included with other headers defining annotations. */
193 #ifndef HAVE_STATIC_ANNOTATIONS
194 #define HAVE_STATIC_ANNOTATIONS
198 #define STATIC_PRECONDITION(COND) __attribute__((precondition(#COND)))
199 #define STATIC_PRECONDITION_ASSUME(COND) __attribute__((precondition_assume(#COND)))
200 #define STATIC_POSTCONDITION(COND) __attribute__((postcondition(#COND)))
201 #define STATIC_POSTCONDITION_ASSUME(COND) __attribute__((postcondition_assume(#COND)))
202 #define STATIC_INVARIANT(COND) __attribute__((invariant(#COND)))
203 #define STATIC_INVARIANT_ASSUME(COND) __attribute__((invariant_assume(#COND)))
205 /* Used to make identifiers for assert/assume annotations in a function. */
206 #define STATIC_PASTE2(X,Y) X ## Y
207 #define STATIC_PASTE1(X,Y) STATIC_PASTE2(X,Y)
209 #define STATIC_ASSERT(COND) \
211 __attribute__((assert_static(#COND), unused)) \
212 int STATIC_PASTE1(assert_static_, __COUNTER__); \
215 #define STATIC_ASSUME(COND) \
217 __attribute__((assume_static(#COND), unused)) \
218 int STATIC_PASTE1(assume_static_, __COUNTER__); \
221 #define STATIC_ASSERT_RUNTIME(COND) \
223 __attribute__((assert_static_runtime(#COND), unused)) \
224 int STATIC_PASTE1(assert_static_runtime_, __COUNTER__); \
227 #else /* XGILL_PLUGIN */
229 #define STATIC_PRECONDITION(COND) /* nothing */
230 #define STATIC_PRECONDITION_ASSUME(COND) /* nothing */
231 #define STATIC_POSTCONDITION(COND) /* nothing */
232 #define STATIC_POSTCONDITION_ASSUME(COND) /* nothing */
233 #define STATIC_INVARIANT(COND) /* nothing */
234 #define STATIC_INVARIANT_ASSUME(COND) /* nothing */
236 #define STATIC_ASSERT(COND) PR_BEGIN_MACRO /* nothing */ PR_END_MACRO
237 #define STATIC_ASSUME(COND) PR_BEGIN_MACRO /* nothing */ PR_END_MACRO
238 #define STATIC_ASSERT_RUNTIME(COND) PR_BEGIN_MACRO /* nothing */ PR_END_MACRO
240 #endif /* XGILL_PLUGIN */
242 #define STATIC_SKIP_INFERENCE STATIC_INVARIANT(skip_inference())
244 #endif /* HAVE_STATIC_ANNOTATIONS */
248 /* Redefine runtime assertion macros to perform static assertions, for both
249 * debug and release builds. Don't include the original runtime assertions;
250 * this ensures the tool will consider cases where the assertion fails. */
252 #undef NS_PRECONDITION
254 #undef NS_POSTCONDITION
256 #define NS_PRECONDITION(expr, str) STATIC_ASSERT_RUNTIME(expr)
257 #define NS_ASSERTION(expr, str) STATIC_ASSERT_RUNTIME(expr)
258 #define NS_POSTCONDITION(expr, str) STATIC_ASSERT_RUNTIME(expr)
260 #endif /* XGILL_PLUGIN */
262 /******************************************************************************
263 ** Macros for terminating execution when an unrecoverable condition is
264 ** reached. These need to be compiled regardless of the NS_DEBUG flag.
265 ******************************************************************************/
268 * Terminate execution <i>immediately</i>, and if possible on the current
269 * platform, in such a way that execution can't be continued by other
270 * code (e.g., by intercepting a signal).
272 #define NS_RUNTIMEABORT(msg) \
273 NS_DebugBreak(NS_DEBUG_ABORT, msg, nsnull, __FILE__, __LINE__)
276 /* Macros for checking the trueness of an expression passed in within an
277 * interface implementation. These need to be compiled regardless of the */
279 ******************************************************************************/
281 #define NS_ENSURE_TRUE(x, ret) \
283 if (NS_UNLIKELY(!(x))) { \
284 NS_WARNING("NS_ENSURE_TRUE(" #x ") failed"); \
289 #define NS_ENSURE_FALSE(x, ret) \
290 NS_ENSURE_TRUE(!(x), ret)
292 /******************************************************************************
293 ** Macros for checking results
294 ******************************************************************************/
296 #if defined(DEBUG) && !defined(XPCOM_GLUE_AVOID_NSPR)
298 #define NS_ENSURE_SUCCESS_BODY(res, ret) \
299 char *msg = PR_smprintf("NS_ENSURE_SUCCESS(%s, %s) failed with " \
300 "result 0x%X", #res, #ret, __rv); \
302 PR_smprintf_free(msg);
306 #define NS_ENSURE_SUCCESS_BODY(res, ret) \
307 NS_WARNING("NS_ENSURE_SUCCESS(" #res ", " #ret ") failed");
311 #define NS_ENSURE_SUCCESS(res, ret) \
313 nsresult __rv = res; /* Don't evaluate |res| more than once */ \
314 if (NS_FAILED(__rv)) { \
315 NS_ENSURE_SUCCESS_BODY(res, ret) \
320 /******************************************************************************
321 ** Macros for checking state and arguments upon entering interface boundaries
322 ******************************************************************************/
324 #define NS_ENSURE_ARG(arg) \
325 NS_ENSURE_TRUE(arg, NS_ERROR_INVALID_ARG)
327 #define NS_ENSURE_ARG_POINTER(arg) \
328 NS_ENSURE_TRUE(arg, NS_ERROR_INVALID_POINTER)
330 #define NS_ENSURE_ARG_MIN(arg, min) \
331 NS_ENSURE_TRUE((arg) >= min, NS_ERROR_INVALID_ARG)
333 #define NS_ENSURE_ARG_MAX(arg, max) \
334 NS_ENSURE_TRUE((arg) <= max, NS_ERROR_INVALID_ARG)
336 #define NS_ENSURE_ARG_RANGE(arg, min, max) \
337 NS_ENSURE_TRUE(((arg) >= min) && ((arg) <= max), NS_ERROR_INVALID_ARG)
339 #define NS_ENSURE_STATE(state) \
340 NS_ENSURE_TRUE(state, NS_ERROR_UNEXPECTED)
342 #define NS_ENSURE_NO_AGGREGATION(outer) \
343 NS_ENSURE_FALSE(outer, NS_ERROR_NO_AGGREGATION)
345 #define NS_ENSURE_PROPER_AGGREGATION(outer, iid) \
346 NS_ENSURE_FALSE(outer && !iid.Equals(NS_GET_IID(nsISupports)), NS_ERROR_INVALID_ARG)
348 /*****************************************************************************/
351 #define NS_CheckThreadSafe
353 #define NS_CheckThreadSafe(owningThread, msg) \
354 NS_ASSERTION(owningThread == PR_GetCurrentThread(), msg)
357 /* When compiling the XPCOM Glue on Windows, we pretend that it's going to
358 * be linked with a static CRT (-MT) even when it's not. This means that we
359 * cannot link to data exports from the CRT, only function exports. So,
360 * instead of referencing "stderr" directly, use fdopen.
365 printf_stderr(const char *fmt
, ...);
369 #endif /* nsDebug_h___ */