14c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner/* Copyright (C) 2009 The Android Open Source Project
24c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner**
34c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner** This software is licensed under the terms of the GNU General Public
44c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner** License version 2, as published by the Free Software Foundation, and
54c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner** may be copied, distributed, and modified under those terms.
64c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner**
74c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner** This program is distributed in the hope that it will be useful,
84c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner** but WITHOUT ANY WARRANTY; without even the implied warranty of
94c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
104c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner** GNU General Public License for more details.
114c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner*/
124c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner#ifndef ANDROID_UTILS_ASSERT_H
134c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner#define ANDROID_UTILS_ASSERT_H
144c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner
154c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner#include <stdarg.h>
164c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner
172086c639648ccecc9081705a279249ce939d818bDavid 'Digit' Turner/* These are always defined, so you can write your own macros that
182086c639648ccecc9081705a279249ce939d818bDavid 'Digit' Turner * call them, independently of the value of ACONFIG_USE_ASSERT
192086c639648ccecc9081705a279249ce939d818bDavid 'Digit' Turner */
204c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner
212086c639648ccecc9081705a279249ce939d818bDavid 'Digit' Turner/* Used internally by the macros to register the current source location */
224c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turnervoid  _android_assert_loc(const char*  fileName,
234c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner                          long         fileLineno,
244c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner                          const char*  functionName);
254c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner
262086c639648ccecc9081705a279249ce939d818bDavid 'Digit' Turner/* Call this after _android_assert_loc() to dump an assertion failed message
272086c639648ccecc9081705a279249ce939d818bDavid 'Digit' Turner * just before panicking, i.e. abort the current program
282086c639648ccecc9081705a279249ce939d818bDavid 'Digit' Turner */
292086c639648ccecc9081705a279249ce939d818bDavid 'Digit' Turnervoid __attribute__((noreturn)) android_assert_fail(const char*  messageFmt, ...);
302086c639648ccecc9081705a279249ce939d818bDavid 'Digit' Turner
312086c639648ccecc9081705a279249ce939d818bDavid 'Digit' Turner/* See _android_assert_loc() */
322086c639648ccecc9081705a279249ce939d818bDavid 'Digit' Turner#define  _ANDROID_ASSERT_LOC()  \
334c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner    _android_assert_loc(__FILE__,__LINE__,__FUNCTION__)
344c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner
352086c639648ccecc9081705a279249ce939d818bDavid 'Digit' Turner/* Report an assertion failure then panic. Arguments are formatted string */
362086c639648ccecc9081705a279249ce939d818bDavid 'Digit' Turner#define  _ANDROID_ASSERT_FAIL(...) \
374c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner    android_assert_fail(__VA_ARGS__)
384c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner
392086c639648ccecc9081705a279249ce939d818bDavid 'Digit' Turner/* Report an unreachable code */
402086c639648ccecc9081705a279249ce939d818bDavid 'Digit' Turner#define  _ANDROID_ASSERT_UNREACHED(...)   \
414c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner    do { \
422086c639648ccecc9081705a279249ce939d818bDavid 'Digit' Turner        _ANDROID_ASSERT_LOC(); \
432086c639648ccecc9081705a279249ce939d818bDavid 'Digit' Turner        android_assert_fail(__VA_ARGS__); \
444c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner    } while (0);
454c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner
462086c639648ccecc9081705a279249ce939d818bDavid 'Digit' Turner/* Check that 'cond' is true, and report an assertion failure otherwise */
472086c639648ccecc9081705a279249ce939d818bDavid 'Digit' Turner#define  _ANDROID_ASSERT(cond,...)  \
484c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner    do { \
494c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner        if (!(cond)) { \
502086c639648ccecc9081705a279249ce939d818bDavid 'Digit' Turner            _ANDROID_ASSERT_LOC(); \
514c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner            android_assert_fail(__VA_ARGS__); \
524c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner        } \
534c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner    } while (0)
544c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner
552086c639648ccecc9081705a279249ce939d818bDavid 'Digit' Turner/* Check that 'cond' is boolean true (i.e. not 0), and report an assertion
562086c639648ccecc9081705a279249ce939d818bDavid 'Digit' Turner * failure otherwise. */
572086c639648ccecc9081705a279249ce939d818bDavid 'Digit' Turner#define  _ANDROID_ASSERT_BOOL(cond_,expected_)    \
584c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner    do { \
594c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner        int  cond_result_   = !!(cond_); \
604c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner        int  cond_expected_ = !!(expected_); \
614c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner        if (cond_result_ != cond_expected_) { \
622086c639648ccecc9081705a279249ce939d818bDavid 'Digit' Turner            _ANDROID_ASSERT_LOC(); \
634c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner            android_assert_fail("%s is %s instead of %s\n",\
644c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner               #cond_, \
654c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner               cond_result_ ? "TRUE" : "FALSE", \
664c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner               cond_expected_ ? "TRUE" : "FALSE" ); \
674c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner        } \
684c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner    } while (0)
694c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner
702086c639648ccecc9081705a279249ce939d818bDavid 'Digit' Turner/* Assert that a given expression is of a given integer value */
712086c639648ccecc9081705a279249ce939d818bDavid 'Digit' Turner#define  _ANDROID_ASSERT_INT(cond_,expected_)  \
724c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner    do { \
734c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner        int  cond_result_ = (cond_); \
744c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner        int  cond_expected_ = (expected_); \
754c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner        if (cond_result_ != cond_expected_) { \
762086c639648ccecc9081705a279249ce939d818bDavid 'Digit' Turner            _ANDROID_ASSERT_LOC(); \
774c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner            android_assert_fail("%s is %d instead of %d\n", \
784c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner                                #cond_ , cond_result_, cond_expected_); \
794c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner        } \
804c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner    } while (0)
814c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner
822086c639648ccecc9081705a279249ce939d818bDavid 'Digit' Turner#define  _ANDROID_ASSERT_INT_OP(cond_,expected_,op_) \
832086c639648ccecc9081705a279249ce939d818bDavid 'Digit' Turner    do { \
842086c639648ccecc9081705a279249ce939d818bDavid 'Digit' Turner        int  cond_result_ = (cond_); \
852086c639648ccecc9081705a279249ce939d818bDavid 'Digit' Turner        int  cond_expected_ = (expected_); \
862086c639648ccecc9081705a279249ce939d818bDavid 'Digit' Turner        if (!(cond_result_ _op cond_expected_)) { \
872086c639648ccecc9081705a279249ce939d818bDavid 'Digit' Turner            _ANDROID_ASSERT_LOC(); \
882086c639648ccecc9081705a279249ce939d818bDavid 'Digit' Turner            android_assert_fail("%s is %d and should be %s %d\n", \
892086c639648ccecc9081705a279249ce939d818bDavid 'Digit' Turner                                #cond_ , cond_result_, #op_, cond_expected_); \
902086c639648ccecc9081705a279249ce939d818bDavid 'Digit' Turner        } \
912086c639648ccecc9081705a279249ce939d818bDavid 'Digit' Turner    } while (0)
922086c639648ccecc9081705a279249ce939d818bDavid 'Digit' Turner
932086c639648ccecc9081705a279249ce939d818bDavid 'Digit' Turner#  define  _ANDROID_ASSERT_PTR(cond_,expected_)  \
944c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner    do { \
954c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner        void*  cond_result_ = (cond_); \
964c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner        void*  cond_expected_ = (void*)(expected_); \
974c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner        if (cond_result_ != cond_expected_) { \
982086c639648ccecc9081705a279249ce939d818bDavid 'Digit' Turner            _ANDROID_ASSERT_LOC(); \
994c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner            android_assert_fail("%s is %p instead of %p\n", \
1004c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner                                #cond_ , cond_result_, cond_expected_); \
1014c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner        } \
1024c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner    } while (0)
1034c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner
1042086c639648ccecc9081705a279249ce939d818bDavid 'Digit' Turner#  define  _ANDROID_NEVER_NULL(ptr_)  \
1054c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner    do { \
1064c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner        void*  never_ptr_ = (ptr_); \
1074c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner        if (never_ptr_ == NULL) { \
1082086c639648ccecc9081705a279249ce939d818bDavid 'Digit' Turner            _ANDROID_ASSERT_LOC(); \
1094c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner            android_assert_fail("%s is NULL\n", #ptr_); \
1104c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner        } \
1114c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner    } while (0)
1124c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner
1132086c639648ccecc9081705a279249ce939d818bDavid 'Digit' Turner
1142086c639648ccecc9081705a279249ce939d818bDavid 'Digit' Turner
1152086c639648ccecc9081705a279249ce939d818bDavid 'Digit' Turner#ifdef ACONFIG_USE_ASSERT
1162086c639648ccecc9081705a279249ce939d818bDavid 'Digit' Turner
1172086c639648ccecc9081705a279249ce939d818bDavid 'Digit' Turner#  define  AASSERT_LOC()   _ANDROID_ASSERT_LOC()
1182086c639648ccecc9081705a279249ce939d818bDavid 'Digit' Turner#  define  AASSERT_FAIL(...) _ANDROID_ASSERT_FAIL(__VA_ARGS__)
1192086c639648ccecc9081705a279249ce939d818bDavid 'Digit' Turner
1202086c639648ccecc9081705a279249ce939d818bDavid 'Digit' Turner/* Assert we never reach some code point */
1212086c639648ccecc9081705a279249ce939d818bDavid 'Digit' Turner#  define  AASSERT_UNREACHED(...)   _ANDROID_ASSERT_UNREACHED(__VA_ARGS__)
1222086c639648ccecc9081705a279249ce939d818bDavid 'Digit' Turner
1232086c639648ccecc9081705a279249ce939d818bDavid 'Digit' Turner
1242086c639648ccecc9081705a279249ce939d818bDavid 'Digit' Turner/* Generic assertion, must be followed by formatted string parameters */
1252086c639648ccecc9081705a279249ce939d818bDavid 'Digit' Turner#  define  AASSERT(cond,...)  _ANDROID_ASSERT(cond,__VA_ARGS__)
1262086c639648ccecc9081705a279249ce939d818bDavid 'Digit' Turner
1272086c639648ccecc9081705a279249ce939d818bDavid 'Digit' Turner/* Assert a condition evaluates to a given boolean */
1282086c639648ccecc9081705a279249ce939d818bDavid 'Digit' Turner#  define  AASSERT_BOOL(cond_,expected_)   _ANDROID_ASSERT_BOOL(cond_,expected_)
1292086c639648ccecc9081705a279249ce939d818bDavid 'Digit' Turner
1302086c639648ccecc9081705a279249ce939d818bDavid 'Digit' Turner/* Assert a condition evaluates to a given integer */
1312086c639648ccecc9081705a279249ce939d818bDavid 'Digit' Turner#  define  AASSERT_INT(cond_,expected_)  _ANDROID_ASSERT_INT(cond_,expected_)
1322086c639648ccecc9081705a279249ce939d818bDavid 'Digit' Turner
1332086c639648ccecc9081705a279249ce939d818bDavid 'Digit' Turner#  define  AASSERT_INT_LT(cond_,expected_)  _ANDROID_ASSERT_INT_OP(cond_,expected_,< )
1342086c639648ccecc9081705a279249ce939d818bDavid 'Digit' Turner#  define  AASSERT_INT_LTE(cond_,expected_) _ANDROID_ASSERT_INT_OP(cond_,expected_,<= )
1352086c639648ccecc9081705a279249ce939d818bDavid 'Digit' Turner#  define  AASSERT_INT_GT(cond_,expected_)  _ANDROID_ASSERT_INT_OP(cond_,expected_,> )
1362086c639648ccecc9081705a279249ce939d818bDavid 'Digit' Turner#  define  AASSERT_INT_GTE(cond_,expected_) _ANDROID_ASSERT_INT_OP(cond_,expected_,>= )
1372086c639648ccecc9081705a279249ce939d818bDavid 'Digit' Turner#  define  AASSERT_INT_EQ(cond_,expected_)  _ANDROID_ASSERT_INT_OP(cond_,expected_,==)
1382086c639648ccecc9081705a279249ce939d818bDavid 'Digit' Turner#  define  AASSERT_INT_NEQ(cond_,expected_) _ANDROID_ASSERT_INT_OP(cond_,expected_,!=)
1392086c639648ccecc9081705a279249ce939d818bDavid 'Digit' Turner
1402086c639648ccecc9081705a279249ce939d818bDavid 'Digit' Turner#  define  AASSERT_PTR(cond_,expected_)  _ANDROID_ASSERT_PTR(cond_,expected_)
1412086c639648ccecc9081705a279249ce939d818bDavid 'Digit' Turner
1422086c639648ccecc9081705a279249ce939d818bDavid 'Digit' Turner#  define  ANEVER_NULL(ptr_)   _ANDROID_NEVER_NULL(ptr_)
1432086c639648ccecc9081705a279249ce939d818bDavid 'Digit' Turner
1444c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner#else /* !ACONFIG_USE_ASSERT */
1454c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner
1464c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner#  define AASSERT_LOC()              ((void)0)
1474c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner#  define  AASSERT_FAIL(...)        ((void)0)
1484c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner#  define  AASSERT_UNREACHED(...)   ((void)0)
1494c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner
1504c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner/* for side-effects */
1514c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner#  define  AASSERT(cond,...)             ((void)(cond), (void)0)
1524c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner#  define  AASSERT_BOOL(cond,val)        ((void)(cond), (void)0)
1534c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner#  define  AASSERT_INT(cond,val)         AASSERT_BOOL(cond,val)
1544c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner#  define  AASSERT_PTR(cond,val)         AASSERT_BOOL(cond,val)
1554c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner#  define  ANEVER_NULL(ptr)              ((void)(ptr), (void)0)
1564c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner
1574c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner#endif /* !ACONFIG_USE_ASSERT */
1584c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner
1594c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner#  define  AASSERT_TRUE(cond_)   AASSERT_BOOL(cond_,1)
1604c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner#  define  AASSERT_FALSE(cond_)  AASSERT_BOOL(cond_,0)
1614c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner
1624c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner
1634c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner/* this can be used to redirect the assertion log to something
1644c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner * other than stderr. Note that android_assert_fail also calls
1654c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner * android_vpanic.
1664c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner */
1674c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turnertypedef void (*AAssertLogFunc)( const char*  fmt, va_list  args );
1684c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turnervoid  android_assert_registerLog( AAssertLogFunc  logger );
1694c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner
1704c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner#endif /* ANDROID_UTILS_ASSERT_H */
171