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)
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,
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). */
29 #pragma implementation
31 #define _STREAM_COMPAT
34 #include <stdio.h> /* Needed for sprintf */
41 extern "C" int __printf_fp (_IO_FILE
*, const struct printf_info
*,
46 int __cvt_double(double number
, register int prec
, int flags
, int *signp
,
47 int fmtch
, char *startp
, char *endp
);
51 #define BUF (MAXEXP+MAXFRACT+1) /* + decimal point */
53 //#define isspace(ch) ((ch)==' ' || (ch)=='\t' || (ch)=='\n')
55 istream::istream(streambuf
*sb
, ostream
* tied
)
61 int skip_ws(streambuf
* sb
)
66 if (ch
== EOF
|| !isspace(ch
))
71 istream
& istream::get(char& c
)
74 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile
,
76 int ch
= _strbuf
->sbumpc();
78 set(ios::eofbit
|ios::failbit
);
86 _IO_cleanup_region_end (0);
97 if (_tie
&& rdbuf()->in_avail() == 0)
99 int ch
= _strbuf
->sgetc();
105 istream
& istream::ignore(int n
/* = 1 */, int delim
/* = EOF */)
109 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile
,
111 register streambuf
* sb
= _strbuf
;
113 _gcount
= sb
->ignore(n
);
118 if (n
!= MAXINT
) // FIXME
122 int ch
= sb
->sbumpc();
124 set(ios::eofbit
|ios::failbit
);
133 _IO_cleanup_region_end (0);
138 istream
& istream::read(char *s
, streamsize n
)
141 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile
,
143 _gcount
= _strbuf
->sgetn(s
, n
);
145 set(ios::failbit
|ios::eofbit
);
147 _IO_cleanup_region_end (0);
157 streambuf
*sb
= rdbuf ();
160 if (sb
->sync ()) // Later: pubsync
162 setstate (ios::badbit
);
169 istream
& istream::seekg(streampos pos
)
171 pos
= _strbuf
->pubseekpos(pos
, ios::in
);
172 if (pos
== streampos(EOF
))
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
))
185 streampos
istream::tellg()
188 streampos pos
= _strbuf
->pubseekoff(0, ios::cur
, ios::in
);
190 streampos pos
= _IO_seekoff (_strbuf
, 0, _IO_seek_cur
, _IOS_INPUT
);
192 if (pos
== streampos(EOF
))
197 istream
& istream::operator>>(char& c
)
200 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile
,
202 int ch
= _strbuf
->sbumpc();
204 set(ios::eofbit
|ios::failbit
);
208 _IO_cleanup_region_end (0);
214 istream::operator>> (char* ptr
)
216 register char *p
= ptr
;
220 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile
,
222 register streambuf
* sb
= _strbuf
;
225 int ch
= sb
->sbumpc();
231 else if (isspace(ch
) || w
== 1)
242 _IO_cleanup_region_end (0);
248 #if defined(__GNUC__) && !defined(__STRICT_ANSI__)
249 #define LONGEST long long
254 static int read_int(istream
& stream
, unsigned LONGEST
& val
, int& neg
)
259 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile
,
261 register streambuf
* sb
= stream
.rdbuf();
264 register int ch
= skip_ws(sb
);
271 else if (ch
== '-') {
275 if (ch
== EOF
) goto eof_fail
;
276 if (!(stream
.flags() & ios::basefield
)) {
283 if (ch
== 'x' || ch
== 'X') {
286 if (ch
== EOF
) goto eof_fail
;
295 else if ((stream
.flags() & ios::basefield
) == ios::hex
)
297 else if ((stream
.flags() & ios::basefield
) == ios::oct
)
304 if (ch
>= '0' && ch
<= '9')
306 else if (ch
>= 'A' && ch
<= 'F')
307 digit
= ch
- 'A' + 10;
308 else if (ch
>= 'a' && ch
<= 'f')
309 digit
= ch
- 'a' + 10;
320 val
= base
* val
+ digit
;
327 stream
.set(ios::failbit
);
331 stream
.set(ios::failbit
|ios::eofbit
);
335 _IO_cleanup_region_end (0);
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;\
351 READ_INT(unsigned short)
353 READ_INT(unsigned int)
355 READ_INT(unsigned long)
356 #if defined(__GNUC__) && !defined(__STRICT_ANSI__)
358 READ_INT(unsigned long long)
364 istream
& istream::operator>>(long double& x
)
368 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile
,
370 #if _G_HAVE_LONG_DOUBLE_IO
378 _IO_cleanup_region_end (0);
383 istream
& istream::operator>>(double& x
)
387 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile
,
391 _IO_cleanup_region_end (0);
396 istream
& istream::operator>>(float& x
)
400 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile
,
404 _IO_cleanup_region_end (0);
409 istream
& istream::operator>>(register streambuf
* sbuf
)
412 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile
,
414 register streambuf
* inbuf
= rdbuf();
415 // FIXME: Should optimize!
417 register int ch
= inbuf
->sbumpc();
422 if (sbuf
->sputc(ch
) == EOF
) {
428 _IO_cleanup_region_end (0);
433 ostream
& ostream::operator<<(char c
)
436 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile
,
439 // This is what the cfront implementation does.
440 if (_strbuf
->sputc(c
) == EOF
) {
445 // This is what cfront documentation and current ANSI drafts say.
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
) {
455 if (sb
->sputc(c
) == EOF
) {
459 if (flags() & ios::left
&& padding
) // Left adjustment.
460 if (_IO_padn(sb
, fill_char
, padding
) < padding
)
465 _IO_cleanup_region_end (0);
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
489 *--buf_ptr
= (val
& 7) + '0';
492 if ((stream
.flags() & ios::showbase
) && (*buf_ptr
!= '0'))
495 else if ((stream
.flags() & ios::basefield
) == ios::hex
) { // Hex
496 const char *xdigs
= (stream
.flags() & ios::uppercase
) ? "0123456789ABCDEF0X"
497 : "0123456789abcdef0x";
499 *--buf_ptr
= xdigs
[val
& 15];
502 if ((stream
.flags() & ios::showbase
)) {
503 show_base
= xdigs
+ 16; // Either "0X" or "0x".
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';
514 // Use more efficient (int) arithmetic for the rest.
515 register unsigned int ival
= (unsigned int)val
;
517 register unsigned LONGEST ival
= val
;
520 *--buf_ptr
= (ival
% 10) + '0';
523 if (sign
> 0 && (stream
.flags() & ios::showpos
))
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
;
533 len
+= show_base_len
;
534 int padding
= len
> w
? 0 : w
- len
;
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();
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
)
546 if (sign
< 0 || show_pos
)
548 char ch
= sign
< 0 ? '-' : '+';
549 if (sbuf
->sputc(ch
) < 0)
553 if (_IO_sputn(sbuf
, show_base
, show_base_len
) <= 0)
555 if (pad_kind
== (ios::fmtflags
)ios::internal
&& padding
> 0)
556 if (_IO_padn(sbuf
, fill_char
, padding
) < padding
)
558 if (_IO_sputn (sbuf
, buf_ptr
, buf_len
) != buf_len
)
560 if (pad_kind
== (ios::fmtflags
)ios::left
&& padding
> 0) // Left adjustment
561 if (_IO_padn(sbuf
, fill_char
, padding
) < padding
)
566 stream
.set(ios::badbit
);
570 ostream
& ostream::operator<<(int n
)
573 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile
,
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);
585 ostream
& ostream::operator<<(unsigned int n
)
588 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile
,
590 write_int(*this, n
, 0);
591 _IO_cleanup_region_end (0);
597 ostream
& ostream::operator<<(long n
)
600 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile
,
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);
612 ostream
& ostream::operator<<(unsigned long n
)
615 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile
,
617 write_int(*this, n
, 0);
618 _IO_cleanup_region_end (0);
623 #if defined(__GNUC__) && !defined(__STRICT_ANSI__)
624 ostream
& ostream::operator<<(long long n
)
627 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile
,
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);
640 ostream
& ostream::operator<<(unsigned long long n
)
643 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile
,
645 write_int(*this, n
, 0);
646 _IO_cleanup_region_end (0);
652 ostream
& ostream::operator<<(double n
)
655 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile
,
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).
661 if ((flags() & ios::floatfield
) == ios::fixed
)
663 else if ((flags() & ios::floatfield
) == ios::scientific
)
664 format_char
= flags() & ios::uppercase
? 'E' : 'e';
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,
681 /* alt: */ (flags() & ios::showpoint
) != 0,
683 /* left: */ (flags() & ios::left
) != 0,
684 /* showsign: */ (flags() & ios::showpos
) != 0,
686 #if defined __GLIBC__ && __GLIBC__ >= 2
688 #if __GLIBC_MINOR__ >= 1
690 #if __GLIBC_MINOR__ >= 2
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),
705 flags() & ios::showpos
? '+' : 0,
707 set(ios::badbit
|ios::failbit
); // ??
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
;
720 int size
= __cvt_double(n
, prec
,
721 flags() & ios::showpoint
? 0x80 : 0,
723 format_char
, cp
, buf
+ sizeof(buf
));
724 if (negative
) sign
= '-';
725 else if (flags() & ios::showpos
) sign
= '+';
729 // Calculate padding.
730 int fieldsize
= size
+ fpprec
;
731 if (sign
) fieldsize
++;
735 padding
= w
- fieldsize
;
738 register streambuf
* sbuf
= rdbuf();
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
);
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
);
759 _IO_cleanup_region_end (0);
764 #if _G_HAVE_LONG_DOUBLE_IO
765 ostream
& ostream::operator<<(long double n
)
769 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile
,
772 if ((flags() & ios::floatfield
) == ios::fixed
)
774 else if ((flags() & ios::floatfield
) == ios::scientific
)
775 format_char
= flags() & ios::uppercase
? 'E' : 'e';
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,
791 /* alt: */ (flags() & ios::showpoint
) != 0,
793 /* left: */ (flags() & ios::left
) != 0,
794 /* showsign: */ (flags() & ios::showpos
) != 0,
796 #if defined __GLIBC__ && __GLIBC__ >= 2
798 #if __GLIBC_MINOR__ >= 1
800 #if __GLIBC_MINOR__ >= 2
809 const void *ptr
= (const void *) &n
;
811 if (__printf_fp (rdbuf(), &info
, &ptr
) < 0)
812 set (ios::badbit
|ios::failbit
);
814 # error "long double I/O using dtoa or cvt_double is not implemented"
817 _IO_cleanup_region_end (0);
823 ostream
& ostream::operator<<(const char *s
)
827 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile
,
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
)
843 if (_IO_sputn (sbuf
, s
, len
) != len
)
848 if (flags() & ios::left
&& padding
> 0) // Left adjustment.
849 if (_IO_padn(sbuf
, fill_char
, padding
) != padding
)
853 _IO_cleanup_region_end (0);
859 ostream
& ostream::operator<<(const void *p
)
860 { Is in osform
.cc
, to avoid pulling in all of _IO_vfprintf by
this file
. */
}
863 ostream
& ostream::operator<<(register streambuf
* sbuf
)
867 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile
,
869 char buffer
[_IO_BUFSIZ
];
870 register streambuf
* outbuf
= _strbuf
;
873 _IO_size_t count
= _IO_sgetn(sbuf
, buffer
, _IO_BUFSIZ
);
876 if (_IO_sputn(outbuf
, buffer
, count
) != count
)
883 _IO_cleanup_region_end (0);
888 ostream::ostream(streambuf
* sb
, ostream
* tied
)
893 ostream
& ostream::seekp(streampos pos
)
895 pos
= _strbuf
->pubseekpos(pos
, ios::out
);
896 if (pos
== streampos(EOF
))
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
))
909 streampos
ostream::tellp()
912 streampos pos
= _IO_seekoff (_strbuf
, 0, _IO_seek_cur
, _IOS_OUTPUT
);
914 streampos pos
= _strbuf
->pubseekoff(0, ios::cur
, ios::out
);
916 if (pos
== streampos(EOF
))
921 ostream
& ostream::flush()
928 ostream
& flush(ostream
& outs
)
933 istream
& ws(istream
& ins
)
936 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile
,
938 int ch
= skip_ws(ins
._strbuf
);
940 ins
.set(ios::eofbit
);
942 ins
._strbuf
->sputbackc(ch
);
944 _IO_cleanup_region_end (0);
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
);
957 set(ios::eofbit
|ios::failbit
);
961 _strbuf
->sputbackc(ch
);
966 ostream
& ends(ostream
& outs
)
969 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile
,
973 _IO_cleanup_region_end (0);
978 ostream
& endl(ostream
& outs
)
981 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile
,
983 flush(outs
.put('\n'));
985 _IO_cleanup_region_end (0);
990 istream
& lock(istream
& ins
)
992 _IO_flockfile (ins
._strbuf
);
995 istream
& unlock(istream
& ins
)
997 _IO_funlockfile (ins
._strbuf
);
1000 ostream
& lock(ostream
& outs
)
1002 _IO_flockfile (outs
._strbuf
);
1005 ostream
& unlock(ostream
& outs
)
1007 _IO_funlockfile (outs
._strbuf
);
1012 ostream
& ostream::write(const char *s
, streamsize n
)
1015 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile
,
1017 if (_IO_sputn(_strbuf
, s
, n
) != n
)
1020 _IO_cleanup_region_end (0);
1025 void ostream::do_osfx()
1027 if (flags() & ios::unitbuf
)
1029 if (flags() & ios::stdio
) {
1035 iostream::iostream(streambuf
* sb
, ostream
* tied
)
1040 // NOTE: extension for compatibility with old libg++.
1041 // Not really compatible with fistream::close().
1042 #ifdef _STREAM_COMPAT
1045 if (_strbuf
->_flags
& _IO_IS_FILEBUF
)
1046 ((struct filebuf
*)rdbuf())->close();
1047 else if (_strbuf
!= NULL
)
1053 int istream::skip(int i
)
1055 int old
= (_flags
& ios::skipws
) != 0;
1057 _flags
|= ios::skipws
;
1059 _flags
&= ~ios::skipws
;