• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
25 namespace LIBC_NAMESPACE {
26 namespace printf_core {
27 
convert(Writer * writer,const FormatSection & to_conv)28 int convert(Writer *writer, const FormatSection &to_conv) {
29   if (!to_conv.has_conv)
30     return writer->write(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("%");
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(to_conv.raw_string);
94   }
95   return -1;
96 }
97 
98 } // namespace printf_core
99 } // namespace LIBC_NAMESPACE
100