libc.src.stdio.fwrite
libc.src.stdio.fwrite_unlocked
libc.src.stdio.sprintf
+ libc.src.stdio.snprintf
# signal.h entrypoints
# TODO: Enable signal.h entrypoints after fixing signal.h
ArgSpec<ConstCharRestrictedPtr>,
ArgSpec<VarArgType>]
>,
+ FunctionSpec<
+ "snprintf",
+ RetValSpec<IntType>,
+ [ArgSpec<CharRestrictedPtr>,
+ ArgSpec<SizeTType>,
+ ArgSpec<ConstCharRestrictedPtr>,
+ ArgSpec<VarArgType>]
+ >,
+ FunctionSpec<
+ "printf",
+ RetValSpec<IntType>,
+ [ArgSpec<ConstCharRestrictedPtr>,
+ ArgSpec<VarArgType>]
+ >,
+ FunctionSpec<
+ "fprintf",
+ RetValSpec<IntType>,
+ [ArgSpec<FILERestrictedPtr>,
+ ArgSpec<ConstCharRestrictedPtr>,
+ ArgSpec<VarArgType>]
+ >,
]
>;
HDRS
sprintf.h
DEPENDS
- libc.include.stdio
+ libc.src.stdio.printf_core.printf_main
+ libc.src.stdio.printf_core.string_writer
+ libc.src.stdio.printf_core.writer
+)
+
+add_entrypoint_object(
+ snprintf
+ SRCS
+ snprintf.cpp
+ HDRS
+ snprintf.h
+ DEPENDS
libc.src.stdio.printf_core.printf_main
libc.src.stdio.printf_core.string_writer
libc.src.stdio.printf_core.writer
--- /dev/null
+//===-- Implementation of snprintf ------------------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/stdio/snprintf.h"
+
+#include "src/__support/arg_list.h"
+#include "src/stdio/printf_core/printf_main.h"
+#include "src/stdio/printf_core/string_writer.h"
+#include "src/stdio/printf_core/writer.h"
+
+#include <stdarg.h>
+#include <stddef.h>
+
+namespace __llvm_libc {
+
+LLVM_LIBC_FUNCTION(int, snprintf,
+ (char *__restrict buffer, size_t buffsz,
+ const char *__restrict format, ...)) {
+ va_list vlist;
+ va_start(vlist, format);
+ internal::ArgList args(vlist); // This holder class allows for easier copying
+ // and pointer semantics, as well as handling
+ // destruction automatically.
+ va_end(vlist);
+ printf_core::StringWriter str_writer(buffer, (buffsz > 0 ? buffsz - 1 : 0));
+ printf_core::Writer writer(reinterpret_cast<void *>(&str_writer),
+ printf_core::write_to_string);
+
+ int ret_val = printf_core::printf_main(&writer, format, args);
+ if (buffsz > 0) // if the buffsz is 0 the buffer may be a null pointer.
+ str_writer.terminate();
+ return ret_val;
+}
+
+} // namespace __llvm_libc
--- /dev/null
+//===-- Implementation header of snprintf -----------------------*- 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_SNPRINTF_H
+#define LLVM_LIBC_SRC_STDIO_SNPRINTF_H
+
+#include <stddef.h>
+
+namespace __llvm_libc {
+
+int snprintf(char *__restrict buffer, size_t buffsz,
+ const char *__restrict format, ...);
+
+} // namespace __llvm_libc
+
+#endif // LLVM_LIBC_SRC_STDIO_SNPRINTF_H
va_list vlist;
va_start(vlist, format);
internal::ArgList args(vlist); // This holder class allows for easier copying
- // and pointer semantics, as well as handing
+ // and pointer semantics, as well as handling
// destruction automatically.
va_end(vlist);
printf_core::StringWriter str_writer(buffer);
libc.src.stdio.sprintf
)
+add_libc_unittest(
+ snprintf_test
+ SUITE
+ libc_stdio_unittests
+ SRCS
+ snprintf_test.cpp
+ DEPENDS
+ libc.src.stdio.snprintf
+)
+
add_subdirectory(printf_core)
add_subdirectory(testdata)
--- /dev/null
+//===-- Unittests for snprintf --------------------------------------------===//
+//
+// 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/snprintf.h"
+
+#include "utils/UnitTest/Test.h"
+
+// The sprintf test cases cover testing the shared printf functionality, so
+// these tests will focus on snprintf exclusive features.
+
+TEST(LlvmLibcSNPrintfTest, CutOff) {
+ char buff[64];
+ int written;
+
+ written =
+ __llvm_libc::snprintf(buff, 16, "A simple string with no conversions.");
+ EXPECT_EQ(written, 36);
+ ASSERT_STREQ(buff, "A simple string");
+
+ written = __llvm_libc::snprintf(buff, 5, "%s", "1234567890");
+ EXPECT_EQ(written, 10);
+ ASSERT_STREQ(buff, "1234");
+
+ // passing null as the output pointer is allowed as long as buffsz is 0.
+ written = __llvm_libc::snprintf(nullptr, 0, "%s and more", "1234567890");
+ EXPECT_EQ(written, 19);
+}
+
+TEST(LlvmLibcSNPrintfTest, NoCutOff) {
+ char buff[64];
+ int written;
+
+ written =
+ __llvm_libc::snprintf(buff, 37, "A simple string with no conversions.");
+ EXPECT_EQ(written, 36);
+ ASSERT_STREQ(buff, "A simple string with no conversions.");
+
+ written = __llvm_libc::snprintf(buff, 20, "%s", "1234567890");
+ EXPECT_EQ(written, 10);
+ ASSERT_STREQ(buff, "1234567890");
+}