1 //===-- Format specifier converter 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 #ifndef LLVM_LIBC_SRC_STDIO_SCANF_CORE_CONVERTER_UTILS_H
10 #define LLVM_LIBC_SRC_STDIO_SCANF_CORE_CONVERTER_UTILS_H
12 #include "src/__support/ctype_utils.h"
13 #include "src/__support/macros/config.h"
14 #include "src/__support/str_to_float.h"
15 #include "src/stdio/scanf_core/core_structs.h"
19 namespace LIBC_NAMESPACE_DECL
{
20 namespace scanf_core
{
22 LIBC_INLINE
void write_int_with_length(uintmax_t output_val
,
23 const FormatSection
&to_conv
) {
24 if ((to_conv
.flags
& NO_WRITE
) != 0) {
27 void *output_ptr
= to_conv
.output_ptr
;
28 // The %p conversion uses this function, and is always void*.
29 if (to_conv
.conv_name
== 'p') {
30 *reinterpret_cast<void **>(output_ptr
) =
31 reinterpret_cast<void *>(output_val
);
34 LengthModifier lm
= to_conv
.length_modifier
;
36 case (LengthModifier::hh
):
37 *reinterpret_cast<unsigned char *>(output_ptr
) =
38 static_cast<unsigned char>(output_val
);
40 case (LengthModifier::h
):
41 *reinterpret_cast<unsigned short *>(output_ptr
) =
42 static_cast<unsigned short>(output_val
);
44 case (LengthModifier::NONE
):
45 *reinterpret_cast<unsigned int *>(output_ptr
) =
46 static_cast<unsigned int>(output_val
);
48 case (LengthModifier::l
):
49 *reinterpret_cast<unsigned long *>(output_ptr
) =
50 static_cast<unsigned long>(output_val
);
52 case (LengthModifier::ll
):
53 case (LengthModifier::L
):
54 *reinterpret_cast<unsigned long long *>(output_ptr
) =
55 static_cast<unsigned long long>(output_val
);
57 case (LengthModifier::j
):
58 *reinterpret_cast<uintmax_t *>(output_ptr
) =
59 static_cast<uintmax_t>(output_val
);
61 case (LengthModifier::z
):
62 *reinterpret_cast<size_t *>(output_ptr
) = static_cast<size_t>(output_val
);
64 case (LengthModifier::t
):
65 *reinterpret_cast<ptrdiff_t *>(output_ptr
) =
66 static_cast<ptrdiff_t>(output_val
);
71 LIBC_INLINE
void write_float_with_length(char *str
,
72 const FormatSection
&to_conv
) {
73 if ((to_conv
.flags
& NO_WRITE
) != 0) {
77 void *output_ptr
= to_conv
.output_ptr
;
79 LengthModifier lm
= to_conv
.length_modifier
;
81 case (LengthModifier::l
): {
82 auto value
= internal::strtofloatingpoint
<double>(str
);
83 *reinterpret_cast<double *>(output_ptr
) = value
;
86 case (LengthModifier::L
): {
87 auto value
= internal::strtofloatingpoint
<long double>(str
);
88 *reinterpret_cast<long double *>(output_ptr
) = value
;
92 auto value
= internal::strtofloatingpoint
<float>(str
);
93 *reinterpret_cast<float *>(output_ptr
) = value
;
99 } // namespace scanf_core
100 } // namespace LIBC_NAMESPACE_DECL
102 #endif // LLVM_LIBC_SRC_STDIO_SCANF_CORE_CONVERTER_UTILS_H