[libc-commits] [libc] 096463d - [libc] move printf to use StringViews
Michael Jones via libc-commits
libc-commits at lists.llvm.org
Wed Aug 24 10:28:41 PDT 2022
Author: Michael Jones
Date: 2022-08-24T10:28:31-07:00
New Revision: 096463d08eaa053c000700c3d4648f0c93cb7af6
URL: https://github.com/llvm/llvm-project/commit/096463d08eaa053c000700c3d4648f0c93cb7af6
DIFF: https://github.com/llvm/llvm-project/commit/096463d08eaa053c000700c3d4648f0c93cb7af6.diff
LOG: [libc] move printf to use StringViews
The FormatSection and the writer functions both previously took a char*
and a length to represent a string. Now they use the StringView class to
represent that more succinctly. This change also required fixing
everywhere these were used, so it touches a lot of files.
Reviewed By: sivachandra
Differential Revision: https://reviews.llvm.org/D131994
Added:
Modified:
libc/src/stdio/printf_core/CMakeLists.txt
libc/src/stdio/printf_core/char_converter.h
libc/src/stdio/printf_core/converter.cpp
libc/src/stdio/printf_core/core_structs.h
libc/src/stdio/printf_core/file_writer.cpp
libc/src/stdio/printf_core/file_writer.h
libc/src/stdio/printf_core/float_hex_converter.h
libc/src/stdio/printf_core/float_inf_nan_converter.h
libc/src/stdio/printf_core/int_converter.h
libc/src/stdio/printf_core/parser.cpp
libc/src/stdio/printf_core/parser.h
libc/src/stdio/printf_core/printf_main.cpp
libc/src/stdio/printf_core/ptr_converter.h
libc/src/stdio/printf_core/string_converter.h
libc/src/stdio/printf_core/string_writer.cpp
libc/src/stdio/printf_core/string_writer.h
libc/src/stdio/printf_core/vfprintf_internal.cpp
libc/src/stdio/printf_core/writer.cpp
libc/src/stdio/printf_core/writer.h
libc/src/stdio/snprintf.cpp
libc/src/stdio/sprintf.cpp
libc/test/src/stdio/printf_core/CMakeLists.txt
libc/test/src/stdio/printf_core/converter_test.cpp
libc/test/src/stdio/printf_core/parser_test.cpp
libc/test/src/stdio/printf_core/string_writer_test.cpp
libc/utils/UnitTest/CMakeLists.txt
libc/utils/UnitTest/PrintfMatcher.cpp
Removed:
################################################################################
diff --git a/libc/src/stdio/printf_core/CMakeLists.txt b/libc/src/stdio/printf_core/CMakeLists.txt
index edf77fe0018ba..4ab4d61a41bc1 100644
--- a/libc/src/stdio/printf_core/CMakeLists.txt
+++ b/libc/src/stdio/printf_core/CMakeLists.txt
@@ -3,6 +3,9 @@ add_header_library(
core_structs
HDRS
core_structs.h
+ DEPENDS
+ libc.src.__support.CPP.string_view
+ libc.src.__support.FPUtil.fputil
)
add_object_library(
@@ -17,7 +20,7 @@ add_object_library(
libc.src.__support.ctype_utils
libc.src.__support.str_to_integer
libc.src.__support.CPP.bit
- libc.src.string.memory_utils.memset_implementation
+ libc.src.__support.CPP.string_view
)
add_object_library(
@@ -27,7 +30,9 @@ add_object_library(
HDRS
string_writer.h
DEPENDS
+ libc.src.__support.CPP.string_view
libc.src.string.memory_utils.memcpy_implementation
+ libc.src.string.memory_utils.memset_implementation
.core_structs
)
@@ -37,8 +42,6 @@ add_object_library(
writer.cpp
HDRS
writer.h
- DEPENDS
- libc.src.string.memory_utils.memset_implementation
)
add_object_library(
@@ -95,6 +98,8 @@ add_object_library(
file_writer.h
DEPENDS
libc.src.__support.File.file
+ libc.src.__support.CPP.string_view
+ libc.src.string.memory_utils.memset_implementation
.core_structs
)
diff --git a/libc/src/stdio/printf_core/char_converter.h b/libc/src/stdio/printf_core/char_converter.h
index b32a39c419ff4..cd4724fd7695b 100644
--- a/libc/src/stdio/printf_core/char_converter.h
+++ b/libc/src/stdio/printf_core/char_converter.h
@@ -9,6 +9,7 @@
#ifndef LLVM_LIBC_SRC_STDIO_PRINTF_CORE_CHAR_CONVERTER_H
#define LLVM_LIBC_SRC_STDIO_PRINTF_CORE_CHAR_CONVERTER_H
+#include "src/__support/CPP/string_view.h"
#include "src/stdio/printf_core/converter_utils.h"
#include "src/stdio/printf_core/core_structs.h"
#include "src/stdio/printf_core/writer.h"
@@ -19,18 +20,25 @@ namespace printf_core {
int inline convert_char(Writer *writer, const FormatSection &to_conv) {
char c = to_conv.conv_val_raw;
- if (to_conv.min_width > 1) {
- if ((to_conv.flags & FormatFlags::LEFT_JUSTIFIED) ==
- FormatFlags::LEFT_JUSTIFIED) {
- RET_IF_RESULT_NEGATIVE(writer->write(&c, 1));
- RET_IF_RESULT_NEGATIVE(writer->write_chars(' ', to_conv.min_width - 1));
- } else {
- RET_IF_RESULT_NEGATIVE(writer->write_chars(' ', to_conv.min_width - 1));
- RET_IF_RESULT_NEGATIVE(writer->write(&c, 1));
- }
- } else {
- RET_IF_RESULT_NEGATIVE(writer->write(&c, 1));
+ constexpr int string_len = 1;
+
+ size_t padding_spaces =
+ to_conv.min_width > string_len ? to_conv.min_width - string_len : 0;
+
+ // If the padding is on the left side, write the spaces first.
+ if (padding_spaces > 0 &&
+ (to_conv.flags & FormatFlags::LEFT_JUSTIFIED) == 0) {
+ RET_IF_RESULT_NEGATIVE(writer->write(' ', to_conv.min_width - string_len));
+ }
+
+ RET_IF_RESULT_NEGATIVE(writer->write(c));
+
+ // If the padding is on the right side, write the spaces last.
+ if (padding_spaces > 0 &&
+ (to_conv.flags & FormatFlags::LEFT_JUSTIFIED) != 0) {
+ RET_IF_RESULT_NEGATIVE(writer->write(' ', to_conv.min_width - string_len));
}
+
return WRITE_OK;
}
diff --git a/libc/src/stdio/printf_core/converter.cpp b/libc/src/stdio/printf_core/converter.cpp
index 663d5bb54d6a0..597e75553bfb0 100644
--- a/libc/src/stdio/printf_core/converter.cpp
+++ b/libc/src/stdio/printf_core/converter.cpp
@@ -26,11 +26,11 @@ namespace printf_core {
int convert(Writer *writer, const FormatSection &to_conv) {
if (!to_conv.has_conv)
- return writer->write(to_conv.raw_string, to_conv.raw_len);
+ return writer->write(to_conv.raw_string);
switch (to_conv.conv_name) {
case '%':
- return writer->write("%", 1);
+ return writer->write("%");
case 'c':
return convert_char(writer, to_conv);
case 's':
@@ -63,7 +63,7 @@ int convert(Writer *writer, const FormatSection &to_conv) {
case 'p':
return convert_pointer(writer, to_conv);
default:
- return writer->write(to_conv.raw_string, to_conv.raw_len);
+ return writer->write(to_conv.raw_string);
}
return -1;
}
diff --git a/libc/src/stdio/printf_core/core_structs.h b/libc/src/stdio/printf_core/core_structs.h
index 25e530337eec4..fb8c8bbd9e1f2 100644
--- a/libc/src/stdio/printf_core/core_structs.h
+++ b/libc/src/stdio/printf_core/core_structs.h
@@ -37,8 +37,7 @@ enum FormatFlags : uint8_t {
struct FormatSection {
bool has_conv;
- const char *__restrict raw_string;
- size_t raw_len;
+ cpp::string_view raw_string;
// Format Specifier Values
FormatFlags flags = FormatFlags(0);
@@ -58,8 +57,7 @@ struct FormatSection {
if (has_conv != other.has_conv)
return false;
- if (cpp::string_view(raw_string, raw_len) !=
- cpp::string_view(other.raw_string, other.raw_len))
+ if (raw_string != other.raw_string)
return false;
if (has_conv) {
diff --git a/libc/src/stdio/printf_core/file_writer.cpp b/libc/src/stdio/printf_core/file_writer.cpp
index 888c5ecbb60ff..7e0dd1b678e7b 100644
--- a/libc/src/stdio/printf_core/file_writer.cpp
+++ b/libc/src/stdio/printf_core/file_writer.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "src/stdio/printf_core/file_writer.h"
+#include "src/__support/CPP/string_view.h"
#include "src/__support/File/file.h"
#include "src/stdio/printf_core/core_structs.h"
#include <stddef.h>
@@ -23,10 +24,29 @@ int FileWriter::write(const char *__restrict to_write, size_t len) {
return written;
}
-int write_to_file(void *raw_pointer, const char *__restrict to_write,
- size_t len) {
+int FileWriter::write_str(void *raw_pointer, cpp::string_view new_string) {
FileWriter *file_writer = reinterpret_cast<FileWriter *>(raw_pointer);
- return file_writer->write(to_write, len);
+ return file_writer->write(new_string.data(), new_string.size());
+}
+
+int FileWriter::write_chars(void *raw_pointer, char new_char, size_t len) {
+ FileWriter *file_writer = reinterpret_cast<FileWriter *>(raw_pointer);
+ constexpr size_t BUFF_SIZE = 8;
+ char buff[BUFF_SIZE] = {new_char};
+ int result;
+ while (len > BUFF_SIZE) {
+ result = file_writer->write(buff, BUFF_SIZE);
+ if (result < 0)
+ return result;
+ len -= BUFF_SIZE;
+ }
+ return file_writer->write(buff, len);
+}
+
+// TODO(michaelrj): Move this to putc_unlocked once that is available.
+int FileWriter::write_char(void *raw_pointer, char new_char) {
+ FileWriter *file_writer = reinterpret_cast<FileWriter *>(raw_pointer);
+ return file_writer->write(&new_char, 1);
}
} // namespace printf_core
diff --git a/libc/src/stdio/printf_core/file_writer.h b/libc/src/stdio/printf_core/file_writer.h
index 9e4eb331687f2..6ba1428a160e2 100644
--- a/libc/src/stdio/printf_core/file_writer.h
+++ b/libc/src/stdio/printf_core/file_writer.h
@@ -9,6 +9,7 @@
#ifndef LLVM_LIBC_SRC_STDIO_PRINTF_CORE_FILE_WRITER_H
#define LLVM_LIBC_SRC_STDIO_PRINTF_CORE_FILE_WRITER_H
+#include "src/__support/CPP/string_view.h"
#include "src/__support/File/file.h"
#include <stddef.h>
@@ -29,12 +30,13 @@ class FileWriter {
~FileWriter() { file->unlock(); }
int write(const char *__restrict to_write, size_t len);
-};
-// write_to_file treats raw_pointer as a File and calls its write
-// function.
-int write_to_file(void *raw_pointer, const char *__restrict to_write,
- size_t len);
+ // These write functions take a FileWriter as a void* in raw_pointer, and
+ // call the appropriate write function on it.
+ static int write_str(void *raw_pointer, cpp::string_view new_string);
+ static int write_chars(void *raw_pointer, char new_char, size_t len);
+ static int write_char(void *raw_pointer, char new_char);
+};
} // namespace printf_core
} // namespace __llvm_libc
diff --git a/libc/src/stdio/printf_core/float_hex_converter.h b/libc/src/stdio/printf_core/float_hex_converter.h
index 0844f4cb0e809..9cc3b14b5ae4a 100644
--- a/libc/src/stdio/printf_core/float_hex_converter.h
+++ b/libc/src/stdio/printf_core/float_hex_converter.h
@@ -9,6 +9,7 @@
#ifndef LLVM_LIBC_SRC_STDIO_PRINTF_CORE_FLOAT_HEX_CONVERTER_H
#define LLVM_LIBC_SRC_STDIO_PRINTF_CORE_FLOAT_HEX_CONVERTER_H
+#include "src/__support/CPP/string_view.h"
#include "src/__support/FPUtil/FEnvImpl.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/stdio/printf_core/converter_utils.h"
@@ -193,6 +194,7 @@ int inline convert_float_hex_exp(Writer *writer, const FormatSection &to_conv) {
char prefix[PREFIX_LEN];
prefix[0] = '0';
prefix[1] = a + ('x' - 'a');
+ const cpp::string_view prefix_str(prefix, PREFIX_LEN);
// If the precision is greater than the actual result, pad with 0s
if (to_conv.precision > static_cast<int>(mant_digits - 1))
@@ -201,7 +203,7 @@ int inline convert_float_hex_exp(Writer *writer, const FormatSection &to_conv) {
bool has_hexadecimal_point =
(mant_digits > 1) || ((to_conv.flags & FormatFlags::ALTERNATE_FORM) ==
FormatFlags::ALTERNATE_FORM);
- constexpr char HEXADECIMAL_POINT = '.';
+ constexpr cpp::string_view HEXADECIMAL_POINT(".");
// This is for the letter 'p' before the exponent.
const char exp_seperator = a + ('p' - 'a');
@@ -218,42 +220,42 @@ int inline convert_float_hex_exp(Writer *writer, const FormatSection &to_conv) {
// The pattern is (sign), 0x, digit, (.), (other digits), (zeroes), p,
// exponent, (spaces)
if (sign_char > 0)
- RET_IF_RESULT_NEGATIVE(writer->write(&sign_char, 1));
- RET_IF_RESULT_NEGATIVE(writer->write(prefix, PREFIX_LEN));
- RET_IF_RESULT_NEGATIVE(writer->write(mant_buffer, 1));
+ RET_IF_RESULT_NEGATIVE(writer->write(sign_char));
+ RET_IF_RESULT_NEGATIVE(writer->write(prefix_str));
+ RET_IF_RESULT_NEGATIVE(writer->write(mant_buffer[0]));
if (has_hexadecimal_point)
- RET_IF_RESULT_NEGATIVE(writer->write(&HEXADECIMAL_POINT, 1));
+ RET_IF_RESULT_NEGATIVE(writer->write(HEXADECIMAL_POINT));
if (mant_digits > 1)
- RET_IF_RESULT_NEGATIVE(writer->write(mant_buffer + 1, mant_digits - 1));
+ RET_IF_RESULT_NEGATIVE(writer->write({mant_buffer + 1, mant_digits - 1}));
if (trailing_zeroes > 0)
- RET_IF_RESULT_NEGATIVE(writer->write_chars('0', trailing_zeroes));
- RET_IF_RESULT_NEGATIVE(writer->write(&exp_seperator, EXP_SEPERATOR_LEN));
+ RET_IF_RESULT_NEGATIVE(writer->write('0', trailing_zeroes));
+ RET_IF_RESULT_NEGATIVE(writer->write(exp_seperator));
RET_IF_RESULT_NEGATIVE(
- writer->write(exp_buffer + exp_cur, EXP_LEN - exp_cur));
+ writer->write({exp_buffer + exp_cur, EXP_LEN - exp_cur}));
if (padding > 0)
- RET_IF_RESULT_NEGATIVE(writer->write_chars(' ', padding));
+ RET_IF_RESULT_NEGATIVE(writer->write(' ', padding));
} else {
// The pattern is (spaces), (sign), 0x, (zeroes), digit, (.), (other
// digits), (zeroes), p, exponent
if ((padding > 0) && ((to_conv.flags & FormatFlags::LEADING_ZEROES) !=
FormatFlags::LEADING_ZEROES))
- RET_IF_RESULT_NEGATIVE(writer->write_chars(' ', padding));
+ RET_IF_RESULT_NEGATIVE(writer->write(' ', padding));
if (sign_char > 0)
- RET_IF_RESULT_NEGATIVE(writer->write(&sign_char, 1));
- RET_IF_RESULT_NEGATIVE(writer->write(prefix, PREFIX_LEN));
+ RET_IF_RESULT_NEGATIVE(writer->write(sign_char));
+ RET_IF_RESULT_NEGATIVE(writer->write(prefix_str));
if ((padding > 0) && ((to_conv.flags & FormatFlags::LEADING_ZEROES) ==
FormatFlags::LEADING_ZEROES))
- RET_IF_RESULT_NEGATIVE(writer->write_chars('0', padding));
- RET_IF_RESULT_NEGATIVE(writer->write(mant_buffer, 1));
+ RET_IF_RESULT_NEGATIVE(writer->write('0', padding));
+ RET_IF_RESULT_NEGATIVE(writer->write(mant_buffer[0]));
if (has_hexadecimal_point)
- RET_IF_RESULT_NEGATIVE(writer->write(&HEXADECIMAL_POINT, 1));
+ RET_IF_RESULT_NEGATIVE(writer->write(HEXADECIMAL_POINT));
if (mant_digits > 1)
- RET_IF_RESULT_NEGATIVE(writer->write(mant_buffer + 1, mant_digits - 1));
+ RET_IF_RESULT_NEGATIVE(writer->write({mant_buffer + 1, mant_digits - 1}));
if (trailing_zeroes > 0)
- RET_IF_RESULT_NEGATIVE(writer->write_chars('0', trailing_zeroes));
- RET_IF_RESULT_NEGATIVE(writer->write(&exp_seperator, EXP_SEPERATOR_LEN));
+ RET_IF_RESULT_NEGATIVE(writer->write('0', trailing_zeroes));
+ RET_IF_RESULT_NEGATIVE(writer->write(exp_seperator));
RET_IF_RESULT_NEGATIVE(
- writer->write(exp_buffer + exp_cur, EXP_LEN - exp_cur));
+ writer->write({exp_buffer + exp_cur, EXP_LEN - exp_cur}));
}
return WRITE_OK;
}
diff --git a/libc/src/stdio/printf_core/float_inf_nan_converter.h b/libc/src/stdio/printf_core/float_inf_nan_converter.h
index 640612e1b6d4d..35c5f44ba8125 100644
--- a/libc/src/stdio/printf_core/float_inf_nan_converter.h
+++ b/libc/src/stdio/printf_core/float_inf_nan_converter.h
@@ -59,19 +59,19 @@ int inline convert_inf_nan(Writer *writer, const FormatSection &to_conv) {
if (padding > 0 && ((to_conv.flags & FormatFlags::LEFT_JUSTIFIED) !=
FormatFlags::LEFT_JUSTIFIED))
- RET_IF_RESULT_NEGATIVE(writer->write_chars(' ', padding));
+ RET_IF_RESULT_NEGATIVE(writer->write(' ', padding));
if (sign_char)
- RET_IF_RESULT_NEGATIVE(writer->write(&sign_char, 1));
+ RET_IF_RESULT_NEGATIVE(writer->write(sign_char));
if (mantissa == 0) { // inf
- RET_IF_RESULT_NEGATIVE(writer->write((a == 'a' ? "inf" : "INF"), 3));
+ RET_IF_RESULT_NEGATIVE(writer->write(a == 'a' ? "inf" : "INF"));
} else { // nan
- RET_IF_RESULT_NEGATIVE(writer->write((a == 'a' ? "nan" : "NAN"), 3));
+ RET_IF_RESULT_NEGATIVE(writer->write(a == 'a' ? "nan" : "NAN"));
}
if (padding > 0 && ((to_conv.flags & FormatFlags::LEFT_JUSTIFIED) ==
FormatFlags::LEFT_JUSTIFIED))
- RET_IF_RESULT_NEGATIVE(writer->write_chars(' ', padding));
+ RET_IF_RESULT_NEGATIVE(writer->write(' ', padding));
return WRITE_OK;
}
diff --git a/libc/src/stdio/printf_core/int_converter.h b/libc/src/stdio/printf_core/int_converter.h
index 219605e672ccf..4479ec6e88e42 100644
--- a/libc/src/stdio/printf_core/int_converter.h
+++ b/libc/src/stdio/printf_core/int_converter.h
@@ -27,8 +27,9 @@ namespace printf_core {
constexpr char inline to_lower(char a) { return a | 32; }
constexpr bool inline is_lower(char a) { return (a & 32) > 0; }
-cpp::optional<cpp::string_view> inline num_to_strview(
- uintmax_t num, cpp::span<char> bufref, char conv_name) {
+cpp::optional<cpp::string_view> inline num_to_strview(uintmax_t num,
+ cpp::span<char> bufref,
+ char conv_name) {
if (to_lower(conv_name) == 'x') {
return IntegerToString::hex(num, bufref, is_lower(conv_name));
} else if (conv_name == 'o') {
@@ -88,7 +89,7 @@ int inline convert_int(Writer *writer, const FormatSection &to_conv) {
// prefix is "0x" for hexadecimal, or the sign character for signed
// conversions. Since hexadecimal is unsigned these will never conflict.
- int prefix_len;
+ size_t prefix_len;
char prefix[2];
if ((to_lower(to_conv.conv_name) == 'x') &&
((flags & FormatFlags::ALTERNATE_FORM) != 0)) {
@@ -141,23 +142,23 @@ int inline convert_int(Writer *writer, const FormatSection &to_conv) {
if ((flags & FormatFlags::LEFT_JUSTIFIED) == FormatFlags::LEFT_JUSTIFIED) {
// If left justified it goes prefix zeroes digits spaces
if (prefix_len != 0)
- RET_IF_RESULT_NEGATIVE(writer->write(prefix, prefix_len));
+ RET_IF_RESULT_NEGATIVE(writer->write({prefix, prefix_len}));
if (zeroes > 0)
- RET_IF_RESULT_NEGATIVE(writer->write_chars('0', zeroes));
+ RET_IF_RESULT_NEGATIVE(writer->write('0', zeroes));
if (digits_written > 0)
- RET_IF_RESULT_NEGATIVE(writer->write(str->data(), digits_written));
+ RET_IF_RESULT_NEGATIVE(writer->write(*str));
if (spaces > 0)
- RET_IF_RESULT_NEGATIVE(writer->write_chars(' ', spaces));
+ RET_IF_RESULT_NEGATIVE(writer->write(' ', spaces));
} else {
// Else it goes spaces prefix zeroes digits
if (spaces > 0)
- RET_IF_RESULT_NEGATIVE(writer->write_chars(' ', spaces));
+ RET_IF_RESULT_NEGATIVE(writer->write(' ', spaces));
if (prefix_len != 0)
- RET_IF_RESULT_NEGATIVE(writer->write(prefix, prefix_len));
+ RET_IF_RESULT_NEGATIVE(writer->write({prefix, prefix_len}));
if (zeroes > 0)
- RET_IF_RESULT_NEGATIVE(writer->write_chars('0', zeroes));
+ RET_IF_RESULT_NEGATIVE(writer->write('0', zeroes));
if (digits_written > 0)
- RET_IF_RESULT_NEGATIVE(writer->write(str->data(), digits_written));
+ RET_IF_RESULT_NEGATIVE(writer->write(*str));
}
return WRITE_OK;
}
diff --git a/libc/src/stdio/printf_core/parser.cpp b/libc/src/stdio/printf_core/parser.cpp
index d2f0b89b0f1ba..38d2e1e69cf92 100644
--- a/libc/src/stdio/printf_core/parser.cpp
+++ b/libc/src/stdio/printf_core/parser.cpp
@@ -13,6 +13,7 @@
#include "src/__support/arg_list.h"
#include "src/__support/CPP/bit.h"
+#include "src/__support/CPP/string_view.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/ctype_utils.h"
#include "src/__support/str_to_integer.h"
@@ -28,7 +29,6 @@ namespace printf_core {
FormatSection Parser::get_next_section() {
FormatSection section;
- section.raw_string = str + cur_pos;
size_t starting_pos = cur_pos;
if (str[cur_pos] == '%') {
// format section
@@ -158,7 +158,7 @@ FormatSection Parser::get_next_section() {
while (str[cur_pos] != '%' && str[cur_pos] != '\0')
++cur_pos;
}
- section.raw_len = cur_pos - starting_pos;
+ section.raw_string = {str + starting_pos, cur_pos - starting_pos};
return section;
}
diff --git a/libc/src/stdio/printf_core/parser.h b/libc/src/stdio/printf_core/parser.h
index 25dd0f65e8171..3d47f6af39bf4 100644
--- a/libc/src/stdio/printf_core/parser.h
+++ b/libc/src/stdio/printf_core/parser.h
@@ -11,7 +11,6 @@
#include "src/__support/arg_list.h"
#include "src/stdio/printf_core/core_structs.h"
-#include "src/string/memory_utils/memset_implementations.h"
#include <stddef.h>
@@ -49,7 +48,7 @@ class Parser {
// TypeDesc objects, which store the size as well as minimal type information.
// This is necessary because some systems separate the floating point and
// integer values in va_args.
- TypeDesc desc_arr[DESC_ARR_LEN];
+ TypeDesc desc_arr[DESC_ARR_LEN] = {{0, Integer}};;
// TODO: Look into object stores for optimization.
@@ -58,10 +57,7 @@ class Parser {
public:
#ifndef LLVM_LIBC_PRINTF_DISABLE_INDEX_MODE
Parser(const char *__restrict new_str, internal::ArgList &args)
- : str(new_str), args_cur(args), args_start(args) {
- inline_memset(reinterpret_cast<char *>(desc_arr), 0,
- DESC_ARR_LEN * sizeof(TypeDesc));
- }
+ : str(new_str), args_cur(args), args_start(args) {}
#else
Parser(const char *__restrict new_str, internal::ArgList &args)
: str(new_str), args_cur(args) {}
diff --git a/libc/src/stdio/printf_core/printf_main.cpp b/libc/src/stdio/printf_core/printf_main.cpp
index fb46da46e074d..b7684cdf1e74f 100644
--- a/libc/src/stdio/printf_core/printf_main.cpp
+++ b/libc/src/stdio/printf_core/printf_main.cpp
@@ -24,11 +24,12 @@ int printf_main(Writer *writer, const char *__restrict str,
Parser parser(str, args);
int result = 0;
for (FormatSection cur_section = parser.get_next_section();
- cur_section.raw_len > 0; cur_section = parser.get_next_section()) {
+ !cur_section.raw_string.empty();
+ cur_section = parser.get_next_section()) {
if (cur_section.has_conv)
result = convert(writer, cur_section);
else
- result = writer->write(cur_section.raw_string, cur_section.raw_len);
+ result = writer->write(cur_section.raw_string);
if (result < 0)
return result;
diff --git a/libc/src/stdio/printf_core/ptr_converter.h b/libc/src/stdio/printf_core/ptr_converter.h
index 17c05924bcc66..a2738447c0dc4 100644
--- a/libc/src/stdio/printf_core/ptr_converter.h
+++ b/libc/src/stdio/printf_core/ptr_converter.h
@@ -9,6 +9,7 @@
#ifndef LLVM_LIBC_SRC_STDIO_PRINTF_CORE_PTR_CONVERTER_H
#define LLVM_LIBC_SRC_STDIO_PRINTF_CORE_PTR_CONVERTER_H
+#include "src/__support/CPP/string_view.h"
#include "src/stdio/printf_core/converter_utils.h"
#include "src/stdio/printf_core/core_structs.h"
#include "src/stdio/printf_core/int_converter.h"
@@ -19,9 +20,7 @@ namespace printf_core {
int inline convert_pointer(Writer *writer, const FormatSection &to_conv) {
if (to_conv.conv_val_ptr == (void *)(nullptr)) {
- const char ZERO_STR[] = "(nullptr)";
- // subtract 1 from sizeof to remove the null byte at the end.
- RET_IF_RESULT_NEGATIVE(writer->write(ZERO_STR, sizeof(ZERO_STR) - 1));
+ RET_IF_RESULT_NEGATIVE(writer->write("(nullptr)"));
} else {
FormatSection hex_conv;
hex_conv.has_conv = true;
diff --git a/libc/src/stdio/printf_core/string_converter.h b/libc/src/stdio/printf_core/string_converter.h
index eaf9b9987620c..e10ecd6f9f55d 100644
--- a/libc/src/stdio/printf_core/string_converter.h
+++ b/libc/src/stdio/printf_core/string_converter.h
@@ -9,6 +9,7 @@
#ifndef LLVM_LIBC_SRC_STDIO_PRINTF_CORE_STRING_CONVERTER_H
#define LLVM_LIBC_SRC_STDIO_PRINTF_CORE_STRING_CONVERTER_H
+#include "src/__support/CPP/string_view.h"
#include "src/stdio/printf_core/converter_utils.h"
#include "src/stdio/printf_core/core_structs.h"
#include "src/stdio/printf_core/writer.h"
@@ -19,33 +20,34 @@ namespace __llvm_libc {
namespace printf_core {
int inline convert_string(Writer *writer, const FormatSection &to_conv) {
- int string_len = 0;
+ size_t string_len = 0;
for (char *cur_str = reinterpret_cast<char *>(to_conv.conv_val_ptr);
cur_str[string_len]; ++string_len) {
;
}
- if (to_conv.precision >= 0 && to_conv.precision < string_len)
+ if (to_conv.precision >= 0 &&
+ static_cast<size_t>(to_conv.precision) < string_len)
string_len = to_conv.precision;
- if (to_conv.min_width > string_len) {
- if ((to_conv.flags & FormatFlags::LEFT_JUSTIFIED) ==
- FormatFlags::LEFT_JUSTIFIED) {
- RET_IF_RESULT_NEGATIVE(writer->write(
- reinterpret_cast<const char *>(to_conv.conv_val_ptr), string_len));
- RET_IF_RESULT_NEGATIVE(
- writer->write_chars(' ', to_conv.min_width - string_len));
-
- } else {
- RET_IF_RESULT_NEGATIVE(
- writer->write_chars(' ', to_conv.min_width - string_len));
- RET_IF_RESULT_NEGATIVE(writer->write(
- reinterpret_cast<const char *>(to_conv.conv_val_ptr), string_len));
- }
- } else {
- RET_IF_RESULT_NEGATIVE(writer->write(
- reinterpret_cast<const char *>(to_conv.conv_val_ptr), string_len));
+ size_t padding_spaces = to_conv.min_width > static_cast<int>(string_len)
+ ? to_conv.min_width - string_len
+ : 0;
+
+ // If the padding is on the left side, write the spaces first.
+ if (padding_spaces > 0 &&
+ (to_conv.flags & FormatFlags::LEFT_JUSTIFIED) == 0) {
+ RET_IF_RESULT_NEGATIVE(writer->write(' ', to_conv.min_width - string_len));
+ }
+
+ RET_IF_RESULT_NEGATIVE(writer->write(
+ {reinterpret_cast<const char *>(to_conv.conv_val_ptr), string_len}));
+
+ // If the padding is on the right side, write the spaces last.
+ if (padding_spaces > 0 &&
+ (to_conv.flags & FormatFlags::LEFT_JUSTIFIED) != 0) {
+ RET_IF_RESULT_NEGATIVE(writer->write(' ', to_conv.min_width - string_len));
}
return WRITE_OK;
}
diff --git a/libc/src/stdio/printf_core/string_writer.cpp b/libc/src/stdio/printf_core/string_writer.cpp
index 1e95ec805dcd4..a80df32d40a02 100644
--- a/libc/src/stdio/printf_core/string_writer.cpp
+++ b/libc/src/stdio/printf_core/string_writer.cpp
@@ -7,28 +7,62 @@
//===----------------------------------------------------------------------===//
#include "src/stdio/printf_core/string_writer.h"
+#include "src/__support/CPP/string_view.h"
#include "src/stdio/printf_core/core_structs.h"
#include "src/string/memory_utils/memcpy_implementations.h"
+#include "src/string/memory_utils/memset_implementations.h"
#include <stddef.h>
namespace __llvm_libc {
namespace printf_core {
-void StringWriter::write(const char *__restrict to_write, size_t len) {
+void StringWriter::write(cpp::string_view new_string) {
+ size_t len = new_string.size();
if (len > available_capacity)
len = available_capacity;
if (len > 0) {
- inline_memcpy(cur_buffer, to_write, len);
+ inline_memcpy(cur_buffer, new_string.data(), len);
cur_buffer += len;
available_capacity -= len;
}
}
-int write_to_string(void *raw_pointer, const char *__restrict to_write,
- size_t len) {
+void StringWriter::write(char new_char, size_t len) {
+ if (len > available_capacity)
+ len = available_capacity;
+
+ if (len > 0) {
+ inline_memset(cur_buffer, new_char, len);
+ cur_buffer += len;
+ available_capacity -= len;
+ }
+}
+
+void StringWriter::write(char new_char) {
+ if (1 > available_capacity)
+ return;
+
+ cur_buffer[0] = new_char;
+ ++cur_buffer;
+ available_capacity -= 1;
+}
+
+int StringWriter::write_str(void *raw_pointer, cpp::string_view new_string) {
+ StringWriter *string_writer = reinterpret_cast<StringWriter *>(raw_pointer);
+ string_writer->write(new_string);
+ return WRITE_OK;
+}
+
+int StringWriter::write_chars(void *raw_pointer, char new_char, size_t len) {
+ StringWriter *string_writer = reinterpret_cast<StringWriter *>(raw_pointer);
+ string_writer->write(new_char, len);
+ return WRITE_OK;
+}
+
+int StringWriter::write_char(void *raw_pointer, char new_char) {
StringWriter *string_writer = reinterpret_cast<StringWriter *>(raw_pointer);
- string_writer->write(to_write, len);
+ string_writer->write(new_char);
return WRITE_OK;
}
diff --git a/libc/src/stdio/printf_core/string_writer.h b/libc/src/stdio/printf_core/string_writer.h
index bcf040b9b16f5..9d2578904c734 100644
--- a/libc/src/stdio/printf_core/string_writer.h
+++ b/libc/src/stdio/printf_core/string_writer.h
@@ -9,6 +9,7 @@
#ifndef LLVM_LIBC_SRC_STDIO_PRINTF_CORE_STRING_WRITER_H
#define LLVM_LIBC_SRC_STDIO_PRINTF_CORE_STRING_WRITER_H
+#include "src/__support/CPP/string_view.h"
#include "src/string/memory_utils/memcpy_implementations.h"
#include <stddef.h>
@@ -26,18 +27,21 @@ class StringWriter {
StringWriter(char *__restrict buffer, size_t max_len = ~size_t(0))
: cur_buffer(buffer), available_capacity(max_len) {}
- void write(const char *__restrict to_write, size_t len);
+ void write(cpp::string_view new_string);
+ void write(char new_char, size_t len);
+ void write(char new_char);
// Terminate should only be called if the original max length passed to
// snprintf was greater than 0. It writes a null byte to the end of the
// cur_buffer, regardless of available_capacity.
void terminate() { *cur_buffer = '\0'; }
-};
-// write_to_string treats raw_pointer as a StringWriter and calls its write
-// function.
-int write_to_string(void *raw_pointer, const char *__restrict to_write,
- size_t len);
+ // These write functions take a StringWriter as a void* in raw_pointer, and
+ // call the appropriate write function on it.
+ static int write_str(void *raw_pointer, cpp::string_view new_string);
+ static int write_chars(void *raw_pointer, char new_char, size_t len);
+ static int write_char(void *raw_pointer, char new_char);
+};
} // namespace printf_core
} // namespace __llvm_libc
diff --git a/libc/src/stdio/printf_core/vfprintf_internal.cpp b/libc/src/stdio/printf_core/vfprintf_internal.cpp
index 479bf1acc6260..b25d545e54a11 100644
--- a/libc/src/stdio/printf_core/vfprintf_internal.cpp
+++ b/libc/src/stdio/printf_core/vfprintf_internal.cpp
@@ -22,7 +22,9 @@ int vfprintf_internal(::FILE *__restrict stream, const char *__restrict format,
internal::ArgList &args) {
FileWriter file_writer(stream);
printf_core::Writer writer(reinterpret_cast<void *>(&file_writer),
- printf_core::write_to_file);
+ printf_core::FileWriter::write_str,
+ printf_core::FileWriter::write_chars,
+ printf_core::FileWriter::write_char);
return printf_core::printf_main(&writer, format, args);
}
diff --git a/libc/src/stdio/printf_core/writer.cpp b/libc/src/stdio/printf_core/writer.cpp
index fe48414837189..825697103492c 100644
--- a/libc/src/stdio/printf_core/writer.cpp
+++ b/libc/src/stdio/printf_core/writer.cpp
@@ -7,29 +7,25 @@
//===----------------------------------------------------------------------===//
#include "writer.h"
-#include "src/string/memory_utils/memset_implementations.h"
+#include "src/__support/CPP/string_view.h"
#include <stddef.h>
namespace __llvm_libc {
namespace printf_core {
-int Writer::write(const char *new_string, size_t length) {
+int Writer::write(cpp::string_view new_string) {
+ chars_written += new_string.size();
+ return str_write(output, new_string);
+}
+
+int Writer::write(char new_char, size_t length) {
chars_written += length;
- return raw_write(output, new_string, length);
+ return chars_write(output, new_char, length);
}
-int Writer::write_chars(char new_char, size_t length) {
- constexpr size_t BUFF_SIZE = 8;
- char buff[BUFF_SIZE];
- int result;
- inline_memset(buff, new_char, BUFF_SIZE);
- while (length > BUFF_SIZE) {
- result = write(buff, BUFF_SIZE);
- if (result < 0)
- return result;
- length -= BUFF_SIZE;
- }
- return write(buff, length);
+int Writer::write(char new_char) {
+ chars_written += 1;
+ return char_write(output, new_char);
}
} // namespace printf_core
diff --git a/libc/src/stdio/printf_core/writer.h b/libc/src/stdio/printf_core/writer.h
index c8a9f7d7e8786..b5c36bf38e814 100644
--- a/libc/src/stdio/printf_core/writer.h
+++ b/libc/src/stdio/printf_core/writer.h
@@ -9,12 +9,15 @@
#ifndef LLVM_LIBC_SRC_STDIO_PRINTF_CORE_WRITER_H
#define LLVM_LIBC_SRC_STDIO_PRINTF_CORE_WRITER_H
+#include "src/__support/CPP/string_view.h"
#include <stddef.h>
namespace __llvm_libc {
namespace printf_core {
-using WriteFunc = int (*)(void *, const char *__restrict, size_t);
+using WriteStrFunc = int (*)(void *, cpp::string_view);
+using WriteCharsFunc = int (*)(void *, char, size_t);
+using WriteCharFunc = int (*)(void *, char);
class Writer final {
// output is a pointer to the string or file that the writer is meant to write
@@ -25,23 +28,31 @@ class Writer final {
// length, will copy the number of bytes equal to the length from the char*
// onto the end of output. It should return a positive number or zero on
// success, or a negative number on failure.
- WriteFunc raw_write;
+ WriteStrFunc str_write;
+ WriteCharsFunc chars_write;
+ WriteCharFunc char_write;
int chars_written = 0;
public:
- Writer(void *init_output, WriteFunc init_raw_write)
- : output(init_output), raw_write(init_raw_write) {}
-
- // write will copy length bytes from new_string into output using
- // raw_write. It increments chars_written by length always. It returns the
- // result of raw_write.
- int write(const char *new_string, size_t length);
-
- // write_chars will copy length copies of new_char into output using the write
- // function and a statically sized buffer. This is primarily used for padding.
- // If write returns a negative value, this will return early with that value.
- int write_chars(char new_char, size_t length);
+ Writer(void *init_output, WriteStrFunc init_str_write,
+ WriteCharsFunc init_chars_write, WriteCharFunc init_char_write)
+ : output(init_output), str_write(init_str_write),
+ chars_write(init_chars_write), char_write(init_char_write) {}
+
+ // write will copy new_string into output using str_write. It increments
+ // chars_written by the length of new_string. It returns the result of
+ // str_write.
+ int write(cpp::string_view new_string);
+
+ // this version of write will copy length copies of new_char into output using
+ // chars_write. This is primarily used for padding. It returns the result of
+ // chars_write.
+ int write(char new_char, size_t len);
+
+ // this version of write will copy just new_char into output. This is often
+ // used for negative signs. It returns the result of chars_write.
+ int write(char new_char);
int get_chars_written() { return chars_written; }
};
diff --git a/libc/src/stdio/snprintf.cpp b/libc/src/stdio/snprintf.cpp
index ecc5fc94e6e8c..571a547ed8f2d 100644
--- a/libc/src/stdio/snprintf.cpp
+++ b/libc/src/stdio/snprintf.cpp
@@ -29,7 +29,9 @@ LLVM_LIBC_FUNCTION(int, snprintf,
va_end(vlist);
printf_core::StringWriter str_writer(buffer, (buffsz > 0 ? buffsz - 1 : 0));
printf_core::Writer writer(reinterpret_cast<void *>(&str_writer),
- printf_core::write_to_string);
+ printf_core::StringWriter::write_str,
+ printf_core::StringWriter::write_chars,
+ printf_core::StringWriter::write_char);
int ret_val = printf_core::printf_main(&writer, format, args);
if (buffsz > 0) // if the buffsz is 0 the buffer may be a null pointer.
diff --git a/libc/src/stdio/sprintf.cpp b/libc/src/stdio/sprintf.cpp
index 442dbdfb14d11..a97b83e805d1e 100644
--- a/libc/src/stdio/sprintf.cpp
+++ b/libc/src/stdio/sprintf.cpp
@@ -28,7 +28,9 @@ LLVM_LIBC_FUNCTION(int, sprintf,
va_end(vlist);
printf_core::StringWriter str_writer(buffer);
printf_core::Writer writer(reinterpret_cast<void *>(&str_writer),
- printf_core::write_to_string);
+ printf_core::StringWriter::write_str,
+ printf_core::StringWriter::write_chars,
+ printf_core::StringWriter::write_char);
int ret_val = printf_core::printf_main(&writer, format, args);
str_writer.terminate();
diff --git a/libc/test/src/stdio/printf_core/CMakeLists.txt b/libc/test/src/stdio/printf_core/CMakeLists.txt
index 3b38f2ccdb1a7..7636eec138d38 100644
--- a/libc/test/src/stdio/printf_core/CMakeLists.txt
+++ b/libc/test/src/stdio/printf_core/CMakeLists.txt
@@ -9,6 +9,7 @@ add_libc_unittest(
DEPENDS
libc.src.stdio.printf_core.parser
libc.src.stdio.printf_core.core_structs
+ libc.src.__support.CPP.string_view
libc.src.__support.arg_list
)
@@ -21,6 +22,7 @@ add_libc_unittest(
DEPENDS
libc.src.stdio.printf_core.writer
libc.src.stdio.printf_core.string_writer
+ libc.src.__support.CPP.string_view
)
add_libc_unittest(
diff --git a/libc/test/src/stdio/printf_core/converter_test.cpp b/libc/test/src/stdio/printf_core/converter_test.cpp
index 62a7356ec787c..ac79d67d75dfb 100644
--- a/libc/test/src/stdio/printf_core/converter_test.cpp
+++ b/libc/test/src/stdio/printf_core/converter_test.cpp
@@ -23,14 +23,15 @@ class LlvmLibcPrintfConverterTest : public __llvm_libc::testing::Test {
__llvm_libc::printf_core::StringWriter(str);
__llvm_libc::printf_core::Writer writer = __llvm_libc::printf_core::Writer(
reinterpret_cast<void *>(&str_writer),
- __llvm_libc::printf_core::write_to_string);
+ __llvm_libc::printf_core::StringWriter::write_str,
+ __llvm_libc::printf_core::StringWriter::write_chars,
+ __llvm_libc::printf_core::StringWriter::write_char);
};
TEST_F(LlvmLibcPrintfConverterTest, SimpleRawConversion) {
__llvm_libc::printf_core::FormatSection raw_section;
raw_section.has_conv = false;
raw_section.raw_string = "abc";
- raw_section.raw_len = 3;
__llvm_libc::printf_core::convert(&writer, raw_section);
@@ -196,17 +197,10 @@ TEST_F(LlvmLibcPrintfConverterTest, IntConversionSimple) {
ASSERT_EQ(writer.get_chars_written(), 5);
}
-TEST(LlvmLibcPrintfConverterTest, HexConversion) {
- char str[20];
- __llvm_libc::printf_core::StringWriter str_writer(str);
- __llvm_libc::printf_core::Writer writer(
- reinterpret_cast<void *>(&str_writer),
- __llvm_libc::printf_core::write_to_string);
-
+TEST_F(LlvmLibcPrintfConverterTest, HexConversion) {
__llvm_libc::printf_core::FormatSection section;
section.has_conv = true;
section.raw_string = "%#018x";
- section.raw_len = 6;
section.conv_name = 'x';
section.flags = static_cast<__llvm_libc::printf_core::FormatFlags>(
__llvm_libc::printf_core::FormatFlags::ALTERNATE_FORM |
@@ -220,17 +214,11 @@ TEST(LlvmLibcPrintfConverterTest, HexConversion) {
ASSERT_EQ(writer.get_chars_written(), 18);
}
-TEST(LlvmLibcPrintfConverterTest, PointerConversion) {
- char str[20];
- __llvm_libc::printf_core::StringWriter str_writer(str);
- __llvm_libc::printf_core::Writer writer(
- reinterpret_cast<void *>(&str_writer),
- __llvm_libc::printf_core::write_to_string);
+TEST_F(LlvmLibcPrintfConverterTest, PointerConversion) {
__llvm_libc::printf_core::FormatSection section;
section.has_conv = true;
section.raw_string = "%p";
- section.raw_len = 2;
section.conv_name = 'p';
section.conv_val_ptr = (void *)(0x123456ab);
__llvm_libc::printf_core::convert(&writer, section);
@@ -240,17 +228,11 @@ TEST(LlvmLibcPrintfConverterTest, PointerConversion) {
ASSERT_EQ(writer.get_chars_written(), 10);
}
-TEST(LlvmLibcPrintfConverterTest, OctConversion) {
- char str[20];
- __llvm_libc::printf_core::StringWriter str_writer(str);
- __llvm_libc::printf_core::Writer writer(
- reinterpret_cast<void *>(&str_writer),
- __llvm_libc::printf_core::write_to_string);
+TEST_F(LlvmLibcPrintfConverterTest, OctConversion) {
__llvm_libc::printf_core::FormatSection section;
section.has_conv = true;
section.raw_string = "%o";
- section.raw_len = 2;
section.conv_name = 'o';
section.conv_val_raw = 01234;
__llvm_libc::printf_core::convert(&writer, section);
diff --git a/libc/test/src/stdio/printf_core/parser_test.cpp b/libc/test/src/stdio/printf_core/parser_test.cpp
index d2f32b795ffbd..643c32bd69c91 100644
--- a/libc/test/src/stdio/printf_core/parser_test.cpp
+++ b/libc/test/src/stdio/printf_core/parser_test.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "src/__support/CPP/bit.h"
+#include "src/__support/CPP/string_view.h"
#include "src/__support/arg_list.h"
#include "src/stdio/printf_core/parser.h"
@@ -15,6 +16,8 @@
#include "utils/UnitTest/PrintfMatcher.h"
#include "utils/UnitTest/Test.h"
+using __llvm_libc::cpp::string_view;
+
void init(const char *__restrict str, ...) {
va_list vlist;
va_start(vlist, str);
@@ -33,7 +36,8 @@ void evaluate(__llvm_libc::printf_core::FormatSection *format_arr,
__llvm_libc::printf_core::Parser parser(str, v);
- for (auto cur_section = parser.get_next_section(); cur_section.raw_len > 0;
+ for (auto cur_section = parser.get_next_section();
+ !cur_section.raw_string.empty();
cur_section = parser.get_next_section()) {
*format_arr = cur_section;
++format_arr;
@@ -49,8 +53,8 @@ TEST(LlvmLibcPrintfParserTest, EvalRaw) {
__llvm_libc::printf_core::FormatSection expected;
expected.has_conv = false;
- expected.raw_len = 4;
- expected.raw_string = str;
+
+ expected.raw_string = {str, 4};
ASSERT_FORMAT_EQ(expected, format_arr[0]);
// TODO: add checks that the format_arr after the last one has length 0
@@ -63,21 +67,21 @@ TEST(LlvmLibcPrintfParserTest, EvalSimple) {
__llvm_libc::printf_core::FormatSection expected0, expected1, expected2;
expected0.has_conv = false;
- expected0.raw_len = 5;
- expected0.raw_string = str;
+
+ expected0.raw_string = {str, 5};
ASSERT_FORMAT_EQ(expected0, format_arr[0]);
expected1.has_conv = true;
- expected1.raw_len = 2;
- expected1.raw_string = str + 5;
+
+ expected1.raw_string = {str + 5, 2};
expected1.conv_name = '%';
ASSERT_FORMAT_EQ(expected1, format_arr[1]);
expected2.has_conv = false;
- expected2.raw_len = 5;
- expected2.raw_string = str + 7;
+
+ expected2.raw_string = {str + 7, 5};
ASSERT_FORMAT_EQ(expected2, format_arr[2]);
}
@@ -90,8 +94,8 @@ TEST(LlvmLibcPrintfParserTest, EvalOneArg) {
__llvm_libc::printf_core::FormatSection expected;
expected.has_conv = true;
- expected.raw_len = 2;
- expected.raw_string = str;
+
+ expected.raw_string = {str, 2};
expected.conv_val_raw = arg1;
expected.conv_name = 'd';
@@ -106,8 +110,8 @@ TEST(LlvmLibcPrintfParserTest, EvalOneArgWithFlags) {
__llvm_libc::printf_core::FormatSection expected;
expected.has_conv = true;
- expected.raw_len = 7;
- expected.raw_string = str;
+
+ expected.raw_string = {str, 7};
expected.flags = static_cast<__llvm_libc::printf_core::FormatFlags>(
__llvm_libc::printf_core::FormatFlags::FORCE_SIGN |
__llvm_libc::printf_core::FormatFlags::LEFT_JUSTIFIED |
@@ -128,8 +132,8 @@ TEST(LlvmLibcPrintfParserTest, EvalOneArgWithWidth) {
__llvm_libc::printf_core::FormatSection expected;
expected.has_conv = true;
- expected.raw_len = 4;
- expected.raw_string = str;
+
+ expected.raw_string = {str, 4};
expected.min_width = 12;
expected.conv_val_raw = arg1;
expected.conv_name = 'd';
@@ -145,8 +149,8 @@ TEST(LlvmLibcPrintfParserTest, EvalOneArgWithPrecision) {
__llvm_libc::printf_core::FormatSection expected;
expected.has_conv = true;
- expected.raw_len = 5;
- expected.raw_string = str;
+
+ expected.raw_string = {str, 5};
expected.precision = 34;
expected.conv_val_raw = arg1;
expected.conv_name = 'd';
@@ -162,8 +166,8 @@ TEST(LlvmLibcPrintfParserTest, EvalOneArgWithTrivialPrecision) {
__llvm_libc::printf_core::FormatSection expected;
expected.has_conv = true;
- expected.raw_len = 3;
- expected.raw_string = str;
+
+ expected.raw_string = {str, 3};
expected.precision = 0;
expected.conv_val_raw = arg1;
expected.conv_name = 'd';
@@ -179,8 +183,8 @@ TEST(LlvmLibcPrintfParserTest, EvalOneArgWithShortLengthModifier) {
__llvm_libc::printf_core::FormatSection expected;
expected.has_conv = true;
- expected.raw_len = 3;
- expected.raw_string = str;
+
+ expected.raw_string = {str, 3};
expected.length_modifier = __llvm_libc::printf_core::LengthModifier::h;
expected.conv_val_raw = arg1;
expected.conv_name = 'd';
@@ -196,8 +200,8 @@ TEST(LlvmLibcPrintfParserTest, EvalOneArgWithLongLengthModifier) {
__llvm_libc::printf_core::FormatSection expected;
expected.has_conv = true;
- expected.raw_len = 4;
- expected.raw_string = str;
+
+ expected.raw_string = {str, 4};
expected.length_modifier = __llvm_libc::printf_core::LengthModifier::ll;
expected.conv_val_raw = arg1;
expected.conv_name = 'd';
@@ -213,8 +217,8 @@ TEST(LlvmLibcPrintfParserTest, EvalOneArgWithAllOptions) {
__llvm_libc::printf_core::FormatSection expected;
expected.has_conv = true;
- expected.raw_len = 11;
- expected.raw_string = str;
+
+ expected.raw_string = {str, 11};
expected.flags = static_cast<__llvm_libc::printf_core::FormatFlags>(
__llvm_libc::printf_core::FormatFlags::LEFT_JUSTIFIED |
__llvm_libc::printf_core::FormatFlags::LEADING_ZEROES |
@@ -238,24 +242,24 @@ TEST(LlvmLibcPrintfParserTest, EvalThreeArgs) {
__llvm_libc::printf_core::FormatSection expected0, expected1, expected2;
expected0.has_conv = true;
- expected0.raw_len = 2;
- expected0.raw_string = str;
+
+ expected0.raw_string = {str, 2};
expected0.conv_val_raw = arg1;
expected0.conv_name = 'd';
ASSERT_FORMAT_EQ(expected0, format_arr[0]);
expected1.has_conv = true;
- expected1.raw_len = 2;
- expected1.raw_string = str + 2;
+
+ expected1.raw_string = {str + 2, 2};
expected1.conv_val_raw = __llvm_libc::cpp::bit_cast<uint64_t>(arg2);
expected1.conv_name = 'f';
ASSERT_FORMAT_EQ(expected1, format_arr[1]);
expected2.has_conv = true;
- expected2.raw_len = 2;
- expected2.raw_string = str + 4;
+
+ expected2.raw_string = {str + 4, 2};
expected2.conv_val_ptr = const_cast<char *>(arg3);
expected2.conv_name = 's';
@@ -272,8 +276,8 @@ TEST(LlvmLibcPrintfParserTest, IndexModeOneArg) {
__llvm_libc::printf_core::FormatSection expected;
expected.has_conv = true;
- expected.raw_len = 4;
- expected.raw_string = str;
+
+ expected.raw_string = {str, 4};
expected.conv_val_raw = arg1;
expected.conv_name = 'd';
@@ -290,24 +294,24 @@ TEST(LlvmLibcPrintfParserTest, IndexModeThreeArgsSequential) {
__llvm_libc::printf_core::FormatSection expected0, expected1, expected2;
expected0.has_conv = true;
- expected0.raw_len = 4;
- expected0.raw_string = str;
+
+ expected0.raw_string = {str, 4};
expected0.conv_val_raw = arg1;
expected0.conv_name = 'd';
ASSERT_FORMAT_EQ(expected0, format_arr[0]);
expected1.has_conv = true;
- expected1.raw_len = 4;
- expected1.raw_string = str + 4;
+
+ expected1.raw_string = {str + 4, 4};
expected1.conv_val_raw = __llvm_libc::cpp::bit_cast<uint64_t>(arg2);
expected1.conv_name = 'f';
ASSERT_FORMAT_EQ(expected1, format_arr[1]);
expected2.has_conv = true;
- expected2.raw_len = 4;
- expected2.raw_string = str + 8;
+
+ expected2.raw_string = {str + 8, 4};
expected2.conv_val_ptr = const_cast<char *>(arg3);
expected2.conv_name = 's';
@@ -324,24 +328,24 @@ TEST(LlvmLibcPrintfParserTest, IndexModeThreeArgsReverse) {
__llvm_libc::printf_core::FormatSection expected0, expected1, expected2;
expected0.has_conv = true;
- expected0.raw_len = 4;
- expected0.raw_string = str;
+
+ expected0.raw_string = {str, 4};
expected0.conv_val_raw = arg1;
expected0.conv_name = 'd';
ASSERT_FORMAT_EQ(expected0, format_arr[0]);
expected1.has_conv = true;
- expected1.raw_len = 4;
- expected1.raw_string = str + 4;
+
+ expected1.raw_string = {str + 4, 4};
expected1.conv_val_raw = __llvm_libc::cpp::bit_cast<uint64_t>(arg2);
expected1.conv_name = 'f';
ASSERT_FORMAT_EQ(expected1, format_arr[1]);
expected2.has_conv = true;
- expected2.raw_len = 4;
- expected2.raw_string = str + 8;
+
+ expected2.raw_string = {str + 8, 4};
expected2.conv_val_ptr = const_cast<char *>(arg3);
expected2.conv_name = 's';
@@ -358,8 +362,9 @@ TEST(LlvmLibcPrintfParserTest, IndexModeTenArgsRandom) {
for (size_t i = 0; i < 10; ++i) {
__llvm_libc::printf_core::FormatSection expected;
expected.has_conv = true;
- expected.raw_len = 4 + (i >= 9 ? 1 : 0);
- expected.raw_string = str + (4 * i);
+
+ expected.raw_string = {str + (4 * i),
+ static_cast<size_t>(4 + (i >= 9 ? 1 : 0))};
expected.conv_val_raw = i + 1;
expected.conv_name = 'd';
EXPECT_FORMAT_EQ(expected, format_arr[i]);
@@ -380,14 +385,14 @@ TEST(LlvmLibcPrintfParserTest, IndexModeComplexParsing) {
expected9;
expected0.has_conv = false;
- expected0.raw_len = 12;
- expected0.raw_string = str;
+
+ expected0.raw_string = {str, 12};
EXPECT_FORMAT_EQ(expected0, format_arr[0]);
expected1.has_conv = true;
- expected1.raw_len = 6;
- expected1.raw_string = str + 12;
+
+ expected1.raw_string = {str + 12, 6};
expected1.length_modifier = __llvm_libc::printf_core::LengthModifier::ll;
expected1.conv_val_raw = arg3;
expected1.conv_name = 'u';
@@ -395,27 +400,27 @@ TEST(LlvmLibcPrintfParserTest, IndexModeComplexParsing) {
EXPECT_FORMAT_EQ(expected1, format_arr[1]);
expected2.has_conv = false;
- expected2.raw_len = 1;
- expected2.raw_string = str + 18;
+
+ expected2.raw_string = {str + 18, 1};
EXPECT_FORMAT_EQ(expected2, format_arr[2]);
expected3.has_conv = true;
- expected3.raw_len = 2;
- expected3.raw_string = str + 19;
+
+ expected3.raw_string = {str + 19, 2};
expected3.conv_name = '%';
EXPECT_FORMAT_EQ(expected3, format_arr[3]);
expected4.has_conv = false;
- expected4.raw_len = 1;
- expected4.raw_string = str + 21;
+
+ expected4.raw_string = {str + 21, 1};
EXPECT_FORMAT_EQ(expected4, format_arr[4]);
expected5.has_conv = true;
- expected5.raw_len = 8;
- expected5.raw_string = str + 22;
+
+ expected5.raw_string = {str + 22, 8};
expected5.flags = __llvm_libc::printf_core::FormatFlags::SPACE_PREFIX;
expected5.min_width = arg4;
expected5.conv_val_raw = __llvm_libc::cpp::bit_cast<uint64_t>(arg2);
@@ -424,14 +429,14 @@ TEST(LlvmLibcPrintfParserTest, IndexModeComplexParsing) {
EXPECT_FORMAT_EQ(expected5, format_arr[5]);
expected6.has_conv = false;
- expected6.raw_len = 1;
- expected6.raw_string = str + 30;
+
+ expected6.raw_string = {str + 30, 1};
EXPECT_FORMAT_EQ(expected6, format_arr[6]);
expected7.has_conv = true;
- expected7.raw_len = 9;
- expected7.raw_string = str + 31;
+
+ expected7.raw_string = {str + 31, 9};
expected7.flags = __llvm_libc::printf_core::FormatFlags::SPACE_PREFIX;
expected7.precision = arg4;
expected7.conv_val_raw = __llvm_libc::cpp::bit_cast<uint64_t>(arg2);
@@ -440,14 +445,14 @@ TEST(LlvmLibcPrintfParserTest, IndexModeComplexParsing) {
EXPECT_FORMAT_EQ(expected7, format_arr[7]);
expected8.has_conv = false;
- expected8.raw_len = 1;
- expected8.raw_string = str + 40;
+
+ expected8.raw_string = {str + 40, 1};
EXPECT_FORMAT_EQ(expected8, format_arr[8]);
expected9.has_conv = true;
- expected9.raw_len = 7;
- expected9.raw_string = str + 41;
+
+ expected9.raw_string = {str + 41, 7};
expected9.min_width = 1;
expected9.precision = 1;
expected9.conv_val_raw = arg1;
diff --git a/libc/test/src/stdio/printf_core/string_writer_test.cpp b/libc/test/src/stdio/printf_core/string_writer_test.cpp
index 12a6e93705b9f..b7ad69524b54c 100644
--- a/libc/test/src/stdio/printf_core/string_writer_test.cpp
+++ b/libc/test/src/stdio/printf_core/string_writer_test.cpp
@@ -6,26 +6,34 @@
//
//===----------------------------------------------------------------------===//
+#include "src/__support/CPP/string_view.h"
#include "src/stdio/printf_core/string_writer.h"
#include "src/stdio/printf_core/writer.h"
#include "utils/UnitTest/Test.h"
+using __llvm_libc::cpp::string_view;
+
+__llvm_libc::printf_core::Writer get_writer(void *str_writer) {
+ return __llvm_libc::printf_core::Writer(
+ str_writer, __llvm_libc::printf_core::StringWriter::write_str,
+ __llvm_libc::printf_core::StringWriter::write_chars,
+ __llvm_libc::printf_core::StringWriter::write_char);
+}
+
TEST(LlvmLibcPrintfStringWriterTest, Constructor) {
char str[10];
__llvm_libc::printf_core::StringWriter str_writer(str);
- __llvm_libc::printf_core::Writer writer(
- reinterpret_cast<void *>(&str_writer),
- __llvm_libc::printf_core::write_to_string);
+ __llvm_libc::printf_core::Writer writer =
+ get_writer(reinterpret_cast<void *>(&str_writer));
}
TEST(LlvmLibcPrintfStringWriterTest, Write) {
char str[4] = {'D', 'E', 'F', 'G'};
__llvm_libc::printf_core::StringWriter str_writer(str);
- __llvm_libc::printf_core::Writer writer(
- reinterpret_cast<void *>(&str_writer),
- __llvm_libc::printf_core::write_to_string);
- writer.write("abc", 3);
+ __llvm_libc::printf_core::Writer writer =
+ get_writer(reinterpret_cast<void *>(&str_writer));
+ writer.write({"abc", 3});
EXPECT_EQ(str[3], 'G');
// This null terminates the string. The writer has no indication when the
@@ -42,12 +50,11 @@ TEST(LlvmLibcPrintfStringWriterTest, Write) {
TEST(LlvmLibcPrintfStringWriterTest, WriteMultipleTimes) {
char str[10];
__llvm_libc::printf_core::StringWriter str_writer(str);
- __llvm_libc::printf_core::Writer writer(
- reinterpret_cast<void *>(&str_writer),
- __llvm_libc::printf_core::write_to_string);
- writer.write("abc", 3);
- writer.write("DEF", 3);
- writer.write("1234", 3);
+ __llvm_libc::printf_core::Writer writer =
+ get_writer(reinterpret_cast<void *>(&str_writer));
+ writer.write({"abc", 3});
+ writer.write({"DEF", 3});
+ writer.write({"1234", 3});
str_writer.terminate();
@@ -58,10 +65,9 @@ TEST(LlvmLibcPrintfStringWriterTest, WriteMultipleTimes) {
TEST(LlvmLibcPrintfStringWriterTest, WriteChars) {
char str[4] = {'D', 'E', 'F', 'G'};
__llvm_libc::printf_core::StringWriter str_writer(str);
- __llvm_libc::printf_core::Writer writer(
- reinterpret_cast<void *>(&str_writer),
- __llvm_libc::printf_core::write_to_string);
- writer.write_chars('a', 3);
+ __llvm_libc::printf_core::Writer writer =
+ get_writer(reinterpret_cast<void *>(&str_writer));
+ writer.write('a', 3);
EXPECT_EQ(str[3], 'G');
str_writer.terminate();
@@ -73,12 +79,11 @@ TEST(LlvmLibcPrintfStringWriterTest, WriteChars) {
TEST(LlvmLibcPrintfStringWriterTest, WriteCharsMultipleTimes) {
char str[10];
__llvm_libc::printf_core::StringWriter str_writer(str);
- __llvm_libc::printf_core::Writer writer(
- reinterpret_cast<void *>(&str_writer),
- __llvm_libc::printf_core::write_to_string);
- writer.write_chars('a', 3);
- writer.write_chars('D', 3);
- writer.write_chars('1', 3);
+ __llvm_libc::printf_core::Writer writer =
+ get_writer(reinterpret_cast<void *>(&str_writer));
+ writer.write('a', 3);
+ writer.write('D', 3);
+ writer.write('1', 3);
str_writer.terminate();
@@ -89,10 +94,9 @@ TEST(LlvmLibcPrintfStringWriterTest, WriteCharsMultipleTimes) {
TEST(LlvmLibcPrintfStringWriterTest, WriteManyChars) {
char str[100];
__llvm_libc::printf_core::StringWriter str_writer(str);
- __llvm_libc::printf_core::Writer writer(
- reinterpret_cast<void *>(&str_writer),
- __llvm_libc::printf_core::write_to_string);
- writer.write_chars('Z', 99);
+ __llvm_libc::printf_core::Writer writer =
+ get_writer(reinterpret_cast<void *>(&str_writer));
+ writer.write('Z', 99);
str_writer.terminate();
@@ -113,13 +117,12 @@ TEST(LlvmLibcPrintfStringWriterTest, WriteManyChars) {
TEST(LlvmLibcPrintfStringWriterTest, MixedWrites) {
char str[13];
__llvm_libc::printf_core::StringWriter str_writer(str);
- __llvm_libc::printf_core::Writer writer(
- reinterpret_cast<void *>(&str_writer),
- __llvm_libc::printf_core::write_to_string);
- writer.write_chars('a', 3);
- writer.write("DEF", 3);
- writer.write_chars('1', 3);
- writer.write("456", 3);
+ __llvm_libc::printf_core::Writer writer =
+ get_writer(reinterpret_cast<void *>(&str_writer));
+ writer.write('a', 3);
+ writer.write({"DEF", 3});
+ writer.write('1', 3);
+ writer.write({"456", 3});
str_writer.terminate();
@@ -130,10 +133,9 @@ TEST(LlvmLibcPrintfStringWriterTest, MixedWrites) {
TEST(LlvmLibcPrintfStringWriterTest, WriteWithMaxLength) {
char str[11];
__llvm_libc::printf_core::StringWriter str_writer(str, 10);
- __llvm_libc::printf_core::Writer writer(
- reinterpret_cast<void *>(&str_writer),
- __llvm_libc::printf_core::write_to_string);
- writer.write("abcDEF123456", 12);
+ __llvm_libc::printf_core::Writer writer =
+ get_writer(reinterpret_cast<void *>(&str_writer));
+ writer.write({"abcDEF123456", 12});
str_writer.terminate();
@@ -144,11 +146,10 @@ TEST(LlvmLibcPrintfStringWriterTest, WriteWithMaxLength) {
TEST(LlvmLibcPrintfStringWriterTest, WriteCharsWithMaxLength) {
char str[11];
__llvm_libc::printf_core::StringWriter str_writer(str, 10);
- __llvm_libc::printf_core::Writer writer(
- reinterpret_cast<void *>(&str_writer),
- __llvm_libc::printf_core::write_to_string);
+ __llvm_libc::printf_core::Writer writer =
+ get_writer(reinterpret_cast<void *>(&str_writer));
- writer.write_chars('1', 15);
+ writer.write('1', 15);
str_writer.terminate();
@@ -159,13 +160,12 @@ TEST(LlvmLibcPrintfStringWriterTest, WriteCharsWithMaxLength) {
TEST(LlvmLibcPrintfStringWriterTest, MixedWriteWithMaxLength) {
char str[11];
__llvm_libc::printf_core::StringWriter str_writer(str, 10);
- __llvm_libc::printf_core::Writer writer(
- reinterpret_cast<void *>(&str_writer),
- __llvm_libc::printf_core::write_to_string);
- writer.write_chars('a', 3);
- writer.write("DEF", 3);
- writer.write_chars('1', 3);
- writer.write("456", 3);
+ __llvm_libc::printf_core::Writer writer =
+ get_writer(reinterpret_cast<void *>(&str_writer));
+ writer.write('a', 3);
+ writer.write({"DEF", 3});
+ writer.write('1', 3);
+ writer.write({"456", 3});
str_writer.terminate();
@@ -176,15 +176,14 @@ TEST(LlvmLibcPrintfStringWriterTest, MixedWriteWithMaxLength) {
TEST(LlvmLibcPrintfStringWriterTest, StringWithMaxLengthOne) {
char str[1];
__llvm_libc::printf_core::StringWriter str_writer(str, 0);
- __llvm_libc::printf_core::Writer writer(
- reinterpret_cast<void *>(&str_writer),
- __llvm_libc::printf_core::write_to_string);
+ __llvm_libc::printf_core::Writer writer =
+ get_writer(reinterpret_cast<void *>(&str_writer));
// This is because the max length should be at most 1 less than the size of
// the buffer it's writing to.
- writer.write_chars('a', 3);
- writer.write("DEF", 3);
- writer.write_chars('1', 3);
- writer.write("456", 3);
+ writer.write('a', 3);
+ writer.write({"DEF", 3});
+ writer.write('1', 3);
+ writer.write({"456", 3});
str_writer.terminate();
@@ -194,13 +193,12 @@ TEST(LlvmLibcPrintfStringWriterTest, StringWithMaxLengthOne) {
TEST(LlvmLibcPrintfStringWriterTest, NullStringWithZeroMaxLength) {
__llvm_libc::printf_core::StringWriter str_writer(nullptr, 0);
- __llvm_libc::printf_core::Writer writer(
- reinterpret_cast<void *>(&str_writer),
- __llvm_libc::printf_core::write_to_string);
- writer.write_chars('a', 3);
- writer.write("DEF", 3);
- writer.write_chars('1', 3);
- writer.write("456", 3);
+ __llvm_libc::printf_core::Writer writer =
+ get_writer(reinterpret_cast<void *>(&str_writer));
+ writer.write('a', 3);
+ writer.write({"DEF", 3});
+ writer.write('1', 3);
+ writer.write({"456", 3});
ASSERT_EQ(writer.get_chars_written(), 12);
}
diff --git a/libc/utils/UnitTest/CMakeLists.txt b/libc/utils/UnitTest/CMakeLists.txt
index 2f0fbd28db5e6..5c3debdaa41f5 100644
--- a/libc/utils/UnitTest/CMakeLists.txt
+++ b/libc/utils/UnitTest/CMakeLists.txt
@@ -64,7 +64,7 @@ target_link_libraries(LibcPrintfHelpers LibcUnitTest)
add_dependencies(
LibcPrintfHelpers
LibcUnitTest
- libc.src.__support.CPP.uint128
+ libc.src.__support.FPUtil.fputil #FPBits
libc.src.stdio.printf_core.core_structs
libc.utils.UnitTest.string_utils
)
diff --git a/libc/utils/UnitTest/PrintfMatcher.cpp b/libc/utils/UnitTest/PrintfMatcher.cpp
index cd17060faa8b1..85bbd2d92a3db 100644
--- a/libc/utils/UnitTest/PrintfMatcher.cpp
+++ b/libc/utils/UnitTest/PrintfMatcher.cpp
@@ -8,7 +8,7 @@
#include "PrintfMatcher.h"
-#include "src/__support/CPP/UInt128.h"
+#include "src/__support/FPUtil/FPBits.h"
#include "src/stdio/printf_core/core_structs.h"
#include "utils/UnitTest/StringUtils.h"
@@ -37,8 +37,8 @@ namespace {
break
void display(testutils::StreamWrapper &stream, FormatSection form) {
- stream << "Raw String (len " << form.raw_len << "): \"";
- for (size_t i = 0; i < form.raw_len; ++i) {
+ stream << "Raw String (len " << form.raw_string.size() << "): \"";
+ for (size_t i = 0; i < form.raw_string.size(); ++i) {
stream << form.raw_string[i];
}
stream << "\"";
@@ -72,7 +72,10 @@ void display(testutils::StreamWrapper &stream, FormatSection form) {
reinterpret_cast<uintptr_t>(form.conv_val_ptr))
<< "\n";
else if (form.conv_name != '%')
- stream << "\tvalue: " << int_to_hex<UInt128>(form.conv_val_raw) << "\n";
+ stream << "\tvalue: "
+ << int_to_hex<fputil::FPBits<long double>::UIntType>(
+ form.conv_val_raw)
+ << "\n";
}
}
} // anonymous namespace
More information about the libc-commits
mailing list