cmdlib: fix broken Q_strcasecmp and Q_strncasecmp
string_view isn't null terminated, can't use C string functions
This commit is contained in:
parent
638076ffb2
commit
d7eca5f317
|
|
@ -41,34 +41,47 @@
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#if defined(__has_include) && __has_include(<strings.h>)
|
char Q_tolower(char x)
|
||||||
#include <strings.h>
|
{
|
||||||
#endif
|
if (x >= 'A' && x <= 'Z') {
|
||||||
|
x += 'a' - 'A';
|
||||||
|
}
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
int32_t Q_strncasecmp(std::string_view a, std::string_view b, size_t maxcount)
|
int32_t Q_strncasecmp(std::string_view a, std::string_view b, size_t maxcount)
|
||||||
{
|
{
|
||||||
return
|
return Q_strcasecmp(
|
||||||
#ifdef _WIN32
|
a.substr(0, maxcount),
|
||||||
_strnicmp
|
b.substr(0, maxcount));
|
||||||
#elif defined(__has_include) && __has_include(<strings.h>)
|
|
||||||
strncasecmp
|
|
||||||
#else
|
|
||||||
strnicmp
|
|
||||||
#endif
|
|
||||||
(a.data(), b.data(), maxcount);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t Q_strcasecmp(std::string_view a, std::string_view b)
|
int32_t Q_strcasecmp(std::string_view a, std::string_view b)
|
||||||
{
|
{
|
||||||
return
|
const char *a_ptr = a.data();
|
||||||
#ifdef _WIN32
|
const char *b_ptr = b.data();
|
||||||
_stricmp
|
const size_t common_size = std::min(a.size(), b.size());
|
||||||
#elif defined(__has_include) && __has_include(<strings.h>)
|
|
||||||
strcasecmp
|
for (size_t i = 0; i < common_size; ++i) {
|
||||||
#else
|
char achar = Q_tolower(a_ptr[i]);
|
||||||
stricmp
|
char bchar = Q_tolower(b_ptr[i]);
|
||||||
#endif
|
|
||||||
(a.data(), b.data());
|
if (achar < bchar) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (achar > bchar) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// the first common_size chars are the same
|
||||||
|
if (a.size() < b.size()) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (a.size() > b.size()) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void // mxd
|
void // mxd
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
#include <tuple> // for std::apply()
|
#include <tuple> // for std::apply()
|
||||||
|
|
||||||
|
char Q_tolower(char x);
|
||||||
int32_t Q_strncasecmp(std::string_view a, std::string_view b, size_t maxcount);
|
int32_t Q_strncasecmp(std::string_view a, std::string_view b, size_t maxcount);
|
||||||
int32_t Q_strcasecmp(std::string_view a, std::string_view b);
|
int32_t Q_strcasecmp(std::string_view a, std::string_view b);
|
||||||
bool string_iequals(std::string_view a, std::string_view b); // mxd
|
bool string_iequals(std::string_view a, std::string_view b); // mxd
|
||||||
|
|
|
||||||
|
|
@ -382,3 +382,33 @@ TEST(qmat, transpose)
|
||||||
|
|
||||||
EXPECT_EQ(in.transpose(), exp);
|
EXPECT_EQ(in.transpose(), exp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(string, strcasecmp)
|
||||||
|
{
|
||||||
|
EXPECT_EQ('x', Q_tolower('X'));
|
||||||
|
EXPECT_EQ('"', Q_tolower('"'));
|
||||||
|
|
||||||
|
const char *test = "abcA**";
|
||||||
|
|
||||||
|
// lhs < rhs
|
||||||
|
EXPECT_LT(Q_strcasecmp("a", "aa"), 0);
|
||||||
|
EXPECT_LT(Q_strcasecmp("aaa", "BBB"), 0);
|
||||||
|
EXPECT_LT(Q_strcasecmp("AAA", "bbb"), 0);
|
||||||
|
|
||||||
|
// lhs == rhs
|
||||||
|
EXPECT_EQ(Q_strcasecmp(std::string_view(&test[0], 1), std::string_view(&test[3], 1)), 0);
|
||||||
|
EXPECT_EQ(Q_strcasecmp("test", "TEST"), 0);
|
||||||
|
EXPECT_EQ(Q_strcasecmp("test", "test"), 0);
|
||||||
|
|
||||||
|
// lhs > rhs
|
||||||
|
EXPECT_GT(Q_strcasecmp("test", "aaaa"), 0);
|
||||||
|
EXPECT_GT(Q_strcasecmp("test", "AAAA"), 0);
|
||||||
|
EXPECT_GT(Q_strcasecmp("test", "tes"), 0);
|
||||||
|
EXPECT_GT(Q_strcasecmp("TEST", "T"), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(string, strncasecmp)
|
||||||
|
{
|
||||||
|
EXPECT_EQ(Q_strncasecmp("*lava123", "*LAVA", 5), 0);
|
||||||
|
EXPECT_EQ(Q_strncasecmp("*lava123", "*LAVA", 8), 1);
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue