forked from OSchip/llvm-project
[libc] add fputs and puts
add fputs, puts, and the EOF macro that they use. Reviewed By: sivachandra Differential Revision: https://reviews.llvm.org/D134328
This commit is contained in:
parent
f40266603e
commit
a9e0dbefdd
|
@ -153,6 +153,7 @@ def StdIOAPI : PublicAPI<"stdio.h"> {
|
|||
SimpleMacroDef<"_IOFBF", "0">,
|
||||
SimpleMacroDef<"_IOLBF", "1">,
|
||||
SimpleMacroDef<"_IONBF", "2">,
|
||||
SimpleMacroDef<"EOF", "-1">,
|
||||
];
|
||||
let Types = ["size_t", "FILE", "cookie_io_functions_t"];
|
||||
}
|
||||
|
|
|
@ -324,6 +324,7 @@ if(LLVM_LIBC_FULL_BUILD)
|
|||
libc.src.stdio.ferror_unlocked
|
||||
libc.src.stdio.fflush
|
||||
libc.src.stdio.fopen
|
||||
libc.src.stdio.fputs
|
||||
libc.src.stdio.fopencookie
|
||||
libc.src.stdio.fread
|
||||
libc.src.stdio.fread_unlocked
|
||||
|
@ -333,6 +334,7 @@ if(LLVM_LIBC_FULL_BUILD)
|
|||
libc.src.stdio.fwrite_unlocked
|
||||
libc.src.stdio.fprintf
|
||||
libc.src.stdio.printf
|
||||
libc.src.stdio.puts
|
||||
libc.src.stdio.stderr
|
||||
libc.src.stdio.stdout
|
||||
|
||||
|
|
|
@ -72,7 +72,7 @@ These functions operate on files on the host's system, without using the
|
|||
============= =========
|
||||
Function_Name Available
|
||||
============= =========
|
||||
remove
|
||||
remove YES
|
||||
rename
|
||||
tmpnam
|
||||
============= =========
|
||||
|
@ -91,7 +91,7 @@ fgets
|
|||
getchar
|
||||
fread YES
|
||||
(f)putc
|
||||
(f)puts
|
||||
(f)puts YES
|
||||
putchar
|
||||
fwrite YES
|
||||
ungetc
|
||||
|
|
|
@ -496,6 +496,7 @@ def StdC : StandardSpec<"stdc"> {
|
|||
Macro<"_IOFBF">,
|
||||
Macro<"_IOLBF">,
|
||||
Macro<"_IONBF">,
|
||||
Macro<"EOF">,
|
||||
], // Macros
|
||||
[ // Types
|
||||
SizeTType,
|
||||
|
@ -534,6 +535,17 @@ def StdC : StandardSpec<"stdc"> {
|
|||
[ArgSpec<ConstCharPtr>,
|
||||
ArgSpec<ConstCharPtr>]
|
||||
>,
|
||||
FunctionSpec<
|
||||
"fputs",
|
||||
RetValSpec<IntType>,
|
||||
[ArgSpec<ConstCharRestrictedPtr>,
|
||||
ArgSpec<FILERestrictedPtr>]
|
||||
>,
|
||||
FunctionSpec<
|
||||
"puts",
|
||||
RetValSpec<IntType>,
|
||||
[ArgSpec<ConstCharRestrictedPtr>]
|
||||
>,
|
||||
FunctionSpec<
|
||||
"fread",
|
||||
RetValSpec<SizeTType>,
|
||||
|
|
|
@ -131,7 +131,7 @@ size_t File::write_unlocked_fbf(const uint8_t *data, size_t len) {
|
|||
size_t File::write_unlocked_lbf(const uint8_t *data, size_t len) {
|
||||
constexpr uint8_t NEWLINE_CHAR = '\n';
|
||||
size_t last_newline = len;
|
||||
for (size_t i = len; i > 1; --i) {
|
||||
for (size_t i = len; i >= 1; --i) {
|
||||
if (data[i - 1] == NEWLINE_CHAR) {
|
||||
last_newline = i - 1;
|
||||
break;
|
||||
|
|
|
@ -184,6 +184,31 @@ add_entrypoint_object(
|
|||
libc.src.__support.File.platform_file
|
||||
)
|
||||
|
||||
add_entrypoint_object(
|
||||
fputs
|
||||
SRCS
|
||||
fputs.cpp
|
||||
HDRS
|
||||
fputs.h
|
||||
DEPENDS
|
||||
libc.include.stdio
|
||||
libc.src.__support.File.file
|
||||
libc.src.__support.File.platform_file
|
||||
)
|
||||
|
||||
|
||||
add_entrypoint_object(
|
||||
puts
|
||||
SRCS
|
||||
puts.cpp
|
||||
HDRS
|
||||
puts.h
|
||||
DEPENDS
|
||||
libc.include.stdio
|
||||
libc.src.__support.File.file
|
||||
libc.src.__support.File.platform_file
|
||||
)
|
||||
|
||||
add_entrypoint_object(
|
||||
fseek
|
||||
SRCS
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
//===-- Implementation of fputs -------------------------------------------===//
|
||||
//
|
||||
// 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/fputs.h"
|
||||
#include "src/__support/CPP/string_view.h"
|
||||
#include "src/__support/File/file.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
namespace __llvm_libc {
|
||||
|
||||
LLVM_LIBC_FUNCTION(int, fputs,
|
||||
(const char *__restrict str, ::FILE *__restrict stream)) {
|
||||
cpp::string_view str_view(str);
|
||||
|
||||
size_t written = reinterpret_cast<__llvm_libc::File *>(stream)->write(
|
||||
str, str_view.size());
|
||||
if (str_view.size() != written) {
|
||||
// The stream should be in an error state in this case.
|
||||
return EOF;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace __llvm_libc
|
|
@ -0,0 +1,20 @@
|
|||
//===-- Implementation header of fputs --------------------------*- 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_FPUTS_H
|
||||
#define LLVM_LIBC_SRC_STDIO_FPUTS_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
namespace __llvm_libc {
|
||||
|
||||
int fputs(const char *__restrict str, ::FILE *__restrict stream);
|
||||
|
||||
} // namespace __llvm_libc
|
||||
|
||||
#endif // LLVM_LIBC_SRC_STDIO_FPUTS_H
|
|
@ -0,0 +1,32 @@
|
|||
//===-- Implementation of puts --------------------------------------------===//
|
||||
//
|
||||
// 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/puts.h"
|
||||
#include "src/__support/CPP/string_view.h"
|
||||
#include "src/__support/File/file.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
namespace __llvm_libc {
|
||||
|
||||
LLVM_LIBC_FUNCTION(int, puts, (const char *__restrict str)) {
|
||||
cpp::string_view str_view(str);
|
||||
size_t written = __llvm_libc::stdout->write(str, str_view.size());
|
||||
if (str_view.size() != written) {
|
||||
// The stream should be in an error state in this case.
|
||||
return EOF;
|
||||
}
|
||||
written = __llvm_libc::stdout->write("\n", 1);
|
||||
if (1 != written) {
|
||||
// The stream should be in an error state in this case.
|
||||
return EOF;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace __llvm_libc
|
|
@ -0,0 +1,20 @@
|
|||
//===-- Implementation header of puts ---------------------------*- 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_PUTS_H
|
||||
#define LLVM_LIBC_SRC_STDIO_PUTS_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
namespace __llvm_libc {
|
||||
|
||||
int puts(const char *__restrict str);
|
||||
|
||||
} // namespace __llvm_libc
|
||||
|
||||
#endif // LLVM_LIBC_SRC_STDIO_PUTS_H
|
|
@ -15,6 +15,7 @@ add_libc_unittest(
|
|||
libc.src.stdio.ferror
|
||||
libc.src.stdio.fflush
|
||||
libc.src.stdio.fopen
|
||||
libc.src.stdio.fputs
|
||||
libc.src.stdio.fread
|
||||
libc.src.stdio.fseek
|
||||
libc.src.stdio.fwrite
|
||||
|
@ -108,7 +109,16 @@ add_libc_unittest(
|
|||
printf_test.cpp
|
||||
DEPENDS
|
||||
libc.src.stdio.printf
|
||||
libc.src.fenv.fesetround
|
||||
)
|
||||
|
||||
add_libc_unittest(
|
||||
puts_test
|
||||
SUITE
|
||||
libc_stdio_unittests
|
||||
SRCS
|
||||
puts_test.cpp
|
||||
DEPENDS
|
||||
libc.src.stdio.puts
|
||||
)
|
||||
|
||||
add_libc_unittest(
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include "src/stdio/ferror.h"
|
||||
#include "src/stdio/fflush.h"
|
||||
#include "src/stdio/fopen.h"
|
||||
#include "src/stdio/fputs.h"
|
||||
#include "src/stdio/fread.h"
|
||||
#include "src/stdio/fseek.h"
|
||||
#include "src/stdio/fwrite.h"
|
||||
|
@ -66,10 +67,39 @@ TEST(LlvmLibcFILETest, SimpleFileOperations) {
|
|||
ASSERT_NE(errno, 0);
|
||||
errno = 0;
|
||||
|
||||
__llvm_libc::clearerr(file);
|
||||
|
||||
// Should be an error to puts.
|
||||
ASSERT_EQ(EOF, __llvm_libc::fputs(CONTENT, file));
|
||||
ASSERT_NE(__llvm_libc::ferror(file), 0);
|
||||
ASSERT_NE(errno, 0);
|
||||
errno = 0;
|
||||
|
||||
__llvm_libc::clearerr(file);
|
||||
ASSERT_EQ(__llvm_libc::ferror(file), 0);
|
||||
|
||||
ASSERT_EQ(__llvm_libc::fclose(file), 0);
|
||||
|
||||
// Now try puts.
|
||||
file = __llvm_libc::fopen(FILENAME, "w");
|
||||
ASSERT_FALSE(file == nullptr);
|
||||
// fputs returns a negative value on error (EOF) or any non-negative value on
|
||||
// success. This assert checks that the return value is non-negative.
|
||||
ASSERT_GE(__llvm_libc::fputs(CONTENT, file), 0);
|
||||
|
||||
__llvm_libc::clearerr(file);
|
||||
ASSERT_EQ(__llvm_libc::ferror(file), 0);
|
||||
|
||||
ASSERT_EQ(0, __llvm_libc::fclose(file));
|
||||
|
||||
file = __llvm_libc::fopen(FILENAME, "r");
|
||||
ASSERT_FALSE(file == nullptr);
|
||||
|
||||
ASSERT_EQ(__llvm_libc::fread(read_data, 1, sizeof(CONTENT) - 1, file),
|
||||
sizeof(CONTENT) - 1);
|
||||
read_data[sizeof(CONTENT) - 1] = '\0';
|
||||
ASSERT_STREQ(read_data, CONTENT);
|
||||
ASSERT_EQ(__llvm_libc::fclose(file), 0);
|
||||
}
|
||||
|
||||
TEST(LlvmLibcFILETest, FFlush) {
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
//===-- Unittests for puts ---------------------------------------------===//
|
||||
//
|
||||
// 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/puts.h"
|
||||
|
||||
#include "utils/UnitTest/Test.h"
|
||||
|
||||
TEST(LlvmLibcPutsTest, PrintOut) {
|
||||
int result;
|
||||
|
||||
constexpr char simple[] = "A simple string";
|
||||
result = __llvm_libc::puts(simple);
|
||||
EXPECT_GE(result, 0);
|
||||
|
||||
// check that it appends a second newline at the end.
|
||||
constexpr char numbers[] = "1234567890\n";
|
||||
result = __llvm_libc::puts(numbers);
|
||||
EXPECT_GE(result, 0);
|
||||
|
||||
constexpr char more[] = "1234 and more\n6789 and rhyme";
|
||||
result = __llvm_libc::puts(more);
|
||||
EXPECT_GE(result, 0);
|
||||
}
|
Loading…
Reference in New Issue