Skip to content

Commit c2ff701

Browse files
committed
[libc++] Fix num_get base parsing
1 parent 2697c8c commit c2ff701

File tree

2 files changed

+98
-0
lines changed
  • libcxx
    • include/__locale_dir
    • test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members

2 files changed

+98
-0
lines changed

libcxx/include/__locale_dir/num.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,7 @@ class num_get : public locale::facet, private __num_get<_CharT> {
436436
++__first;
437437
if (__first == __last) {
438438
__err |= ios_base::eofbit;
439+
__v = 0;
439440
return __first;
440441
}
441442
// __c2 == 'x' || __c2 == 'X'
@@ -444,6 +445,7 @@ class num_get : public locale::facet, private __num_get<_CharT> {
444445
++__first;
445446
} else {
446447
__base = 8;
448+
__parsed_num = true; // We only swallowed '0', so we've started to parse a number
447449
}
448450
} else {
449451
__base = 10;

libcxx/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_long.pass.cpp

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -670,5 +670,101 @@ int main(int, char**)
670670
assert(v == std::numeric_limits<long>::min());
671671
}
672672

673+
{ // Check that auto-detection of the base works properly
674+
ios.flags(ios.flags() & ~std::ios::basefield);
675+
{ // zeroes
676+
{
677+
v = -1;
678+
const char str[] = "0";
679+
std::ios_base::iostate err = ios.goodbit;
680+
681+
cpp17_input_iterator<const char*> iter =
682+
f.get(cpp17_input_iterator<const char*>(str), cpp17_input_iterator<const char*>(str + 1), ios, err, v);
683+
assert(base(iter) == str + 1);
684+
assert(err == ios.eofbit);
685+
assert(v == 0);
686+
}
687+
{
688+
v = -1;
689+
const char str[] = "00";
690+
std::ios_base::iostate err = ios.goodbit;
691+
692+
cpp17_input_iterator<const char*> iter =
693+
f.get(cpp17_input_iterator<const char*>(str), cpp17_input_iterator<const char*>(str + 2), ios, err, v);
694+
assert(base(iter) == str + 2);
695+
assert(err == ios.eofbit);
696+
assert(v == 0);
697+
}
698+
{
699+
v = -1;
700+
const char str[] = "0x0";
701+
std::ios_base::iostate err = ios.goodbit;
702+
703+
cpp17_input_iterator<const char*> iter =
704+
f.get(cpp17_input_iterator<const char*>(str), cpp17_input_iterator<const char*>(str + 3), ios, err, v);
705+
assert(base(iter) == str + 3);
706+
assert(err == ios.eofbit);
707+
assert(v == 0);
708+
}
709+
{
710+
v = -1;
711+
const char str[] = "0X0";
712+
std::ios_base::iostate err = ios.goodbit;
713+
714+
cpp17_input_iterator<const char*> iter =
715+
f.get(cpp17_input_iterator<const char*>(str), cpp17_input_iterator<const char*>(str + 3), ios, err, v);
716+
assert(base(iter) == str + 3);
717+
assert(err == ios.eofbit);
718+
assert(v == 0);
719+
}
720+
}
721+
{ // first character after base is out of range
722+
{
723+
v = -1;
724+
const char str[] = "08";
725+
std::ios_base::iostate err = ios.goodbit;
726+
727+
cpp17_input_iterator<const char*> iter =
728+
f.get(cpp17_input_iterator<const char*>(str), cpp17_input_iterator<const char*>(str + 2), ios, err, v);
729+
assert(base(iter) == str + 1);
730+
assert(err == ios.goodbit);
731+
assert(v == 0);
732+
}
733+
{
734+
v = -1;
735+
const char str[] = "1a";
736+
std::ios_base::iostate err = ios.goodbit;
737+
738+
cpp17_input_iterator<const char*> iter =
739+
f.get(cpp17_input_iterator<const char*>(str), cpp17_input_iterator<const char*>(str + 2), ios, err, v);
740+
assert(base(iter) == str + 1);
741+
assert(err == ios.goodbit);
742+
assert(v == 1);
743+
}
744+
{
745+
v = -1;
746+
const char str[] = "0xg";
747+
std::ios_base::iostate err = ios.goodbit;
748+
749+
cpp17_input_iterator<const char*> iter =
750+
f.get(cpp17_input_iterator<const char*>(str), cpp17_input_iterator<const char*>(str + 3), ios, err, v);
751+
assert(base(iter) == str + 2);
752+
assert(err == ios.failbit);
753+
assert(v == 0);
754+
}
755+
{
756+
v = -1;
757+
const char str[] = "0Xg";
758+
std::ios_base::iostate err = ios.goodbit;
759+
760+
cpp17_input_iterator<const char*> iter =
761+
f.get(cpp17_input_iterator<const char*>(str), cpp17_input_iterator<const char*>(str + 3), ios, err, v);
762+
assert(base(iter) == str + 2);
763+
assert(err == ios.failbit);
764+
assert(v == 0);
765+
}
766+
}
767+
}
768+
673769
return 0;
674770
}

0 commit comments

Comments
 (0)