1//===-- Shared Converter Utilities 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_CONVERTER_UTILS_H
10#define LLVM_LIBC_SRC_STDIO_PRINTF_CORE_CONVERTER_UTILS_H
11
12#include "src/__support/CPP/limits.h"
13#include "src/stdio/printf_core/core_structs.h"
14
15#include <inttypes.h>
16#include <stddef.h>
17
18namespace LIBC_NAMESPACE {
19namespace printf_core {
20
21LIBC_INLINE uintmax_t apply_length_modifier(uintmax_t num,
22 LengthSpec length_spec) {
23 auto [lm, bw] = length_spec;
24 switch (lm) {
25 case LengthModifier::none:
26 return num & cpp::numeric_limits<unsigned int>::max();
27 case LengthModifier::l:
28 return num & cpp::numeric_limits<unsigned long>::max();
29 case LengthModifier::ll:
30 case LengthModifier::L:
31 return num & cpp::numeric_limits<unsigned long long>::max();
32 case LengthModifier::h:
33 return num & cpp::numeric_limits<unsigned short>::max();
34 case LengthModifier::hh:
35 return num & cpp::numeric_limits<unsigned char>::max();
36 case LengthModifier::z:
37 return num & cpp::numeric_limits<size_t>::max();
38 case LengthModifier::t:
39 // We don't have unsigned ptrdiff so uintptr_t is used, since we need an
40 // unsigned type and ptrdiff is usually the same size as a pointer.
41 static_assert(sizeof(ptrdiff_t) == sizeof(uintptr_t));
42 return num & cpp::numeric_limits<uintptr_t>::max();
43 case LengthModifier::j:
44 return num; // j is intmax, so no mask is necessary.
45 case LengthModifier::w:
46 case LengthModifier::wf: {
47 uintmax_t mask;
48 if (bw == 0) {
49 mask = 0;
50 } else if (bw < sizeof(uintmax_t) * CHAR_BIT) {
51 mask = (static_cast<uintmax_t>(1) << bw) - 1;
52 } else {
53 mask = UINTMAX_MAX;
54 }
55 return num & mask;
56 }
57 }
58 __builtin_unreachable();
59}
60
61#define RET_IF_RESULT_NEGATIVE(func) \
62 { \
63 int result = (func); \
64 if (result < 0) \
65 return result; \
66 }
67
68// This is used to represent which direction the number should be rounded.
69enum class RoundDirection { Up, Down, Even };
70
71} // namespace printf_core
72} // namespace LIBC_NAMESPACE
73
74#endif // LLVM_LIBC_SRC_STDIO_PRINTF_CORE_CONVERTER_UTILS_H
75

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