| // Copyright 2023 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef JNI_ZERO_LOGGING_H_ |
| #define JNI_ZERO_LOGGING_H_ |
| |
| #include "third_party/jni_zero/jni_export.h" |
| |
| // Simplified version of Google's logging. Adapted from perfetto's |
| // implementation. |
| namespace jni_zero { |
| |
| // Constexpr functions to extract basename(__FILE__), e.g.: ../foo/f.c -> f.c . |
| constexpr const char* StrEnd(const char* s) { |
| return *s ? StrEnd(s + 1) : s; |
| } |
| |
| constexpr const char* BasenameRecursive(const char* s, |
| const char* begin, |
| const char* end) { |
| return (*s == '/' && s < end) |
| ? (s + 1) |
| : ((s > begin) ? BasenameRecursive(s - 1, begin, end) : s); |
| } |
| |
| constexpr const char* Basename(const char* str) { |
| return BasenameRecursive(StrEnd(str), str, StrEnd(str)); |
| } |
| |
| enum LogLev { kLogInfo = 0, kLogError, kLogFatal }; |
| |
| struct LogMessageCallbackArgs { |
| LogLev level; |
| int line; |
| const char* filename; |
| const char* message; |
| }; |
| |
| using LogMessageCallback = void (*)(LogMessageCallbackArgs); |
| |
| // This is not thread safe and must be called before using tracing from other |
| // threads. |
| JNI_ZERO_COMPONENT_BUILD_EXPORT void SetLogMessageCallback( |
| LogMessageCallback callback); |
| |
| JNI_ZERO_COMPONENT_BUILD_EXPORT void LogMessage(LogLev, |
| const char* fname, |
| int line, |
| const char* fmt, |
| ...) |
| __attribute__((__format__(__printf__, 4, 5))); |
| |
| #define JNI_ZERO_IMMEDIATE_CRASH() \ |
| do { \ |
| __builtin_trap(); \ |
| __builtin_unreachable(); \ |
| } while (0) |
| #define JNI_ZERO_XLOG(level, fmt, ...) \ |
| ::jni_zero::LogMessage(level, ::jni_zero::Basename(__FILE__), __LINE__, fmt, \ |
| ##__VA_ARGS__) |
| #define JNI_ZERO_ILOG(fmt, ...) \ |
| JNI_ZERO_XLOG(::jni_zero::kLogInfo, fmt, ##__VA_ARGS__) |
| #define JNI_ZERO_ELOG(fmt, ...) \ |
| JNI_ZERO_XLOG(::jni_zero::kLogError, fmt, ##__VA_ARGS__) |
| #define JNI_ZERO_FLOG(fmt, ...) \ |
| JNI_ZERO_XLOG(::jni_zero::kLogFatal, fmt, ##__VA_ARGS__) |
| |
| #define JNI_ZERO_CHECK(x) \ |
| do { \ |
| if (__builtin_expect(!(x), 0)) { \ |
| JNI_ZERO_FLOG("%s", "JNI_ZERO_CHECK(" #x ")"); \ |
| } \ |
| } while (0) |
| #if defined(NDEBUG) && !defined(DCHECK_ALWAYS_ON) |
| #define JNI_ZERO_DCHECK(x) \ |
| do { \ |
| } while (false && (x)) |
| #else |
| #define JNI_ZERO_DCHECK(x) JNI_ZERO_CHECK(x) |
| #endif |
| } // namespace jni_zero |
| |
| #endif // JNI_ZERO_LOGGING_H_ |