xref: /llvm-project/libc/test/src/stdio/vfprintf_test.cpp (revision c63112a9118277a20ae440f3f69189c0937e8f4d)
116d5c242SMichael Jones //===-- Unittests for vfprintf --------------------------------------------===//
216d5c242SMichael Jones //
316d5c242SMichael Jones // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
416d5c242SMichael Jones // See https://llvm.org/LICENSE.txt for license information.
516d5c242SMichael Jones // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
616d5c242SMichael Jones //
716d5c242SMichael Jones //===----------------------------------------------------------------------===//
816d5c242SMichael Jones 
916d5c242SMichael Jones // These tests are copies of the non-v variants of the printf functions. This is
1016d5c242SMichael Jones // because these functions are identical in every way except for how the varargs
1116d5c242SMichael Jones // are passed.
1216d5c242SMichael Jones 
13a5a008ffSmichaelrj-google #ifndef LIBC_COPT_STDIO_USE_SYSTEM_FILE
1416d5c242SMichael Jones #include "src/stdio/fclose.h"
1516d5c242SMichael Jones #include "src/stdio/ferror.h"
1616d5c242SMichael Jones #include "src/stdio/fopen.h"
1716d5c242SMichael Jones #include "src/stdio/fread.h"
18a5a008ffSmichaelrj-google #endif // LIBC_COPT_STDIO_USE_SYSTEM_FILE
1916d5c242SMichael Jones 
2016d5c242SMichael Jones #include "src/stdio/vfprintf.h"
2116d5c242SMichael Jones 
2216d5c242SMichael Jones #include "test/UnitTest/Test.h"
2316d5c242SMichael Jones 
2416d5c242SMichael Jones namespace printf_test {
25a5a008ffSmichaelrj-google #ifndef LIBC_COPT_STDIO_USE_SYSTEM_FILE
26*b6bc9d72SGuillaume Chatelet using LIBC_NAMESPACE::fclose;
27*b6bc9d72SGuillaume Chatelet using LIBC_NAMESPACE::ferror;
28*b6bc9d72SGuillaume Chatelet using LIBC_NAMESPACE::fopen;
29*b6bc9d72SGuillaume Chatelet using LIBC_NAMESPACE::fread;
30a5a008ffSmichaelrj-google #else  // defined(LIBC_COPT_STDIO_USE_SYSTEM_FILE)
3116d5c242SMichael Jones using ::fclose;
3216d5c242SMichael Jones using ::ferror;
3316d5c242SMichael Jones using ::fopen;
3416d5c242SMichael Jones using ::fread;
35a5a008ffSmichaelrj-google #endif // LIBC_COPT_STDIO_USE_SYSTEM_FILE
3616d5c242SMichael Jones } // namespace printf_test
3716d5c242SMichael Jones 
3816d5c242SMichael Jones int call_vfprintf(::FILE *__restrict stream, const char *__restrict format,
3916d5c242SMichael Jones                   ...) {
4016d5c242SMichael Jones   va_list vlist;
4116d5c242SMichael Jones   va_start(vlist, format);
42*b6bc9d72SGuillaume Chatelet   int ret = LIBC_NAMESPACE::vfprintf(stream, format, vlist);
4316d5c242SMichael Jones   va_end(vlist);
4416d5c242SMichael Jones   return ret;
4516d5c242SMichael Jones }
4616d5c242SMichael Jones 
4716d5c242SMichael Jones TEST(LlvmLibcVFPrintfTest, WriteToFile) {
488b374310SMichael Jones   const char *FILENAME = "vfprintf_output.test";
4916d5c242SMichael Jones   auto FILE_PATH = libc_make_test_file_path(FILENAME);
5016d5c242SMichael Jones 
5116d5c242SMichael Jones   ::FILE *file = printf_test::fopen(FILE_PATH, "w");
5216d5c242SMichael Jones   ASSERT_FALSE(file == nullptr);
5316d5c242SMichael Jones 
5416d5c242SMichael Jones   int written;
5516d5c242SMichael Jones 
5616d5c242SMichael Jones   constexpr char simple[] = "A simple string with no conversions.\n";
5716d5c242SMichael Jones   written = call_vfprintf(file, simple);
5816d5c242SMichael Jones   EXPECT_EQ(written, 37);
5916d5c242SMichael Jones 
6016d5c242SMichael Jones   constexpr char numbers[] = "1234567890\n";
6116d5c242SMichael Jones   written = call_vfprintf(file, "%s", numbers);
6216d5c242SMichael Jones   EXPECT_EQ(written, 11);
6316d5c242SMichael Jones 
6416d5c242SMichael Jones   constexpr char format_more[] = "%s and more\n";
6516d5c242SMichael Jones   constexpr char short_numbers[] = "1234";
6616d5c242SMichael Jones   written = call_vfprintf(file, format_more, short_numbers);
6716d5c242SMichael Jones   EXPECT_EQ(written, 14);
6816d5c242SMichael Jones 
6916d5c242SMichael Jones   ASSERT_EQ(0, printf_test::fclose(file));
7016d5c242SMichael Jones 
7116d5c242SMichael Jones   file = printf_test::fopen(FILE_PATH, "r");
7216d5c242SMichael Jones   ASSERT_FALSE(file == nullptr);
7316d5c242SMichael Jones 
7416d5c242SMichael Jones   char data[50];
7516d5c242SMichael Jones   ASSERT_EQ(printf_test::fread(data, 1, sizeof(simple) - 1, file),
7616d5c242SMichael Jones             sizeof(simple) - 1);
7716d5c242SMichael Jones   data[sizeof(simple) - 1] = '\0';
7816d5c242SMichael Jones   ASSERT_STREQ(data, simple);
7916d5c242SMichael Jones   ASSERT_EQ(printf_test::fread(data, 1, sizeof(numbers) - 1, file),
8016d5c242SMichael Jones             sizeof(numbers) - 1);
8116d5c242SMichael Jones   data[sizeof(numbers) - 1] = '\0';
8216d5c242SMichael Jones   ASSERT_STREQ(data, numbers);
8316d5c242SMichael Jones   ASSERT_EQ(printf_test::fread(
8416d5c242SMichael Jones                 data, 1, sizeof(format_more) + sizeof(short_numbers) - 4, file),
8516d5c242SMichael Jones             sizeof(format_more) + sizeof(short_numbers) - 4);
8616d5c242SMichael Jones   data[sizeof(format_more) + sizeof(short_numbers) - 4] = '\0';
8716d5c242SMichael Jones   ASSERT_STREQ(data, "1234 and more\n");
8816d5c242SMichael Jones 
8916d5c242SMichael Jones   ASSERT_EQ(printf_test::ferror(file), 0);
9016d5c242SMichael Jones 
9116d5c242SMichael Jones   written = call_vfprintf(file, "Writing to a read only file should fail.");
9216d5c242SMichael Jones   EXPECT_LT(written, 0);
9316d5c242SMichael Jones 
9416d5c242SMichael Jones   ASSERT_EQ(printf_test::fclose(file), 0);
9516d5c242SMichael Jones }
96