• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2023 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef JNI_ZERO_LOGGING_H_
6 #define JNI_ZERO_LOGGING_H_
7 
8 #include "third_party/jni_zero/jni_export.h"
9 
10 // Simplified version of Google's logging. Adapted from perfetto's
11 // implementation.
12 namespace jni_zero {
13 
14 // Constexpr functions to extract basename(__FILE__), e.g.: ../foo/f.c -> f.c .
StrEnd(const char * s)15 constexpr const char* StrEnd(const char* s) {
16   return *s ? StrEnd(s + 1) : s;
17 }
18 
BasenameRecursive(const char * s,const char * begin,const char * end)19 constexpr const char* BasenameRecursive(const char* s,
20                                         const char* begin,
21                                         const char* end) {
22   return (*s == '/' && s < end)
23              ? (s + 1)
24              : ((s > begin) ? BasenameRecursive(s - 1, begin, end) : s);
25 }
26 
Basename(const char * str)27 constexpr const char* Basename(const char* str) {
28   return BasenameRecursive(StrEnd(str), str, StrEnd(str));
29 }
30 
31 enum LogLev { kLogInfo = 0, kLogError, kLogFatal };
32 
33 struct LogMessageCallbackArgs {
34   LogLev level;
35   int line;
36   const char* filename;
37   const char* message;
38 };
39 
40 using LogMessageCallback = void (*)(LogMessageCallbackArgs);
41 
42 // This is not thread safe and must be called before using tracing from other
43 // threads.
44 JNI_ZERO_COMPONENT_BUILD_EXPORT void SetLogMessageCallback(
45     LogMessageCallback callback);
46 
47 JNI_ZERO_COMPONENT_BUILD_EXPORT void LogMessage(LogLev,
48                                                 const char* fname,
49                                                 int line,
50                                                 const char* fmt,
51                                                 ...)
52     __attribute__((__format__(__printf__, 4, 5)));
53 
54 #define JNI_ZERO_IMMEDIATE_CRASH() \
55   do {                             \
56     __builtin_trap();              \
57     __builtin_unreachable();       \
58   } while (0)
59 #define JNI_ZERO_XLOG(level, fmt, ...)                                         \
60   ::jni_zero::LogMessage(level, ::jni_zero::Basename(__FILE__), __LINE__, fmt, \
61                          ##__VA_ARGS__)
62 #define JNI_ZERO_ILOG(fmt, ...) \
63   JNI_ZERO_XLOG(::jni_zero::kLogInfo, fmt, ##__VA_ARGS__)
64 #define JNI_ZERO_ELOG(fmt, ...) \
65   JNI_ZERO_XLOG(::jni_zero::kLogError, fmt, ##__VA_ARGS__)
66 #define JNI_ZERO_FLOG(fmt, ...) \
67   JNI_ZERO_XLOG(::jni_zero::kLogFatal, fmt, ##__VA_ARGS__)
68 
69 #define JNI_ZERO_CHECK(x)                            \
70   do {                                               \
71     if (__builtin_expect(!(x), 0)) {                 \
72       JNI_ZERO_FLOG("%s", "JNI_ZERO_CHECK(" #x ")"); \
73     }                                                \
74   } while (0)
75 #if defined(NDEBUG) && !defined(DCHECK_ALWAYS_ON)
76 #define JNI_ZERO_DCHECK(x) \
77   do {                     \
78   } while (false && (x))
79 #else
80 #define JNI_ZERO_DCHECK(x) JNI_ZERO_CHECK(x)
81 #endif
82 }  // namespace jni_zero
83 
84 #endif  // JNI_ZERO_LOGGING_H_
85