mirror of
https://git.hardenedbsd.org/hardenedbsd/HardenedBSD.git
synced 2024-11-28 12:07:10 +01:00
154 lines
4.9 KiB
C++
154 lines
4.9 KiB
C++
/* This is part of libio/iostream, providing -*- C++ -*- input/output.
|
|
Copyright (C) 1993 Free Software Foundation
|
|
|
|
This file is part of the GNU IO Library. This library is free
|
|
software; you can redistribute it and/or modify it under the
|
|
terms of the GNU General Public License as published by the
|
|
Free Software Foundation; either version 2, or (at your option)
|
|
any later version.
|
|
|
|
This library is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this library; see the file COPYING. If not, write to the Free
|
|
Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
As a special exception, if you link this library with files
|
|
compiled with a GNU compiler to produce an executable, this does not cause
|
|
the resulting executable to be covered by the GNU General Public License.
|
|
This exception does not however invalidate any other reasons why
|
|
the executable file might be covered by the GNU General Public License. */
|
|
|
|
/* Written by Per Bothner (bothner@cygnus.com). */
|
|
|
|
#include "libioP.h"
|
|
#include "streambuf.h"
|
|
#include <stdio.h>
|
|
|
|
// The ANSI draft requires that operations on cin/cout/cerr can be
|
|
// mixed with operations on stdin/stdout/stderr on a character by
|
|
// character basis. This normally requires that the streambuf's
|
|
// used by cin/cout/cerr be stdiostreams. However, if the stdio
|
|
// implementation is the one that is built using this library,
|
|
// then we don't need to, since in that case stdin/stdout/stderr
|
|
// are identical to _IO_stdin/_IO_stdout/_IO_stderr.
|
|
|
|
#include <libio.h>
|
|
|
|
#ifdef _STDIO_USES_IOSTREAM
|
|
#define CIN_SBUF _IO_stdin_
|
|
#define COUT_SBUF _IO_stdout_
|
|
#define CERR_SBUF _IO_stderr_
|
|
static int use_stdiobuf = 0;
|
|
#else
|
|
#define CIN_SBUF _IO_stdin_buf
|
|
#define COUT_SBUF _IO_stdout_buf
|
|
#define CERR_SBUF _IO_stderr_buf
|
|
static int use_stdiobuf = 1;
|
|
#endif
|
|
|
|
#define cin CIN
|
|
#define cout COUT
|
|
#define cerr CERR
|
|
#define clog CLOG
|
|
#include "iostream.h"
|
|
#undef cin
|
|
#undef cout
|
|
#undef cerr
|
|
#undef clog
|
|
|
|
#ifdef __GNUG__
|
|
#define PAD 0 /* g++ allows 0-length arrays. */
|
|
#else
|
|
#define PAD 1
|
|
#endif
|
|
struct _fake_istream {
|
|
struct myfields {
|
|
#ifdef __GNUC__
|
|
_ios_fields *vb; /* pointer to virtual base class ios */
|
|
_IO_ssize_t _gcount;
|
|
#else
|
|
/* This is supposedly correct for cfront. */
|
|
_IO_ssize_t _gcount;
|
|
void *vptr;
|
|
_ios_fields *vb; /* pointer to virtual base class ios */
|
|
#endif
|
|
} mine;
|
|
_ios_fields base;
|
|
char filler[sizeof(struct istream)-sizeof(struct _ios_fields)+PAD];
|
|
};
|
|
struct _fake_ostream {
|
|
struct myfields {
|
|
#ifndef __GNUC__
|
|
void *vptr;
|
|
#endif
|
|
_ios_fields *vb; /* pointer to virtual base class ios */
|
|
} mine;
|
|
_ios_fields base;
|
|
char filler[sizeof(struct ostream)-sizeof(struct _ios_fields)+PAD];
|
|
};
|
|
|
|
|
|
#ifdef _IO_NEW_STREAMS
|
|
#define STD_STR(SBUF, TIE, EXTRA_FLAGS) \
|
|
(streambuf*)&SBUF, TIE, 0, ios::skipws|ios::dec|EXTRA_FLAGS, ' ',0,0,6
|
|
#else
|
|
#define STD_STR(SBUF, TIE, EXTRA_FLAGS) \
|
|
(streambuf*)&SBUF, TIE, 0, ios::dont_close|ios::dec|ios::skipws|EXTRA_FLAGS, ' ',0,0,6
|
|
#endif
|
|
|
|
#ifdef __GNUC__
|
|
#define OSTREAM_DEF(NAME, SBUF, TIE, EXTRA_FLAGS, ASM) \
|
|
_fake_ostream NAME ASM = { {&NAME.base}, {STD_STR(SBUF, TIE, EXTRA_FLAGS) }};
|
|
#define ISTREAM_DEF(NAME, SBUF, TIE, EXTRA_FLAGS) \
|
|
_fake_istream NAME = { {&NAME.base}, {STD_STR(SBUF, TIE, EXTRA_FLAGS) }};
|
|
#else
|
|
#define OSTREAM_DEF(NAME, SBUF, TIE, EXTRA_FLAGS) \
|
|
_fake_ostream NAME = { {0, &NAME.base}, {STD_STR(SBUF, TIE, EXTRA_FLAGS) }};
|
|
#define ISTREAM_DEF(NAME, SBUF, TIE, EXTRA_FLAGS) \
|
|
_fake_istream NAME = {{0, 0, &NAME.base}, {STD_STR(SBUF, TIE, EXTRA_FLAGS)}};
|
|
#endif
|
|
|
|
OSTREAM_DEF(cout, COUT_SBUF, NULL, 0, )
|
|
OSTREAM_DEF(cerr, CERR_SBUF,(ostream*)&cout, ios::unitbuf, )
|
|
ISTREAM_DEF(cin, CIN_SBUF, (ostream*)&cout, 0)
|
|
|
|
/* Only for (partial) compatibility with AT&T's library. */
|
|
#if _G_CLOG_CONFLICT
|
|
OSTREAM_DEF(clog, CERR_SBUF, (ostream*)&cout, 0, __asm__ ("__IO_clog"))
|
|
#else
|
|
OSTREAM_DEF(clog, CERR_SBUF, (ostream*)&cout, 0, )
|
|
#endif
|
|
|
|
// Switches between using _IO_std{in,out,err} and __std{in,out,err}_buf
|
|
// for standard streams. This does not normally need to be called
|
|
// explicitly, but is provided for AT&T compatibility.
|
|
|
|
int ios::sync_with_stdio(int new_state)
|
|
{
|
|
#ifdef _STDIO_USES_IOSTREAM
|
|
// It is always synced.
|
|
return 0;
|
|
#else
|
|
if (new_state == use_stdiobuf) // The usual case now.
|
|
return use_stdiobuf;
|
|
if (new_state) {
|
|
cin.base._strbuf = (streambuf*)&_IO_stdin_buf;
|
|
cout.base._strbuf = (streambuf*)&_IO_stdout_buf;
|
|
cerr.base._strbuf = (streambuf*)&_IO_stderr_buf;
|
|
clog.base._strbuf = (streambuf*)&_IO_stderr_buf;
|
|
} else {
|
|
cin.base._strbuf = (streambuf*)_IO_stdin;
|
|
cout.base._strbuf = (streambuf*)_IO_stdout;
|
|
cerr.base._strbuf = (streambuf*)_IO_stderr;
|
|
clog.base._strbuf = (streambuf*)_IO_stderr;
|
|
}
|
|
int old_state = use_stdiobuf;
|
|
use_stdiobuf = new_state;
|
|
return old_state;
|
|
#endif
|
|
}
|