OSDN Git Service

* configure.in (target frags): Add powerpc*-linux-gnulibc1.
[pf3gnuchains/gcc-fork.git] / libio / iostream.cc
1 /* This is part of libio/iostream, providing -*- C++ -*- input/output.
2    Copyright (C) 1993, 1997 Free Software Foundation, Inc.
3
4    This file is part of the GNU IO Library.  This library is free
5    software; you can redistribute it and/or modify it under the
6    terms of the GNU General Public License as published by the
7    Free Software Foundation; either version 2, or (at your option)
8    any later version.
9
10    This library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU General Public License for more details.
14
15    You should have received a copy of the GNU General Public License
16    along with this library; see the file COPYING.  If not, write to the Free
17    Software Foundation, 59 Temple Place - Suite 330, Boston, MA  02111-1307,
18    USA.
19
20    As a special exception, if you link this library with files
21    compiled with a GNU compiler to produce an executable, this does not cause
22    the resulting executable to be covered by the GNU General Public License.
23    This exception does not however invalidate any other reasons why
24    the executable file might be covered by the GNU General Public License. */
25
26 /* Written by Per Bothner (bothner@cygnus.com). */
27
28 #ifdef __GNUC__
29 #pragma implementation
30 #endif
31 #define _STREAM_COMPAT
32 #include <iostream.h>
33 #include "libioP.h"
34 #include <stdio.h>  /* Needed for sprintf */
35 #include <ctype.h>
36 #include <string.h>
37 #include <limits.h>
38
39 #if _G_HAVE_PRINTF_FP
40 #include <printf.h>
41 extern "C" int __printf_fp (_IO_FILE *, const struct printf_info *,
42                             const void *const *);
43 #else
44 #include "floatio.h"
45 # ifndef _IO_USE_DTOA
46 int __cvt_double(double number, register int prec, int flags, int *signp,
47                  int fmtch, char *startp, char *endp);
48 # endif
49 #endif
50
51 #define BUF             (MAXEXP+MAXFRACT+1)     /* + decimal point */
52
53 //#define isspace(ch) ((ch)==' ' || (ch)=='\t' || (ch)=='\n')
54
55 istream::istream(streambuf *sb, ostream* tied)
56 {
57   init (sb, tied);
58   _gcount = 0;
59 }
60
61 int skip_ws(streambuf* sb)
62 {
63     int ch;
64     for (;;) {
65         ch = sb->sbumpc();
66         if (ch == EOF || !isspace(ch))
67             return ch;
68     }
69 }
70
71 istream& istream::get(char& c)
72 {
73     if (ipfx1()) {
74         int ch = _strbuf->sbumpc();
75         if (ch == EOF) {
76           set(ios::eofbit|ios::failbit);
77           _gcount = 0;
78         }
79         else {
80           c = (char)ch;
81           _gcount = 1;
82         }
83     }
84     else
85       _gcount = 0;
86     return *this;
87 }
88
89 int istream::peek()
90 {
91   if (!good())
92     return EOF;
93   if (_tie && rdbuf()->in_avail() == 0)
94     _tie->flush();
95   int ch = _strbuf->sgetc();
96   if (ch == EOF)
97     set(ios::eofbit);
98   return ch;
99 }
100
101 istream& istream::ignore(int n /* = 1 */, int delim /* = EOF */)
102 {
103     _gcount = 0;
104     if (ipfx1()) {
105         register streambuf* sb = _strbuf;
106         if (delim == EOF) {
107             _gcount = sb->ignore(n);
108             return *this;
109         }
110         for (;;) {
111 #if 0
112             if (n != MAXINT) // FIXME
113 #endif
114             if (--n < 0)
115                 break;
116             int ch = sb->sbumpc();
117             if (ch == EOF) {
118                 set(ios::eofbit|ios::failbit);
119                 break;
120             }
121             _gcount++;
122             if (ch == delim)
123                 break;
124         }
125     }
126     return *this;
127 }
128
129 istream& istream::read(char *s, streamsize n)
130 {
131     if (ipfx1()) {
132         _gcount = _strbuf->sgetn(s, n);
133         if (_gcount != n)
134             set(ios::failbit|ios::eofbit);
135     }
136     else
137       _gcount = 0;
138     return *this;
139 }
140
141 int
142 istream::sync ()
143 {
144   streambuf *sb = rdbuf ();
145   if (sb == NULL)
146     return EOF;
147   if (sb->sync ()) // Later: pubsync
148     {
149       setstate (ios::badbit);
150       return EOF;
151     }
152   else
153     return 0;
154 }
155
156 istream& istream::seekg(streampos pos)
157 {
158     pos = _strbuf->pubseekpos(pos, ios::in);
159     if (pos == streampos(EOF))
160         set(ios::badbit);
161     return *this;
162 }
163
164 istream& istream::seekg(streamoff off, _seek_dir dir)
165 {
166   streampos pos = _IO_seekoff (_strbuf, off, (int) dir, _IOS_INPUT);
167   if (pos == streampos(EOF))
168     set(ios::badbit);
169   return *this;
170 }
171
172 streampos istream::tellg()
173 {
174 #if 0
175     streampos pos = _strbuf->pubseekoff(0, ios::cur, ios::in);
176 #else
177     streampos pos = _IO_seekoff (_strbuf, 0, _IO_seek_cur, _IOS_INPUT);
178 #endif
179     if (pos == streampos(EOF))
180         set(ios::badbit);
181     return pos;
182 }
183
184 istream& istream::operator>>(char& c)
185 {
186     if (ipfx0()) {
187         int ch = _strbuf->sbumpc();
188         if (ch == EOF)
189             set(ios::eofbit|ios::failbit);
190         else
191             c = (char)ch;
192     }
193     return *this;
194 }
195
196 istream&
197 istream::operator>> (char* ptr)
198 {
199   register char *p = ptr;
200   int w = width(0);
201   if (ipfx0())
202     {
203       register streambuf* sb = _strbuf;
204       for (;;)
205         {
206           int ch = sb->sbumpc();
207           if (ch == EOF)
208             {
209               set(ios::eofbit);
210               break;
211             }
212           else if (isspace(ch) || w == 1)
213             {
214               sb->sputbackc(ch);
215               break;
216             }
217           else *p++ = ch;
218           w--;
219         }
220       if (p == ptr)
221         set(ios::failbit);
222     }
223   *p = '\0';
224   return *this;
225 }
226
227 #if defined(__GNUC__) && !defined(__STRICT_ANSI__)
228 #define LONGEST long long
229 #else
230 #define LONGEST long
231 #endif
232
233 static int read_int(istream& stream, unsigned LONGEST& val, int& neg)
234 {
235     if (!stream.ipfx0())
236       return 0;
237     register streambuf* sb = stream.rdbuf();
238     int base = 10;
239     int ndigits = 0;
240     register int ch = skip_ws(sb);
241     if (ch == EOF)
242         goto eof_fail;
243     neg = 0;
244     if (ch == '+') {
245         ch = skip_ws(sb);
246     }
247     else if (ch == '-') {
248         neg = 1;
249         ch = skip_ws(sb);
250     }
251     if (ch == EOF) goto eof_fail;
252     if (!(stream.flags() & ios::basefield)) {
253         if (ch == '0') {
254             ch = sb->sbumpc();
255             if (ch == EOF) {
256                 val = 0;
257                 return 1;
258             }
259             if (ch == 'x' || ch == 'X') {
260                 base = 16;
261                 ch = sb->sbumpc();
262                 if (ch == EOF) goto eof_fail;
263             }
264             else {
265                 sb->sputbackc(ch);
266                 base = 8;
267                 ch = '0';
268             }
269         }
270     }
271     else if ((stream.flags() & ios::basefield) == ios::hex)
272         base = 16;
273     else if ((stream.flags() & ios::basefield) == ios::oct)
274         base = 8;
275     val = 0;
276     for (;;) {
277         if (ch == EOF)
278             break;
279         int digit;
280         if (ch >= '0' && ch <= '9')
281             digit = ch - '0';
282         else if (ch >= 'A' && ch <= 'F')
283             digit = ch - 'A' + 10;
284         else if (ch >= 'a' && ch <= 'f')
285             digit = ch - 'a' + 10;
286         else
287             digit = 999;
288         if (digit >= base) {
289             sb->sputbackc(ch);
290             if (ndigits == 0)
291                 goto fail;
292             else
293                 return 1;
294         }
295         ndigits++;
296         val = base * val + digit;
297         ch = sb->sbumpc();
298     }
299     return 1;
300   fail:
301     stream.set(ios::failbit);
302     return 0;
303   eof_fail:
304     stream.set(ios::failbit|ios::eofbit);
305     return 0;
306 }
307
308 #define READ_INT(TYPE) \
309 istream& istream::operator>>(TYPE& i)\
310 {\
311     unsigned LONGEST val; int neg;\
312     if (read_int(*this, val, neg)) {\
313         if (neg) val = -val;\
314         i = (TYPE)val;\
315     }\
316     return *this;\
317 }
318
319 READ_INT(short)
320 READ_INT(unsigned short)
321 READ_INT(int)
322 READ_INT(unsigned int)
323 READ_INT(long)
324 READ_INT(unsigned long)
325 #if defined(__GNUC__) && !defined(__STRICT_ANSI__)
326 READ_INT(long long)
327 READ_INT(unsigned long long)
328 #endif
329 #if _G_HAVE_BOOL
330 READ_INT(bool)
331 #endif
332
333 istream& istream::operator>>(long double& x)
334 {
335     if (ipfx0())
336 #if _G_HAVE_LONG_DOUBLE_IO
337         scan("%Lg", &x);
338 #else
339         scan("%lg", &x);
340 #endif
341     return *this;
342 }
343
344 istream& istream::operator>>(double& x)
345 {
346     if (ipfx0())
347         scan("%lg", &x);
348     return *this;
349 }
350
351 istream& istream::operator>>(float& x)
352 {
353     if (ipfx0())
354         scan("%g", &x);
355     return *this;
356 }
357
358 istream& istream::operator>>(register streambuf* sbuf)
359 {
360     if (ipfx0()) {
361         register streambuf* inbuf = rdbuf();
362         // FIXME: Should optimize!
363         for (;;) {
364             register int ch = inbuf->sbumpc();
365             if (ch == EOF) {
366                 set(ios::eofbit);
367                 break;
368             }
369             if (sbuf->sputc(ch) == EOF) {
370                 set(ios::failbit);
371                 break;
372             }
373         }
374     }
375     return *this;
376 }
377
378 ostream& ostream::operator<<(char c)
379 {
380     if (opfx()) {
381         _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
382                                   _strbuf);
383 #if 1
384         // This is what the cfront implementation does.
385         if (_strbuf->sputc(c) == EOF) {
386             set(ios::badbit);
387             goto failed;
388         }
389 #else
390         // This is what cfront documentation and current ANSI drafts say.
391         int w = width(0);
392         char fill_char = fill();
393         register int padding = w > 0 ? w - 1 : 0;
394         register streambuf *sb = _strbuf;
395         if (!(flags() & ios::left) && padding) // Default adjustment.
396             if (_IO_padn(sb, fill_char, padding) < padding) {
397               set(ios::badbit);
398               goto failed;
399             }
400         if (sb->sputc(c) == EOF) {
401           set(ios::badbit);
402           goto failed;
403         }
404         if (flags() & ios::left && padding) // Left adjustment.
405             if (_IO_padn(sb, fill_char, padding) < padding)
406               set(ios::badbit);
407 #endif
408        failed:
409         osfx();
410         _IO_cleanup_region_end (0);
411     }
412     return *this;
413 }
414
415 /* Write VAL on STREAM.
416    If SIGN<0, val is the absolute value of a negative number.
417    If SIGN>0, val is a signed non-negative number.
418    If SIGN==0, val is unsigned. */
419
420 static void write_int(ostream& stream, unsigned LONGEST val, int sign)
421 {
422 #define WRITE_BUF_SIZE (10 + sizeof(unsigned LONGEST) * 3)
423     char buf[WRITE_BUF_SIZE];
424     register char *buf_ptr = buf+WRITE_BUF_SIZE; // End of buf.
425     const char *show_base = "";
426     int show_base_len = 0;
427     int show_pos = 0; // If 1, print a '+'.
428
429     // Now do the actual conversion, placing the result at the *end* of buf.
430     // Note that we use separate code for decimal, octal, and hex,
431     // so we can divide by optimizable constants.
432     if ((stream.flags() & ios::basefield) == ios::oct) { // Octal
433         do {
434             *--buf_ptr = (val & 7) + '0';
435             val = val >> 3;
436         } while (val != 0);
437         if ((stream.flags() & ios::showbase) && (*buf_ptr != '0'))
438             *--buf_ptr = '0';
439     }
440     else if ((stream.flags() & ios::basefield) == ios::hex) { // Hex
441         const char *xdigs = (stream.flags() & ios::uppercase) ? "0123456789ABCDEF0X"
442             : "0123456789abcdef0x";
443         do {
444             *--buf_ptr = xdigs[val & 15];
445             val = val >> 4;
446         } while (val != 0);
447         if ((stream.flags() & ios::showbase)) {
448             show_base = xdigs + 16; // Either "0X" or "0x".
449             show_base_len = 2;
450         }
451     }
452     else { // Decimal
453 #if defined(__GNUC__) && !defined(__STRICT_ANSI__)
454         // Optimization:  Only use long long when we need to.
455         while (val > UINT_MAX) {
456             *--buf_ptr = (val % 10) + '0';
457             val /= 10;
458         }
459         // Use more efficient (int) arithmetic for the rest.
460         register unsigned int ival = (unsigned int)val;
461 #else
462         register unsigned LONGEST ival = val;
463 #endif
464         do {
465             *--buf_ptr = (ival % 10) + '0';
466             ival /= 10;
467         } while (ival != 0);
468         if (sign > 0 && (stream.flags() & ios::showpos))
469             show_pos=1;
470     }
471
472     int buf_len = buf+WRITE_BUF_SIZE - buf_ptr;
473     int w = stream.width(0);
474
475     // Calculate padding.
476     int len = buf_len+show_pos;
477     if (sign < 0) len++;
478     len += show_base_len;
479     int padding = len > w ? 0 : w - len;
480
481     // Do actual output.
482     register streambuf* sbuf = stream.rdbuf();
483     ios::fmtflags pad_kind =
484         stream.flags() & (ios::left|ios::right|ios::internal);
485     char fill_char = stream.fill();
486     if (padding > 0
487         && pad_kind != (ios::fmtflags)ios::left
488         && pad_kind != (ios::fmtflags)ios::internal) // Default (right) adjust.
489         if (_IO_padn(sbuf, fill_char, padding) < padding)
490           goto failed;
491     if (sign < 0 || show_pos)
492       {
493         char ch = sign < 0 ? '-' : '+';
494         if (sbuf->sputc(ch) < 0)
495           goto failed;
496       }
497     if (show_base_len)
498         if (_IO_sputn(sbuf, show_base, show_base_len) <= 0)
499           goto failed;
500     if (pad_kind == (ios::fmtflags)ios::internal && padding > 0)
501       if (_IO_padn(sbuf, fill_char, padding) < padding)
502         goto failed;
503     if (_IO_sputn (sbuf, buf_ptr, buf_len) != buf_len)
504       goto failed;
505     if (pad_kind == (ios::fmtflags)ios::left && padding > 0) // Left adjustment
506       if (_IO_padn(sbuf, fill_char, padding) < padding)
507         goto failed;
508     stream.osfx();
509     return;
510   failed:
511     stream.set(ios::badbit);
512     stream.osfx();
513 }
514
515 ostream& ostream::operator<<(int n)
516 {
517     if (opfx()) {
518         _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
519                                   _strbuf);
520         int sign = 1;
521         unsigned int abs_n = (unsigned)n;
522         if (n < 0 && (flags() & (ios::oct|ios::hex)) == 0)
523             abs_n = -((unsigned)n), sign = -1;
524         write_int(*this, abs_n, sign);
525         _IO_cleanup_region_end (0);
526     }
527     return *this;
528 }
529
530 ostream& ostream::operator<<(unsigned int n)
531 {
532     if (opfx()) {
533         _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
534                                   _strbuf);
535         write_int(*this, n, 0);
536         _IO_cleanup_region_end (0);
537     }
538     return *this;
539 }
540
541
542 ostream& ostream::operator<<(long n)
543 {
544     if (opfx()) {
545         _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
546                                   _strbuf);
547         int sign = 1;
548         unsigned long abs_n = (unsigned long)n;
549         if (n < 0 && (flags() & (ios::oct|ios::hex)) == 0)
550             abs_n = -((unsigned long)n), sign = -1;
551         write_int(*this, abs_n, sign);
552         _IO_cleanup_region_end (0);
553     }
554     return *this;
555 }
556
557 ostream& ostream::operator<<(unsigned long n)
558 {
559     if (opfx()) {
560         _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
561                                   _strbuf);
562         write_int(*this, n, 0);
563         _IO_cleanup_region_end (0);
564     }
565     return *this;
566 }
567
568 #if defined(__GNUC__) && !defined(__STRICT_ANSI__)
569 ostream& ostream::operator<<(long long n)
570 {
571     if (opfx()) {
572         _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
573                                   _strbuf);
574         int sign = 1;
575         unsigned long long abs_n = (unsigned long long)n;
576         if (n < 0 && (flags() & (ios::oct|ios::hex)) == 0)
577             abs_n = -((unsigned long long)n), sign = -1;
578         write_int(*this, abs_n, sign);
579         _IO_cleanup_region_end (0);
580     }
581     return *this;
582 }
583
584
585 ostream& ostream::operator<<(unsigned long long n)
586 {
587     if (opfx()) {
588         _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
589                                   _strbuf);
590         write_int(*this, n, 0);
591         _IO_cleanup_region_end (0);
592     }
593     return *this;
594 }
595 #endif /*__GNUC__*/
596
597 ostream& ostream::operator<<(double n)
598 {
599     if (opfx()) {
600         _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
601                                   _strbuf);
602         // Uses __cvt_double (renamed from static cvt), in Chris Torek's
603         // stdio implementation.  The setup code uses the same logic
604         // as in __vsbprintf.C (also based on Torek's code).
605         int format_char;
606         if ((flags() & ios::floatfield) == ios::fixed)
607             format_char = 'f';
608         else if ((flags() & ios::floatfield) == ios::scientific)
609             format_char = flags() & ios::uppercase ? 'E' : 'e';
610         else
611             format_char = flags() & ios::uppercase ? 'G' : 'g';
612
613         int prec = precision();
614         if (prec <= 0 && !(flags() & ios::fixed))
615           prec = 6; /* default */
616
617         // Do actual conversion.
618 #if _G_HAVE_PRINTF_FP
619         {
620           struct printf_info info = { prec: prec,
621                                       width: width(0),
622                                       spec: format_char,
623                                       is_long_double: 0,
624                                       is_short: 0,
625                                       is_long: 0,
626                                       alt: (flags() & ios::showpoint) != 0,
627                                       space: 0,
628                                       left: (flags() & ios::left) != 0,
629                                       showsign: (flags() & ios::showpos) != 0,
630                                       group: 0,
631                                       pad: fill()
632 #if defined __GLIBC__ && __GLIBC__ >= 2
633                                       , extra: 0
634 #endif
635           };
636           const void *ptr = (const void *) &n;
637           if (__printf_fp (rdbuf(), &info, &ptr) < 0)
638             set(ios::badbit|ios::failbit);
639         }
640 #elif defined  _IO_USE_DTOA
641         if (_IO_outfloat(n, rdbuf(), format_char, width(0),
642                          prec, flags(),
643                          flags() & ios::showpos ? '+' : 0,
644                          fill()) < 0)
645             set(ios::badbit|ios::failbit); // ??
646 #else
647         int fpprec = 0; // 'Extra' (suppressed) floating precision.
648         if (prec > MAXFRACT) {
649             if (flags() & (ios::fixed|ios::scientific) & ios::showpos)
650                 fpprec = prec - MAXFRACT;
651             prec = MAXFRACT;
652         }
653         int negative;
654         char buf[BUF];
655         int sign = '\0';
656         char *cp = buf;
657         *cp = 0;
658         int size = __cvt_double(n, prec,
659                                 flags() & ios::showpoint ? 0x80 : 0,
660                                 &negative,
661                                 format_char, cp, buf + sizeof(buf));
662         if (negative) sign = '-';
663         else if (flags() & ios::showpos) sign = '+';
664         if (*cp == 0)
665             cp++;
666
667         // Calculate padding.
668         int fieldsize = size + fpprec;
669         if (sign) fieldsize++;
670         int padding = 0;
671         int w = width(0);
672         if (fieldsize < w)
673             padding = w - fieldsize;
674
675         // Do actual output.
676         register streambuf* sbuf = rdbuf();
677         register i;
678         char fill_char = fill();
679         ios::fmtflags pad_kind =
680             flags() & (ios::left|ios::right|ios::internal);
681         if (pad_kind != (ios::fmtflags)ios::left // Default (right) adjust.
682             && pad_kind != (ios::fmtflags)ios::internal)
683             for (i = padding; --i >= 0; ) sbuf->sputc(fill_char);
684         if (sign)
685             sbuf->sputc(sign);
686         if (pad_kind == (ios::fmtflags)ios::internal)
687             for (i = padding; --i >= 0; ) sbuf->sputc(fill_char);
688
689         // Emit the actual concented field, followed by extra zeros.
690         _IO_sputn (sbuf, cp, size);
691         for (i = fpprec; --i >= 0; ) sbuf->sputc('0');
692
693         if (pad_kind == (ios::fmtflags)ios::left) // Left adjustment
694             for (i = padding; --i >= 0; ) sbuf->sputc(fill_char);
695 #endif
696         osfx();
697         _IO_cleanup_region_end (0);
698     }
699     return *this;
700 }
701
702 #if _G_HAVE_LONG_DOUBLE_IO
703 ostream& ostream::operator<<(long double n)
704 {
705   if (opfx())
706     {
707       _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
708                                 _strbuf);
709       int format_char;
710       if ((flags() & ios::floatfield) == ios::fixed)
711         format_char = 'f';
712       else if ((flags() & ios::floatfield) == ios::scientific)
713         format_char = flags() & ios::uppercase ? 'E' : 'e';
714       else
715         format_char = flags() & ios::uppercase ? 'G' : 'g';
716
717       int prec = precision();
718       if (prec <= 0 && !(flags() & ios::fixed))
719         prec = 6; /* default */
720
721 #if _G_HAVE_PRINTF_FP
722       // Do actual conversion.
723       struct printf_info info = { prec: prec,
724                                   width: width(0),
725                                   spec: format_char,
726                                   is_long_double: 1,
727                                   is_short: 0,
728                                   is_long: 0,
729                                   alt: (flags() & ios::showpoint) != 0,
730                                   space: 0,
731                                   left: (flags() & ios::left) != 0,
732                                   showsign: (flags() & ios::showpos) != 0,
733                                   group: 0,
734                                   pad: fill()
735 #if defined __GLIBC__ && __GLIBC__ >= 2
736                                   , extra: 0
737 #endif
738       };
739
740       const void *ptr = (const void *) &n;
741
742       if (__printf_fp (rdbuf(), &info, &ptr) < 0)
743         set (ios::badbit|ios::failbit);
744 #else
745 # error "long double I/O using dtoa or cvt_double is not implemented"
746 #endif
747       osfx();
748       _IO_cleanup_region_end (0);
749     }
750   return *this;
751 }
752 #endif
753
754 ostream& ostream::operator<<(const char *s)
755 {
756   if (opfx())
757     {
758       _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
759                                 _strbuf);
760       if (s == NULL)
761         s = "(null)";
762       int len = strlen(s);
763       int w = width(0);
764 // FIXME: Should we: if (w && len>w) len = w;
765       char fill_char = fill();
766       register streambuf *sbuf = rdbuf();
767       register int padding = w > len ? w - len : 0;
768       if (!(flags() & ios::left) && padding > 0) // Default adjustment.
769         if (_IO_padn(sbuf, fill_char, padding) != padding)
770           {
771             set(ios::badbit);
772             goto failed;
773           }
774       if (_IO_sputn (sbuf, s, len) != len)
775         {
776           set(ios::badbit);
777           goto failed;
778         }
779       if (flags() & ios::left && padding > 0) // Left adjustment.
780         if (_IO_padn(sbuf, fill_char, padding) != padding)
781           set(ios::badbit);
782       osfx();
783      failed:
784       _IO_cleanup_region_end (0);
785     }
786   return *this;
787 }
788
789 #if 0
790 ostream& ostream::operator<<(const void *p)
791 { Is in osform.cc, to avoid pulling in all of _IO_vfprintf by this file. */ }
792 #endif
793
794 ostream& ostream::operator<<(register streambuf* sbuf)
795 {
796   if (opfx())
797     {
798       _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
799                                 _strbuf);
800       char buffer[_IO_BUFSIZ];
801       register streambuf* outbuf = _strbuf;
802       for (;;)
803         {
804           _IO_size_t count = _IO_sgetn(sbuf, buffer, _IO_BUFSIZ);
805           if (count <= 0)
806             break;
807           if (_IO_sputn(outbuf, buffer, count) != count)
808             {
809               set(ios::badbit);
810               break;
811             }
812         }
813       osfx();
814       _IO_cleanup_region_end (0);
815     }
816   return *this;
817 }
818
819 ostream::ostream(streambuf* sb, ostream* tied)
820 {
821   init (sb, tied);
822 }
823
824 ostream& ostream::seekp(streampos pos)
825 {
826     pos = _strbuf->pubseekpos(pos, ios::out);
827     if (pos == streampos(EOF))
828         set(ios::badbit);
829     return *this;
830 }
831
832 ostream& ostream::seekp(streamoff off, _seek_dir dir)
833 {
834   streampos pos = _IO_seekoff (_strbuf, off, (int) dir, _IOS_OUTPUT);
835   if (pos == streampos(EOF))
836     set(ios::badbit);
837   return *this;
838 }
839
840 streampos ostream::tellp()
841 {
842 #if 1
843     streampos pos = _IO_seekoff (_strbuf, 0, _IO_seek_cur, _IOS_OUTPUT);
844 #else
845     streampos pos = _strbuf->pubseekoff(0, ios::cur, ios::out);
846 #endif
847     if (pos == streampos(EOF))
848         set(ios::badbit);
849     return pos;
850 }
851
852 ostream& ostream::flush()
853 {
854     if (_strbuf->sync())
855         set(ios::badbit);
856     return *this;
857 }
858
859 ostream& flush(ostream& outs)
860 {
861   return outs.flush();
862 }
863
864 istream& ws(istream& ins)
865 {
866     if (ins.ipfx1()) {
867         _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
868                                   ins._strbuf);
869         int ch = skip_ws(ins._strbuf);
870         if (ch == EOF)
871             ins.set(ios::eofbit);
872         else
873             ins._strbuf->sputbackc(ch);
874         ins.isfx();
875         _IO_cleanup_region_end (0);
876     }
877     return ins;
878 }
879
880 // Skip white-space.  Return 0 on failure (EOF), or 1 on success.
881 // Differs from ws() manipulator in that failbit is set on EOF.
882 // Called by ipfx() and ipfx0() if needed.
883
884 int istream::_skip_ws()
885 {
886     int ch = skip_ws(_strbuf);
887     if (ch == EOF) {
888         set(ios::eofbit|ios::failbit);
889         return 0;
890     }
891     else {
892         _strbuf->sputbackc(ch);
893         return 1;
894     }
895 }
896
897 ostream& ends(ostream& outs)
898 {
899     outs.put('\0');
900     return outs;
901 }
902
903 ostream& endl(ostream& outs)
904 {
905     return flush(outs.put('\n'));
906 }
907
908 istream& lock(istream& ins)
909 {
910   _IO_flockfile (ins._strbuf);
911   return ins;
912 }
913 istream& unlock(istream& ins)
914 {
915   _IO_funlockfile (ins._strbuf);
916   return ins;
917 }
918 ostream& lock(ostream& outs)
919 {
920   _IO_flockfile (outs._strbuf);
921   return outs;
922 }
923 ostream& unlock(ostream& outs)
924 {
925   _IO_funlockfile (outs._strbuf);
926   return outs;
927 }
928
929
930 ostream& ostream::write(const char *s, streamsize n)
931 {
932     if (opfx()) {
933         _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
934                                   _strbuf);
935         if (_IO_sputn(_strbuf, s, n) != n)
936             set(ios::failbit);
937         osfx();
938         _IO_cleanup_region_end (0);
939     }
940     return *this;
941 }
942
943 void ostream::do_osfx()
944 {
945     if (flags() & ios::unitbuf)
946         flush();
947     if (flags() & ios::stdio) {
948         fflush(stdout);
949         fflush(stderr);
950     }
951 }
952
953 iostream::iostream(streambuf* sb, ostream* tied)
954 {
955   init (sb, tied);
956 }
957
958 // NOTE: extension for compatibility with old libg++.
959 // Not really compatible with fistream::close().
960 #ifdef _STREAM_COMPAT
961 void ios::close()
962 {
963   if (_strbuf->_flags & _IO_IS_FILEBUF)
964     ((struct filebuf*)rdbuf())->close();
965   else if (_strbuf != NULL)
966     rdbuf()->sync();
967   _strbuf = NULL;
968   _state = badbit;
969 }
970
971 int istream::skip(int i)
972 {
973     int old = (_flags & ios::skipws) != 0;
974     if (i)
975         _flags |= ios::skipws;
976     else
977         _flags &= ~ios::skipws;
978     return old;
979 }
980 #endif