* tree.c (make_lang_type_fn): New funtion pointer.
[official-gcc.git] / libio / iostream.cc
blob4b75fca764dd25782addb95b64fcc16b5ebca23d
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 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
75 _strbuf);
76 int ch = _strbuf->sbumpc();
77 if (ch == EOF) {
78 set(ios::eofbit|ios::failbit);
79 _gcount = 0;
81 else {
82 c = (char)ch;
83 _gcount = 1;
85 isfx();
86 _IO_cleanup_region_end (0);
88 else
89 _gcount = 0;
90 return *this;
93 int istream::peek()
95 if (!good())
96 return EOF;
97 if (_tie && rdbuf()->in_avail() == 0)
98 _tie->flush();
99 int ch = _strbuf->sgetc();
100 if (ch == EOF)
101 set(ios::eofbit);
102 return ch;
105 istream& istream::ignore(int n /* = 1 */, int delim /* = EOF */)
107 _gcount = 0;
108 if (ipfx1()) {
109 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
110 _strbuf);
111 register streambuf* sb = _strbuf;
112 if (delim == EOF) {
113 _gcount = sb->ignore(n);
114 goto unlock;
116 for (;;) {
117 #if 0
118 if (n != MAXINT) // FIXME
119 #endif
120 if (--n < 0)
121 break;
122 int ch = sb->sbumpc();
123 if (ch == EOF) {
124 set(ios::eofbit|ios::failbit);
125 break;
127 _gcount++;
128 if (ch == delim)
129 break;
131 unlock:
132 isfx();
133 _IO_cleanup_region_end (0);
135 return *this;
138 istream& istream::read(char *s, streamsize n)
140 if (ipfx1()) {
141 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
142 _strbuf);
143 _gcount = _strbuf->sgetn(s, n);
144 if (_gcount != n)
145 set(ios::failbit|ios::eofbit);
146 isfx();
147 _IO_cleanup_region_end (0);
149 else
150 _gcount = 0;
151 return *this;
155 istream::sync ()
157 streambuf *sb = rdbuf ();
158 if (sb == NULL)
159 return EOF;
160 if (sb->sync ()) // Later: pubsync
162 setstate (ios::badbit);
163 return EOF;
165 else
166 return 0;
169 istream& istream::seekg(streampos pos)
171 pos = _strbuf->pubseekpos(pos, ios::in);
172 if (pos == streampos(EOF))
173 set(ios::badbit);
174 return *this;
177 istream& istream::seekg(streamoff off, _seek_dir dir)
179 streampos pos = _IO_seekoff (_strbuf, off, (int) dir, _IOS_INPUT);
180 if (pos == streampos(EOF))
181 set(ios::badbit);
182 return *this;
185 streampos istream::tellg()
187 #if 0
188 streampos pos = _strbuf->pubseekoff(0, ios::cur, ios::in);
189 #else
190 streampos pos = _IO_seekoff (_strbuf, 0, _IO_seek_cur, _IOS_INPUT);
191 #endif
192 if (pos == streampos(EOF))
193 set(ios::badbit);
194 return pos;
197 istream& istream::operator>>(char& c)
199 if (ipfx0()) {
200 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
201 _strbuf);
202 int ch = _strbuf->sbumpc();
203 if (ch == EOF)
204 set(ios::eofbit|ios::failbit);
205 else
206 c = (char)ch;
207 isfx();
208 _IO_cleanup_region_end (0);
210 return *this;
213 istream&
214 istream::operator>> (char* ptr)
216 register char *p = ptr;
217 int w = width(0);
218 if (ipfx0())
220 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
221 _strbuf);
222 register streambuf* sb = _strbuf;
223 for (;;)
225 int ch = sb->sbumpc();
226 if (ch == EOF)
228 set(ios::eofbit);
229 break;
231 else if (isspace(ch) || w == 1)
233 sb->sputbackc(ch);
234 break;
236 else *p++ = ch;
237 w--;
239 if (p == ptr)
240 set(ios::failbit);
241 isfx();
242 _IO_cleanup_region_end (0);
244 *p = '\0';
245 return *this;
248 #if defined(__GNUC__) && !defined(__STRICT_ANSI__)
249 #define LONGEST long long
250 #else
251 #define LONGEST long
252 #endif
254 static int read_int(istream& stream, unsigned LONGEST& val, int& neg)
256 if (!stream.ipfx0())
257 return 0;
258 int retval;
259 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
260 stream._strbuf);
261 register streambuf* sb = stream.rdbuf();
262 int base = 10;
263 int ndigits = 0;
264 register int ch = skip_ws(sb);
265 if (ch == EOF)
266 goto eof_fail;
267 neg = 0;
268 if (ch == '+') {
269 ch = skip_ws(sb);
271 else if (ch == '-') {
272 neg = 1;
273 ch = skip_ws(sb);
275 if (ch == EOF) goto eof_fail;
276 if (!(stream.flags() & ios::basefield)) {
277 if (ch == '0') {
278 ch = sb->sbumpc();
279 if (ch == EOF) {
280 val = 0;
281 goto unlock;
283 if (ch == 'x' || ch == 'X') {
284 base = 16;
285 ch = sb->sbumpc();
286 if (ch == EOF) goto eof_fail;
288 else {
289 sb->sputbackc(ch);
290 base = 8;
291 ch = '0';
295 else if ((stream.flags() & ios::basefield) == ios::hex)
296 base = 16;
297 else if ((stream.flags() & ios::basefield) == ios::oct)
298 base = 8;
299 val = 0;
300 for (;;) {
301 if (ch == EOF)
302 break;
303 int digit;
304 if (ch >= '0' && ch <= '9')
305 digit = ch - '0';
306 else if (ch >= 'A' && ch <= 'F')
307 digit = ch - 'A' + 10;
308 else if (ch >= 'a' && ch <= 'f')
309 digit = ch - 'a' + 10;
310 else
311 digit = 999;
312 if (digit >= base) {
313 sb->sputbackc(ch);
314 if (ndigits == 0)
315 goto fail;
316 else
317 goto unlock;
319 ndigits++;
320 val = base * val + digit;
321 ch = sb->sbumpc();
323 unlock:
324 retval = 1;
325 goto out;
326 fail:
327 stream.set(ios::failbit);
328 retval = 0;
329 goto out;
330 eof_fail:
331 stream.set(ios::failbit|ios::eofbit);
332 retval = 0;
333 out:
334 stream.isfx();
335 _IO_cleanup_region_end (0);
336 return retval;
339 #define READ_INT(TYPE) \
340 istream& istream::operator>>(TYPE& i)\
342 unsigned LONGEST val; int neg;\
343 if (read_int(*this, val, neg)) {\
344 if (neg) val = -val;\
345 i = (TYPE)val;\
347 return *this;\
350 READ_INT(short)
351 READ_INT(unsigned short)
352 READ_INT(int)
353 READ_INT(unsigned int)
354 READ_INT(long)
355 READ_INT(unsigned long)
356 #if defined(__GNUC__) && !defined(__STRICT_ANSI__)
357 READ_INT(long long)
358 READ_INT(unsigned long long)
359 #endif
360 #if _G_HAVE_BOOL
361 READ_INT(bool)
362 #endif
364 istream& istream::operator>>(long double& x)
366 if (ipfx0())
368 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
369 _strbuf);
370 #if _G_HAVE_LONG_DOUBLE_IO
371 scan("%Lg", &x);
372 #else
373 double y;
374 scan("%lg", &y);
375 x = y;
376 #endif
377 isfx();
378 _IO_cleanup_region_end (0);
380 return *this;
383 istream& istream::operator>>(double& x)
385 if (ipfx0())
387 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
388 _strbuf);
389 scan("%lg", &x);
390 isfx();
391 _IO_cleanup_region_end (0);
393 return *this;
396 istream& istream::operator>>(float& x)
398 if (ipfx0())
400 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
401 _strbuf);
402 scan("%g", &x);
403 isfx();
404 _IO_cleanup_region_end (0);
406 return *this;
409 istream& istream::operator>>(register streambuf* sbuf)
411 if (ipfx0()) {
412 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
413 _strbuf);
414 register streambuf* inbuf = rdbuf();
415 // FIXME: Should optimize!
416 for (;;) {
417 register int ch = inbuf->sbumpc();
418 if (ch == EOF) {
419 set(ios::eofbit);
420 break;
422 if (sbuf->sputc(ch) == EOF) {
423 set(ios::failbit);
424 break;
427 isfx();
428 _IO_cleanup_region_end (0);
430 return *this;
433 ostream& ostream::operator<<(char c)
435 if (opfx()) {
436 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
437 _strbuf);
438 #if 1
439 // This is what the cfront implementation does.
440 if (_strbuf->sputc(c) == EOF) {
441 set(ios::badbit);
442 goto failed;
444 #else
445 // This is what cfront documentation and current ANSI drafts say.
446 int w = width(0);
447 char fill_char = fill();
448 register int padding = w > 0 ? w - 1 : 0;
449 register streambuf *sb = _strbuf;
450 if (!(flags() & ios::left) && padding) // Default adjustment.
451 if (_IO_padn(sb, fill_char, padding) < padding) {
452 set(ios::badbit);
453 goto failed;
455 if (sb->sputc(c) == EOF) {
456 set(ios::badbit);
457 goto failed;
459 if (flags() & ios::left && padding) // Left adjustment.
460 if (_IO_padn(sb, fill_char, padding) < padding)
461 set(ios::badbit);
462 #endif
463 failed:
464 osfx();
465 _IO_cleanup_region_end (0);
467 return *this;
470 /* Write VAL on STREAM.
471 If SIGN<0, val is the absolute value of a negative number.
472 If SIGN>0, val is a signed non-negative number.
473 If SIGN==0, val is unsigned. */
475 static void write_int(ostream& stream, unsigned LONGEST val, int sign)
477 #define WRITE_BUF_SIZE (10 + sizeof(unsigned LONGEST) * 3)
478 char buf[WRITE_BUF_SIZE];
479 register char *buf_ptr = buf+WRITE_BUF_SIZE; // End of buf.
480 const char *show_base = "";
481 int show_base_len = 0;
482 int show_pos = 0; // If 1, print a '+'.
484 // Now do the actual conversion, placing the result at the *end* of buf.
485 // Note that we use separate code for decimal, octal, and hex,
486 // so we can divide by optimizable constants.
487 if ((stream.flags() & ios::basefield) == ios::oct) { // Octal
488 do {
489 *--buf_ptr = (val & 7) + '0';
490 val = val >> 3;
491 } while (val != 0);
492 if ((stream.flags() & ios::showbase) && (*buf_ptr != '0'))
493 *--buf_ptr = '0';
495 else if ((stream.flags() & ios::basefield) == ios::hex) { // Hex
496 const char *xdigs = (stream.flags() & ios::uppercase) ? "0123456789ABCDEF0X"
497 : "0123456789abcdef0x";
498 do {
499 *--buf_ptr = xdigs[val & 15];
500 val = val >> 4;
501 } while (val != 0);
502 if ((stream.flags() & ios::showbase)) {
503 show_base = xdigs + 16; // Either "0X" or "0x".
504 show_base_len = 2;
507 else { // Decimal
508 #if defined(__GNUC__) && !defined(__STRICT_ANSI__)
509 // Optimization: Only use long long when we need to.
510 while (val > UINT_MAX) {
511 *--buf_ptr = (val % 10) + '0';
512 val /= 10;
514 // Use more efficient (int) arithmetic for the rest.
515 register unsigned int ival = (unsigned int)val;
516 #else
517 register unsigned LONGEST ival = val;
518 #endif
519 do {
520 *--buf_ptr = (ival % 10) + '0';
521 ival /= 10;
522 } while (ival != 0);
523 if (sign > 0 && (stream.flags() & ios::showpos))
524 show_pos=1;
527 int buf_len = buf+WRITE_BUF_SIZE - buf_ptr;
528 int w = stream.width(0);
530 // Calculate padding.
531 int len = buf_len+show_pos;
532 if (sign < 0) len++;
533 len += show_base_len;
534 int padding = len > w ? 0 : w - len;
536 // Do actual output.
537 register streambuf* sbuf = stream.rdbuf();
538 ios::fmtflags pad_kind =
539 stream.flags() & (ios::left|ios::right|ios::internal);
540 char fill_char = stream.fill();
541 if (padding > 0
542 && pad_kind != (ios::fmtflags)ios::left
543 && pad_kind != (ios::fmtflags)ios::internal) // Default (right) adjust.
544 if (_IO_padn(sbuf, fill_char, padding) < padding)
545 goto failed;
546 if (sign < 0 || show_pos)
548 char ch = sign < 0 ? '-' : '+';
549 if (sbuf->sputc(ch) < 0)
550 goto failed;
552 if (show_base_len)
553 if (_IO_sputn(sbuf, show_base, show_base_len) <= 0)
554 goto failed;
555 if (pad_kind == (ios::fmtflags)ios::internal && padding > 0)
556 if (_IO_padn(sbuf, fill_char, padding) < padding)
557 goto failed;
558 if (_IO_sputn (sbuf, buf_ptr, buf_len) != buf_len)
559 goto failed;
560 if (pad_kind == (ios::fmtflags)ios::left && padding > 0) // Left adjustment
561 if (_IO_padn(sbuf, fill_char, padding) < padding)
562 goto failed;
563 stream.osfx();
564 return;
565 failed:
566 stream.set(ios::badbit);
567 stream.osfx();
570 ostream& ostream::operator<<(int n)
572 if (opfx()) {
573 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
574 _strbuf);
575 int sign = 1;
576 unsigned int abs_n = (unsigned)n;
577 if (n < 0 && (flags() & (ios::oct|ios::hex)) == 0)
578 abs_n = -((unsigned)n), sign = -1;
579 write_int(*this, abs_n, sign);
580 _IO_cleanup_region_end (0);
582 return *this;
585 ostream& ostream::operator<<(unsigned int 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;
597 ostream& ostream::operator<<(long n)
599 if (opfx()) {
600 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
601 _strbuf);
602 int sign = 1;
603 unsigned long abs_n = (unsigned long)n;
604 if (n < 0 && (flags() & (ios::oct|ios::hex)) == 0)
605 abs_n = -((unsigned long)n), sign = -1;
606 write_int(*this, abs_n, sign);
607 _IO_cleanup_region_end (0);
609 return *this;
612 ostream& ostream::operator<<(unsigned long n)
614 if (opfx()) {
615 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
616 _strbuf);
617 write_int(*this, n, 0);
618 _IO_cleanup_region_end (0);
620 return *this;
623 #if defined(__GNUC__) && !defined(__STRICT_ANSI__)
624 ostream& ostream::operator<<(long long n)
626 if (opfx()) {
627 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
628 _strbuf);
629 int sign = 1;
630 unsigned long long abs_n = (unsigned long long)n;
631 if (n < 0 && (flags() & (ios::oct|ios::hex)) == 0)
632 abs_n = -((unsigned long long)n), sign = -1;
633 write_int(*this, abs_n, sign);
634 _IO_cleanup_region_end (0);
636 return *this;
640 ostream& ostream::operator<<(unsigned long long n)
642 if (opfx()) {
643 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
644 _strbuf);
645 write_int(*this, n, 0);
646 _IO_cleanup_region_end (0);
648 return *this;
650 #endif /*__GNUC__*/
652 ostream& ostream::operator<<(double n)
654 if (opfx()) {
655 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
656 _strbuf);
657 // Uses __cvt_double (renamed from static cvt), in Chris Torek's
658 // stdio implementation. The setup code uses the same logic
659 // as in __vsbprintf.C (also based on Torek's code).
660 int format_char;
661 if ((flags() & ios::floatfield) == ios::fixed)
662 format_char = 'f';
663 else if ((flags() & ios::floatfield) == ios::scientific)
664 format_char = flags() & ios::uppercase ? 'E' : 'e';
665 else
666 format_char = flags() & ios::uppercase ? 'G' : 'g';
668 int prec = precision();
669 if (prec <= 0 && !(flags() & ios::fixed))
670 prec = 6; /* default */
672 // Do actual conversion.
673 #if _G_HAVE_PRINTF_FP
675 struct printf_info info = { /* prec: */ prec,
676 /* width: */ width(0),
677 /* spec: */ format_char,
678 /* is_long_double: */ 0,
679 /* is_short: */ 0,
680 /* is_long: */ 0,
681 /* alt: */ (flags() & ios::showpoint) != 0,
682 /* space: */ 0,
683 /* left: */ (flags() & ios::left) != 0,
684 /* showsign: */ (flags() & ios::showpos) != 0,
685 /* group: */ 0,
686 #if defined __GLIBC__ && __GLIBC__ >= 2
687 /* extra: */ 0,
688 #if __GLIBC_MINOR__ >= 1
689 /* is_char: */ 0,
690 #endif
691 #endif
692 /* pad: */ fill()
694 const void *ptr = (const void *) &n;
695 if (__printf_fp (rdbuf(), &info, &ptr) < 0)
696 set(ios::badbit|ios::failbit);
698 #elif defined _IO_USE_DTOA
699 if (_IO_outfloat(n, rdbuf(), format_char, width(0),
700 prec, flags(),
701 flags() & ios::showpos ? '+' : 0,
702 fill()) < 0)
703 set(ios::badbit|ios::failbit); // ??
704 #else
705 int fpprec = 0; // 'Extra' (suppressed) floating precision.
706 if (prec > MAXFRACT) {
707 if (flags() & (ios::fixed|ios::scientific) & ios::showpos)
708 fpprec = prec - MAXFRACT;
709 prec = MAXFRACT;
711 int negative;
712 char buf[BUF];
713 int sign = '\0';
714 char *cp = buf;
715 *cp = 0;
716 int size = __cvt_double(n, prec,
717 flags() & ios::showpoint ? 0x80 : 0,
718 &negative,
719 format_char, cp, buf + sizeof(buf));
720 if (negative) sign = '-';
721 else if (flags() & ios::showpos) sign = '+';
722 if (*cp == 0)
723 cp++;
725 // Calculate padding.
726 int fieldsize = size + fpprec;
727 if (sign) fieldsize++;
728 int padding = 0;
729 int w = width(0);
730 if (fieldsize < w)
731 padding = w - fieldsize;
733 // Do actual output.
734 register streambuf* sbuf = rdbuf();
735 register i;
736 char fill_char = fill();
737 ios::fmtflags pad_kind =
738 flags() & (ios::left|ios::right|ios::internal);
739 if (pad_kind != (ios::fmtflags)ios::left // Default (right) adjust.
740 && pad_kind != (ios::fmtflags)ios::internal)
741 for (i = padding; --i >= 0; ) sbuf->sputc(fill_char);
742 if (sign)
743 sbuf->sputc(sign);
744 if (pad_kind == (ios::fmtflags)ios::internal)
745 for (i = padding; --i >= 0; ) sbuf->sputc(fill_char);
747 // Emit the actual concented field, followed by extra zeros.
748 _IO_sputn (sbuf, cp, size);
749 for (i = fpprec; --i >= 0; ) sbuf->sputc('0');
751 if (pad_kind == (ios::fmtflags)ios::left) // Left adjustment
752 for (i = padding; --i >= 0; ) sbuf->sputc(fill_char);
753 #endif
754 osfx();
755 _IO_cleanup_region_end (0);
757 return *this;
760 #if _G_HAVE_LONG_DOUBLE_IO
761 ostream& ostream::operator<<(long double n)
763 if (opfx())
765 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
766 _strbuf);
767 int format_char;
768 if ((flags() & ios::floatfield) == ios::fixed)
769 format_char = 'f';
770 else if ((flags() & ios::floatfield) == ios::scientific)
771 format_char = flags() & ios::uppercase ? 'E' : 'e';
772 else
773 format_char = flags() & ios::uppercase ? 'G' : 'g';
775 int prec = precision();
776 if (prec <= 0 && !(flags() & ios::fixed))
777 prec = 6; /* default */
779 #if _G_HAVE_PRINTF_FP
780 // Do actual conversion.
781 struct printf_info info = { /* prec: */ prec,
782 /* width: */ width(0),
783 /* spec: */ format_char,
784 /* is_long_double: */ 1,
785 /* is_short: */ 0,
786 /* is_long: */ 0,
787 /* alt: */ (flags() & ios::showpoint) != 0,
788 /* space: */ 0,
789 /* left: */ (flags() & ios::left) != 0,
790 /* showsign: */ (flags() & ios::showpos) != 0,
791 /* group: */ 0,
792 #if defined __GLIBC__ && __GLIBC__ >= 2
793 /* extra: */ 0,
794 #if __GLIBC_MINOR__ >= 1
795 /* is_char: */ 0,
796 #endif
797 #endif
798 /* pad: */ fill()
801 const void *ptr = (const void *) &n;
803 if (__printf_fp (rdbuf(), &info, &ptr) < 0)
804 set (ios::badbit|ios::failbit);
805 #else
806 # error "long double I/O using dtoa or cvt_double is not implemented"
807 #endif
808 osfx();
809 _IO_cleanup_region_end (0);
811 return *this;
813 #endif
815 ostream& ostream::operator<<(const char *s)
817 if (opfx())
819 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
820 _strbuf);
821 if (s == NULL)
822 s = "(null)";
823 int len = strlen(s);
824 int w = width(0);
825 // FIXME: Should we: if (w && len>w) len = w;
826 char fill_char = fill();
827 register streambuf *sbuf = rdbuf();
828 register int padding = w > len ? w - len : 0;
829 if (!(flags() & ios::left) && padding > 0) // Default adjustment.
830 if (_IO_padn(sbuf, fill_char, padding) != padding)
832 set(ios::badbit);
833 goto failed;
835 if (_IO_sputn (sbuf, s, len) != len)
837 set(ios::badbit);
838 goto failed;
840 if (flags() & ios::left && padding > 0) // Left adjustment.
841 if (_IO_padn(sbuf, fill_char, padding) != padding)
842 set(ios::badbit);
843 failed:
844 osfx();
845 _IO_cleanup_region_end (0);
847 return *this;
850 #if 0
851 ostream& ostream::operator<<(const void *p)
852 { Is in osform.cc, to avoid pulling in all of _IO_vfprintf by this file. */ }
853 #endif
855 ostream& ostream::operator<<(register streambuf* sbuf)
857 if (opfx())
859 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
860 _strbuf);
861 char buffer[_IO_BUFSIZ];
862 register streambuf* outbuf = _strbuf;
863 for (;;)
865 _IO_size_t count = _IO_sgetn(sbuf, buffer, _IO_BUFSIZ);
866 if (count <= 0)
867 break;
868 if (_IO_sputn(outbuf, buffer, count) != count)
870 set(ios::badbit);
871 break;
874 osfx();
875 _IO_cleanup_region_end (0);
877 return *this;
880 ostream::ostream(streambuf* sb, ostream* tied)
882 init (sb, tied);
885 ostream& ostream::seekp(streampos pos)
887 pos = _strbuf->pubseekpos(pos, ios::out);
888 if (pos == streampos(EOF))
889 set(ios::badbit);
890 return *this;
893 ostream& ostream::seekp(streamoff off, _seek_dir dir)
895 streampos pos = _IO_seekoff (_strbuf, off, (int) dir, _IOS_OUTPUT);
896 if (pos == streampos(EOF))
897 set(ios::badbit);
898 return *this;
901 streampos ostream::tellp()
903 #if 1
904 streampos pos = _IO_seekoff (_strbuf, 0, _IO_seek_cur, _IOS_OUTPUT);
905 #else
906 streampos pos = _strbuf->pubseekoff(0, ios::cur, ios::out);
907 #endif
908 if (pos == streampos(EOF))
909 set(ios::badbit);
910 return pos;
913 ostream& ostream::flush()
915 if (_strbuf->sync())
916 set(ios::badbit);
917 return *this;
920 ostream& flush(ostream& outs)
922 return outs.flush();
925 istream& ws(istream& ins)
927 if (ins.ipfx1()) {
928 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
929 ins._strbuf);
930 int ch = skip_ws(ins._strbuf);
931 if (ch == EOF)
932 ins.set(ios::eofbit);
933 else
934 ins._strbuf->sputbackc(ch);
935 ins.isfx();
936 _IO_cleanup_region_end (0);
938 return ins;
941 // Skip white-space. Return 0 on failure (EOF), or 1 on success.
942 // Differs from ws() manipulator in that failbit is set on EOF.
943 // Called by ipfx() and ipfx0() if needed.
945 int istream::_skip_ws()
947 int ch = skip_ws(_strbuf);
948 if (ch == EOF) {
949 set(ios::eofbit|ios::failbit);
950 return 0;
952 else {
953 _strbuf->sputbackc(ch);
954 return 1;
958 ostream& ends(ostream& outs)
960 outs.put('\0');
961 return outs;
964 ostream& endl(ostream& outs)
966 return flush(outs.put('\n'));
969 istream& lock(istream& ins)
971 _IO_flockfile (ins._strbuf);
972 return ins;
974 istream& unlock(istream& ins)
976 _IO_funlockfile (ins._strbuf);
977 return ins;
979 ostream& lock(ostream& outs)
981 _IO_flockfile (outs._strbuf);
982 return outs;
984 ostream& unlock(ostream& outs)
986 _IO_funlockfile (outs._strbuf);
987 return outs;
991 ostream& ostream::write(const char *s, streamsize n)
993 if (opfx()) {
994 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
995 _strbuf);
996 if (_IO_sputn(_strbuf, s, n) != n)
997 set(ios::failbit);
998 osfx();
999 _IO_cleanup_region_end (0);
1001 return *this;
1004 void ostream::do_osfx()
1006 if (flags() & ios::unitbuf)
1007 flush();
1008 if (flags() & ios::stdio) {
1009 fflush(stdout);
1010 fflush(stderr);
1014 iostream::iostream(streambuf* sb, ostream* tied)
1016 init (sb, tied);
1019 // NOTE: extension for compatibility with old libg++.
1020 // Not really compatible with fistream::close().
1021 #ifdef _STREAM_COMPAT
1022 void ios::close()
1024 if (_strbuf->_flags & _IO_IS_FILEBUF)
1025 ((struct filebuf*)rdbuf())->close();
1026 else if (_strbuf != NULL)
1027 rdbuf()->sync();
1028 _strbuf = NULL;
1029 _state = badbit;
1032 int istream::skip(int i)
1034 int old = (_flags & ios::skipws) != 0;
1035 if (i)
1036 _flags |= ios::skipws;
1037 else
1038 _flags &= ~ios::skipws;
1039 return old;
1041 #endif