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 <string.h>
18
19 #ifdef _MSC_VER
20 #define strcasecmp _stricmp
21 #else
22 #include <strings.h> // for strcasecmp, but msvc does not have this header
23 #endif
24
25 #include <sstream>
26 #include <string>
27
28 #include "absl/base/config.h"
29 #include "absl/strings/str_cat.h"
30
31 namespace absl {
32 ABSL_NAMESPACE_BEGIN
33 namespace log_internal {
34
35 #define ABSL_LOGGING_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING(x) \
36 template std::string* MakeCheckOpString(x, x, const char*)
37 ABSL_LOGGING_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING(bool);
38 ABSL_LOGGING_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING(int64_t);
39 ABSL_LOGGING_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING(uint64_t);
40 ABSL_LOGGING_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING(float);
41 ABSL_LOGGING_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING(double);
42 ABSL_LOGGING_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING(char);
43 ABSL_LOGGING_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING(unsigned char);
44 ABSL_LOGGING_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING(const std::string&);
45 ABSL_LOGGING_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING(const absl::string_view&);
46 ABSL_LOGGING_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING(const char*);
47 ABSL_LOGGING_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING(const signed char*);
48 ABSL_LOGGING_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING(const unsigned char*);
49 ABSL_LOGGING_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING(const void*);
50 #undef ABSL_LOGGING_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING
51
CheckOpMessageBuilder(const char * exprtext)52 CheckOpMessageBuilder::CheckOpMessageBuilder(const char* exprtext) {
53 stream_ << exprtext << " (";
54 }
55
ForVar2()56 std::ostream& CheckOpMessageBuilder::ForVar2() {
57 stream_ << " vs. ";
58 return stream_;
59 }
60
NewString()61 std::string* CheckOpMessageBuilder::NewString() {
62 stream_ << ")";
63 return new std::string(stream_.str());
64 }
65
MakeCheckOpValueString(std::ostream & os,const char v)66 void MakeCheckOpValueString(std::ostream& os, const char v) {
67 if (v >= 32 && v <= 126) {
68 os << "'" << v << "'";
69 } else {
70 os << "char value " << int{v};
71 }
72 }
73
MakeCheckOpValueString(std::ostream & os,const signed char v)74 void MakeCheckOpValueString(std::ostream& os, const signed char v) {
75 if (v >= 32 && v <= 126) {
76 os << "'" << v << "'";
77 } else {
78 os << "signed char value " << int{v};
79 }
80 }
81
MakeCheckOpValueString(std::ostream & os,const unsigned char v)82 void MakeCheckOpValueString(std::ostream& os, const unsigned char v) {
83 if (v >= 32 && v <= 126) {
84 os << "'" << v << "'";
85 } else {
86 os << "unsigned char value " << int{v};
87 }
88 }
89
MakeCheckOpValueString(std::ostream & os,const void * p)90 void MakeCheckOpValueString(std::ostream& os, const void* p) {
91 if (p == nullptr) {
92 os << "(null)";
93 } else {
94 os << p;
95 }
96 }
97
98 // Helper functions for string comparisons.
99 #define DEFINE_CHECK_STROP_IMPL(name, func, expected) \
100 std::string* Check##func##expected##Impl(const char* s1, const char* s2, \
101 const char* exprtext) { \
102 bool equal = s1 == s2 || (s1 && s2 && !func(s1, s2)); \
103 if (equal == expected) { \
104 return nullptr; \
105 } else { \
106 return new std::string( \
107 absl::StrCat(exprtext, " (", s1, " vs. ", s2, ")")); \
108 } \
109 }
110 DEFINE_CHECK_STROP_IMPL(CHECK_STREQ, strcmp, true)
111 DEFINE_CHECK_STROP_IMPL(CHECK_STRNE, strcmp, false)
112 DEFINE_CHECK_STROP_IMPL(CHECK_STRCASEEQ, strcasecmp, true)
113 DEFINE_CHECK_STROP_IMPL(CHECK_STRCASENE, strcasecmp, false)
114 #undef DEFINE_CHECK_STROP_IMPL
115
116 } // namespace log_internal
117 ABSL_NAMESPACE_END
118 } // namespace absl
119