Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prefer FMT_COMPILE for string formatting in VtRenderer #10426

Merged
13 commits merged into from
Jun 22, 2021
54 changes: 54 additions & 0 deletions src/inc/til/format.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

#pragma once

#include <stdint.h>
#include <string>

#ifdef UNIT_TESTING
#endif

namespace til // Terminal Implementation Library. Also: "Today I Learned"
{
namespace format
{
inline char* format_uint8(char* ptr, uint8_t number)
{
if (number >= 100)
{
*ptr++ = static_cast<char>((number / 100) + '0');
}
if (number >= 10)
{
*ptr++ = static_cast<char>(((number / 10) % 10) + '0');
}

*ptr++ = static_cast<char>((number % 10) + '0');
return ptr;
}

inline char* format(char* pDst, const char* pFormat, ...)
skyline75489 marked this conversation as resolved.
Show resolved Hide resolved
{
va_list args;
va_start(args, pFormat);

const char* pSrc = pFormat;
while (*pSrc != '\0')
{
if (*pSrc == '{' && *(pSrc + 1) == '}')
{
pDst = format_uint8(pDst, va_arg(args, uint8_t));
pSrc += 2;
continue;
}

*pDst++ = *pSrc++;
}

va_end(args);

return pDst;
}
}
}
25 changes: 14 additions & 11 deletions src/renderer/vt/VtSequences.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "precomp.h"
#include "vtrenderer.hpp"
#include "../../inc/conattrs.hpp"
#include "til/format.h"

#pragma hdrstop
using namespace Microsoft::Console::Render;
Expand Down Expand Up @@ -234,7 +235,10 @@ using namespace Microsoft::Console::Render;
(WI_IsFlagSet(wAttr, FOREGROUND_GREEN) ? 2 : 0) +
(WI_IsFlagSet(wAttr, FOREGROUND_BLUE) ? 4 : 0);

return _WriteFormattedString(&fmt, vtIndex);
char buf[6];
char* end = til::format::format(buf, "\x1b[{}m", vtIndex);
// An example string with max length would be "\x1b[100m", which has length = 6.
return _Write({ buf, static_cast<std::string_view::size_type>(end - buf) });
}

// Method Description:
Expand All @@ -248,11 +252,10 @@ using namespace Microsoft::Console::Render;
[[nodiscard]] HRESULT VtEngine::_SetGraphicsRendition256Color(const WORD index,
const bool fIsForeground) noexcept
{
const std::string fmt = fIsForeground ?
"\x1b[38;5;%dm" :
"\x1b[48;5;%dm";

return _WriteFormattedString(&fmt, ::Xterm256ToWindowsIndex(index));
char buf[11];
// An example string with max length would be "\x1b[38;5;128m", which has length = 11.
char* end = til::format::format(buf, "\x1b[{};5;{}m", fIsForeground ? 38 : 48, ::Xterm256ToWindowsIndex(index));
return _Write({buf, static_cast<std::string_view::size_type>(end - buf)});
}

// Method Description:
Expand All @@ -266,15 +269,15 @@ using namespace Microsoft::Console::Render;
[[nodiscard]] HRESULT VtEngine::_SetGraphicsRenditionRGBColor(const COLORREF color,
const bool fIsForeground) noexcept
{
const std::string fmt = fIsForeground ?
"\x1b[38;2;%d;%d;%dm" :
"\x1b[48;2;%d;%d;%dm";

DWORD const r = GetRValue(color);
DWORD const g = GetGValue(color);
DWORD const b = GetBValue(color);

return _WriteFormattedString(&fmt, r, g, b);
char buf[19];
char* end = til::format::format(buf, "\x1b[{};2;{};{};{}m", fIsForeground ? 38 : 48, r, g, b);

// An example string with max length would be "\x1b[38;2;128;128;128m", which has length = 19.
return _Write({ buf, static_cast<std::string_view::size_type>(end - buf) });
}

// Method Description:
Expand Down