Warning: This file is not a C or C++ file. It does not have highlighting.
| 1 | //===-- Inf or Nan Converter 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 | #ifndef LLVM_LIBC_SRC_STDIO_PRINTF_CORE_FLOAT_INF_NAN_CONVERTER_H |
| 10 | #define LLVM_LIBC_SRC_STDIO_PRINTF_CORE_FLOAT_INF_NAN_CONVERTER_H |
| 11 | |
| 12 | #include "src/__support/FPUtil/FPBits.h" |
| 13 | #include "src/__support/ctype_utils.h" |
| 14 | #include "src/__support/macros/config.h" |
| 15 | #include "src/stdio/printf_core/converter_utils.h" |
| 16 | #include "src/stdio/printf_core/core_structs.h" |
| 17 | #include "src/stdio/printf_core/writer.h" |
| 18 | |
| 19 | #include <inttypes.h> |
| 20 | #include <stddef.h> |
| 21 | |
| 22 | namespace LIBC_NAMESPACE_DECL { |
| 23 | namespace printf_core { |
| 24 | |
| 25 | using StorageType = fputil::FPBits<long double>::StorageType; |
| 26 | |
| 27 | template <WriteMode write_mode> |
| 28 | LIBC_INLINE int convert_inf_nan(Writer<write_mode> *writer, |
| 29 | const FormatSection &to_conv) { |
| 30 | // All of the letters will be defined relative to variable a, which will be |
| 31 | // the appropriate case based on the case of the conversion. |
| 32 | bool is_negative; |
| 33 | StorageType mantissa; |
| 34 | if (to_conv.length_modifier == LengthModifier::L) { |
| 35 | fputil::FPBits<long double>::StorageType float_raw = to_conv.conv_val_raw; |
| 36 | fputil::FPBits<long double> float_bits(float_raw); |
| 37 | is_negative = float_bits.is_neg(); |
| 38 | mantissa = float_bits.get_mantissa(); |
| 39 | } else { |
| 40 | fputil::FPBits<double>::StorageType float_raw = |
| 41 | static_cast<fputil::FPBits<double>::StorageType>(to_conv.conv_val_raw); |
| 42 | fputil::FPBits<double> float_bits(float_raw); |
| 43 | is_negative = float_bits.is_neg(); |
| 44 | mantissa = float_bits.get_mantissa(); |
| 45 | } |
| 46 | |
| 47 | char sign_char = 0; |
| 48 | |
| 49 | if (is_negative) |
| 50 | sign_char = '-'; |
| 51 | else if ((to_conv.flags & FormatFlags::FORCE_SIGN) == FormatFlags::FORCE_SIGN) |
| 52 | sign_char = '+'; // FORCE_SIGN has precedence over SPACE_PREFIX |
| 53 | else if ((to_conv.flags & FormatFlags::SPACE_PREFIX) == |
| 54 | FormatFlags::SPACE_PREFIX) |
| 55 | sign_char = ' '; |
| 56 | |
| 57 | // Both "inf" and "nan" are the same number of characters, being 3. |
| 58 | int padding = to_conv.min_width - (sign_char > 0 ? 1 : 0) - 3; |
| 59 | |
| 60 | // The right justified pattern is (spaces), (sign), inf/nan |
| 61 | // The left justified pattern is (sign), inf/nan, (spaces) |
| 62 | |
| 63 | if (padding > 0 && ((to_conv.flags & FormatFlags::LEFT_JUSTIFIED) != |
| 64 | FormatFlags::LEFT_JUSTIFIED)) |
| 65 | RET_IF_RESULT_NEGATIVE(writer->write(' ', padding)); |
| 66 | |
| 67 | if (sign_char) |
| 68 | RET_IF_RESULT_NEGATIVE(writer->write(sign_char)); |
| 69 | if (mantissa == 0) { // inf |
| 70 | RET_IF_RESULT_NEGATIVE( |
| 71 | writer->write(internal::islower(to_conv.conv_name) ? "inf" : "INF")); |
| 72 | } else { // nan |
| 73 | RET_IF_RESULT_NEGATIVE( |
| 74 | writer->write(internal::islower(to_conv.conv_name) ? "nan" : "NAN")); |
| 75 | } |
| 76 | |
| 77 | if (padding > 0 && ((to_conv.flags & FormatFlags::LEFT_JUSTIFIED) == |
| 78 | FormatFlags::LEFT_JUSTIFIED)) |
| 79 | RET_IF_RESULT_NEGATIVE(writer->write(' ', padding)); |
| 80 | |
| 81 | return WRITE_OK; |
| 82 | } |
| 83 | |
| 84 | } // namespace printf_core |
| 85 | } // namespace LIBC_NAMESPACE_DECL |
| 86 | |
| 87 | #endif // LLVM_LIBC_SRC_STDIO_PRINTF_CORE_FLOAT_INF_NAN_CONVERTER_H |
| 88 |
Warning: This file is not a C or C++ file. It does not have highlighting.
