blob: 0270090e5bbc6656c1bebbedaf12d2dd99c7a303 [file] [log] [blame]
// Copyright 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef MINI_CHROMIUM_BASE_LOGGING_H_
#define MINI_CHROMIUM_BASE_LOGGING_H_
#include <assert.h>
#include <errno.h>
#include <limits>
#include <sstream>
#include <string>
#include "base/base_wrapper.h"
#include "base/macros.h"
#include "build/build_config.h"
namespace logging {
typedef int LogSeverity;
const LogSeverity LOG_VERBOSE = -1;
const LogSeverity LOG_INFO = 0;
const LogSeverity LOG_WARNING = 1;
const LogSeverity LOG_ERROR = 2;
const LogSeverity LOG_ERROR_REPORT = 3;
const LogSeverity LOG_FATAL = 4;
const LogSeverity LOG_NUM_SEVERITIES = 5;
#if defined(NDEBUG)
const LogSeverity LOG_DFATAL = LOG_ERROR;
#else
const LogSeverity LOG_DFATAL = LOG_FATAL;
#endif
typedef bool (*LogMessageHandlerFunction)(LogSeverity severity,
const char* file_poath,
int line,
size_t message_start,
const std::string& string);
void SetLogMessageHandler(LogMessageHandlerFunction log_message_handler);
LogMessageHandlerFunction GetLogMessageHandler();
static inline int GetMinLogLevel() {
return LOG_INFO;
}
static inline int GetVlogLevel(const char*) {
return std::numeric_limits<int>::max();
}
#if defined(OS_WIN)
// This is just ::GetLastError, but out-of-line to avoid including windows.h in
// such a widely used place.
unsigned long GetLastSystemErrorCode();
std::string SystemErrorCodeToString(unsigned long error_code);
#elif defined(OS_POSIX)
static inline int GetLastSystemErrorCode() {
return errno;
}
#endif
template<typename t1, typename t2>
std::string* MakeCheckOpString(const t1& v1, const t2& v2, const char* names) {
std::ostringstream ss;
ss << names << " (" << v1 << " vs. " << v2 << ")";
std::string* msg = new std::string(ss.str());
return msg;
}
#define DEFINE_CHECK_OP_IMPL(name, op) \
template <typename t1, typename t2> \
inline std::string* Check ## name ## Impl(const t1& v1, const t2& v2, \
const char* names) { \
if (v1 op v2) { \
return NULL; \
} else { \
return MakeCheckOpString(v1, v2, names); \
} \
} \
inline std::string* Check ## name ## Impl(int v1, int v2, \
const char* names) { \
if (v1 op v2) { \
return NULL; \
} else { \
return MakeCheckOpString(v1, v2, names); \
} \
}
DEFINE_CHECK_OP_IMPL(EQ, ==)
DEFINE_CHECK_OP_IMPL(NE, !=)
DEFINE_CHECK_OP_IMPL(LE, <=)
DEFINE_CHECK_OP_IMPL(LT, <)
DEFINE_CHECK_OP_IMPL(GE, >=)
DEFINE_CHECK_OP_IMPL(GT, >)
#undef DEFINE_CHECK_OP_IMPL
class LogMessage {
public:
LogMessage(const char* function,
const char* file_path,
int line,
LogSeverity severity);
LogMessage(const char* function,
const char* file_path,
int line,
std::string* result);
~LogMessage();
std::ostream& stream() { return stream_; }
private:
void Init(const char* function);
std::ostringstream stream_;
const char* file_path_;
size_t message_start_;
const int line_;
LogSeverity severity_;
DISALLOW_COPY_AND_ASSIGN(LogMessage);
};
class LogMessageVoidify {
public:
LogMessageVoidify() {}
void operator&(const std::ostream&) const {}
};
#if defined(OS_WIN)
class Win32ErrorLogMessage : public LogMessage {
public:
Win32ErrorLogMessage(const char* function,
const char* file_path,
int line,
LogSeverity severity,
unsigned long err);
~Win32ErrorLogMessage();
private:
unsigned long err_;
DISALLOW_COPY_AND_ASSIGN(Win32ErrorLogMessage);
};
#elif defined(OS_POSIX)
class ErrnoLogMessage : public LogMessage {
public:
ErrnoLogMessage(const char* function,
const char* file_path,
int line,
LogSeverity severity,
int err);
~ErrnoLogMessage();
private:
int err_;
DISALLOW_COPY_AND_ASSIGN(ErrnoLogMessage);
};
#endif
} // namespace logging
#if defined(COMPILER_MSVC)
#define FUNCTION_SIGNATURE __FUNCSIG__
#else
#define FUNCTION_SIGNATURE __PRETTY_FUNCTION__
#endif
#define COMPACT_GOOGLE_LOG_EX_INFO(ClassName, ...) \
logging::ClassName(FUNCTION_SIGNATURE, __FILE__, __LINE__, \
logging::LOG_INFO, ## __VA_ARGS__)
#define COMPACT_GOOGLE_LOG_EX_WARNING(ClassName, ...) \
logging::ClassName(FUNCTION_SIGNATURE, __FILE__, __LINE__, \
logging::LOG_WARNING, ## __VA_ARGS__)
#define COMPACT_GOOGLE_LOG_EX_ERROR(ClassName, ...) \
logging::ClassName(FUNCTION_SIGNATURE, __FILE__, __LINE__, \
logging::LOG_ERROR, ## __VA_ARGS__)
#define COMPACT_GOOGLE_LOG_EX_ERROR_REPORT(ClassName, ...) \
logging::ClassName(FUNCTION_SIGNATURE, __FILE__, __LINE__, \
logging::LOG_ERROR_REPORT, ## __VA_ARGS__)
#define COMPACT_GOOGLE_LOG_EX_FATAL(ClassName, ...) \
logging::ClassName(FUNCTION_SIGNATURE, __FILE__, __LINE__, \
logging::LOG_FATAL, ## __VA_ARGS__)
#define COMPACT_GOOGLE_LOG_EX_DFATAL(ClassName, ...) \
logging::ClassName(FUNCTION_SIGNATURE, __FILE__, __LINE__, \
logging::LOG_DFATAL, ## __VA_ARGS__)
#define COMPACT_GOOGLE_LOG_INFO \
COMPACT_GOOGLE_LOG_EX_INFO(LogMessage)
#define COMPACT_GOOGLE_LOG_WARNING \
COMPACT_GOOGLE_LOG_EX_WARNING(LogMessage)
#define COMPACT_GOOGLE_LOG_ERROR \
COMPACT_GOOGLE_LOG_EX_ERROR(LogMessage)
#define COMPACT_GOOGLE_LOG_ERROR_REPORT \
COMPACT_GOOGLE_LOG_EX_ERROR_REPORT(LogMessage)
#define COMPACT_GOOGLE_LOG_FATAL \
COMPACT_GOOGLE_LOG_EX_FATAL(LogMessage)
#define COMPACT_GOOGLE_LOG_DFATAL \
COMPACT_GOOGLE_LOG_EX_DFATAL(LogMessage)
#if defined(OS_WIN)
// wingdi.h defines ERROR 0. We don't want to include windows.h here, and we
// want to allow "LOG(ERROR)", which will expand to LOG_0.
// This will not cause a warning if the RHS text is identical to that in
// wingdi.h (which it is).
#define ERROR 0
#define COMPACT_GOOGLE_LOG_EX_0(ClassName, ...) \
COMPACT_GOOGLE_LOG_EX_ERROR(ClassName , ##__VA_ARGS__)
#define COMPACT_GOOGLE_LOG_0 COMPACT_GOOGLE_LOG_ERROR
namespace logging {
const LogSeverity LOG_0 = LOG_ERROR;
} // namespace logging
#endif // OS_WIN
#define LAZY_STREAM(stream, condition) \
!(condition) ? (void) 0 : ::logging::LogMessageVoidify() & (stream)
#define LOG_IS_ON(severity) \
((::logging::LOG_ ## severity) >= ::logging::GetMinLogLevel())
#define VLOG_IS_ON(verbose_level) \
((verbose_level) <= ::logging::GetVlogLevel(__FILE__))
#define LOG_STREAM(severity) COMPACT_GOOGLE_LOG_ ## severity.stream()
#define VLOG_STREAM(verbose_level) \
logging::LogMessage(FUNCTION_SIGNATURE, __FILE__, __LINE__, \
-verbose_level).stream()
#if defined(OS_WIN)
#define PLOG_STREAM(severity) COMPACT_GOOGLE_LOG_EX_ ## severity( \
Win32ErrorLogMessage, ::logging::GetLastSystemErrorCode()).stream()
#define VPLOG_STREAM(verbose_level) \
logging::Win32ErrorLogMessage(FUNCTION_SIGNATURE, __FILE__, __LINE__, \
-verbose_level, \
::logging::GetLastSystemErrorCode()).stream()
#elif defined(OS_POSIX)
#define PLOG_STREAM(severity) COMPACT_GOOGLE_LOG_EX_ ## severity( \
ErrnoLogMessage, ::logging::GetLastSystemErrorCode()).stream()
#define VPLOG_STREAM(verbose_level) \
logging::ErrnoLogMessage(FUNCTION_SIGNATURE, __FILE__, __LINE__, \
-verbose_level, \
::logging::GetLastSystemErrorCode()).stream()
#endif
#define LOG(severity) LAZY_STREAM(LOG_STREAM(severity), LOG_IS_ON(severity))
#define LOG_IF(severity, condition) \
LAZY_STREAM(LOG_STREAM(severity), LOG_IS_ON(severity) && (condition))
#define LOG_ASSERT(condition) \
LOG_IF(FATAL, !(condition)) << "Assertion failed: " # condition ". "
#define VLOG(verbose_level) \
LAZY_STREAM(VLOG_STREAM(verbose_level), VLOG_IS_ON(verbose_level))
#define VLOG_IF(verbose_level, condition) \
LAZY_STREAM(VLOG_STREAM(verbose_level), \
VLOG_IS_ON(verbose_level) && (condition))
#define PLOG(severity) LAZY_STREAM(PLOG_STREAM(severity), LOG_IS_ON(severity))
#define PLOG_IF(severity, condition) \
LAZY_STREAM(PLOG_STREAM(severity), LOG_IS_ON(severity) && (condition))
#define VPLOG(verbose_level) \
LAZY_STREAM(VPLOG_STREAM(verbose_level), VLOG_IS_ON(verbose_level))
#define VPLOG_IF(verbose_level, condition) \
LAZY_STREAM(VPLOG_STREAM(verbose_level), \
VLOG_IS_ON(verbose_level) && (condition))
#define CHECK(condition) \
LAZY_STREAM(LOG_STREAM(FATAL), !(condition)) \
<< "Check failed: " # condition << ". "
#define PCHECK(condition) \
LAZY_STREAM(PLOG_STREAM(FATAL), !(condition)) \
<< "Check failed: " # condition << ". "
#define CHECK_OP(name, op, val1, val2) \
if (std::string* _result = \
logging::Check ## name ## Impl((val1), (val2), \
# val1 " " # op " " # val2)) \
logging::LogMessage(FUNCTION_SIGNATURE, __FILE__, __LINE__, \
_result).stream()
#define CHECK_EQ(val1, val2) CHECK_OP(EQ, ==, val1, val2)
#define CHECK_NE(val1, val2) CHECK_OP(NE, !=, val1, val2)
#define CHECK_LE(val1, val2) CHECK_OP(LE, <=, val1, val2)
#define CHECK_LT(val1, val2) CHECK_OP(LT, <, val1, val2)
#define CHECK_GE(val1, val2) CHECK_OP(GE, >=, val1, val2)
#define CHECK_GT(val1, val2) CHECK_OP(GT, >, val1, val2)
#if defined(NDEBUG)
#define DLOG_IS_ON(severity) 0
#define DVLOG_IS_ON(verbose_level) 0
#define DCHECK_IS_ON() 0
#else
#define DLOG_IS_ON(severity) LOG_IS_ON(severity)
#define DVLOG_IS_ON(verbose_level) VLOG_IS_ON(verbose_level)
#define DCHECK_IS_ON() 1
#endif
#define DLOG(severity) LAZY_STREAM(LOG_STREAM(severity), DLOG_IS_ON(severity))
#define DLOG_IF(severity, condition) \
LAZY_STREAM(LOG_STREAM(severity), DLOG_IS_ON(severity) && (condition))
#define DLOG_ASSERT(condition) \
DLOG_IF(FATAL, !(condition)) << "Assertion failed: " # condition ". "
#define DVLOG(verbose_level) \
LAZY_STREAM(VLOG_STREAM(verbose_level), DVLOG_IS_ON(verbose_level))
#define DVLOG_IF(verbose_level, condition) \
LAZY_STREAM(VLOG_STREAM(verbose_level), \
DVLOG_IS_ON(verbose_level) && (condition))
#define DPLOG(severity) LAZY_STREAM(PLOG_STREAM(severity), DLOG_IS_ON(severity))
#define DPLOG_IF(severity, condition) \
LAZY_STREAM(PLOG_STREAM(severity), DLOG_IS_ON(severity) && (condition))
#define DVPLOG(verbose_level) \
LAZY_STREAM(VPLOG_STREAM(verbose_level), DVLOG_IS_ON(verbose_level))
#define DVPLOG_IF(verbose_level, condition) \
LAZY_STREAM(VPLOG_STREAM(verbose_level), \
DVLOG_IS_ON(verbose_level) && (condition))
#define DCHECK(condition) \
LAZY_STREAM(LOG_STREAM(FATAL), DCHECK_IS_ON() ? !(condition) : false) \
<< "Check failed: " # condition << ". "
#define DPCHECK(condition) \
LAZY_STREAM(PLOG_STREAM(FATAL), DCHECK_IS_ON() ? !(condition) : false) \
<< "Check failed: " # condition << ". "
#define DCHECK_OP(name, op, val1, val2) \
if (DCHECK_IS_ON()) \
if (std::string* _result = \
logging::Check ## name ## Impl((val1), (val2), \
# val1 " " # op " " # val2)) \
logging::LogMessage(FUNCTION_SIGNATURE, __FILE__, __LINE__, \
_result).stream()
#define DCHECK_EQ(val1, val2) DCHECK_OP(EQ, ==, val1, val2)
#define DCHECK_NE(val1, val2) DCHECK_OP(NE, !=, val1, val2)
#define DCHECK_LE(val1, val2) DCHECK_OP(LE, <=, val1, val2)
#define DCHECK_LT(val1, val2) DCHECK_OP(LT, <, val1, val2)
#define DCHECK_GE(val1, val2) DCHECK_OP(GE, >=, val1, val2)
#define DCHECK_GT(val1, val2) DCHECK_OP(GT, >, val1, val2)
#define NOTREACHED() DCHECK(false)
#undef assert
#define assert(condition) DLOG_ASSERT(condition)
#endif // MINI_CHROMIUM_BASE_LOGGING_H_