]> gcc.gnu.org Git - gcc.git/blob - libio/iostream.cc
Handle __set_errno correctly.
[gcc.git] / libio / iostream.cc
1 /* This is part of libio/iostream, providing -*- C++ -*- input/output.
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. */
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>
38
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 #endif
46
47 #define BUF (MAXEXP+MAXFRACT+1) /* + decimal point */
48
49 //#define isspace(ch) ((ch)==' ' || (ch)=='\t' || (ch)=='\n')
50
51 istream::istream(streambuf *sb, ostream* tied)
52 {
53 init (sb, tied);
54 _gcount = 0;
55 }
56
57 int skip_ws(streambuf* sb)
58 {
59 int ch;
60 for (;;) {
61 ch = sb->sbumpc();
62 if (ch == EOF || !isspace(ch))
63 return ch;
64 }
65 }
66
67 istream& istream::get(char& c)
68 {
69 if (ipfx1()) {
70 int ch = _strbuf->sbumpc();
71 if (ch == EOF) {
72 set(ios::eofbit|ios::failbit);
73 _gcount = 0;
74 }
75 else {
76 c = (char)ch;
77 _gcount = 1;
78 }
79 }
80 else
81 _gcount = 0;
82 return *this;
83 }
84
85 int istream::peek()
86 {
87 if (!good())
88 return EOF;
89 if (_tie && rdbuf()->in_avail() == 0)
90 _tie->flush();
91 int ch = _strbuf->sgetc();
92 if (ch == EOF)
93 set(ios::eofbit);
94 return ch;
95 }
96
97 istream& istream::ignore(int n /* = 1 */, int delim /* = EOF */)
98 {
99 _gcount = 0;
100 if (ipfx1()) {
101 register streambuf* sb = _strbuf;
102 if (delim == EOF) {
103 _gcount = sb->ignore(n);
104 return *this;
105 }
106 for (;;) {
107 #if 0
108 if (n != MAXINT) // FIXME
109 #endif
110 if (--n < 0)
111 break;
112 int ch = sb->sbumpc();
113 if (ch == EOF) {
114 set(ios::eofbit|ios::failbit);
115 break;
116 }
117 _gcount++;
118 if (ch == delim)
119 break;
120 }
121 }
122 return *this;
123 }
124
125 istream& istream::read(char *s, streamsize n)
126 {
127 if (ipfx1()) {
128 _gcount = _strbuf->sgetn(s, n);
129 if (_gcount != n)
130 set(ios::failbit|ios::eofbit);
131 }
132 else
133 _gcount = 0;
134 return *this;
135 }
136
137 int
138 istream::sync ()
139 {
140 streambuf *sb = rdbuf ();
141 if (sb == NULL)
142 return EOF;
143 if (sb->sync ()) // Later: pubsync
144 {
145 setstate (ios::badbit);
146 return EOF;
147 }
148 else
149 return 0;
150 }
151
152 istream& istream::seekg(streampos pos)
153 {
154 pos = _strbuf->pubseekpos(pos, ios::in);
155 if (pos == streampos(EOF))
156 set(ios::badbit);
157 return *this;
158 }
159
160 istream& istream::seekg(streamoff off, _seek_dir dir)
161 {
162 streampos pos = _IO_seekoff (_strbuf, off, (int) dir, _IOS_INPUT);
163 if (pos == streampos(EOF))
164 set(ios::badbit);
165 return *this;
166 }
167
168 streampos istream::tellg()
169 {
170 #if 0
171 streampos pos = _strbuf->pubseekoff(0, ios::cur, ios::in);
172 #else
173 streampos pos = _IO_seekoff (_strbuf, 0, _IO_seek_cur, _IOS_INPUT);
174 #endif
175 if (pos == streampos(EOF))
176 set(ios::badbit);
177 return pos;
178 }
179
180 istream& istream::operator>>(char& c)
181 {
182 if (ipfx0()) {
183 int ch = _strbuf->sbumpc();
184 if (ch == EOF)
185 set(ios::eofbit|ios::failbit);
186 else
187 c = (char)ch;
188 }
189 return *this;
190 }
191
192 istream&
193 istream::operator>> (char* ptr)
194 {
195 register char *p = ptr;
196 int w = width(0);
197 if (ipfx0())
198 {
199 register streambuf* sb = _strbuf;
200 for (;;)
201 {
202 int ch = sb->sbumpc();
203 if (ch == EOF)
204 {
205 set(ios::eofbit);
206 break;
207 }
208 else if (isspace(ch) || w == 1)
209 {
210 sb->sputbackc(ch);
211 break;
212 }
213 else *p++ = ch;
214 w--;
215 }
216 if (p == ptr)
217 set(ios::failbit);
218 }
219 *p = '\0';
220 return *this;
221 }
222
223 #if defined(__GNUC__) && !defined(__STRICT_ANSI__)
224 #define LONGEST long long
225 #else
226 #define LONGEST long
227 #endif
228
229 static int read_int(istream& stream, unsigned LONGEST& val, int& neg)
230 {
231 if (!stream.ipfx0())
232 return 0;
233 register streambuf* sb = stream.rdbuf();
234 int base = 10;
235 int ndigits = 0;
236 register int ch = skip_ws(sb);
237 if (ch == EOF)
238 goto eof_fail;
239 neg = 0;
240 if (ch == '+') {
241 ch = skip_ws(sb);
242 }
243 else if (ch == '-') {
244 neg = 1;
245 ch = skip_ws(sb);
246 }
247 if (ch == EOF) goto eof_fail;
248 if (!(stream.flags() & ios::basefield)) {
249 if (ch == '0') {
250 ch = sb->sbumpc();
251 if (ch == EOF) {
252 val = 0;
253 return 1;
254 }
255 if (ch == 'x' || ch == 'X') {
256 base = 16;
257 ch = sb->sbumpc();
258 if (ch == EOF) goto eof_fail;
259 }
260 else {
261 sb->sputbackc(ch);
262 base = 8;
263 ch = '0';
264 }
265 }
266 }
267 else if ((stream.flags() & ios::basefield) == ios::hex)
268 base = 16;
269 else if ((stream.flags() & ios::basefield) == ios::oct)
270 base = 8;
271 val = 0;
272 for (;;) {
273 if (ch == EOF)
274 break;
275 int digit;
276 if (ch >= '0' && ch <= '9')
277 digit = ch - '0';
278 else if (ch >= 'A' && ch <= 'F')
279 digit = ch - 'A' + 10;
280 else if (ch >= 'a' && ch <= 'f')
281 digit = ch - 'a' + 10;
282 else
283 digit = 999;
284 if (digit >= base) {
285 sb->sputbackc(ch);
286 if (ndigits == 0)
287 goto fail;
288 else
289 return 1;
290 }
291 ndigits++;
292 val = base * val + digit;
293 ch = sb->sbumpc();
294 }
295 return 1;
296 fail:
297 stream.set(ios::failbit);
298 return 0;
299 eof_fail:
300 stream.set(ios::failbit|ios::eofbit);
301 return 0;
302 }
303
304 #define READ_INT(TYPE) \
305 istream& istream::operator>>(TYPE& i)\
306 {\
307 unsigned LONGEST val; int neg;\
308 if (read_int(*this, val, neg)) {\
309 if (neg) val = -val;\
310 i = (TYPE)val;\
311 }\
312 return *this;\
313 }
314
315 READ_INT(short)
316 READ_INT(unsigned short)
317 READ_INT(int)
318 READ_INT(unsigned int)
319 READ_INT(long)
320 READ_INT(unsigned long)
321 #if defined(__GNUC__) && !defined(__STRICT_ANSI__)
322 READ_INT(long long)
323 READ_INT(unsigned long long)
324 #endif
325 #if _G_HAVE_BOOL
326 READ_INT(bool)
327 #endif
328
329 istream& istream::operator>>(long double& x)
330 {
331 if (ipfx0())
332 #if _G_HAVE_LONG_DOUBLE_IO
333 scan("%Lg", &x);
334 #else
335 scan("%lg", &x);
336 #endif
337 return *this;
338 }
339
340 istream& istream::operator>>(double& x)
341 {
342 if (ipfx0())
343 scan("%lg", &x);
344 return *this;
345 }
346
347 istream& istream::operator>>(float& x)
348 {
349 if (ipfx0())
350 scan("%g", &x);
351 return *this;
352 }
353
354 istream& istream::operator>>(register streambuf* sbuf)
355 {
356 if (ipfx0()) {
357 register streambuf* inbuf = rdbuf();
358 // FIXME: Should optimize!
359 for (;;) {
360 register int ch = inbuf->sbumpc();
361 if (ch == EOF) {
362 set(ios::eofbit);
363 break;
364 }
365 if (sbuf->sputc(ch) == EOF) {
366 set(ios::failbit);
367 break;
368 }
369 }
370 }
371 return *this;
372 }
373
374 ostream& ostream::operator<<(char c)
375 {
376 if (opfx()) {
377 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
378 _strbuf);
379 #if 1
380 // This is what the cfront implementation does.
381 if (_strbuf->sputc(c) == EOF) {
382 set(ios::badbit);
383 goto failed;
384 }
385 #else
386 // This is what cfront documentation and current ANSI drafts say.
387 int w = width(0);
388 char fill_char = fill();
389 register int padding = w > 0 ? w - 1 : 0;
390 register streambuf *sb = _strbuf;
391 if (!(flags() & ios::left) && padding) // Default adjustment.
392 if (_IO_padn(sb, fill_char, padding) < padding) {
393 set(ios::badbit);
394 goto failed;
395 }
396 if (sb->sputc(c) == EOF) {
397 set(ios::badbit);
398 goto failed;
399 }
400 if (flags() & ios::left && padding) // Left adjustment.
401 if (_IO_padn(sb, fill_char, padding) < padding)
402 set(ios::badbit);
403 #endif
404 failed:
405 osfx();
406 _IO_cleanup_region_end (0);
407 }
408 return *this;
409 }
410
411 /* Write VAL on STREAM.
412 If SIGN<0, val is the absolute value of a negative number.
413 If SIGN>0, val is a signed non-negative number.
414 If SIGN==0, val is unsigned. */
415
416 static void write_int(ostream& stream, unsigned LONGEST val, int sign)
417 {
418 #define WRITE_BUF_SIZE (10 + sizeof(unsigned LONGEST) * 3)
419 char buf[WRITE_BUF_SIZE];
420 register char *buf_ptr = buf+WRITE_BUF_SIZE; // End of buf.
421 const char *show_base = "";
422 int show_base_len = 0;
423 int show_pos = 0; // If 1, print a '+'.
424
425 // Now do the actual conversion, placing the result at the *end* of buf.
426 // Note that we use separate code for decimal, octal, and hex,
427 // so we can divide by optimizable constants.
428 if ((stream.flags() & ios::basefield) == ios::oct) { // Octal
429 do {
430 *--buf_ptr = (val & 7) + '0';
431 val = val >> 3;
432 } while (val != 0);
433 if ((stream.flags() & ios::showbase) && (*buf_ptr != '0'))
434 *--buf_ptr = '0';
435 }
436 else if ((stream.flags() & ios::basefield) == ios::hex) { // Hex
437 const char *xdigs = (stream.flags() & ios::uppercase) ? "0123456789ABCDEF0X"
438 : "0123456789abcdef0x";
439 do {
440 *--buf_ptr = xdigs[val & 15];
441 val = val >> 4;
442 } while (val != 0);
443 if ((stream.flags() & ios::showbase)) {
444 show_base = xdigs + 16; // Either "0X" or "0x".
445 show_base_len = 2;
446 }
447 }
448 else { // Decimal
449 #if defined(__GNUC__) && !defined(__STRICT_ANSI__)
450 // Optimization: Only use long long when we need to.
451 while (val > UINT_MAX) {
452 *--buf_ptr = (val % 10) + '0';
453 val /= 10;
454 }
455 // Use more efficient (int) arithmetic for the rest.
456 register unsigned int ival = (unsigned int)val;
457 #else
458 register unsigned LONGEST ival = val;
459 #endif
460 do {
461 *--buf_ptr = (ival % 10) + '0';
462 ival /= 10;
463 } while (ival != 0);
464 if (sign > 0 && (stream.flags() & ios::showpos))
465 show_pos=1;
466 }
467
468 int buf_len = buf+WRITE_BUF_SIZE - buf_ptr;
469 int w = stream.width(0);
470
471 // Calculate padding.
472 int len = buf_len+show_pos;
473 if (sign < 0) len++;
474 len += show_base_len;
475 int padding = len > w ? 0 : w - len;
476
477 // Do actual output.
478 register streambuf* sbuf = stream.rdbuf();
479 ios::fmtflags pad_kind =
480 stream.flags() & (ios::left|ios::right|ios::internal);
481 char fill_char = stream.fill();
482 if (padding > 0
483 && pad_kind != (ios::fmtflags)ios::left
484 && pad_kind != (ios::fmtflags)ios::internal) // Default (right) adjust.
485 if (_IO_padn(sbuf, fill_char, padding) < padding)
486 goto failed;
487 if (sign < 0 || show_pos)
488 {
489 char ch = sign < 0 ? '-' : '+';
490 if (sbuf->sputc(ch) < 0)
491 goto failed;
492 }
493 if (show_base_len)
494 if (_IO_sputn(sbuf, show_base, show_base_len) <= 0)
495 goto failed;
496 if (pad_kind == (ios::fmtflags)ios::internal && padding > 0)
497 if (_IO_padn(sbuf, fill_char, padding) < padding)
498 goto failed;
499 if (_IO_sputn (sbuf, buf_ptr, buf_len) != buf_len)
500 goto failed;
501 if (pad_kind == (ios::fmtflags)ios::left && padding > 0) // Left adjustment
502 if (_IO_padn(sbuf, fill_char, padding) < padding)
503 goto failed;
504 stream.osfx();
505 return;
506 failed:
507 stream.set(ios::badbit);
508 stream.osfx();
509 }
510
511 ostream& ostream::operator<<(int n)
512 {
513 if (opfx()) {
514 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
515 _strbuf);
516 int sign = 1;
517 unsigned int abs_n = (unsigned)n;
518 if (n < 0 && (flags() & (ios::oct|ios::hex)) == 0)
519 abs_n = -((unsigned)n), sign = -1;
520 write_int(*this, abs_n, sign);
521 _IO_cleanup_region_end (0);
522 }
523 return *this;
524 }
525
526 ostream& ostream::operator<<(unsigned int n)
527 {
528 if (opfx()) {
529 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
530 _strbuf);
531 write_int(*this, n, 0);
532 _IO_cleanup_region_end (0);
533 }
534 return *this;
535 }
536
537
538 ostream& ostream::operator<<(long n)
539 {
540 if (opfx()) {
541 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
542 _strbuf);
543 int sign = 1;
544 unsigned long abs_n = (unsigned long)n;
545 if (n < 0 && (flags() & (ios::oct|ios::hex)) == 0)
546 abs_n = -((unsigned long)n), sign = -1;
547 write_int(*this, abs_n, sign);
548 _IO_cleanup_region_end (0);
549 }
550 return *this;
551 }
552
553 ostream& ostream::operator<<(unsigned long n)
554 {
555 if (opfx()) {
556 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
557 _strbuf);
558 write_int(*this, n, 0);
559 _IO_cleanup_region_end (0);
560 }
561 return *this;
562 }
563
564 #if defined(__GNUC__) && !defined(__STRICT_ANSI__)
565 ostream& ostream::operator<<(long long n)
566 {
567 if (opfx()) {
568 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
569 _strbuf);
570 int sign = 1;
571 unsigned long long abs_n = (unsigned long long)n;
572 if (n < 0 && (flags() & (ios::oct|ios::hex)) == 0)
573 abs_n = -((unsigned long long)n), sign = -1;
574 write_int(*this, abs_n, sign);
575 _IO_cleanup_region_end (0);
576 }
577 return *this;
578 }
579
580
581 ostream& ostream::operator<<(unsigned long long n)
582 {
583 if (opfx()) {
584 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
585 _strbuf);
586 write_int(*this, n, 0);
587 _IO_cleanup_region_end (0);
588 }
589 return *this;
590 }
591 #endif /*__GNUC__*/
592
593 ostream& ostream::operator<<(double n)
594 {
595 if (opfx()) {
596 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
597 _strbuf);
598 // Uses __cvt_double (renamed from static cvt), in Chris Torek's
599 // stdio implementation. The setup code uses the same logic
600 // as in __vsbprintf.C (also based on Torek's code).
601 int format_char;
602 if ((flags() & ios::floatfield) == ios::fixed)
603 format_char = 'f';
604 else if ((flags() & ios::floatfield) == ios::scientific)
605 format_char = flags() & ios::uppercase ? 'E' : 'e';
606 else
607 format_char = flags() & ios::uppercase ? 'G' : 'g';
608
609 int prec = precision();
610 if (prec <= 0 && !(flags() & ios::fixed))
611 prec = 6; /* default */
612
613 // Do actual conversion.
614 #ifdef _G_HAVE_PRINTF_FP
615 {
616 struct printf_info info = { prec: prec,
617 width: width(0),
618 spec: format_char,
619 is_long_double: 0,
620 is_short: 0,
621 is_long: 0,
622 alt: flags() & ios::showpoint,
623 space: 0,
624 left: ios::left,
625 showsign: flags() & ios::showpos,
626 group: 0,
627 pad: fill(),
628 extra: 0};
629 const void *ptr = &n;
630 if (__printf_fp (rdbuf(), &info, &ptr) < 0)
631 set(ios::badbit|ios::failbit);
632 }
633 #elif defined _IO_USE_DTOA
634 if (_IO_outfloat(n, rdbuf(), format_char, width(0),
635 prec, flags(),
636 flags() & ios::showpos ? '+' : 0,
637 fill()) < 0)
638 set(ios::badbit|ios::failbit); // ??
639 #else
640 int fpprec = 0; // 'Extra' (suppressed) floating precision.
641 if (prec > MAXFRACT) {
642 if (flags() & (ios::fixed|ios::scientific) & ios::showpos)
643 fpprec = prec - MAXFRACT;
644 prec = MAXFRACT;
645 }
646 int negative;
647 char buf[BUF];
648 int sign = '\0';
649 char *cp = buf;
650 *cp = 0;
651 int size = __cvt_double(n, prec,
652 flags() & ios::showpoint ? 0x80 : 0,
653 &negative,
654 format_char, cp, buf + sizeof(buf));
655 if (negative) sign = '-';
656 else if (flags() & ios::showpos) sign = '+';
657 if (*cp == 0)
658 cp++;
659
660 // Calculate padding.
661 int fieldsize = size + fpprec;
662 if (sign) fieldsize++;
663 int padding = 0;
664 int w = width(0);
665 if (fieldsize < w)
666 padding = w - fieldsize;
667
668 // Do actual output.
669 register streambuf* sbuf = rdbuf();
670 register i;
671 char fill_char = fill();
672 ios::fmtflags pad_kind =
673 flags() & (ios::left|ios::right|ios::internal);
674 if (pad_kind != (ios::fmtflags)ios::left // Default (right) adjust.
675 && pad_kind != (ios::fmtflags)ios::internal)
676 for (i = padding; --i >= 0; ) sbuf->sputc(fill_char);
677 if (sign)
678 sbuf->sputc(sign);
679 if (pad_kind == (ios::fmtflags)ios::internal)
680 for (i = padding; --i >= 0; ) sbuf->sputc(fill_char);
681
682 // Emit the actual concented field, followed by extra zeros.
683 _IO_sputn (sbuf, cp, size);
684 for (i = fpprec; --i >= 0; ) sbuf->sputc('0');
685
686 if (pad_kind == (ios::fmtflags)ios::left) // Left adjustment
687 for (i = padding; --i >= 0; ) sbuf->sputc(fill_char);
688 #endif
689 osfx();
690 _IO_cleanup_region_end (0);
691 }
692 return *this;
693 }
694
695 #if _G_HAVE_LONG_DOUBLE_IO
696 ostream& ostream::operator<<(long double n)
697 {
698 if (opfx())
699 {
700 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
701 _strbuf);
702 int format_char;
703 if ((flags() & ios::floatfield) == ios::fixed)
704 format_char = 'f';
705 else if ((flags() & ios::floatfield) == ios::scientific)
706 format_char = flags() & ios::uppercase ? 'E' : 'e';
707 else
708 format_char = flags() & ios::uppercase ? 'G' : 'g';
709
710 int prec = precision();
711 if (prec <= 0 && !(flags() & ios::fixed))
712 prec = 6; /* default */
713
714 #ifdef _G_HAVE_PRINTF_FP
715 // Do actual conversion.
716 struct printf_info info = { prec: prec,
717 width: width(0),
718 spec: format_char,
719 is_long_double: 1,
720 is_short: 0,
721 is_long: 0,
722 alt: flags() & ios::showpoint,
723 space: 0,
724 left: ios::left,
725 showsign: flags() & ios::showpos,
726 group: 0,
727 pad: fill(),
728 extra: 0};
729
730 const void *ptr = &n;
731
732 if (__printf_fp (rdbuf(), &info, &ptr) < 0)
733 set (ios::badbit|ios::failbit);
734 #else
735 # error "long double I/O using dtoa or cvt_double is not implemented"
736 #endif
737 osfx();
738 _IO_cleanup_region_end (0);
739 }
740 return *this;
741 }
742 #endif
743
744 ostream& ostream::operator<<(const char *s)
745 {
746 if (opfx())
747 {
748 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
749 _strbuf);
750 if (s == NULL)
751 s = "(null)";
752 int len = strlen(s);
753 int w = width(0);
754 // FIXME: Should we: if (w && len>w) len = w;
755 char fill_char = fill();
756 register streambuf *sbuf = rdbuf();
757 register int padding = w > len ? w - len : 0;
758 if (!(flags() & ios::left) && padding > 0) // Default adjustment.
759 if (_IO_padn(sbuf, fill_char, padding) != padding)
760 {
761 set(ios::badbit);
762 goto failed;
763 }
764 if (_IO_sputn (sbuf, s, len) != len)
765 {
766 set(ios::badbit);
767 goto failed;
768 }
769 if (flags() & ios::left && padding > 0) // Left adjustment.
770 if (_IO_padn(sbuf, fill_char, padding) != padding)
771 set(ios::badbit);
772 osfx();
773 failed:
774 _IO_cleanup_region_end (0);
775 }
776 return *this;
777 }
778
779 #if 0
780 ostream& ostream::operator<<(const void *p)
781 { Is in osform.cc, to avoid pulling in all of _IO_vfprintf by this file. */ }
782 #endif
783
784 ostream& ostream::operator<<(register streambuf* sbuf)
785 {
786 if (opfx())
787 {
788 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
789 _strbuf);
790 char buffer[_IO_BUFSIZ];
791 register streambuf* outbuf = _strbuf;
792 for (;;)
793 {
794 _IO_size_t count = _IO_sgetn(sbuf, buffer, _IO_BUFSIZ);
795 if (count <= 0)
796 break;
797 if (_IO_sputn(outbuf, buffer, count) != count)
798 {
799 set(ios::badbit);
800 break;
801 }
802 }
803 osfx();
804 _IO_cleanup_region_end (0);
805 }
806 return *this;
807 }
808
809 ostream::ostream(streambuf* sb, ostream* tied)
810 {
811 init (sb, tied);
812 }
813
814 ostream& ostream::seekp(streampos pos)
815 {
816 pos = _strbuf->pubseekpos(pos, ios::out);
817 if (pos == streampos(EOF))
818 set(ios::badbit);
819 return *this;
820 }
821
822 ostream& ostream::seekp(streamoff off, _seek_dir dir)
823 {
824 streampos pos = _IO_seekoff (_strbuf, off, (int) dir, _IOS_OUTPUT);
825 if (pos == streampos(EOF))
826 set(ios::badbit);
827 return *this;
828 }
829
830 streampos ostream::tellp()
831 {
832 #if 1
833 streampos pos = _IO_seekoff (_strbuf, 0, _IO_seek_cur, _IOS_OUTPUT);
834 #else
835 streampos pos = _strbuf->pubseekoff(0, ios::cur, ios::out);
836 #endif
837 if (pos == streampos(EOF))
838 set(ios::badbit);
839 return pos;
840 }
841
842 ostream& ostream::flush()
843 {
844 if (_strbuf->sync())
845 set(ios::badbit);
846 return *this;
847 }
848
849 ostream& flush(ostream& outs)
850 {
851 return outs.flush();
852 }
853
854 istream& ws(istream& ins)
855 {
856 if (ins.ipfx1()) {
857 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
858 ins._strbuf);
859 int ch = skip_ws(ins._strbuf);
860 if (ch == EOF)
861 ins.set(ios::eofbit);
862 else
863 ins._strbuf->sputbackc(ch);
864 ins.isfx();
865 _IO_cleanup_region_end (0);
866 }
867 return ins;
868 }
869
870 // Skip white-space. Return 0 on failure (EOF), or 1 on success.
871 // Differs from ws() manipulator in that failbit is set on EOF.
872 // Called by ipfx() and ipfx0() if needed.
873
874 int istream::_skip_ws()
875 {
876 int ch = skip_ws(_strbuf);
877 if (ch == EOF) {
878 set(ios::eofbit|ios::failbit);
879 return 0;
880 }
881 else {
882 _strbuf->sputbackc(ch);
883 return 1;
884 }
885 }
886
887 ostream& ends(ostream& outs)
888 {
889 outs.put('\0');
890 return outs;
891 }
892
893 ostream& endl(ostream& outs)
894 {
895 return flush(outs.put('\n'));
896 }
897
898 istream& lock(istream& ins)
899 {
900 _IO_flockfile (ins._strbuf);
901 return ins;
902 }
903 istream& unlock(istream& ins)
904 {
905 _IO_funlockfile (ins._strbuf);
906 return ins;
907 }
908 ostream& lock(ostream& outs)
909 {
910 _IO_flockfile (outs._strbuf);
911 return outs;
912 }
913 ostream& unlock(ostream& outs)
914 {
915 _IO_funlockfile (outs._strbuf);
916 return outs;
917 }
918
919
920 ostream& ostream::write(const char *s, streamsize n)
921 {
922 if (opfx()) {
923 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
924 _strbuf);
925 if (_IO_sputn(_strbuf, s, n) != n)
926 set(ios::failbit);
927 osfx();
928 _IO_cleanup_region_end (0);
929 }
930 return *this;
931 }
932
933 void ostream::do_osfx()
934 {
935 if (flags() & ios::unitbuf)
936 flush();
937 if (flags() & ios::stdio) {
938 fflush(stdout);
939 fflush(stderr);
940 }
941 }
942
943 iostream::iostream(streambuf* sb, ostream* tied)
944 {
945 init (sb, tied);
946 }
947
948 // NOTE: extension for compatibility with old libg++.
949 // Not really compatible with fistream::close().
950 #ifdef _STREAM_COMPAT
951 void ios::close()
952 {
953 if (_strbuf->_flags & _IO_IS_FILEBUF)
954 ((struct filebuf*)rdbuf())->close();
955 else if (_strbuf != NULL)
956 rdbuf()->sync();
957 _strbuf = NULL;
958 _state = badbit;
959 }
960
961 int istream::skip(int i)
962 {
963 int old = (_flags & ios::skipws) != 0;
964 if (i)
965 _flags |= ios::skipws;
966 else
967 _flags &= ~ios::skipws;
968 return old;
969 }
970 #endif
This page took 0.07955 seconds and 5 git commands to generate.