|
|
1.1 root 1: /* This is part of libio/iostream, providing -*- C++ -*- input/output.
2: Copyright (C) 1993 Free Software Foundation
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 GNU CC; see the file COPYING. If not, write to
17: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
18:
19: As a special exception, if you link this library with files
20: compiled with a GNU compiler to produce an executable, this does not cause
21: the resulting executable to be covered by the GNU General Public License.
22: This exception does not however invalidate any other reasons why
23: the executable file might be covered by the GNU General Public License. */
24:
25: /* Written by Per Bothner ([email protected]). */
26:
27: #include "libioP.h"
28: #include "streambuf.h"
29:
30: // The ANSI draft requires that operations on cin/cout/cerr can be
31: // mixed with operations on stdin/stdout/stderr on a character by
32: // character basis. This normally requires that the streambuf's
33: // used by cin/cout/cerr be stdiostreams. However, if the stdio
34: // implementation is the one that is built using this library,
35: // then we don't need to, since in that case stdin/stdout/stderr
36: // are identical to &__std_filebuf_0/&__std_filebuf_1/&__std_filebuf_2.
37:
38: #if 1 //def _STDIO_USES_IOSTREAM
39: #define USE_FILEBUF
40: #endif
41:
42: #if _G_NAMES_HAVE_UNDERSCORE
43: #define UNDERSCORE "_"
44: #else
45: #define UNDERSCORE ""
46: #endif
47:
48: #ifdef USE_FILEBUF
49: #if 1
50: #include "libio.h"
51: #define CIN_SBUF _IO_stdin_
52: #define COUT_SBUF _IO_stdout_
53: #define CERR_SBUF _IO_stderr_
54: #else
55: #define CIN_SBUF __std_filebuf_0
56: #define COUT_SBUF __std_filebuf_1
57: #define CERR_SBUF __std_filebuf_2
58: #endif
59: static int use_stdiobuf = 0;
60: #else
61: #define CIN_SBUF __stdin_stdiobuf
62: #define COUT_SBUF __stdout_stdiobuf
63: #define CERR_SBUF __stderr_stdiobuf
64: static int use_stdiobuf = 1;
65: #endif
66:
67: #if 1
68: struct _fake_filebuf;
69: extern _fake_filebuf __std_filebuf_0, __std_filebuf_1, __std_filebuf_2;
70: #endif
71: struct _fake_stdiobuf;
72: extern _fake_stdiobuf __stdin_stdiobuf, __stdout_stdiobuf, __stderr_stdiobuf;
73:
74: #define cin CIN
75: #define cout COUT
76: #define cerr CERR
77: #define clog CLOG
78: #include "iostream.h"
79: #undef cin
80: #undef cout
81: #undef cerr
82: #undef clog
83:
84: #ifdef __GNUG__
85: #define PAD 0 /* g++ allows 0-length arrays. */
86: #else
87: #define PAD 1
88: #endif
89: struct _fake_istream {
90: struct myfields {
91: #ifdef __GNUC__
92: _ios_fields *vb; /* pointer to virtual base class ios */
93: _IO_ssize_t _gcount;
94: #else
95: /* This is supposedly correct for cfront. */
96: _IO_ssize_t _gcount;
97: void *vptr;
98: _ios_fields *vb; /* pointer to virtual base class ios */
99: #endif
100: } mine;
101: _ios_fields base;
102: char filler[sizeof(struct istream)-sizeof(struct _ios_fields)+PAD];
103: };
104: struct _fake_ostream {
105: struct myfields {
106: #ifndef __GNUC__
107: void *vptr;
108: #endif
109: _ios_fields *vb; /* pointer to virtual base class ios */
110: } mine;
111: _ios_fields base;
112: char filler[sizeof(struct ostream)-sizeof(struct _ios_fields)+PAD];
113: };
114:
115: #define STD_STR(SBUF, TIE, EXTRA_FLAGS) \
116: (streambuf*)&SBUF, TIE, 0, ios::dont_close|ios::skipws|EXTRA_FLAGS, ' ',0,0,6
117:
118: #ifdef __GNUC__
119: #define OSTREAM_DEF(NAME, SBUF, TIE, EXTRA_FLAGS) \
120: _fake_ostream NAME = { {&NAME.base}, {STD_STR(SBUF, TIE, EXTRA_FLAGS) }};
121: #define ISTREAM_DEF(NAME, SBUF, TIE, EXTRA_FLAGS) \
122: _fake_istream NAME = { {&NAME.base}, {STD_STR(SBUF, TIE, EXTRA_FLAGS) }};
123: #else
124: #define OSTREAM_DEF(NAME, SBUF, TIE, EXTRA_FLAGS) \
125: _fake_ostream NAME = { {0, &NAME.base}, {STD_STR(SBUF, TIE, EXTRA_FLAGS) }};
126: #define ISTREAM_DEF(NAME, SBUF, TIE, EXTRA_FLAGS) \
127: _fake_ostream NAME = {{0, 0, &NAME.base}, {STD_STR(SBUF, TIE, EXTRA_FLAGS)}};
128: #endif
129:
130: OSTREAM_DEF(cout, COUT_SBUF, NULL, 0)
131: OSTREAM_DEF(cerr, CERR_SBUF,(ostream*)&cout, ios::unitbuf)
132: ISTREAM_DEF(cin, CIN_SBUF, (ostream*)&cout, 0)
133:
134: /* Only for (partial) compatibility with AT&T's library. */
135: OSTREAM_DEF(clog, CERR_SBUF, (ostream*)&cout, 0)
136:
137: // Switches between using __std_filebuf_{0,1,2} and
138: // __std{in,out,err}_stdiobuf for standard streams. This is
139: // normally not needed, but is provided for AT&T compatibility.
140:
141: int ios::sync_with_stdio(int new_state)
142: {
143: #ifdef TODO
144: #ifdef _STDIO_USES_IOSTREAM
145: // It is always synced.
146: return 0;
147: #else
148: if (new_state == use_stdiobuf) // The usual case now.
149: return use_stdiobuf;
150: if (new_state) {
151: cout.base._strbuf = (streambuf*)&__stdout_stdiobuf;
152: cin.base._strbuf = (streambuf*)&__stdin_stdiobuf;
153: cerr.base._strbuf = (streambuf*)&__stderr_stdiobuf;
154: clog.base._strbuf = (streambuf*)&__stderr_stdiobuf;
155: } else {
156: cout.base._strbuf = (streambuf*)&__std_filebuf_1;
157: cin.base._strbuf = (streambuf*)&__std_filebuf_0;
158: cerr.base._strbuf = (streambuf*)&__std_filebuf_2;
159: clog.base._strbuf = (streambuf*)&__std_filebuf_2;
160: }
161: int old_state = use_stdiobuf;
162: use_stdiobuf = new_state;
163: return old_state;
164: #endif
165: #endif
166: return 0;
167: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.