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 |