1010#define LLVM_LIBC_SRC_STDIO_SCANF_CORE_CONVERTER_H
1111
1212#include " src/__support/CPP/string_view.h"
13+ #include " src/__support/ctype_utils.h"
1314#include " src/__support/macros/config.h"
1415#include " src/stdio/scanf_core/core_structs.h"
1516#include " src/stdio/scanf_core/reader.h"
1617
18+ #ifndef LIBC_COPT_SCANF_DISABLE_FLOAT
19+ #include " src/stdio/scanf_core/float_converter.h"
20+ #endif // LIBC_COPT_SCANF_DISABLE_FLOAT
21+ #include " src/stdio/scanf_core/current_pos_converter.h"
22+ #include " src/stdio/scanf_core/int_converter.h"
23+ #include " src/stdio/scanf_core/ptr_converter.h"
24+ #include " src/stdio/scanf_core/string_converter.h"
25+
1726#include < stddef.h>
1827
1928namespace LIBC_NAMESPACE_DECL {
@@ -22,11 +31,81 @@ namespace scanf_core {
2231// convert will call a conversion function to convert the FormatSection into
2332// its string representation, and then that will write the result to the
2433// reader.
25- int convert (Reader *reader, const FormatSection &to_conv);
34+ template <typename T>
35+ int convert (Reader<T> *reader, const FormatSection &to_conv) {
36+ int ret_val = 0 ;
37+ switch (to_conv.conv_name ) {
38+ case ' %' :
39+ return raw_match (reader, " %" );
40+ case ' s' :
41+ ret_val = raw_match (reader, " " );
42+ if (ret_val != READ_OK)
43+ return ret_val;
44+ return convert_string (reader, to_conv);
45+ case ' c' :
46+ case ' [' :
47+ return convert_string (reader, to_conv);
48+ case ' d' :
49+ case ' i' :
50+ case ' u' :
51+ case ' o' :
52+ case ' x' :
53+ case ' X' :
54+ ret_val = raw_match (reader, " " );
55+ if (ret_val != READ_OK)
56+ return ret_val;
57+ return convert_int (reader, to_conv);
58+ #ifndef LIBC_COPT_SCANF_DISABLE_FLOAT
59+ case ' f' :
60+ case ' F' :
61+ case ' e' :
62+ case ' E' :
63+ case ' a' :
64+ case ' A' :
65+ case ' g' :
66+ case ' G' :
67+ ret_val = raw_match (reader, " " );
68+ if (ret_val != READ_OK)
69+ return ret_val;
70+ return convert_float (reader, to_conv);
71+ #endif // LIBC_COPT_SCANF_DISABLE_FLOAT
72+ case ' n' :
73+ return convert_current_pos (reader, to_conv);
74+ case ' p' :
75+ ret_val = raw_match (reader, " " );
76+ if (ret_val != READ_OK)
77+ return ret_val;
78+ return convert_pointer (reader, to_conv);
79+ default :
80+ return raw_match (reader, to_conv.raw_string );
81+ }
82+ return -1 ;
83+ }
2684
2785// raw_match takes a raw string and matches it to the characters obtained from
2886// the reader.
29- int raw_match (Reader *reader, cpp::string_view raw_string);
87+ template <typename T>
88+ int raw_match (Reader<T> *reader, cpp::string_view raw_string) {
89+ char cur_char = reader->getc ();
90+ int ret_val = READ_OK;
91+ for (size_t i = 0 ; i < raw_string.size (); ++i) {
92+ // Any space character matches any number of space characters.
93+ if (internal::isspace (raw_string[i])) {
94+ while (internal::isspace (cur_char)) {
95+ cur_char = reader->getc ();
96+ }
97+ } else {
98+ if (raw_string[i] == cur_char) {
99+ cur_char = reader->getc ();
100+ } else {
101+ ret_val = MATCHING_FAILURE;
102+ break ;
103+ }
104+ }
105+ }
106+ reader->ungetc (cur_char);
107+ return ret_val;
108+ }
30109
31110} // namespace scanf_core
32111} // namespace LIBC_NAMESPACE_DECL
0 commit comments