#ifndef LLVM_LIBC_SRC_STDIO_PRINTF_CORE_INT_CONVERTER_H
#define LLVM_LIBC_SRC_STDIO_PRINTF_CORE_INT_CONVERTER_H
#include "src/__support/integer_to_string.h"
#include "src/stdio/printf_core/converter_utils.h"
#include "src/stdio/printf_core/core_structs.h"
#include "src/stdio/printf_core/writer.h"
#include <inttypes.h>
#include <stddef.h>
namespace __llvm_libc {
namespace printf_core {
int inline convert_int(Writer *writer, const FormatSection &to_conv) {
static constexpr size_t BITS_IN_BYTE = 8;
static constexpr size_t BITS_IN_NUM = sizeof(uintmax_t) * BITS_IN_BYTE;
uintmax_t num = to_conv.conv_val_raw;
bool is_negative = false;
FormatFlags flags = to_conv.flags;
if (to_conv.conv_name == 'u') {
flags = FormatFlags(flags &
~(FormatFlags::FORCE_SIGN | FormatFlags::SPACE_PREFIX));
} else {
if ((num & (uintmax_t(1) << (BITS_IN_NUM - 1))) > 0) {
is_negative = true;
num = -num;
}
}
num = apply_length_modifier(num, to_conv.length_modifier);
auto const int_to_str = integer_to_string(num);
size_t digits_written = int_to_str.str().size();
char sign_char = 0;
if (is_negative)
sign_char = '-';
else if ((flags & FormatFlags::FORCE_SIGN) == FormatFlags::FORCE_SIGN)
sign_char = '+';
else if ((flags & FormatFlags::SPACE_PREFIX) == FormatFlags::SPACE_PREFIX)
sign_char = ' ';
int sign_char_len = (sign_char == 0 ? 0 : 1);
int zeroes;
int spaces;
if (to_conv.precision < 0) {
if ((flags & (FormatFlags::LEADING_ZEROES | FormatFlags::LEFT_JUSTIFIED)) ==
FormatFlags::LEADING_ZEROES) {
zeroes = to_conv.min_width - digits_written - sign_char_len;
if (zeroes < 0)
zeroes = 0;
spaces = 0;
} else {
zeroes = 0;
spaces = to_conv.min_width - digits_written - sign_char_len;
}
} else {
if (num == 0 && to_conv.precision == 0)
digits_written = 0;
zeroes = to_conv.precision - digits_written;
if (zeroes < 0)
zeroes = 0;
spaces = to_conv.min_width - zeroes - digits_written - sign_char_len;
}
if (spaces < 0)
spaces = 0;
if ((flags & FormatFlags::LEFT_JUSTIFIED) == FormatFlags::LEFT_JUSTIFIED) {
if (sign_char != 0)
RET_IF_RESULT_NEGATIVE(writer->write(&sign_char, 1));
if (zeroes > 0)
RET_IF_RESULT_NEGATIVE(writer->write_chars('0', zeroes));
if (digits_written > 0)
RET_IF_RESULT_NEGATIVE(
writer->write(int_to_str.str().data(), digits_written));
if (spaces > 0)
RET_IF_RESULT_NEGATIVE(writer->write_chars(' ', spaces));
} else {
if (spaces > 0)
RET_IF_RESULT_NEGATIVE(writer->write_chars(' ', spaces));
if (sign_char != 0)
RET_IF_RESULT_NEGATIVE(writer->write(&sign_char, 1));
if (zeroes > 0)
RET_IF_RESULT_NEGATIVE(writer->write_chars('0', zeroes));
if (digits_written > 0)
RET_IF_RESULT_NEGATIVE(
writer->write(int_to_str.str().data(), digits_written));
}
return WRITE_OK;
}
}
}
#endif