1 //===-- Internal implementation header of vfscanf ---------------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #ifndef LLVM_LIBC_SRC_STDIO_SCANF_CORE_VFSCANF_INTERNAL_H
10 #define LLVM_LIBC_SRC_STDIO_SCANF_CORE_VFSCANF_INTERNAL_H
12 #include "src/__support/File/file.h"
13 #include "src/__support/arg_list.h"
14 #include "src/stdio/scanf_core/reader.h"
15 #include "src/stdio/scanf_core/scanf_main.h"
19 namespace LIBC_NAMESPACE
{
23 #ifndef LIBC_COPT_STDIO_USE_SYSTEM_FILE
25 LIBC_INLINE
void flockfile(FILE *f
) {
26 reinterpret_cast<LIBC_NAMESPACE::File
*>(f
)->lock();
29 LIBC_INLINE
void funlockfile(FILE *f
) {
30 reinterpret_cast<LIBC_NAMESPACE::File
*>(f
)->unlock();
33 LIBC_INLINE
int getc(void *f
) {
36 reinterpret_cast<LIBC_NAMESPACE::File
*>(f
)->read_unlocked(&c
, 1);
37 size_t r
= result
.value
;
38 if (result
.has_error() || r
!= 1)
44 LIBC_INLINE
void ungetc(int c
, void *f
) {
45 reinterpret_cast<LIBC_NAMESPACE::File
*>(f
)->ungetc_unlocked(c
);
48 LIBC_INLINE
int ferror_unlocked(FILE *f
) {
49 return reinterpret_cast<LIBC_NAMESPACE::File
*>(f
)->error_unlocked();
52 #else // defined(LIBC_COPT_STDIO_USE_SYSTEM_FILE)
54 // Since ungetc_unlocked isn't always available, we don't acquire the lock for
56 LIBC_INLINE
void flockfile(::FILE *) { return; }
58 LIBC_INLINE
void funlockfile(::FILE *) { return; }
60 LIBC_INLINE
int getc(void *f
) { return ::getc(reinterpret_cast<::FILE *>(f
)); }
62 LIBC_INLINE
void ungetc(int c
, void *f
) {
63 ::ungetc(c
, reinterpret_cast<::FILE *>(f
));
66 LIBC_INLINE
int ferror_unlocked(::FILE *f
) { return ::ferror(f
); }
68 #endif // LIBC_COPT_STDIO_USE_SYSTEM_FILE
70 } // namespace internal
72 namespace scanf_core
{
74 LIBC_INLINE
int vfscanf_internal(::FILE *__restrict stream
,
75 const char *__restrict format
,
76 internal::ArgList
&args
) {
77 internal::flockfile(stream
);
78 scanf_core::Reader
reader(stream
, &internal::getc
, internal::ungetc
);
79 int retval
= scanf_core::scanf_main(&reader
, format
, args
);
80 if (retval
== 0 && internal::ferror_unlocked(stream
))
82 internal::funlockfile(stream
);
86 } // namespace scanf_core
87 } // namespace LIBC_NAMESPACE
89 #endif // LLVM_LIBC_SRC_STDIO_SCANF_CORE_VFSCANF_INTERNAL_H