Fix Turbo's LPRng compilation failure due to assembler errors.
[official-gcc.git] / libio / iostream.cc
blobae1db1afd9c9f8583f63d8cf9e440c95eef19b2d
1 /* This is part of libio/iostream, providing -*- C++ -*- input/output.
2 Copyright (C) 1993, 1997, 2000 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 #if __GLIBC_MINOR__ >= 2
691 /* wide: */ 0,
692 /* i18n: */ 0,
693 #endif
694 #endif
695 #endif
696 /* pad: */ fill()
698 const void *ptr = (const void *) &n;
699 if (__printf_fp (rdbuf(), &info, &ptr) < 0)
700 set(ios::badbit|ios::failbit);
702 #elif defined _IO_USE_DTOA
703 if (_IO_outfloat(n, rdbuf(), format_char, width(0),
704 prec, flags(),
705 flags() & ios::showpos ? '+' : 0,
706 fill()) < 0)
707 set(ios::badbit|ios::failbit); // ??
708 #else
709 int fpprec = 0; // 'Extra' (suppressed) floating precision.
710 if (prec > MAXFRACT) {
711 if (flags() & (ios::fixed|ios::scientific) & ios::showpos)
712 fpprec = prec - MAXFRACT;
713 prec = MAXFRACT;
715 int negative;
716 char buf[BUF];
717 int sign = '\0';
718 char *cp = buf;
719 *cp = 0;
720 int size = __cvt_double(n, prec,
721 flags() & ios::showpoint ? 0x80 : 0,
722 &negative,
723 format_char, cp, buf + sizeof(buf));
724 if (negative) sign = '-';
725 else if (flags() & ios::showpos) sign = '+';
726 if (*cp == 0)
727 cp++;
729 // Calculate padding.
730 int fieldsize = size + fpprec;
731 if (sign) fieldsize++;
732 int padding = 0;
733 int w = width(0);
734 if (fieldsize < w)
735 padding = w - fieldsize;
737 // Do actual output.
738 register streambuf* sbuf = rdbuf();
739 register i;
740 char fill_char = fill();
741 ios::fmtflags pad_kind =
742 flags() & (ios::left|ios::right|ios::internal);
743 if (pad_kind != (ios::fmtflags)ios::left // Default (right) adjust.
744 && pad_kind != (ios::fmtflags)ios::internal)
745 for (i = padding; --i >= 0; ) sbuf->sputc(fill_char);
746 if (sign)
747 sbuf->sputc(sign);
748 if (pad_kind == (ios::fmtflags)ios::internal)
749 for (i = padding; --i >= 0; ) sbuf->sputc(fill_char);
751 // Emit the actual concented field, followed by extra zeros.
752 _IO_sputn (sbuf, cp, size);
753 for (i = fpprec; --i >= 0; ) sbuf->sputc('0');
755 if (pad_kind == (ios::fmtflags)ios::left) // Left adjustment
756 for (i = padding; --i >= 0; ) sbuf->sputc(fill_char);
757 #endif
758 osfx();
759 _IO_cleanup_region_end (0);
761 return *this;
764 #if _G_HAVE_LONG_DOUBLE_IO
765 ostream& ostream::operator<<(long double n)
767 if (opfx())
769 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
770 _strbuf);
771 int format_char;
772 if ((flags() & ios::floatfield) == ios::fixed)
773 format_char = 'f';
774 else if ((flags() & ios::floatfield) == ios::scientific)
775 format_char = flags() & ios::uppercase ? 'E' : 'e';
776 else
777 format_char = flags() & ios::uppercase ? 'G' : 'g';
779 int prec = precision();
780 if (prec <= 0 && !(flags() & ios::fixed))
781 prec = 6; /* default */
783 #if _G_HAVE_PRINTF_FP
784 // Do actual conversion.
785 struct printf_info info = { /* prec: */ prec,
786 /* width: */ width(0),
787 /* spec: */ format_char,
788 /* is_long_double: */ 1,
789 /* is_short: */ 0,
790 /* is_long: */ 0,
791 /* alt: */ (flags() & ios::showpoint) != 0,
792 /* space: */ 0,
793 /* left: */ (flags() & ios::left) != 0,
794 /* showsign: */ (flags() & ios::showpos) != 0,
795 /* group: */ 0,
796 #if defined __GLIBC__ && __GLIBC__ >= 2
797 /* extra: */ 0,
798 #if __GLIBC_MINOR__ >= 1
799 /* is_char: */ 0,
800 #if __GLIBC_MINOR__ >= 2
801 /* wide: */ 0,
802 /* i18n: */ 0,
803 #endif
804 #endif
805 #endif
806 /* pad: */ fill()
809 const void *ptr = (const void *) &n;
811 if (__printf_fp (rdbuf(), &info, &ptr) < 0)
812 set (ios::badbit|ios::failbit);
813 #else
814 # error "long double I/O using dtoa or cvt_double is not implemented"
815 #endif
816 osfx();
817 _IO_cleanup_region_end (0);
819 return *this;
821 #endif
823 ostream& ostream::operator<<(const char *s)
825 if (opfx())
827 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
828 _strbuf);
829 if (s == NULL)
830 s = "(null)";
831 int len = strlen(s);
832 int w = width(0);
833 // FIXME: Should we: if (w && len>w) len = w;
834 char fill_char = fill();
835 register streambuf *sbuf = rdbuf();
836 register int padding = w > len ? w - len : 0;
837 if (!(flags() & ios::left) && padding > 0) // Default adjustment.
838 if (_IO_padn(sbuf, fill_char, padding) != padding)
840 set(ios::badbit);
841 goto failed;
843 if (_IO_sputn (sbuf, s, len) != len)
845 set(ios::badbit);
846 goto failed;
848 if (flags() & ios::left && padding > 0) // Left adjustment.
849 if (_IO_padn(sbuf, fill_char, padding) != padding)
850 set(ios::badbit);
851 failed:
852 osfx();
853 _IO_cleanup_region_end (0);
855 return *this;
858 #if 0
859 ostream& ostream::operator<<(const void *p)
860 { Is in osform.cc, to avoid pulling in all of _IO_vfprintf by this file. */ }
861 #endif
863 ostream& ostream::operator<<(register streambuf* sbuf)
865 if (opfx())
867 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
868 _strbuf);
869 char buffer[_IO_BUFSIZ];
870 register streambuf* outbuf = _strbuf;
871 for (;;)
873 _IO_size_t count = _IO_sgetn(sbuf, buffer, _IO_BUFSIZ);
874 if (count <= 0)
875 break;
876 if (_IO_sputn(outbuf, buffer, count) != count)
878 set(ios::badbit);
879 break;
882 osfx();
883 _IO_cleanup_region_end (0);
885 return *this;
888 ostream::ostream(streambuf* sb, ostream* tied)
890 init (sb, tied);
893 ostream& ostream::seekp(streampos pos)
895 pos = _strbuf->pubseekpos(pos, ios::out);
896 if (pos == streampos(EOF))
897 set(ios::badbit);
898 return *this;
901 ostream& ostream::seekp(streamoff off, _seek_dir dir)
903 streampos pos = _IO_seekoff (_strbuf, off, (int) dir, _IOS_OUTPUT);
904 if (pos == streampos(EOF))
905 set(ios::badbit);
906 return *this;
909 streampos ostream::tellp()
911 #if 1
912 streampos pos = _IO_seekoff (_strbuf, 0, _IO_seek_cur, _IOS_OUTPUT);
913 #else
914 streampos pos = _strbuf->pubseekoff(0, ios::cur, ios::out);
915 #endif
916 if (pos == streampos(EOF))
917 set(ios::badbit);
918 return pos;
921 ostream& ostream::flush()
923 if (_strbuf->sync())
924 set(ios::badbit);
925 return *this;
928 ostream& flush(ostream& outs)
930 return outs.flush();
933 istream& ws(istream& ins)
935 if (ins.ipfx1()) {
936 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
937 ins._strbuf);
938 int ch = skip_ws(ins._strbuf);
939 if (ch == EOF)
940 ins.set(ios::eofbit);
941 else
942 ins._strbuf->sputbackc(ch);
943 ins.isfx();
944 _IO_cleanup_region_end (0);
946 return ins;
949 // Skip white-space. Return 0 on failure (EOF), or 1 on success.
950 // Differs from ws() manipulator in that failbit is set on EOF.
951 // Called by ipfx() and ipfx0() if needed.
953 int istream::_skip_ws()
955 int ch = skip_ws(_strbuf);
956 if (ch == EOF) {
957 set(ios::eofbit|ios::failbit);
958 return 0;
960 else {
961 _strbuf->sputbackc(ch);
962 return 1;
966 ostream& ends(ostream& outs)
968 if (outs.opfx()) {
969 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
970 outs._strbuf);
971 outs.put('\0');
972 outs.osfx();
973 _IO_cleanup_region_end (0);
975 return outs;
978 ostream& endl(ostream& outs)
980 if (outs.opfx()) {
981 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
982 outs._strbuf);
983 flush(outs.put('\n'));
984 outs.osfx();
985 _IO_cleanup_region_end (0);
987 return outs;
990 istream& lock(istream& ins)
992 _IO_flockfile (ins._strbuf);
993 return ins;
995 istream& unlock(istream& ins)
997 _IO_funlockfile (ins._strbuf);
998 return ins;
1000 ostream& lock(ostream& outs)
1002 _IO_flockfile (outs._strbuf);
1003 return outs;
1005 ostream& unlock(ostream& outs)
1007 _IO_funlockfile (outs._strbuf);
1008 return outs;
1012 ostream& ostream::write(const char *s, streamsize n)
1014 if (opfx()) {
1015 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
1016 _strbuf);
1017 if (_IO_sputn(_strbuf, s, n) != n)
1018 set(ios::failbit);
1019 osfx();
1020 _IO_cleanup_region_end (0);
1022 return *this;
1025 void ostream::do_osfx()
1027 if (flags() & ios::unitbuf)
1028 flush();
1029 if (flags() & ios::stdio) {
1030 fflush(stdout);
1031 fflush(stderr);
1035 iostream::iostream(streambuf* sb, ostream* tied)
1037 init (sb, tied);
1040 // NOTE: extension for compatibility with old libg++.
1041 // Not really compatible with fistream::close().
1042 #ifdef _STREAM_COMPAT
1043 void ios::close()
1045 if (_strbuf->_flags & _IO_IS_FILEBUF)
1046 ((struct filebuf*)rdbuf())->close();
1047 else if (_strbuf != NULL)
1048 rdbuf()->sync();
1049 _strbuf = NULL;
1050 _state = badbit;
1053 int istream::skip(int i)
1055 int old = (_flags & ios::skipws) != 0;
1056 if (i)
1057 _flags |= ios::skipws;
1058 else
1059 _flags &= ~ios::skipws;
1060 return old;
1062 #endif