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

New tokenization & integer parsing helpers #17962

Merged
merged 6 commits into from
Oct 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions src/cascadia/TerminalApp/Jumplist.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -162,10 +162,9 @@ winrt::com_ptr<IShellLinkW> Jumplist::_createShellLink(const std::wstring_view n
const std::wstring iconPath{ path.substr(0, commaPosition) };

// We dont want the comma included so add 1 to its position
int iconIndex = til::to_int(path.substr(commaPosition + 1));
if (iconIndex != til::to_int_error)
if (const auto iconIndex = til::parse_signed<int>(path.substr(commaPosition + 1)))
{
THROW_IF_FAILED(sh->SetIconLocation(iconPath.data(), iconIndex));
THROW_IF_FAILED(sh->SetIconLocation(iconPath.data(), *iconIndex));
}
}
else if (til::ends_with(path, L"exe") || til::ends_with(path, L"dll"))
Expand Down
10 changes: 4 additions & 6 deletions src/cascadia/TerminalSettingsModel/KeyChordSerialization.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,10 +101,10 @@ static int32_t parseNumericCode(const std::wstring_view& str, const std::wstring
return 0;
}

const auto value = til::to_ulong({ str.data() + prefix.size(), str.size() - prefix.size() - suffix.size() });
if (value > 0 && value < 256)
const auto value = til::parse_unsigned<uint8_t>({ str.data() + prefix.size(), str.size() - prefix.size() - suffix.size() });
if (value)
{
return gsl::narrow_cast<int32_t>(value);
return gsl::narrow_cast<int32_t>(*value);
}

throw winrt::hresult_invalid_argument(L"Invalid numeric argument to vk() or sc()");
Expand Down Expand Up @@ -151,10 +151,8 @@ static KeyChord _fromString(std::wstring_view wstr)
auto vkey = 0;
auto scanCode = 0;

while (!wstr.empty())
for (const auto& part : til::split_iterator{ wstr, L'+' })
{
const auto part = til::prefix_split(wstr, L'+');

if (til::equals_insensitive_ascii(part, CTRL_KEY))
{
modifiers |= VirtualKeyModifiers::Control;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -719,8 +719,8 @@ struct ::Microsoft::Terminal::Settings::Model::JsonUtils::ConversionTrait<::winr
if (isIndexed16)
{
const auto indexStr = string.substr(1);
const auto idx = til::to_ulong(indexStr, 16);
color.r = gsl::narrow_cast<uint8_t>(std::min(idx, 15ul));
const auto idx = til::parse_unsigned<uint8_t>(indexStr, 16);
color.r = std::min<uint8_t>(idx.value_or(255), 15);
}
else
{
Expand Down
35 changes: 16 additions & 19 deletions src/cascadia/UIHelpers/Converters.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,35 +73,32 @@ namespace winrt::Microsoft::Terminal::UI::implementation

double Converters::MaxValueFromPaddingString(const winrt::hstring& paddingString)
{
std::wstring_view remaining{ paddingString };
std::wstring buffer;
double maxVal = 0;

auto& errnoRef = errno; // Nonzero cost, pay it once

// Get padding values till we run out of delimiter separated values in the stream
// Non-numeral values detected will default to 0
// std::stod will throw invalid_argument exception if the input is an invalid double value
// std::stod will throw out_of_range exception if the input value is more than DBL_MAX
try
for (const auto& part : til::split_iterator{ std::wstring_view{ paddingString }, L',' })
{
while (!remaining.empty())
buffer.assign(part);

// wcstod handles whitespace prefix (which is ignored) & stops the
// scan when first char outside the range of radix is encountered.
// We'll be permissive till the extent that stod function allows us to be by default
// Ex. a value like 100.3#535w2 will be read as 100.3, but ;df25 will fail
errnoRef = 0;
wchar_t* end;
const double val = wcstod(buffer.c_str(), &end);

if (end != buffer.c_str() && errnoRef != ERANGE)
{
const std::wstring token{ til::prefix_split(remaining, L',') };
// std::stod internally calls wcstod which handles whitespace prefix (which is ignored)
// & stops the scan when first char outside the range of radix is encountered
// We'll be permissive till the extent that stod function allows us to be by default
// Ex. a value like 100.3#535w2 will be read as 100.3, but ;df25 will fail
const auto curVal = std::stod(token);
if (curVal > maxVal)
{
maxVal = curVal;
}
maxVal = std::max(maxVal, val);
}
}
catch (...)
{
// If something goes wrong, even if due to a single bad padding value, we'll return default 0 padding
maxVal = 0;
LOG_CAUGHT_EXCEPTION();
}

return maxVal;
}
Expand Down
7 changes: 1 addition & 6 deletions src/cascadia/UIHelpers/IconPathConverter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -271,12 +271,7 @@ namespace winrt::Microsoft::Terminal::UI::implementation
if (commaIndex != std::wstring::npos)
{
// Convert the string iconIndex to a signed int to support negative numbers which represent an Icon's ID.
const auto index{ til::to_int(pathView.substr(commaIndex + 1)) };
if (index == til::to_int_error)
{
return std::nullopt;
}
return static_cast<int>(index);
return til::parse_signed<int>(pathView.substr(commaIndex + 1));
}

// We had a binary path, but no index. Default to 0.
Expand Down
12 changes: 11 additions & 1 deletion src/common.build.pre.props
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,17 @@
<RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData>
<LanguageStandard>stdcpp20</LanguageStandard>
<LanguageStandard_C>stdc17</LanguageStandard_C>
<AdditionalOptions>%(AdditionalOptions) /utf-8 /Zc:__cplusplus /Zc:__STDC__ /Zc:enumTypes /Zc:externConstexpr /Zc:templateScope /Zc:throwingNew</AdditionalOptions>
<!--
Conformance options that are off by default at the time of writing:
/Zc:__cplusplus Enable the __cplusplus macro to report the supported standard.
/Zc:__STDC__ Enable the __STDC__ macro to report the C standard is supported.
/Zc:enumTypes Enable Standard C++ rules for enum type deduction.
/Zc:inline Remove unreferenced functions or data if they're COMDAT or have internal linkage only.
/Zc:templateScope Enforce Standard C++ template parameter shadowing rules.
/Zc:throwingNew Assume operator new throws on failure.
/diagnostics:caret Places ^^^^^ under the exact location of the issue. The default only shows the line number.
-->
<AdditionalOptions>%(AdditionalOptions) /utf-8 /Zc:__cplusplus /Zc:__STDC__ /Zc:enumTypes /Zc:inline /Zc:templateScope /Zc:throwingNew /diagnostics:caret</AdditionalOptions>
<ControlFlowGuard>Guard</ControlFlowGuard>
</ClCompile>
<ResourceCompile>
Expand Down
Loading
Loading