blob: 9da749f3b8ad1ab6d651947b3200730289e07091 [file] [log] [blame]
//===-- Unittests for the printf Converter --------------------------------===//
//
// 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 "src/stdio/printf_core/converter.h"
#include "src/stdio/printf_core/core_structs.h"
#include "src/stdio/printf_core/writer.h"
#include "test/UnitTest/Test.h"
class LlvmLibcPrintfConverterTest : public LIBC_NAMESPACE::testing::Test {
protected:
// void SetUp() override {}
// void TearDown() override {}
char str[60];
LIBC_NAMESPACE::printf_core::WriteBuffer wb =
LIBC_NAMESPACE::printf_core::WriteBuffer(str, sizeof(str) - 1);
LIBC_NAMESPACE::printf_core::Writer writer =
LIBC_NAMESPACE::printf_core::Writer(&wb);
};
TEST_F(LlvmLibcPrintfConverterTest, SimpleRawConversion) {
LIBC_NAMESPACE::printf_core::FormatSection raw_section;
raw_section.has_conv = false;
raw_section.raw_string = "abc";
LIBC_NAMESPACE::printf_core::convert(&writer, raw_section);
wb.buff[wb.buff_cur] = '\0';
ASSERT_STREQ(str, "abc");
ASSERT_EQ(writer.get_chars_written(), 3);
}
TEST_F(LlvmLibcPrintfConverterTest, PercentConversion) {
LIBC_NAMESPACE::printf_core::FormatSection simple_conv;
simple_conv.has_conv = true;
simple_conv.raw_string = "%%";
simple_conv.conv_name = '%';
LIBC_NAMESPACE::printf_core::convert(&writer, simple_conv);
wb.buff[wb.buff_cur] = '\0';
ASSERT_STREQ(str, "%");
ASSERT_EQ(writer.get_chars_written(), 1);
}
TEST_F(LlvmLibcPrintfConverterTest, CharConversionSimple) {
LIBC_NAMESPACE::printf_core::FormatSection simple_conv;
simple_conv.has_conv = true;
// If has_conv is true, the raw string is ignored. They are not being parsed
// and match the actual conversion taking place so that you can compare these
// tests with other implmentations. The raw strings are completely optional.
simple_conv.raw_string = "%c";
simple_conv.conv_name = 'c';
simple_conv.conv_val_raw = 'D';
LIBC_NAMESPACE::printf_core::convert(&writer, simple_conv);
wb.buff[wb.buff_cur] = '\0';
ASSERT_STREQ(str, "D");
ASSERT_EQ(writer.get_chars_written(), 1);
}
TEST_F(LlvmLibcPrintfConverterTest, CharConversionRightJustified) {
LIBC_NAMESPACE::printf_core::FormatSection right_justified_conv;
right_justified_conv.has_conv = true;
right_justified_conv.raw_string = "%4c";
right_justified_conv.conv_name = 'c';
right_justified_conv.min_width = 4;
right_justified_conv.conv_val_raw = 'E';
LIBC_NAMESPACE::printf_core::convert(&writer, right_justified_conv);
wb.buff[wb.buff_cur] = '\0';
ASSERT_STREQ(str, " E");
ASSERT_EQ(writer.get_chars_written(), 4);
}
TEST_F(LlvmLibcPrintfConverterTest, CharConversionLeftJustified) {
LIBC_NAMESPACE::printf_core::FormatSection left_justified_conv;
left_justified_conv.has_conv = true;
left_justified_conv.raw_string = "%-4c";
left_justified_conv.conv_name = 'c';
left_justified_conv.flags =
LIBC_NAMESPACE::printf_core::FormatFlags::LEFT_JUSTIFIED;
left_justified_conv.min_width = 4;
left_justified_conv.conv_val_raw = 'F';
LIBC_NAMESPACE::printf_core::convert(&writer, left_justified_conv);
wb.buff[wb.buff_cur] = '\0';
ASSERT_STREQ(str, "F ");
ASSERT_EQ(writer.get_chars_written(), 4);
}
TEST_F(LlvmLibcPrintfConverterTest, StringConversionSimple) {
LIBC_NAMESPACE::printf_core::FormatSection simple_conv;
simple_conv.has_conv = true;
simple_conv.raw_string = "%s";
simple_conv.conv_name = 's';
simple_conv.conv_val_ptr = const_cast<char *>("DEF");
LIBC_NAMESPACE::printf_core::convert(&writer, simple_conv);
wb.buff[wb.buff_cur] = '\0';
ASSERT_STREQ(str, "DEF");
ASSERT_EQ(writer.get_chars_written(), 3);
}
TEST_F(LlvmLibcPrintfConverterTest, StringConversionPrecisionHigh) {
LIBC_NAMESPACE::printf_core::FormatSection high_precision_conv;
high_precision_conv.has_conv = true;
high_precision_conv.raw_string = "%4s";
high_precision_conv.conv_name = 's';
high_precision_conv.precision = 4;
high_precision_conv.conv_val_ptr = const_cast<char *>("456");
LIBC_NAMESPACE::printf_core::convert(&writer, high_precision_conv);
wb.buff[wb.buff_cur] = '\0';
ASSERT_STREQ(str, "456");
ASSERT_EQ(writer.get_chars_written(), 3);
}
TEST_F(LlvmLibcPrintfConverterTest, StringConversionPrecisionLow) {
LIBC_NAMESPACE::printf_core::FormatSection low_precision_conv;
low_precision_conv.has_conv = true;
low_precision_conv.raw_string = "%.2s";
low_precision_conv.conv_name = 's';
low_precision_conv.precision = 2;
low_precision_conv.conv_val_ptr = const_cast<char *>("xyz");
LIBC_NAMESPACE::printf_core::convert(&writer, low_precision_conv);
wb.buff[wb.buff_cur] = '\0';
ASSERT_STREQ(str, "xy");
ASSERT_EQ(writer.get_chars_written(), 2);
}
TEST_F(LlvmLibcPrintfConverterTest, StringConversionRightJustified) {
LIBC_NAMESPACE::printf_core::FormatSection right_justified_conv;
right_justified_conv.has_conv = true;
right_justified_conv.raw_string = "%4s";
right_justified_conv.conv_name = 's';
right_justified_conv.min_width = 4;
right_justified_conv.conv_val_ptr = const_cast<char *>("789");
LIBC_NAMESPACE::printf_core::convert(&writer, right_justified_conv);
wb.buff[wb.buff_cur] = '\0';
ASSERT_STREQ(str, " 789");
ASSERT_EQ(writer.get_chars_written(), 4);
}
TEST_F(LlvmLibcPrintfConverterTest, StringConversionLeftJustified) {
LIBC_NAMESPACE::printf_core::FormatSection left_justified_conv;
left_justified_conv.has_conv = true;
left_justified_conv.raw_string = "%-4s";
left_justified_conv.conv_name = 's';
left_justified_conv.flags =
LIBC_NAMESPACE::printf_core::FormatFlags::LEFT_JUSTIFIED;
left_justified_conv.min_width = 4;
left_justified_conv.conv_val_ptr = const_cast<char *>("ghi");
LIBC_NAMESPACE::printf_core::convert(&writer, left_justified_conv);
wb.buff[wb.buff_cur] = '\0';
ASSERT_STREQ(str, "ghi ");
ASSERT_EQ(writer.get_chars_written(), 4);
}
TEST_F(LlvmLibcPrintfConverterTest, IntConversionSimple) {
LIBC_NAMESPACE::printf_core::FormatSection section;
section.has_conv = true;
section.raw_string = "%d";
section.conv_name = 'd';
section.conv_val_raw = 12345;
LIBC_NAMESPACE::printf_core::convert(&writer, section);
wb.buff[wb.buff_cur] = '\0';
ASSERT_STREQ(str, "12345");
ASSERT_EQ(writer.get_chars_written(), 5);
}
TEST_F(LlvmLibcPrintfConverterTest, HexConversion) {
LIBC_NAMESPACE::printf_core::FormatSection section;
section.has_conv = true;
section.raw_string = "%#018x";
section.conv_name = 'x';
section.flags = static_cast<LIBC_NAMESPACE::printf_core::FormatFlags>(
LIBC_NAMESPACE::printf_core::FormatFlags::ALTERNATE_FORM |
LIBC_NAMESPACE::printf_core::FormatFlags::LEADING_ZEROES);
section.min_width = 18;
section.conv_val_raw = 0x123456ab;
LIBC_NAMESPACE::printf_core::convert(&writer, section);
wb.buff[wb.buff_cur] = '\0';
ASSERT_STREQ(str, "0x00000000123456ab");
ASSERT_EQ(writer.get_chars_written(), 18);
}
TEST_F(LlvmLibcPrintfConverterTest, BinaryConversion) {
LIBC_NAMESPACE::printf_core::FormatSection section;
section.has_conv = true;
section.raw_string = "%b";
section.conv_name = 'b';
section.conv_val_raw = 42;
LIBC_NAMESPACE::printf_core::convert(&writer, section);
wb.buff[wb.buff_cur] = '\0';
ASSERT_STREQ(str, "101010");
ASSERT_EQ(writer.get_chars_written(), 6);
}
TEST_F(LlvmLibcPrintfConverterTest, PointerConversion) {
LIBC_NAMESPACE::printf_core::FormatSection section;
section.has_conv = true;
section.raw_string = "%p";
section.conv_name = 'p';
section.conv_val_ptr = (void *)(0x123456ab);
LIBC_NAMESPACE::printf_core::convert(&writer, section);
wb.buff[wb.buff_cur] = '\0';
ASSERT_STREQ(str, "0x123456ab");
ASSERT_EQ(writer.get_chars_written(), 10);
}
TEST_F(LlvmLibcPrintfConverterTest, OctConversion) {
LIBC_NAMESPACE::printf_core::FormatSection section;
section.has_conv = true;
section.raw_string = "%o";
section.conv_name = 'o';
section.conv_val_raw = 01234;
LIBC_NAMESPACE::printf_core::convert(&writer, section);
wb.buff[wb.buff_cur] = '\0';
ASSERT_STREQ(str, "1234");
ASSERT_EQ(writer.get_chars_written(), 4);
}