OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // Logging and checks. | 5 // Logging and checks. Avoids a dependency on base. |
6 // | 6 // |
7 // Log messages to stdout. LOG() prints normal user messages, VLOG() | 7 // LOG(tag) prints messages. Tags are INFO, WARNING, ERROR and FATAL. |
8 // is verbose, for tracing and debugging. SetVerbose() enables/disables | 8 // INFO prints to stdout, the others to stderr. FATAL aborts after printing. |
9 // VLOG() output. | |
10 // | 9 // |
11 // LOG() and VLOG() are printf-like, and arguments are checked by gcc. | 10 // LOG_IF(tag, predicate) logs if predicate evaluates to true, else silent. |
12 // LOG_IF() and VLOG_IF() call LOG/VLOG if their predicate is true. | 11 // |
13 // CHECK() aborts if its predicate is false. NOTREACHED() always aborts. | 12 // VLOG(level) logs INFO messages where level is less than or equal to the |
14 // Logging is not thread-safe. | 13 // verbosity level set with SetVerbose(). |
14 // | |
15 // VLOG_IF(level, predicate) logs INFO if predicate evaluates to true, | |
16 // else silent. | |
17 // | |
18 // CHECK(predicate) logs a FATAL error if predicate is false. | |
19 // NOTREACHED() always aborts. | |
20 // Log streams can be changed with SetStreams(). Logging is not thread-safe. | |
15 // | 21 // |
16 | 22 |
17 #ifndef TOOLS_RELOCATION_PACKER_SRC_DEBUG_H_ | 23 #ifndef TOOLS_RELOCATION_PACKER_SRC_DEBUG_H_ |
18 #define TOOLS_RELOCATION_PACKER_SRC_DEBUG_H_ | 24 #define TOOLS_RELOCATION_PACKER_SRC_DEBUG_H_ |
19 | 25 |
20 #ifdef NDEBUG | 26 #include <limits.h> |
21 #undef NDEBUG | 27 #include <algorithm> |
22 #include <assert.h> | 28 #include <ostream> |
23 #define NDEBUG | 29 #include <sstream> |
24 #else | |
25 #include <assert.h> | |
26 #endif | |
27 | |
28 #include <stdarg.h> | |
29 #include <string.h> | |
30 | 30 |
31 namespace relocation_packer { | 31 namespace relocation_packer { |
32 | 32 |
33 // If gcc, define PRINTF_ATTRIBUTE so that gcc checks Log() as printf-like. | |
34 #if defined(__GNUC__) && (__GNUC__ >= 3) | |
35 #define PRINTF_ATTRIBUTE(string_index, first_to_check) \ | |
36 __attribute__((__format__(__printf__, string_index, first_to_check))) | |
37 #else | |
38 #define PRINTF_ATTRIBUTE(string_index, first_to_check) | |
39 #endif | |
40 | |
41 // Logging and checking macros. | |
42 #define LOG(...) ::relocation_packer::Logger::Log(__VA_ARGS__) | |
43 #define VLOG(...) ::relocation_packer::Logger::VLog(__VA_ARGS__) | |
44 #define LOG_IF(cond, ...) \ | |
45 do { \ | |
46 if ((cond)) \ | |
47 LOG(__VA_ARGS__); \ | |
48 } while (0) | |
49 #define VLOG_IF(cond, ...) \ | |
50 do { \ | |
51 if ((cond)) \ | |
52 VLOG(__VA_ARGS__); \ | |
53 } while (0) | |
54 | |
55 #define CHECK(expr) assert((expr)) | |
56 #define NOTREACHED(_) assert(false) | |
57 | |
58 class Logger { | 33 class Logger { |
59 public: | 34 public: |
60 // Log and verbose log to stdout. | 35 enum Severity {INFO = 0, WARNING, ERROR, FATAL}; |
61 // |format| is a printf format string. | |
62 static void Log(const char* format, ...) PRINTF_ATTRIBUTE(1, 2); | |
63 static void VLog(const char* format, ...) PRINTF_ATTRIBUTE(1, 2); | |
64 | 36 |
65 // Set verbose mode. | 37 // Construct a new message logger. Prints if level is less than or |
66 // |flag| is true to enable verbose logging, false to disable it. | 38 // equal to the level set with SetVerbose() and predicate is true. |
67 static void SetVerbose(bool flag); | 39 // |severity| is an enumerated severity. |
40 // |level| is the verbosity level. | |
41 // |predicate| controls if the logger prints or is silent. | |
42 Logger(Severity severity, int level, bool predicate); | |
43 | |
44 // On destruction, flush and print the strings accumulated in stream_. | |
45 ~Logger(); | |
46 | |
47 // Return the stream for this logger. | |
48 std::ostream& GetStream() { return stream_; } | |
49 | |
50 // Set verbosity level. Messages with a level less than or equal to | |
51 // this level are printed, others are discarded. Static, not thread-safe. | |
52 static void SetVerbose(int level) { max_level_ = level; } | |
53 | |
54 // Set info and error logging streams. Static, not thread-safe. | |
55 static void SetStreams(std::ostream* info_stream, | |
56 std::ostream* error_stream) { | |
57 info_stream_ = info_stream; | |
58 error_stream_ = error_stream; | |
59 } | |
60 | |
61 // Reset to initial state. | |
62 static void Reset(); | |
68 | 63 |
69 private: | 64 private: |
70 Logger() : is_verbose_(false) { } | 65 // Message severity, verbosity level, and predicate. |
71 ~Logger() {} | 66 Severity severity_; |
67 int level_; | |
68 bool predicate_; | |
72 | 69 |
73 // Implementation of log to stdout. | 70 // String stream, accumulates message text. |
74 // |format| is a printf format string. | 71 std::ostringstream stream_; |
75 // |args| is a varargs list of printf arguments. | |
76 void Log(const char* format, va_list args); | |
77 | 72 |
78 // If set, VLOG is enabled, otherwise it is a no-op. | 73 // Verbosity for INFO messages. Not thread-safe. |
79 bool is_verbose_; | 74 static int max_level_; |
80 | 75 |
81 // Singleton support. Not thread-safe. | 76 // Logging streams. Not thread-safe. |
82 static Logger* GetInstance(); | 77 static std::ostream* info_stream_; |
83 static Logger* instance_; | 78 static std::ostream* error_stream_; |
84 }; | 79 }; |
85 | 80 |
86 } // namespace relocation_packer | 81 } // namespace relocation_packer |
87 | 82 |
83 // Make logging severities visible globally. | |
84 typedef relocation_packer::Logger::Severity LogSeverity; | |
85 const LogSeverity INFO = relocation_packer::Logger::INFO; | |
86 const LogSeverity WARNING = relocation_packer::Logger::WARNING; | |
87 const LogSeverity ERROR = relocation_packer::Logger::ERROR; | |
88 const LogSeverity FATAL = relocation_packer::Logger::FATAL; | |
89 | |
90 // LOG(severity) prints a message with the given severity, and aborts if | |
91 // severity is FATAL. LOG_IF(severity, predicate) does the same but only if | |
92 // predicate is true. INT_MIN is guaranteed to be less than or equal to | |
93 // any verbosity level. | |
94 #define LOG(severity) \ | |
95 (relocation_packer::Logger(severity, INT_MIN, true).GetStream()) | |
96 #define LOG_IF(severity, predicate) \ | |
97 (relocation_packer::Logger(severity, INT_MIN, (predicate)).GetStream()) | |
rmcilroy
2014/07/16 11:38:48
nit - I would just use '-1' rather than INT_MIN, s
simonb (inactive)
2014/07/16 12:51:03
Left as is. -1 allows (accidental?) SetVerbose(-2
| |
98 | |
99 // VLOG(level) prints its message as INFO if level is less than or equal to | |
100 // the current verbosity level. | |
101 #define VLOG(level) \ | |
102 (relocation_packer::Logger(INFO, (level), true).GetStream()) | |
103 #define VLOG_IF(level, predicate) \ | |
104 (relocation_packer::Logger(INFO, (level), (predicate)).GetStream()) | |
105 | |
106 // CHECK(predicate) fails with a FATAL log message if predicate is false. | |
107 #define CHECK(predicate) (LOG_IF(FATAL, !(predicate)) \ | |
108 << __FILE__ << ":" << __LINE__ << ": " \ | |
109 << __FUNCTION__ << ": CHECK '" #predicate "' failed") | |
110 | |
111 // NOTREACHED() always fails with a FATAL log message. | |
112 #define NOTREACHED(_) (LOG(FATAL) \ | |
113 << __FILE__ << ":" << __LINE__ << ": " \ | |
114 << __FUNCTION__ << ": NOTREACHED() hit") | |
115 | |
88 #endif // TOOLS_RELOCATION_PACKER_SRC_DEBUG_H_ | 116 #endif // TOOLS_RELOCATION_PACKER_SRC_DEBUG_H_ |
OLD | NEW |