10
10
#define LLVM_LIBC_SRC_STDIO_SCANF_CORE_CONVERTER_H
11
11
12
12
#include " src/__support/CPP/string_view.h"
13
+ #include " src/__support/ctype_utils.h"
13
14
#include " src/__support/macros/config.h"
14
15
#include " src/stdio/scanf_core/core_structs.h"
15
16
#include " src/stdio/scanf_core/reader.h"
16
17
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
+
17
26
#include < stddef.h>
18
27
19
28
namespace LIBC_NAMESPACE_DECL {
@@ -22,11 +31,81 @@ namespace scanf_core {
22
31
// convert will call a conversion function to convert the FormatSection into
23
32
// its string representation, and then that will write the result to the
24
33
// 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
+ }
26
84
27
85
// raw_match takes a raw string and matches it to the characters obtained from
28
86
// 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
+ }
30
109
31
110
} // namespace scanf_core
32
111
} // namespace LIBC_NAMESPACE_DECL
0 commit comments