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