blob: 2d011b6093689adce9d134507e72a2649050643f [file] [log] [blame]
#ifndef __CUTILS_LOG_H__
#define __CUTILS_LOG_H__
#ifndef LOG_TAG
#define LOG_TAG nullptr
#endif
/*
* Normally we strip the effects of ALOGV (VERBOSE messages),
* LOG_FATAL and LOG_FATAL_IF (FATAL assert messages) from the
* release builds be defining NDEBUG. You can modify this (for
* example with "#define LOG_NDEBUG 0" at the top of your source
* file) to change that behavior.
*/
#ifndef LOG_NDEBUG
#ifdef NDEBUG
#define LOG_NDEBUG 1
#else
#define LOG_NDEBUG 0
#endif
#endif
/*
* Use __VA_ARGS__ if running a static analyzer,
* to avoid warnings of unused variables in __VA_ARGS__.
* Use constexpr function in C++ mode, so these macros can be used
* in other constexpr functions without warning.
*/
#ifdef __clang_analyzer__
#ifdef __cplusplus
extern "C++" {
template <typename... Ts>
constexpr int __fake_use_va_args(Ts...) {
return 0;
}
}
#else
extern int __fake_use_va_args(int, ...);
#endif /* __cplusplus */
#define __FAKE_USE_VA_ARGS(...) ((void)__fake_use_va_args(0, ##__VA_ARGS__))
#else
#define __FAKE_USE_VA_ARGS(...) ((void)(0))
#endif /* __clang_analyzer__ */
enum {
ANDROID_LOG_UNKNOWN = 0,
ANDROID_LOG_DEFAULT,
ANDROID_LOG_VERBOSE,
ANDROID_LOG_DEBUG,
ANDROID_LOG_INFO,
ANDROID_LOG_WARN,
ANDROID_LOG_ERROR,
ANDROID_LOG_FATAL,
ANDROID_LOG_SILENT,
};
#define android_printLog(prio, tag, format, ...) \
__android_log_print(prio, tag, __FILE__, __LINE__, "[prio %d] " format, prio, ##__VA_ARGS__)
#define LOG_PRI(priority, tag, ...) android_printLog(priority, tag, __VA_ARGS__)
#define ALOG(priority, tag, ...) LOG_PRI(ANDROID_##priority, tag, __VA_ARGS__)
#define __android_second(dummy, second, ...) second
#define __android_rest(first, ...) , ##__VA_ARGS__
#define android_printAssert(condition, tag, format, ...) \
__android_log_assert(condition, tag, __FILE__, __LINE__, "assert: condition: %s " format, \
condition, ##__VA_ARGS__)
#define LOG_ALWAYS_FATAL_IF(condition, ...) \
((condition) \
? ((void)android_printAssert(#condition, LOG_TAG, ##__VA_ARGS__)) \
: (void)0)
#define LOG_ALWAYS_FATAL(...) \
(((void)android_printAssert(NULL, LOG_TAG, ##__VA_ARGS__)))
/*
* Simplified macro to send a verbose log message using the current LOG_TAG.
*/
#define __ALOGV(...) ((void)ALOG(LOG_VERBOSE, LOG_TAG, __VA_ARGS__))
#if LOG_NDEBUG
#define ALOGV(...) \
do { \
__FAKE_USE_VA_ARGS(__VA_ARGS__); \
if (false) { \
__ALOGV(__VA_ARGS__); \
} \
} while (false)
#else
#define ALOGV(...) __ALOGV(__VA_ARGS__)
#endif
#define ALOGE(...) ((void)ALOG(LOG_ERROR, LOG_TAG, __VA_ARGS__))
#define ALOGW(...) ((void)ALOG(LOG_WARN, LOG_TAG, __VA_ARGS__))
#define ALOGI(...) ((void)ALOG(LOG_INFO, LOG_TAG, __VA_ARGS__))
#define ALOGD(...) ((void)ALOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__))
#if LOG_NDEBUG
#define LOG_FATAL_IF(cond, ...) __FAKE_USE_VA_ARGS(__VA_ARGS__)
#define LOG_FATAL(...) __FAKE_USE_VA_ARGS(__VA_ARGS__)
#else
#define LOG_FATAL_IF(cond, ...) LOG_ALWAYS_FATAL_IF(cond, ##__VA_ARGS__)
#define LOG_FATAL(...) LOG_ALWAYS_FATAL(__VA_ARGS__)
#endif
#define ALOG_ASSERT(cond, ...) LOG_FATAL_IF(!(cond), ##__VA_ARGS__)
extern "C" {
int __android_log_print(int priority, const char* tag, const char* file, int line,
const char* format, ...);
[[noreturn]] void __android_log_assert(const char* condition, const char* tag, const char* file,
int line, const char* format, ...);
}
#endif