Skip to content

Commit f47a907

Browse files
committed
fix numeric prefix parsing
Emulate stol/stod-style handling for hexadecimal and octal constants when using from_chars. Fixes #23
1 parent 87c5a18 commit f47a907

1 file changed

Lines changed: 32 additions & 2 deletions

File tree

expr2/exprfilter.cpp

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,13 @@
4848

4949
#include <boost/charconv.hpp>
5050
using boost::charconv::from_chars;
51+
using boost::charconv::chars_format;
5152

5253
#else
5354

5455
#include <charconv>
5556
using std::from_chars;
57+
using std::chars_format;
5658

5759
#endif
5860

@@ -377,9 +379,26 @@ ExprOp decodeToken(const std::string &token, bool extended = false)
377379
float f = 0;
378380
const size_t len = token.size();
379381

380-
auto resultl = from_chars(token.c_str(), token.c_str() + len, l, 0);
382+
// Emulate stol/stod prefix handling
383+
int base = 10;
384+
size_t prefix = 0;
385+
const char* first = token.c_str();
386+
const char* last = token.c_str() + len;
387+
if (len > 2 && first[0] == '0' && (first[1] == 'x' || first[1] == 'X')) {
388+
base = 16;
389+
prefix = 2;
390+
first += prefix;
391+
} else if (len > 1 && first[0] == '0') {
392+
base = 8;
393+
prefix = 1;
394+
first += prefix;
395+
}
396+
397+
auto resultl = from_chars(first, last, l, base);
381398
if (resultl.ec == std::errc()) {
382399
pos = std::distance(token.c_str(), resultl.ptr);
400+
} else {
401+
pos = prefix;
383402
}
384403

385404
if (pos == len) {
@@ -388,9 +407,20 @@ ExprOp decodeToken(const std::string &token, bool extended = false)
388407
return { ExprOpType::CONSTANTF, (float)l };
389408
}
390409

391-
auto resultf = from_chars(token.c_str(), token.c_str() + len, f);
410+
auto fmt = chars_format::general;
411+
first = token.c_str();
412+
prefix = 0;
413+
if (len > 2 && first[0] == '0' && (first[1] == 'x' || first[1] == 'X')) {
414+
fmt = chars_format::hex;
415+
prefix = 2;
416+
first += prefix;
417+
}
418+
419+
auto resultf = from_chars(first, last, f, fmt);
392420
if (resultf.ec == std::errc()) {
393421
pos = std::distance(token.c_str(), resultf.ptr);
422+
} else {
423+
pos = std::max(pos, prefix);
394424
}
395425

396426
if (pos == len)

0 commit comments

Comments
 (0)