| //===-- Format specifier converter implmentation for printf -----*- C++ -*-===// |
| // |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| // See https://llvm.org/LICENSE.txt for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #include "src/stdio/printf_core/converter.h" |
| |
| #include "src/__support/macros/config.h" |
| #include "src/stdio/printf_core/core_structs.h" |
| #include "src/stdio/printf_core/printf_config.h" |
| #include "src/stdio/printf_core/strerror_converter.h" |
| #include "src/stdio/printf_core/writer.h" |
| |
| // This option allows for replacing all of the conversion functions with custom |
| // replacements. This allows conversions to be replaced at compile time. |
| #ifndef LIBC_COPT_PRINTF_CONV_ATLAS |
| #include "src/stdio/printf_core/converter_atlas.h" |
| #else |
| #include LIBC_COPT_PRINTF_CONV_ATLAS |
| #endif |
| |
| #include <stddef.h> |
| |
| namespace LIBC_NAMESPACE_DECL { |
| namespace printf_core { |
| |
| int convert(Writer *writer, const FormatSection &to_conv) { |
| if (!to_conv.has_conv) |
| return writer->write(to_conv.raw_string); |
| |
| #if !defined(LIBC_COPT_PRINTF_DISABLE_FLOAT) && \ |
| defined(LIBC_COPT_PRINTF_HEX_LONG_DOUBLE) |
| if (to_conv.length_modifier == LengthModifier::L) { |
| switch (to_conv.conv_name) { |
| case 'f': |
| case 'F': |
| case 'e': |
| case 'E': |
| case 'g': |
| case 'G': |
| return convert_float_hex_exp(writer, to_conv); |
| default: |
| break; |
| } |
| } |
| #endif // LIBC_COPT_PRINTF_DISABLE_FLOAT |
| |
| switch (to_conv.conv_name) { |
| case '%': |
| return writer->write("%"); |
| case 'c': |
| return convert_char(writer, to_conv); |
| case 's': |
| return convert_string(writer, to_conv); |
| case 'd': |
| case 'i': |
| case 'u': |
| case 'o': |
| case 'x': |
| case 'X': |
| case 'b': |
| case 'B': |
| return convert_int(writer, to_conv); |
| #ifndef LIBC_COPT_PRINTF_DISABLE_FLOAT |
| case 'f': |
| case 'F': |
| return convert_float_decimal(writer, to_conv); |
| case 'e': |
| case 'E': |
| return convert_float_dec_exp(writer, to_conv); |
| case 'a': |
| case 'A': |
| return convert_float_hex_exp(writer, to_conv); |
| case 'g': |
| case 'G': |
| return convert_float_dec_auto(writer, to_conv); |
| #endif // LIBC_COPT_PRINTF_DISABLE_FLOAT |
| #ifdef LIBC_INTERNAL_PRINTF_HAS_FIXED_POINT |
| case 'r': |
| case 'R': |
| case 'k': |
| case 'K': |
| return convert_fixed(writer, to_conv); |
| #endif // LIBC_INTERNAL_PRINTF_HAS_FIXED_POINT |
| #ifndef LIBC_COPT_PRINTF_DISABLE_STRERROR |
| case 'm': |
| return convert_strerror(writer, to_conv); |
| #endif // LIBC_COPT_PRINTF_DISABLE_STRERROR |
| #ifndef LIBC_COPT_PRINTF_DISABLE_WRITE_INT |
| case 'n': |
| return convert_write_int(writer, to_conv); |
| #endif // LIBC_COPT_PRINTF_DISABLE_WRITE_INT |
| case 'p': |
| return convert_pointer(writer, to_conv); |
| default: |
| return writer->write(to_conv.raw_string); |
| } |
| return -1; |
| } |
| |
| } // namespace printf_core |
| } // namespace LIBC_NAMESPACE_DECL |