Skip to content

Commit

Permalink
Allow trailing spaces on strings for conversions (#1115)
Browse files Browse the repository at this point in the history
Allow trailing spaces on strings for conversions to floating point and
integers.

There was a potential confusing error that could occur if strings with
trailing spaces were converted to integer or floating point values. This
PR allows trailing spaces in the strings that would otherwise be
convertible to the appropriate numerical type.

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
  • Loading branch information
phlptp and pre-commit-ci[bot] authored Jan 28, 2025
1 parent 10ac3e5 commit 92adf2c
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 1 deletion.
15 changes: 14 additions & 1 deletion include/CLI/TypeTools.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -968,6 +968,9 @@ bool integral_conversion(const std::string &input, T &output) noexcept {
nstring.erase(std::remove(nstring.begin(), nstring.end(), '\''), nstring.end());
return integral_conversion(nstring, output);
}
if(std::isspace(static_cast<unsigned char>(input.back()))) {
return integral_conversion(trim_copy(input), output);
}
if(input.compare(0, 2, "0o") == 0 || input.compare(0, 2, "0O") == 0) {
val = nullptr;
errno = 0;
Expand Down Expand Up @@ -1016,13 +1019,16 @@ bool integral_conversion(const std::string &input, T &output) noexcept {
output = static_cast<T>(1);
return true;
}
// remove separators
// remove separators and trailing spaces
if(input.find_first_of("_'") != std::string::npos) {
std::string nstring = input;
nstring.erase(std::remove(nstring.begin(), nstring.end(), '_'), nstring.end());
nstring.erase(std::remove(nstring.begin(), nstring.end(), '\''), nstring.end());
return integral_conversion(nstring, output);
}
if(std::isspace(static_cast<unsigned char>(input.back()))) {
return integral_conversion(trim_copy(input), output);
}
if(input.compare(0, 2, "0o") == 0 || input.compare(0, 2, "0O") == 0) {
val = nullptr;
errno = 0;
Expand Down Expand Up @@ -1147,6 +1153,13 @@ bool lexical_cast(const std::string &input, T &output) {
if(val == (input.c_str() + input.size())) {
return true;
}
while(std::isspace(static_cast<unsigned char>(*val))) {
++val;
if(val == (input.c_str() + input.size())) {
return true;
}
}

// remove separators
if(input.find_first_of("_'") != std::string::npos) {
std::string nstring = input;
Expand Down
10 changes: 10 additions & 0 deletions tests/OptionTypeTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -227,9 +227,13 @@ TEST_CASE_METHOD(TApp, "atomic_int_option", "[optiontype]") {
static const std::map<std::string, double> testValuesDouble{
{"3.14159", 3.14159},
{"-3.14159", -3.14159},
{"-3.14159\t", -3.14159},
{"-3.14159 ", -3.14159},
{"+1.0", 1.0},
{"-0.01", -0.01},
{"5e22", 5e22},
{" 5e22", 5e22},
{" 5e22 ", 5e22},
{"-2E-2", -2e-2},
{"5e+22", 5e22},
{"1e06", 1e6},
Expand Down Expand Up @@ -268,6 +272,7 @@ static const std::map<std::string, std::int64_t> testValuesInt{
{"+99", 99},
{"99", 99},
{"-99", -99},
{"-99 ", -99},
{"0xDEADBEEF", 0xDEADBEEF},
{"0xdeadbeef", 0xDEADBEEF},
{"0XDEADBEEF", 0xDEADBEEF},
Expand All @@ -280,6 +285,7 @@ static const std::map<std::string, std::int64_t> testValuesInt{
{"995862_262", 995862262},
{"995862262", 995862262},
{"-995862275", -995862275},
{"\t-995862275\t", -995862275},
{"-995'862'275", -995862275},
{"0b11010110", 0xD6},
{"0b1101'0110", 0xD6},
Expand Down Expand Up @@ -323,6 +329,7 @@ TEST_CASE_METHOD(TApp, "intConversionsErange", "[optiontype]") {
static const std::map<std::string, std::uint64_t> testValuesUInt{
{"+99", 99},
{"99", 99},
{" 99 ", 99},
{"0xDEADBEEF", 0xDEADBEEF},
{"0xdeadbeef", 0xDEADBEEF},
{"0XDEADBEEF", 0xDEADBEEF},
Expand All @@ -331,13 +338,16 @@ static const std::map<std::string, std::uint64_t> testValuesUInt{
{"0xdead'beef", 0xDEADBEEF},
{"0o01234567", 001234567},
{"0o755", 0755},
{"0o755\t", 0755},
{"0755", 0755},
{"995862_262", 995862262},
{"995862262", 995862262},
{"+995862275", +995862275},
{"+995862275 \n\t", +995862275},
{"995'862'275", 995862275},
{"0b11010110", 0xD6},
{"0b1101'0110", 0xD6},
{"0b1101'0110 ", 0xD6},
{"0B11010110", 0xD6},
{"0B1101'0110", 0xD6},
{"1_2_3_4_5", 12345},
Expand Down

0 comments on commit 92adf2c

Please sign in to comment.