| Index: base/logging.h
|
| diff --git a/base/logging.h b/base/logging.h
|
| index 7068339a3a44f49590526c3a26a0c13278e24481..981669a7858c50e994c6d2b38758a9320a7b32a6 100644
|
| --- a/base/logging.h
|
| +++ b/base/logging.h
|
| @@ -261,11 +261,11 @@ const LogSeverity LOG_ERROR_REPORT = 3;
|
| const LogSeverity LOG_FATAL = 4;
|
| const LogSeverity LOG_NUM_SEVERITIES = 5;
|
|
|
| -// LOG_DFATAL_LEVEL is LOG_FATAL in debug mode, ERROR in normal mode
|
| +// LOG_DFATAL is LOG_FATAL in debug mode, ERROR in normal mode
|
| #ifdef NDEBUG
|
| -const LogSeverity LOG_DFATAL_LEVEL = LOG_ERROR;
|
| +const LogSeverity LOG_DFATAL = LOG_ERROR;
|
| #else
|
| -const LogSeverity LOG_DFATAL_LEVEL = LOG_FATAL;
|
| +const LogSeverity LOG_DFATAL = LOG_FATAL;
|
| #endif
|
|
|
| // A few definitions of macros that don't generate much code. These are used
|
| @@ -283,8 +283,7 @@ const LogSeverity LOG_DFATAL_LEVEL = LOG_FATAL;
|
| #define COMPACT_GOOGLE_LOG_EX_FATAL(ClassName, ...) \
|
| logging::ClassName(__FILE__, __LINE__, logging::LOG_FATAL , ##__VA_ARGS__)
|
| #define COMPACT_GOOGLE_LOG_EX_DFATAL(ClassName, ...) \
|
| - logging::ClassName(__FILE__, __LINE__, \
|
| - logging::LOG_DFATAL_LEVEL , ##__VA_ARGS__)
|
| + logging::ClassName(__FILE__, __LINE__, logging::LOG_DFATAL , ##__VA_ARGS__)
|
|
|
| #define COMPACT_GOOGLE_LOG_INFO \
|
| COMPACT_GOOGLE_LOG_EX_INFO(LogMessage)
|
| @@ -308,6 +307,23 @@ const LogSeverity LOG_DFATAL_LEVEL = LOG_FATAL;
|
| #define COMPACT_GOOGLE_LOG_EX_0(ClassName, ...) \
|
| COMPACT_GOOGLE_LOG_EX_ERROR(ClassName , ##__VA_ARGS__)
|
| #define COMPACT_GOOGLE_LOG_0 COMPACT_GOOGLE_LOG_ERROR
|
| +// Needed for LOG_IS_ON(ERROR).
|
| +const LogSeverity LOG_0 = LOG_ERROR;
|
| +
|
| +#define LOG_IS_ON(severity) \
|
| + ((::logging::LOG_ ## severity) >= ::logging::GetMinLogLevel())
|
| +
|
| +// We can't do any caching tricks with VLOG_IS_ON() like the
|
| +// google-glog version since it requires GCC extensions. This means
|
| +// that using the v-logging functions in conjunction with --vmodule
|
| +// may be slow.
|
| +#define VLOG_IS_ON(verboselevel) \
|
| + ((verboselevel) <= ::logging::GetVlogLevel(__FILE__))
|
| +
|
| +// Helper macro which avoids evaluating the arguments to a stream if
|
| +// the condition doesn't hold.
|
| +#define LAZY_STREAM(stream, condition) \
|
| + !(condition) ? (void) 0 : ::logging::LogMessageVoidify() & (stream)
|
|
|
| // We use the preprocessor's merging operator, "##", so that, e.g.,
|
| // LOG(INFO) becomes the token COMPACT_GOOGLE_LOG_INFO. There's some funny
|
| @@ -317,62 +333,75 @@ const LogSeverity LOG_DFATAL_LEVEL = LOG_FATAL;
|
| // impossible to stream something like a string directly to an unnamed
|
| // ostream. We employ a neat hack by calling the stream() member
|
| // function of LogMessage which seems to avoid the problem.
|
| -//
|
| -// We can't do any caching tricks with VLOG_IS_ON() like the
|
| -// google-glog version since it requires GCC extensions. This means
|
| -// that using the v-logging functions in conjunction with --vmodule
|
| -// may be slow.
|
| -#define VLOG_IS_ON(verboselevel) \
|
| - (logging::GetVlogLevel(__FILE__) >= (verboselevel))
|
| +#define LOG_STREAM(severity) COMPACT_GOOGLE_LOG_ ## severity.stream()
|
| +
|
| +#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(severity) COMPACT_GOOGLE_LOG_ ## severity.stream()
|
| #define SYSLOG(severity) LOG(severity)
|
| +#define SYSLOG_IF(severity, condition) LOG_IF(severity, condition)
|
| +
|
| #define VLOG(verboselevel) LOG_IF(INFO, VLOG_IS_ON(verboselevel))
|
| +#define VLOG_IF(verboselevel, condition) \
|
| + LOG_IF(INFO, VLOG_IS_ON(verboselevel) && (condition))
|
|
|
| // TODO(akalin): Add more VLOG variants, e.g. VPLOG.
|
|
|
| -#define LOG_IF(severity, condition) \
|
| - !(condition) ? (void) 0 : logging::LogMessageVoidify() & LOG(severity)
|
| -#define SYSLOG_IF(severity, condition) LOG_IF(severity, condition)
|
| -#define VLOG_IF(verboselevel, condition) \
|
| - LOG_IF(INFO, (condition) && VLOG_IS_ON(verboselevel))
|
| -
|
| #define LOG_ASSERT(condition) \
|
| LOG_IF(FATAL, !(condition)) << "Assert failed: " #condition ". "
|
| #define SYSLOG_ASSERT(condition) \
|
| SYSLOG_IF(FATAL, !(condition)) << "Assert failed: " #condition ". "
|
|
|
| #if defined(OS_WIN)
|
| -#define LOG_GETLASTERROR(severity) \
|
| +#define LOG_GETLASTERROR_STREAM(severity) \
|
| COMPACT_GOOGLE_LOG_EX_ ## severity(Win32ErrorLogMessage, \
|
| ::logging::GetLastSystemErrorCode()).stream()
|
| -#define LOG_GETLASTERROR_MODULE(severity, module) \
|
| +#define LOG_GETLASTERROR(severity) \
|
| + LAZY_STREAM(LOG_GETLASTERROR_STREAM(severity), LOG_IS_ON(severity))
|
| +#define LOG_GETLASTERROR_MODULE_STREAM(severity, module) \
|
| COMPACT_GOOGLE_LOG_EX_ ## severity(Win32ErrorLogMessage, \
|
| ::logging::GetLastSystemErrorCode(), module).stream()
|
| -// PLOG is the usual error logging macro for each platform.
|
| -#define PLOG(severity) LOG_GETLASTERROR(severity)
|
| -#define DPLOG(severity) DLOG_GETLASTERROR(severity)
|
| +#define LOG_GETLASTERROR_MODULE(severity, module) \
|
| + LAZY_STREAM(LOG_GETLASTERROR_STREAM(severity, module), \
|
| + LOG_IS_ON(severity))
|
| +// PLOG_STREAM is used by PLOG, which is the usual error logging macro
|
| +// for each platform.
|
| +#define PLOG_STREAM(severity) LOG_GETLASTERROR_STREAM(severity)
|
| #elif defined(OS_POSIX)
|
| -#define LOG_ERRNO(severity) \
|
| +#define LOG_ERRNO_STREAM(severity) \
|
| COMPACT_GOOGLE_LOG_EX_ ## severity(ErrnoLogMessage, \
|
| ::logging::GetLastSystemErrorCode()).stream()
|
| -// PLOG is the usual error logging macro for each platform.
|
| -#define PLOG(severity) LOG_ERRNO(severity)
|
| -#define DPLOG(severity) DLOG_ERRNO(severity)
|
| +#define LOG_ERRNO(severity) \
|
| + LAZY_STREAM(LOG_ERRNO_STREAM(severity), LOG_IS_ON(severity))
|
| +// PLOG_STREAM is used by PLOG, which is the usual error logging macro
|
| +// for each platform.
|
| +#define PLOG_STREAM(severity) LOG_ERRNO_STREAM(severity)
|
| // TODO(tschmelcher): Should we add OSStatus logging for Mac?
|
| #endif
|
|
|
| +#define PLOG(severity) \
|
| + LAZY_STREAM(PLOG_STREAM(severity), LOG_IS_ON(severity))
|
| +
|
| #define PLOG_IF(severity, condition) \
|
| - !(condition) ? (void) 0 : logging::LogMessageVoidify() & PLOG(severity)
|
| + LAZY_STREAM(PLOG_STREAM(severity), LOG_IS_ON(severity) && (condition))
|
|
|
| // CHECK dies with a fatal error if condition is not true. It is *not*
|
| // controlled by NDEBUG, so the check will be executed regardless of
|
| // compilation mode.
|
| -#define CHECK(condition) \
|
| - LOG_IF(FATAL, !(condition)) << "Check failed: " #condition ". "
|
| +//
|
| +// We make sure CHECK et al. always evaluates their arguments, as
|
| +// doing CHECK(FunctionWithSideEffect()) is a common idiom.
|
| +//
|
| +// TODO(akalin): Fix the problem where if the min log level is >
|
| +// FATAL, CHECK() et al. won't terminate the program.
|
| +#define CHECK(condition) \
|
| + LAZY_STREAM(LOG_STREAM(FATAL), !(condition)) \
|
| + << "Check failed: " #condition ". "
|
|
|
| #define PCHECK(condition) \
|
| - PLOG_IF(FATAL, !(condition)) << "Check failed: " #condition ". "
|
| + LAZY_STREAM(PLOG_STREAM(FATAL), !(condition)) \
|
| + << "Check failed: " #condition ". "
|
|
|
| // A container for a string pointer which can be evaluated to a bool -
|
| // true iff the pointer is NULL.
|
| @@ -413,13 +442,20 @@ extern template std::string* MakeCheckOpString<std::string, std::string>(
|
|
|
| // Helper macro for binary operators.
|
| // Don't use this macro directly in your code, use CHECK_EQ et al below.
|
| -#define CHECK_OP(name, op, val1, val2) \
|
| - if (logging::CheckOpString _result = \
|
| - logging::Check##name##Impl((val1), (val2), #val1 " " #op " " #val2)) \
|
| +//
|
| +// TODO(akalin): Rewrite this so that constructs like if (...)
|
| +// CHECK_EQ(...) else { ... } work properly.
|
| +#define CHECK_OP(name, op, val1, val2) \
|
| + if (logging::CheckOpString _result = \
|
| + logging::Check##name##Impl((val1), (val2), \
|
| + #val1 " " #op " " #val2)) \
|
| logging::LogMessage(__FILE__, __LINE__, _result).stream()
|
|
|
| // Helper functions for string comparisons.
|
| // To avoid bloat, the definitions are in logging.cc.
|
| +//
|
| +// TODO(akalin): Actually have the implementations in logging.cc, or
|
| +// remove these.
|
| #define DECLARE_CHECK_STROP_IMPL(func, expected) \
|
| std::string* Check##func##expected##Impl(const char* s1, \
|
| const char* s2, \
|
| @@ -465,6 +501,9 @@ DECLARE_CHECK_STROP_IMPL(_stricmp, false)
|
| // defined.
|
| #if ( defined(OS_WIN) && defined(OFFICIAL_BUILD)) || \
|
| (!defined(OS_WIN) && defined(NDEBUG) && defined(GOOGLE_CHROME_BUILD))
|
| +// Used by unit tests.
|
| +#define LOGGING_IS_OFFICIAL_BUILD
|
| +
|
| // In order to have optimized code for official builds, remove DLOGs and
|
| // DCHECKs.
|
| #define ENABLE_DLOG 0
|
| @@ -486,44 +525,25 @@ DECLARE_CHECK_STROP_IMPL(_stricmp, false)
|
|
|
| #if ENABLE_DLOG
|
|
|
| -#define DLOG(severity) LOG(severity)
|
| #define DLOG_IF(severity, condition) LOG_IF(severity, condition)
|
| #define DLOG_ASSERT(condition) LOG_ASSERT(condition)
|
| -
|
| -#if defined(OS_WIN)
|
| -#define DLOG_GETLASTERROR(severity) LOG_GETLASTERROR(severity)
|
| -#define DLOG_GETLASTERROR_MODULE(severity, module) \
|
| - LOG_GETLASTERROR_MODULE(severity, module)
|
| -#elif defined(OS_POSIX)
|
| -#define DLOG_ERRNO(severity) LOG_ERRNO(severity)
|
| -#endif
|
| -
|
| #define DPLOG_IF(severity, condition) PLOG_IF(severity, condition)
|
| +#define DVLOG_IF(verboselevel, condition) VLOG_IF(verboselevel, condition)
|
|
|
| #else // ENABLE_DLOG
|
|
|
| -#define DLOG(severity) \
|
| - true ? (void) 0 : logging::LogMessageVoidify() & LOG(severity)
|
| -
|
| -#define DLOG_IF(severity, condition) \
|
| - true ? (void) 0 : logging::LogMessageVoidify() & LOG(severity)
|
| +// If ENABLE_DLOG is off, we want to avoid emitting any references to
|
| +// |condition| (which may reference a variable defined only if NDEBUG
|
| +// is not defined). Contrast this with DCHECK et al., which has
|
| +// different behavior.
|
|
|
| -#define DLOG_ASSERT(condition) \
|
| - true ? (void) 0 : LOG_ASSERT(condition)
|
| -
|
| -#if defined(OS_WIN)
|
| -#define DLOG_GETLASTERROR(severity) \
|
| - true ? (void) 0 : logging::LogMessageVoidify() & LOG_GETLASTERROR(severity)
|
| -#define DLOG_GETLASTERROR_MODULE(severity, module) \
|
| - true ? (void) 0 : logging::LogMessageVoidify() & \
|
| - LOG_GETLASTERROR_MODULE(severity, module)
|
| -#elif defined(OS_POSIX)
|
| -#define DLOG_ERRNO(severity) \
|
| - true ? (void) 0 : logging::LogMessageVoidify() & LOG_ERRNO(severity)
|
| -#endif
|
| +#define DLOG_EAT_STREAM_PARAMETERS \
|
| + true ? (void) 0 : ::logging::LogMessageVoidify() & LOG_STREAM(FATAL)
|
|
|
| -#define DPLOG_IF(severity, condition) \
|
| - true ? (void) 0 : logging::LogMessageVoidify() & PLOG(severity)
|
| +#define DLOG_IF(severity, condition) DLOG_EAT_STREAM_PARAMETERS
|
| +#define DLOG_ASSERT(condition) DLOG_EAT_STREAM_PARAMETERS
|
| +#define DPLOG_IF(severity, condition) DLOG_EAT_STREAM_PARAMETERS
|
| +#define DVLOG_IF(verboselevel, condition) DLOG_EAT_STREAM_PARAMETERS
|
|
|
| #endif // ENABLE_DLOG
|
|
|
| @@ -539,89 +559,84 @@ enum { DEBUG_MODE = ENABLE_DLOG };
|
|
|
| #undef ENABLE_DLOG
|
|
|
| -// Definitions for DCHECK et al.
|
| +#define DLOG_IS_ON(severity) (::logging::DEBUG_MODE && LOG_IS_ON(severity))
|
|
|
| -// This macro can be followed by a sequence of stream parameters in
|
| -// non-debug mode. The DCHECK and friends macros use this so that
|
| -// the expanded expression DCHECK(foo) << "asdf" is still syntactically
|
| -// valid, even though the expression will get optimized away.
|
| -#define DCHECK_EAT_STREAM_PARAMETERS \
|
| - logging::LogMessage(__FILE__, __LINE__).stream()
|
| +#define DLOG(severity) \
|
| + LAZY_STREAM(LOG_STREAM(severity), DLOG_IS_ON(severity))
|
|
|
| -#if ENABLE_DCHECK
|
| +#if defined(OS_WIN)
|
| +#define DLOG_GETLASTERROR(severity) \
|
| + LAZY_STREAM(LOG_GETLASTERROR_STREAM(severity), DLOG_IS_ON(severity))
|
| +#define DLOG_GETLASTERROR_MODULE(severity, module) \
|
| + LAZY_STREAM(LOG_GETLASTERROR_STREAM(severity, module), \
|
| + DLOG_IS_ON(severity))
|
| +#elif defined(OS_POSIX)
|
| +#define DLOG_ERRNO(severity) \
|
| + LAZY_STREAM(LOG_ERRNO_STREAM(severity), DLOG_IS_ON(severity))
|
| +#endif
|
|
|
| -#ifndef NDEBUG
|
| -// On a regular debug build, we want to have DCHECKS enabled.
|
| +#define DPLOG(severity) \
|
| + LAZY_STREAM(PLOG_STREAM(severity), DLOG_IS_ON(severity))
|
|
|
| -#define DCHECK(condition) CHECK(condition)
|
| -#define DPCHECK(condition) PCHECK(condition)
|
| +#define DVLOG(verboselevel) DLOG_IF(INFO, VLOG_IS_ON(verboselevel))
|
|
|
| -// Helper macro for binary operators.
|
| -// Don't use this macro directly in your code, use DCHECK_EQ et al below.
|
| -#define DCHECK_OP(name, op, val1, val2) \
|
| - if (logging::CheckOpString _result = \
|
| - logging::Check##name##Impl((val1), (val2), #val1 " " #op " " #val2)) \
|
| - logging::LogMessage(__FILE__, __LINE__, _result).stream()
|
| +// Definitions for DCHECK et al.
|
|
|
| -// Helper macro for string comparisons.
|
| -// Don't use this macro directly in your code, use CHECK_STREQ et al below.
|
| -#define DCHECK_STROP(func, op, expected, s1, s2) \
|
| - while (CheckOpString _result = \
|
| - logging::Check##func##expected##Impl((s1), (s2), \
|
| - #s1 " " #op " " #s2)) \
|
| - LOG(FATAL) << *_result.str_
|
| +#if ENABLE_DCHECK
|
|
|
| -// String (char*) equality/inequality checks.
|
| -// CASE versions are case-insensitive.
|
| -//
|
| -// Note that "s1" and "s2" may be temporary strings which are destroyed
|
| -// by the compiler at the end of the current "full expression"
|
| -// (e.g. DCHECK_STREQ(Foo().c_str(), Bar().c_str())).
|
| +#if defined(NDEBUG)
|
|
|
| -#define DCHECK_STREQ(s1, s2) DCHECK_STROP(strcmp, ==, true, s1, s2)
|
| -#define DCHECK_STRNE(s1, s2) DCHECK_STROP(strcmp, !=, false, s1, s2)
|
| -#define DCHECK_STRCASEEQ(s1, s2) DCHECK_STROP(_stricmp, ==, true, s1, s2)
|
| -#define DCHECK_STRCASENE(s1, s2) DCHECK_STROP(_stricmp, !=, false, s1, s2)
|
| +// Set to true in InitLogging when we want to enable the dchecks in release.
|
| +extern bool g_enable_dcheck;
|
| +#define DCHECK_IS_ON() (::logging::g_enable_dcheck)
|
| +#define DCHECK_SEVERITY ERROR_REPORT
|
| +const LogSeverity LOG_DCHECK = LOG_ERROR_REPORT;
|
|
|
| -#define DCHECK_INDEX(I,A) DCHECK(I < (sizeof(A)/sizeof(A[0])))
|
| -#define DCHECK_BOUND(B,A) DCHECK(B <= (sizeof(A)/sizeof(A[0])))
|
| +#else // defined(NDEBUG)
|
| +
|
| +// On a regular debug build, we want to have DCHECKS enabled.
|
| +#define DCHECK_IS_ON() (true)
|
| +#define DCHECK_SEVERITY FATAL
|
| +const LogSeverity LOG_DCHECK = LOG_FATAL;
|
|
|
| -#else // NDEBUG
|
| -// On a regular release build we want to be able to enable DCHECKS through the
|
| -// command line.
|
| +#endif // defined(NDEBUG)
|
|
|
| -// Set to true in InitLogging when we want to enable the dchecks in release.
|
| -extern bool g_enable_dcheck;
|
| -#define DCHECK(condition) \
|
| - !logging::g_enable_dcheck ? void (0) : \
|
| - LOG_IF(ERROR_REPORT, !(condition)) << "Check failed: " #condition ". "
|
| +#else // ENABLE_DCHECK
|
|
|
| -#define DPCHECK(condition) \
|
| - !logging::g_enable_dcheck ? void (0) : \
|
| - PLOG_IF(ERROR_REPORT, !(condition)) << "Check failed: " #condition ". "
|
| +#define DCHECK_IS_ON() (false)
|
| +#define DCHECK_SEVERITY FATAL
|
| +const LogSeverity LOG_DCHECK = LOG_FATAL;
|
|
|
| -// Helper macro for binary operators.
|
| -// Don't use this macro directly in your code, use DCHECK_EQ et al below.
|
| -#define DCHECK_OP(name, op, val1, val2) \
|
| - if (logging::g_enable_dcheck) \
|
| - if (logging::CheckOpString _result = \
|
| - logging::Check##name##Impl((val1), (val2), #val1 " " #op " " #val2)) \
|
| - logging::LogMessage(__FILE__, __LINE__, logging::LOG_ERROR_REPORT, \
|
| - _result).stream()
|
| +#endif // ENABLE_DCHECK
|
|
|
| -#define DCHECK_STREQ(str1, str2) \
|
| - while (false) DCHECK_EAT_STREAM_PARAMETERS
|
| +// Unlike CHECK et al., DCHECK et al. *does* evaluate their arguments
|
| +// lazily.
|
|
|
| -#define DCHECK_STRCASEEQ(str1, str2) \
|
| - while (false) DCHECK_EAT_STREAM_PARAMETERS
|
| +// DCHECK et al. also make sure to reference |condition| regardless of
|
| +// whether DCHECKs are enabled; this is so that we don't get unused
|
| +// variable warnings if the only use of a variable is in a DCHECK.
|
| +// This behavior is different from DLOG_IF et al.
|
|
|
| -#define DCHECK_STRNE(str1, str2) \
|
| - while (false) DCHECK_EAT_STREAM_PARAMETERS
|
| +#define DCHECK(condition) \
|
| + !DCHECK_IS_ON() ? (void) 0 : \
|
| + LOG_IF(DCHECK_SEVERITY, !(condition)) \
|
| + << "Check failed: " #condition ". "
|
|
|
| -#define DCHECK_STRCASENE(str1, str2) \
|
| - while (false) DCHECK_EAT_STREAM_PARAMETERS
|
| +#define DPCHECK(condition) \
|
| + !DCHECK_IS_ON() ? (void) 0 : \
|
| + PLOG_IF(DCHECK_SEVERITY, !(condition)) \
|
| + << "Check failed: " #condition ". "
|
|
|
| -#endif // NDEBUG
|
| +// Helper macro for binary operators.
|
| +// Don't use this macro directly in your code, use DCHECK_EQ et al below.
|
| +#define DCHECK_OP(name, op, val1, val2) \
|
| + if (DLOG_IS_ON(DCHECK_SEVERITY)) \
|
| + if (logging::CheckOpString _result = \
|
| + logging::Check##name##Impl((val1), (val2), \
|
| + #val1 " " #op " " #val2)) \
|
| + logging::LogMessage( \
|
| + __FILE__, __LINE__, ::logging::LOG_DCHECK, \
|
| + _result).stream()
|
|
|
| // Equality/Inequality checks - compare two values, and log a LOG_FATAL message
|
| // including the two values when the result is not as expected. The values
|
| @@ -648,49 +663,25 @@ extern bool g_enable_dcheck;
|
| #define DCHECK_GE(val1, val2) DCHECK_OP(GE, >=, val1, val2)
|
| #define DCHECK_GT(val1, val2) DCHECK_OP(GT, > , val1, val2)
|
|
|
| -#else // ENABLE_DCHECK
|
| -
|
| -// In order to avoid variable unused warnings for code that only uses a
|
| -// variable in a CHECK, we make sure to use the macro arguments.
|
| -
|
| -#define DCHECK(condition) \
|
| - while (false && (condition)) DCHECK_EAT_STREAM_PARAMETERS
|
| -
|
| -#define DPCHECK(condition) \
|
| - while (false && (condition)) DCHECK_EAT_STREAM_PARAMETERS
|
| -
|
| -#define DCHECK_EQ(val1, val2) \
|
| - while (false && (val1) == (val2)) DCHECK_EAT_STREAM_PARAMETERS
|
| -
|
| -#define DCHECK_NE(val1, val2) \
|
| - while (false && (val1) == (val2)) DCHECK_EAT_STREAM_PARAMETERS
|
| -
|
| -#define DCHECK_LE(val1, val2) \
|
| - while (false && (val1) == (val2)) DCHECK_EAT_STREAM_PARAMETERS
|
| -
|
| -#define DCHECK_LT(val1, val2) \
|
| - while (false && (val1) == (val2)) DCHECK_EAT_STREAM_PARAMETERS
|
| -
|
| -#define DCHECK_GE(val1, val2) \
|
| - while (false && (val1) == (val2)) DCHECK_EAT_STREAM_PARAMETERS
|
| -
|
| -#define DCHECK_GT(val1, val2) \
|
| - while (false && (val1) == (val2)) DCHECK_EAT_STREAM_PARAMETERS
|
| -
|
| -#define DCHECK_STREQ(str1, str2) \
|
| - while (false && (str1) == (str2)) DCHECK_EAT_STREAM_PARAMETERS
|
| -
|
| -#define DCHECK_STRCASEEQ(str1, str2) \
|
| - while (false && (str1) == (str2)) DCHECK_EAT_STREAM_PARAMETERS
|
| +// Helper macro for string comparisons.
|
| +// Don't use this macro directly in your code, use DCHECK_STREQ et al below.
|
| +#define DCHECK_STROP(func, op, expected, s1, s2) \
|
| + if (DCHECK_IS_ON()) CHECK_STROP(func, op, expected, s1, s2)
|
|
|
| -#define DCHECK_STRNE(str1, str2) \
|
| - while (false && (str1) == (str2)) DCHECK_EAT_STREAM_PARAMETERS
|
| +// String (char*) equality/inequality checks.
|
| +// CASE versions are case-insensitive.
|
| +//
|
| +// Note that "s1" and "s2" may be temporary strings which are destroyed
|
| +// by the compiler at the end of the current "full expression"
|
| +// (e.g. DCHECK_STREQ(Foo().c_str(), Bar().c_str())).
|
|
|
| -#define DCHECK_STRCASENE(str1, str2) \
|
| - while (false && (str1) == (str2)) DCHECK_EAT_STREAM_PARAMETERS
|
| +#define DCHECK_STREQ(s1, s2) DCHECK_STROP(strcmp, ==, true, s1, s2)
|
| +#define DCHECK_STRNE(s1, s2) DCHECK_STROP(strcmp, !=, false, s1, s2)
|
| +#define DCHECK_STRCASEEQ(s1, s2) DCHECK_STROP(_stricmp, ==, true, s1, s2)
|
| +#define DCHECK_STRCASENE(s1, s2) DCHECK_STROP(_stricmp, !=, false, s1, s2)
|
|
|
| -#endif // ENABLE_DCHECK
|
| -#undef ENABLE_DCHECK
|
| +#define DCHECK_INDEX(I,A) DCHECK(I < (sizeof(A)/sizeof(A[0])))
|
| +#define DCHECK_BOUND(B,A) DCHECK(B <= (sizeof(A)/sizeof(A[0])))
|
|
|
| // Helper functions for CHECK_OP macro.
|
| // The (int, int) specialization works around the issue that the compiler
|
|
|