check_op.cc (5049B)
1 // Copyright 2022 The Abseil Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // https://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #include "absl/log/internal/check_op.h" 16 17 #include <cstring> 18 #include <ostream> 19 #include <string> 20 #include <utility> 21 22 #include "absl/base/config.h" 23 #include "absl/base/nullability.h" 24 #include "absl/debugging/leak_check.h" 25 #include "absl/strings/str_cat.h" 26 #include "absl/strings/string_view.h" 27 28 #ifdef _MSC_VER 29 #define strcasecmp _stricmp 30 #else 31 #include <strings.h> // for strcasecmp, but msvc does not have this header 32 #endif 33 34 namespace absl { 35 ABSL_NAMESPACE_BEGIN 36 namespace log_internal { 37 38 #define ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING(x) \ 39 template absl::Nonnull<const char*> MakeCheckOpString( \ 40 x, x, absl::Nonnull<const char*>) 41 ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING(bool); 42 ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING(int64_t); 43 ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING(uint64_t); 44 ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING(float); 45 ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING(double); 46 ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING(char); 47 ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING(unsigned char); 48 ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING(const std::string&); 49 ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING(const absl::string_view&); 50 ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING(const char*); 51 ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING(const signed char*); 52 ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING(const unsigned char*); 53 ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING(const void*); 54 #undef ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING 55 56 CheckOpMessageBuilder::CheckOpMessageBuilder( 57 absl::Nonnull<const char*> exprtext) { 58 stream_ << exprtext << " ("; 59 } 60 61 std::ostream& CheckOpMessageBuilder::ForVar2() { 62 stream_ << " vs. "; 63 return stream_; 64 } 65 66 absl::Nonnull<const char*> CheckOpMessageBuilder::NewString() { 67 stream_ << ")"; 68 // There's no need to free this string since the process is crashing. 69 return absl::IgnoreLeak(new std::string(std::move(stream_).str()))->c_str(); 70 } 71 72 void MakeCheckOpValueString(std::ostream& os, const char v) { 73 if (v >= 32 && v <= 126) { 74 os << "'" << v << "'"; 75 } else { 76 os << "char value " << int{v}; 77 } 78 } 79 80 void MakeCheckOpValueString(std::ostream& os, const signed char v) { 81 if (v >= 32 && v <= 126) { 82 os << "'" << v << "'"; 83 } else { 84 os << "signed char value " << int{v}; 85 } 86 } 87 88 void MakeCheckOpValueString(std::ostream& os, const unsigned char v) { 89 if (v >= 32 && v <= 126) { 90 os << "'" << v << "'"; 91 } else { 92 os << "unsigned char value " << int{v}; 93 } 94 } 95 96 void MakeCheckOpValueString(std::ostream& os, const void* p) { 97 if (p == nullptr) { 98 os << "(null)"; 99 } else { 100 os << p; 101 } 102 } 103 104 // Helper functions for string comparisons. 105 #define DEFINE_CHECK_STROP_IMPL(name, func, expected) \ 106 absl::Nullable<const char*> Check##func##expected##Impl( \ 107 absl::Nullable<const char*> s1, absl::Nullable<const char*> s2, \ 108 absl::Nonnull<const char*> exprtext) { \ 109 bool equal = s1 == s2 || (s1 && s2 && !func(s1, s2)); \ 110 if (equal == expected) { \ 111 return nullptr; \ 112 } else { \ 113 /* There's no need to free this string since the process is crashing. */ \ 114 return absl::IgnoreLeak(new std::string(absl::StrCat(exprtext, " (", s1, \ 115 " vs. ", s2, ")"))) \ 116 ->c_str(); \ 117 } \ 118 } 119 DEFINE_CHECK_STROP_IMPL(CHECK_STREQ, strcmp, true) 120 DEFINE_CHECK_STROP_IMPL(CHECK_STRNE, strcmp, false) 121 DEFINE_CHECK_STROP_IMPL(CHECK_STRCASEEQ, strcasecmp, true) 122 DEFINE_CHECK_STROP_IMPL(CHECK_STRCASENE, strcasecmp, false) 123 #undef DEFINE_CHECK_STROP_IMPL 124 125 namespace detect_specialization { 126 127 StringifySink::StringifySink(std::ostream& os) : os_(os) {} 128 129 void StringifySink::Append(absl::string_view text) { os_ << text; } 130 131 void StringifySink::Append(size_t length, char ch) { 132 for (size_t i = 0; i < length; ++i) os_.put(ch); 133 } 134 135 void AbslFormatFlush(StringifySink* sink, absl::string_view text) { 136 sink->Append(text); 137 } 138 139 } // namespace detect_specialization 140 141 } // namespace log_internal 142 ABSL_NAMESPACE_END 143 } // namespace absl