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