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