1/* This is part of libio/iostream, providing -*- C++ -*- input/output. 2Copyright (C) 1993 Free Software Foundation 3 4This file is part of the GNU IO Library. This library is free 5software; you can redistribute it and/or modify it under the 6terms of the GNU General Public License as published by the 7Free Software Foundation; either version 2, or (at your option) 8any later version. 9 10This library is distributed in the hope that it will be useful, 11but WITHOUT ANY WARRANTY; without even the implied warranty of 12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13GNU General Public License for more details. 14 15You should have received a copy of the GNU General Public License 16along with this library; see the file COPYING. If not, write to the Free 17Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 18 19As a special exception, if you link this library with files 20compiled with a GNU compiler to produce an executable, this does not cause 21the resulting executable to be covered by the GNU General Public License. 22This exception does not however invalidate any other reasons why 23the executable file might be covered by the GNU General Public License. */ 24 25/* Written by Per Bothner (bothner@cygnus.com). */ 26 27#include "libioP.h" 28#include "streambuf.h" 29#include <stdio.h> 30 31// The ANSI draft requires that operations on cin/cout/cerr can be 32// mixed with operations on stdin/stdout/stderr on a character by 33// character basis. This normally requires that the streambuf's 34// used by cin/cout/cerr be stdiostreams. However, if the stdio 35// implementation is the one that is built using this library, 36// then we don't need to, since in that case stdin/stdout/stderr 37// are identical to _IO_stdin/_IO_stdout/_IO_stderr. 38 39#include <libio.h> 40 41#ifdef _STDIO_USES_IOSTREAM 42#define CIN_SBUF _IO_stdin_ 43#define COUT_SBUF _IO_stdout_ 44#define CERR_SBUF _IO_stderr_ 45static int use_stdiobuf = 0; 46#else 47#define CIN_SBUF _IO_stdin_buf 48#define COUT_SBUF _IO_stdout_buf 49#define CERR_SBUF _IO_stderr_buf 50static int use_stdiobuf = 1; 51#endif 52 53#define cin CIN 54#define cout COUT 55#define cerr CERR 56#define clog CLOG 57#include "iostream.h" 58#undef cin 59#undef cout 60#undef cerr 61#undef clog 62 63#ifdef __GNUG__ 64#define PAD 0 /* g++ allows 0-length arrays. */ 65#else 66#define PAD 1 67#endif 68struct _fake_istream { 69 struct myfields { 70#ifdef __GNUC__ 71 _ios_fields *vb; /* pointer to virtual base class ios */ 72 _IO_ssize_t _gcount; 73#else 74 /* This is supposedly correct for cfront. */ 75 _IO_ssize_t _gcount; 76 void *vptr; 77 _ios_fields *vb; /* pointer to virtual base class ios */ 78#endif 79 } mine; 80 _ios_fields base; 81 char filler[sizeof(struct istream)-sizeof(struct _ios_fields)+PAD]; 82}; 83struct _fake_ostream { 84 struct myfields { 85#ifndef __GNUC__ 86 void *vptr; 87#endif 88 _ios_fields *vb; /* pointer to virtual base class ios */ 89 } mine; 90 _ios_fields base; 91 char filler[sizeof(struct ostream)-sizeof(struct _ios_fields)+PAD]; 92}; 93 94 95#ifdef _IO_NEW_STREAMS 96#define STD_STR(SBUF, TIE, EXTRA_FLAGS) \ 97 (streambuf*)&SBUF, TIE, 0, ios::skipws|ios::dec|EXTRA_FLAGS, ' ',0,0,6 98#else 99#define STD_STR(SBUF, TIE, EXTRA_FLAGS) \ 100 (streambuf*)&SBUF, TIE, 0, ios::dont_close|ios::dec|ios::skipws|EXTRA_FLAGS, ' ',0,0,6 101#endif 102 103#ifdef __GNUC__ 104#define OSTREAM_DEF(NAME, SBUF, TIE, EXTRA_FLAGS, ASM) \ 105 _fake_ostream NAME ASM = { {&NAME.base}, {STD_STR(SBUF, TIE, EXTRA_FLAGS) }}; 106#define ISTREAM_DEF(NAME, SBUF, TIE, EXTRA_FLAGS) \ 107 _fake_istream NAME = { {&NAME.base}, {STD_STR(SBUF, TIE, EXTRA_FLAGS) }}; 108#else 109#define OSTREAM_DEF(NAME, SBUF, TIE, EXTRA_FLAGS) \ 110 _fake_ostream NAME = { {0, &NAME.base}, {STD_STR(SBUF, TIE, EXTRA_FLAGS) }}; 111#define ISTREAM_DEF(NAME, SBUF, TIE, EXTRA_FLAGS) \ 112 _fake_istream NAME = {{0, 0, &NAME.base}, {STD_STR(SBUF, TIE, EXTRA_FLAGS)}}; 113#endif 114 115OSTREAM_DEF(cout, COUT_SBUF, NULL, 0, ) 116OSTREAM_DEF(cerr, CERR_SBUF,(ostream*)&cout, ios::unitbuf, ) 117ISTREAM_DEF(cin, CIN_SBUF, (ostream*)&cout, 0) 118 119/* Only for (partial) compatibility with AT&T's library. */ 120#if _G_CLOG_CONFLICT 121OSTREAM_DEF(clog, CERR_SBUF, (ostream*)&cout, 0, __asm__ ("__IO_clog")) 122#else 123OSTREAM_DEF(clog, CERR_SBUF, (ostream*)&cout, 0, ) 124#endif 125 126// Switches between using _IO_std{in,out,err} and __std{in,out,err}_buf 127// for standard streams. This does not normally need to be called 128// explicitly, but is provided for AT&T compatibility. 129 130int ios::sync_with_stdio(int new_state) 131{ 132#ifdef _STDIO_USES_IOSTREAM 133 // It is always synced. 134 return 0; 135#else 136 if (new_state == use_stdiobuf) // The usual case now. 137 return use_stdiobuf; 138 if (new_state) { 139 cin.base._strbuf = (streambuf*)&_IO_stdin_buf; 140 cout.base._strbuf = (streambuf*)&_IO_stdout_buf; 141 cerr.base._strbuf = (streambuf*)&_IO_stderr_buf; 142 clog.base._strbuf = (streambuf*)&_IO_stderr_buf; 143 } else { 144 cin.base._strbuf = (streambuf*)_IO_stdin; 145 cout.base._strbuf = (streambuf*)_IO_stdout; 146 cerr.base._strbuf = (streambuf*)_IO_stderr; 147 clog.base._strbuf = (streambuf*)_IO_stderr; 148 } 149 int old_state = use_stdiobuf; 150 use_stdiobuf = new_state; 151 return old_state; 152#endif 153} 154