]> gcc.gnu.org Git - gcc.git/blame - libio/iostream.cc
frame.c: Include gansidecl.h for PROTO.
[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,
47 int fmtch, char *startp, char *endp)
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.
e693cc28
UD
618#ifdef _G_HAVE_PRINTF_FP
619 {
620 struct printf_info info = { prec: prec,
621 width: width(0),
622 spec: format_char,
623 is_long_double: 0,
624 is_short: 0,
625 is_long: 0,
626 alt: flags() & ios::showpoint,
627 space: 0,
628 left: ios::left,
629 showsign: flags() & ios::showpos,
630 group: 0,
631 pad: fill(),
632 extra: 0};
633 const void *ptr = &n;
634 if (__printf_fp (rdbuf(), &info, &ptr) < 0)
635 set(ios::badbit|ios::failbit);
636 }
637#elif defined _IO_USE_DTOA
6599da04
JM
638 if (_IO_outfloat(n, rdbuf(), format_char, width(0),
639 prec, flags(),
640 flags() & ios::showpos ? '+' : 0,
641 fill()) < 0)
642 set(ios::badbit|ios::failbit); // ??
643#else
644 int fpprec = 0; // 'Extra' (suppressed) floating precision.
645 if (prec > MAXFRACT) {
646 if (flags() & (ios::fixed|ios::scientific) & ios::showpos)
647 fpprec = prec - MAXFRACT;
648 prec = MAXFRACT;
649 }
650 int negative;
651 char buf[BUF];
652 int sign = '\0';
653 char *cp = buf;
654 *cp = 0;
655 int size = __cvt_double(n, prec,
656 flags() & ios::showpoint ? 0x80 : 0,
657 &negative,
658 format_char, cp, buf + sizeof(buf));
659 if (negative) sign = '-';
660 else if (flags() & ios::showpos) sign = '+';
661 if (*cp == 0)
662 cp++;
663
664 // Calculate padding.
665 int fieldsize = size + fpprec;
666 if (sign) fieldsize++;
667 int padding = 0;
668 int w = width(0);
669 if (fieldsize < w)
670 padding = w - fieldsize;
671
672 // Do actual output.
673 register streambuf* sbuf = rdbuf();
674 register i;
675 char fill_char = fill();
676 ios::fmtflags pad_kind =
677 flags() & (ios::left|ios::right|ios::internal);
678 if (pad_kind != (ios::fmtflags)ios::left // Default (right) adjust.
679 && pad_kind != (ios::fmtflags)ios::internal)
680 for (i = padding; --i >= 0; ) sbuf->sputc(fill_char);
681 if (sign)
682 sbuf->sputc(sign);
683 if (pad_kind == (ios::fmtflags)ios::internal)
684 for (i = padding; --i >= 0; ) sbuf->sputc(fill_char);
e693cc28 685
6599da04
JM
686 // Emit the actual concented field, followed by extra zeros.
687 _IO_sputn (sbuf, cp, size);
688 for (i = fpprec; --i >= 0; ) sbuf->sputc('0');
689
690 if (pad_kind == (ios::fmtflags)ios::left) // Left adjustment
691 for (i = padding; --i >= 0; ) sbuf->sputc(fill_char);
692#endif
693 osfx();
e693cc28 694 _IO_cleanup_region_end (0);
6599da04
JM
695 }
696 return *this;
697}
698
e693cc28
UD
699#if _G_HAVE_LONG_DOUBLE_IO
700ostream& ostream::operator<<(long double n)
701{
702 if (opfx())
703 {
704 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
705 _strbuf);
706 int format_char;
707 if ((flags() & ios::floatfield) == ios::fixed)
708 format_char = 'f';
709 else if ((flags() & ios::floatfield) == ios::scientific)
710 format_char = flags() & ios::uppercase ? 'E' : 'e';
711 else
712 format_char = flags() & ios::uppercase ? 'G' : 'g';
713
714 int prec = precision();
715 if (prec <= 0 && !(flags() & ios::fixed))
716 prec = 6; /* default */
717
718#ifdef _G_HAVE_PRINTF_FP
719 // Do actual conversion.
720 struct printf_info info = { prec: prec,
721 width: width(0),
722 spec: format_char,
723 is_long_double: 1,
724 is_short: 0,
725 is_long: 0,
726 alt: flags() & ios::showpoint,
727 space: 0,
728 left: ios::left,
729 showsign: flags() & ios::showpos,
730 group: 0,
731 pad: fill(),
732 extra: 0};
733
734 const void *ptr = &n;
735
736 if (__printf_fp (rdbuf(), &info, &ptr) < 0)
737 set (ios::badbit|ios::failbit);
738#else
739# error "long double I/O using dtoa or cvt_double is not implemented"
740#endif
741 osfx();
742 _IO_cleanup_region_end (0);
743 }
744 return *this;
745}
746#endif
747
6599da04
JM
748ostream& ostream::operator<<(const char *s)
749{
750 if (opfx())
751 {
e693cc28
UD
752 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
753 _strbuf);
6599da04
JM
754 if (s == NULL)
755 s = "(null)";
756 int len = strlen(s);
757 int w = width(0);
758// FIXME: Should we: if (w && len>w) len = w;
759 char fill_char = fill();
760 register streambuf *sbuf = rdbuf();
761 register int padding = w > len ? w - len : 0;
762 if (!(flags() & ios::left) && padding > 0) // Default adjustment.
763 if (_IO_padn(sbuf, fill_char, padding) != padding)
e693cc28
UD
764 {
765 set(ios::badbit);
766 goto failed;
767 }
6599da04 768 if (_IO_sputn (sbuf, s, len) != len)
e693cc28
UD
769 {
770 set(ios::badbit);
771 goto failed;
772 }
6599da04
JM
773 if (flags() & ios::left && padding > 0) // Left adjustment.
774 if (_IO_padn(sbuf, fill_char, padding) != padding)
e693cc28 775 set(ios::badbit);
6599da04 776 osfx();
e693cc28
UD
777 failed:
778 _IO_cleanup_region_end (0);
6599da04
JM
779 }
780 return *this;
6599da04
JM
781}
782
783#if 0
784ostream& ostream::operator<<(const void *p)
785{ Is in osform.cc, to avoid pulling in all of _IO_vfprintf by this file. */ }
786#endif
787
788ostream& ostream::operator<<(register streambuf* sbuf)
789{
790 if (opfx())
791 {
e693cc28
UD
792 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
793 _strbuf);
6599da04
JM
794 char buffer[_IO_BUFSIZ];
795 register streambuf* outbuf = _strbuf;
796 for (;;)
797 {
798 _IO_size_t count = _IO_sgetn(sbuf, buffer, _IO_BUFSIZ);
799 if (count <= 0)
800 break;
801 if (_IO_sputn(outbuf, buffer, count) != count)
802 {
803 set(ios::badbit);
804 break;
805 }
806 }
807 osfx();
e693cc28 808 _IO_cleanup_region_end (0);
6599da04
JM
809 }
810 return *this;
811}
812
813ostream::ostream(streambuf* sb, ostream* tied)
814{
815 init (sb, tied);
816}
817
818ostream& ostream::seekp(streampos pos)
819{
820 pos = _strbuf->pubseekpos(pos, ios::out);
821 if (pos == streampos(EOF))
822 set(ios::badbit);
823 return *this;
824}
825
826ostream& ostream::seekp(streamoff off, _seek_dir dir)
827{
828 streampos pos = _IO_seekoff (_strbuf, off, (int) dir, _IOS_OUTPUT);
829 if (pos == streampos(EOF))
830 set(ios::badbit);
831 return *this;
832}
833
834streampos ostream::tellp()
835{
836#if 1
837 streampos pos = _IO_seekoff (_strbuf, 0, _IO_seek_cur, _IOS_OUTPUT);
838#else
839 streampos pos = _strbuf->pubseekoff(0, ios::cur, ios::out);
840#endif
841 if (pos == streampos(EOF))
842 set(ios::badbit);
843 return pos;
844}
845
846ostream& ostream::flush()
847{
848 if (_strbuf->sync())
849 set(ios::badbit);
850 return *this;
851}
852
853ostream& flush(ostream& outs)
854{
855 return outs.flush();
856}
857
858istream& ws(istream& ins)
859{
860 if (ins.ipfx1()) {
e693cc28
UD
861 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
862 ins._strbuf);
6599da04
JM
863 int ch = skip_ws(ins._strbuf);
864 if (ch == EOF)
865 ins.set(ios::eofbit);
866 else
867 ins._strbuf->sputbackc(ch);
e693cc28
UD
868 ins.isfx();
869 _IO_cleanup_region_end (0);
6599da04
JM
870 }
871 return ins;
872}
873
874// Skip white-space. Return 0 on failure (EOF), or 1 on success.
875// Differs from ws() manipulator in that failbit is set on EOF.
876// Called by ipfx() and ipfx0() if needed.
877
878int istream::_skip_ws()
879{
880 int ch = skip_ws(_strbuf);
881 if (ch == EOF) {
882 set(ios::eofbit|ios::failbit);
883 return 0;
884 }
885 else {
886 _strbuf->sputbackc(ch);
887 return 1;
888 }
889}
890
891ostream& ends(ostream& outs)
892{
893 outs.put('\0');
894 return outs;
895}
896
897ostream& endl(ostream& outs)
898{
899 return flush(outs.put('\n'));
900}
901
e693cc28
UD
902istream& lock(istream& ins)
903{
904 _IO_flockfile (ins._strbuf);
905 return ins;
906}
907istream& unlock(istream& ins)
908{
909 _IO_funlockfile (ins._strbuf);
910 return ins;
911}
912ostream& lock(ostream& outs)
913{
914 _IO_flockfile (outs._strbuf);
915 return outs;
916}
917ostream& unlock(ostream& outs)
918{
919 _IO_funlockfile (outs._strbuf);
920 return outs;
921}
922
923
6599da04
JM
924ostream& ostream::write(const char *s, streamsize n)
925{
926 if (opfx()) {
e693cc28
UD
927 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
928 _strbuf);
6599da04
JM
929 if (_IO_sputn(_strbuf, s, n) != n)
930 set(ios::failbit);
e693cc28
UD
931 osfx();
932 _IO_cleanup_region_end (0);
6599da04
JM
933 }
934 return *this;
935}
936
937void ostream::do_osfx()
938{
939 if (flags() & ios::unitbuf)
940 flush();
941 if (flags() & ios::stdio) {
942 fflush(stdout);
943 fflush(stderr);
944 }
945}
946
947iostream::iostream(streambuf* sb, ostream* tied)
948{
949 init (sb, tied);
950}
951
952// NOTE: extension for compatibility with old libg++.
953// Not really compatible with fistream::close().
954#ifdef _STREAM_COMPAT
955void ios::close()
956{
957 if (_strbuf->_flags & _IO_IS_FILEBUF)
958 ((struct filebuf*)rdbuf())->close();
959 else if (_strbuf != NULL)
960 rdbuf()->sync();
961 _strbuf = NULL;
962 _state = badbit;
963}
964
965int istream::skip(int i)
966{
967 int old = (_flags & ios::skipws) != 0;
968 if (i)
969 _flags |= ios::skipws;
970 else
971 _flags &= ~ios::skipws;
972 return old;
973}
974#endif
This page took 0.130399 seconds and 5 git commands to generate.