Warning: This file is not a C or C++ file. It does not have highlighting.

1//===-- Format specifier converter for scanf -------------------*- C++ -*-===//
2//
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
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef LLVM_LIBC_SRC_STDIO_SCANF_CORE_CONVERTER_H
10#define LLVM_LIBC_SRC_STDIO_SCANF_CORE_CONVERTER_H
11
12#include "src/__support/CPP/string_view.h"
13#include "src/__support/ctype_utils.h"
14#include "src/__support/macros/config.h"
15#include "src/stdio/scanf_core/core_structs.h"
16#include "src/stdio/scanf_core/reader.h"
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
26#include <stddef.h>
27
28namespace LIBC_NAMESPACE_DECL {
29namespace scanf_core {
30
31// convert will call a conversion function to convert the FormatSection into
32// its string representation, and then that will write the result to the
33// reader.
34template <typename T>
35int 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}
84
85// raw_match takes a raw string and matches it to the characters obtained from
86// the reader.
87template <typename T>
88int 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}
109
110} // namespace scanf_core
111} // namespace LIBC_NAMESPACE_DECL
112
113#endif // LLVM_LIBC_SRC_STDIO_SCANF_CORE_CONVERTER_H
114

Warning: This file is not a C or C++ file. It does not have highlighting.

source code of libc/src/stdio/scanf_core/converter.h