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