187a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov// Copyright 2014 The Chromium Authors. All rights reserved.
287a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov// Use of this source code is governed by a BSD-style license that can be
387a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov// found in the LICENSE file.
487a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov
587a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov// Logging and checks.  Avoids a dependency on base.
687a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov//
787a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov// LOG(tag) prints messages.  Tags are INFO, WARNING, ERROR and FATAL.
887a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov// INFO prints to stdout, the others to stderr.  FATAL aborts after printing.
987a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov//
1087a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov// LOG_IF(tag, predicate) logs if predicate evaluates to true, else silent.
1187a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov//
1287a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov// VLOG(level) logs INFO messages where level is less than or equal to the
1387a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov// verbosity level set with SetVerbose().
1487a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov//
1587a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov// VLOG_IF(level, predicate) logs INFO if predicate evaluates to true,
1687a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov// else silent.
1787a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov//
1887a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov// CHECK(predicate) logs a FATAL error if predicate is false.
1987a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov// NOTREACHED() always aborts.
2087a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov// Log streams can be changed with SetStreams().  Logging is not thread-safe.
2187a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov//
2287a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov
2387a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov#ifndef TOOLS_RELOCATION_PACKER_SRC_DEBUG_H_
2487a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov#define TOOLS_RELOCATION_PACKER_SRC_DEBUG_H_
2587a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov
2687a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov#include <limits.h>
2787a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov#include <ostream>
2887a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov#include <sstream>
2987a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov
3087a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanovnamespace relocation_packer {
3187a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov
3287a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanovclass Logger {
3387a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov public:
3487a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov  enum Severity {INFO = 0, WARNING, ERROR, FATAL};
3587a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov
3687a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov  // Construct a new message logger.  Prints if level is less than or
3787a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov  // equal to the level set with SetVerbose() and predicate is true.
3887a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov  // |severity| is an enumerated severity.
3987a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov  // |level| is the verbosity level.
4087a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov  // |predicate| controls if the logger prints or is silent.
4187a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov  Logger(Severity severity, int level, bool predicate);
4287a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov
4387a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov  // On destruction, flush and print the strings accumulated in stream_.
4487a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov  ~Logger();
4587a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov
4687a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov  // Return the stream for this logger.
4787a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov  std::ostream& GetStream() { return stream_; }
4887a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov
4987a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov  // Set verbosity level.  Messages with a level less than or equal to
5087a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov  // this level are printed, others are discarded.  Static, not thread-safe.
5187a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov  static void SetVerbose(int level) { max_level_ = level; }
5287a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov
5387a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov  // Set info and error logging streams.  Static, not thread-safe.
5487a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov  static void SetStreams(std::ostream* info_stream,
5587a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov                         std::ostream* error_stream) {
5687a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov    info_stream_ = info_stream;
5787a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov    error_stream_ = error_stream;
5887a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov  }
5987a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov
6087a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov  // Reset to initial state.
6187a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov  static void Reset();
6287a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov
6387a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov private:
6487a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov  // Message severity, verbosity level, and predicate.
6587a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov  Severity severity_;
6687a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov  int level_;
6787a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov  bool predicate_;
6887a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov
6987a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov  // String stream, accumulates message text.
7087a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov  std::ostringstream stream_;
7187a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov
7287a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov  // Verbosity for INFO messages.  Not thread-safe.
7387a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov  static int max_level_;
7487a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov
7587a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov  // Logging streams.  Not thread-safe.
7687a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov  static std::ostream* info_stream_;
7787a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov  static std::ostream* error_stream_;
7887a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov};
7987a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov
8087a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov}  // namespace relocation_packer
8187a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov
8287a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov// Make logging severities visible globally.
8387a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanovtypedef relocation_packer::Logger::Severity LogSeverity;
8487a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov
8587a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov// LOG(severity) prints a message with the given severity, and aborts if
8687a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov// severity is FATAL.  LOG_IF(severity, predicate) does the same but only if
8787a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov// predicate is true.  INT_MIN is guaranteed to be less than or equal to
8887a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov// any verbosity level.
8918d0e8c11df23709184e55d0fb22e06d057ae898rnk#define LOG(severity)                                                      \
9018d0e8c11df23709184e55d0fb22e06d057ae898rnk  (relocation_packer::Logger(relocation_packer::Logger::severity, INT_MIN, \
9118d0e8c11df23709184e55d0fb22e06d057ae898rnk                             true)                                         \
9218d0e8c11df23709184e55d0fb22e06d057ae898rnk       .GetStream())
9318d0e8c11df23709184e55d0fb22e06d057ae898rnk#define LOG_IF(severity, predicate)                                        \
9418d0e8c11df23709184e55d0fb22e06d057ae898rnk  (relocation_packer::Logger(relocation_packer::Logger::severity, INT_MIN, \
9518d0e8c11df23709184e55d0fb22e06d057ae898rnk                             (predicate))                                  \
9618d0e8c11df23709184e55d0fb22e06d057ae898rnk       .GetStream())
9787a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov
9887a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov// VLOG(level) prints its message as INFO if level is less than or equal to
9987a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov// the current verbosity level.
10018d0e8c11df23709184e55d0fb22e06d057ae898rnk#define VLOG(level)                                                          \
10118d0e8c11df23709184e55d0fb22e06d057ae898rnk  (relocation_packer::Logger(relocation_packer::Logger::INFO, (level), true) \
10218d0e8c11df23709184e55d0fb22e06d057ae898rnk       .GetStream())
10318d0e8c11df23709184e55d0fb22e06d057ae898rnk#define VLOG_IF(level, predicate)                                      \
10418d0e8c11df23709184e55d0fb22e06d057ae898rnk  (relocation_packer::Logger(relocation_packer::Logger::INFO, (level), \
10518d0e8c11df23709184e55d0fb22e06d057ae898rnk                             (predicate))                              \
10618d0e8c11df23709184e55d0fb22e06d057ae898rnk       .GetStream())
10787a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov
10887a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov// CHECK(predicate) fails with a FATAL log message if predicate is false.
10987a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov#define CHECK(predicate) (LOG_IF(FATAL, !(predicate)) \
11087a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov    << __FILE__ << ":" << __LINE__ << ": " \
11187a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov    << __FUNCTION__ << ": CHECK '" #predicate "' failed")
11287a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov
11387a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov// NOTREACHED() always fails with a FATAL log message.
11487a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov#define NOTREACHED(_) (LOG(FATAL) \
11587a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov    << __FILE__ << ":" << __LINE__ << ": " \
11687a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov    << __FUNCTION__ << ": NOTREACHED() hit")
11787a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov
11887a0617ebe7561bf28d3a19fbe192372598969b8Dmitriy Ivanov#endif  // TOOLS_RELOCATION_PACKER_SRC_DEBUG_H_
119