Files
llvm/libc/test/UnitTest/MemoryMatcher.cpp
Alexey Samsonov 120689e466 [libc] Migrate ctype_utils to use char instead of int where applicable. (#166225)
Functions like isalpha / tolower can operate on chars internally. This
allows us to get rid of unnecessary casts and open a way to creating
wchar_t overloads with the same names (e.g. for isalpha), that would
simplify templated code for conversion functions (see
315dfe5865).

Add the int->char converstion to public entrypoints implementation
instead. We also need to introduce bounds check on the input argument
values - these functions' behavior is unspecified if the argument is
neither EOF nor fits in "unsigned char" range, but the tests we've had
verified that they always return false for small negative values. To
preserve this behavior, cover it explicitly.
2025-11-05 11:02:28 -08:00

86 lines
2.1 KiB
C++

//===-- MemoryMatcher.cpp ---------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "MemoryMatcher.h"
#include "src/__support/ctype_utils.h"
#include "src/__support/macros/config.h"
#include "test/UnitTest/Test.h"
#if LIBC_TEST_HAS_MATCHERS()
using LIBC_NAMESPACE::testing::tlog;
namespace LIBC_NAMESPACE_DECL {
namespace testing {
template <typename T>
bool equals(const cpp::span<T> &Span1, const cpp::span<T> &Span2,
bool &mismatch_size, size_t &mismatch_index) {
if (Span1.size() != Span2.size()) {
mismatch_size = true;
return false;
}
for (size_t Index = 0; Index < Span1.size(); ++Index)
if (Span1[Index] != Span2[Index]) {
mismatch_index = Index;
return false;
}
return true;
}
bool MemoryMatcher::match(MemoryView actualValue) {
actual = actualValue;
return equals(expected, actual, mismatch_size, mismatch_index);
}
static void display(char C) {
const auto print = [](unsigned char i) {
tlog << LIBC_NAMESPACE::internal::toupper(
LIBC_NAMESPACE::internal::int_to_b36_char(i));
};
print(static_cast<unsigned char>(C) / 16);
print(static_cast<unsigned char>(C) & 15);
}
static void display(MemoryView View) {
for (auto C : View) {
tlog << ' ';
display(C);
}
}
void MemoryMatcher::explainError() {
if (mismatch_size) {
tlog << "Size mismatch :";
tlog << "expected : ";
tlog << expected.size();
tlog << '\n';
tlog << "actual : ";
tlog << actual.size();
tlog << '\n';
} else {
tlog << "Mismatch at position : ";
tlog << mismatch_index;
tlog << " / ";
tlog << expected.size();
tlog << "\n";
tlog << "expected :";
display(expected);
tlog << '\n';
tlog << "actual :";
display(actual);
tlog << '\n';
}
}
} // namespace testing
} // namespace LIBC_NAMESPACE_DECL
#endif // LIBC_TEST_HAS_MATCHERS()