1//===-- Format specifier converter implmentation for printf -----*- 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#include "src/stdio/printf_core/converter.h"
10
11#include "src/stdio/printf_core/core_structs.h"
12#include "src/stdio/printf_core/printf_config.h"
13#include "src/stdio/printf_core/writer.h"
14
15// This option allows for replacing all of the conversion functions with custom
16// replacements. This allows conversions to be replaced at compile time.
17#ifndef LIBC_COPT_PRINTF_CONV_ATLAS
18#include "src/stdio/printf_core/converter_atlas.h"
19#else
20#include LIBC_COPT_PRINTF_CONV_ATLAS
21#endif
22
23#include <stddef.h>
24
25namespace LIBC_NAMESPACE {
26namespace printf_core {
27
28int convert(Writer *writer, const FormatSection &to_conv) {
29 if (!to_conv.has_conv)
30 return writer->write(new_string: to_conv.raw_string);
31
32#if !defined(LIBC_COPT_PRINTF_DISABLE_FLOAT) && \
33 defined(LIBC_COPT_PRINTF_HEX_LONG_DOUBLE)
34 if (to_conv.length_modifier == LengthModifier::L) {
35 switch (to_conv.conv_name) {
36 case 'f':
37 case 'F':
38 case 'e':
39 case 'E':
40 case 'g':
41 case 'G':
42 return convert_float_hex_exp(writer, to_conv);
43 default:
44 break;
45 }
46 }
47#endif // LIBC_COPT_PRINTF_DISABLE_FLOAT
48
49 switch (to_conv.conv_name) {
50 case '%':
51 return writer->write(new_string: "%");
52 case 'c':
53 return convert_char(writer, to_conv);
54 case 's':
55 return convert_string(writer, to_conv);
56 case 'd':
57 case 'i':
58 case 'u':
59 case 'o':
60 case 'x':
61 case 'X':
62 case 'b':
63 case 'B':
64 return convert_int(writer, to_conv);
65#ifndef LIBC_COPT_PRINTF_DISABLE_FLOAT
66 case 'f':
67 case 'F':
68 return convert_float_decimal(writer, to_conv);
69 case 'e':
70 case 'E':
71 return convert_float_dec_exp(writer, to_conv);
72 case 'a':
73 case 'A':
74 return convert_float_hex_exp(writer, to_conv);
75 case 'g':
76 case 'G':
77 return convert_float_dec_auto(writer, to_conv);
78#endif // LIBC_COPT_PRINTF_DISABLE_FLOAT
79#ifdef LIBC_INTERNAL_PRINTF_HAS_FIXED_POINT
80 case 'r':
81 case 'R':
82 case 'k':
83 case 'K':
84 return convert_fixed(writer, to_conv);
85#endif // LIBC_INTERNAL_PRINTF_HAS_FIXED_POINT
86#ifndef LIBC_COPT_PRINTF_DISABLE_WRITE_INT
87 case 'n':
88 return convert_write_int(writer, to_conv);
89#endif // LIBC_COPT_PRINTF_DISABLE_WRITE_INT
90 case 'p':
91 return convert_pointer(writer, to_conv);
92 default:
93 return writer->write(new_string: to_conv.raw_string);
94 }
95 return -1;
96}
97
98} // namespace printf_core
99} // namespace LIBC_NAMESPACE
100

source code of libc/src/stdio/printf_core/converter.cpp