OSDN Git Service

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