blob: e1374ddc0c4ccf528d62667665a544dabbd6ec5d [file] [log] [blame]
/* Copyright (C) 2009 The Android Open Source Project
**
** This software is licensed under the terms of the GNU General Public
** License version 2, as published by the Free Software Foundation, and
** may be copied, distributed, and modified under those terms.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
*/
#pragma once
#include <stdarg.h>
#include "android/utils/compiler.h"
ANDROID_BEGIN_HEADER
/* These are always defined, so you can write your own macros that
* call them, independently of the value of ACONFIG_USE_ASSERT
*/
/* Used internally by the macros to register the current source location */
void _android_assert_loc(const char* fileName,
long fileLineno,
const char* functionName);
/* Call this after _android_assert_loc() to dump an assertion failed message
* just before panicking, i.e. abort the current program
*/
void __attribute__((noreturn)) android_assert_fail(const char* messageFmt, ...);
/* See _android_assert_loc() */
#define _ANDROID_ASSERT_LOC() \
_android_assert_loc(__FILE__,__LINE__,__FUNCTION__)
/* Report an assertion failure then panic. Arguments are formatted string */
#define _ANDROID_ASSERT_FAIL(...) \
android_assert_fail(__VA_ARGS__)
/* Report an unreachable code */
#define _ANDROID_ASSERT_UNREACHED(...) \
do { \
_ANDROID_ASSERT_LOC(); \
android_assert_fail(__VA_ARGS__); \
} while (0);
/* Check that 'cond' is true, and report an assertion failure otherwise */
#define _ANDROID_ASSERT(cond,...) \
do { \
if (!(cond)) { \
_ANDROID_ASSERT_LOC(); \
android_assert_fail(__VA_ARGS__); \
} \
} while (0)
/* Check that 'cond' is boolean true (i.e. not 0), and report an assertion
* failure otherwise. */
#define _ANDROID_ASSERT_BOOL(cond_,expected_) \
do { \
int cond_result_ = !!(cond_); \
int cond_expected_ = !!(expected_); \
if (cond_result_ != cond_expected_) { \
_ANDROID_ASSERT_LOC(); \
android_assert_fail("%s is %s instead of %s\n",\
#cond_, \
cond_result_ ? "TRUE" : "FALSE", \
cond_expected_ ? "TRUE" : "FALSE" ); \
} \
} while (0)
/* Assert that a given expression is of a given integer value */
#define _ANDROID_ASSERT_INT(cond_,expected_) \
do { \
int cond_result_ = (cond_); \
int cond_expected_ = (expected_); \
if (cond_result_ != cond_expected_) { \
_ANDROID_ASSERT_LOC(); \
android_assert_fail("%s is %d instead of %d\n", \
#cond_ , cond_result_, cond_expected_); \
} \
} while (0)
#define _ANDROID_ASSERT_INT_OP(cond_,expected_,op_) \
do { \
int cond_result_ = (cond_); \
int cond_expected_ = (expected_); \
if (!(cond_result_ _op cond_expected_)) { \
_ANDROID_ASSERT_LOC(); \
android_assert_fail("%s is %d and should be %s %d\n", \
#cond_ , cond_result_, #op_, cond_expected_); \
} \
} while (0)
# define _ANDROID_ASSERT_PTR(cond_,expected_) \
do { \
void* cond_result_ = (cond_); \
void* cond_expected_ = (void*)(expected_); \
if (cond_result_ != cond_expected_) { \
_ANDROID_ASSERT_LOC(); \
android_assert_fail("%s is %p instead of %p\n", \
#cond_ , cond_result_, cond_expected_); \
} \
} while (0)
# define _ANDROID_NEVER_NULL(ptr_) \
do { \
void* never_ptr_ = (ptr_); \
if (never_ptr_ == NULL) { \
_ANDROID_ASSERT_LOC(); \
android_assert_fail("%s is NULL\n", #ptr_); \
} \
} while (0)
#ifdef ACONFIG_USE_ASSERT
# define AASSERT_LOC() _ANDROID_ASSERT_LOC()
# define AASSERT_FAIL(...) _ANDROID_ASSERT_FAIL(__VA_ARGS__)
/* Assert we never reach some code point */
# define AASSERT_UNREACHED(...) _ANDROID_ASSERT_UNREACHED(__VA_ARGS__)
/* Generic assertion, must be followed by formatted string parameters */
# define AASSERT(cond,...) _ANDROID_ASSERT(cond,__VA_ARGS__)
/* Assert a condition evaluates to a given boolean */
# define AASSERT_BOOL(cond_,expected_) _ANDROID_ASSERT_BOOL(cond_,expected_)
/* Assert a condition evaluates to a given integer */
# define AASSERT_INT(cond_,expected_) _ANDROID_ASSERT_INT(cond_,expected_)
# define AASSERT_INT_LT(cond_,expected_) _ANDROID_ASSERT_INT_OP(cond_,expected_,< )
# define AASSERT_INT_LTE(cond_,expected_) _ANDROID_ASSERT_INT_OP(cond_,expected_,<= )
# define AASSERT_INT_GT(cond_,expected_) _ANDROID_ASSERT_INT_OP(cond_,expected_,> )
# define AASSERT_INT_GTE(cond_,expected_) _ANDROID_ASSERT_INT_OP(cond_,expected_,>= )
# define AASSERT_INT_EQ(cond_,expected_) _ANDROID_ASSERT_INT_OP(cond_,expected_,==)
# define AASSERT_INT_NEQ(cond_,expected_) _ANDROID_ASSERT_INT_OP(cond_,expected_,!=)
# define AASSERT_PTR(cond_,expected_) _ANDROID_ASSERT_PTR(cond_,expected_)
# define ANEVER_NULL(ptr_) _ANDROID_NEVER_NULL(ptr_)
#else /* !ACONFIG_USE_ASSERT */
# define AASSERT_LOC() ((void)0)
# define AASSERT_FAIL(...) ((void)0)
# define AASSERT_UNREACHED(...) ((void)0)
/* for side-effects */
# define AASSERT(cond,...) ((void)(cond), (void)0)
# define AASSERT_BOOL(cond,val) ((void)(cond), (void)0)
# define AASSERT_INT(cond,val) AASSERT_BOOL(cond,val)
# define AASSERT_PTR(cond,val) AASSERT_BOOL(cond,val)
# define ANEVER_NULL(ptr) ((void)(ptr), (void)0)
#endif /* !ACONFIG_USE_ASSERT */
# define AASSERT_TRUE(cond_) AASSERT_BOOL(cond_,1)
# define AASSERT_FALSE(cond_) AASSERT_BOOL(cond_,0)
/* this can be used to redirect the assertion log to something
* other than stderr. Note that android_assert_fail also calls
* android_vpanic.
*/
typedef void (*AAssertLogFunc)( const char* fmt, va_list args );
void android_assert_registerLog( AAssertLogFunc logger );
// Compile-time assertion. If |cond| is false at compile time, an
// error message will be emitted by the compiler.
#ifdef __cplusplus
#define AASSERT_STATIC(cond) static_assert(cond)
#else // !__cpluplus
#define AASSERT_STATIC(cond) \
typedef char _AASSERT_CONCAT(__android_assertion_failed_,__LINE__) \
[2*!!(cond) - 1];
#define _AASSERT_CONCAT(x, y) _AASSERT_CONCAT_(x, y)
#define _AASSERT_CONCAT_(x, y) x ## y
#endif // !__cplusplus
ANDROID_END_HEADER