Put a 1-character unget buffer into cin. This fixes http://llvm.org/bugs/show_bug.cgi?id=15867
git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@181470 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
ecc9742f27
commit
a7f5c1bcd8
@ -55,6 +55,8 @@ private:
|
|||||||
const codecvt<char_type, char, state_type>* __cv_;
|
const codecvt<char_type, char, state_type>* __cv_;
|
||||||
state_type* __st_;
|
state_type* __st_;
|
||||||
int __encoding_;
|
int __encoding_;
|
||||||
|
int_type __last_consumed_;
|
||||||
|
bool __last_consumed_is_next_;
|
||||||
bool __always_noconv_;
|
bool __always_noconv_;
|
||||||
|
|
||||||
__stdinbuf(const __stdinbuf&);
|
__stdinbuf(const __stdinbuf&);
|
||||||
@ -66,7 +68,9 @@ private:
|
|||||||
template <class _CharT>
|
template <class _CharT>
|
||||||
__stdinbuf<_CharT>::__stdinbuf(FILE* __fp, state_type* __st)
|
__stdinbuf<_CharT>::__stdinbuf(FILE* __fp, state_type* __st)
|
||||||
: __file_(__fp),
|
: __file_(__fp),
|
||||||
__st_(__st)
|
__st_(__st),
|
||||||
|
__last_consumed_(traits_type::eof()),
|
||||||
|
__last_consumed_is_next_(false)
|
||||||
{
|
{
|
||||||
imbue(this->getloc());
|
imbue(this->getloc());
|
||||||
}
|
}
|
||||||
@ -100,6 +104,16 @@ template <class _CharT>
|
|||||||
typename __stdinbuf<_CharT>::int_type
|
typename __stdinbuf<_CharT>::int_type
|
||||||
__stdinbuf<_CharT>::__getchar(bool __consume)
|
__stdinbuf<_CharT>::__getchar(bool __consume)
|
||||||
{
|
{
|
||||||
|
if (__last_consumed_is_next_)
|
||||||
|
{
|
||||||
|
int_type __result = __last_consumed_;
|
||||||
|
if (__consume)
|
||||||
|
{
|
||||||
|
__last_consumed_ = traits_type::eof();
|
||||||
|
__last_consumed_is_next_ = false;
|
||||||
|
}
|
||||||
|
return __result;
|
||||||
|
}
|
||||||
char __extbuf[__limit];
|
char __extbuf[__limit];
|
||||||
int __nread = _VSTD::max(1, __encoding_);
|
int __nread = _VSTD::max(1, __encoding_);
|
||||||
for (int __i = 0; __i < __nread; ++__i)
|
for (int __i = 0; __i < __nread; ++__i)
|
||||||
@ -154,6 +168,8 @@ __stdinbuf<_CharT>::__getchar(bool __consume)
|
|||||||
return traits_type::eof();
|
return traits_type::eof();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
__last_consumed_ = traits_type::to_int_type(__1buf);
|
||||||
return traits_type::to_int_type(__1buf);
|
return traits_type::to_int_type(__1buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,10 +178,20 @@ typename __stdinbuf<_CharT>::int_type
|
|||||||
__stdinbuf<_CharT>::pbackfail(int_type __c)
|
__stdinbuf<_CharT>::pbackfail(int_type __c)
|
||||||
{
|
{
|
||||||
if (traits_type::eq_int_type(__c, traits_type::eof()))
|
if (traits_type::eq_int_type(__c, traits_type::eof()))
|
||||||
|
{
|
||||||
|
if (!__last_consumed_is_next_)
|
||||||
|
{
|
||||||
|
__c = __last_consumed_;
|
||||||
|
__last_consumed_is_next_ = !traits_type::eq_int_type(__last_consumed_,
|
||||||
|
traits_type::eof());
|
||||||
|
}
|
||||||
return __c;
|
return __c;
|
||||||
|
}
|
||||||
|
if (__last_consumed_is_next_)
|
||||||
|
{
|
||||||
char __extbuf[__limit];
|
char __extbuf[__limit];
|
||||||
char* __enxt;
|
char* __enxt;
|
||||||
const char_type __ci = traits_type::to_char_type(__c);
|
const char_type __ci = traits_type::to_char_type(__last_consumed_);
|
||||||
const char_type* __inxt;
|
const char_type* __inxt;
|
||||||
switch (__cv_->out(*__st_, &__ci, &__ci + 1, __inxt,
|
switch (__cv_->out(*__st_, &__ci, &__ci + 1, __inxt,
|
||||||
__extbuf, __extbuf + sizeof(__extbuf), __enxt))
|
__extbuf, __extbuf + sizeof(__extbuf), __enxt))
|
||||||
@ -173,7 +199,7 @@ __stdinbuf<_CharT>::pbackfail(int_type __c)
|
|||||||
case _VSTD::codecvt_base::ok:
|
case _VSTD::codecvt_base::ok:
|
||||||
break;
|
break;
|
||||||
case _VSTD::codecvt_base::noconv:
|
case _VSTD::codecvt_base::noconv:
|
||||||
__extbuf[0] = static_cast<char>(__c);
|
__extbuf[0] = static_cast<char>(__last_consumed_);
|
||||||
__enxt = __extbuf + 1;
|
__enxt = __extbuf + 1;
|
||||||
break;
|
break;
|
||||||
case codecvt_base::partial:
|
case codecvt_base::partial:
|
||||||
@ -183,7 +209,10 @@ __stdinbuf<_CharT>::pbackfail(int_type __c)
|
|||||||
while (__enxt > __extbuf)
|
while (__enxt > __extbuf)
|
||||||
if (ungetc(*--__enxt, __file_) == EOF)
|
if (ungetc(*--__enxt, __file_) == EOF)
|
||||||
return traits_type::eof();
|
return traits_type::eof();
|
||||||
return traits_type::not_eof(__c);
|
}
|
||||||
|
__last_consumed_ = __c;
|
||||||
|
__last_consumed_is_next_ = true;
|
||||||
|
return __c;
|
||||||
}
|
}
|
||||||
|
|
||||||
// __stdoutbuf
|
// __stdoutbuf
|
||||||
|
Loading…
x
Reference in New Issue
Block a user