59 changes: 31 additions & 28 deletions libc/test/UnitTest/PrintfMatcher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,12 @@
#include "src/stdio/printf_core/core_structs.h"

#include "test/UnitTest/StringUtils.h"
#include "test/UnitTest/Test.h"

#include <stdint.h>

using __llvm_libc::testing::tlog;

namespace __llvm_libc {
namespace printf_core {
namespace testing {
Expand All @@ -29,30 +32,30 @@ namespace {
#define IF_FLAG_SHOW_FLAG(flag_name) \
do { \
if ((form.flags & FormatFlags::flag_name) == FormatFlags::flag_name) \
stream << "\n\t\t" << #flag_name; \
tlog << "\n\t\t" << #flag_name; \
} while (false)
#define CASE_LM(lm) \
case (LengthModifier::lm): \
stream << #lm; \
tlog << #lm; \
break

void display(testutils::StreamWrapper &stream, FormatSection form) {
stream << "Raw String (len " << form.raw_string.size() << "): \"";
static void display(FormatSection form) {
tlog << "Raw String (len " << form.raw_string.size() << "): \"";
for (size_t i = 0; i < form.raw_string.size(); ++i) {
stream << form.raw_string[i];
tlog << form.raw_string[i];
}
stream << "\"";
tlog << "\"";
if (form.has_conv) {
stream << "\n\tHas Conv\n\tFlags:";
tlog << "\n\tHas Conv\n\tFlags:";
IF_FLAG_SHOW_FLAG(LEFT_JUSTIFIED);
IF_FLAG_SHOW_FLAG(FORCE_SIGN);
IF_FLAG_SHOW_FLAG(SPACE_PREFIX);
IF_FLAG_SHOW_FLAG(ALTERNATE_FORM);
IF_FLAG_SHOW_FLAG(LEADING_ZEROES);
stream << "\n";
stream << "\tmin width: " << form.min_width << "\n";
stream << "\tprecision: " << form.precision << "\n";
stream << "\tlength modifier: ";
tlog << "\n";
tlog << "\tmin width: " << form.min_width << "\n";
tlog << "\tprecision: " << form.precision << "\n";
tlog << "\tlength modifier: ";
switch (form.length_modifier) {
CASE_LM(none);
CASE_LM(l);
Expand All @@ -64,29 +67,29 @@ void display(testutils::StreamWrapper &stream, FormatSection form) {
CASE_LM(t);
CASE_LM(L);
}
stream << "\n";
stream << "\tconversion name: " << form.conv_name << "\n";
tlog << "\n";
tlog << "\tconversion name: " << form.conv_name << "\n";
if (form.conv_name == 'p' || form.conv_name == 'n' || form.conv_name == 's')
stream << "\tpointer value: "
<< int_to_hex<uintptr_t>(
reinterpret_cast<uintptr_t>(form.conv_val_ptr))
<< "\n";
tlog << "\tpointer value: "
<< int_to_hex<uintptr_t>(
reinterpret_cast<uintptr_t>(form.conv_val_ptr))
<< "\n";
else if (form.conv_name != '%')
stream << "\tvalue: "
<< int_to_hex<fputil::FPBits<long double>::UIntType>(
form.conv_val_raw)
<< "\n";
tlog << "\tvalue: "
<< int_to_hex<fputil::FPBits<long double>::UIntType>(
form.conv_val_raw)
<< "\n";
}
}
} // anonymous namespace

void FormatSectionMatcher::explainError(testutils::StreamWrapper &stream) {
stream << "expected format section: ";
display(stream, expected);
stream << '\n';
stream << "actual format section : ";
display(stream, actual);
stream << '\n';
void FormatSectionMatcher::explainError() {
tlog << "expected format section: ";
display(expected);
tlog << '\n';
tlog << "actual format section : ";
display(actual);
tlog << '\n';
}

} // namespace testing
Expand Down
2 changes: 1 addition & 1 deletion libc/test/UnitTest/PrintfMatcher.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class FormatSectionMatcher

bool match(FormatSection actualValue);

void explainError(testutils::StreamWrapper &stream) override;
void explainError() override;
};

} // namespace testing
Expand Down
55 changes: 29 additions & 26 deletions libc/test/UnitTest/ScanfMatcher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,12 @@
#include "src/stdio/scanf_core/core_structs.h"

#include "test/UnitTest/StringUtils.h"
#include "test/UnitTest/Test.h"

#include <stdint.h>

using __llvm_libc::testing::tlog;

namespace __llvm_libc {
namespace scanf_core {
namespace testing {
Expand All @@ -29,26 +32,26 @@ namespace {
#define IF_FLAG_SHOW_FLAG(flag_name) \
do { \
if ((form.flags & FormatFlags::flag_name) == FormatFlags::flag_name) \
stream << "\n\t\t" << #flag_name; \
tlog << "\n\t\t" << #flag_name; \
} while (false)
#define CASE_LM(lm) \
case (LengthModifier::lm): \
stream << #lm; \
tlog << #lm; \
break

void display(testutils::StreamWrapper &stream, FormatSection form) {
stream << "Raw String (len " << form.raw_string.size() << "): \"";
void display(FormatSection form) {
tlog << "Raw String (len " << form.raw_string.size() << "): \"";
for (size_t i = 0; i < form.raw_string.size(); ++i) {
stream << form.raw_string[i];
tlog << form.raw_string[i];
}
stream << "\"";
tlog << "\"";
if (form.has_conv) {
stream << "\n\tHas Conv\n\tFlags:";
tlog << "\n\tHas Conv\n\tFlags:";
IF_FLAG_SHOW_FLAG(NO_WRITE);
IF_FLAG_SHOW_FLAG(ALLOCATE);
stream << "\n";
stream << "\tmax width: " << form.max_width << "\n";
stream << "\tlength modifier: ";
tlog << "\n";
tlog << "\tmax width: " << form.max_width << "\n";
tlog << "\tlength modifier: ";
switch (form.length_modifier) {
CASE_LM(NONE);
CASE_LM(l);
Expand All @@ -60,38 +63,38 @@ void display(testutils::StreamWrapper &stream, FormatSection form) {
CASE_LM(t);
CASE_LM(L);
}
stream << "\n";
tlog << "\n";
// If the pointer is used (NO_WRITE is not set and the conversion isn't %).
if (((form.flags & FormatFlags::NO_WRITE) == 0) &&
(form.conv_name != '%')) {
stream << "\tpointer value: "
<< int_to_hex<uintptr_t>(
reinterpret_cast<uintptr_t>(form.output_ptr))
<< "\n";
tlog << "\tpointer value: "
<< int_to_hex<uintptr_t>(
reinterpret_cast<uintptr_t>(form.output_ptr))
<< "\n";
}

stream << "\tconversion name: " << form.conv_name << "\n";
tlog << "\tconversion name: " << form.conv_name << "\n";

if (form.conv_name == '[') {
stream << "\t\t";
tlog << "\t\t";
for (size_t i = 0; i < 256 /* char max */; ++i) {
if (form.scan_set.test(i)) {
stream << static_cast<char>(i);
tlog << static_cast<char>(i);
}
}
stream << "\n\t]\n";
tlog << "\n\t]\n";
}
}
}
} // anonymous namespace

void FormatSectionMatcher::explainError(testutils::StreamWrapper &stream) {
stream << "expected format section: ";
display(stream, expected);
stream << '\n';
stream << "actual format section : ";
display(stream, actual);
stream << '\n';
void FormatSectionMatcher::explainError() {
tlog << "expected format section: ";
display(expected);
tlog << '\n';
tlog << "actual format section : ";
display(actual);
tlog << '\n';
}

} // namespace testing
Expand Down
2 changes: 1 addition & 1 deletion libc/test/UnitTest/ScanfMatcher.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class FormatSectionMatcher

bool match(FormatSection actualValue);

void explainError(testutils::StreamWrapper &stream) override;
void explainError() override;
};

} // namespace testing
Expand Down
22 changes: 12 additions & 10 deletions libc/test/UnitTest/StringUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,26 @@
#ifndef LLVM_LIBC_UTILS_UNITTEST_SIMPLE_STRING_CONV_H
#define LLVM_LIBC_UTILS_UNITTEST_SIMPLE_STRING_CONV_H

#include "src/__support/CPP/string.h"
#include "src/__support/CPP/type_traits.h"

#include <string>

namespace __llvm_libc {

// Return the first N hex digits of an integer as a string in upper case.
template <typename T>
cpp::enable_if_t<cpp::is_integral_v<T>, std::string>
int_to_hex(T X, size_t Length = sizeof(T) * 2) {
std::string s(Length, '0');

for (auto it = s.rbegin(), end = s.rend(); it != end; ++it, X >>= 4) {
unsigned char Mod = static_cast<unsigned char>(X) & 15;
*it = (Mod < 10 ? '0' + Mod : 'a' + Mod - 10);
cpp::enable_if_t<cpp::is_integral_v<T>, cpp::string>
int_to_hex(T value, size_t length = sizeof(T) * 2) {
cpp::string s(length, '0');

constexpr char HEXADECIMALS[16] = {'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
for (size_t i = 0; i < length; i += 2, value >>= 8) {
unsigned char mod = static_cast<unsigned char>(value) & 0xFF;
s[length - i] = HEXADECIMALS[mod & 0x0F];
s[length - (i + 1)] = HEXADECIMALS[mod & 0x0F];
}

return s;
return "0x" + s;
}

} // namespace __llvm_libc
Expand Down
14 changes: 13 additions & 1 deletion libc/test/UnitTest/TestLogger.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
#include "test/UnitTest/TestLogger.h"
#include "src/__support/CPP/string.h"
#include "src/__support/CPP/string_view.h"
#include "src/__support/OSUtil/io.h" //write_to_stderr
#include "src/__support/OSUtil/io.h" // write_to_stderr

#include <stdint.h>

namespace __llvm_libc {
namespace testing {
Expand All @@ -23,11 +25,21 @@ template <> TestLogger &TestLogger::operator<< <const char *>(const char *str) {
return *this << cpp::string_view(str);
}

// char* specialization
template <> TestLogger &TestLogger::operator<< <char *>(char *str) {
return *this << cpp::string_view(str);
}

// char specialization
template <> TestLogger &TestLogger::operator<<(char ch) {
return *this << cpp::string_view(&ch, 1);
}

// void * specialization
template <> TestLogger &TestLogger::operator<<(void *addr) {
return *this << "0x" << cpp::to_string(reinterpret_cast<uintptr_t>(addr));
}

template <typename T> TestLogger &TestLogger::operator<<(T t) {
return *this << cpp::to_string(t);
}
Expand Down
9 changes: 0 additions & 9 deletions libc/test/src/math/log10_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,12 @@
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
#include "utils/testutils/StreamWrapper.h"
#include <math.h>

#include <errno.h>
#include <stdint.h>

namespace mpfr = __llvm_libc::testing::mpfr;
auto outs = __llvm_libc::testutils::outs();

DECLARE_SPECIAL_CONSTANTS(double)

Expand Down Expand Up @@ -104,23 +102,16 @@ TEST(LlvmLibcLog10Test, InDoubleRange) {
}
}
}
outs << " Log10 failed: " << fails << "/" << count << "/" << cc
<< " tests.\n";
outs << " Max ULPs is at most: " << tol << ".\n";
if (fails) {
EXPECT_MPFR_MATCH(mpfr::Operation::Log10, mx, mr, 0.5, rounding_mode);
}
};

outs << " Test Rounding To Nearest...\n";
test(mpfr::RoundingMode::Nearest);

outs << " Test Rounding Downward...\n";
test(mpfr::RoundingMode::Downward);

outs << " Test Rounding Upward...\n";
test(mpfr::RoundingMode::Upward);

outs << " Test Rounding Toward Zero...\n";
test(mpfr::RoundingMode::TowardZero);
}
31 changes: 15 additions & 16 deletions libc/test/src/time/TmMatcher.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,24 +37,23 @@ class StructTmMatcher : public __llvm_libc::testing::Matcher<::tm> {
actual.tm_isdst == expected.tm_isdst);
}

void describeValue(const char *label, ::tm value,
__llvm_libc::testutils::StreamWrapper &stream) {
stream << label;
stream << " sec: " << value.tm_sec;
stream << " min: " << value.tm_min;
stream << " hour: " << value.tm_hour;
stream << " mday: " << value.tm_mday;
stream << " mon: " << value.tm_mon;
stream << " year: " << value.tm_year;
stream << " wday: " << value.tm_wday;
stream << " yday: " << value.tm_yday;
stream << " isdst: " << value.tm_isdst;
stream << '\n';
void describeValue(const char *label, ::tm value) {
__llvm_libc::testing::tlog << label;
__llvm_libc::testing::tlog << " sec: " << value.tm_sec;
__llvm_libc::testing::tlog << " min: " << value.tm_min;
__llvm_libc::testing::tlog << " hour: " << value.tm_hour;
__llvm_libc::testing::tlog << " mday: " << value.tm_mday;
__llvm_libc::testing::tlog << " mon: " << value.tm_mon;
__llvm_libc::testing::tlog << " year: " << value.tm_year;
__llvm_libc::testing::tlog << " wday: " << value.tm_wday;
__llvm_libc::testing::tlog << " yday: " << value.tm_yday;
__llvm_libc::testing::tlog << " isdst: " << value.tm_isdst;
__llvm_libc::testing::tlog << '\n';
}

void explainError(__llvm_libc::testutils::StreamWrapper &stream) override {
describeValue("Expected tm_struct value: ", expected, stream);
describeValue(" Actual tm_struct value: ", actual, stream);
void explainError() override {
describeValue("Expected tm_struct value: ", expected);
describeValue(" Actual tm_struct value: ", actual);
}
};

Expand Down
237 changes: 116 additions & 121 deletions libc/utils/MPFRWrapper/MPFRUtils.cpp

Large diffs are not rendered by default.

55 changes: 25 additions & 30 deletions libc/utils/MPFRWrapper/MPFRUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -156,27 +156,30 @@ template <typename T>
void explain_unary_operation_single_output_error(Operation op, T input,
T match_value,
double ulp_tolerance,
RoundingMode rounding,
testutils::StreamWrapper &OS);
RoundingMode rounding);
template <typename T>
void explain_unary_operation_two_outputs_error(
Operation op, T input, const BinaryOutput<T> &match_value,
double ulp_tolerance, RoundingMode rounding, testutils::StreamWrapper &OS);
double ulp_tolerance, RoundingMode rounding);
template <typename T>
void explain_binary_operation_two_outputs_error(
Operation op, const BinaryInput<T> &input,
const BinaryOutput<T> &match_value, double ulp_tolerance,
RoundingMode rounding, testutils::StreamWrapper &OS);
RoundingMode rounding);

template <typename T>
void explain_binary_operation_one_output_error(
Operation op, const BinaryInput<T> &input, T match_value,
double ulp_tolerance, RoundingMode rounding, testutils::StreamWrapper &OS);
void explain_binary_operation_one_output_error(Operation op,
const BinaryInput<T> &input,
T match_value,
double ulp_tolerance,
RoundingMode rounding);

template <typename T>
void explain_ternary_operation_one_output_error(
Operation op, const TernaryInput<T> &input, T match_value,
double ulp_tolerance, RoundingMode rounding, testutils::StreamWrapper &OS);
void explain_ternary_operation_one_output_error(Operation op,
const TernaryInput<T> &input,
T match_value,
double ulp_tolerance,
RoundingMode rounding);

template <Operation op, bool silent, typename InputType, typename OutputType>
class MPFRMatcher : public testing::Matcher<OutputType> {
Expand All @@ -196,8 +199,8 @@ class MPFRMatcher : public testing::Matcher<OutputType> {

// This method is marked with NOLINT because it the name `explainError`
// does not confirm to the coding style.
void explainError(testutils::StreamWrapper &OS) override { // NOLINT
explain_error(input, match_value, OS);
void explainError() override { // NOLINT
explain_error(input, match_value);
}

// Whether the `explainError` step is skipped or not.
Expand Down Expand Up @@ -230,38 +233,30 @@ class MPFRMatcher : public testing::Matcher<OutputType> {
rounding);
}

template <typename T>
void explain_error(T in, T out, testutils::StreamWrapper &OS) {
template <typename T> void explain_error(T in, T out) {
explain_unary_operation_single_output_error(op, in, out, ulp_tolerance,
rounding, OS);
rounding);
}

template <typename T>
void explain_error(T in, const BinaryOutput<T> &out,
testutils::StreamWrapper &OS) {
template <typename T> void explain_error(T in, const BinaryOutput<T> &out) {
explain_unary_operation_two_outputs_error(op, in, out, ulp_tolerance,
rounding, OS);
rounding);
}

template <typename T>
void explain_error(const BinaryInput<T> &in, const BinaryOutput<T> &out,
testutils::StreamWrapper &OS) {
void explain_error(const BinaryInput<T> &in, const BinaryOutput<T> &out) {
explain_binary_operation_two_outputs_error(op, in, out, ulp_tolerance,
rounding, OS);
rounding);
}

template <typename T>
void explain_error(const BinaryInput<T> &in, T out,
testutils::StreamWrapper &OS) {
template <typename T> void explain_error(const BinaryInput<T> &in, T out) {
explain_binary_operation_one_output_error(op, in, out, ulp_tolerance,
rounding, OS);
rounding);
}

template <typename T>
void explain_error(const TernaryInput<T> &in, T out,
testutils::StreamWrapper &OS) {
template <typename T> void explain_error(const TernaryInput<T> &in, T out) {
explain_ternary_operation_one_output_error(op, in, out, ulp_tolerance,
rounding, OS);
rounding);
}
};

Expand Down
2 changes: 0 additions & 2 deletions libc/utils/testutils/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ endif()

add_library(
libc_test_utils
StreamWrapper.cpp
StreamWrapper.h
${EFFile}
ExecuteFunction.h
${FDReaderFile}
Expand Down
59 changes: 0 additions & 59 deletions libc/utils/testutils/StreamWrapper.cpp

This file was deleted.

39 changes: 0 additions & 39 deletions libc/utils/testutils/StreamWrapper.h

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ cc_library(
name = "fp_test_helpers",
srcs = [
"FPExceptMatcher.cpp",
"FPMatcher.cpp",
],
hdrs = [
"FPExceptMatcher.h",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,11 @@ cc_library(
"ExecuteFunctionUnix.cpp",
"FDReaderUnix.cpp",
"RoundingModeUtils.cpp",
"StreamWrapper.cpp",
],
hdrs = [
"ExecuteFunction.h",
"FDReader.h",
"RoundingModeUtils.h",
"StreamWrapper.h",
],
deps = [
"//libc:libc_root",
Expand Down