* rs6000.c (output_function_profiler): Put label address in r0, and
[official-gcc.git] / libio / iostream.cc
blobf4b1e167ddede93337f72f3592c4c54f327e19de
1 /* This is part of libio/iostream, providing -*- C++ -*- input/output.
2 Copyright (C) 1993, 1997 Free Software Foundation, Inc.
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.
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.
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.
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. */
26 /* Written by Per Bothner (bothner@cygnus.com). */
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>
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
51 #define BUF (MAXEXP+MAXFRACT+1) /* + decimal point */
53 //#define isspace(ch) ((ch)==' ' || (ch)=='\t' || (ch)=='\n')
55 istream::istream(streambuf *sb, ostream* tied)
57 init (sb, tied);
58 _gcount = 0;
61 int skip_ws(streambuf* sb)
63 int ch;
64 for (;;) {
65 ch = sb->sbumpc();
66 if (ch == EOF || !isspace(ch))
67 return ch;
71 istream& istream::get(char& c)
73 if (ipfx1()) {
74 int ch = _strbuf->sbumpc();
75 if (ch == EOF) {
76 set(ios::eofbit|ios::failbit);
77 _gcount = 0;
79 else {
80 c = (char)ch;
81 _gcount = 1;
84 else
85 _gcount = 0;
86 return *this;
89 int istream::peek()
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;
101 istream& istream::ignore(int n /* = 1 */, int delim /* = EOF */)
103 _gcount = 0;
104 if (ipfx1()) {
105 register streambuf* sb = _strbuf;
106 if (delim == EOF) {
107 _gcount = sb->ignore(n);
108 return *this;
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;
121 _gcount++;
122 if (ch == delim)
123 break;
126 return *this;
129 istream& istream::read(char *s, streamsize n)
131 if (ipfx1()) {
132 _gcount = _strbuf->sgetn(s, n);
133 if (_gcount != n)
134 set(ios::failbit|ios::eofbit);
136 else
137 _gcount = 0;
138 return *this;
142 istream::sync ()
144 streambuf *sb = rdbuf ();
145 if (sb == NULL)
146 return EOF;
147 if (sb->sync ()) // Later: pubsync
149 setstate (ios::badbit);
150 return EOF;
152 else
153 return 0;
156 istream& istream::seekg(streampos pos)
158 pos = _strbuf->pubseekpos(pos, ios::in);
159 if (pos == streampos(EOF))
160 set(ios::badbit);
161 return *this;
164 istream& istream::seekg(streamoff off, _seek_dir dir)
166 streampos pos = _IO_seekoff (_strbuf, off, (int) dir, _IOS_INPUT);
167 if (pos == streampos(EOF))
168 set(ios::badbit);
169 return *this;
172 streampos istream::tellg()
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;
184 istream& istream::operator>>(char& c)
186 if (ipfx0()) {
187 int ch = _strbuf->sbumpc();
188 if (ch == EOF)
189 set(ios::eofbit|ios::failbit);
190 else
191 c = (char)ch;
193 return *this;
196 istream&
197 istream::operator>> (char* ptr)
199 register char *p = ptr;
200 int w = width(0);
201 if (ipfx0())
203 register streambuf* sb = _strbuf;
204 for (;;)
206 int ch = sb->sbumpc();
207 if (ch == EOF)
209 set(ios::eofbit);
210 break;
212 else if (isspace(ch) || w == 1)
214 sb->sputbackc(ch);
215 break;
217 else *p++ = ch;
218 w--;
220 if (p == ptr)
221 set(ios::failbit);
223 *p = '\0';
224 return *this;
227 #if defined(__GNUC__) && !defined(__STRICT_ANSI__)
228 #define LONGEST long long
229 #else
230 #define LONGEST long
231 #endif
233 static int read_int(istream& stream, unsigned LONGEST& val, int& neg)
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);
247 else if (ch == '-') {
248 neg = 1;
249 ch = skip_ws(sb);
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;
259 if (ch == 'x' || ch == 'X') {
260 base = 16;
261 ch = sb->sbumpc();
262 if (ch == EOF) goto eof_fail;
264 else {
265 sb->sputbackc(ch);
266 base = 8;
267 ch = '0';
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;
295 ndigits++;
296 val = base * val + digit;
297 ch = sb->sbumpc();
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;
308 #define READ_INT(TYPE) \
309 istream& istream::operator>>(TYPE& i)\
311 unsigned LONGEST val; int neg;\
312 if (read_int(*this, val, neg)) {\
313 if (neg) val = -val;\
314 i = (TYPE)val;\
316 return *this;\
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
333 istream& istream::operator>>(long double& x)
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;
344 istream& istream::operator>>(double& x)
346 if (ipfx0())
347 scan("%lg", &x);
348 return *this;
351 istream& istream::operator>>(float& x)
353 if (ipfx0())
354 scan("%g", &x);
355 return *this;
358 istream& istream::operator>>(register streambuf* sbuf)
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;
369 if (sbuf->sputc(ch) == EOF) {
370 set(ios::failbit);
371 break;
375 return *this;
378 ostream& ostream::operator<<(char c)
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;
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;
400 if (sb->sputc(c) == EOF) {
401 set(ios::badbit);
402 goto failed;
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);
412 return *this;
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. */
420 static void write_int(ostream& stream, unsigned LONGEST val, int sign)
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 '+'.
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';
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;
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;
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;
472 int buf_len = buf+WRITE_BUF_SIZE - buf_ptr;
473 int w = stream.width(0);
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;
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)
493 char ch = sign < 0 ? '-' : '+';
494 if (sbuf->sputc(ch) < 0)
495 goto failed;
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();
515 ostream& ostream::operator<<(int n)
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);
527 return *this;
530 ostream& ostream::operator<<(unsigned int n)
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);
538 return *this;
542 ostream& ostream::operator<<(long n)
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);
554 return *this;
557 ostream& ostream::operator<<(unsigned long n)
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);
565 return *this;
568 #if defined(__GNUC__) && !defined(__STRICT_ANSI__)
569 ostream& ostream::operator<<(long long n)
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);
581 return *this;
585 ostream& ostream::operator<<(unsigned long long n)
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);
593 return *this;
595 #endif /*__GNUC__*/
597 ostream& ostream::operator<<(double n)
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';
613 int prec = precision();
614 if (prec <= 0 && !(flags() & ios::fixed))
615 prec = 6; /* default */
617 // Do actual conversion.
618 #if _G_HAVE_PRINTF_FP
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
636 const void *ptr = (const void *) &n;
637 if (__printf_fp (rdbuf(), &info, &ptr) < 0)
638 set(ios::badbit|ios::failbit);
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;
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++;
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;
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);
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');
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);
699 return *this;
702 #if _G_HAVE_LONG_DOUBLE_IO
703 ostream& ostream::operator<<(long double n)
705 if (opfx())
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';
717 int prec = precision();
718 if (prec <= 0 && !(flags() & ios::fixed))
719 prec = 6; /* default */
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
740 const void *ptr = (const void *) &n;
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);
750 return *this;
752 #endif
754 ostream& ostream::operator<<(const char *s)
756 if (opfx())
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)
771 set(ios::badbit);
772 goto failed;
774 if (_IO_sputn (sbuf, s, len) != len)
776 set(ios::badbit);
777 goto failed;
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);
786 return *this;
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
794 ostream& ostream::operator<<(register streambuf* sbuf)
796 if (opfx())
798 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
799 _strbuf);
800 char buffer[_IO_BUFSIZ];
801 register streambuf* outbuf = _strbuf;
802 for (;;)
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)
809 set(ios::badbit);
810 break;
813 osfx();
814 _IO_cleanup_region_end (0);
816 return *this;
819 ostream::ostream(streambuf* sb, ostream* tied)
821 init (sb, tied);
824 ostream& ostream::seekp(streampos pos)
826 pos = _strbuf->pubseekpos(pos, ios::out);
827 if (pos == streampos(EOF))
828 set(ios::badbit);
829 return *this;
832 ostream& ostream::seekp(streamoff off, _seek_dir dir)
834 streampos pos = _IO_seekoff (_strbuf, off, (int) dir, _IOS_OUTPUT);
835 if (pos == streampos(EOF))
836 set(ios::badbit);
837 return *this;
840 streampos ostream::tellp()
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;
852 ostream& ostream::flush()
854 if (_strbuf->sync())
855 set(ios::badbit);
856 return *this;
859 ostream& flush(ostream& outs)
861 return outs.flush();
864 istream& ws(istream& ins)
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);
877 return ins;
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.
884 int istream::_skip_ws()
886 int ch = skip_ws(_strbuf);
887 if (ch == EOF) {
888 set(ios::eofbit|ios::failbit);
889 return 0;
891 else {
892 _strbuf->sputbackc(ch);
893 return 1;
897 ostream& ends(ostream& outs)
899 outs.put('\0');
900 return outs;
903 ostream& endl(ostream& outs)
905 return flush(outs.put('\n'));
908 istream& lock(istream& ins)
910 _IO_flockfile (ins._strbuf);
911 return ins;
913 istream& unlock(istream& ins)
915 _IO_funlockfile (ins._strbuf);
916 return ins;
918 ostream& lock(ostream& outs)
920 _IO_flockfile (outs._strbuf);
921 return outs;
923 ostream& unlock(ostream& outs)
925 _IO_funlockfile (outs._strbuf);
926 return outs;
930 ostream& ostream::write(const char *s, streamsize n)
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);
940 return *this;
943 void ostream::do_osfx()
945 if (flags() & ios::unitbuf)
946 flush();
947 if (flags() & ios::stdio) {
948 fflush(stdout);
949 fflush(stderr);
953 iostream::iostream(streambuf* sb, ostream* tied)
955 init (sb, tied);
958 // NOTE: extension for compatibility with old libg++.
959 // Not really compatible with fistream::close().
960 #ifdef _STREAM_COMPAT
961 void ios::close()
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;
971 int istream::skip(int i)
973 int old = (_flags & ios::skipws) != 0;
974 if (i)
975 _flags |= ios::skipws;
976 else
977 _flags &= ~ios::skipws;
978 return old;
980 #endif