xref: /aosp_15_r20/external/regex-re2/util/logging.h (revision ccdc9c3e24c519bfa4832a66aa2e83a52c19f295)
1*ccdc9c3eSSadaf Ebrahimi // Copyright 2009 The RE2 Authors.  All Rights Reserved.
2*ccdc9c3eSSadaf Ebrahimi // Use of this source code is governed by a BSD-style
3*ccdc9c3eSSadaf Ebrahimi // license that can be found in the LICENSE file.
4*ccdc9c3eSSadaf Ebrahimi 
5*ccdc9c3eSSadaf Ebrahimi #ifndef UTIL_LOGGING_H_
6*ccdc9c3eSSadaf Ebrahimi #define UTIL_LOGGING_H_
7*ccdc9c3eSSadaf Ebrahimi 
8*ccdc9c3eSSadaf Ebrahimi // Simplified version of Google's logging.
9*ccdc9c3eSSadaf Ebrahimi 
10*ccdc9c3eSSadaf Ebrahimi #include <assert.h>
11*ccdc9c3eSSadaf Ebrahimi #include <stdio.h>
12*ccdc9c3eSSadaf Ebrahimi #include <stdlib.h>
13*ccdc9c3eSSadaf Ebrahimi #include <ostream>
14*ccdc9c3eSSadaf Ebrahimi #include <sstream>
15*ccdc9c3eSSadaf Ebrahimi 
16*ccdc9c3eSSadaf Ebrahimi #include "util/util.h"
17*ccdc9c3eSSadaf Ebrahimi 
18*ccdc9c3eSSadaf Ebrahimi // Debug-only checking.
19*ccdc9c3eSSadaf Ebrahimi #define DCHECK(condition) assert(condition)
20*ccdc9c3eSSadaf Ebrahimi #define DCHECK_EQ(val1, val2) assert((val1) == (val2))
21*ccdc9c3eSSadaf Ebrahimi #define DCHECK_NE(val1, val2) assert((val1) != (val2))
22*ccdc9c3eSSadaf Ebrahimi #define DCHECK_LE(val1, val2) assert((val1) <= (val2))
23*ccdc9c3eSSadaf Ebrahimi #define DCHECK_LT(val1, val2) assert((val1) < (val2))
24*ccdc9c3eSSadaf Ebrahimi #define DCHECK_GE(val1, val2) assert((val1) >= (val2))
25*ccdc9c3eSSadaf Ebrahimi #define DCHECK_GT(val1, val2) assert((val1) > (val2))
26*ccdc9c3eSSadaf Ebrahimi 
27*ccdc9c3eSSadaf Ebrahimi // Always-on checking
28*ccdc9c3eSSadaf Ebrahimi #define CHECK(x)	if(x){}else LogMessageFatal(__FILE__, __LINE__).stream() << "Check failed: " #x
29*ccdc9c3eSSadaf Ebrahimi #define CHECK_LT(x, y)	CHECK((x) < (y))
30*ccdc9c3eSSadaf Ebrahimi #define CHECK_GT(x, y)	CHECK((x) > (y))
31*ccdc9c3eSSadaf Ebrahimi #define CHECK_LE(x, y)	CHECK((x) <= (y))
32*ccdc9c3eSSadaf Ebrahimi #define CHECK_GE(x, y)	CHECK((x) >= (y))
33*ccdc9c3eSSadaf Ebrahimi #define CHECK_EQ(x, y)	CHECK((x) == (y))
34*ccdc9c3eSSadaf Ebrahimi #define CHECK_NE(x, y)	CHECK((x) != (y))
35*ccdc9c3eSSadaf Ebrahimi 
36*ccdc9c3eSSadaf Ebrahimi #define LOG_INFO LogMessage(__FILE__, __LINE__)
37*ccdc9c3eSSadaf Ebrahimi #define LOG_WARNING LogMessage(__FILE__, __LINE__)
38*ccdc9c3eSSadaf Ebrahimi #define LOG_ERROR LogMessage(__FILE__, __LINE__)
39*ccdc9c3eSSadaf Ebrahimi #define LOG_FATAL LogMessageFatal(__FILE__, __LINE__)
40*ccdc9c3eSSadaf Ebrahimi #define LOG_QFATAL LOG_FATAL
41*ccdc9c3eSSadaf Ebrahimi 
42*ccdc9c3eSSadaf Ebrahimi // It seems that one of the Windows header files defines ERROR as 0.
43*ccdc9c3eSSadaf Ebrahimi #ifdef _WIN32
44*ccdc9c3eSSadaf Ebrahimi #define LOG_0 LOG_INFO
45*ccdc9c3eSSadaf Ebrahimi #endif
46*ccdc9c3eSSadaf Ebrahimi 
47*ccdc9c3eSSadaf Ebrahimi #ifdef NDEBUG
48*ccdc9c3eSSadaf Ebrahimi #define LOG_DFATAL LOG_ERROR
49*ccdc9c3eSSadaf Ebrahimi #else
50*ccdc9c3eSSadaf Ebrahimi #define LOG_DFATAL LOG_FATAL
51*ccdc9c3eSSadaf Ebrahimi #endif
52*ccdc9c3eSSadaf Ebrahimi 
53*ccdc9c3eSSadaf Ebrahimi #define LOG(severity) LOG_ ## severity.stream()
54*ccdc9c3eSSadaf Ebrahimi 
55*ccdc9c3eSSadaf Ebrahimi #define VLOG(x) if((x)>0){}else LOG_INFO.stream()
56*ccdc9c3eSSadaf Ebrahimi 
57*ccdc9c3eSSadaf Ebrahimi class LogMessage {
58*ccdc9c3eSSadaf Ebrahimi  public:
LogMessage(const char * file,int line)59*ccdc9c3eSSadaf Ebrahimi   LogMessage(const char* file, int line)
60*ccdc9c3eSSadaf Ebrahimi       : flushed_(false) {
61*ccdc9c3eSSadaf Ebrahimi     stream() << file << ":" << line << ": ";
62*ccdc9c3eSSadaf Ebrahimi   }
Flush()63*ccdc9c3eSSadaf Ebrahimi   void Flush() {
64*ccdc9c3eSSadaf Ebrahimi     stream() << "\n";
65*ccdc9c3eSSadaf Ebrahimi     string s = str_.str();
66*ccdc9c3eSSadaf Ebrahimi     size_t n = s.size();
67*ccdc9c3eSSadaf Ebrahimi     if (fwrite(s.data(), 1, n, stderr) < n) {}  // shut up gcc
68*ccdc9c3eSSadaf Ebrahimi     flushed_ = true;
69*ccdc9c3eSSadaf Ebrahimi   }
~LogMessage()70*ccdc9c3eSSadaf Ebrahimi   ~LogMessage() {
71*ccdc9c3eSSadaf Ebrahimi     if (!flushed_) {
72*ccdc9c3eSSadaf Ebrahimi       Flush();
73*ccdc9c3eSSadaf Ebrahimi     }
74*ccdc9c3eSSadaf Ebrahimi   }
stream()75*ccdc9c3eSSadaf Ebrahimi   std::ostream& stream() { return str_; }
76*ccdc9c3eSSadaf Ebrahimi 
77*ccdc9c3eSSadaf Ebrahimi  private:
78*ccdc9c3eSSadaf Ebrahimi   bool flushed_;
79*ccdc9c3eSSadaf Ebrahimi   std::ostringstream str_;
80*ccdc9c3eSSadaf Ebrahimi 
81*ccdc9c3eSSadaf Ebrahimi   LogMessage(const LogMessage&) = delete;
82*ccdc9c3eSSadaf Ebrahimi   LogMessage& operator=(const LogMessage&) = delete;
83*ccdc9c3eSSadaf Ebrahimi };
84*ccdc9c3eSSadaf Ebrahimi 
85*ccdc9c3eSSadaf Ebrahimi // Silence "destructor never returns" warning for ~LogMessageFatal().
86*ccdc9c3eSSadaf Ebrahimi // Since this is a header file, push and then pop to limit the scope.
87*ccdc9c3eSSadaf Ebrahimi #ifdef _MSC_VER
88*ccdc9c3eSSadaf Ebrahimi #pragma warning(push)
89*ccdc9c3eSSadaf Ebrahimi #pragma warning(disable: 4722)
90*ccdc9c3eSSadaf Ebrahimi #endif
91*ccdc9c3eSSadaf Ebrahimi 
92*ccdc9c3eSSadaf Ebrahimi class LogMessageFatal : public LogMessage {
93*ccdc9c3eSSadaf Ebrahimi  public:
LogMessageFatal(const char * file,int line)94*ccdc9c3eSSadaf Ebrahimi   LogMessageFatal(const char* file, int line)
95*ccdc9c3eSSadaf Ebrahimi       : LogMessage(file, line) {}
~LogMessageFatal()96*ccdc9c3eSSadaf Ebrahimi   ATTRIBUTE_NORETURN ~LogMessageFatal() {
97*ccdc9c3eSSadaf Ebrahimi     Flush();
98*ccdc9c3eSSadaf Ebrahimi     abort();
99*ccdc9c3eSSadaf Ebrahimi   }
100*ccdc9c3eSSadaf Ebrahimi  private:
101*ccdc9c3eSSadaf Ebrahimi   LogMessageFatal(const LogMessageFatal&) = delete;
102*ccdc9c3eSSadaf Ebrahimi   LogMessageFatal& operator=(const LogMessageFatal&) = delete;
103*ccdc9c3eSSadaf Ebrahimi };
104*ccdc9c3eSSadaf Ebrahimi 
105*ccdc9c3eSSadaf Ebrahimi #ifdef _MSC_VER
106*ccdc9c3eSSadaf Ebrahimi #pragma warning(pop)
107*ccdc9c3eSSadaf Ebrahimi #endif
108*ccdc9c3eSSadaf Ebrahimi 
109*ccdc9c3eSSadaf Ebrahimi #endif  // UTIL_LOGGING_H_
110