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)
336 #if _G_HAVE_LONG_DOUBLE_IO
344 istream& istream::operator>>(double& x)
351 istream& istream::operator>>(float& x)
358 istream& istream::operator>>(register streambuf* sbuf)
361 register streambuf* inbuf = rdbuf();
362 // FIXME: Should optimize!
364 register int ch = inbuf->sbumpc();
369 if (sbuf->sputc(ch) == EOF) {
378 ostream& ostream::operator<<(char c)
381 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
384 // This is what the cfront implementation does.
385 if (_strbuf->sputc(c) == EOF) {
390 // This is what cfront documentation and current ANSI drafts say.
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.
396 if (_IO_padn(sb, fill_char, padding) < padding) {
400 if (sb->sputc(c) == EOF) {
404 if (flags() & ios::left && padding) // Left adjustment.
405 if (_IO_padn(sb, fill_char, padding) < padding)
410 _IO_cleanup_region_end (0);
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. */
420 static void write_int(ostream& stream, unsigned LONGEST val, int sign)
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 '+'.
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
434 *--buf_ptr = (val & 7) + '0';
437 if ((stream.flags() & ios::showbase) && (*buf_ptr != '0'))
440 else if ((stream.flags() & ios::basefield) == ios::hex) { // Hex
441 const char *xdigs = (stream.flags() & ios::uppercase) ? "0123456789ABCDEF0X"
442 : "0123456789abcdef0x";
444 *--buf_ptr = xdigs[val & 15];
447 if ((stream.flags() & ios::showbase)) {
448 show_base = xdigs + 16; // Either "0X" or "0x".
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';
459 // Use more efficient (int) arithmetic for the rest.
460 register unsigned int ival = (unsigned int)val;
462 register unsigned LONGEST ival = val;
465 *--buf_ptr = (ival % 10) + '0';
468 if (sign > 0 && (stream.flags() & ios::showpos))
472 int buf_len = buf+WRITE_BUF_SIZE - buf_ptr;
473 int w = stream.width(0);
475 // Calculate padding.
476 int len = buf_len+show_pos;
478 len += show_base_len;
479 int padding = len > w ? 0 : w - len;
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();
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)
491 if (sign < 0 || show_pos)
493 char ch = sign < 0 ? '-' : '+';
494 if (sbuf->sputc(ch) < 0)
498 if (_IO_sputn(sbuf, show_base, show_base_len) <= 0)
500 if (pad_kind == (ios::fmtflags)ios::internal && padding > 0)
501 if (_IO_padn(sbuf, fill_char, padding) < padding)
503 if (_IO_sputn (sbuf, buf_ptr, buf_len) != buf_len)
505 if (pad_kind == (ios::fmtflags)ios::left && padding > 0) // Left adjustment
506 if (_IO_padn(sbuf, fill_char, padding) < padding)
511 stream.set(ios::badbit);
515 ostream& ostream::operator<<(int n)
518 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
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);
525 _IO_cleanup_region_end (0);
530 ostream& ostream::operator<<(unsigned int n)
533 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
535 write_int(*this, n, 0);
536 _IO_cleanup_region_end (0);
542 ostream& ostream::operator<<(long n)
545 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
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);
552 _IO_cleanup_region_end (0);
557 ostream& ostream::operator<<(unsigned long n)
560 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
562 write_int(*this, n, 0);
563 _IO_cleanup_region_end (0);
568 #if defined(__GNUC__) && !defined(__STRICT_ANSI__)
569 ostream& ostream::operator<<(long long n)
572 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
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);
579 _IO_cleanup_region_end (0);
585 ostream& ostream::operator<<(unsigned long long 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<<(double n)
600 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
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).
606 if ((flags() & ios::floatfield) == ios::fixed)
608 else if ((flags() & ios::floatfield) == ios::scientific)
609 format_char = flags() & ios::uppercase ? 'E' : 'e';
611 format_char = flags() & ios::uppercase ? 'G' : 'g';
613 int prec = precision();
614 if (prec <= 0 && !(flags() & ios::fixed))
615 prec = 6; /* default */
617 // Do actual conversion.
618 #if _G_HAVE_PRINTF_FP
620 struct printf_info info = { prec: prec,
626 alt: (flags() & ios::showpoint) != 0,
628 left: (flags() & ios::left) != 0,
629 showsign: (flags() & ios::showpos) != 0,
632 #if defined __GLIBC__ && __GLIBC__ >= 2
636 const void *ptr = (const void *) &n;
637 if (__printf_fp (rdbuf(), &info, &ptr) < 0)
638 set(ios::badbit|ios::failbit);
640 #elif defined _IO_USE_DTOA
641 if (_IO_outfloat(n, rdbuf(), format_char, width(0),
643 flags() & ios::showpos ? '+' : 0,
645 set(ios::badbit|ios::failbit); // ??
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;
658 int size = __cvt_double(n, prec,
659 flags() & ios::showpoint ? 0x80 : 0,
661 format_char, cp, buf + sizeof(buf));
662 if (negative) sign = '-';
663 else if (flags() & ios::showpos) sign = '+';
667 // Calculate padding.
668 int fieldsize = size + fpprec;
669 if (sign) fieldsize++;
673 padding = w - fieldsize;
676 register streambuf* sbuf = rdbuf();
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);
686 if (pad_kind == (ios::fmtflags)ios::internal)
687 for (i = padding; --i >= 0; ) sbuf->sputc(fill_char);
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');
693 if (pad_kind == (ios::fmtflags)ios::left) // Left adjustment
694 for (i = padding; --i >= 0; ) sbuf->sputc(fill_char);
697 _IO_cleanup_region_end (0);
702 #if _G_HAVE_LONG_DOUBLE_IO
703 ostream& ostream::operator<<(long double n)
707 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
710 if ((flags() & ios::floatfield) == ios::fixed)
712 else if ((flags() & ios::floatfield) == ios::scientific)
713 format_char = flags() & ios::uppercase ? 'E' : 'e';
715 format_char = flags() & ios::uppercase ? 'G' : 'g';
717 int prec = precision();
718 if (prec <= 0 && !(flags() & ios::fixed))
719 prec = 6; /* default */
721 #if _G_HAVE_PRINTF_FP
722 // Do actual conversion.
723 struct printf_info info = { prec: prec,
729 alt: (flags() & ios::showpoint) != 0,
731 left: (flags() & ios::left) != 0,
732 showsign: (flags() & ios::showpos) != 0,
735 #if defined __GLIBC__ && __GLIBC__ >= 2
740 const void *ptr = (const void *) &n;
742 if (__printf_fp (rdbuf(), &info, &ptr) < 0)
743 set (ios::badbit|ios::failbit);
745 # error "long double I/O using dtoa or cvt_double is not implemented"
748 _IO_cleanup_region_end (0);
754 ostream& ostream::operator<<(const char *s)
758 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
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)
774 if (_IO_sputn (sbuf, s, len) != len)
779 if (flags() & ios::left && padding > 0) // Left adjustment.
780 if (_IO_padn(sbuf, fill_char, padding) != padding)
784 _IO_cleanup_region_end (0);
790 ostream& ostream::operator<<(const void *p)
791 { Is in osform.cc, to avoid pulling in all of _IO_vfprintf by this file. */ }
794 ostream& ostream::operator<<(register streambuf* sbuf)
798 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
800 char buffer[_IO_BUFSIZ];
801 register streambuf* outbuf = _strbuf;
804 _IO_size_t count = _IO_sgetn(sbuf, buffer, _IO_BUFSIZ);
807 if (_IO_sputn(outbuf, buffer, count) != count)
814 _IO_cleanup_region_end (0);
819 ostream::ostream(streambuf* sb, ostream* tied)
824 ostream& ostream::seekp(streampos pos)
826 pos = _strbuf->pubseekpos(pos, ios::out);
827 if (pos == streampos(EOF))
832 ostream& ostream::seekp(streamoff off, _seek_dir dir)
834 streampos pos = _IO_seekoff (_strbuf, off, (int) dir, _IOS_OUTPUT);
835 if (pos == streampos(EOF))
840 streampos ostream::tellp()
843 streampos pos = _IO_seekoff (_strbuf, 0, _IO_seek_cur, _IOS_OUTPUT);
845 streampos pos = _strbuf->pubseekoff(0, ios::cur, ios::out);
847 if (pos == streampos(EOF))
852 ostream& ostream::flush()
859 ostream& flush(ostream& outs)
864 istream& ws(istream& ins)
867 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
869 int ch = skip_ws(ins._strbuf);
871 ins.set(ios::eofbit);
873 ins._strbuf->sputbackc(ch);
875 _IO_cleanup_region_end (0);
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.
884 int istream::_skip_ws()
886 int ch = skip_ws(_strbuf);
888 set(ios::eofbit|ios::failbit);
892 _strbuf->sputbackc(ch);
897 ostream& ends(ostream& outs)
903 ostream& endl(ostream& outs)
905 return flush(outs.put('\n'));
908 istream& lock(istream& ins)
910 _IO_flockfile (ins._strbuf);
913 istream& unlock(istream& ins)
915 _IO_funlockfile (ins._strbuf);
918 ostream& lock(ostream& outs)
920 _IO_flockfile (outs._strbuf);
923 ostream& unlock(ostream& outs)
925 _IO_funlockfile (outs._strbuf);
930 ostream& ostream::write(const char *s, streamsize n)
933 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
935 if (_IO_sputn(_strbuf, s, n) != n)
938 _IO_cleanup_region_end (0);
943 void ostream::do_osfx()
945 if (flags() & ios::unitbuf)
947 if (flags() & ios::stdio) {
953 iostream::iostream(streambuf* sb, ostream* tied)
958 // NOTE: extension for compatibility with old libg++.
959 // Not really compatible with fistream::close().
960 #ifdef _STREAM_COMPAT
963 if (_strbuf->_flags & _IO_IS_FILEBUF)
964 ((struct filebuf*)rdbuf())->close();
965 else if (_strbuf != NULL)
971 int istream::skip(int i)
973 int old = (_flags & ios::skipws) != 0;
975 _flags |= ios::skipws;
977 _flags &= ~ios::skipws;