xref: /aosp_15_r20/external/llvm-libc/test/src/stdio/fgets_test.cpp (revision 71db0c75aadcf003ffe3238005f61d7618a3fead)
1*71db0c75SAndroid Build Coastguard Worker //===-- Unittests for fgets -----------------------------------------------===//
2*71db0c75SAndroid Build Coastguard Worker //
3*71db0c75SAndroid Build Coastguard Worker // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*71db0c75SAndroid Build Coastguard Worker // See https://llvm.org/LICENSE.txt for license information.
5*71db0c75SAndroid Build Coastguard Worker // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*71db0c75SAndroid Build Coastguard Worker //
7*71db0c75SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
8*71db0c75SAndroid Build Coastguard Worker 
9*71db0c75SAndroid Build Coastguard Worker #include "src/stdio/fclose.h"
10*71db0c75SAndroid Build Coastguard Worker #include "src/stdio/feof.h"
11*71db0c75SAndroid Build Coastguard Worker #include "src/stdio/ferror.h"
12*71db0c75SAndroid Build Coastguard Worker #include "src/stdio/fgets.h"
13*71db0c75SAndroid Build Coastguard Worker #include "src/stdio/fopen.h"
14*71db0c75SAndroid Build Coastguard Worker #include "src/stdio/fwrite.h"
15*71db0c75SAndroid Build Coastguard Worker #include "test/UnitTest/Test.h"
16*71db0c75SAndroid Build Coastguard Worker 
17*71db0c75SAndroid Build Coastguard Worker #include "src/errno/libc_errno.h"
18*71db0c75SAndroid Build Coastguard Worker 
TEST(LlvmLibcFgetsTest,WriteAndReadCharacters)19*71db0c75SAndroid Build Coastguard Worker TEST(LlvmLibcFgetsTest, WriteAndReadCharacters) {
20*71db0c75SAndroid Build Coastguard Worker   constexpr char FILENAME[] = "testdata/fgets.test";
21*71db0c75SAndroid Build Coastguard Worker   ::FILE *file = LIBC_NAMESPACE::fopen(FILENAME, "w");
22*71db0c75SAndroid Build Coastguard Worker   ASSERT_FALSE(file == nullptr);
23*71db0c75SAndroid Build Coastguard Worker   constexpr char CONTENT[] = "123456789\n"
24*71db0c75SAndroid Build Coastguard Worker                              "1234567\n"
25*71db0c75SAndroid Build Coastguard Worker                              "123456\n"
26*71db0c75SAndroid Build Coastguard Worker                              "1";
27*71db0c75SAndroid Build Coastguard Worker   constexpr size_t WRITE_SIZE = sizeof(CONTENT) - 1;
28*71db0c75SAndroid Build Coastguard Worker 
29*71db0c75SAndroid Build Coastguard Worker   char buff[8];
30*71db0c75SAndroid Build Coastguard Worker   char *output;
31*71db0c75SAndroid Build Coastguard Worker 
32*71db0c75SAndroid Build Coastguard Worker   ASSERT_EQ(WRITE_SIZE, LIBC_NAMESPACE::fwrite(CONTENT, 1, WRITE_SIZE, file));
33*71db0c75SAndroid Build Coastguard Worker   // This is a write-only file so reads should fail.
34*71db0c75SAndroid Build Coastguard Worker   ASSERT_TRUE(LIBC_NAMESPACE::fgets(buff, 8, file) == nullptr);
35*71db0c75SAndroid Build Coastguard Worker   // This is an error and not a real EOF.
36*71db0c75SAndroid Build Coastguard Worker   ASSERT_EQ(LIBC_NAMESPACE::feof(file), 0);
37*71db0c75SAndroid Build Coastguard Worker   ASSERT_NE(LIBC_NAMESPACE::ferror(file), 0);
38*71db0c75SAndroid Build Coastguard Worker   LIBC_NAMESPACE::libc_errno = 0;
39*71db0c75SAndroid Build Coastguard Worker 
40*71db0c75SAndroid Build Coastguard Worker   ASSERT_EQ(0, LIBC_NAMESPACE::fclose(file));
41*71db0c75SAndroid Build Coastguard Worker 
42*71db0c75SAndroid Build Coastguard Worker   file = LIBC_NAMESPACE::fopen(FILENAME, "r");
43*71db0c75SAndroid Build Coastguard Worker   ASSERT_FALSE(file == nullptr);
44*71db0c75SAndroid Build Coastguard Worker 
45*71db0c75SAndroid Build Coastguard Worker   // The GPU build relies on the host C library, so this check may be different.
46*71db0c75SAndroid Build Coastguard Worker #ifndef LIBC_TARGET_ARCH_IS_GPU
47*71db0c75SAndroid Build Coastguard Worker   // If we request just 1 byte, it should return just a null byte and not
48*71db0c75SAndroid Build Coastguard Worker   // advance the read head. This is implementation defined.
49*71db0c75SAndroid Build Coastguard Worker   output = LIBC_NAMESPACE::fgets(buff, 1, file);
50*71db0c75SAndroid Build Coastguard Worker   ASSERT_TRUE(output == buff);
51*71db0c75SAndroid Build Coastguard Worker   ASSERT_EQ(buff[0], '\0');
52*71db0c75SAndroid Build Coastguard Worker   ASSERT_ERRNO_SUCCESS();
53*71db0c75SAndroid Build Coastguard Worker 
54*71db0c75SAndroid Build Coastguard Worker   // If we request less than 1 byte, it should do nothing and return nullptr.
55*71db0c75SAndroid Build Coastguard Worker   // This is also implementation defined.
56*71db0c75SAndroid Build Coastguard Worker   output = LIBC_NAMESPACE::fgets(buff, 0, file);
57*71db0c75SAndroid Build Coastguard Worker   ASSERT_TRUE(output == nullptr);
58*71db0c75SAndroid Build Coastguard Worker #endif
59*71db0c75SAndroid Build Coastguard Worker 
60*71db0c75SAndroid Build Coastguard Worker   const char *output_arr[] = {
61*71db0c75SAndroid Build Coastguard Worker       "1234567", "89\n", "1234567", "\n", "123456\n", "1",
62*71db0c75SAndroid Build Coastguard Worker   };
63*71db0c75SAndroid Build Coastguard Worker 
64*71db0c75SAndroid Build Coastguard Worker   constexpr size_t ARR_SIZE = sizeof(output_arr) / sizeof(char *);
65*71db0c75SAndroid Build Coastguard Worker 
66*71db0c75SAndroid Build Coastguard Worker   for (size_t i = 0; i < ARR_SIZE; ++i) {
67*71db0c75SAndroid Build Coastguard Worker     output = LIBC_NAMESPACE::fgets(buff, 8, file);
68*71db0c75SAndroid Build Coastguard Worker 
69*71db0c75SAndroid Build Coastguard Worker     // This pointer comparison is intentional, fgets should return a pointer to
70*71db0c75SAndroid Build Coastguard Worker     // buff when it succeeds.
71*71db0c75SAndroid Build Coastguard Worker     ASSERT_TRUE(output == buff);
72*71db0c75SAndroid Build Coastguard Worker     ASSERT_EQ(LIBC_NAMESPACE::ferror(file), 0);
73*71db0c75SAndroid Build Coastguard Worker 
74*71db0c75SAndroid Build Coastguard Worker     EXPECT_STREQ(buff, output_arr[i]);
75*71db0c75SAndroid Build Coastguard Worker   }
76*71db0c75SAndroid Build Coastguard Worker 
77*71db0c75SAndroid Build Coastguard Worker   // This should have hit the end of the file, but that isn't an error unless it
78*71db0c75SAndroid Build Coastguard Worker   // fails to read anything.
79*71db0c75SAndroid Build Coastguard Worker   ASSERT_NE(LIBC_NAMESPACE::feof(file), 0);
80*71db0c75SAndroid Build Coastguard Worker   ASSERT_EQ(LIBC_NAMESPACE::ferror(file), 0);
81*71db0c75SAndroid Build Coastguard Worker   ASSERT_ERRNO_SUCCESS();
82*71db0c75SAndroid Build Coastguard Worker 
83*71db0c75SAndroid Build Coastguard Worker   // Reading more should be an EOF, but not an error.
84*71db0c75SAndroid Build Coastguard Worker   output = LIBC_NAMESPACE::fgets(buff, 8, file);
85*71db0c75SAndroid Build Coastguard Worker   ASSERT_TRUE(output == nullptr);
86*71db0c75SAndroid Build Coastguard Worker   ASSERT_NE(LIBC_NAMESPACE::feof(file), 0);
87*71db0c75SAndroid Build Coastguard Worker   ASSERT_ERRNO_SUCCESS();
88*71db0c75SAndroid Build Coastguard Worker 
89*71db0c75SAndroid Build Coastguard Worker   ASSERT_EQ(0, LIBC_NAMESPACE::fclose(file));
90*71db0c75SAndroid Build Coastguard Worker }
91