Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 | 7 |
| 8 #include <cassert> | 8 #include <cassert> |
| 9 #include <string> | 9 #include <string> |
| 10 #include <cstring> | 10 #include <cstring> |
| (...skipping 462 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 473 #define CHECK(condition) \ | 473 #define CHECK(condition) \ |
| 474 LAZY_STREAM(LOG_STREAM(FATAL), !(condition)) \ | 474 LAZY_STREAM(LOG_STREAM(FATAL), !(condition)) \ |
| 475 << "Check failed: " #condition ". " | 475 << "Check failed: " #condition ". " |
| 476 | 476 |
| 477 #define PCHECK(condition) \ | 477 #define PCHECK(condition) \ |
| 478 LAZY_STREAM(PLOG_STREAM(FATAL), !(condition)) \ | 478 LAZY_STREAM(PLOG_STREAM(FATAL), !(condition)) \ |
| 479 << "Check failed: " #condition ". " | 479 << "Check failed: " #condition ". " |
| 480 | 480 |
| 481 #endif // _PREFAST_ | 481 #endif // _PREFAST_ |
| 482 | 482 |
| 483 // Captures the result of a CHECK_EQ (for example) and facilitates testing as a | |
| 484 // boolean. | |
| 485 class CheckOpResult { | |
| 486 public: | |
| 487 // |message| must be null if and only if the check failed. | |
| 488 CheckOpResult(std::string* message) : message_(message) {} | |
| 489 // Returns true if the check succeeded. | |
| 490 operator bool() const { return !message_; } | |
| 491 // Returns the message. | |
| 492 std::string* message() { return message_; } | |
| 493 | |
| 494 private: | |
| 495 std::string* message_; | |
| 496 }; | |
|
Nico
2015/07/06 22:41:52
why is this needed?
erikwright (departed)
2015/07/07 17:25:08
It allows us to both store the result of logging::
| |
| 497 | |
| 483 // Helper macro for binary operators. | 498 // Helper macro for binary operators. |
| 484 // Don't use this macro directly in your code, use CHECK_EQ et al below. | 499 // Don't use this macro directly in your code, use CHECK_EQ et al below. |
| 485 // | 500 // The 'switch' is used to prevent the 'if' from being ambiguous when the macro |
| 486 // TODO(akalin): Rewrite this so that constructs like if (...) | 501 // is used in an 'else' clause such as: |
| 487 // CHECK_EQ(...) else { ... } work properly. | 502 // if (a == 1) |
| 488 #define CHECK_OP(name, op, val1, val2) \ | 503 // statement; |
| 489 if (std::string* _result = \ | 504 // else |
| 490 logging::Check##name##Impl((val1), (val2), \ | 505 // DCHECK_EQ(2, a); |
|
danakj
2015/07/06 22:38:26
But else if works fine, what is ambiguous?
Nico
2015/07/07 16:59:43
I think the example is wrong and it's supposed to
erikwright (departed)
2015/07/07 17:25:08
You're correct, the example is wrong. I'm updating
| |
| 491 #val1 " " #op " " #val2)) \ | 506 #define CHECK_OP(name, op, val1, val2) \ |
|
Nico
2015/07/06 22:41:52
isn't the usual pattern for this
do { /* stuff
danakj
2015/07/06 22:43:27
Ya, that's what I've seen elsewhere too.
erikwright (departed)
2015/07/07 17:25:08
That doesn't work because you need the possible '<
| |
| 492 logging::LogMessage(__FILE__, __LINE__, _result).stream() | 507 switch (0) case 0: default: \ |
| 508 if (logging::CheckOpResult _result = \ | |
| 509 logging::Check##name##Impl((val1), (val2), \ | |
| 510 #val1 " " #op " " #val2)) \ | |
| 511 ; \ | |
| 512 else \ | |
| 513 logging::LogMessage(__FILE__, __LINE__, _result.message()).stream() | |
| 493 | 514 |
| 494 #endif | 515 #endif |
| 495 | 516 |
| 496 // Build the error message string. This is separate from the "Impl" | 517 // Build the error message string. This is separate from the "Impl" |
| 497 // function template because it is not performance critical and so can | 518 // function template because it is not performance critical and so can |
| 498 // be out of line, while the "Impl" code should be inline. Caller | 519 // be out of line, while the "Impl" code should be inline. Caller |
| 499 // takes ownership of the returned string. | 520 // takes ownership of the returned string. |
| 500 template<class t1, class t2> | 521 template<class t1, class t2> |
| 501 std::string* MakeCheckOpString(const t1& v1, const t2& v2, const char* names) { | 522 std::string* MakeCheckOpString(const t1& v1, const t2& v2, const char* names) { |
| 502 std::ostringstream ss; | 523 std::ostringstream ss; |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 658 << "Check failed: " #condition ". " | 679 << "Check failed: " #condition ". " |
| 659 | 680 |
| 660 #define DPCHECK(condition) \ | 681 #define DPCHECK(condition) \ |
| 661 LAZY_STREAM(PLOG_STREAM(DCHECK), DCHECK_IS_ON() ? !(condition) : false) \ | 682 LAZY_STREAM(PLOG_STREAM(DCHECK), DCHECK_IS_ON() ? !(condition) : false) \ |
| 662 << "Check failed: " #condition ". " | 683 << "Check failed: " #condition ". " |
| 663 | 684 |
| 664 #endif // _PREFAST_ | 685 #endif // _PREFAST_ |
| 665 | 686 |
| 666 // Helper macro for binary operators. | 687 // Helper macro for binary operators. |
| 667 // Don't use this macro directly in your code, use DCHECK_EQ et al below. | 688 // Don't use this macro directly in your code, use DCHECK_EQ et al below. |
| 668 #define DCHECK_OP(name, op, val1, val2) \ | 689 // The 'switch' is used to prevent the 'if' from being ambiguous when the macro |
| 669 if (DCHECK_IS_ON()) \ | 690 // is used in an 'else' clause such as: |
| 670 if (std::string* _result = logging::Check##name##Impl( \ | 691 // if (a == 1) |
| 671 (val1), (val2), #val1 " " #op " " #val2)) \ | 692 // statement; |
| 672 logging::LogMessage(__FILE__, __LINE__, ::logging::LOG_DCHECK, _result) \ | 693 // else |
| 673 .stream() | 694 // DCHECK_EQ(2, a); |
| 695 #define DCHECK_OP(name, op, val1, val2) \ | |
| 696 switch (0) case 0: default: \ | |
| 697 if (logging::CheckOpResult _result = \ | |
| 698 DCHECK_IS_ON() ? \ | |
| 699 logging::Check##name##Impl((val1), (val2), \ | |
| 700 #val1 " " #op " " #val2) : nullptr) \ | |
| 701 ; \ | |
| 702 else \ | |
| 703 logging::LogMessage(__FILE__, __LINE__, ::logging::LOG_DCHECK, \ | |
| 704 _result.message()).stream() | |
| 674 | 705 |
| 675 // Equality/Inequality checks - compare two values, and log a | 706 // Equality/Inequality checks - compare two values, and log a |
| 676 // LOG_DCHECK message including the two values when the result is not | 707 // LOG_DCHECK message including the two values when the result is not |
| 677 // as expected. The values must have operator<<(ostream, ...) | 708 // as expected. The values must have operator<<(ostream, ...) |
| 678 // defined. | 709 // defined. |
| 679 // | 710 // |
| 680 // You may append to the error message like so: | 711 // You may append to the error message like so: |
| 681 // DCHECK_NE(1, 2) << ": The world must be ending!"; | 712 // DCHECK_NE(1, 2) << ": The world must be ending!"; |
| 682 // | 713 // |
| 683 // We are very careful to ensure that each argument is evaluated exactly | 714 // We are very careful to ensure that each argument is evaluated exactly |
| (...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 930 #elif NOTIMPLEMENTED_POLICY == 5 | 961 #elif NOTIMPLEMENTED_POLICY == 5 |
| 931 #define NOTIMPLEMENTED() do {\ | 962 #define NOTIMPLEMENTED() do {\ |
| 932 static bool logged_once = false;\ | 963 static bool logged_once = false;\ |
| 933 LOG_IF(ERROR, !logged_once) << NOTIMPLEMENTED_MSG;\ | 964 LOG_IF(ERROR, !logged_once) << NOTIMPLEMENTED_MSG;\ |
| 934 logged_once = true;\ | 965 logged_once = true;\ |
| 935 } while(0);\ | 966 } while(0);\ |
| 936 EAT_STREAM_PARAMETERS | 967 EAT_STREAM_PARAMETERS |
| 937 #endif | 968 #endif |
| 938 | 969 |
| 939 #endif // BASE_LOGGING_H_ | 970 #endif // BASE_LOGGING_H_ |
| OLD | NEW |