[libc-commits] [libc] [libc] Refactor scanf reader to match printf (PR #66023)
via libc-commits
libc-commits at lists.llvm.org
Mon Sep 11 15:45:03 PDT 2023
llvmbot wrote:
@llvm/pr-subscribers-libc
<details>
<summary>Changes</summary>
In a previous patch, the printf writer was rewritten to use a single writer class with a buffer and a callback hook. This patch refactors scanf's reader to match conceptually.
--
Patch is 26.54 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/66023.diff
20 Files Affected:
- (modified) libc/config/linux/aarch64/entrypoints.txt (+4)
- (modified) libc/config/linux/riscv64/entrypoints.txt (+3-4)
- (modified) libc/config/linux/x86_64/entrypoints.txt (+3-3)
- (modified) libc/src/stdio/CMakeLists.txt (+21-5)
- (modified) libc/src/stdio/scanf.cpp (+7-1)
- (modified) libc/src/stdio/scanf_core/CMakeLists.txt (+10-30)
- (removed) libc/src/stdio/scanf_core/file_reader.cpp (-27)
- (removed) libc/src/stdio/scanf_core/file_reader.h (-39)
- (modified) libc/src/stdio/scanf_core/reader.cpp (+8-24)
- (modified) libc/src/stdio/scanf_core/reader.h (+33-16)
- (modified) libc/src/stdio/scanf_core/scanf_main.cpp (-5)
- (removed) libc/src/stdio/scanf_core/string_reader.cpp (-24)
- (removed) libc/src/stdio/scanf_core/string_reader.h (-33)
- (removed) libc/src/stdio/scanf_core/vfscanf_internal.cpp (-29)
- (modified) libc/src/stdio/scanf_core/vfscanf_internal.h (+44-2)
- (modified) libc/src/stdio/sscanf.cpp (+4-3)
- (modified) libc/test/src/stdio/CMakeLists.txt (+17-4)
- (modified) libc/test/src/stdio/fscanf_test.cpp (+28-10)
- (modified) libc/test/src/stdio/scanf_core/CMakeLists.txt (+8-9)
- (renamed) libc/test/src/stdio/scanf_core/reader_test.cpp (+8-7)
<pre>
diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index e0bf9800ec881c2..fc865dc0cbb6a57 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -126,6 +126,10 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.stdio.snprintf
libc.src.stdio.vsprintf
libc.src.stdio.vsnprintf
+ #TODO: Check if scanf can be enabled on aarch64
+ #libc.src.stdio.sscanf
+ #libc.src.stdio.scanf
+ #libc.src.stdio.fscanf
# sys/mman.h entrypoints
libc.src.sys.mman.madvise
diff --git a/libc/config/linux/riscv64/entrypoints.txt b/libc/config/linux/riscv64/entrypoints.txt
index 2b2f2629f78ce67..9574595ed459383 100644
--- a/libc/config/linux/riscv64/entrypoints.txt
+++ b/libc/config/linux/riscv64/entrypoints.txt
@@ -132,6 +132,9 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.stdio.vsnprintf
libc.src.stdio.vfprintf
libc.src.stdio.vprintf
+ libc.src.stdio.sscanf
+ libc.src.stdio.scanf
+ libc.src.stdio.fscanf
# sys/mman.h entrypoints
libc.src.sys.mman.madvise
@@ -439,10 +442,6 @@ if(LLVM_LIBC_FULL_BUILD)
libc.src.stdio.getc_unlocked
libc.src.stdio.getchar
libc.src.stdio.getchar_unlocked
- libc.src.stdio.printf
- libc.src.stdio.sscanf
- libc.src.stdio.scanf
- libc.src.stdio.fscanf
libc.src.stdio.putc
libc.src.stdio.putchar
libc.src.stdio.puts
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index dcb8c6231432d35..1c3fcb0c1e7c9e9 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -132,6 +132,9 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.stdio.vsnprintf
libc.src.stdio.vfprintf
libc.src.stdio.vprintf
+ libc.src.stdio.sscanf
+ libc.src.stdio.scanf
+ libc.src.stdio.fscanf
# sys/mman.h entrypoints
libc.src.sys.mman.madvise
@@ -445,9 +448,6 @@ if(LLVM_LIBC_FULL_BUILD)
libc.src.stdio.getc_unlocked
libc.src.stdio.getchar
libc.src.stdio.getchar_unlocked
- libc.src.stdio.sscanf
- libc.src.stdio.scanf
- libc.src.stdio.fscanf
libc.src.stdio.putc
libc.src.stdio.putchar
libc.src.stdio.puts
diff --git a/libc/src/stdio/CMakeLists.txt b/libc/src/stdio/CMakeLists.txt
index 740ec106da2e4d7..6c393855b28cada 100644
--- a/libc/src/stdio/CMakeLists.txt
+++ b/libc/src/stdio/CMakeLists.txt
@@ -292,6 +292,21 @@ add_entrypoint_object(
libc.src.__support.File.platform_file
)
+list(APPEND scanf_deps
+ libc.src.__support.arg_list
+ libc.src.stdio.scanf_core.vfscanf_internal
+)
+
+if(LLVM_LIBC_FULL_BUILD)
+ list(APPEND scanf_deps
+ libc.src.__support.File.file
+ libc.src.__support.File.platform_file
+ libc.src.__support.File.platform_stdin
+ )
+else()
+ list(APPEND scanf_copts "-DLIBC_COPT_SCANF_USE_SYSTEM_FILE")
+endif()
+
add_entrypoint_object(
sscanf
SRCS
@@ -300,7 +315,6 @@ add_entrypoint_object(
sscanf.h
DEPENDS
libc.src.__support.arg_list
- libc.src.stdio.scanf_core.string_reader
libc.src.stdio.scanf_core.reader
libc.src.stdio.scanf_core.scanf_main
)
@@ -312,8 +326,9 @@ add_entrypoint_object(
HDRS
fscanf.h
DEPENDS
- libc.src.__support.arg_list
- libc.src.stdio.scanf_core.vfscanf_internal
+ ${scanf_deps}
+ COMPILE_OPTIONS
+ ${scanf_copts}
)
add_entrypoint_object(
@@ -323,8 +338,9 @@ add_entrypoint_object(
HDRS
scanf.h
DEPENDS
- libc.src.__support.arg_list
- libc.src.stdio.scanf_core.vfscanf_internal
+ ${scanf_deps}
+ COMPILE_OPTIONS
+ ${scanf_copts}
)
add_entrypoint_object(
diff --git a/libc/src/stdio/scanf.cpp b/libc/src/stdio/scanf.cpp
index 60e77895edcc3c6..d98cc3d58e23251 100644
--- a/libc/src/stdio/scanf.cpp
+++ b/libc/src/stdio/scanf.cpp
@@ -15,6 +15,12 @@
#include <stdarg.h>
#include <stdio.h>
+#ifndef LIBC_COPT_SCANF_USE_SYSTEM_FILE
+#define SCANF_STDIN __llvm_libc::stdin
+#else // LIBC_COPT_SCANF_USE_SYSTEM_FILE
+#define SCANF_STDIN ::stdin
+#endif // LIBC_COPT_SCANF_USE_SYSTEM_FILE
+
namespace __llvm_libc {
LLVM_LIBC_FUNCTION(int, scanf, (const char *__restrict format, ...)) {
@@ -25,7 +31,7 @@ LLVM_LIBC_FUNCTION(int, scanf, (const char *__restrict format, ...)) {
// destruction automatically.
va_end(vlist);
int ret_val = scanf_core::vfscanf_internal(
- reinterpret_cast<::FILE *>(__llvm_libc::stdin), format, args);
+ reinterpret_cast<::FILE *>(SCANF_STDIN), format, args);
// This is done to avoid including stdio.h in the internals. On most systems
// EOF is -1, so this will be transformed into just "return ret_val".
return (ret_val == -1) ? EOF : ret_val;
diff --git a/libc/src/stdio/scanf_core/CMakeLists.txt b/libc/src/stdio/scanf_core/CMakeLists.txt
index 9f6cb9c386eb226..dd775b437a9d840 100644
--- a/libc/src/stdio/scanf_core/CMakeLists.txt
+++ b/libc/src/stdio/scanf_core/CMakeLists.txt
@@ -24,12 +24,6 @@ add_object_library(
libc.src.__support.CPP.string_view
)
-if(NOT (TARGET libc.src.__support.File.file))
- # Not all platforms have a file implementation. If file is unvailable,
- # then we must skip all the parts that need file.
- return()
-endif()
-
add_object_library(
scanf_main
SRCS
@@ -44,24 +38,6 @@ add_object_library(
libc.src.__support.arg_list
)
-add_object_library(
- string_reader
- SRCS
- string_reader.cpp
- HDRS
- string_reader.h
-)
-
-add_object_library(
- file_reader
- SRCS
- file_reader.cpp
- HDRS
- file_reader.h
- DEPENDS
- libc.src.__support.File.file
-)
-
add_object_library(
reader
SRCS
@@ -69,8 +45,7 @@ add_object_library(
HDRS
reader.h
DEPENDS
- .string_reader
- .file_reader
+ libc.src.__support.macros.attributes
)
add_object_library(
@@ -101,15 +76,20 @@ add_object_library(
libc.src.__support.str_to_float
)
-add_object_library(
+if(NOT (TARGET libc.src.__support.File.file) AND LLVM_LIBC_FULL_BUILD)
+ # Not all platforms have a file implementation. If file is unvailable, and a
+ # full build is requested, then we must skip all file based printf sections.
+ return()
+endif()
+
+add_header_library(
vfscanf_internal
- SRCS
- vfscanf_internal.cpp
HDRS
vfscanf_internal.h
DEPENDS
.reader
- .file_reader
.scanf_main
+ libc.include.stdio
+ libc.src.__support.File.file
libc.src.__support.arg_list
)
diff --git a/libc/src/stdio/scanf_core/file_reader.cpp b/libc/src/stdio/scanf_core/file_reader.cpp
deleted file mode 100644
index 51e22299e3dd2c5..000000000000000
--- a/libc/src/stdio/scanf_core/file_reader.cpp
+++ /dev/null
@@ -1,27 +0,0 @@
-//===-- FILE Reader implementation for scanf --------------------*- 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/scanf_core/file_reader.h"
-#include "src/__support/File/file.h"
-#include <stddef.h>
-
-namespace __llvm_libc {
-namespace scanf_core {
-
-char FileReader::get_char() {
- char tiny_buff = 0;
- auto result = file->read_unlocked(&tiny_buff, 1);
- if (result.value != 1 || result.has_error())
- return 0;
- return tiny_buff;
-}
-
-void FileReader::unget_char(char c) { file->ungetc_unlocked(c); }
-
-} // namespace scanf_core
-} // namespace __llvm_libc
diff --git a/libc/src/stdio/scanf_core/file_reader.h b/libc/src/stdio/scanf_core/file_reader.h
deleted file mode 100644
index a70e00bc2413963..000000000000000
--- a/libc/src/stdio/scanf_core/file_reader.h
+++ /dev/null
@@ -1,39 +0,0 @@
-//===-- FILE Reader definition for scanf ------------------------*- 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_SCANF_CORE_FILE_READER_H
-#define LLVM_LIBC_SRC_STDIO_SCANF_CORE_FILE_READER_H
-
-#include "src/__support/File/file.h"
-
-#include <stddef.h>
-#include <stdio.h>
-
-namespace __llvm_libc {
-namespace scanf_core {
-
-class FileReader {
- __llvm_libc::File *file;
-
-public:
- FileReader(::FILE *init_file) {
- file = reinterpret_cast<__llvm_libc::File *>(init_file);
- file->lock();
- }
-
- ~FileReader() { file->unlock(); }
-
- char get_char();
- void unget_char(char c);
- bool has_error() { return file->error_unlocked(); }
-};
-
-} // namespace scanf_core
-} // namespace __llvm_libc
-
-#endif // LLVM_LIBC_SRC_STDIO_SCANF_CORE_FILE_READER_H
diff --git a/libc/src/stdio/scanf_core/reader.cpp b/libc/src/stdio/scanf_core/reader.cpp
index 4834f4d6a6e7955..45241d8d86b01fe 100644
--- a/libc/src/stdio/scanf_core/reader.cpp
+++ b/libc/src/stdio/scanf_core/reader.cpp
@@ -12,33 +12,17 @@
namespace __llvm_libc {
namespace scanf_core {
-char Reader::getc() {
- ++cur_chars_read;
- if (reader_type == ReaderType::String) {
- return string_reader->get_char();
- } else {
- return file_reader->get_char();
- }
-}
-
void Reader::ungetc(char c) {
--cur_chars_read;
- if (reader_type == ReaderType::String) {
- // The string reader ignores the char c passed to unget since it doesn't
- // need to place anything back into a buffer, and modifying the source
- // string would be dangerous.
- return string_reader->unget_char();
- } else {
- return file_reader->unget_char(c);
+ if (rb != nullptr && rb->buff_cur > 0) {
+ // While technically c should be written back to the buffer, in scanf we
+ // always write the character that was already there. Additionally, the
+ // buffer is most likely to contain a string that isn't part of a file,
+ // which may not be writable.
+ --(rb->buff_cur);
+ return;
}
+ stream_ungetc(static_cast<int>(c), input_stream);
}
-
-bool Reader::has_error() {
- if (reader_type == ReaderType::File) {
- return file_reader->has_error();
- }
- return false;
-}
-
} // namespace scanf_core
} // namespace __llvm_libc
diff --git a/libc/src/stdio/scanf_core/reader.h b/libc/src/stdio/scanf_core/reader.h
index 000ab02ad28f21e..7e9cfc5c8ca2fb1 100644
--- a/libc/src/stdio/scanf_core/reader.h
+++ b/libc/src/stdio/scanf_core/reader.h
@@ -9,44 +9,61 @@
#ifndef LLVM_LIBC_SRC_STDIO_SCANF_CORE_READER_H
#define LLVM_LIBC_SRC_STDIO_SCANF_CORE_READER_H
-#include "src/stdio/scanf_core/file_reader.h"
-#include "src/stdio/scanf_core/string_reader.h"
+#include "src/__support/macros/attributes.h" // For LIBC_INLINE
#include <stddef.h>
namespace __llvm_libc {
namespace scanf_core {
-enum class ReaderType { String, File };
+using StreamGetc = int (*)(void *);
+using StreamUngetc = void (*)(int, void *);
-class Reader final {
- union {
- StringReader *string_reader;
- FileReader *file_reader;
- };
+// This is intended to be either a raw string or a buffer syncronized with the
+// file's internal buffer.
+struct ReadBuffer {
+ char *buffer;
+ size_t buff_len;
+ size_t buff_cur = 0;
+};
+
+class Reader {
+ ReadBuffer *rb;
- const ReaderType reader_type;
+ void *input_stream = nullptr;
+
+ StreamGetc stream_getc = nullptr;
+ StreamUngetc stream_ungetc = nullptr;
size_t cur_chars_read = 0;
public:
- Reader(StringReader *init_string_reader)
- : string_reader(init_string_reader), reader_type(ReaderType::String) {}
+ // TODO: Set buff_len with a proper constant
+ Reader(ReadBuffer *string_buffer) : rb(string_buffer) {}
- Reader(FileReader *init_file_reader)
- : file_reader(init_file_reader), reader_type(ReaderType::File) {}
+ Reader(void *stream, StreamGetc stream_getc_in, StreamUngetc stream_ungetc_in,
+ ReadBuffer *stream_buffer = nullptr)
+ : rb(stream_buffer), input_stream(stream), stream_getc(stream_getc_in),
+ stream_ungetc(stream_ungetc_in) {}
// This returns the next character from the input and advances it by one
// character. When it hits the end of the string or file it returns '\0' to
// signal to stop parsing.
- char getc();
+ LIBC_INLINE char getc() {
+ ++cur_chars_read;
+ if (rb != nullptr) {
+ char output = rb->buffer[rb->buff_cur];
+ ++(rb->buff_cur);
+ return output;
+ }
+ // This should reset the buffer if applicable.
+ return static_cast<char>(stream_getc(input_stream));
+ }
// This moves the input back by one character, placing c into the buffer if
// this is a file reader, else c is ignored.
void ungetc(char c);
size_t chars_read() { return cur_chars_read; }
-
- bool has_error();
};
} // namespace scanf_core
diff --git a/libc/src/stdio/scanf_core/scanf_main.cpp b/libc/src/stdio/scanf_core/scanf_main.cpp
index 5a79d2e624ab0aa..270024f31d2b68c 100644
--- a/libc/src/stdio/scanf_core/scanf_main.cpp
+++ b/libc/src/stdio/scanf_core/scanf_main.cpp
@@ -38,11 +38,6 @@ int scanf_main(Reader *reader, const char *__restrict str,
}
}
- if (conversions == 0 && reader->has_error()) {
- // This is intended to be converted to EOF in the client call to avoid
- // including stdio.h in this internal file.
- return -1;
- }
return conversions;
}
diff --git a/libc/src/stdio/scanf_core/string_reader.cpp b/libc/src/stdio/scanf_core/string_reader.cpp
deleted file mode 100644
index 1d728d2b9eb35e6..000000000000000
--- a/libc/src/stdio/scanf_core/string_reader.cpp
+++ /dev/null
@@ -1,24 +0,0 @@
-//===-- String Reader implementation for scanf ------------------*- 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/scanf_core/string_reader.h"
-#include <stddef.h>
-
-namespace __llvm_libc {
-namespace scanf_core {
-
-char StringReader::get_char() {
- char cur_char = string[cur_index];
- ++cur_index;
- return cur_char;
-}
-
-void StringReader::unget_char() { --cur_index; }
-
-} // namespace scanf_core
-} // namespace __llvm_libc
diff --git a/libc/src/stdio/scanf_core/string_reader.h b/libc/src/stdio/scanf_core/string_reader.h
deleted file mode 100644
index 35550b16c32140f..000000000000000
--- a/libc/src/stdio/scanf_core/string_reader.h
+++ /dev/null
@@ -1,33 +0,0 @@
-//===-- String Reader definition for scanf ----------------------*- 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_SCANF_CORE_STRING_READER_H
-#define LLVM_LIBC_SRC_STDIO_SCANF_CORE_STRING_READER_H
-
-#include <stddef.h>
-
-namespace __llvm_libc {
-namespace scanf_core {
-
-class StringReader {
- const char *string;
- size_t cur_index = 0;
-
-public:
- StringReader(const char *init_string) { string = init_string; }
-
- ~StringReader() {}
-
- char get_char();
- void unget_char();
-};
-
-} // namespace scanf_core
-} // namespace __llvm_libc
-
-#endif // LLVM_LIBC_SRC_STDIO_SCANF_CORE_STRING_READER_H
diff --git a/libc/src/stdio/scanf_core/vfscanf_internal.cpp b/libc/src/stdio/scanf_core/vfscanf_internal.cpp
deleted file mode 100644
index af2f6fa01ad475d..000000000000000
--- a/libc/src/stdio/scanf_core/vfscanf_internal.cpp
+++ /dev/null
@@ -1,29 +0,0 @@
-//===-- Internal implementation of vfscanf ---------------------*- 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/scanf_core/vfscanf_internal.h"
-
-#include "src/__support/arg_list.h"
-#include "src/stdio/scanf_core/file_reader.h"
-#include "src/stdio/scanf_core/reader.h"
-#include "src/stdio/scanf_core/scanf_main.h"
-
-#include <stdio.h>
-
-namespace __llvm_libc {
-namespace scanf_core {
-
-int vfscanf_internal(::FILE *__restrict stream, const char *__restrict format,
- internal::ArgList &args) {
- FileReader file_reader(stream);
- scanf_core::Reader reader(&file_reader);
- return scanf_core::scanf_main(&reader, format, args);
-}
-
-} // namespace scanf_core
-} // namespace __llvm_libc
diff --git a/libc/src/stdio/scanf_core/vfscanf_internal.h b/libc/src/stdio/scanf_core/vfscanf_internal.h
index 456d1ff92056bed..693230560bc4f30 100644
--- a/libc/src/stdio/scanf_core/vfscanf_internal.h
+++ b/libc/src/stdio/scanf_core/vfscanf_internal.h
@@ -9,15 +9,57 @@
#ifndef LLVM_LIBC_SRC_STDIO_SCANF_CORE_VFSCANF_INTERNAL_H
#define LLVM_LIBC_SRC_STDIO_SCANF_CORE_VFSCANF_INTERNAL_H
+#include "src/__support/File/file.h"
#include "src/__support/arg_list.h"
+#include "src/stdio/scanf_core/reader.h"
+#include "src/stdio/scanf_core/scanf_main.h"
#include <stdio.h>
namespace __llvm_libc {
+
+namespace internal {
+#ifndef LIBC_COPT_SCANF_USE_SYSTEM_FILE
+LIBC_INLINE int getc(void *f) {
+ unsigned char c;
+ auto result = reinterpret_cast<__llvm_libc::File *>(f)->read_unlocked(&c, 1);
+ size_t r = result.value;
+ if (result.has_error() || r != 1) {
+ return '\0';
+ }
+ return c;
+}
+
+LIBC_INLINE void ungetc(int c, void *f) {
+ reinterpret_cast<__llvm_libc::File *>(f)->ungetc(c);
+}
+
+LIBC_INLINE int ferror_unlocked(FILE *f) {
+ return reinterpret_cast<__llvm_libc::File *>(f)->error_unlocked();
+}
+#else // defined(LIBC_COPT_PRINTF_USE_SYSTEM_FILE)
+LIBC_INLINE int getc(void *f) { return ::getc(reinterpret_cast<::FILE *>(f)); }
+
+LIBC_INLINE void ungetc(int c, void *f) {
+ ::ungetc(c, reinterpret_cast<::FILE *>(f));
+}
+
+LIBC_INLINE int ferror_unlocked(::FILE *f) { return ::ferror_unlocked(f); }
+#endif // LIBC_COPT_SCANF_USE_SYSTEM_FILE
+} // namespace internal
+
namespace scanf_core {
-int vfscanf_internal(::FILE *__restrict stream, const char *__restrict format,
- internal::ArgList &args);
+LIBC_INLINE int vfscanf_internal(::FILE *__restrict stream,
+ const char *__restrict format,
+ internal::ArgList &args) {
+ scanf_core::Reader reader(stream, &internal::getc, internal::ungetc);
+ int retval = scanf_core::scanf_main(&reader, format, args);
+ if (retval == 0 && internal::ferror_unlocked(stream)) {
+ return EOF;
+ }
+ return retval;
+}
} // namespace scanf_core
} // namespace __llvm_libc
diff --git a/libc/src/stdio/sscanf.cpp b/libc/src/stdio/sscanf.cpp
index 205b58fb3390e95..1f3e5ba888cd8fa 100644
--- a/libc/src/stdio/sscanf.cpp
+++ b/libc/src/stdio/sscanf.cpp
@@ -8,10 +8,10 @@
#include "src/stdio/sscanf.h"
+#include "src/__support/CPP/limits.h"
#include "src/__supp...
<truncated>
</pre>
</details>
https://github.com/llvm/llvm-project/pull/66023
More information about the libc-commits
mailing list