]> gcc.gnu.org Git - gcc.git/blame - libio/iostream.cc
Patch from Richard Henderson to make __builtin_return_address(0) work.
[gcc.git] / libio / iostream.cc
CommitLineData
6599da04 1/* This is part of libio/iostream, providing -*- C++ -*- input/output.
e693cc28
UD
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. */
6599da04
JM
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>
e693cc28
UD
38
39#if _G_HAVE_PRINTF_FP
40#include <printf.h>
41extern "C" int __printf_fp (_IO_FILE *, const struct printf_info *,
42 const void *const *);
43#else
6599da04 44#include "floatio.h"
6c1d5706
UD
45# ifndef _IO_USE_DTOA
46int __cvt_double(double number, register int prec, int flags, int *signp,
d604f4c6 47 int fmtch, char *startp, char *endp);
6c1d5706 48# endif
e693cc28 49#endif
6599da04
JM
50
51#define BUF (MAXEXP+MAXFRACT+1) /* + decimal point */
52
53//#define isspace(ch) ((ch)==' ' || (ch)=='\t' || (ch)=='\n')
54
55istream::istream(streambuf *sb, ostream* tied)
56{
57 init (sb, tied);
58 _gcount = 0;
59}
60
61int 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
71istream& 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
89int 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
101istream& 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
129istream& 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
141int
142istream::sync ()
143{
144 streambuf *sb = rdbuf ();
145 if (sb == NULL)
146 return EOF;
147 if (sb->sync ()) // Later: pubsync
e693cc28 148 {
6599da04
JM
149 setstate (ios::badbit);
150 return EOF;
151 }
152 else
153 return 0;
154}
155
156istream& 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
164istream& 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
172streampos 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
184istream& 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
196istream&
197istream::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
233static 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) \
309istream& 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
319READ_INT(short)
320READ_INT(unsigned short)
321READ_INT(int)
322READ_INT(unsigned int)
323READ_INT(long)
324READ_INT(unsigned long)
325#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
326READ_INT(long long)
327READ_INT(unsigned long long)
328#endif
329#if _G_HAVE_BOOL
330READ_INT(bool)
331#endif
332
333istream& istream::operator>>(long double& x)
334{
335 if (ipfx0())
e693cc28
UD
336#if _G_HAVE_LONG_DOUBLE_IO
337 scan("%Lg", &x);
338#else
6599da04 339 scan("%lg", &x);
e693cc28 340#endif
6599da04
JM
341 return *this;
342}
343
344istream& istream::operator>>(double& x)
345{
346 if (ipfx0())
347 scan("%lg", &x);
348 return *this;
349}
350
351istream& istream::operator>>(float& x)
352{
353 if (ipfx0())
354 scan("%g", &x);
355 return *this;
356}
357
358istream& 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
378ostream& ostream::operator<<(char c)
379{
380 if (opfx()) {
e693cc28
UD
381 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
382 _strbuf);
6599da04
JM
383#if 1
384 // This is what the cfront implementation does.
e693cc28
UD
385 if (_strbuf->sputc(c) == EOF) {
386 set(ios::badbit);
387 goto failed;
388 }
6599da04
JM
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.
e693cc28
UD
396 if (_IO_padn(sb, fill_char, padding) < padding) {
397 set(ios::badbit);
6599da04 398 goto failed;
e693cc28
UD
399 }
400 if (sb->sputc(c) == EOF) {
401 set(ios::badbit);
6599da04 402 goto failed;
e693cc28 403 }
6599da04
JM
404 if (flags() & ios::left && padding) // Left adjustment.
405 if (_IO_padn(sb, fill_char, padding) < padding)
e693cc28 406 set(ios::badbit);
6599da04 407#endif
e693cc28 408 failed:
6599da04 409 osfx();
e693cc28 410 _IO_cleanup_region_end (0);
6599da04
JM
411 }
412 return *this;
6599da04
JM
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
420static 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
515ostream& ostream::operator<<(int n)
516{
517 if (opfx()) {
e693cc28
UD
518 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
519 _strbuf);
6599da04
JM
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);
e693cc28 525 _IO_cleanup_region_end (0);
6599da04
JM
526 }
527 return *this;
528}
529
530ostream& ostream::operator<<(unsigned int n)
531{
e693cc28
UD
532 if (opfx()) {
533 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
534 _strbuf);
6599da04 535 write_int(*this, n, 0);
e693cc28
UD
536 _IO_cleanup_region_end (0);
537 }
6599da04
JM
538 return *this;
539}
540
541
542ostream& ostream::operator<<(long n)
543{
544 if (opfx()) {
e693cc28
UD
545 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
546 _strbuf);
6599da04
JM
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);
e693cc28 552 _IO_cleanup_region_end (0);
6599da04
JM
553 }
554 return *this;
555}
556
557ostream& ostream::operator<<(unsigned long n)
558{
e693cc28
UD
559 if (opfx()) {
560 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
561 _strbuf);
6599da04 562 write_int(*this, n, 0);
e693cc28
UD
563 _IO_cleanup_region_end (0);
564 }
6599da04
JM
565 return *this;
566}
567
568#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
569ostream& ostream::operator<<(long long n)
570{
571 if (opfx()) {
e693cc28
UD
572 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
573 _strbuf);
6599da04
JM
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);
e693cc28 579 _IO_cleanup_region_end (0);
6599da04
JM
580 }
581 return *this;
582}
583
584
585ostream& ostream::operator<<(unsigned long long n)
586{
e693cc28
UD
587 if (opfx()) {
588 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
589 _strbuf);
6599da04 590 write_int(*this, n, 0);
e693cc28
UD
591 _IO_cleanup_region_end (0);
592 }
6599da04
JM
593 return *this;
594}
595#endif /*__GNUC__*/
596
597ostream& ostream::operator<<(double n)
598{
599 if (opfx()) {
e693cc28
UD
600 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
601 _strbuf);
6599da04
JM
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.
808d0b10 618#if _G_HAVE_PRINTF_FP
e693cc28
UD
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,
d604f4c6 626 alt: (flags() & ios::showpoint) != 0,
e693cc28 627 space: 0,
d604f4c6
UD
628 left: (flags() & ios::left) != 0,
629 showsign: (flags() & ios::showpos) != 0,
e693cc28 630 group: 0,
d604f4c6
UD
631 pad: fill()
632#if defined __GLIBC__ && __GLIBC__ >= 2
633 , extra: 0
634#endif
635 };
636 const void *ptr = (const void *) &n;
e693cc28
UD
637 if (__printf_fp (rdbuf(), &info, &ptr) < 0)
638 set(ios::badbit|ios::failbit);
639 }
640#elif defined _IO_USE_DTOA
6599da04
JM
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);
e693cc28 688
6599da04
JM
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();
e693cc28 697 _IO_cleanup_region_end (0);
6599da04
JM
698 }
699 return *this;
700}
701
e693cc28
UD
702#if _G_HAVE_LONG_DOUBLE_IO
703ostream& 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#ifdef _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,
d604f4c6 729 alt: (flags() & ios::showpoint) != 0,
e693cc28 730 space: 0,
d604f4c6
UD
731 left: (flags() & ios::left) != 0,
732 showsign: (flags() & ios::showpos) != 0,
e693cc28 733 group: 0,
d604f4c6
UD
734 pad: fill()
735#if defined __GLIBC__ && __GLIBC__ >= 2
736 , extra: 0
737#endif
738 };
e693cc28 739
d604f4c6 740 const void *ptr = (const void *) &n;
e693cc28
UD
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
6599da04
JM
754ostream& ostream::operator<<(const char *s)
755{
756 if (opfx())
757 {
e693cc28
UD
758 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
759 _strbuf);
6599da04
JM
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)
e693cc28
UD
770 {
771 set(ios::badbit);
772 goto failed;
773 }
6599da04 774 if (_IO_sputn (sbuf, s, len) != len)
e693cc28
UD
775 {
776 set(ios::badbit);
777 goto failed;
778 }
6599da04
JM
779 if (flags() & ios::left && padding > 0) // Left adjustment.
780 if (_IO_padn(sbuf, fill_char, padding) != padding)
e693cc28 781 set(ios::badbit);
6599da04 782 osfx();
e693cc28
UD
783 failed:
784 _IO_cleanup_region_end (0);
6599da04
JM
785 }
786 return *this;
6599da04
JM
787}
788
789#if 0
790ostream& ostream::operator<<(const void *p)
791{ Is in osform.cc, to avoid pulling in all of _IO_vfprintf by this file. */ }
792#endif
793
794ostream& ostream::operator<<(register streambuf* sbuf)
795{
796 if (opfx())
797 {
e693cc28
UD
798 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
799 _strbuf);
6599da04
JM
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();
e693cc28 814 _IO_cleanup_region_end (0);
6599da04
JM
815 }
816 return *this;
817}
818
819ostream::ostream(streambuf* sb, ostream* tied)
820{
821 init (sb, tied);
822}
823
824ostream& 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
832ostream& 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
840streampos 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
852ostream& ostream::flush()
853{
854 if (_strbuf->sync())
855 set(ios::badbit);
856 return *this;
857}
858
859ostream& flush(ostream& outs)
860{
861 return outs.flush();
862}
863
864istream& ws(istream& ins)
865{
866 if (ins.ipfx1()) {
e693cc28
UD
867 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
868 ins._strbuf);
6599da04
JM
869 int ch = skip_ws(ins._strbuf);
870 if (ch == EOF)
871 ins.set(ios::eofbit);
872 else
873 ins._strbuf->sputbackc(ch);
e693cc28
UD
874 ins.isfx();
875 _IO_cleanup_region_end (0);
6599da04
JM
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
884int 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
897ostream& ends(ostream& outs)
898{
899 outs.put('\0');
900 return outs;
901}
902
903ostream& endl(ostream& outs)
904{
905 return flush(outs.put('\n'));
906}
907
e693cc28
UD
908istream& lock(istream& ins)
909{
910 _IO_flockfile (ins._strbuf);
911 return ins;
912}
913istream& unlock(istream& ins)
914{
915 _IO_funlockfile (ins._strbuf);
916 return ins;
917}
918ostream& lock(ostream& outs)
919{
920 _IO_flockfile (outs._strbuf);
921 return outs;
922}
923ostream& unlock(ostream& outs)
924{
925 _IO_funlockfile (outs._strbuf);
926 return outs;
927}
928
929
6599da04
JM
930ostream& ostream::write(const char *s, streamsize n)
931{
932 if (opfx()) {
e693cc28
UD
933 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
934 _strbuf);
6599da04
JM
935 if (_IO_sputn(_strbuf, s, n) != n)
936 set(ios::failbit);
e693cc28
UD
937 osfx();
938 _IO_cleanup_region_end (0);
6599da04
JM
939 }
940 return *this;
941}
942
943void 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
953iostream::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
961void 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
971int 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
This page took 0.126135 seconds and 5 git commands to generate.