| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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 #ifndef BASE_LOGGING_H_ | 5 #ifndef BASE_LOGGING_H_ |
| 6 #define BASE_LOGGING_H_ | 6 #define BASE_LOGGING_H_ |
| 7 #pragma once | 7 #pragma once |
| 8 | 8 |
| 9 #include <string> | 9 #include <string> |
| 10 #include <cstring> | 10 #include <cstring> |
| (...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 254 void SetLogMessageHandler(LogMessageHandlerFunction handler); | 254 void SetLogMessageHandler(LogMessageHandlerFunction handler); |
| 255 | 255 |
| 256 typedef int LogSeverity; | 256 typedef int LogSeverity; |
| 257 const LogSeverity LOG_INFO = 0; | 257 const LogSeverity LOG_INFO = 0; |
| 258 const LogSeverity LOG_WARNING = 1; | 258 const LogSeverity LOG_WARNING = 1; |
| 259 const LogSeverity LOG_ERROR = 2; | 259 const LogSeverity LOG_ERROR = 2; |
| 260 const LogSeverity LOG_ERROR_REPORT = 3; | 260 const LogSeverity LOG_ERROR_REPORT = 3; |
| 261 const LogSeverity LOG_FATAL = 4; | 261 const LogSeverity LOG_FATAL = 4; |
| 262 const LogSeverity LOG_NUM_SEVERITIES = 5; | 262 const LogSeverity LOG_NUM_SEVERITIES = 5; |
| 263 | 263 |
| 264 // LOG_DFATAL_LEVEL is LOG_FATAL in debug mode, ERROR in normal mode | 264 // LOG_DFATAL is LOG_FATAL in debug mode, ERROR in normal mode |
| 265 #ifdef NDEBUG | 265 #ifdef NDEBUG |
| 266 const LogSeverity LOG_DFATAL_LEVEL = LOG_ERROR; | 266 const LogSeverity LOG_DFATAL = LOG_ERROR; |
| 267 #else | 267 #else |
| 268 const LogSeverity LOG_DFATAL_LEVEL = LOG_FATAL; | 268 const LogSeverity LOG_DFATAL = LOG_FATAL; |
| 269 #endif | 269 #endif |
| 270 | 270 |
| 271 // A few definitions of macros that don't generate much code. These are used | 271 // A few definitions of macros that don't generate much code. These are used |
| 272 // by LOG() and LOG_IF, etc. Since these are used all over our code, it's | 272 // by LOG() and LOG_IF, etc. Since these are used all over our code, it's |
| 273 // better to have compact code for these operations. | 273 // better to have compact code for these operations. |
| 274 #define COMPACT_GOOGLE_LOG_EX_INFO(ClassName, ...) \ | 274 #define COMPACT_GOOGLE_LOG_EX_INFO(ClassName, ...) \ |
| 275 logging::ClassName(__FILE__, __LINE__, logging::LOG_INFO , ##__VA_ARGS__) | 275 logging::ClassName(__FILE__, __LINE__, logging::LOG_INFO , ##__VA_ARGS__) |
| 276 #define COMPACT_GOOGLE_LOG_EX_WARNING(ClassName, ...) \ | 276 #define COMPACT_GOOGLE_LOG_EX_WARNING(ClassName, ...) \ |
| 277 logging::ClassName(__FILE__, __LINE__, logging::LOG_WARNING , ##__VA_ARGS__) | 277 logging::ClassName(__FILE__, __LINE__, logging::LOG_WARNING , ##__VA_ARGS__) |
| 278 #define COMPACT_GOOGLE_LOG_EX_ERROR(ClassName, ...) \ | 278 #define COMPACT_GOOGLE_LOG_EX_ERROR(ClassName, ...) \ |
| 279 logging::ClassName(__FILE__, __LINE__, logging::LOG_ERROR , ##__VA_ARGS__) | 279 logging::ClassName(__FILE__, __LINE__, logging::LOG_ERROR , ##__VA_ARGS__) |
| 280 #define COMPACT_GOOGLE_LOG_EX_ERROR_REPORT(ClassName, ...) \ | 280 #define COMPACT_GOOGLE_LOG_EX_ERROR_REPORT(ClassName, ...) \ |
| 281 logging::ClassName(__FILE__, __LINE__, \ | 281 logging::ClassName(__FILE__, __LINE__, \ |
| 282 logging::LOG_ERROR_REPORT , ##__VA_ARGS__) | 282 logging::LOG_ERROR_REPORT , ##__VA_ARGS__) |
| 283 #define COMPACT_GOOGLE_LOG_EX_FATAL(ClassName, ...) \ | 283 #define COMPACT_GOOGLE_LOG_EX_FATAL(ClassName, ...) \ |
| 284 logging::ClassName(__FILE__, __LINE__, logging::LOG_FATAL , ##__VA_ARGS__) | 284 logging::ClassName(__FILE__, __LINE__, logging::LOG_FATAL , ##__VA_ARGS__) |
| 285 #define COMPACT_GOOGLE_LOG_EX_DFATAL(ClassName, ...) \ | 285 #define COMPACT_GOOGLE_LOG_EX_DFATAL(ClassName, ...) \ |
| 286 logging::ClassName(__FILE__, __LINE__, \ | 286 logging::ClassName(__FILE__, __LINE__, logging::LOG_DFATAL , ##__VA_ARGS__) |
| 287 logging::LOG_DFATAL_LEVEL , ##__VA_ARGS__) | |
| 288 | 287 |
| 289 #define COMPACT_GOOGLE_LOG_INFO \ | 288 #define COMPACT_GOOGLE_LOG_INFO \ |
| 290 COMPACT_GOOGLE_LOG_EX_INFO(LogMessage) | 289 COMPACT_GOOGLE_LOG_EX_INFO(LogMessage) |
| 291 #define COMPACT_GOOGLE_LOG_WARNING \ | 290 #define COMPACT_GOOGLE_LOG_WARNING \ |
| 292 COMPACT_GOOGLE_LOG_EX_WARNING(LogMessage) | 291 COMPACT_GOOGLE_LOG_EX_WARNING(LogMessage) |
| 293 #define COMPACT_GOOGLE_LOG_ERROR \ | 292 #define COMPACT_GOOGLE_LOG_ERROR \ |
| 294 COMPACT_GOOGLE_LOG_EX_ERROR(LogMessage) | 293 COMPACT_GOOGLE_LOG_EX_ERROR(LogMessage) |
| 295 #define COMPACT_GOOGLE_LOG_ERROR_REPORT \ | 294 #define COMPACT_GOOGLE_LOG_ERROR_REPORT \ |
| 296 COMPACT_GOOGLE_LOG_EX_ERROR_REPORT(LogMessage) | 295 COMPACT_GOOGLE_LOG_EX_ERROR_REPORT(LogMessage) |
| 297 #define COMPACT_GOOGLE_LOG_FATAL \ | 296 #define COMPACT_GOOGLE_LOG_FATAL \ |
| 298 COMPACT_GOOGLE_LOG_EX_FATAL(LogMessage) | 297 COMPACT_GOOGLE_LOG_EX_FATAL(LogMessage) |
| 299 #define COMPACT_GOOGLE_LOG_DFATAL \ | 298 #define COMPACT_GOOGLE_LOG_DFATAL \ |
| 300 COMPACT_GOOGLE_LOG_EX_DFATAL(LogMessage) | 299 COMPACT_GOOGLE_LOG_EX_DFATAL(LogMessage) |
| 301 | 300 |
| 302 // wingdi.h defines ERROR to be 0. When we call LOG(ERROR), it gets | 301 // wingdi.h defines ERROR to be 0. When we call LOG(ERROR), it gets |
| 303 // substituted with 0, and it expands to COMPACT_GOOGLE_LOG_0. To allow us | 302 // substituted with 0, and it expands to COMPACT_GOOGLE_LOG_0. To allow us |
| 304 // to keep using this syntax, we define this macro to do the same thing | 303 // to keep using this syntax, we define this macro to do the same thing |
| 305 // as COMPACT_GOOGLE_LOG_ERROR, and also define ERROR the same way that | 304 // as COMPACT_GOOGLE_LOG_ERROR, and also define ERROR the same way that |
| 306 // the Windows SDK does for consistency. | 305 // the Windows SDK does for consistency. |
| 307 #define ERROR 0 | 306 #define ERROR 0 |
| 308 #define COMPACT_GOOGLE_LOG_EX_0(ClassName, ...) \ | 307 #define COMPACT_GOOGLE_LOG_EX_0(ClassName, ...) \ |
| 309 COMPACT_GOOGLE_LOG_EX_ERROR(ClassName , ##__VA_ARGS__) | 308 COMPACT_GOOGLE_LOG_EX_ERROR(ClassName , ##__VA_ARGS__) |
| 310 #define COMPACT_GOOGLE_LOG_0 COMPACT_GOOGLE_LOG_ERROR | 309 #define COMPACT_GOOGLE_LOG_0 COMPACT_GOOGLE_LOG_ERROR |
| 310 // Needed for LOG_IS_ON(ERROR). |
| 311 const LogSeverity LOG_0 = LOG_ERROR; |
| 312 |
| 313 #define LOG_IS_ON(severity) \ |
| 314 ((::logging::LOG_ ## severity) >= ::logging::GetMinLogLevel()) |
| 315 |
| 316 // We can't do any caching tricks with VLOG_IS_ON() like the |
| 317 // google-glog version since it requires GCC extensions. This means |
| 318 // that using the v-logging functions in conjunction with --vmodule |
| 319 // may be slow. |
| 320 #define VLOG_IS_ON(verboselevel) \ |
| 321 ((verboselevel) <= ::logging::GetVlogLevel(__FILE__)) |
| 322 |
| 323 // Helper macro which avoids evaluating the arguments to a stream if |
| 324 // the condition doesn't hold. |
| 325 #define LAZY_STREAM(stream, condition) \ |
| 326 !(condition) ? (void) 0 : ::logging::LogMessageVoidify() & (stream) |
| 311 | 327 |
| 312 // We use the preprocessor's merging operator, "##", so that, e.g., | 328 // We use the preprocessor's merging operator, "##", so that, e.g., |
| 313 // LOG(INFO) becomes the token COMPACT_GOOGLE_LOG_INFO. There's some funny | 329 // LOG(INFO) becomes the token COMPACT_GOOGLE_LOG_INFO. There's some funny |
| 314 // subtle difference between ostream member streaming functions (e.g., | 330 // subtle difference between ostream member streaming functions (e.g., |
| 315 // ostream::operator<<(int) and ostream non-member streaming functions | 331 // ostream::operator<<(int) and ostream non-member streaming functions |
| 316 // (e.g., ::operator<<(ostream&, string&): it turns out that it's | 332 // (e.g., ::operator<<(ostream&, string&): it turns out that it's |
| 317 // impossible to stream something like a string directly to an unnamed | 333 // impossible to stream something like a string directly to an unnamed |
| 318 // ostream. We employ a neat hack by calling the stream() member | 334 // ostream. We employ a neat hack by calling the stream() member |
| 319 // function of LogMessage which seems to avoid the problem. | 335 // function of LogMessage which seems to avoid the problem. |
| 320 // | 336 #define LOG_STREAM(severity) COMPACT_GOOGLE_LOG_ ## severity.stream() |
| 321 // We can't do any caching tricks with VLOG_IS_ON() like the | |
| 322 // google-glog version since it requires GCC extensions. This means | |
| 323 // that using the v-logging functions in conjunction with --vmodule | |
| 324 // may be slow. | |
| 325 #define VLOG_IS_ON(verboselevel) \ | |
| 326 (logging::GetVlogLevel(__FILE__) >= (verboselevel)) | |
| 327 | 337 |
| 328 #define LOG(severity) COMPACT_GOOGLE_LOG_ ## severity.stream() | 338 #define LOG(severity) LAZY_STREAM(LOG_STREAM(severity), LOG_IS_ON(severity)) |
| 339 #define LOG_IF(severity, condition) \ |
| 340 LAZY_STREAM(LOG_STREAM(severity), LOG_IS_ON(severity) && (condition)) |
| 341 |
| 329 #define SYSLOG(severity) LOG(severity) | 342 #define SYSLOG(severity) LOG(severity) |
| 343 #define SYSLOG_IF(severity, condition) LOG_IF(severity, condition) |
| 344 |
| 330 #define VLOG(verboselevel) LOG_IF(INFO, VLOG_IS_ON(verboselevel)) | 345 #define VLOG(verboselevel) LOG_IF(INFO, VLOG_IS_ON(verboselevel)) |
| 346 #define VLOG_IF(verboselevel, condition) \ |
| 347 LOG_IF(INFO, VLOG_IS_ON(verboselevel) && (condition)) |
| 331 | 348 |
| 332 // TODO(akalin): Add more VLOG variants, e.g. VPLOG. | 349 // TODO(akalin): Add more VLOG variants, e.g. VPLOG. |
| 333 | 350 |
| 334 #define LOG_IF(severity, condition) \ | |
| 335 !(condition) ? (void) 0 : logging::LogMessageVoidify() & LOG(severity) | |
| 336 #define SYSLOG_IF(severity, condition) LOG_IF(severity, condition) | |
| 337 #define VLOG_IF(verboselevel, condition) \ | |
| 338 LOG_IF(INFO, (condition) && VLOG_IS_ON(verboselevel)) | |
| 339 | |
| 340 #define LOG_ASSERT(condition) \ | 351 #define LOG_ASSERT(condition) \ |
| 341 LOG_IF(FATAL, !(condition)) << "Assert failed: " #condition ". " | 352 LOG_IF(FATAL, !(condition)) << "Assert failed: " #condition ". " |
| 342 #define SYSLOG_ASSERT(condition) \ | 353 #define SYSLOG_ASSERT(condition) \ |
| 343 SYSLOG_IF(FATAL, !(condition)) << "Assert failed: " #condition ". " | 354 SYSLOG_IF(FATAL, !(condition)) << "Assert failed: " #condition ". " |
| 344 | 355 |
| 345 #if defined(OS_WIN) | 356 #if defined(OS_WIN) |
| 346 #define LOG_GETLASTERROR(severity) \ | 357 #define LOG_GETLASTERROR_STREAM(severity) \ |
| 347 COMPACT_GOOGLE_LOG_EX_ ## severity(Win32ErrorLogMessage, \ | 358 COMPACT_GOOGLE_LOG_EX_ ## severity(Win32ErrorLogMessage, \ |
| 348 ::logging::GetLastSystemErrorCode()).stream() | 359 ::logging::GetLastSystemErrorCode()).stream() |
| 349 #define LOG_GETLASTERROR_MODULE(severity, module) \ | 360 #define LOG_GETLASTERROR(severity) \ |
| 361 LAZY_STREAM(LOG_GETLASTERROR_STREAM(severity), LOG_IS_ON(severity)) |
| 362 #define LOG_GETLASTERROR_MODULE_STREAM(severity, module) \ |
| 350 COMPACT_GOOGLE_LOG_EX_ ## severity(Win32ErrorLogMessage, \ | 363 COMPACT_GOOGLE_LOG_EX_ ## severity(Win32ErrorLogMessage, \ |
| 351 ::logging::GetLastSystemErrorCode(), module).stream() | 364 ::logging::GetLastSystemErrorCode(), module).stream() |
| 352 // PLOG is the usual error logging macro for each platform. | 365 #define LOG_GETLASTERROR_MODULE(severity, module) \ |
| 353 #define PLOG(severity) LOG_GETLASTERROR(severity) | 366 LAZY_STREAM(LOG_GETLASTERROR_STREAM(severity, module), \ |
| 354 #define DPLOG(severity) DLOG_GETLASTERROR(severity) | 367 LOG_IS_ON(severity)) |
| 368 // PLOG_STREAM is used by PLOG, which is the usual error logging macro |
| 369 // for each platform. |
| 370 #define PLOG_STREAM(severity) LOG_GETLASTERROR_STREAM(severity) |
| 355 #elif defined(OS_POSIX) | 371 #elif defined(OS_POSIX) |
| 356 #define LOG_ERRNO(severity) \ | 372 #define LOG_ERRNO_STREAM(severity) \ |
| 357 COMPACT_GOOGLE_LOG_EX_ ## severity(ErrnoLogMessage, \ | 373 COMPACT_GOOGLE_LOG_EX_ ## severity(ErrnoLogMessage, \ |
| 358 ::logging::GetLastSystemErrorCode()).stream() | 374 ::logging::GetLastSystemErrorCode()).stream() |
| 359 // PLOG is the usual error logging macro for each platform. | 375 #define LOG_ERRNO(severity) \ |
| 360 #define PLOG(severity) LOG_ERRNO(severity) | 376 LAZY_STREAM(LOG_ERRNO_STREAM(severity), LOG_IS_ON(severity)) |
| 361 #define DPLOG(severity) DLOG_ERRNO(severity) | 377 // PLOG_STREAM is used by PLOG, which is the usual error logging macro |
| 378 // for each platform. |
| 379 #define PLOG_STREAM(severity) LOG_ERRNO_STREAM(severity) |
| 362 // TODO(tschmelcher): Should we add OSStatus logging for Mac? | 380 // TODO(tschmelcher): Should we add OSStatus logging for Mac? |
| 363 #endif | 381 #endif |
| 364 | 382 |
| 383 #define PLOG(severity) \ |
| 384 LAZY_STREAM(PLOG_STREAM(severity), LOG_IS_ON(severity)) |
| 385 |
| 365 #define PLOG_IF(severity, condition) \ | 386 #define PLOG_IF(severity, condition) \ |
| 366 !(condition) ? (void) 0 : logging::LogMessageVoidify() & PLOG(severity) | 387 LAZY_STREAM(PLOG_STREAM(severity), LOG_IS_ON(severity) && (condition)) |
| 367 | 388 |
| 368 // CHECK dies with a fatal error if condition is not true. It is *not* | 389 // CHECK dies with a fatal error if condition is not true. It is *not* |
| 369 // controlled by NDEBUG, so the check will be executed regardless of | 390 // controlled by NDEBUG, so the check will be executed regardless of |
| 370 // compilation mode. | 391 // compilation mode. |
| 371 #define CHECK(condition) \ | 392 // |
| 372 LOG_IF(FATAL, !(condition)) << "Check failed: " #condition ". " | 393 // We make sure CHECK et al. always evaluates their arguments, as |
| 394 // doing CHECK(FunctionWithSideEffect()) is a common idiom. |
| 395 // |
| 396 // TODO(akalin): Fix the problem where if the min log level is > |
| 397 // FATAL, CHECK() et al. won't terminate the program. |
| 398 #define CHECK(condition) \ |
| 399 LAZY_STREAM(LOG_STREAM(FATAL), !(condition)) \ |
| 400 << "Check failed: " #condition ". " |
| 373 | 401 |
| 374 #define PCHECK(condition) \ | 402 #define PCHECK(condition) \ |
| 375 PLOG_IF(FATAL, !(condition)) << "Check failed: " #condition ". " | 403 LAZY_STREAM(PLOG_STREAM(FATAL), !(condition)) \ |
| 404 << "Check failed: " #condition ". " |
| 376 | 405 |
| 377 // A container for a string pointer which can be evaluated to a bool - | 406 // A container for a string pointer which can be evaluated to a bool - |
| 378 // true iff the pointer is NULL. | 407 // true iff the pointer is NULL. |
| 379 struct CheckOpString { | 408 struct CheckOpString { |
| 380 CheckOpString(std::string* str) : str_(str) { } | 409 CheckOpString(std::string* str) : str_(str) { } |
| 381 // No destructor: if str_ is non-NULL, we're about to LOG(FATAL), | 410 // No destructor: if str_ is non-NULL, we're about to LOG(FATAL), |
| 382 // so there's no point in cleaning up str_. | 411 // so there's no point in cleaning up str_. |
| 383 operator bool() const { return str_ != NULL; } | 412 operator bool() const { return str_ != NULL; } |
| 384 std::string* str_; | 413 std::string* str_; |
| 385 }; | 414 }; |
| (...skipping 20 matching lines...) Expand all Loading... |
| 406 extern template std::string* MakeCheckOpString<unsigned long, unsigned int>( | 435 extern template std::string* MakeCheckOpString<unsigned long, unsigned int>( |
| 407 const unsigned long&, const unsigned int&, const char* names); | 436 const unsigned long&, const unsigned int&, const char* names); |
| 408 extern template std::string* MakeCheckOpString<unsigned int, unsigned long>( | 437 extern template std::string* MakeCheckOpString<unsigned int, unsigned long>( |
| 409 const unsigned int&, const unsigned long&, const char* names); | 438 const unsigned int&, const unsigned long&, const char* names); |
| 410 extern template std::string* MakeCheckOpString<std::string, std::string>( | 439 extern template std::string* MakeCheckOpString<std::string, std::string>( |
| 411 const std::string&, const std::string&, const char* name); | 440 const std::string&, const std::string&, const char* name); |
| 412 #endif | 441 #endif |
| 413 | 442 |
| 414 // Helper macro for binary operators. | 443 // Helper macro for binary operators. |
| 415 // Don't use this macro directly in your code, use CHECK_EQ et al below. | 444 // Don't use this macro directly in your code, use CHECK_EQ et al below. |
| 416 #define CHECK_OP(name, op, val1, val2) \ | 445 // |
| 417 if (logging::CheckOpString _result = \ | 446 // TODO(akalin): Rewrite this so that constructs like if (...) |
| 418 logging::Check##name##Impl((val1), (val2), #val1 " " #op " " #val2)) \ | 447 // CHECK_EQ(...) else { ... } work properly. |
| 448 #define CHECK_OP(name, op, val1, val2) \ |
| 449 if (logging::CheckOpString _result = \ |
| 450 logging::Check##name##Impl((val1), (val2), \ |
| 451 #val1 " " #op " " #val2)) \ |
| 419 logging::LogMessage(__FILE__, __LINE__, _result).stream() | 452 logging::LogMessage(__FILE__, __LINE__, _result).stream() |
| 420 | 453 |
| 421 // Helper functions for string comparisons. | 454 // Helper functions for string comparisons. |
| 422 // To avoid bloat, the definitions are in logging.cc. | 455 // To avoid bloat, the definitions are in logging.cc. |
| 456 // |
| 457 // TODO(akalin): Actually have the implementations in logging.cc, or |
| 458 // remove these. |
| 423 #define DECLARE_CHECK_STROP_IMPL(func, expected) \ | 459 #define DECLARE_CHECK_STROP_IMPL(func, expected) \ |
| 424 std::string* Check##func##expected##Impl(const char* s1, \ | 460 std::string* Check##func##expected##Impl(const char* s1, \ |
| 425 const char* s2, \ | 461 const char* s2, \ |
| 426 const char* names); | 462 const char* names); |
| 427 DECLARE_CHECK_STROP_IMPL(strcmp, true) | 463 DECLARE_CHECK_STROP_IMPL(strcmp, true) |
| 428 DECLARE_CHECK_STROP_IMPL(strcmp, false) | 464 DECLARE_CHECK_STROP_IMPL(strcmp, false) |
| 429 DECLARE_CHECK_STROP_IMPL(_stricmp, true) | 465 DECLARE_CHECK_STROP_IMPL(_stricmp, true) |
| 430 DECLARE_CHECK_STROP_IMPL(_stricmp, false) | 466 DECLARE_CHECK_STROP_IMPL(_stricmp, false) |
| 431 #undef DECLARE_CHECK_STROP_IMPL | 467 #undef DECLARE_CHECK_STROP_IMPL |
| 432 | 468 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 458 #define CHECK_LE(val1, val2) CHECK_OP(LE, <=, val1, val2) | 494 #define CHECK_LE(val1, val2) CHECK_OP(LE, <=, val1, val2) |
| 459 #define CHECK_LT(val1, val2) CHECK_OP(LT, < , val1, val2) | 495 #define CHECK_LT(val1, val2) CHECK_OP(LT, < , val1, val2) |
| 460 #define CHECK_GE(val1, val2) CHECK_OP(GE, >=, val1, val2) | 496 #define CHECK_GE(val1, val2) CHECK_OP(GE, >=, val1, val2) |
| 461 #define CHECK_GT(val1, val2) CHECK_OP(GT, > , val1, val2) | 497 #define CHECK_GT(val1, val2) CHECK_OP(GT, > , val1, val2) |
| 462 | 498 |
| 463 // http://crbug.com/16512 is open for a real fix for this. For now, Windows | 499 // http://crbug.com/16512 is open for a real fix for this. For now, Windows |
| 464 // uses OFFICIAL_BUILD and other platforms use the branding flag when NDEBUG is | 500 // uses OFFICIAL_BUILD and other platforms use the branding flag when NDEBUG is |
| 465 // defined. | 501 // defined. |
| 466 #if ( defined(OS_WIN) && defined(OFFICIAL_BUILD)) || \ | 502 #if ( defined(OS_WIN) && defined(OFFICIAL_BUILD)) || \ |
| 467 (!defined(OS_WIN) && defined(NDEBUG) && defined(GOOGLE_CHROME_BUILD)) | 503 (!defined(OS_WIN) && defined(NDEBUG) && defined(GOOGLE_CHROME_BUILD)) |
| 504 // Used by unit tests. |
| 505 #define LOGGING_IS_OFFICIAL_BUILD |
| 506 |
| 468 // In order to have optimized code for official builds, remove DLOGs and | 507 // In order to have optimized code for official builds, remove DLOGs and |
| 469 // DCHECKs. | 508 // DCHECKs. |
| 470 #define ENABLE_DLOG 0 | 509 #define ENABLE_DLOG 0 |
| 471 #define ENABLE_DCHECK 0 | 510 #define ENABLE_DCHECK 0 |
| 472 | 511 |
| 473 #elif defined(NDEBUG) | 512 #elif defined(NDEBUG) |
| 474 // Otherwise, if we're a release build, remove DLOGs but not DCHECKs | 513 // Otherwise, if we're a release build, remove DLOGs but not DCHECKs |
| 475 // (since those can still be turned on via a command-line flag). | 514 // (since those can still be turned on via a command-line flag). |
| 476 #define ENABLE_DLOG 0 | 515 #define ENABLE_DLOG 0 |
| 477 #define ENABLE_DCHECK 1 | 516 #define ENABLE_DCHECK 1 |
| 478 | 517 |
| 479 #else | 518 #else |
| 480 // Otherwise, we're a debug build so enable DLOGs and DCHECKs. | 519 // Otherwise, we're a debug build so enable DLOGs and DCHECKs. |
| 481 #define ENABLE_DLOG 1 | 520 #define ENABLE_DLOG 1 |
| 482 #define ENABLE_DCHECK 1 | 521 #define ENABLE_DCHECK 1 |
| 483 #endif | 522 #endif |
| 484 | 523 |
| 485 // Definitions for DLOG et al. | 524 // Definitions for DLOG et al. |
| 486 | 525 |
| 487 #if ENABLE_DLOG | 526 #if ENABLE_DLOG |
| 488 | 527 |
| 489 #define DLOG(severity) LOG(severity) | |
| 490 #define DLOG_IF(severity, condition) LOG_IF(severity, condition) | 528 #define DLOG_IF(severity, condition) LOG_IF(severity, condition) |
| 491 #define DLOG_ASSERT(condition) LOG_ASSERT(condition) | 529 #define DLOG_ASSERT(condition) LOG_ASSERT(condition) |
| 492 | |
| 493 #if defined(OS_WIN) | |
| 494 #define DLOG_GETLASTERROR(severity) LOG_GETLASTERROR(severity) | |
| 495 #define DLOG_GETLASTERROR_MODULE(severity, module) \ | |
| 496 LOG_GETLASTERROR_MODULE(severity, module) | |
| 497 #elif defined(OS_POSIX) | |
| 498 #define DLOG_ERRNO(severity) LOG_ERRNO(severity) | |
| 499 #endif | |
| 500 | |
| 501 #define DPLOG_IF(severity, condition) PLOG_IF(severity, condition) | 530 #define DPLOG_IF(severity, condition) PLOG_IF(severity, condition) |
| 531 #define DVLOG_IF(verboselevel, condition) VLOG_IF(verboselevel, condition) |
| 502 | 532 |
| 503 #else // ENABLE_DLOG | 533 #else // ENABLE_DLOG |
| 504 | 534 |
| 505 #define DLOG(severity) \ | 535 // If ENABLE_DLOG is off, we want to avoid emitting any references to |
| 506 true ? (void) 0 : logging::LogMessageVoidify() & LOG(severity) | 536 // |condition| (which may reference a variable defined only if NDEBUG |
| 537 // is not defined). Contrast this with DCHECK et al., which has |
| 538 // different behavior. |
| 507 | 539 |
| 508 #define DLOG_IF(severity, condition) \ | 540 #define DLOG_EAT_STREAM_PARAMETERS \ |
| 509 true ? (void) 0 : logging::LogMessageVoidify() & LOG(severity) | 541 true ? (void) 0 : ::logging::LogMessageVoidify() & LOG_STREAM(FATAL) |
| 510 | 542 |
| 511 #define DLOG_ASSERT(condition) \ | 543 #define DLOG_IF(severity, condition) DLOG_EAT_STREAM_PARAMETERS |
| 512 true ? (void) 0 : LOG_ASSERT(condition) | 544 #define DLOG_ASSERT(condition) DLOG_EAT_STREAM_PARAMETERS |
| 513 | 545 #define DPLOG_IF(severity, condition) DLOG_EAT_STREAM_PARAMETERS |
| 514 #if defined(OS_WIN) | 546 #define DVLOG_IF(verboselevel, condition) DLOG_EAT_STREAM_PARAMETERS |
| 515 #define DLOG_GETLASTERROR(severity) \ | |
| 516 true ? (void) 0 : logging::LogMessageVoidify() & LOG_GETLASTERROR(severity) | |
| 517 #define DLOG_GETLASTERROR_MODULE(severity, module) \ | |
| 518 true ? (void) 0 : logging::LogMessageVoidify() & \ | |
| 519 LOG_GETLASTERROR_MODULE(severity, module) | |
| 520 #elif defined(OS_POSIX) | |
| 521 #define DLOG_ERRNO(severity) \ | |
| 522 true ? (void) 0 : logging::LogMessageVoidify() & LOG_ERRNO(severity) | |
| 523 #endif | |
| 524 | |
| 525 #define DPLOG_IF(severity, condition) \ | |
| 526 true ? (void) 0 : logging::LogMessageVoidify() & PLOG(severity) | |
| 527 | 547 |
| 528 #endif // ENABLE_DLOG | 548 #endif // ENABLE_DLOG |
| 529 | 549 |
| 530 // DEBUG_MODE is for uses like | 550 // DEBUG_MODE is for uses like |
| 531 // if (DEBUG_MODE) foo.CheckThatFoo(); | 551 // if (DEBUG_MODE) foo.CheckThatFoo(); |
| 532 // instead of | 552 // instead of |
| 533 // #ifndef NDEBUG | 553 // #ifndef NDEBUG |
| 534 // foo.CheckThatFoo(); | 554 // foo.CheckThatFoo(); |
| 535 // #endif | 555 // #endif |
| 536 // | 556 // |
| 537 // We tie its state to ENABLE_DLOG. | 557 // We tie its state to ENABLE_DLOG. |
| 538 enum { DEBUG_MODE = ENABLE_DLOG }; | 558 enum { DEBUG_MODE = ENABLE_DLOG }; |
| 539 | 559 |
| 540 #undef ENABLE_DLOG | 560 #undef ENABLE_DLOG |
| 541 | 561 |
| 562 #define DLOG_IS_ON(severity) (::logging::DEBUG_MODE && LOG_IS_ON(severity)) |
| 563 |
| 564 #define DLOG(severity) \ |
| 565 LAZY_STREAM(LOG_STREAM(severity), DLOG_IS_ON(severity)) |
| 566 |
| 567 #if defined(OS_WIN) |
| 568 #define DLOG_GETLASTERROR(severity) \ |
| 569 LAZY_STREAM(LOG_GETLASTERROR_STREAM(severity), DLOG_IS_ON(severity)) |
| 570 #define DLOG_GETLASTERROR_MODULE(severity, module) \ |
| 571 LAZY_STREAM(LOG_GETLASTERROR_STREAM(severity, module), \ |
| 572 DLOG_IS_ON(severity)) |
| 573 #elif defined(OS_POSIX) |
| 574 #define DLOG_ERRNO(severity) \ |
| 575 LAZY_STREAM(LOG_ERRNO_STREAM(severity), DLOG_IS_ON(severity)) |
| 576 #endif |
| 577 |
| 578 #define DPLOG(severity) \ |
| 579 LAZY_STREAM(PLOG_STREAM(severity), DLOG_IS_ON(severity)) |
| 580 |
| 581 #define DVLOG(verboselevel) DLOG_IF(INFO, VLOG_IS_ON(verboselevel)) |
| 582 |
| 542 // Definitions for DCHECK et al. | 583 // Definitions for DCHECK et al. |
| 543 | 584 |
| 544 // This macro can be followed by a sequence of stream parameters in | |
| 545 // non-debug mode. The DCHECK and friends macros use this so that | |
| 546 // the expanded expression DCHECK(foo) << "asdf" is still syntactically | |
| 547 // valid, even though the expression will get optimized away. | |
| 548 #define DCHECK_EAT_STREAM_PARAMETERS \ | |
| 549 logging::LogMessage(__FILE__, __LINE__).stream() | |
| 550 | |
| 551 #if ENABLE_DCHECK | 585 #if ENABLE_DCHECK |
| 552 | 586 |
| 553 #ifndef NDEBUG | 587 #if defined(NDEBUG) |
| 588 |
| 589 // Set to true in InitLogging when we want to enable the dchecks in release. |
| 590 extern bool g_enable_dcheck; |
| 591 #define DCHECK_IS_ON() (::logging::g_enable_dcheck) |
| 592 #define DCHECK_SEVERITY ERROR_REPORT |
| 593 const LogSeverity LOG_DCHECK = LOG_ERROR_REPORT; |
| 594 |
| 595 #else // defined(NDEBUG) |
| 596 |
| 554 // On a regular debug build, we want to have DCHECKS enabled. | 597 // On a regular debug build, we want to have DCHECKS enabled. |
| 598 #define DCHECK_IS_ON() (true) |
| 599 #define DCHECK_SEVERITY FATAL |
| 600 const LogSeverity LOG_DCHECK = LOG_FATAL; |
| 555 | 601 |
| 556 #define DCHECK(condition) CHECK(condition) | 602 #endif // defined(NDEBUG) |
| 557 #define DPCHECK(condition) PCHECK(condition) | 603 |
| 604 #else // ENABLE_DCHECK |
| 605 |
| 606 #define DCHECK_IS_ON() (false) |
| 607 #define DCHECK_SEVERITY FATAL |
| 608 const LogSeverity LOG_DCHECK = LOG_FATAL; |
| 609 |
| 610 #endif // ENABLE_DCHECK |
| 611 |
| 612 // Unlike CHECK et al., DCHECK et al. *does* evaluate their arguments |
| 613 // lazily. |
| 614 |
| 615 // DCHECK et al. also make sure to reference |condition| regardless of |
| 616 // whether DCHECKs are enabled; this is so that we don't get unused |
| 617 // variable warnings if the only use of a variable is in a DCHECK. |
| 618 // This behavior is different from DLOG_IF et al. |
| 619 |
| 620 #define DCHECK(condition) \ |
| 621 !DCHECK_IS_ON() ? (void) 0 : \ |
| 622 LOG_IF(DCHECK_SEVERITY, !(condition)) \ |
| 623 << "Check failed: " #condition ". " |
| 624 |
| 625 #define DPCHECK(condition) \ |
| 626 !DCHECK_IS_ON() ? (void) 0 : \ |
| 627 PLOG_IF(DCHECK_SEVERITY, !(condition)) \ |
| 628 << "Check failed: " #condition ". " |
| 558 | 629 |
| 559 // Helper macro for binary operators. | 630 // Helper macro for binary operators. |
| 560 // Don't use this macro directly in your code, use DCHECK_EQ et al below. | 631 // Don't use this macro directly in your code, use DCHECK_EQ et al below. |
| 561 #define DCHECK_OP(name, op, val1, val2) \ | 632 #define DCHECK_OP(name, op, val1, val2) \ |
| 562 if (logging::CheckOpString _result = \ | 633 if (DLOG_IS_ON(DCHECK_SEVERITY)) \ |
| 563 logging::Check##name##Impl((val1), (val2), #val1 " " #op " " #val2)) \ | 634 if (logging::CheckOpString _result = \ |
| 564 logging::LogMessage(__FILE__, __LINE__, _result).stream() | 635 logging::Check##name##Impl((val1), (val2), \ |
| 565 | 636 #val1 " " #op " " #val2)) \ |
| 566 // Helper macro for string comparisons. | 637 logging::LogMessage( \ |
| 567 // Don't use this macro directly in your code, use CHECK_STREQ et al below. | 638 __FILE__, __LINE__, ::logging::LOG_DCHECK, \ |
| 568 #define DCHECK_STROP(func, op, expected, s1, s2) \ | 639 _result).stream() |
| 569 while (CheckOpString _result = \ | |
| 570 logging::Check##func##expected##Impl((s1), (s2), \ | |
| 571 #s1 " " #op " " #s2)) \ | |
| 572 LOG(FATAL) << *_result.str_ | |
| 573 | |
| 574 // String (char*) equality/inequality checks. | |
| 575 // CASE versions are case-insensitive. | |
| 576 // | |
| 577 // Note that "s1" and "s2" may be temporary strings which are destroyed | |
| 578 // by the compiler at the end of the current "full expression" | |
| 579 // (e.g. DCHECK_STREQ(Foo().c_str(), Bar().c_str())). | |
| 580 | |
| 581 #define DCHECK_STREQ(s1, s2) DCHECK_STROP(strcmp, ==, true, s1, s2) | |
| 582 #define DCHECK_STRNE(s1, s2) DCHECK_STROP(strcmp, !=, false, s1, s2) | |
| 583 #define DCHECK_STRCASEEQ(s1, s2) DCHECK_STROP(_stricmp, ==, true, s1, s2) | |
| 584 #define DCHECK_STRCASENE(s1, s2) DCHECK_STROP(_stricmp, !=, false, s1, s2) | |
| 585 | |
| 586 #define DCHECK_INDEX(I,A) DCHECK(I < (sizeof(A)/sizeof(A[0]))) | |
| 587 #define DCHECK_BOUND(B,A) DCHECK(B <= (sizeof(A)/sizeof(A[0]))) | |
| 588 | |
| 589 #else // NDEBUG | |
| 590 // On a regular release build we want to be able to enable DCHECKS through the | |
| 591 // command line. | |
| 592 | |
| 593 // Set to true in InitLogging when we want to enable the dchecks in release. | |
| 594 extern bool g_enable_dcheck; | |
| 595 #define DCHECK(condition) \ | |
| 596 !logging::g_enable_dcheck ? void (0) : \ | |
| 597 LOG_IF(ERROR_REPORT, !(condition)) << "Check failed: " #condition ". " | |
| 598 | |
| 599 #define DPCHECK(condition) \ | |
| 600 !logging::g_enable_dcheck ? void (0) : \ | |
| 601 PLOG_IF(ERROR_REPORT, !(condition)) << "Check failed: " #condition ". " | |
| 602 | |
| 603 // Helper macro for binary operators. | |
| 604 // Don't use this macro directly in your code, use DCHECK_EQ et al below. | |
| 605 #define DCHECK_OP(name, op, val1, val2) \ | |
| 606 if (logging::g_enable_dcheck) \ | |
| 607 if (logging::CheckOpString _result = \ | |
| 608 logging::Check##name##Impl((val1), (val2), #val1 " " #op " " #val2)) \ | |
| 609 logging::LogMessage(__FILE__, __LINE__, logging::LOG_ERROR_REPORT, \ | |
| 610 _result).stream() | |
| 611 | |
| 612 #define DCHECK_STREQ(str1, str2) \ | |
| 613 while (false) DCHECK_EAT_STREAM_PARAMETERS | |
| 614 | |
| 615 #define DCHECK_STRCASEEQ(str1, str2) \ | |
| 616 while (false) DCHECK_EAT_STREAM_PARAMETERS | |
| 617 | |
| 618 #define DCHECK_STRNE(str1, str2) \ | |
| 619 while (false) DCHECK_EAT_STREAM_PARAMETERS | |
| 620 | |
| 621 #define DCHECK_STRCASENE(str1, str2) \ | |
| 622 while (false) DCHECK_EAT_STREAM_PARAMETERS | |
| 623 | |
| 624 #endif // NDEBUG | |
| 625 | 640 |
| 626 // Equality/Inequality checks - compare two values, and log a LOG_FATAL message | 641 // Equality/Inequality checks - compare two values, and log a LOG_FATAL message |
| 627 // including the two values when the result is not as expected. The values | 642 // including the two values when the result is not as expected. The values |
| 628 // must have operator<<(ostream, ...) defined. | 643 // must have operator<<(ostream, ...) defined. |
| 629 // | 644 // |
| 630 // You may append to the error message like so: | 645 // You may append to the error message like so: |
| 631 // DCHECK_NE(1, 2) << ": The world must be ending!"; | 646 // DCHECK_NE(1, 2) << ": The world must be ending!"; |
| 632 // | 647 // |
| 633 // We are very careful to ensure that each argument is evaluated exactly | 648 // We are very careful to ensure that each argument is evaluated exactly |
| 634 // once, and that anything which is legal to pass as a function argument is | 649 // once, and that anything which is legal to pass as a function argument is |
| 635 // legal here. In particular, the arguments may be temporary expressions | 650 // legal here. In particular, the arguments may be temporary expressions |
| 636 // which will end up being destroyed at the end of the apparent statement, | 651 // which will end up being destroyed at the end of the apparent statement, |
| 637 // for example: | 652 // for example: |
| 638 // DCHECK_EQ(string("abc")[1], 'b'); | 653 // DCHECK_EQ(string("abc")[1], 'b'); |
| 639 // | 654 // |
| 640 // WARNING: These may not compile correctly if one of the arguments is a pointer | 655 // WARNING: These may not compile correctly if one of the arguments is a pointer |
| 641 // and the other is NULL. To work around this, simply static_cast NULL to the | 656 // and the other is NULL. To work around this, simply static_cast NULL to the |
| 642 // type of the desired pointer. | 657 // type of the desired pointer. |
| 643 | 658 |
| 644 #define DCHECK_EQ(val1, val2) DCHECK_OP(EQ, ==, val1, val2) | 659 #define DCHECK_EQ(val1, val2) DCHECK_OP(EQ, ==, val1, val2) |
| 645 #define DCHECK_NE(val1, val2) DCHECK_OP(NE, !=, val1, val2) | 660 #define DCHECK_NE(val1, val2) DCHECK_OP(NE, !=, val1, val2) |
| 646 #define DCHECK_LE(val1, val2) DCHECK_OP(LE, <=, val1, val2) | 661 #define DCHECK_LE(val1, val2) DCHECK_OP(LE, <=, val1, val2) |
| 647 #define DCHECK_LT(val1, val2) DCHECK_OP(LT, < , val1, val2) | 662 #define DCHECK_LT(val1, val2) DCHECK_OP(LT, < , val1, val2) |
| 648 #define DCHECK_GE(val1, val2) DCHECK_OP(GE, >=, val1, val2) | 663 #define DCHECK_GE(val1, val2) DCHECK_OP(GE, >=, val1, val2) |
| 649 #define DCHECK_GT(val1, val2) DCHECK_OP(GT, > , val1, val2) | 664 #define DCHECK_GT(val1, val2) DCHECK_OP(GT, > , val1, val2) |
| 650 | 665 |
| 651 #else // ENABLE_DCHECK | 666 // Helper macro for string comparisons. |
| 667 // Don't use this macro directly in your code, use DCHECK_STREQ et al below. |
| 668 #define DCHECK_STROP(func, op, expected, s1, s2) \ |
| 669 if (DCHECK_IS_ON()) CHECK_STROP(func, op, expected, s1, s2) |
| 652 | 670 |
| 653 // In order to avoid variable unused warnings for code that only uses a | 671 // String (char*) equality/inequality checks. |
| 654 // variable in a CHECK, we make sure to use the macro arguments. | 672 // CASE versions are case-insensitive. |
| 673 // |
| 674 // Note that "s1" and "s2" may be temporary strings which are destroyed |
| 675 // by the compiler at the end of the current "full expression" |
| 676 // (e.g. DCHECK_STREQ(Foo().c_str(), Bar().c_str())). |
| 655 | 677 |
| 656 #define DCHECK(condition) \ | 678 #define DCHECK_STREQ(s1, s2) DCHECK_STROP(strcmp, ==, true, s1, s2) |
| 657 while (false && (condition)) DCHECK_EAT_STREAM_PARAMETERS | 679 #define DCHECK_STRNE(s1, s2) DCHECK_STROP(strcmp, !=, false, s1, s2) |
| 680 #define DCHECK_STRCASEEQ(s1, s2) DCHECK_STROP(_stricmp, ==, true, s1, s2) |
| 681 #define DCHECK_STRCASENE(s1, s2) DCHECK_STROP(_stricmp, !=, false, s1, s2) |
| 658 | 682 |
| 659 #define DPCHECK(condition) \ | 683 #define DCHECK_INDEX(I,A) DCHECK(I < (sizeof(A)/sizeof(A[0]))) |
| 660 while (false && (condition)) DCHECK_EAT_STREAM_PARAMETERS | 684 #define DCHECK_BOUND(B,A) DCHECK(B <= (sizeof(A)/sizeof(A[0]))) |
| 661 | |
| 662 #define DCHECK_EQ(val1, val2) \ | |
| 663 while (false && (val1) == (val2)) DCHECK_EAT_STREAM_PARAMETERS | |
| 664 | |
| 665 #define DCHECK_NE(val1, val2) \ | |
| 666 while (false && (val1) == (val2)) DCHECK_EAT_STREAM_PARAMETERS | |
| 667 | |
| 668 #define DCHECK_LE(val1, val2) \ | |
| 669 while (false && (val1) == (val2)) DCHECK_EAT_STREAM_PARAMETERS | |
| 670 | |
| 671 #define DCHECK_LT(val1, val2) \ | |
| 672 while (false && (val1) == (val2)) DCHECK_EAT_STREAM_PARAMETERS | |
| 673 | |
| 674 #define DCHECK_GE(val1, val2) \ | |
| 675 while (false && (val1) == (val2)) DCHECK_EAT_STREAM_PARAMETERS | |
| 676 | |
| 677 #define DCHECK_GT(val1, val2) \ | |
| 678 while (false && (val1) == (val2)) DCHECK_EAT_STREAM_PARAMETERS | |
| 679 | |
| 680 #define DCHECK_STREQ(str1, str2) \ | |
| 681 while (false && (str1) == (str2)) DCHECK_EAT_STREAM_PARAMETERS | |
| 682 | |
| 683 #define DCHECK_STRCASEEQ(str1, str2) \ | |
| 684 while (false && (str1) == (str2)) DCHECK_EAT_STREAM_PARAMETERS | |
| 685 | |
| 686 #define DCHECK_STRNE(str1, str2) \ | |
| 687 while (false && (str1) == (str2)) DCHECK_EAT_STREAM_PARAMETERS | |
| 688 | |
| 689 #define DCHECK_STRCASENE(str1, str2) \ | |
| 690 while (false && (str1) == (str2)) DCHECK_EAT_STREAM_PARAMETERS | |
| 691 | |
| 692 #endif // ENABLE_DCHECK | |
| 693 #undef ENABLE_DCHECK | |
| 694 | 685 |
| 695 // Helper functions for CHECK_OP macro. | 686 // Helper functions for CHECK_OP macro. |
| 696 // The (int, int) specialization works around the issue that the compiler | 687 // The (int, int) specialization works around the issue that the compiler |
| 697 // will not instantiate the template version of the function on values of | 688 // will not instantiate the template version of the function on values of |
| 698 // unnamed enum type - see comment below. | 689 // unnamed enum type - see comment below. |
| 699 #define DEFINE_CHECK_OP_IMPL(name, op) \ | 690 #define DEFINE_CHECK_OP_IMPL(name, op) \ |
| 700 template <class t1, class t2> \ | 691 template <class t1, class t2> \ |
| 701 inline std::string* Check##name##Impl(const t1& v1, const t2& v2, \ | 692 inline std::string* Check##name##Impl(const t1& v1, const t2& v2, \ |
| 702 const char* names) { \ | 693 const char* names) { \ |
| 703 if (v1 op v2) return NULL; \ | 694 if (v1 op v2) return NULL; \ |
| (...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 936 #elif NOTIMPLEMENTED_POLICY == 4 | 927 #elif NOTIMPLEMENTED_POLICY == 4 |
| 937 #define NOTIMPLEMENTED() LOG(ERROR) << NOTIMPLEMENTED_MSG | 928 #define NOTIMPLEMENTED() LOG(ERROR) << NOTIMPLEMENTED_MSG |
| 938 #elif NOTIMPLEMENTED_POLICY == 5 | 929 #elif NOTIMPLEMENTED_POLICY == 5 |
| 939 #define NOTIMPLEMENTED() do {\ | 930 #define NOTIMPLEMENTED() do {\ |
| 940 static int count = 0;\ | 931 static int count = 0;\ |
| 941 LOG_IF(ERROR, 0 == count++) << NOTIMPLEMENTED_MSG;\ | 932 LOG_IF(ERROR, 0 == count++) << NOTIMPLEMENTED_MSG;\ |
| 942 } while(0) | 933 } while(0) |
| 943 #endif | 934 #endif |
| 944 | 935 |
| 945 #endif // BASE_LOGGING_H_ | 936 #endif // BASE_LOGGING_H_ |
| OLD | NEW |