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
22namespace LIBC_NAMESPACE_DECL {
23namespace printf_core {
24
25using StorageType = fputil::FPBits<long double>::StorageType;
26
27template <WriteMode write_mode>
28LIBC_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.

source code of libc/src/stdio/printf_core/float_inf_nan_converter.h