Chromium Code Reviews| 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 |