1 //===-- Format specifier converter implmentation for scanf -----*- 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 #include "src/stdio/scanf_core/converter.h"
11 #include "src/__support/ctype_utils.h"
12 #include "src/stdio/scanf_core/core_structs.h"
13 #include "src/stdio/scanf_core/reader.h"
15 #ifndef LIBC_COPT_SCANF_DISABLE_FLOAT
16 #include "src/stdio/scanf_core/float_converter.h"
17 #endif // LIBC_COPT_SCANF_DISABLE_FLOAT
18 #include "src/stdio/scanf_core/current_pos_converter.h"
19 #include "src/stdio/scanf_core/int_converter.h"
20 #include "src/stdio/scanf_core/ptr_converter.h"
21 #include "src/stdio/scanf_core/string_converter.h"
25 namespace LIBC_NAMESPACE
{
26 namespace scanf_core
{
28 int convert(Reader
*reader
, const FormatSection
&to_conv
) {
30 switch (to_conv
.conv_name
) {
32 return raw_match(reader
, "%");
34 ret_val
= raw_match(reader
, " ");
35 if (ret_val
!= READ_OK
)
37 return convert_string(reader
, to_conv
);
40 return convert_string(reader
, to_conv
);
47 ret_val
= raw_match(reader
, " ");
48 if (ret_val
!= READ_OK
)
50 return convert_int(reader
, to_conv
);
51 #ifndef LIBC_COPT_SCANF_DISABLE_FLOAT
60 ret_val
= raw_match(reader
, " ");
61 if (ret_val
!= READ_OK
)
63 return convert_float(reader
, to_conv
);
64 #endif // LIBC_COPT_SCANF_DISABLE_FLOAT
66 return convert_current_pos(reader
, to_conv
);
68 ret_val
= raw_match(reader
, " ");
69 if (ret_val
!= READ_OK
)
71 return convert_pointer(reader
, to_conv
);
73 return raw_match(reader
, to_conv
.raw_string
);
78 // raw_string is assumed to have a positive size.
79 int raw_match(Reader
*reader
, cpp::string_view raw_string
) {
80 char cur_char
= reader
->getc();
81 int ret_val
= READ_OK
;
82 for (size_t i
= 0; i
< raw_string
.size(); ++i
) {
83 // Any space character matches any number of space characters.
84 if (internal::isspace(raw_string
[i
])) {
85 while (internal::isspace(cur_char
)) {
86 cur_char
= reader
->getc();
89 if (raw_string
[i
] == cur_char
) {
90 cur_char
= reader
->getc();
92 ret_val
= MATCHING_FAILURE
;
97 reader
->ungetc(cur_char
);
101 } // namespace scanf_core
102 } // namespace LIBC_NAMESPACE