[libc] Add implementation of fgetc.

Reviewed By: michaelrj

Differential Revision: https://reviews.llvm.org/D136421
This commit is contained in:
Siva Chandra Reddy 2022-10-21 06:46:31 +00:00
parent 2a038f9138
commit 0480b45e9e
7 changed files with 129 additions and 0 deletions

View File

@ -370,6 +370,7 @@ if(LLVM_LIBC_FULL_BUILD)
libc.src.stdio.feof_unlocked
libc.src.stdio.ferror
libc.src.stdio.ferror_unlocked
libc.src.stdio.fgetc
libc.src.stdio.fflush
libc.src.stdio.fopen
libc.src.stdio.fputc

View File

@ -525,6 +525,11 @@ def StdC : StandardSpec<"stdc"> {
RetValSpec<IntType>,
[ArgSpec<FILEPtr>]
>,
FunctionSpec<
"fgetc",
RetValSpec<IntType>,
[ArgSpec<FILEPtr>]
>,
FunctionSpec<
"fflush",
RetValSpec<IntType>,

View File

@ -100,6 +100,18 @@ add_entrypoint_object(
libc.src.__support.File.platform_file
)
add_entrypoint_object(
fgetc
SRCS
fgetc.cpp
HDRS
fgetc.h
DEPENDS
libc.include.stdio
libc.src.__support.File.file
libc.src.__support.File.platform_file
)
add_entrypoint_object(
fflush
SRCS

24
libc/src/stdio/fgetc.cpp Normal file
View File

@ -0,0 +1,24 @@
//===-- Implementation of fgetc -------------------------------------------===//
//
// 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/fgetc.h"
#include "src/__support/File/file.h"
#include <stdio.h>
namespace __llvm_libc {
LLVM_LIBC_FUNCTION(int, fgetc, (::FILE * stream)) {
unsigned char c;
size_t r = reinterpret_cast<__llvm_libc::File *>(stream)->read(&c, 1);
if (r != 1)
return EOF;
return c;
}
} // namespace __llvm_libc

20
libc/src/stdio/fgetc.h Normal file
View File

@ -0,0 +1,20 @@
//===-- Implementation header of fgetc --------------------------*- C++ -*-===//
//
// 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
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_LIBC_SRC_STDIO_FGETC_H
#define LLVM_LIBC_SRC_STDIO_FGETC_H
#include <stdio.h>
namespace __llvm_libc {
int fgetc(::FILE *f);
} // namespace __llvm_libc
#endif // LLVM_LIBC_SRC_STDIO_FGETC_H

View File

@ -153,5 +153,22 @@ if(${LIBC_TARGET_OS} STREQUAL "linux")
)
endif()
add_libc_unittest(
fgetc_test
SUITE
libc_stdio_unittests
SRCS
fgetc_test.cpp
DEPENDS
libc.include.errno
libc.include.stdio
libc.src.stdio.fclose
libc.src.stdio.feof
libc.src.stdio.ferror
libc.src.stdio.fgetc
libc.src.stdio.fopen
libc.src.stdio.fwrite
)
add_subdirectory(printf_core)
add_subdirectory(testdata)

View File

@ -0,0 +1,50 @@
//===-- Unittests for fgetc -----------------------------------------------===//
//
// 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/clearerr.h"
#include "src/stdio/fclose.h"
#include "src/stdio/feof.h"
#include "src/stdio/ferror.h"
#include "src/stdio/fgetc.h"
#include "src/stdio/fopen.h"
#include "src/stdio/fwrite.h"
#include "utils/UnitTest/Test.h"
#include <errno.h>
#include <stdio.h>
TEST(LlvmLibcFGetCTest, WriteAndReadCharacters) {
constexpr char FILENAME[] = "testdata/fgetc.test";
::FILE *file = __llvm_libc::fopen(FILENAME, "w");
ASSERT_FALSE(file == nullptr);
constexpr char CONTENT[] = "123456789";
constexpr size_t WRITE_SIZE = sizeof(CONTENT) - 1;
ASSERT_EQ(WRITE_SIZE, __llvm_libc::fwrite(CONTENT, 1, WRITE_SIZE, file));
// This is a write-only file so reads should fail.
ASSERT_EQ(__llvm_libc::fgetc(file), EOF);
// This is an error and not a real EOF.
ASSERT_EQ(__llvm_libc::feof(file), 0);
ASSERT_NE(__llvm_libc::ferror(file), 0);
errno = 0;
ASSERT_EQ(0, __llvm_libc::fclose(file));
file = __llvm_libc::fopen(FILENAME, "r");
ASSERT_FALSE(file == nullptr);
for (size_t i = 0; i < WRITE_SIZE; ++i) {
int c = __llvm_libc::fgetc(file);
ASSERT_EQ(c, int('1' + i));
}
// Reading more should return EOF but not set error.
ASSERT_EQ(__llvm_libc::fgetc(file), EOF);
ASSERT_NE(__llvm_libc::feof(file), 0);
ASSERT_EQ(__llvm_libc::ferror(file), 0);
ASSERT_EQ(0, __llvm_libc::fclose(file));
}