1*e4b17023SJohn Marino // Input streams -*- C++ -*-
2*e4b17023SJohn Marino 
3*e4b17023SJohn Marino // Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009
4*e4b17023SJohn Marino // Free Software Foundation, Inc.
5*e4b17023SJohn Marino //
6*e4b17023SJohn Marino // This file is part of the GNU ISO C++ Library.  This library is free
7*e4b17023SJohn Marino // software; you can redistribute it and/or modify it under the
8*e4b17023SJohn Marino // terms of the GNU General Public License as published by the
9*e4b17023SJohn Marino // Free Software Foundation; either version 3, or (at your option)
10*e4b17023SJohn Marino // any later version.
11*e4b17023SJohn Marino 
12*e4b17023SJohn Marino // This library is distributed in the hope that it will be useful,
13*e4b17023SJohn Marino // but WITHOUT ANY WARRANTY; without even the implied warranty of
14*e4b17023SJohn Marino // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15*e4b17023SJohn Marino // GNU General Public License for more details.
16*e4b17023SJohn Marino 
17*e4b17023SJohn Marino // Under Section 7 of GPL version 3, you are granted additional
18*e4b17023SJohn Marino // permissions described in the GCC Runtime Library Exception, version
19*e4b17023SJohn Marino // 3.1, as published by the Free Software Foundation.
20*e4b17023SJohn Marino 
21*e4b17023SJohn Marino // You should have received a copy of the GNU General Public License and
22*e4b17023SJohn Marino // a copy of the GCC Runtime Library Exception along with this program;
23*e4b17023SJohn Marino // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
24*e4b17023SJohn Marino // <http://www.gnu.org/licenses/>.
25*e4b17023SJohn Marino 
26*e4b17023SJohn Marino //
27*e4b17023SJohn Marino // ISO C++ 14882: 27.6.1  Input streams
28*e4b17023SJohn Marino //
29*e4b17023SJohn Marino 
30*e4b17023SJohn Marino #include <istream>
31*e4b17023SJohn Marino 
32*e4b17023SJohn Marino namespace std _GLIBCXX_VISIBILITY(default)
33*e4b17023SJohn Marino {
34*e4b17023SJohn Marino _GLIBCXX_BEGIN_NAMESPACE_VERSION
35*e4b17023SJohn Marino 
36*e4b17023SJohn Marino   template<>
37*e4b17023SJohn Marino     basic_istream<char>&
38*e4b17023SJohn Marino     basic_istream<char>::
getline(char_type * __s,streamsize __n,char_type __delim)39*e4b17023SJohn Marino     getline(char_type* __s, streamsize __n, char_type __delim)
40*e4b17023SJohn Marino     {
41*e4b17023SJohn Marino       _M_gcount = 0;
42*e4b17023SJohn Marino       ios_base::iostate __err = ios_base::goodbit;
43*e4b17023SJohn Marino       sentry __cerb(*this, true);
44*e4b17023SJohn Marino       if (__cerb)
45*e4b17023SJohn Marino 	{
46*e4b17023SJohn Marino           __try
47*e4b17023SJohn Marino 	    {
48*e4b17023SJohn Marino 	      const int_type __idelim = traits_type::to_int_type(__delim);
49*e4b17023SJohn Marino 	      const int_type __eof = traits_type::eof();
50*e4b17023SJohn Marino 	      __streambuf_type* __sb = this->rdbuf();
51*e4b17023SJohn Marino 	      int_type __c = __sb->sgetc();
52*e4b17023SJohn Marino 
53*e4b17023SJohn Marino 	      while (_M_gcount + 1 < __n
54*e4b17023SJohn Marino 		     && !traits_type::eq_int_type(__c, __eof)
55*e4b17023SJohn Marino 		     && !traits_type::eq_int_type(__c, __idelim))
56*e4b17023SJohn Marino 		{
57*e4b17023SJohn Marino 		  streamsize __size = std::min(streamsize(__sb->egptr()
58*e4b17023SJohn Marino 							  - __sb->gptr()),
59*e4b17023SJohn Marino 					       streamsize(__n - _M_gcount
60*e4b17023SJohn Marino 							  - 1));
61*e4b17023SJohn Marino 		  if (__size > 1)
62*e4b17023SJohn Marino 		    {
63*e4b17023SJohn Marino 		      const char_type* __p = traits_type::find(__sb->gptr(),
64*e4b17023SJohn Marino 							       __size,
65*e4b17023SJohn Marino 							       __delim);
66*e4b17023SJohn Marino 		      if (__p)
67*e4b17023SJohn Marino 			__size = __p - __sb->gptr();
68*e4b17023SJohn Marino 		      traits_type::copy(__s, __sb->gptr(), __size);
69*e4b17023SJohn Marino 		      __s += __size;
70*e4b17023SJohn Marino 		      __sb->__safe_gbump(__size);
71*e4b17023SJohn Marino 		      _M_gcount += __size;
72*e4b17023SJohn Marino 		      __c = __sb->sgetc();
73*e4b17023SJohn Marino 		    }
74*e4b17023SJohn Marino 		  else
75*e4b17023SJohn Marino 		    {
76*e4b17023SJohn Marino 		      *__s++ = traits_type::to_char_type(__c);
77*e4b17023SJohn Marino 		      ++_M_gcount;
78*e4b17023SJohn Marino 		      __c = __sb->snextc();
79*e4b17023SJohn Marino 		    }
80*e4b17023SJohn Marino 		}
81*e4b17023SJohn Marino 
82*e4b17023SJohn Marino 	      if (traits_type::eq_int_type(__c, __eof))
83*e4b17023SJohn Marino 		__err |= ios_base::eofbit;
84*e4b17023SJohn Marino 	      else if (traits_type::eq_int_type(__c, __idelim))
85*e4b17023SJohn Marino 		{
86*e4b17023SJohn Marino 		  ++_M_gcount;
87*e4b17023SJohn Marino 		  __sb->sbumpc();
88*e4b17023SJohn Marino 		}
89*e4b17023SJohn Marino 	      else
90*e4b17023SJohn Marino 		__err |= ios_base::failbit;
91*e4b17023SJohn Marino 	    }
92*e4b17023SJohn Marino 	  __catch(__cxxabiv1::__forced_unwind&)
93*e4b17023SJohn Marino 	    {
94*e4b17023SJohn Marino 	      this->_M_setstate(ios_base::badbit);
95*e4b17023SJohn Marino 	      __throw_exception_again;
96*e4b17023SJohn Marino 	    }
97*e4b17023SJohn Marino 	  __catch(...)
98*e4b17023SJohn Marino 	    { this->_M_setstate(ios_base::badbit); }
99*e4b17023SJohn Marino 	}
100*e4b17023SJohn Marino       // _GLIBCXX_RESOLVE_LIB_DEFECTS
101*e4b17023SJohn Marino       // 243. get and getline when sentry reports failure.
102*e4b17023SJohn Marino       if (__n > 0)
103*e4b17023SJohn Marino 	*__s = char_type();
104*e4b17023SJohn Marino       if (!_M_gcount)
105*e4b17023SJohn Marino 	__err |= ios_base::failbit;
106*e4b17023SJohn Marino       if (__err)
107*e4b17023SJohn Marino 	this->setstate(__err);
108*e4b17023SJohn Marino       return *this;
109*e4b17023SJohn Marino     }
110*e4b17023SJohn Marino 
111*e4b17023SJohn Marino   template<>
112*e4b17023SJohn Marino     basic_istream<char>&
113*e4b17023SJohn Marino     basic_istream<char>::
ignore(streamsize __n,int_type __delim)114*e4b17023SJohn Marino     ignore(streamsize __n, int_type __delim)
115*e4b17023SJohn Marino     {
116*e4b17023SJohn Marino       if (traits_type::eq_int_type(__delim, traits_type::eof()))
117*e4b17023SJohn Marino 	return ignore(__n);
118*e4b17023SJohn Marino 
119*e4b17023SJohn Marino       _M_gcount = 0;
120*e4b17023SJohn Marino       sentry __cerb(*this, true);
121*e4b17023SJohn Marino       if (__n > 0 && __cerb)
122*e4b17023SJohn Marino 	{
123*e4b17023SJohn Marino 	  ios_base::iostate __err = ios_base::goodbit;
124*e4b17023SJohn Marino 	  __try
125*e4b17023SJohn Marino 	    {
126*e4b17023SJohn Marino 	      const char_type __cdelim = traits_type::to_char_type(__delim);
127*e4b17023SJohn Marino 	      const int_type __eof = traits_type::eof();
128*e4b17023SJohn Marino 	      __streambuf_type* __sb = this->rdbuf();
129*e4b17023SJohn Marino 	      int_type __c = __sb->sgetc();
130*e4b17023SJohn Marino 
131*e4b17023SJohn Marino 	      bool __large_ignore = false;
132*e4b17023SJohn Marino 	      while (true)
133*e4b17023SJohn Marino 		{
134*e4b17023SJohn Marino 		  while (_M_gcount < __n
135*e4b17023SJohn Marino 			 && !traits_type::eq_int_type(__c, __eof)
136*e4b17023SJohn Marino 			 && !traits_type::eq_int_type(__c, __delim))
137*e4b17023SJohn Marino 		    {
138*e4b17023SJohn Marino 		      streamsize __size = std::min(streamsize(__sb->egptr()
139*e4b17023SJohn Marino 							      - __sb->gptr()),
140*e4b17023SJohn Marino 						   streamsize(__n - _M_gcount));
141*e4b17023SJohn Marino 		      if (__size > 1)
142*e4b17023SJohn Marino 			{
143*e4b17023SJohn Marino 			  const char_type* __p = traits_type::find(__sb->gptr(),
144*e4b17023SJohn Marino 								   __size,
145*e4b17023SJohn Marino 								   __cdelim);
146*e4b17023SJohn Marino 			  if (__p)
147*e4b17023SJohn Marino 			    __size = __p - __sb->gptr();
148*e4b17023SJohn Marino 			  __sb->__safe_gbump(__size);
149*e4b17023SJohn Marino 			  _M_gcount += __size;
150*e4b17023SJohn Marino 			  __c = __sb->sgetc();
151*e4b17023SJohn Marino 			}
152*e4b17023SJohn Marino 		      else
153*e4b17023SJohn Marino 			{
154*e4b17023SJohn Marino 			  ++_M_gcount;
155*e4b17023SJohn Marino 			  __c = __sb->snextc();
156*e4b17023SJohn Marino 			}
157*e4b17023SJohn Marino 		    }
158*e4b17023SJohn Marino 		  if (__n == __gnu_cxx::__numeric_traits<streamsize>::__max
159*e4b17023SJohn Marino 		      && !traits_type::eq_int_type(__c, __eof)
160*e4b17023SJohn Marino 		      && !traits_type::eq_int_type(__c, __delim))
161*e4b17023SJohn Marino 		    {
162*e4b17023SJohn Marino 		      _M_gcount =
163*e4b17023SJohn Marino 			__gnu_cxx::__numeric_traits<streamsize>::__min;
164*e4b17023SJohn Marino 		      __large_ignore = true;
165*e4b17023SJohn Marino 		    }
166*e4b17023SJohn Marino 		  else
167*e4b17023SJohn Marino 		    break;
168*e4b17023SJohn Marino 		}
169*e4b17023SJohn Marino 
170*e4b17023SJohn Marino 	      if (__large_ignore)
171*e4b17023SJohn Marino 		_M_gcount = __gnu_cxx::__numeric_traits<streamsize>::__max;
172*e4b17023SJohn Marino 
173*e4b17023SJohn Marino 	      if (traits_type::eq_int_type(__c, __eof))
174*e4b17023SJohn Marino 		__err |= ios_base::eofbit;
175*e4b17023SJohn Marino 	      else if (traits_type::eq_int_type(__c, __delim))
176*e4b17023SJohn Marino 		{
177*e4b17023SJohn Marino 		  if (_M_gcount
178*e4b17023SJohn Marino 		      < __gnu_cxx::__numeric_traits<streamsize>::__max)
179*e4b17023SJohn Marino 		    ++_M_gcount;
180*e4b17023SJohn Marino 		  __sb->sbumpc();
181*e4b17023SJohn Marino 		}
182*e4b17023SJohn Marino 	    }
183*e4b17023SJohn Marino 	  __catch(__cxxabiv1::__forced_unwind&)
184*e4b17023SJohn Marino 	    {
185*e4b17023SJohn Marino 	      this->_M_setstate(ios_base::badbit);
186*e4b17023SJohn Marino 	      __throw_exception_again;
187*e4b17023SJohn Marino 	    }
188*e4b17023SJohn Marino 	  __catch(...)
189*e4b17023SJohn Marino 	    { this->_M_setstate(ios_base::badbit); }
190*e4b17023SJohn Marino 	  if (__err)
191*e4b17023SJohn Marino 	    this->setstate(__err);
192*e4b17023SJohn Marino 	}
193*e4b17023SJohn Marino       return *this;
194*e4b17023SJohn Marino     }
195*e4b17023SJohn Marino 
196*e4b17023SJohn Marino   template<>
197*e4b17023SJohn Marino     basic_istream<char>&
operator >>(basic_istream<char> & __in,char * __s)198*e4b17023SJohn Marino     operator>>(basic_istream<char>& __in, char* __s)
199*e4b17023SJohn Marino     {
200*e4b17023SJohn Marino       typedef basic_istream<char>       	__istream_type;
201*e4b17023SJohn Marino       typedef __istream_type::int_type		__int_type;
202*e4b17023SJohn Marino       typedef __istream_type::char_type		__char_type;
203*e4b17023SJohn Marino       typedef __istream_type::traits_type	__traits_type;
204*e4b17023SJohn Marino       typedef __istream_type::__streambuf_type  __streambuf_type;
205*e4b17023SJohn Marino       typedef __istream_type::__ctype_type	__ctype_type;
206*e4b17023SJohn Marino 
207*e4b17023SJohn Marino       streamsize __extracted = 0;
208*e4b17023SJohn Marino       ios_base::iostate __err = ios_base::goodbit;
209*e4b17023SJohn Marino       __istream_type::sentry __cerb(__in, false);
210*e4b17023SJohn Marino       if (__cerb)
211*e4b17023SJohn Marino 	{
212*e4b17023SJohn Marino 	  __try
213*e4b17023SJohn Marino 	    {
214*e4b17023SJohn Marino 	      // Figure out how many characters to extract.
215*e4b17023SJohn Marino 	      streamsize __num = __in.width();
216*e4b17023SJohn Marino 	      if (__num <= 0)
217*e4b17023SJohn Marino 		__num = __gnu_cxx::__numeric_traits<streamsize>::__max;
218*e4b17023SJohn Marino 
219*e4b17023SJohn Marino 	      const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc());
220*e4b17023SJohn Marino 
221*e4b17023SJohn Marino 	      const __int_type __eof = __traits_type::eof();
222*e4b17023SJohn Marino 	      __streambuf_type* __sb = __in.rdbuf();
223*e4b17023SJohn Marino 	      __int_type __c = __sb->sgetc();
224*e4b17023SJohn Marino 
225*e4b17023SJohn Marino 	      while (__extracted < __num - 1
226*e4b17023SJohn Marino 		     && !__traits_type::eq_int_type(__c, __eof)
227*e4b17023SJohn Marino 		     && !__ct.is(ctype_base::space,
228*e4b17023SJohn Marino 				 __traits_type::to_char_type(__c)))
229*e4b17023SJohn Marino 		{
230*e4b17023SJohn Marino 		  streamsize __size = std::min(streamsize(__sb->egptr()
231*e4b17023SJohn Marino 							  - __sb->gptr()),
232*e4b17023SJohn Marino 					       streamsize(__num - __extracted
233*e4b17023SJohn Marino 							  - 1));
234*e4b17023SJohn Marino 		  if (__size > 1)
235*e4b17023SJohn Marino 		    {
236*e4b17023SJohn Marino 		      __size = (__ct.scan_is(ctype_base::space,
237*e4b17023SJohn Marino 					     __sb->gptr() + 1,
238*e4b17023SJohn Marino 					     __sb->gptr() + __size)
239*e4b17023SJohn Marino 				- __sb->gptr());
240*e4b17023SJohn Marino 		      __traits_type::copy(__s, __sb->gptr(), __size);
241*e4b17023SJohn Marino 		      __s += __size;
242*e4b17023SJohn Marino 		      __sb->__safe_gbump(__size);
243*e4b17023SJohn Marino 		      __extracted += __size;
244*e4b17023SJohn Marino 		      __c = __sb->sgetc();
245*e4b17023SJohn Marino 		    }
246*e4b17023SJohn Marino 		  else
247*e4b17023SJohn Marino 		    {
248*e4b17023SJohn Marino 		      *__s++ = __traits_type::to_char_type(__c);
249*e4b17023SJohn Marino 		      ++__extracted;
250*e4b17023SJohn Marino 		      __c = __sb->snextc();
251*e4b17023SJohn Marino 		    }
252*e4b17023SJohn Marino 		}
253*e4b17023SJohn Marino 
254*e4b17023SJohn Marino 	      if (__traits_type::eq_int_type(__c, __eof))
255*e4b17023SJohn Marino 		__err |= ios_base::eofbit;
256*e4b17023SJohn Marino 
257*e4b17023SJohn Marino 	      // _GLIBCXX_RESOLVE_LIB_DEFECTS
258*e4b17023SJohn Marino 	      // 68.  Extractors for char* should store null at end
259*e4b17023SJohn Marino 	      *__s = __char_type();
260*e4b17023SJohn Marino 	      __in.width(0);
261*e4b17023SJohn Marino 	    }
262*e4b17023SJohn Marino 	  __catch(__cxxabiv1::__forced_unwind&)
263*e4b17023SJohn Marino 	    {
264*e4b17023SJohn Marino 	      __in._M_setstate(ios_base::badbit);
265*e4b17023SJohn Marino 	      __throw_exception_again;
266*e4b17023SJohn Marino 	    }
267*e4b17023SJohn Marino 	  __catch(...)
268*e4b17023SJohn Marino 	    { __in._M_setstate(ios_base::badbit); }
269*e4b17023SJohn Marino 	}
270*e4b17023SJohn Marino       if (!__extracted)
271*e4b17023SJohn Marino 	__err |= ios_base::failbit;
272*e4b17023SJohn Marino       if (__err)
273*e4b17023SJohn Marino 	__in.setstate(__err);
274*e4b17023SJohn Marino       return __in;
275*e4b17023SJohn Marino     }
276*e4b17023SJohn Marino 
277*e4b17023SJohn Marino   template<>
278*e4b17023SJohn Marino     basic_istream<char>&
operator >>(basic_istream<char> & __in,basic_string<char> & __str)279*e4b17023SJohn Marino     operator>>(basic_istream<char>& __in, basic_string<char>& __str)
280*e4b17023SJohn Marino     {
281*e4b17023SJohn Marino       typedef basic_istream<char>       	__istream_type;
282*e4b17023SJohn Marino       typedef __istream_type::int_type		__int_type;
283*e4b17023SJohn Marino       typedef __istream_type::traits_type	__traits_type;
284*e4b17023SJohn Marino       typedef __istream_type::__streambuf_type  __streambuf_type;
285*e4b17023SJohn Marino       typedef __istream_type::__ctype_type	__ctype_type;
286*e4b17023SJohn Marino       typedef basic_string<char>        	__string_type;
287*e4b17023SJohn Marino       typedef __string_type::size_type		__size_type;
288*e4b17023SJohn Marino 
289*e4b17023SJohn Marino       __size_type __extracted = 0;
290*e4b17023SJohn Marino       ios_base::iostate __err = ios_base::goodbit;
291*e4b17023SJohn Marino       __istream_type::sentry __cerb(__in, false);
292*e4b17023SJohn Marino       if (__cerb)
293*e4b17023SJohn Marino 	{
294*e4b17023SJohn Marino 	  __try
295*e4b17023SJohn Marino 	    {
296*e4b17023SJohn Marino 	      __str.erase();
297*e4b17023SJohn Marino 	      const streamsize __w = __in.width();
298*e4b17023SJohn Marino 	      const __size_type __n = __w > 0 ? static_cast<__size_type>(__w)
299*e4b17023SJohn Marino 		                              : __str.max_size();
300*e4b17023SJohn Marino 	      const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc());
301*e4b17023SJohn Marino 	      const __int_type __eof = __traits_type::eof();
302*e4b17023SJohn Marino 	      __streambuf_type* __sb = __in.rdbuf();
303*e4b17023SJohn Marino 	      __int_type __c = __sb->sgetc();
304*e4b17023SJohn Marino 
305*e4b17023SJohn Marino 	      while (__extracted < __n
306*e4b17023SJohn Marino 		     && !__traits_type::eq_int_type(__c, __eof)
307*e4b17023SJohn Marino 		     && !__ct.is(ctype_base::space,
308*e4b17023SJohn Marino 				 __traits_type::to_char_type(__c)))
309*e4b17023SJohn Marino 		{
310*e4b17023SJohn Marino 		  streamsize __size = std::min(streamsize(__sb->egptr()
311*e4b17023SJohn Marino 							  - __sb->gptr()),
312*e4b17023SJohn Marino 					       streamsize(__n - __extracted));
313*e4b17023SJohn Marino 		  if (__size > 1)
314*e4b17023SJohn Marino 		    {
315*e4b17023SJohn Marino 		      __size = (__ct.scan_is(ctype_base::space,
316*e4b17023SJohn Marino 					     __sb->gptr() + 1,
317*e4b17023SJohn Marino 					     __sb->gptr() + __size)
318*e4b17023SJohn Marino 				- __sb->gptr());
319*e4b17023SJohn Marino 		      __str.append(__sb->gptr(), __size);
320*e4b17023SJohn Marino 		      __sb->__safe_gbump(__size);
321*e4b17023SJohn Marino 		      __extracted += __size;
322*e4b17023SJohn Marino 		      __c = __sb->sgetc();
323*e4b17023SJohn Marino 		    }
324*e4b17023SJohn Marino 		  else
325*e4b17023SJohn Marino 		    {
326*e4b17023SJohn Marino 		      __str += __traits_type::to_char_type(__c);
327*e4b17023SJohn Marino 		      ++__extracted;
328*e4b17023SJohn Marino 		      __c = __sb->snextc();
329*e4b17023SJohn Marino 		    }
330*e4b17023SJohn Marino 		}
331*e4b17023SJohn Marino 
332*e4b17023SJohn Marino 	      if (__traits_type::eq_int_type(__c, __eof))
333*e4b17023SJohn Marino 		__err |= ios_base::eofbit;
334*e4b17023SJohn Marino 	      __in.width(0);
335*e4b17023SJohn Marino 	    }
336*e4b17023SJohn Marino 	  __catch(__cxxabiv1::__forced_unwind&)
337*e4b17023SJohn Marino 	    {
338*e4b17023SJohn Marino 	      __in._M_setstate(ios_base::badbit);
339*e4b17023SJohn Marino 	      __throw_exception_again;
340*e4b17023SJohn Marino 	    }
341*e4b17023SJohn Marino 	  __catch(...)
342*e4b17023SJohn Marino 	    {
343*e4b17023SJohn Marino 	      // _GLIBCXX_RESOLVE_LIB_DEFECTS
344*e4b17023SJohn Marino 	      // 91. Description of operator>> and getline() for string<>
345*e4b17023SJohn Marino 	      // might cause endless loop
346*e4b17023SJohn Marino 	      __in._M_setstate(ios_base::badbit);
347*e4b17023SJohn Marino 	    }
348*e4b17023SJohn Marino 	}
349*e4b17023SJohn Marino       if (!__extracted)
350*e4b17023SJohn Marino 	__err |= ios_base::failbit;
351*e4b17023SJohn Marino       if (__err)
352*e4b17023SJohn Marino 	__in.setstate(__err);
353*e4b17023SJohn Marino       return __in;
354*e4b17023SJohn Marino     }
355*e4b17023SJohn Marino 
356*e4b17023SJohn Marino   template<>
357*e4b17023SJohn Marino     basic_istream<char>&
getline(basic_istream<char> & __in,basic_string<char> & __str,char __delim)358*e4b17023SJohn Marino     getline(basic_istream<char>& __in, basic_string<char>& __str,
359*e4b17023SJohn Marino 	    char __delim)
360*e4b17023SJohn Marino     {
361*e4b17023SJohn Marino       typedef basic_istream<char>       	__istream_type;
362*e4b17023SJohn Marino       typedef __istream_type::int_type		__int_type;
363*e4b17023SJohn Marino       typedef __istream_type::char_type		__char_type;
364*e4b17023SJohn Marino       typedef __istream_type::traits_type	__traits_type;
365*e4b17023SJohn Marino       typedef __istream_type::__streambuf_type  __streambuf_type;
366*e4b17023SJohn Marino       typedef basic_string<char>        	__string_type;
367*e4b17023SJohn Marino       typedef __string_type::size_type		__size_type;
368*e4b17023SJohn Marino 
369*e4b17023SJohn Marino       __size_type __extracted = 0;
370*e4b17023SJohn Marino       const __size_type __n = __str.max_size();
371*e4b17023SJohn Marino       ios_base::iostate __err = ios_base::goodbit;
372*e4b17023SJohn Marino       __istream_type::sentry __cerb(__in, true);
373*e4b17023SJohn Marino       if (__cerb)
374*e4b17023SJohn Marino 	{
375*e4b17023SJohn Marino 	  __try
376*e4b17023SJohn Marino 	    {
377*e4b17023SJohn Marino 	      __str.erase();
378*e4b17023SJohn Marino 	      const __int_type __idelim = __traits_type::to_int_type(__delim);
379*e4b17023SJohn Marino 	      const __int_type __eof = __traits_type::eof();
380*e4b17023SJohn Marino 	      __streambuf_type* __sb = __in.rdbuf();
381*e4b17023SJohn Marino 	      __int_type __c = __sb->sgetc();
382*e4b17023SJohn Marino 
383*e4b17023SJohn Marino 	      while (__extracted < __n
384*e4b17023SJohn Marino 		     && !__traits_type::eq_int_type(__c, __eof)
385*e4b17023SJohn Marino 		     && !__traits_type::eq_int_type(__c, __idelim))
386*e4b17023SJohn Marino 		{
387*e4b17023SJohn Marino 		  streamsize __size = std::min(streamsize(__sb->egptr()
388*e4b17023SJohn Marino 							  - __sb->gptr()),
389*e4b17023SJohn Marino 					       streamsize(__n - __extracted));
390*e4b17023SJohn Marino 		  if (__size > 1)
391*e4b17023SJohn Marino 		    {
392*e4b17023SJohn Marino 		      const __char_type* __p = __traits_type::find(__sb->gptr(),
393*e4b17023SJohn Marino 								   __size,
394*e4b17023SJohn Marino 								   __delim);
395*e4b17023SJohn Marino 		      if (__p)
396*e4b17023SJohn Marino 			__size = __p - __sb->gptr();
397*e4b17023SJohn Marino 		      __str.append(__sb->gptr(), __size);
398*e4b17023SJohn Marino 		      __sb->__safe_gbump(__size);
399*e4b17023SJohn Marino 		      __extracted += __size;
400*e4b17023SJohn Marino 		      __c = __sb->sgetc();
401*e4b17023SJohn Marino 		    }
402*e4b17023SJohn Marino 		  else
403*e4b17023SJohn Marino 		    {
404*e4b17023SJohn Marino 		      __str += __traits_type::to_char_type(__c);
405*e4b17023SJohn Marino 		      ++__extracted;
406*e4b17023SJohn Marino 		      __c = __sb->snextc();
407*e4b17023SJohn Marino 		    }
408*e4b17023SJohn Marino 		}
409*e4b17023SJohn Marino 
410*e4b17023SJohn Marino 	      if (__traits_type::eq_int_type(__c, __eof))
411*e4b17023SJohn Marino 		__err |= ios_base::eofbit;
412*e4b17023SJohn Marino 	      else if (__traits_type::eq_int_type(__c, __idelim))
413*e4b17023SJohn Marino 		{
414*e4b17023SJohn Marino 		  ++__extracted;
415*e4b17023SJohn Marino 		  __sb->sbumpc();
416*e4b17023SJohn Marino 		}
417*e4b17023SJohn Marino 	      else
418*e4b17023SJohn Marino 		__err |= ios_base::failbit;
419*e4b17023SJohn Marino 	    }
420*e4b17023SJohn Marino 	  __catch(__cxxabiv1::__forced_unwind&)
421*e4b17023SJohn Marino 	    {
422*e4b17023SJohn Marino 	      __in._M_setstate(ios_base::badbit);
423*e4b17023SJohn Marino 	      __throw_exception_again;
424*e4b17023SJohn Marino 	    }
425*e4b17023SJohn Marino 	  __catch(...)
426*e4b17023SJohn Marino 	    {
427*e4b17023SJohn Marino 	      // _GLIBCXX_RESOLVE_LIB_DEFECTS
428*e4b17023SJohn Marino 	      // 91. Description of operator>> and getline() for string<>
429*e4b17023SJohn Marino 	      // might cause endless loop
430*e4b17023SJohn Marino 	      __in._M_setstate(ios_base::badbit);
431*e4b17023SJohn Marino 	    }
432*e4b17023SJohn Marino 	}
433*e4b17023SJohn Marino       if (!__extracted)
434*e4b17023SJohn Marino 	__err |= ios_base::failbit;
435*e4b17023SJohn Marino       if (__err)
436*e4b17023SJohn Marino 	__in.setstate(__err);
437*e4b17023SJohn Marino       return __in;
438*e4b17023SJohn Marino     }
439*e4b17023SJohn Marino 
440*e4b17023SJohn Marino #ifdef _GLIBCXX_USE_WCHAR_T
441*e4b17023SJohn Marino   template<>
442*e4b17023SJohn Marino     basic_istream<wchar_t>&
443*e4b17023SJohn Marino     basic_istream<wchar_t>::
getline(char_type * __s,streamsize __n,char_type __delim)444*e4b17023SJohn Marino     getline(char_type* __s, streamsize __n, char_type __delim)
445*e4b17023SJohn Marino     {
446*e4b17023SJohn Marino       _M_gcount = 0;
447*e4b17023SJohn Marino       ios_base::iostate __err = ios_base::goodbit;
448*e4b17023SJohn Marino       sentry __cerb(*this, true);
449*e4b17023SJohn Marino       if (__cerb)
450*e4b17023SJohn Marino 	{
451*e4b17023SJohn Marino           __try
452*e4b17023SJohn Marino 	    {
453*e4b17023SJohn Marino 	      const int_type __idelim = traits_type::to_int_type(__delim);
454*e4b17023SJohn Marino 	      const int_type __eof = traits_type::eof();
455*e4b17023SJohn Marino 	      __streambuf_type* __sb = this->rdbuf();
456*e4b17023SJohn Marino 	      int_type __c = __sb->sgetc();
457*e4b17023SJohn Marino 
458*e4b17023SJohn Marino 	      while (_M_gcount + 1 < __n
459*e4b17023SJohn Marino 		     && !traits_type::eq_int_type(__c, __eof)
460*e4b17023SJohn Marino 		     && !traits_type::eq_int_type(__c, __idelim))
461*e4b17023SJohn Marino 		{
462*e4b17023SJohn Marino 		  streamsize __size = std::min(streamsize(__sb->egptr()
463*e4b17023SJohn Marino 							  - __sb->gptr()),
464*e4b17023SJohn Marino 					       streamsize(__n - _M_gcount
465*e4b17023SJohn Marino 							  - 1));
466*e4b17023SJohn Marino 		  if (__size > 1)
467*e4b17023SJohn Marino 		    {
468*e4b17023SJohn Marino 		      const char_type* __p = traits_type::find(__sb->gptr(),
469*e4b17023SJohn Marino 							       __size,
470*e4b17023SJohn Marino 							       __delim);
471*e4b17023SJohn Marino 		      if (__p)
472*e4b17023SJohn Marino 			__size = __p - __sb->gptr();
473*e4b17023SJohn Marino 		      traits_type::copy(__s, __sb->gptr(), __size);
474*e4b17023SJohn Marino 		      __s += __size;
475*e4b17023SJohn Marino 		      __sb->__safe_gbump(__size);
476*e4b17023SJohn Marino 		      _M_gcount += __size;
477*e4b17023SJohn Marino 		      __c = __sb->sgetc();
478*e4b17023SJohn Marino 		    }
479*e4b17023SJohn Marino 		  else
480*e4b17023SJohn Marino 		    {
481*e4b17023SJohn Marino 		      *__s++ = traits_type::to_char_type(__c);
482*e4b17023SJohn Marino 		      ++_M_gcount;
483*e4b17023SJohn Marino 		      __c = __sb->snextc();
484*e4b17023SJohn Marino 		    }
485*e4b17023SJohn Marino 		}
486*e4b17023SJohn Marino 
487*e4b17023SJohn Marino 	      if (traits_type::eq_int_type(__c, __eof))
488*e4b17023SJohn Marino 		__err |= ios_base::eofbit;
489*e4b17023SJohn Marino 	      else if (traits_type::eq_int_type(__c, __idelim))
490*e4b17023SJohn Marino 		{
491*e4b17023SJohn Marino 		  ++_M_gcount;
492*e4b17023SJohn Marino 		  __sb->sbumpc();
493*e4b17023SJohn Marino 		}
494*e4b17023SJohn Marino 	      else
495*e4b17023SJohn Marino 		__err |= ios_base::failbit;
496*e4b17023SJohn Marino 	    }
497*e4b17023SJohn Marino 	  __catch(__cxxabiv1::__forced_unwind&)
498*e4b17023SJohn Marino 	    {
499*e4b17023SJohn Marino 	      this->_M_setstate(ios_base::badbit);
500*e4b17023SJohn Marino 	      __throw_exception_again;
501*e4b17023SJohn Marino 	    }
502*e4b17023SJohn Marino 	  __catch(...)
503*e4b17023SJohn Marino 	    { this->_M_setstate(ios_base::badbit); }
504*e4b17023SJohn Marino 	}
505*e4b17023SJohn Marino       // _GLIBCXX_RESOLVE_LIB_DEFECTS
506*e4b17023SJohn Marino       // 243. get and getline when sentry reports failure.
507*e4b17023SJohn Marino       if (__n > 0)
508*e4b17023SJohn Marino 	*__s = char_type();
509*e4b17023SJohn Marino       if (!_M_gcount)
510*e4b17023SJohn Marino 	__err |= ios_base::failbit;
511*e4b17023SJohn Marino       if (__err)
512*e4b17023SJohn Marino 	this->setstate(__err);
513*e4b17023SJohn Marino       return *this;
514*e4b17023SJohn Marino     }
515*e4b17023SJohn Marino 
516*e4b17023SJohn Marino   template<>
517*e4b17023SJohn Marino     basic_istream<wchar_t>&
518*e4b17023SJohn Marino     basic_istream<wchar_t>::
ignore(streamsize __n,int_type __delim)519*e4b17023SJohn Marino     ignore(streamsize __n, int_type __delim)
520*e4b17023SJohn Marino     {
521*e4b17023SJohn Marino       if (traits_type::eq_int_type(__delim, traits_type::eof()))
522*e4b17023SJohn Marino 	return ignore(__n);
523*e4b17023SJohn Marino 
524*e4b17023SJohn Marino       _M_gcount = 0;
525*e4b17023SJohn Marino       sentry __cerb(*this, true);
526*e4b17023SJohn Marino       if (__n > 0 && __cerb)
527*e4b17023SJohn Marino 	{
528*e4b17023SJohn Marino 	  ios_base::iostate __err = ios_base::goodbit;
529*e4b17023SJohn Marino 	  __try
530*e4b17023SJohn Marino 	    {
531*e4b17023SJohn Marino 	      const char_type __cdelim = traits_type::to_char_type(__delim);
532*e4b17023SJohn Marino 	      const int_type __eof = traits_type::eof();
533*e4b17023SJohn Marino 	      __streambuf_type* __sb = this->rdbuf();
534*e4b17023SJohn Marino 	      int_type __c = __sb->sgetc();
535*e4b17023SJohn Marino 
536*e4b17023SJohn Marino 	      bool __large_ignore = false;
537*e4b17023SJohn Marino 	      while (true)
538*e4b17023SJohn Marino 		{
539*e4b17023SJohn Marino 		  while (_M_gcount < __n
540*e4b17023SJohn Marino 			 && !traits_type::eq_int_type(__c, __eof)
541*e4b17023SJohn Marino 			 && !traits_type::eq_int_type(__c, __delim))
542*e4b17023SJohn Marino 		    {
543*e4b17023SJohn Marino 		      streamsize __size = std::min(streamsize(__sb->egptr()
544*e4b17023SJohn Marino 							      - __sb->gptr()),
545*e4b17023SJohn Marino 						   streamsize(__n - _M_gcount));
546*e4b17023SJohn Marino 		      if (__size > 1)
547*e4b17023SJohn Marino 			{
548*e4b17023SJohn Marino 			  const char_type* __p = traits_type::find(__sb->gptr(),
549*e4b17023SJohn Marino 								   __size,
550*e4b17023SJohn Marino 								   __cdelim);
551*e4b17023SJohn Marino 			  if (__p)
552*e4b17023SJohn Marino 			    __size = __p - __sb->gptr();
553*e4b17023SJohn Marino 			  __sb->__safe_gbump(__size);
554*e4b17023SJohn Marino 			  _M_gcount += __size;
555*e4b17023SJohn Marino 			  __c = __sb->sgetc();
556*e4b17023SJohn Marino 			}
557*e4b17023SJohn Marino 		      else
558*e4b17023SJohn Marino 			{
559*e4b17023SJohn Marino 			  ++_M_gcount;
560*e4b17023SJohn Marino 			  __c = __sb->snextc();
561*e4b17023SJohn Marino 			}
562*e4b17023SJohn Marino 		    }
563*e4b17023SJohn Marino 		  if (__n == __gnu_cxx::__numeric_traits<streamsize>::__max
564*e4b17023SJohn Marino 		      && !traits_type::eq_int_type(__c, __eof)
565*e4b17023SJohn Marino 		      && !traits_type::eq_int_type(__c, __delim))
566*e4b17023SJohn Marino 		    {
567*e4b17023SJohn Marino 		      _M_gcount =
568*e4b17023SJohn Marino 			__gnu_cxx::__numeric_traits<streamsize>::__min;
569*e4b17023SJohn Marino 		      __large_ignore = true;
570*e4b17023SJohn Marino 		    }
571*e4b17023SJohn Marino 		  else
572*e4b17023SJohn Marino 		    break;
573*e4b17023SJohn Marino 		}
574*e4b17023SJohn Marino 
575*e4b17023SJohn Marino 	      if (__large_ignore)
576*e4b17023SJohn Marino 		_M_gcount = __gnu_cxx::__numeric_traits<streamsize>::__max;
577*e4b17023SJohn Marino 
578*e4b17023SJohn Marino 	      if (traits_type::eq_int_type(__c, __eof))
579*e4b17023SJohn Marino 		__err |= ios_base::eofbit;
580*e4b17023SJohn Marino 	      else if (traits_type::eq_int_type(__c, __delim))
581*e4b17023SJohn Marino 		{
582*e4b17023SJohn Marino 		  if (_M_gcount
583*e4b17023SJohn Marino 		      < __gnu_cxx::__numeric_traits<streamsize>::__max)
584*e4b17023SJohn Marino 		    ++_M_gcount;
585*e4b17023SJohn Marino 		  __sb->sbumpc();
586*e4b17023SJohn Marino 		}
587*e4b17023SJohn Marino 	    }
588*e4b17023SJohn Marino 	  __catch(__cxxabiv1::__forced_unwind&)
589*e4b17023SJohn Marino 	    {
590*e4b17023SJohn Marino 	      this->_M_setstate(ios_base::badbit);
591*e4b17023SJohn Marino 	      __throw_exception_again;
592*e4b17023SJohn Marino 	    }
593*e4b17023SJohn Marino 	  __catch(...)
594*e4b17023SJohn Marino 	    { this->_M_setstate(ios_base::badbit); }
595*e4b17023SJohn Marino 	  if (__err)
596*e4b17023SJohn Marino 	    this->setstate(__err);
597*e4b17023SJohn Marino 	}
598*e4b17023SJohn Marino       return *this;
599*e4b17023SJohn Marino     }
600*e4b17023SJohn Marino 
601*e4b17023SJohn Marino   template<>
602*e4b17023SJohn Marino     basic_istream<wchar_t>&
getline(basic_istream<wchar_t> & __in,basic_string<wchar_t> & __str,wchar_t __delim)603*e4b17023SJohn Marino     getline(basic_istream<wchar_t>& __in, basic_string<wchar_t>& __str,
604*e4b17023SJohn Marino 	    wchar_t __delim)
605*e4b17023SJohn Marino     {
606*e4b17023SJohn Marino       typedef basic_istream<wchar_t>       	__istream_type;
607*e4b17023SJohn Marino       typedef __istream_type::int_type		__int_type;
608*e4b17023SJohn Marino       typedef __istream_type::char_type		__char_type;
609*e4b17023SJohn Marino       typedef __istream_type::traits_type	__traits_type;
610*e4b17023SJohn Marino       typedef __istream_type::__streambuf_type  __streambuf_type;
611*e4b17023SJohn Marino       typedef basic_string<wchar_t>        	__string_type;
612*e4b17023SJohn Marino       typedef __string_type::size_type		__size_type;
613*e4b17023SJohn Marino 
614*e4b17023SJohn Marino       __size_type __extracted = 0;
615*e4b17023SJohn Marino       const __size_type __n = __str.max_size();
616*e4b17023SJohn Marino       ios_base::iostate __err = ios_base::goodbit;
617*e4b17023SJohn Marino       __istream_type::sentry __cerb(__in, true);
618*e4b17023SJohn Marino       if (__cerb)
619*e4b17023SJohn Marino 	{
620*e4b17023SJohn Marino 	  __try
621*e4b17023SJohn Marino 	    {
622*e4b17023SJohn Marino 	      __str.erase();
623*e4b17023SJohn Marino 	      const __int_type __idelim = __traits_type::to_int_type(__delim);
624*e4b17023SJohn Marino 	      const __int_type __eof = __traits_type::eof();
625*e4b17023SJohn Marino 	      __streambuf_type* __sb = __in.rdbuf();
626*e4b17023SJohn Marino 	      __int_type __c = __sb->sgetc();
627*e4b17023SJohn Marino 
628*e4b17023SJohn Marino 	      while (__extracted < __n
629*e4b17023SJohn Marino 		     && !__traits_type::eq_int_type(__c, __eof)
630*e4b17023SJohn Marino 		     && !__traits_type::eq_int_type(__c, __idelim))
631*e4b17023SJohn Marino 		{
632*e4b17023SJohn Marino 		  streamsize __size = std::min(streamsize(__sb->egptr()
633*e4b17023SJohn Marino 							  - __sb->gptr()),
634*e4b17023SJohn Marino 					       streamsize(__n - __extracted));
635*e4b17023SJohn Marino 		  if (__size > 1)
636*e4b17023SJohn Marino 		    {
637*e4b17023SJohn Marino 		      const __char_type* __p = __traits_type::find(__sb->gptr(),
638*e4b17023SJohn Marino 								   __size,
639*e4b17023SJohn Marino 								   __delim);
640*e4b17023SJohn Marino 		      if (__p)
641*e4b17023SJohn Marino 			__size = __p - __sb->gptr();
642*e4b17023SJohn Marino 		      __str.append(__sb->gptr(), __size);
643*e4b17023SJohn Marino 		      __sb->__safe_gbump(__size);
644*e4b17023SJohn Marino 		      __extracted += __size;
645*e4b17023SJohn Marino 		      __c = __sb->sgetc();
646*e4b17023SJohn Marino 		    }
647*e4b17023SJohn Marino 		  else
648*e4b17023SJohn Marino 		    {
649*e4b17023SJohn Marino 		      __str += __traits_type::to_char_type(__c);
650*e4b17023SJohn Marino 		      ++__extracted;
651*e4b17023SJohn Marino 		      __c = __sb->snextc();
652*e4b17023SJohn Marino 		    }
653*e4b17023SJohn Marino 		}
654*e4b17023SJohn Marino 
655*e4b17023SJohn Marino 	      if (__traits_type::eq_int_type(__c, __eof))
656*e4b17023SJohn Marino 		__err |= ios_base::eofbit;
657*e4b17023SJohn Marino 	      else if (__traits_type::eq_int_type(__c, __idelim))
658*e4b17023SJohn Marino 		{
659*e4b17023SJohn Marino 		  ++__extracted;
660*e4b17023SJohn Marino 		  __sb->sbumpc();
661*e4b17023SJohn Marino 		}
662*e4b17023SJohn Marino 	      else
663*e4b17023SJohn Marino 		__err |= ios_base::failbit;
664*e4b17023SJohn Marino 	    }
665*e4b17023SJohn Marino 	  __catch(__cxxabiv1::__forced_unwind&)
666*e4b17023SJohn Marino 	    {
667*e4b17023SJohn Marino 	      __in._M_setstate(ios_base::badbit);
668*e4b17023SJohn Marino 	      __throw_exception_again;
669*e4b17023SJohn Marino 	    }
670*e4b17023SJohn Marino 	  __catch(...)
671*e4b17023SJohn Marino 	    {
672*e4b17023SJohn Marino 	      // _GLIBCXX_RESOLVE_LIB_DEFECTS
673*e4b17023SJohn Marino 	      // 91. Description of operator>> and getline() for string<>
674*e4b17023SJohn Marino 	      // might cause endless loop
675*e4b17023SJohn Marino 	      __in._M_setstate(ios_base::badbit);
676*e4b17023SJohn Marino 	    }
677*e4b17023SJohn Marino 	}
678*e4b17023SJohn Marino       if (!__extracted)
679*e4b17023SJohn Marino 	__err |= ios_base::failbit;
680*e4b17023SJohn Marino       if (__err)
681*e4b17023SJohn Marino 	__in.setstate(__err);
682*e4b17023SJohn Marino       return __in;
683*e4b17023SJohn Marino     }
684*e4b17023SJohn Marino #endif
685*e4b17023SJohn Marino 
686*e4b17023SJohn Marino _GLIBCXX_END_NAMESPACE_VERSION
687*e4b17023SJohn Marino } // namespace
688