Refactor ansi_color_escape to track size instead of using a null terminator (#4511)

This commit is contained in:
Victor Chernyakin
2025-08-09 08:08:41 -07:00
committed by GitHub
parent ae8cb1e8e6
commit 8f3a965186

View File

@@ -375,19 +375,17 @@ template <typename Char> struct ansi_color_escape {
// 10 more. // 10 more.
if (is_background) value += 10u; if (is_background) value += 10u;
size_t index = 0; buffer[size++] = static_cast<Char>('\x1b');
buffer[index++] = static_cast<Char>('\x1b'); buffer[size++] = static_cast<Char>('[');
buffer[index++] = static_cast<Char>('[');
if (value >= 100u) { if (value >= 100u) {
buffer[index++] = static_cast<Char>('1'); buffer[size++] = static_cast<Char>('1');
value %= 100u; value %= 100u;
} }
buffer[index++] = static_cast<Char>('0' + value / 10u); buffer[size++] = static_cast<Char>('0' + value / 10u);
buffer[index++] = static_cast<Char>('0' + value % 10u); buffer[size++] = static_cast<Char>('0' + value % 10u);
buffer[index++] = static_cast<Char>('m'); buffer[size++] = static_cast<Char>('m');
buffer[index++] = static_cast<Char>('\0');
return; return;
} }
@@ -398,7 +396,7 @@ template <typename Char> struct ansi_color_escape {
to_esc(color.r, buffer + 7, ';'); to_esc(color.r, buffer + 7, ';');
to_esc(color.g, buffer + 11, ';'); to_esc(color.g, buffer + 11, ';');
to_esc(color.b, buffer + 15, 'm'); to_esc(color.b, buffer + 15, 'm');
buffer[19] = static_cast<Char>(0); size = 19;
} }
FMT_CONSTEXPR ansi_color_escape(emphasis em) noexcept { FMT_CONSTEXPR ansi_color_escape(emphasis em) noexcept {
uint8_t em_codes[num_emphases] = {}; uint8_t em_codes[num_emphases] = {};
@@ -411,26 +409,25 @@ template <typename Char> struct ansi_color_escape {
if (has_emphasis(em, emphasis::conceal)) em_codes[6] = 8; if (has_emphasis(em, emphasis::conceal)) em_codes[6] = 8;
if (has_emphasis(em, emphasis::strikethrough)) em_codes[7] = 9; if (has_emphasis(em, emphasis::strikethrough)) em_codes[7] = 9;
size_t index = 0;
for (size_t i = 0; i < num_emphases; ++i) { for (size_t i = 0; i < num_emphases; ++i) {
if (!em_codes[i]) continue; if (!em_codes[i]) continue;
buffer[index++] = static_cast<Char>('\x1b'); buffer[size++] = static_cast<Char>('\x1b');
buffer[index++] = static_cast<Char>('['); buffer[size++] = static_cast<Char>('[');
buffer[index++] = static_cast<Char>('0' + em_codes[i]); buffer[size++] = static_cast<Char>('0' + em_codes[i]);
buffer[index++] = static_cast<Char>('m'); buffer[size++] = static_cast<Char>('m');
} }
buffer[index++] = static_cast<Char>(0);
} }
FMT_CONSTEXPR operator const Char*() const noexcept { return buffer; } FMT_CONSTEXPR operator const Char*() const noexcept { return buffer; }
FMT_CONSTEXPR auto begin() const noexcept -> const Char* { return buffer; } FMT_CONSTEXPR auto begin() const noexcept -> const Char* { return buffer; }
FMT_CONSTEXPR20 auto end() const noexcept -> const Char* { FMT_CONSTEXPR auto end() const noexcept -> const Char* {
return buffer + basic_string_view<Char>(buffer).size(); return buffer + size;
} }
private: private:
static constexpr size_t num_emphases = 8; static constexpr size_t num_emphases = 8;
Char buffer[7u + 4u * num_emphases + 1u]; Char buffer[7u + 4u * num_emphases];
size_t size = 0;
static FMT_CONSTEXPR void to_esc(uint8_t c, Char* out, static FMT_CONSTEXPR void to_esc(uint8_t c, Char* out,
char delimiter) noexcept { char delimiter) noexcept {