1 /* This is part of libio/iostream, providing -*- C++ -*- input/output.
2 Copyright (C) 1993, 1997 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 int ch
= _strbuf
->sbumpc();
76 set(ios::eofbit
|ios::failbit
);
93 if (_tie
&& rdbuf()->in_avail() == 0)
95 int ch
= _strbuf
->sgetc();
101 istream
& istream::ignore(int n
/* = 1 */, int delim
/* = EOF */)
105 register streambuf
* sb
= _strbuf
;
107 _gcount
= sb
->ignore(n
);
112 if (n
!= MAXINT
) // FIXME
116 int ch
= sb
->sbumpc();
118 set(ios::eofbit
|ios::failbit
);
129 istream
& istream::read(char *s
, streamsize n
)
132 _gcount
= _strbuf
->sgetn(s
, n
);
134 set(ios::failbit
|ios::eofbit
);
144 streambuf
*sb
= rdbuf ();
147 if (sb
->sync ()) // Later: pubsync
149 setstate (ios::badbit
);
156 istream
& istream::seekg(streampos pos
)
158 pos
= _strbuf
->pubseekpos(pos
, ios::in
);
159 if (pos
== streampos(EOF
))
164 istream
& istream::seekg(streamoff off
, _seek_dir dir
)
166 streampos pos
= _IO_seekoff (_strbuf
, off
, (int) dir
, _IOS_INPUT
);
167 if (pos
== streampos(EOF
))
172 streampos
istream::tellg()
175 streampos pos
= _strbuf
->pubseekoff(0, ios::cur
, ios::in
);
177 streampos pos
= _IO_seekoff (_strbuf
, 0, _IO_seek_cur
, _IOS_INPUT
);
179 if (pos
== streampos(EOF
))
184 istream
& istream::operator>>(char& c
)
187 int ch
= _strbuf
->sbumpc();
189 set(ios::eofbit
|ios::failbit
);
197 istream::operator>> (char* ptr
)
199 register char *p
= ptr
;
203 register streambuf
* sb
= _strbuf
;
206 int ch
= sb
->sbumpc();
212 else if (isspace(ch
) || w
== 1)
227 #if defined(__GNUC__) && !defined(__STRICT_ANSI__)
228 #define LONGEST long long
233 static int read_int(istream
& stream
, unsigned LONGEST
& val
, int& neg
)
237 register streambuf
* sb
= stream
.rdbuf();
240 register int ch
= skip_ws(sb
);
247 else if (ch
== '-') {
251 if (ch
== EOF
) goto eof_fail
;
252 if (!(stream
.flags() & ios::basefield
)) {
259 if (ch
== 'x' || ch
== 'X') {
262 if (ch
== EOF
) goto eof_fail
;
271 else if ((stream
.flags() & ios::basefield
) == ios::hex
)
273 else if ((stream
.flags() & ios::basefield
) == ios::oct
)
280 if (ch
>= '0' && ch
<= '9')
282 else if (ch
>= 'A' && ch
<= 'F')
283 digit
= ch
- 'A' + 10;
284 else if (ch
>= 'a' && ch
<= 'f')
285 digit
= ch
- 'a' + 10;
296 val
= base
* val
+ digit
;
301 stream
.set(ios::failbit
);
304 stream
.set(ios::failbit
|ios::eofbit
);
308 #define READ_INT(TYPE) \
309 istream& istream::operator>>(TYPE& i)\
311 unsigned LONGEST val; int neg;\
312 if (read_int(*this, val, neg)) {\
313 if (neg) val = -val;\
320 READ_INT(unsigned short)
322 READ_INT(unsigned int)
324 READ_INT(unsigned long)
325 #if defined(__GNUC__) && !defined(__STRICT_ANSI__)
327 READ_INT(unsigned long long)
333 istream
& istream::operator>>(long double& x
)
337 #if _G_HAVE_LONG_DOUBLE_IO
348 istream
& istream::operator>>(double& x
)
355 istream
& istream::operator>>(float& x
)
362 istream
& istream::operator>>(register streambuf
* sbuf
)
365 register streambuf
* inbuf
= rdbuf();
366 // FIXME: Should optimize!
368 register int ch
= inbuf
->sbumpc();
373 if (sbuf
->sputc(ch
) == EOF
) {
382 ostream
& ostream::operator<<(char c
)
385 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile
,
388 // This is what the cfront implementation does.
389 if (_strbuf
->sputc(c
) == EOF
) {
394 // This is what cfront documentation and current ANSI drafts say.
396 char fill_char
= fill();
397 register int padding
= w
> 0 ? w
- 1 : 0;
398 register streambuf
*sb
= _strbuf
;
399 if (!(flags() & ios::left
) && padding
) // Default adjustment.
400 if (_IO_padn(sb
, fill_char
, padding
) < padding
) {
404 if (sb
->sputc(c
) == EOF
) {
408 if (flags() & ios::left
&& padding
) // Left adjustment.
409 if (_IO_padn(sb
, fill_char
, padding
) < padding
)
414 _IO_cleanup_region_end (0);
419 /* Write VAL on STREAM.
420 If SIGN<0, val is the absolute value of a negative number.
421 If SIGN>0, val is a signed non-negative number.
422 If SIGN==0, val is unsigned. */
424 static void write_int(ostream
& stream
, unsigned LONGEST val
, int sign
)
426 #define WRITE_BUF_SIZE (10 + sizeof(unsigned LONGEST) * 3)
427 char buf
[WRITE_BUF_SIZE
];
428 register char *buf_ptr
= buf
+WRITE_BUF_SIZE
; // End of buf.
429 const char *show_base
= "";
430 int show_base_len
= 0;
431 int show_pos
= 0; // If 1, print a '+'.
433 // Now do the actual conversion, placing the result at the *end* of buf.
434 // Note that we use separate code for decimal, octal, and hex,
435 // so we can divide by optimizable constants.
436 if ((stream
.flags() & ios::basefield
) == ios::oct
) { // Octal
438 *--buf_ptr
= (val
& 7) + '0';
441 if ((stream
.flags() & ios::showbase
) && (*buf_ptr
!= '0'))
444 else if ((stream
.flags() & ios::basefield
) == ios::hex
) { // Hex
445 const char *xdigs
= (stream
.flags() & ios::uppercase
) ? "0123456789ABCDEF0X"
446 : "0123456789abcdef0x";
448 *--buf_ptr
= xdigs
[val
& 15];
451 if ((stream
.flags() & ios::showbase
)) {
452 show_base
= xdigs
+ 16; // Either "0X" or "0x".
457 #if defined(__GNUC__) && !defined(__STRICT_ANSI__)
458 // Optimization: Only use long long when we need to.
459 while (val
> UINT_MAX
) {
460 *--buf_ptr
= (val
% 10) + '0';
463 // Use more efficient (int) arithmetic for the rest.
464 register unsigned int ival
= (unsigned int)val
;
466 register unsigned LONGEST ival
= val
;
469 *--buf_ptr
= (ival
% 10) + '0';
472 if (sign
> 0 && (stream
.flags() & ios::showpos
))
476 int buf_len
= buf
+WRITE_BUF_SIZE
- buf_ptr
;
477 int w
= stream
.width(0);
479 // Calculate padding.
480 int len
= buf_len
+show_pos
;
482 len
+= show_base_len
;
483 int padding
= len
> w
? 0 : w
- len
;
486 register streambuf
* sbuf
= stream
.rdbuf();
487 ios::fmtflags pad_kind
=
488 stream
.flags() & (ios::left
|ios::right
|ios::internal
);
489 char fill_char
= stream
.fill();
491 && pad_kind
!= (ios::fmtflags
)ios::left
492 && pad_kind
!= (ios::fmtflags
)ios::internal
) // Default (right) adjust.
493 if (_IO_padn(sbuf
, fill_char
, padding
) < padding
)
495 if (sign
< 0 || show_pos
)
497 char ch
= sign
< 0 ? '-' : '+';
498 if (sbuf
->sputc(ch
) < 0)
502 if (_IO_sputn(sbuf
, show_base
, show_base_len
) <= 0)
504 if (pad_kind
== (ios::fmtflags
)ios::internal
&& padding
> 0)
505 if (_IO_padn(sbuf
, fill_char
, padding
) < padding
)
507 if (_IO_sputn (sbuf
, buf_ptr
, buf_len
) != buf_len
)
509 if (pad_kind
== (ios::fmtflags
)ios::left
&& padding
> 0) // Left adjustment
510 if (_IO_padn(sbuf
, fill_char
, padding
) < padding
)
515 stream
.set(ios::badbit
);
519 ostream
& ostream::operator<<(int n
)
522 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile
,
525 unsigned int abs_n
= (unsigned)n
;
526 if (n
< 0 && (flags() & (ios::oct
|ios::hex
)) == 0)
527 abs_n
= -((unsigned)n
), sign
= -1;
528 write_int(*this, abs_n
, sign
);
529 _IO_cleanup_region_end (0);
534 ostream
& ostream::operator<<(unsigned int n
)
537 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile
,
539 write_int(*this, n
, 0);
540 _IO_cleanup_region_end (0);
546 ostream
& ostream::operator<<(long n
)
549 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile
,
552 unsigned long abs_n
= (unsigned long)n
;
553 if (n
< 0 && (flags() & (ios::oct
|ios::hex
)) == 0)
554 abs_n
= -((unsigned long)n
), sign
= -1;
555 write_int(*this, abs_n
, sign
);
556 _IO_cleanup_region_end (0);
561 ostream
& ostream::operator<<(unsigned long n
)
564 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile
,
566 write_int(*this, n
, 0);
567 _IO_cleanup_region_end (0);
572 #if defined(__GNUC__) && !defined(__STRICT_ANSI__)
573 ostream
& ostream::operator<<(long long n
)
576 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile
,
579 unsigned long long abs_n
= (unsigned long long)n
;
580 if (n
< 0 && (flags() & (ios::oct
|ios::hex
)) == 0)
581 abs_n
= -((unsigned long long)n
), sign
= -1;
582 write_int(*this, abs_n
, sign
);
583 _IO_cleanup_region_end (0);
589 ostream
& ostream::operator<<(unsigned long long n
)
592 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile
,
594 write_int(*this, n
, 0);
595 _IO_cleanup_region_end (0);
601 ostream
& ostream::operator<<(double n
)
604 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile
,
606 // Uses __cvt_double (renamed from static cvt), in Chris Torek's
607 // stdio implementation. The setup code uses the same logic
608 // as in __vsbprintf.C (also based on Torek's code).
610 if ((flags() & ios::floatfield
) == ios::fixed
)
612 else if ((flags() & ios::floatfield
) == ios::scientific
)
613 format_char
= flags() & ios::uppercase
? 'E' : 'e';
615 format_char
= flags() & ios::uppercase
? 'G' : 'g';
617 int prec
= precision();
618 if (prec
<= 0 && !(flags() & ios::fixed
))
619 prec
= 6; /* default */
621 // Do actual conversion.
622 #if _G_HAVE_PRINTF_FP
624 struct printf_info info
= { /* prec: */ prec
,
625 /* width: */ width(0),
626 /* spec: */ format_char
,
627 /* is_long_double: */ 0,
630 /* alt: */ (flags() & ios::showpoint
) != 0,
632 /* left: */ (flags() & ios::left
) != 0,
633 /* showsign: */ (flags() & ios::showpos
) != 0,
635 #if defined __GLIBC__ && __GLIBC__ >= 2
637 #if __GLIBC_MINOR__ >= 1
643 const void *ptr
= (const void *) &n
;
644 if (__printf_fp (rdbuf(), &info
, &ptr
) < 0)
645 set(ios::badbit
|ios::failbit
);
647 #elif defined _IO_USE_DTOA
648 if (_IO_outfloat(n
, rdbuf(), format_char
, width(0),
650 flags() & ios::showpos
? '+' : 0,
652 set(ios::badbit
|ios::failbit
); // ??
654 int fpprec
= 0; // 'Extra' (suppressed) floating precision.
655 if (prec
> MAXFRACT
) {
656 if (flags() & (ios::fixed
|ios::scientific
) & ios::showpos
)
657 fpprec
= prec
- MAXFRACT
;
665 int size
= __cvt_double(n
, prec
,
666 flags() & ios::showpoint
? 0x80 : 0,
668 format_char
, cp
, buf
+ sizeof(buf
));
669 if (negative
) sign
= '-';
670 else if (flags() & ios::showpos
) sign
= '+';
674 // Calculate padding.
675 int fieldsize
= size
+ fpprec
;
676 if (sign
) fieldsize
++;
680 padding
= w
- fieldsize
;
683 register streambuf
* sbuf
= rdbuf();
685 char fill_char
= fill();
686 ios::fmtflags pad_kind
=
687 flags() & (ios::left
|ios::right
|ios::internal
);
688 if (pad_kind
!= (ios::fmtflags
)ios::left
// Default (right) adjust.
689 && pad_kind
!= (ios::fmtflags
)ios::internal
)
690 for (i
= padding
; --i
>= 0; ) sbuf
->sputc(fill_char
);
693 if (pad_kind
== (ios::fmtflags
)ios::internal
)
694 for (i
= padding
; --i
>= 0; ) sbuf
->sputc(fill_char
);
696 // Emit the actual concented field, followed by extra zeros.
697 _IO_sputn (sbuf
, cp
, size
);
698 for (i
= fpprec
; --i
>= 0; ) sbuf
->sputc('0');
700 if (pad_kind
== (ios::fmtflags
)ios::left
) // Left adjustment
701 for (i
= padding
; --i
>= 0; ) sbuf
->sputc(fill_char
);
704 _IO_cleanup_region_end (0);
709 #if _G_HAVE_LONG_DOUBLE_IO
710 ostream
& ostream::operator<<(long double n
)
714 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile
,
717 if ((flags() & ios::floatfield
) == ios::fixed
)
719 else if ((flags() & ios::floatfield
) == ios::scientific
)
720 format_char
= flags() & ios::uppercase
? 'E' : 'e';
722 format_char
= flags() & ios::uppercase
? 'G' : 'g';
724 int prec
= precision();
725 if (prec
<= 0 && !(flags() & ios::fixed
))
726 prec
= 6; /* default */
728 #if _G_HAVE_PRINTF_FP
729 // Do actual conversion.
730 struct printf_info info
= { /* prec: */ prec
,
731 /* width: */ width(0),
732 /* spec: */ format_char
,
733 /* is_long_double: */ 1,
736 /* alt: */ (flags() & ios::showpoint
) != 0,
738 /* left: */ (flags() & ios::left
) != 0,
739 /* showsign: */ (flags() & ios::showpos
) != 0,
741 #if defined __GLIBC__ && __GLIBC__ >= 2
743 #if __GLIBC_MINOR__ >= 1
750 const void *ptr
= (const void *) &n
;
752 if (__printf_fp (rdbuf(), &info
, &ptr
) < 0)
753 set (ios::badbit
|ios::failbit
);
755 # error "long double I/O using dtoa or cvt_double is not implemented"
758 _IO_cleanup_region_end (0);
764 ostream
& ostream::operator<<(const char *s
)
768 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile
,
774 // FIXME: Should we: if (w && len>w) len = w;
775 char fill_char
= fill();
776 register streambuf
*sbuf
= rdbuf();
777 register int padding
= w
> len
? w
- len
: 0;
778 if (!(flags() & ios::left
) && padding
> 0) // Default adjustment.
779 if (_IO_padn(sbuf
, fill_char
, padding
) != padding
)
784 if (_IO_sputn (sbuf
, s
, len
) != len
)
789 if (flags() & ios::left
&& padding
> 0) // Left adjustment.
790 if (_IO_padn(sbuf
, fill_char
, padding
) != padding
)
794 _IO_cleanup_region_end (0);
800 ostream
& ostream::operator<<(const void *p
)
801 { Is in osform
.cc
, to avoid pulling in all of _IO_vfprintf by
this file
. */
}
804 ostream
& ostream::operator<<(register streambuf
* sbuf
)
808 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile
,
810 char buffer
[_IO_BUFSIZ
];
811 register streambuf
* outbuf
= _strbuf
;
814 _IO_size_t count
= _IO_sgetn(sbuf
, buffer
, _IO_BUFSIZ
);
817 if (_IO_sputn(outbuf
, buffer
, count
) != count
)
824 _IO_cleanup_region_end (0);
829 ostream::ostream(streambuf
* sb
, ostream
* tied
)
834 ostream
& ostream::seekp(streampos pos
)
836 pos
= _strbuf
->pubseekpos(pos
, ios::out
);
837 if (pos
== streampos(EOF
))
842 ostream
& ostream::seekp(streamoff off
, _seek_dir dir
)
844 streampos pos
= _IO_seekoff (_strbuf
, off
, (int) dir
, _IOS_OUTPUT
);
845 if (pos
== streampos(EOF
))
850 streampos
ostream::tellp()
853 streampos pos
= _IO_seekoff (_strbuf
, 0, _IO_seek_cur
, _IOS_OUTPUT
);
855 streampos pos
= _strbuf
->pubseekoff(0, ios::cur
, ios::out
);
857 if (pos
== streampos(EOF
))
862 ostream
& ostream::flush()
869 ostream
& flush(ostream
& outs
)
874 istream
& ws(istream
& ins
)
877 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile
,
879 int ch
= skip_ws(ins
._strbuf
);
881 ins
.set(ios::eofbit
);
883 ins
._strbuf
->sputbackc(ch
);
885 _IO_cleanup_region_end (0);
890 // Skip white-space. Return 0 on failure (EOF), or 1 on success.
891 // Differs from ws() manipulator in that failbit is set on EOF.
892 // Called by ipfx() and ipfx0() if needed.
894 int istream::_skip_ws()
896 int ch
= skip_ws(_strbuf
);
898 set(ios::eofbit
|ios::failbit
);
902 _strbuf
->sputbackc(ch
);
907 ostream
& ends(ostream
& outs
)
913 ostream
& endl(ostream
& outs
)
915 return flush(outs
.put('\n'));
918 istream
& lock(istream
& ins
)
920 _IO_flockfile (ins
._strbuf
);
923 istream
& unlock(istream
& ins
)
925 _IO_funlockfile (ins
._strbuf
);
928 ostream
& lock(ostream
& outs
)
930 _IO_flockfile (outs
._strbuf
);
933 ostream
& unlock(ostream
& outs
)
935 _IO_funlockfile (outs
._strbuf
);
940 ostream
& ostream::write(const char *s
, streamsize n
)
943 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile
,
945 if (_IO_sputn(_strbuf
, s
, n
) != n
)
948 _IO_cleanup_region_end (0);
953 void ostream::do_osfx()
955 if (flags() & ios::unitbuf
)
957 if (flags() & ios::stdio
) {
963 iostream::iostream(streambuf
* sb
, ostream
* tied
)
968 // NOTE: extension for compatibility with old libg++.
969 // Not really compatible with fistream::close().
970 #ifdef _STREAM_COMPAT
973 if (_strbuf
->_flags
& _IO_IS_FILEBUF
)
974 ((struct filebuf
*)rdbuf())->close();
975 else if (_strbuf
!= NULL
)
981 int istream::skip(int i
)
983 int old
= (_flags
& ios::skipws
) != 0;
985 _flags
|= ios::skipws
;
987 _flags
&= ~ios::skipws
;