[libc] Add implementation of fgetc.
Reviewed By: michaelrj Differential Revision: https://reviews.llvm.org/D136421
This commit is contained in:
parent
2a038f9138
commit
0480b45e9e
|
@ -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
|
||||
|
|
|
@ -525,6 +525,11 @@ def StdC : StandardSpec<"stdc"> {
|
|||
RetValSpec<IntType>,
|
||||
[ArgSpec<FILEPtr>]
|
||||
>,
|
||||
FunctionSpec<
|
||||
"fgetc",
|
||||
RetValSpec<IntType>,
|
||||
[ArgSpec<FILEPtr>]
|
||||
>,
|
||||
FunctionSpec<
|
||||
"fflush",
|
||||
RetValSpec<IntType>,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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)
|
||||
|
|
|
@ -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));
|
||||
}
|
Loading…
Reference in New Issue